github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/apiserver/client/destroy.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package client
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  
     9  	"github.com/juju/juju/environs"
    10  	"github.com/juju/juju/instance"
    11  	"github.com/juju/juju/state"
    12  )
    13  
    14  // DestroyEnvironment destroys all services and non-manager machine
    15  // instances in the environment.
    16  func (c *Client) DestroyEnvironment() (err error) {
    17  	if err = c.check.DestroyAllowed(); err != nil {
    18  		return errors.Trace(err)
    19  	}
    20  
    21  	env, err := c.api.state.Environment()
    22  	if err != nil {
    23  		return errors.Trace(err)
    24  	}
    25  
    26  	if err = env.Destroy(); err != nil {
    27  		return errors.Trace(err)
    28  	}
    29  
    30  	machines, err := c.api.state.AllMachines()
    31  	if err != nil {
    32  		return errors.Trace(err)
    33  	}
    34  
    35  	// We must destroy instances server-side to support JES (Juju Environment
    36  	// Server), as there's no CLI to fall back on. In that case, we only ever
    37  	// destroy non-state machines; we leave destroying state servers in non-
    38  	// hosted environments to the CLI, as otherwise the API server may get cut
    39  	// off.
    40  	if err := destroyInstances(c.api.state, machines); err != nil {
    41  		return errors.Trace(err)
    42  	}
    43  
    44  	// If this is not the state server environment, remove all documents from
    45  	// state associated with the environment.
    46  	if env.UUID() != env.ServerTag().Id() {
    47  		return errors.Trace(c.api.state.RemoveAllEnvironDocs())
    48  	}
    49  
    50  	// Return to the caller. If it's the CLI, it will finish up
    51  	// by calling the provider's Destroy method, which will
    52  	// destroy the state servers, any straggler instances, and
    53  	// other provider-specific resources.
    54  	return nil
    55  }
    56  
    57  // destroyInstances directly destroys all non-manager,
    58  // non-manual machine instances.
    59  func destroyInstances(st *state.State, machines []*state.Machine) error {
    60  	var ids []instance.Id
    61  	for _, m := range machines {
    62  		if m.IsManager() {
    63  			continue
    64  		}
    65  		if _, isContainer := m.ParentId(); isContainer {
    66  			continue
    67  		}
    68  		manual, err := m.IsManual()
    69  		if manual {
    70  			continue
    71  		} else if err != nil {
    72  			return err
    73  		}
    74  		id, err := m.InstanceId()
    75  		if err != nil {
    76  			continue
    77  		}
    78  		ids = append(ids, id)
    79  	}
    80  	if len(ids) == 0 {
    81  		return nil
    82  	}
    83  	envcfg, err := st.EnvironConfig()
    84  	if err != nil {
    85  		return err
    86  	}
    87  	env, err := environs.New(envcfg)
    88  	if err != nil {
    89  		return err
    90  	}
    91  	return env.StopInstances(ids...)
    92  }