12
"launchpad.net/goyaml"
11
13
"launchpad.net/gozk/zookeeper"
14
17
// State represents the state of an environment
15
18
// managed by juju.
16
19
type State struct {
21
23
// Open returns a new State representing the environment
22
24
// being accessed through the ZooKeeper connection.
23
25
func Open(zk *zookeeper.Conn) (*State, error) {
24
t, err := readTopology(zk)
28
return &State{zk, t}, nil
26
return &State{zk}, nil
29
// AddService creates a new service with the given unique name
30
// and the charm state.
31
func (s *State) AddService(name string, charm *Charm) (*Service, error) {
32
details := map[string]interface{}{"charm": charm.URL().String()}
33
yaml, err := goyaml.Marshal(details)
37
path, err := s.zk.Create("/services/service-", string(yaml), zookeeper.SEQUENCE, zkPermAll)
41
key := strings.Split(path, "/")[2]
42
service := &Service{s.zk, key, name}
43
// Create an empty configuration node.
44
_, err = createConfigNode(s.zk, service.zkConfigPath(), map[string]interface{}{})
48
addService := func(t *topology) error {
49
if _, err := t.ServiceKey(name); err == nil {
50
// No error, so service name already in use.
51
return fmt.Errorf("service name %q is already in use", name)
53
return t.AddService(key, name)
55
if err = retryTopologyChange(s.zk, addService); err != nil {
61
// RemoveService removes a service from the state. It will
62
// also remove all its units and break any of its existing
64
func (s *State) RemoveService(svc *Service) error {
65
// TODO Remove relations first, to prevent spurious hook execution.
68
units, err := svc.AllUnits()
72
for _, unit := range units {
73
if err = svc.RemoveUnit(unit); err != nil {
77
// Remove the service from the topology.
78
removeService := func(t *topology) error {
79
if !t.HasService(svc.key) {
82
t.RemoveService(svc.key)
85
if err = retryTopologyChange(s.zk, removeService); err != nil {
88
return zkRemoveTree(s.zk, svc.zkPath())
31
91
// Service returns a service state by name.
32
92
func (s *State) Service(name string) (*Service, error) {
33
key, err := s.topology.serviceKey(name)
93
topology, err := readTopology(s.zk)
97
key, err := topology.ServiceKey(name)
50
114
return service.Unit(name)
117
// Initialize performs an initialization of the ZooKeeper nodes.
118
func Initialize(zk *zookeeper.Conn) error {
119
stat, err := zk.Exists("/initialized")
120
if stat == nil && err == nil {
122
if _, err := zk.Create("/charms", "", 0, zkPermAll); err != nil {
125
if _, err := zk.Create("/services", "", 0, zkPermAll); err != nil {
128
if _, err := zk.Create("/machines", "", 0, zkPermAll); err != nil {
131
if _, err := zk.Create("/units", "", 0, zkPermAll); err != nil {
134
if _, err := zk.Create("/relations", "", 0, zkPermAll); err != nil {
137
// TODO Create node for bootstrap machine.
139
// TODO Setup default global settings information.
141
// Finally creation of /initialized as marker.
142
if _, err := zk.Create("/initialized", "", 0, zkPermAll); err != nil {