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  }