github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/undertaker.go (about)

     1  package state
     2  
     3  import (
     4  	"gopkg.in/mgo.v2/bson"
     5  
     6  	"github.com/juju/errors"
     7  
     8  	"gopkg.in/mgo.v2/txn"
     9  )
    10  
    11  var ErrModelNotDying = errors.New("model is not dying")
    12  
    13  // ProcessDyingModel checks if there are any machines or services left in
    14  // state. If there are none, the model's life is changed from dying to dead.
    15  func (st *State) ProcessDyingModel() (err error) {
    16  	buildTxn := func(attempt int) ([]txn.Op, error) {
    17  		model, err := st.Model()
    18  		if err != nil {
    19  			return nil, errors.Trace(err)
    20  		}
    21  
    22  		if model.Life() != Dying {
    23  			return nil, errors.Trace(ErrModelNotDying)
    24  		}
    25  
    26  		if st.IsController() {
    27  			models, err := st.AllModels()
    28  			if err != nil {
    29  				return nil, errors.Trace(err)
    30  			}
    31  			for _, model := range models {
    32  				if model.UUID() != st.ModelUUID() && model.Life() != Dead {
    33  					return nil, errors.Errorf("one or more hosted models are not yet dead")
    34  				}
    35  			}
    36  		}
    37  
    38  		if err := model.checkEmpty(); err != nil {
    39  			return nil, errors.Trace(err)
    40  		}
    41  
    42  		ops := []txn.Op{{
    43  			C:      modelsC,
    44  			Id:     st.ModelUUID(),
    45  			Assert: isDyingDoc,
    46  			Update: bson.M{"$set": bson.M{
    47  				"life":          Dead,
    48  				"time-of-death": nowToTheSecond(),
    49  			}},
    50  		}}
    51  		return ops, nil
    52  	}
    53  
    54  	if err = st.run(buildTxn); err != nil {
    55  		return errors.Trace(err)
    56  	}
    57  	return nil
    58  }