LEFT | RIGHT |
1 package cloudinit | 1 package cloudinit |
2 | 2 |
3 import ( | 3 import ( |
4 "encoding/base64" | 4 "encoding/base64" |
5 "fmt" | 5 "fmt" |
6 "launchpad.net/goyaml" | 6 "launchpad.net/goyaml" |
7 "launchpad.net/juju-core/cloudinit" | 7 "launchpad.net/juju-core/cloudinit" |
8 "launchpad.net/juju-core/environs" | 8 "launchpad.net/juju-core/environs" |
9 "launchpad.net/juju-core/environs/config" | 9 "launchpad.net/juju-core/environs/config" |
10 "launchpad.net/juju-core/log" | 10 "launchpad.net/juju-core/log" |
(...skipping 28 matching lines...) Expand all Loading... |
39 ProviderType string | 39 ProviderType string |
40 | 40 |
41 // StateInfo holds the means for the new instance to communicate with th
e | 41 // StateInfo holds the means for the new instance to communicate with th
e |
42 // juju state. Unless the new machine is running zookeeper (ZooKeeper is | 42 // juju state. Unless the new machine is running zookeeper (ZooKeeper is |
43 // set), there must be at least one zookeeper address supplied. | 43 // set), there must be at least one zookeeper address supplied. |
44 StateInfo *state.Info | 44 StateInfo *state.Info |
45 | 45 |
46 // Tools is juju tools to be used on the new machine. | 46 // Tools is juju tools to be used on the new machine. |
47 Tools *state.Tools | 47 Tools *state.Tools |
48 | 48 |
49 » // VarDir holds the directory that juju state will be put in the new | 49 » // DataDir holds the directory that juju state will be put in the new |
50 // machine. | 50 // machine. |
51 » VarDir string | 51 » DataDir string |
52 | 52 |
53 // MachineId identifies the new machine. It must be non-negative. | 53 // MachineId identifies the new machine. It must be non-negative. |
54 MachineId int | 54 MachineId int |
55 | 55 |
56 // AuthorizedKeys specifies the keys that are allowed to | 56 // AuthorizedKeys specifies the keys that are allowed to |
57 // connect to the machine (see cloudinit.SSHAddAuthorizedKeys) | 57 // connect to the machine (see cloudinit.SSHAddAuthorizedKeys) |
58 // If no keys are supplied, there can be no ssh access to the node. | 58 // If no keys are supplied, there can be no ssh access to the node. |
59 // On a bootstrap machine, that is fatal. On other | 59 // On a bootstrap machine, that is fatal. On other |
60 // machines it will mean that the ssh, scp and debug-hooks | 60 // machines it will mean that the ssh, scp and debug-hooks |
61 // commands cannot work. | 61 // commands cannot work. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 // TODO(dfc) remove these once we cut over to mstate | 98 // TODO(dfc) remove these once we cut over to mstate |
99 c.AddPackage("default-jre-headless") | 99 c.AddPackage("default-jre-headless") |
100 c.AddPackage("zookeeper") | 100 c.AddPackage("zookeeper") |
101 c.AddPackage("zookeeperd") | 101 c.AddPackage("zookeeperd") |
102 | 102 |
103 // mongodb | 103 // mongodb |
104 c.AddPackage("mongodb-server") | 104 c.AddPackage("mongodb-server") |
105 } | 105 } |
106 | 106 |
107 addScripts(c, | 107 addScripts(c, |
108 » » fmt.Sprintf("sudo mkdir -p %s", cfg.VarDir), | 108 » » fmt.Sprintf("sudo mkdir -p %s", cfg.DataDir), |
109 "sudo mkdir -p /var/log/juju") | 109 "sudo mkdir -p /var/log/juju") |
110 | 110 |
111 // Make a directory for the tools to live in, then fetch the | 111 // Make a directory for the tools to live in, then fetch the |
112 // tools and unarchive them into it. | 112 // tools and unarchive them into it. |
113 addScripts(c, | 113 addScripts(c, |
114 "bin="+shquote(cfg.jujuTools()), | 114 "bin="+shquote(cfg.jujuTools()), |
115 "mkdir -p $bin", | 115 "mkdir -p $bin", |
116 fmt.Sprintf("wget -O - %s | tar xz -C $bin", shquote(cfg.Tools.U
RL)), | 116 fmt.Sprintf("wget -O - %s | tar xz -C $bin", shquote(cfg.Tools.U
RL)), |
117 fmt.Sprintf("echo -n %s > $bin/downloaded-url.txt", shquote(cfg.
Tools.URL)), | 117 fmt.Sprintf("echo -n %s > $bin/downloaded-url.txt", shquote(cfg.
Tools.URL)), |
118 ) | 118 ) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 c.SetAptUpgrade(true) | 152 c.SetAptUpgrade(true) |
153 c.SetAptUpdate(true) | 153 c.SetAptUpdate(true) |
154 c.SetOutput(cloudinit.OutAll, "| tee -a /var/log/cloud-init-output.log",
"") | 154 c.SetOutput(cloudinit.OutAll, "| tee -a /var/log/cloud-init-output.log",
"") |
155 return c, nil | 155 return c, nil |
156 } | 156 } |
157 | 157 |
158 func addAgentScript(c *cloudinit.Config, cfg *MachineConfig, name, args string)
error { | 158 func addAgentScript(c *cloudinit.Config, cfg *MachineConfig, name, args string)
error { |
159 // Make the agent run via a symbolic link to the actual tools | 159 // Make the agent run via a symbolic link to the actual tools |
160 // directory, so it can upgrade itself without needing to change | 160 // directory, so it can upgrade itself without needing to change |
161 // the upstart script. | 161 // the upstart script. |
162 » toolsDir := environs.AgentToolsDir(cfg.VarDir, name) | 162 » toolsDir := environs.AgentToolsDir(cfg.DataDir, name) |
163 addScripts(c, fmt.Sprintf("ln -s $bin %s", toolsDir)) | 163 addScripts(c, fmt.Sprintf("ln -s $bin %s", toolsDir)) |
164 svc := upstart.NewService(fmt.Sprintf("jujud-%s", name)) | 164 svc := upstart.NewService(fmt.Sprintf("jujud-%s", name)) |
165 cmd := fmt.Sprintf( | 165 cmd := fmt.Sprintf( |
166 » » "%s/jujud %s --zookeeper-servers '%s' --log-file /var/log/juju/%
s-agent.log %s", | 166 » » "%s/jujud %s"+ |
167 » » toolsDir, name, cfg.zookeeperHostAddrs(), name, args, | 167 » » » " --zookeeper-servers '%s'"+ |
| 168 » » » " --log-file /var/log/juju/%s-agent.log"+ |
| 169 » » » " --data-dir '%s'"+ |
| 170 » » » " %s", |
| 171 » » toolsDir, name, |
| 172 » » cfg.zookeeperHostAddrs(), |
| 173 » » name, |
| 174 » » cfg.DataDir, |
| 175 » » args, |
168 ) | 176 ) |
169 conf := &upstart.Conf{ | 177 conf := &upstart.Conf{ |
170 Service: *svc, | 178 Service: *svc, |
171 Desc: fmt.Sprintf("juju %s agent", name), | 179 Desc: fmt.Sprintf("juju %s agent", name), |
172 Cmd: cmd, | 180 Cmd: cmd, |
173 } | 181 } |
174 cmds, err := conf.InstallCommands() | 182 cmds, err := conf.InstallCommands() |
175 if err != nil { | 183 if err != nil { |
176 return fmt.Errorf("cannot make cloud-init %s agent upstart scrip
t: %v", name, err) | 184 return fmt.Errorf("cannot make cloud-init %s agent upstart scrip
t: %v", name, err) |
177 } | 185 } |
178 addScripts(c, cmds...) | 186 addScripts(c, cmds...) |
179 return nil | 187 return nil |
180 } | 188 } |
181 | 189 |
182 // versionDir converts a tools URL into a name | 190 // versionDir converts a tools URL into a name |
183 // to use as a directory for storing the tools executables in | 191 // to use as a directory for storing the tools executables in |
184 // by using the last element stripped of its extension. | 192 // by using the last element stripped of its extension. |
185 func versionDir(toolsURL string) string { | 193 func versionDir(toolsURL string) string { |
186 name := path.Base(toolsURL) | 194 name := path.Base(toolsURL) |
187 ext := path.Ext(name) | 195 ext := path.Ext(name) |
188 return name[:len(name)-len(ext)] | 196 return name[:len(name)-len(ext)] |
189 } | 197 } |
190 | 198 |
191 func (cfg *MachineConfig) jujuTools() string { | 199 func (cfg *MachineConfig) jujuTools() string { |
192 » return environs.ToolsDir(cfg.VarDir, cfg.Tools.Binary) | 200 » return environs.ToolsDir(cfg.DataDir, cfg.Tools.Binary) |
193 } | 201 } |
194 | 202 |
195 func (cfg *MachineConfig) zookeeperHostAddrs() string { | 203 func (cfg *MachineConfig) zookeeperHostAddrs() string { |
196 var hosts []string | 204 var hosts []string |
197 if cfg.StateServer { | 205 if cfg.StateServer { |
198 hosts = append(hosts, "localhost"+zkPortSuffix) | 206 hosts = append(hosts, "localhost"+zkPortSuffix) |
199 } | 207 } |
200 if cfg.StateInfo != nil { | 208 if cfg.StateInfo != nil { |
201 hosts = append(hosts, cfg.StateInfo.Addrs...) | 209 hosts = append(hosts, cfg.StateInfo.Addrs...) |
202 } | 210 } |
203 return strings.Join(hosts, ",") | 211 return strings.Join(hosts, ",") |
204 } | 212 } |
205 | 213 |
206 // shquote quotes s so that when read by bash, no metacharacters | 214 // shquote quotes s so that when read by bash, no metacharacters |
207 // within s will be interpreted as such. | 215 // within s will be interpreted as such. |
208 func shquote(s string) string { | 216 func shquote(s string) string { |
209 // single-quote becomes single-quote, double-quote, single-quote, double
-quote, single-quote | 217 // single-quote becomes single-quote, double-quote, single-quote, double
-quote, single-quote |
210 return `'` + strings.Replace(s, `'`, `'"'"'`, -1) + `'` | 218 return `'` + strings.Replace(s, `'`, `'"'"'`, -1) + `'` |
211 } | 219 } |
212 | 220 |
213 func verifyConfig(cfg *MachineConfig) error { | 221 func verifyConfig(cfg *MachineConfig) error { |
214 if cfg.MachineId < 0 { | 222 if cfg.MachineId < 0 { |
215 return fmt.Errorf("invalid machine configuration: negative machi
ne id") | 223 return fmt.Errorf("invalid machine configuration: negative machi
ne id") |
216 } | 224 } |
217 if cfg.ProviderType == "" { | 225 if cfg.ProviderType == "" { |
218 return requiresError("provider type") | 226 return requiresError("provider type") |
219 } | 227 } |
220 » if cfg.VarDir == "" { | 228 » if cfg.DataDir == "" { |
221 return requiresError("var directory") | 229 return requiresError("var directory") |
222 } | 230 } |
223 if cfg.Tools == nil { | 231 if cfg.Tools == nil { |
224 return requiresError("tools") | 232 return requiresError("tools") |
225 } | 233 } |
226 if cfg.Tools.URL == "" { | 234 if cfg.Tools.URL == "" { |
227 return requiresError("tools URL") | 235 return requiresError("tools URL") |
228 } | 236 } |
229 if cfg.StateServer { | 237 if cfg.StateServer { |
230 if cfg.InstanceIdAccessor == "" { | 238 if cfg.InstanceIdAccessor == "" { |
231 return requiresError("instance id accessor") | 239 return requiresError("instance id accessor") |
232 } | 240 } |
233 if cfg.Config == nil { | 241 if cfg.Config == nil { |
234 return requiresError("environment configuration") | 242 return requiresError("environment configuration") |
235 } | 243 } |
236 } else { | 244 } else { |
237 if cfg.StateInfo == nil || len(cfg.StateInfo.Addrs) == 0 { | 245 if cfg.StateInfo == nil || len(cfg.StateInfo.Addrs) == 0 { |
238 return requiresError("zookeeper hosts") | 246 return requiresError("zookeeper hosts") |
239 } | 247 } |
240 } | 248 } |
241 return nil | 249 return nil |
242 } | 250 } |
LEFT | RIGHT |