| LEFT | RIGHT |
| 1 // The state package enables reading, observing, and changing | 1 // The state package enables reading, observing, and changing |
| 2 // the state stored in MongoDB of a whole environment | 2 // the state stored in MongoDB of a whole environment |
| 3 // managed by juju. | 3 // managed by juju. |
| 4 package mstate | 4 package mstate |
| 5 | 5 |
| 6 import ( | 6 import ( |
| 7 "fmt" | 7 "fmt" |
| 8 "labix.org/v2/mgo" | 8 "labix.org/v2/mgo" |
| 9 "labix.org/v2/mgo/bson" | 9 "labix.org/v2/mgo/bson" |
| 10 "launchpad.net/juju-core/charm" | 10 "launchpad.net/juju-core/charm" |
| 11 "launchpad.net/juju-core/mstate/life" | |
| 12 "net/url" | 11 "net/url" |
| 12 ) |
| 13 |
| 14 type Life int |
| 15 |
| 16 const ( |
| 17 Alive Life = 1 + iota |
| 18 Dying |
| 19 Dead |
| 13 ) | 20 ) |
| 14 | 21 |
| 15 // State represents the state of an environment | 22 // State represents the state of an environment |
| 16 // managed by juju. | 23 // managed by juju. |
| 17 type State struct { | 24 type State struct { |
| 18 db *mgo.Database | 25 db *mgo.Database |
| 19 charms *mgo.Collection | 26 charms *mgo.Collection |
| 20 machines *mgo.Collection | 27 machines *mgo.Collection |
| 21 services *mgo.Collection | 28 services *mgo.Collection |
| 22 units *mgo.Collection | 29 units *mgo.Collection |
| 23 } | 30 } |
| 24 | 31 |
| 25 // AddMachine creates a new machine state. | 32 // AddMachine creates a new machine state. |
| 26 func (s *State) AddMachine() (m *Machine, err error) { | 33 func (s *State) AddMachine() (m *Machine, err error) { |
| 27 defer errorContextf(&err, "can't add a new machine") | 34 defer errorContextf(&err, "can't add a new machine") |
| 28 id, err := s.sequence("machine") | 35 id, err := s.sequence("machine") |
| 29 if err != nil { | 36 if err != nil { |
| 30 return nil, err | 37 return nil, err |
| 31 } | 38 } |
| 32 mdoc := machineDoc{ | 39 mdoc := machineDoc{ |
| 33 » » Id: id, | 40 » » Id: id, |
| 34 » » LifeCycle: life.Alive, | 41 » » Life: Alive, |
| 35 } | 42 } |
| 36 err = s.machines.Insert(mdoc) | 43 err = s.machines.Insert(mdoc) |
| 37 if err != nil { | 44 if err != nil { |
| 38 return nil, err | 45 return nil, err |
| 39 } | 46 } |
| 40 return &Machine{st: s, id: id}, nil | 47 return &Machine{st: s, id: id}, nil |
| 41 } | 48 } |
| 42 | 49 |
| 43 // RemoveMachine removes the machine with the the given id. | 50 // RemoveMachine removes the machine with the the given id. |
| 44 func (s *State) RemoveMachine(id int) error { | 51 func (s *State) RemoveMachine(id int) error { |
| 45 » sel := bson.D{{"_id", id}, {"lifecycle", life.Alive}} | 52 » sel := bson.D{{"_id", id}, {"life", Alive}} |
| 46 » change := bson.D{{"$set", bson.D{{"lifecycle", life.Dying}}}} | 53 » change := bson.D{{"$set", bson.D{{"life", Dying}}}} |
| 47 err := s.machines.Update(sel, change) | 54 err := s.machines.Update(sel, change) |
| 48 if err != nil { | 55 if err != nil { |
| 49 return fmt.Errorf("can't remove machine %d", id) | 56 return fmt.Errorf("can't remove machine %d", id) |
| 50 } | 57 } |
| 51 return nil | 58 return nil |
| 52 } | 59 } |
| 53 | 60 |
| 54 // AllMachines returns all machines in the environment. | 61 // AllMachines returns all machines in the environment. |
| 55 func (s *State) AllMachines() (machines []*Machine, err error) { | 62 func (s *State) AllMachines() (machines []*Machine, err error) { |
| 56 mdocs := []machineDoc{} | 63 mdocs := []machineDoc{} |
| 57 » sel := bson.D{{"lifecycle", life.Alive}} | 64 » sel := bson.D{{"life", Alive}} |
| 58 err = s.machines.Find(sel).Select(bson.D{{"_id", 1}}).All(&mdocs) | 65 err = s.machines.Find(sel).Select(bson.D{{"_id", 1}}).All(&mdocs) |
| 59 if err != nil { | 66 if err != nil { |
| 60 return nil, fmt.Errorf("can't get all machines: %v", err) | 67 return nil, fmt.Errorf("can't get all machines: %v", err) |
| 61 } | 68 } |
| 62 for _, v := range mdocs { | 69 for _, v := range mdocs { |
| 63 machines = append(machines, &Machine{st: s, id: v.Id}) | 70 machines = append(machines, &Machine{st: s, id: v.Id}) |
| 64 } | 71 } |
| 65 return | 72 return |
| 66 } | 73 } |
| 67 | 74 |
| 68 // Machine returns the machine with the given id. | 75 // Machine returns the machine with the given id. |
| 69 func (s *State) Machine(id int) (*Machine, error) { | 76 func (s *State) Machine(id int) (*Machine, error) { |
| 70 mdoc := &machineDoc{} | 77 mdoc := &machineDoc{} |
| 71 » sel := bson.D{{"_id", id}, {"lifecycle", life.Alive}} | 78 » sel := bson.D{{"_id", id}, {"life", Alive}} |
| 72 err := s.machines.Find(sel).One(mdoc) | 79 err := s.machines.Find(sel).One(mdoc) |
| 73 if err != nil { | 80 if err != nil { |
| 74 return nil, fmt.Errorf("can't get machine %d: %v", id, err) | 81 return nil, fmt.Errorf("can't get machine %d: %v", id, err) |
| 75 } | 82 } |
| 76 return &Machine{st: s, id: mdoc.Id}, nil | 83 return &Machine{st: s, id: mdoc.Id}, nil |
| 77 } | 84 } |
| 78 | 85 |
| 79 // AddCharm adds the ch charm with curl to the state. bundleUrl must be | 86 // AddCharm adds the ch charm with curl to the state. bundleUrl must be |
| 80 // set to a URL where the bundle for ch may be downloaded from. | 87 // set to a URL where the bundle for ch may be downloaded from. |
| 81 // On success the newly added charm state is returned. | 88 // On success the newly added charm state is returned. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 102 return nil, fmt.Errorf("can't get charm %q: %v", curl, err) | 109 return nil, fmt.Errorf("can't get charm %q: %v", curl, err) |
| 103 } | 110 } |
| 104 | 111 |
| 105 return newCharm(s, cdoc) | 112 return newCharm(s, cdoc) |
| 106 } | 113 } |
| 107 | 114 |
| 108 // AddService creates a new service state with the given unique name | 115 // AddService creates a new service state with the given unique name |
| 109 // and the charm state. | 116 // and the charm state. |
| 110 func (s *State) AddService(name string, ch *Charm) (service *Service, err error)
{ | 117 func (s *State) AddService(name string, ch *Charm) (service *Service, err error)
{ |
| 111 sdoc := &serviceDoc{ | 118 sdoc := &serviceDoc{ |
| 112 » » Name: name, | 119 » » Name: name, |
| 113 » » CharmURL: ch.URL(), | 120 » » CharmURL: ch.URL(), |
| 114 » » LifeCycle: life.Alive, | 121 » » Life: Alive, |
| 115 } | 122 } |
| 116 err = s.services.Insert(sdoc) | 123 err = s.services.Insert(sdoc) |
| 117 if err != nil { | 124 if err != nil { |
| 118 return nil, fmt.Errorf("can't add service %q:", name, err) | 125 return nil, fmt.Errorf("can't add service %q:", name, err) |
| 119 } | 126 } |
| 120 return &Service{st: s, name: name}, nil | 127 return &Service{st: s, name: name}, nil |
| 121 } | 128 } |
| 122 | 129 |
| 123 // RemoveService removes a service from the state. It will also remove all | 130 // RemoveService removes a service from the state. It will also remove all |
| 124 // its units and break any of its existing relations. | 131 // its units and break any of its existing relations. |
| 125 func (s *State) RemoveService(svc *Service) (err error) { | 132 func (s *State) RemoveService(svc *Service) (err error) { |
| 126 defer errorContextf(&err, "can't remove service %s", svc) | 133 defer errorContextf(&err, "can't remove service %s", svc) |
| 127 | 134 |
| 128 » sel := bson.D{{"_id", svc.name}, {"lifecycle", life.Alive}} | 135 » sel := bson.D{{"_id", svc.name}, {"life", Alive}} |
| 129 » change := bson.D{{"$set", bson.D{{"lifecycle", life.Dying}}}} | 136 » change := bson.D{{"$set", bson.D{{"life", Dying}}}} |
| 130 err = s.services.Update(sel, change) | 137 err = s.services.Update(sel, change) |
| 131 if err != nil { | 138 if err != nil { |
| 132 return err | 139 return err |
| 133 } | 140 } |
| 134 | 141 |
| 135 sel = bson.D{{"service", svc.name}} | 142 sel = bson.D{{"service", svc.name}} |
| 136 » change = bson.D{{"$set", bson.D{{"lifecycle", life.Dying}, {"machineid",
nil}}}} | 143 » change = bson.D{{"$set", bson.D{{"life", Dying}, {"machineid", nil}}}} |
| 137 _, err = s.units.UpdateAll(sel, change) | 144 _, err = s.units.UpdateAll(sel, change) |
| 138 return err | 145 return err |
| 139 } | 146 } |
| 140 | 147 |
| 141 // Service returns a service state by name. | 148 // Service returns a service state by name. |
| 142 func (s *State) Service(name string) (service *Service, err error) { | 149 func (s *State) Service(name string) (service *Service, err error) { |
| 143 sdoc := &serviceDoc{} | 150 sdoc := &serviceDoc{} |
| 144 » sel := bson.D{{"_id", name}, {"lifecycle", life.Alive}} | 151 » sel := bson.D{{"_id", name}, {"life", Alive}} |
| 145 err = s.services.Find(sel).One(sdoc) | 152 err = s.services.Find(sel).One(sdoc) |
| 146 if err != nil { | 153 if err != nil { |
| 147 return nil, fmt.Errorf("can't get service %q: %v", name, err) | 154 return nil, fmt.Errorf("can't get service %q: %v", name, err) |
| 148 } | 155 } |
| 149 return &Service{st: s, name: name}, nil | 156 return &Service{st: s, name: name}, nil |
| 150 } | 157 } |
| 151 | 158 |
| 152 // AllServices returns all deployed services in the environment. | 159 // AllServices returns all deployed services in the environment. |
| 153 func (s *State) AllServices() (services []*Service, err error) { | 160 func (s *State) AllServices() (services []*Service, err error) { |
| 154 sdocs := []serviceDoc{} | 161 sdocs := []serviceDoc{} |
| 155 » err = s.services.Find(bson.D{{"lifecycle", life.Alive}}).All(&sdocs) | 162 » err = s.services.Find(bson.D{{"life", Alive}}).All(&sdocs) |
| 156 if err != nil { | 163 if err != nil { |
| 157 return nil, fmt.Errorf("can't get all services") | 164 return nil, fmt.Errorf("can't get all services") |
| 158 } | 165 } |
| 159 for _, v := range sdocs { | 166 for _, v := range sdocs { |
| 160 services = append(services, &Service{st: s, name: v.Name}) | 167 services = append(services, &Service{st: s, name: v.Name}) |
| 161 } | 168 } |
| 162 return services, nil | 169 return services, nil |
| 163 } | 170 } |
| LEFT | RIGHT |