Revision 827f753e lib/bootstrap.py
b/lib/bootstrap.py | ||
---|---|---|
227 | 227 |
mac_prefix, vg_name, def_bridge) |
228 | 228 |
|
229 | 229 |
ssh.WriteKnownHostsFile(cfg, ss, constants.SSH_KNOWN_HOSTS_FILE) |
230 |
|
|
231 |
def SetupNodeDaemon(node): |
|
232 |
"""Add a node to the cluster. |
|
233 |
|
|
234 |
This function must be called before the actual opcode, and will ssh to the |
|
235 |
remote node, copy the needed files, and start ganeti-noded, allowing the master |
|
236 |
to do the rest via normal rpc calls. |
|
237 |
|
|
238 |
Args: |
|
239 |
node: fully qualified domain name for the new node |
|
240 |
|
|
241 |
""" |
|
242 |
ss = ssconf.SimpleStore() |
|
243 |
sshrunner = ssh.SshRunner(ss) |
|
244 |
gntpass = ss.GetNodeDaemonPassword() |
|
245 |
if not re.match('^[a-zA-Z0-9.]{1,64}$', gntpass): |
|
246 |
raise errors.OpExecError("ganeti password corruption detected") |
|
247 |
f = open(constants.SSL_CERT_FILE) |
|
248 |
try: |
|
249 |
gntpem = f.read(8192) |
|
250 |
finally: |
|
251 |
f.close() |
|
252 |
# in the base64 pem encoding, neither '!' nor '.' are valid chars, |
|
253 |
# so we use this to detect an invalid certificate; as long as the |
|
254 |
# cert doesn't contain this, the here-document will be correctly |
|
255 |
# parsed by the shell sequence below |
|
256 |
if re.search('^!EOF\.', gntpem, re.MULTILINE): |
|
257 |
raise errors.OpExecError("invalid PEM encoding in the SSL certificate") |
|
258 |
if not gntpem.endswith("\n"): |
|
259 |
raise errors.OpExecError("PEM must end with newline") |
|
260 |
|
|
261 |
# set up inter-node password and certificate and restarts the node daemon |
|
262 |
# and then connect with ssh to set password and start ganeti-noded |
|
263 |
# note that all the below variables are sanitized at this point, |
|
264 |
# either by being constants or by the checks above |
|
265 |
mycommand = ("umask 077 && " |
|
266 |
"echo '%s' > '%s' && " |
|
267 |
"cat > '%s' << '!EOF.' && \n" |
|
268 |
"%s!EOF.\n%s restart" % |
|
269 |
(gntpass, ss.KeyToFilename(ss.SS_NODED_PASS), |
|
270 |
constants.SSL_CERT_FILE, gntpem, |
|
271 |
constants.NODE_INITD_SCRIPT)) |
|
272 |
|
|
273 |
result = sshrunner.Run(node, 'root', mycommand, batch=False, ask_key=True) |
|
274 |
if result.failed: |
|
275 |
raise errors.OpExecError("Remote command on node %s, error: %s," |
|
276 |
" output: %s" % |
|
277 |
(node, result.fail_reason, result.output)) |
|
278 |
|
|
279 |
return 0 |
|
280 |
|
Also available in: Unified diff