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 // AddMachine creates a new machine state. | 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 creates a new charm state based on a charm, its URL | 41 // AddCharm adds the ch charm with curl to the state. |
41 // and its bundle URL. | 42 // bundleUrl must be set to a URL where the bundle for ch |
42 func (s *State) AddCharm(ch charm.Charm, curl *charm.URL, url string) (*Charm, e
rror) { | 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) { |
43 data := &charmData{ | 46 data := &charmData{ |
44 Meta: ch.Meta(), | 47 Meta: ch.Meta(), |
45 Config: ch.Config(), | 48 Config: ch.Config(), |
46 » » BundleURL: url, | 49 » » BundleURL: bundleURL.String(), |
47 } | 50 } |
48 yaml, err := goyaml.Marshal(data) | 51 yaml, err := goyaml.Marshal(data) |
49 if err != nil { | 52 if err != nil { |
50 return nil, err | 53 return nil, err |
51 } | 54 } |
52 path, err := charmPath(curl) | 55 path, err := charmPath(curl) |
53 if err != nil { | 56 if err != nil { |
54 return nil, err | 57 return nil, err |
55 } | 58 } |
56 _, err = s.zk.Create(path, string(yaml), 0, zkPermAll) | 59 _, err = s.zk.Create(path, string(yaml), 0, zkPermAll) |
57 if err != nil { | 60 if err != nil { |
58 return nil, err | 61 return nil, err |
59 } | 62 } |
60 » return newCharm(s, curl, data), nil | 63 » return newCharm(s, curl, data) |
61 } | 64 } |
62 | 65 |
63 // Charm returns a charm by the given id. | 66 // Charm returns a charm by the given id. |
64 func (s *State) Charm(curl *charm.URL) (*Charm, error) { | 67 func (s *State) Charm(curl *charm.URL) (*Charm, error) { |
65 path, err := charmPath(curl) | 68 path, err := charmPath(curl) |
66 if err != nil { | 69 if err != nil { |
67 return nil, err | 70 return nil, err |
68 } | 71 } |
69 yaml, _, err := s.zk.Get(path) | 72 yaml, _, err := s.zk.Get(path) |
70 if err == zookeeper.ZNONODE { | 73 if err == zookeeper.ZNONODE { |
71 return nil, fmt.Errorf("charm not found: %q", curl) | 74 return nil, fmt.Errorf("charm not found: %q", curl) |
72 } | 75 } |
73 if err != nil { | 76 if err != nil { |
74 return nil, err | 77 return nil, err |
75 } | 78 } |
76 data := &charmData{} | 79 data := &charmData{} |
77 if err := goyaml.Unmarshal([]byte(yaml), data); err != nil { | 80 if err := goyaml.Unmarshal([]byte(yaml), data); err != nil { |
78 return nil, err | 81 return nil, err |
79 } | 82 } |
80 » return newCharm(s, curl, data), nil | 83 » return newCharm(s, curl, data) |
81 } | 84 } |
82 | 85 |
83 // AddService creates a new service state with the given unique name | 86 // AddService creates a new service state with the given unique name |
84 // and the charm state. | 87 // and the charm state. |
85 func (s *State) AddService(name string, ch *Charm) (*Service, error) { | 88 func (s *State) AddService(name string, ch *Charm) (*Service, error) { |
86 details := map[string]interface{}{"charm": ch.URL().String()} | 89 details := map[string]interface{}{"charm": ch.URL().String()} |
87 yaml, err := goyaml.Marshal(details) | 90 yaml, err := goyaml.Marshal(details) |
88 if err != nil { | 91 if err != nil { |
89 return nil, err | 92 return nil, err |
90 } | 93 } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 // TODO Create node for bootstrap machine. | 216 // TODO Create node for bootstrap machine. |
214 | 217 |
215 // TODO Setup default global settings information. | 218 // TODO Setup default global settings information. |
216 | 219 |
217 // Finally creation of /initialized as marker. | 220 // Finally creation of /initialized as marker. |
218 if _, err := s.zk.Create("/initialized", "", 0, zkPermAll); err != nil { | 221 if _, err := s.zk.Create("/initialized", "", 0, zkPermAll); err != nil { |
219 return err | 222 return err |
220 } | 223 } |
221 return nil | 224 return nil |
222 } | 225 } |
LEFT | RIGHT |