Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 // launchpad.net/juju/state | 1 // launchpad.net/juju/state |
2 // | 2 // |
3 // Copyright (c) 2011-2012 Canonical Ltd. | 3 // Copyright (c) 2011-2012 Canonical Ltd. |
4 | 4 |
5 // The state package enables reading, observing, and changing | 5 // The state package enables reading, observing, and changing |
6 // the state stored in ZooKeeper of a whole environment | 6 // the state stored in ZooKeeper of a whole environment |
7 // managed by juju. | 7 // managed by juju. |
8 package state | 8 package state |
9 | 9 |
10 import ( | 10 import ( |
11 "fmt" | 11 "fmt" |
12 "launchpad.net/goyaml" | 12 "launchpad.net/goyaml" |
13 "launchpad.net/gozk/zookeeper" | 13 "launchpad.net/gozk/zookeeper" |
14 "launchpad.net/juju/go/charm" | 14 "launchpad.net/juju/go/charm" |
15 "net/url" | |
15 "strings" | 16 "strings" |
16 ) | 17 ) |
17 | 18 |
18 // State represents the state of an environment | 19 // State represents the state of an environment |
19 // managed by juju. | 20 // managed by juju. |
20 type State struct { | 21 type State struct { |
21 zk *zookeeper.Conn | 22 zk *zookeeper.Conn |
22 } | 23 } |
23 | 24 |
24 // Add machine creates a new machine. | 25 // AddMachine creates a new machine state. |
25 func (s *State) AddMachine() (*Machine, error) { | 26 func (s *State) AddMachine() (*Machine, error) { |
26 path, err := s.zk.Create("/machines/machine-", "", zookeeper.SEQUENCE, z kPermAll) | 27 path, err := s.zk.Create("/machines/machine-", "", zookeeper.SEQUENCE, z kPermAll) |
27 if err != nil { | 28 if err != nil { |
28 return nil, err | 29 return nil, err |
29 } | 30 } |
30 key := strings.Split(path, "/")[2] | 31 key := strings.Split(path, "/")[2] |
31 addMachine := func(t *topology) error { | 32 addMachine := func(t *topology) error { |
32 return t.AddMachine(key) | 33 return t.AddMachine(key) |
33 } | 34 } |
34 if err = retryTopologyChange(s.zk, addMachine); err != nil { | 35 if err = retryTopologyChange(s.zk, addMachine); err != nil { |
35 return nil, err | 36 return nil, err |
36 } | 37 } |
37 return &Machine{s.zk, key}, nil | 38 return &Machine{s.zk, key}, nil |
38 } | 39 } |
39 | 40 |
40 // AddCharm registers metadata about the provided Charm. | 41 // AddCharm adds the ch charm with curl to the state. |
niemeyer
2012/02/23 14:57:46
Please improve this comment.
TheMue
2012/02/24 10:38:38
Done.
| |
41 func (s *State) AddCharm(charmURL *charm.URL, ch charm.Charm, url string) (*Char m, error) { | 42 // bundleUrl must be set to a URL where the bundle for ch |
niemeyer
2012/02/23 14:57:46
(ch charm.Charm, curl *charm.URL, bundleUrl string
TheMue
2012/02/24 10:38:38
Done.
niemeyer
2012/02/27 15:58:10
Half Done. Please fix the bundle URL argument too.
| |
43 // may be downloaded from. | |
44 // On success the newly added charm state is returned. | |
45 func (s *State) AddCharm(ch charm.Charm, curl *charm.URL, bundleURL *url.URL) (* Charm, error) { | |
42 data := &charmData{ | 46 data := &charmData{ |
43 » » Meta: ch.Meta(), | 47 » » Meta: ch.Meta(), |
44 » » Config: ch.Config(), | 48 » » Config: ch.Config(), |
45 » » URL: url, | 49 » » BundleURL: bundleURL.String(), |
46 } | 50 } |
47 yaml, err := goyaml.Marshal(data) | 51 yaml, err := goyaml.Marshal(data) |
48 if err != nil { | 52 if err != nil { |
49 return nil, err | 53 return nil, err |
50 } | 54 } |
51 » _, err = s.zk.Create(charmPath(charmURL), string(yaml), 0, zkPermAll) | 55 » path, err := charmPath(curl) |
52 » if err != nil { | 56 » if err != nil { |
53 » » return nil, err | 57 » » return nil, err |
54 » } | 58 » } |
55 » return newCharm(s.zk, charmURL, data) | 59 » _, err = s.zk.Create(path, string(yaml), 0, zkPermAll) |
60 » if err != nil { | |
61 » » return nil, err | |
62 » } | |
63 » return newCharm(s, curl, data) | |
56 } | 64 } |
57 | 65 |
58 // Charm returns a charm by the given id. | 66 // Charm returns a charm by the given id. |
59 func (s *State) Charm(charmURL *charm.URL) (*Charm, error) { | 67 func (s *State) Charm(curl *charm.URL) (*Charm, error) { |
niemeyer
2012/02/23 14:57:46
s/charmURL/curl/
TheMue
2012/02/24 10:38:38
Done.
| |
60 » return readCharm(s.zk, charmURL) | 68 » path, err := charmPath(curl) |
niemeyer
2012/02/23 14:57:46
We shouldn't need this helper function, unless the
TheMue
2012/02/24 10:38:38
Done.
| |
61 } | 69 » if err != nil { |
62 | 70 » » return nil, err |
63 // AddService creates a new service with the given unique name | 71 » } |
72 » yaml, _, err := s.zk.Get(path) | |
73 » if err == zookeeper.ZNONODE { | |
74 » » return nil, fmt.Errorf("charm not found: %q", curl) | |
75 » } | |
76 » if err != nil { | |
77 » » return nil, err | |
78 » } | |
79 » data := &charmData{} | |
80 » if err := goyaml.Unmarshal([]byte(yaml), data); err != nil { | |
81 » » return nil, err | |
82 » } | |
83 » return newCharm(s, curl, data) | |
84 } | |
85 | |
86 // AddService creates a new service state with the given unique name | |
64 // and the charm state. | 87 // and the charm state. |
65 func (s *State) AddService(name string, ch *Charm) (*Service, error) { | 88 func (s *State) AddService(name string, ch *Charm) (*Service, error) { |
66 details := map[string]interface{}{"charm": ch.URL().String()} | 89 details := map[string]interface{}{"charm": ch.URL().String()} |
67 yaml, err := goyaml.Marshal(details) | 90 yaml, err := goyaml.Marshal(details) |
68 if err != nil { | 91 if err != nil { |
69 return nil, err | 92 return nil, err |
70 } | 93 } |
71 path, err := s.zk.Create("/services/service-", string(yaml), zookeeper.S EQUENCE, zkPermAll) | 94 path, err := s.zk.Create("/services/service-", string(yaml), zookeeper.S EQUENCE, zkPermAll) |
72 if err != nil { | 95 if err != nil { |
73 return nil, err | 96 return nil, err |
74 } | 97 } |
75 key := strings.Split(path, "/")[2] | 98 key := strings.Split(path, "/")[2] |
76 » service := &Service{s.zk, key, name} | 99 » service := &Service{s, key, name} |
77 // Create an empty configuration node. | 100 // Create an empty configuration node. |
78 _, err = createConfigNode(s.zk, service.zkConfigPath(), map[string]inter face{}{}) | 101 _, err = createConfigNode(s.zk, service.zkConfigPath(), map[string]inter face{}{}) |
79 if err != nil { | 102 if err != nil { |
80 return nil, err | 103 return nil, err |
81 } | 104 } |
82 addService := func(t *topology) error { | 105 addService := func(t *topology) error { |
83 if _, err := t.ServiceKey(name); err == nil { | 106 if _, err := t.ServiceKey(name); err == nil { |
84 // No error, so service name already in use. | 107 // No error, so service name already in use. |
85 return fmt.Errorf("service name %q is already in use", n ame) | 108 return fmt.Errorf("service name %q is already in use", n ame) |
86 } | 109 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
125 // Service returns a service state by name. | 148 // Service returns a service state by name. |
126 func (s *State) Service(name string) (*Service, error) { | 149 func (s *State) Service(name string) (*Service, error) { |
127 topology, err := readTopology(s.zk) | 150 topology, err := readTopology(s.zk) |
128 if err != nil { | 151 if err != nil { |
129 return nil, err | 152 return nil, err |
130 } | 153 } |
131 key, err := topology.ServiceKey(name) | 154 key, err := topology.ServiceKey(name) |
132 if err != nil { | 155 if err != nil { |
133 return nil, err | 156 return nil, err |
134 } | 157 } |
135 » return &Service{s.zk, key, name}, nil | 158 » return &Service{s, key, name}, nil |
136 } | 159 } |
137 | 160 |
138 // AllServices returns all deployed services in the environment. | 161 // AllServices returns all deployed services in the environment. |
139 func (s *State) AllServices() ([]*Service, error) { | 162 func (s *State) AllServices() ([]*Service, error) { |
140 topology, err := readTopology(s.zk) | 163 topology, err := readTopology(s.zk) |
141 if err != nil { | 164 if err != nil { |
142 return nil, err | 165 return nil, err |
143 } | 166 } |
144 services := []*Service{} | 167 services := []*Service{} |
145 for _, key := range topology.ServiceKeys() { | 168 for _, key := range topology.ServiceKeys() { |
146 name, err := topology.ServiceName(key) | 169 name, err := topology.ServiceName(key) |
147 if err != nil { | 170 if err != nil { |
148 return nil, err | 171 return nil, err |
149 } | 172 } |
150 » » services = append(services, &Service{s.zk, key, name}) | 173 » » services = append(services, &Service{s, key, name}) |
151 } | 174 } |
152 return services, nil | 175 return services, nil |
153 } | 176 } |
154 | 177 |
155 // Unit returns a unit by name. | 178 // Unit returns a unit by name. |
156 func (s *State) Unit(name string) (*Unit, error) { | 179 func (s *State) Unit(name string) (*Unit, error) { |
157 serviceName, _, err := parseUnitName(name) | 180 serviceName, _, err := parseUnitName(name) |
158 if err != nil { | 181 if err != nil { |
159 return nil, err | 182 return nil, err |
160 } | 183 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
193 // TODO Create node for bootstrap machine. | 216 // TODO Create node for bootstrap machine. |
194 | 217 |
195 // TODO Setup default global settings information. | 218 // TODO Setup default global settings information. |
196 | 219 |
197 // Finally creation of /initialized as marker. | 220 // Finally creation of /initialized as marker. |
198 if _, err := s.zk.Create("/initialized", "", 0, zkPermAll); err != nil { | 221 if _, err := s.zk.Create("/initialized", "", 0, zkPermAll); err != nil { |
199 return err | 222 return err |
200 } | 223 } |
201 return nil | 224 return nil |
202 } | 225 } |
LEFT | RIGHT |