Revision 82122173
b/lib/backend.py | ||
---|---|---|
122 | 122 |
|
123 | 123 |
utils.RunCmd(["/etc/init.d/ssh", "restart"]) |
124 | 124 |
|
125 |
utils.RemoveFile("/root/.ssh/known_hosts") |
|
126 | 125 |
return True |
127 | 126 |
|
128 | 127 |
|
... | ... | |
790 | 789 |
return False |
791 | 790 |
|
792 | 791 |
allowed_files = [constants.CLUSTER_CONF_FILE, "/etc/hosts", |
793 |
"/etc/ssh/ssh_known_hosts"]
|
|
792 |
constants.SSH_KNOWN_HOSTS_FILE]
|
|
794 | 793 |
allowed_files.extend(ssconf.SimpleStore().GetFileList()) |
795 | 794 |
if file_name not in allowed_files: |
796 | 795 |
logger.Error("Filename passed to UploadFile not in allowed" |
b/lib/cmdlib.py | ||
---|---|---|
350 | 350 |
pubkey - the public key of the cluster |
351 | 351 |
|
352 | 352 |
""" |
353 |
if os.path.exists('/etc/ssh/ssh_known_hosts'):
|
|
354 |
f = open('/etc/ssh/ssh_known_hosts', 'r+')
|
|
353 |
if os.path.exists(constants.SSH_KNOWN_HOSTS_FILE):
|
|
354 |
f = open(constants.SSH_KNOWN_HOSTS_FILE, 'r+')
|
|
355 | 355 |
else: |
356 |
f = open('/etc/ssh/ssh_known_hosts', 'w+')
|
|
356 |
f = open(constants.SSH_KNOWN_HOSTS_FILE, 'w+')
|
|
357 | 357 |
|
358 | 358 |
inthere = False |
359 | 359 |
|
... | ... | |
405 | 405 |
save_lines = save_lines + add_lines |
406 | 406 |
|
407 | 407 |
# Write a new file and replace old. |
408 |
fd, tmpname = tempfile.mkstemp('tmp', 'ssh_known_hosts_', '/etc/ssh') |
|
408 |
fd, tmpname = tempfile.mkstemp('.tmp', 'known_hosts.', |
|
409 |
constants.DATA_DIR) |
|
409 | 410 |
newfile = os.fdopen(fd, 'w') |
410 |
newfile.write(''.join(save_lines)) |
|
411 |
newfile.close() |
|
411 |
try: |
|
412 |
newfile.write(''.join(save_lines)) |
|
413 |
finally: |
|
414 |
newfile.close() |
|
412 | 415 |
logger.Debug("Wrote new known_hosts.") |
413 |
os.rename(tmpname, '/etc/ssh/ssh_known_hosts')
|
|
416 |
os.rename(tmpname, constants.SSH_KNOWN_HOSTS_FILE)
|
|
414 | 417 |
|
415 | 418 |
elif add_lines: |
416 | 419 |
# Simply appending a new line will do the trick. |
... | ... | |
448 | 451 |
node: the name of this host as a fqdn |
449 | 452 |
|
450 | 453 |
""" |
451 |
utils.RemoveFile('/root/.ssh/known_hosts') |
|
452 |
|
|
453 | 454 |
if os.path.exists('/root/.ssh/id_dsa'): |
454 | 455 |
utils.CreateBackup('/root/.ssh/id_dsa') |
455 | 456 |
if os.path.exists('/root/.ssh/id_dsa.pub'): |
... | ... | |
1365 | 1366 |
raise errors.OpExecError("PEM must end with newline") |
1366 | 1367 |
logger.Info("copy cluster pass to %s and starting the node daemon" % node) |
1367 | 1368 |
|
1368 |
# remove first the root's known_hosts file |
|
1369 |
utils.RemoveFile("/root/.ssh/known_hosts") |
|
1370 | 1369 |
# and then connect with ssh to set password and start ganeti-noded |
1371 | 1370 |
# note that all the below variables are sanitized at this point, |
1372 | 1371 |
# either by being constants or by the checks above |
... | ... | |
1442 | 1441 |
dist_nodes.remove(myself.name) |
1443 | 1442 |
|
1444 | 1443 |
logger.Debug("Copying hosts and known_hosts to all nodes") |
1445 |
for fname in ("/etc/hosts", "/etc/ssh/ssh_known_hosts"):
|
|
1444 |
for fname in ("/etc/hosts", constants.SSH_KNOWN_HOSTS_FILE):
|
|
1446 | 1445 |
result = rpc.call_upload_file(dist_nodes, fname) |
1447 | 1446 |
for to_node in dist_nodes: |
1448 | 1447 |
if not result[to_node]: |
... | ... | |
2798 | 2797 |
|
2799 | 2798 |
hyper = hypervisor.GetHypervisor() |
2800 | 2799 |
console_cmd = hyper.GetShellCommandForConsole(instance.name) |
2801 |
return node, console_cmd |
|
2800 |
# build ssh cmdline |
|
2801 |
argv = ["ssh", "-q", "-t"] |
|
2802 |
argv.extend(ssh.KNOWN_HOSTS_OPTS) |
|
2803 |
argv.extend(ssh.BATCH_MODE_OPTS) |
|
2804 |
argv.append(node) |
|
2805 |
argv.append(console_cmd) |
|
2806 |
return "ssh", argv |
|
2802 | 2807 |
|
2803 | 2808 |
|
2804 | 2809 |
class LUAddMDDRBDComponent(LogicalUnit): |
b/lib/constants.py | ||
---|---|---|
34 | 34 |
CLUSTER_CONF_FILE = DATA_DIR + "/config.data" |
35 | 35 |
SSL_CERT_FILE = DATA_DIR + "/server.pem" |
36 | 36 |
WATCHER_STATEFILE = DATA_DIR + "/restart_state" |
37 |
SSH_KNOWN_HOSTS_FILE = DATA_DIR + "/known_hosts" |
|
37 | 38 |
|
38 | 39 |
NODE_INITD_SCRIPT = "/etc/init.d/ganeti" |
39 | 40 |
DEFAULT_NODED_PORT = 1811 |
b/lib/ssh.py | ||
---|---|---|
29 | 29 |
from ganeti import logger |
30 | 30 |
from ganeti import utils |
31 | 31 |
from ganeti import errors |
32 |
from ganeti import constants |
|
33 |
|
|
34 |
|
|
35 |
__all__ = ["SSHCall", "CopyFileToNode", "VerifyNodeHostname", |
|
36 |
"KNOWN_HOSTS_OPTS", "BATCH_MODE_OPTS", "ASK_KEY_OPTS"] |
|
37 |
|
|
38 |
|
|
39 |
KNOWN_HOSTS_OPTS = [ |
|
40 |
"-oGlobalKnownHostsFile=%s" % constants.SSH_KNOWN_HOSTS_FILE, |
|
41 |
"-oUserKnownHostsFile=/dev/null", |
|
42 |
] |
|
43 |
|
|
44 |
# Note: BATCH_MODE conflicts with ASK_KEY |
|
45 |
BATCH_MODE_OPTS = [ |
|
46 |
"-oEscapeChar=none", |
|
47 |
"-oBatchMode=yes", |
|
48 |
"-oStrictHostKeyChecking=yes", |
|
49 |
] |
|
50 |
|
|
51 |
ASK_KEY_OPTS = [ |
|
52 |
"-oStrictHostKeyChecking=ask", |
|
53 |
"-oEscapeChar=none", |
|
54 |
"-oHashKnownHosts=no", |
|
55 |
] |
|
56 |
|
|
32 | 57 |
|
33 | 58 |
def SSHCall(hostname, user, command, batch=True, ask_key=False): |
34 | 59 |
"""Execute a command on a remote node. |
... | ... | |
40 | 65 |
hostname: the target host, string |
41 | 66 |
user: user to auth as |
42 | 67 |
command: the command |
68 |
batch: if true, ssh will run in batch mode with no prompting |
|
69 |
ask_key: if true, ssh will run with StrictHostKeyChecking=ask, so that |
|
70 |
we can connect to an unknown host (not valid in batch mode) |
|
43 | 71 |
|
44 | 72 |
Returns: |
45 | 73 |
`utils.RunResult` as for `utils.RunCmd()` |
46 | 74 |
|
47 | 75 |
""" |
48 |
argv = ["ssh", "-q", "-oEscapeChar=none"] |
|
76 |
argv = ["ssh", "-q"] |
|
77 |
argv.extend(KNOWN_HOSTS_OPTS) |
|
49 | 78 |
if batch: |
50 |
argv.append("-oBatchMode=yes") |
|
51 | 79 |
# if we are in batch mode, we can't ask the key |
52 | 80 |
if ask_key: |
53 | 81 |
raise errors.ProgrammerError("SSH call requested conflicting options") |
54 |
if ask_key: |
|
55 |
argv.append("-oStrictHostKeyChecking=ask") |
|
56 |
argv.append("-oHashKnownHosts=no") |
|
57 |
else: |
|
58 |
argv.append("-oStrictHostKeyChecking=yes") |
|
82 |
argv.extend(BATCH_MODE_OPTS) |
|
83 |
elif ask_key: |
|
84 |
argv.extend(ASK_KEY_OPTS) |
|
59 | 85 |
argv.extend(["%s@%s" % (user, hostname), command]) |
60 | 86 |
return utils.RunCmd(argv) |
61 | 87 |
|
... | ... | |
79 | 105 |
logger.Error("file %s must be an absolute path" % (filename)) |
80 | 106 |
return False |
81 | 107 |
|
82 |
command = ["scp", "-q", "-p", "-oStrictHostKeyChecking=yes", |
|
83 |
"-oBatchMode=yes", filename, "%s:%s" % (node, filename)] |
|
108 |
command = ["scp", "-q", "-p"] |
|
109 |
command.extend(KNOWN_HOSTS_OPTS) |
|
110 |
command.extend(BATCH_MODE_OPTS) |
|
111 |
command.append(filename) |
|
112 |
command.append("%s:%s" % (node, filename)) |
|
84 | 113 |
|
85 | 114 |
result = utils.RunCmd(command) |
86 | 115 |
|
b/scripts/gnt-instance | ||
---|---|---|
290 | 290 |
instance_name = args[0] |
291 | 291 |
|
292 | 292 |
op = opcodes.OpConnectConsole(instance_name=instance_name) |
293 |
node, console_cmd = SubmitOpCode(op)
|
|
293 |
cmd, argv = SubmitOpCode(op)
|
|
294 | 294 |
# drop lock and exec so other commands can run while we have console |
295 | 295 |
utils.Unlock("cmd") |
296 | 296 |
try: |
297 |
os.execv("/usr/bin/ssh", ["ssh", "-qt", node, console_cmd])
|
|
297 |
os.execvp(cmd, argv)
|
|
298 | 298 |
finally: |
299 |
sys.stderr.write("Can't run console command %s on node %s" %
|
|
300 |
(console_cmd, node))
|
|
299 |
sys.stderr.write("Can't run console command %s with arguments:\n'%s'" %
|
|
300 |
(cmd, " ".join(argv)))
|
|
301 | 301 |
os._exit(1) |
302 | 302 |
|
303 | 303 |
|
Also available in: Unified diff