github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/common/modeldestroy.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/names"
     9  
    10  	"github.com/juju/juju/apiserver/metricsender"
    11  	"github.com/juju/juju/state"
    12  )
    13  
    14  var sendMetrics = func(st *state.State) error {
    15  	err := metricsender.SendMetrics(st, metricsender.DefaultMetricSender(), metricsender.DefaultMaxBatchesPerSend())
    16  	return errors.Trace(err)
    17  }
    18  
    19  // DestroyModelIncludingHosted sets the model to dying. Cleanup jobs then destroy
    20  // all services and non-manager, non-manual machine instances in the specified
    21  // model. This function assumes that all necessary authentication checks
    22  // have been done. If the model is a controller hosting other
    23  // models, they will also be destroyed.
    24  func DestroyModelIncludingHosted(st *state.State, modelTag names.ModelTag) error {
    25  	return destroyModel(st, modelTag, true)
    26  }
    27  
    28  // DestroyModel sets the environment to dying. Cleanup jobs then destroy
    29  // all services and non-manager, non-manual machine instances in the specified
    30  // model. This function assumes that all necessary authentication checks
    31  // have been done. An error will be returned if this model is a
    32  // controller hosting other model.
    33  func DestroyModel(st *state.State, modelTag names.ModelTag) error {
    34  	return destroyModel(st, modelTag, false)
    35  }
    36  
    37  func destroyModel(st *state.State, modelTag names.ModelTag, destroyHostedModels bool) error {
    38  	var err error
    39  	if modelTag != st.ModelTag() {
    40  		if st, err = st.ForModel(modelTag); err != nil {
    41  			return errors.Trace(err)
    42  		}
    43  		defer st.Close()
    44  	}
    45  
    46  	if destroyHostedModels {
    47  		envs, err := st.AllModels()
    48  		if err != nil {
    49  			return errors.Trace(err)
    50  		}
    51  		for _, env := range envs {
    52  			envSt, err := st.ForModel(env.ModelTag())
    53  			defer envSt.Close()
    54  			if err != nil {
    55  				return errors.Trace(err)
    56  			}
    57  			check := NewBlockChecker(envSt)
    58  			if err = check.DestroyAllowed(); err != nil {
    59  				return errors.Trace(err)
    60  			}
    61  		}
    62  	} else {
    63  		check := NewBlockChecker(st)
    64  		if err = check.DestroyAllowed(); err != nil {
    65  			return errors.Trace(err)
    66  		}
    67  	}
    68  
    69  	env, err := st.Model()
    70  	if err != nil {
    71  		return errors.Trace(err)
    72  	}
    73  
    74  	if destroyHostedModels {
    75  		if err := env.DestroyIncludingHosted(); err != nil {
    76  			return err
    77  		}
    78  	} else {
    79  		if err = env.Destroy(); err != nil {
    80  			return errors.Trace(err)
    81  		}
    82  	}
    83  
    84  	err = sendMetrics(st)
    85  	if err != nil {
    86  		logger.Warningf("failed to send leftover metrics: %v", err)
    87  	}
    88  
    89  	// Return to the caller. If it's the CLI, it will finish up by calling the
    90  	// provider's Destroy method, which will destroy the controllers, any
    91  	// straggler instances, and other provider-specific resources. Once all
    92  	// resources are torn down, the Undertaker worker handles the removal of
    93  	// the environment.
    94  	return nil
    95  }