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 }