github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/machine/remove.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package machine 5 6 import ( 7 "github.com/juju/cmd" 8 "github.com/juju/errors" 9 "github.com/juju/gnuflag" 10 "gopkg.in/juju/names.v2" 11 12 "github.com/juju/juju/cmd/juju/block" 13 "github.com/juju/juju/cmd/modelcmd" 14 ) 15 16 // NewRemoveCommand returns a command used to remove a specified machine. 17 func NewRemoveCommand() cmd.Command { 18 return modelcmd.Wrap(&removeCommand{}) 19 } 20 21 // removeCommand causes an existing machine to be destroyed. 22 type removeCommand struct { 23 modelcmd.ModelCommandBase 24 api RemoveMachineAPI 25 MachineIds []string 26 Force bool 27 } 28 29 const destroyMachineDoc = ` 30 Machines are specified by their numbers, which may be retrieved from the 31 output of ` + "`juju status`." + ` 32 Machines responsible for the model cannot be removed. 33 Machines running units or containers can be removed using the '--force' 34 option; this will also remove those units and containers without giving 35 them an opportunity to shut down cleanly. 36 37 Examples: 38 39 Remove machine number 5 which has no running units or containers: 40 41 juju remove-machine 5 42 43 Remove machine 6 and any running units or containers: 44 45 juju remove-machine 6 --force 46 47 See also: 48 add-machine 49 ` 50 51 // Info implements Command.Info. 52 func (c *removeCommand) Info() *cmd.Info { 53 return &cmd.Info{ 54 Name: "remove-machine", 55 Args: "<machine number> ...", 56 Purpose: "Removes one or more machines from a model.", 57 Doc: destroyMachineDoc, 58 } 59 } 60 61 // SetFlags implements Command.SetFlags. 62 func (c *removeCommand) SetFlags(f *gnuflag.FlagSet) { 63 c.ModelCommandBase.SetFlags(f) 64 f.BoolVar(&c.Force, "force", false, "Completely remove a machine and all its dependencies") 65 } 66 67 func (c *removeCommand) Init(args []string) error { 68 if len(args) == 0 { 69 return errors.Errorf("no machines specified") 70 } 71 for _, id := range args { 72 if !names.IsValidMachine(id) { 73 return errors.Errorf("invalid machine id %q", id) 74 } 75 } 76 c.MachineIds = args 77 return nil 78 } 79 80 type RemoveMachineAPI interface { 81 DestroyMachines(machines ...string) error 82 ForceDestroyMachines(machines ...string) error 83 Close() error 84 } 85 86 func (c *removeCommand) getRemoveMachineAPI() (RemoveMachineAPI, error) { 87 if c.api != nil { 88 return c.api, nil 89 } 90 return c.NewAPIClient() 91 } 92 93 // Run implements Command.Run. 94 func (c *removeCommand) Run(_ *cmd.Context) error { 95 client, err := c.getRemoveMachineAPI() 96 if err != nil { 97 return err 98 } 99 defer client.Close() 100 if c.Force { 101 err = client.ForceDestroyMachines(c.MachineIds...) 102 } else { 103 err = client.DestroyMachines(c.MachineIds...) 104 } 105 return block.ProcessBlockedError(err, block.BlockRemove) 106 }