~fwereade/pyjuju/go-fix-deploy-doc

« back to all changes in this revision

Viewing changes to state/state.go

  • Committer: William Reade
  • Date: 2012-01-31 12:50:10 UTC
  • mfrom: (45 go)
  • mto: This revision was merged to the branch mainline in revision 47.
  • Revision ID: fwereade@gmail.com-20120131125010-k4jry0q3wocc3mhk
merge parent

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
package state
9
9
 
10
10
import (
 
11
        "fmt"
 
12
        "launchpad.net/goyaml"
11
13
        "launchpad.net/gozk/zookeeper"
 
14
        "strings"
12
15
)
13
16
 
14
17
// State represents the state of an environment
15
18
// managed by juju.
16
19
type State struct {
17
 
        zk       *zookeeper.Conn
18
 
        topology *topology
 
20
        zk *zookeeper.Conn
19
21
}
20
22
 
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)
25
 
        if err != nil {
26
 
                return nil, err
27
 
        }
28
 
        return &State{zk, t}, nil
 
26
        return &State{zk}, nil
 
27
}
 
28
 
 
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)
 
34
        if err != nil {
 
35
                return nil, err
 
36
        }
 
37
        path, err := s.zk.Create("/services/service-", string(yaml), zookeeper.SEQUENCE, zkPermAll)
 
38
        if err != nil {
 
39
                return nil, err
 
40
        }
 
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{}{})
 
45
        if err != nil {
 
46
                return nil, err
 
47
        }
 
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)
 
52
                }
 
53
                return t.AddService(key, name)
 
54
        }
 
55
        if err = retryTopologyChange(s.zk, addService); err != nil {
 
56
                return nil, err
 
57
        }
 
58
        return service, nil
 
59
}
 
60
 
 
61
// RemoveService removes a service from the state. It will
 
62
// also remove all its units and break any of its existing
 
63
// relations.
 
64
func (s *State) RemoveService(svc *Service) error {
 
65
        // TODO Remove relations first, to prevent spurious hook execution.
 
66
 
 
67
        // Remove the units.
 
68
        units, err := svc.AllUnits()
 
69
        if err != nil {
 
70
                return err
 
71
        }
 
72
        for _, unit := range units {
 
73
                if err = svc.RemoveUnit(unit); err != nil {
 
74
                        return err
 
75
                }
 
76
        }
 
77
        // Remove the service from the topology.
 
78
        removeService := func(t *topology) error {
 
79
                if !t.HasService(svc.key) {
 
80
                        return stateChanged
 
81
                }
 
82
                t.RemoveService(svc.key)
 
83
                return nil
 
84
        }
 
85
        if err = retryTopologyChange(s.zk, removeService); err != nil {
 
86
                return err
 
87
        }
 
88
        return zkRemoveTree(s.zk, svc.zkPath())
29
89
}
30
90
 
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)
 
94
        if err != nil {
 
95
                return nil, err
 
96
        }
 
97
        key, err := topology.ServiceKey(name)
34
98
        if err != nil {
35
99
                return nil, err
36
100
        }
49
113
        }
50
114
        return service.Unit(name)
51
115
}
 
116
 
 
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 {
 
121
                // Create new nodes.
 
122
                if _, err := zk.Create("/charms", "", 0, zkPermAll); err != nil {
 
123
                        return err
 
124
                }
 
125
                if _, err := zk.Create("/services", "", 0, zkPermAll); err != nil {
 
126
                        return err
 
127
                }
 
128
                if _, err := zk.Create("/machines", "", 0, zkPermAll); err != nil {
 
129
                        return err
 
130
                }
 
131
                if _, err := zk.Create("/units", "", 0, zkPermAll); err != nil {
 
132
                        return err
 
133
                }
 
134
                if _, err := zk.Create("/relations", "", 0, zkPermAll); err != nil {
 
135
                        return err
 
136
                }
 
137
                // TODO Create node for bootstrap machine.
 
138
 
 
139
                // TODO Setup default global settings information.
 
140
 
 
141
                // Finally creation of /initialized as marker.
 
142
                if _, err := zk.Create("/initialized", "", 0, zkPermAll); err != nil {
 
143
                        return err
 
144
                }
 
145
        }
 
146
        if err != nil {
 
147
                return err
 
148
        }
 
149
        return nil
 
150
}