Revision cb91d46e
b/daemons/ganeti-noded | ||
---|---|---|
243 | 243 |
def perspective_version(self, params): |
244 | 244 |
return constants.PROTOCOL_VERSION |
245 | 245 |
|
246 |
def perspective_configfile_list(self, params): |
|
247 |
return backend.ListConfigFiles() |
|
248 |
|
|
249 | 246 |
def perspective_upload_file(self, params): |
250 | 247 |
return backend.UploadFile(*params) |
251 | 248 |
|
b/lib/backend.py | ||
---|---|---|
43 | 43 |
from ganeti import ssconf |
44 | 44 |
|
45 | 45 |
|
46 |
def ListConfigFiles(): |
|
47 |
"""Return a list of the config files present on the local node. |
|
48 |
""" |
|
49 |
|
|
50 |
configfiles = [] |
|
51 |
|
|
52 |
for testfile in constants.MASTER_CONFIGFILES: |
|
53 |
if os.path.exists(testfile): |
|
54 |
configfiles.append(testfile) |
|
55 |
|
|
56 |
for testfile in constants.NODE_CONFIGFILES: |
|
57 |
if os.path.exists(testfile): |
|
58 |
configfiles.append(testfile) |
|
59 |
|
|
60 |
return configfiles |
|
61 |
|
|
62 |
|
|
63 | 46 |
def StartMaster(): |
64 | 47 |
"""Activate local node as master node. |
65 | 48 |
|
... | ... | |
75 | 58 |
" error: '%s'" % (result.cmd, result.output)) |
76 | 59 |
return False |
77 | 60 |
|
78 |
utils.RemoveFile(constants.MASTER_CRON_LINK) |
|
79 |
os.symlink(constants.MASTER_CRON_FILE, constants.MASTER_CRON_LINK) |
|
80 | 61 |
return True |
81 | 62 |
|
82 | 63 |
|
... | ... | |
95 | 76 |
" error: '%s'" % (result.cmd, result.output)) |
96 | 77 |
return False |
97 | 78 |
|
98 |
utils.RemoveFile(constants.MASTER_CRON_LINK) |
|
99 |
|
|
100 | 79 |
return True |
101 | 80 |
|
102 | 81 |
|
b/lib/cmdlib.py | ||
---|---|---|
738 | 738 |
bad = True |
739 | 739 |
return bad |
740 | 740 |
|
741 |
|
|
742 | 741 |
def _VerifyOrphanInstances(self, instancelist, node_instance, feedback_fn): |
743 | 742 |
"""Verify the list of running instances. |
744 | 743 |
|
... | ... | |
754 | 753 |
bad = True |
755 | 754 |
return bad |
756 | 755 |
|
757 |
def _VerifyNodeConfigFiles(self, ismaster, node, file_list, feedback_fn): |
|
758 |
"""Verify the list of node config files""" |
|
759 |
|
|
760 |
bad = False |
|
761 |
for file_name in constants.MASTER_CONFIGFILES: |
|
762 |
if ismaster and file_name not in file_list: |
|
763 |
feedback_fn(" - ERROR: master config file %s missing from master" |
|
764 |
" node %s" % (file_name, node)) |
|
765 |
bad = True |
|
766 |
elif not ismaster and file_name in file_list: |
|
767 |
feedback_fn(" - ERROR: master config file %s should not exist" |
|
768 |
" on non-master node %s" % (file_name, node)) |
|
769 |
bad = True |
|
770 |
|
|
771 |
for file_name in constants.NODE_CONFIGFILES: |
|
772 |
if file_name not in file_list: |
|
773 |
feedback_fn(" - ERROR: config file %s missing from node %s" % |
|
774 |
(file_name, node)) |
|
775 |
bad = True |
|
776 |
|
|
777 |
return bad |
|
778 |
|
|
779 | 756 |
def CheckPrereq(self): |
780 | 757 |
"""Check prerequisites. |
781 | 758 |
|
... | ... | |
801 | 778 |
|
802 | 779 |
# FIXME: verify OS list |
803 | 780 |
# do local checksums |
804 |
file_names = constants.CLUSTER_CONF_FILES |
|
781 |
file_names = list(self.sstore.GetFileList()) |
|
782 |
file_names.append(constants.SSL_CERT_FILE) |
|
783 |
file_names.append(constants.CLUSTER_CONF_FILE) |
|
805 | 784 |
local_checksums = utils.FingerprintFiles(file_names) |
806 | 785 |
|
807 | 786 |
feedback_fn("* Gathering data (%d nodes)" % len(nodelist)) |
808 |
all_configfile = rpc.call_configfile_list(nodelist) |
|
809 | 787 |
all_volumeinfo = rpc.call_volume_list(nodelist, vg_name) |
810 | 788 |
all_instanceinfo = rpc.call_instance_list(nodelist) |
811 | 789 |
all_vglist = rpc.call_vg_list(nodelist) |
... | ... | |
823 | 801 |
all_vglist[node], all_nvinfo[node], |
824 | 802 |
all_rversion[node], feedback_fn) |
825 | 803 |
bad = bad or result |
826 |
# node_configfile |
|
827 |
nodeconfigfile = all_configfile[node] |
|
828 |
|
|
829 |
if not nodeconfigfile: |
|
830 |
feedback_fn(" - ERROR: connection to %s failed" % (node)) |
|
831 |
bad = True |
|
832 |
continue |
|
833 |
|
|
834 |
bad = bad or self._VerifyNodeConfigFiles(node==master, node, |
|
835 |
nodeconfigfile, feedback_fn) |
|
836 | 804 |
|
837 | 805 |
# node_volume |
838 | 806 |
volumeinfo = all_volumeinfo[node] |
... | ... | |
1452 | 1420 |
logger.Error("copy of file %s to node %s failed" % |
1453 | 1421 |
(fname, to_node)) |
1454 | 1422 |
|
1455 |
to_copy = [constants.MASTER_CRON_FILE] |
|
1456 |
to_copy.extend(ss.GetFileList()) |
|
1423 |
to_copy = ss.GetFileList() |
|
1457 | 1424 |
for fname in to_copy: |
1458 | 1425 |
if not ssh.CopyFileToNode(node, fname): |
1459 | 1426 |
logger.Error("could not copy file %s to node %s" % (fname, node)) |
b/lib/constants.py | ||
---|---|---|
33 | 33 |
DATA_DIR = "/var/lib/ganeti" |
34 | 34 |
CLUSTER_CONF_FILE = DATA_DIR + "/config.data" |
35 | 35 |
SSL_CERT_FILE = DATA_DIR + "/server.pem" |
36 |
HYPERCONF_FILE = DATA_DIR + "/hypervisor" |
|
37 | 36 |
WATCHER_STATEFILE = DATA_DIR + "/restart_state" |
38 | 37 |
|
39 |
ETC_DIR = "/etc/ganeti" |
|
40 |
|
|
41 |
MASTER_CRON_FILE = ETC_DIR + "/master-cron" |
|
42 |
MASTER_CRON_LINK = "/etc/cron.d/ganeti-master-cron" |
|
43 | 38 |
NODE_INITD_SCRIPT = "/etc/init.d/ganeti" |
44 |
NODE_INITD_NAME = "ganeti" |
|
45 | 39 |
DEFAULT_NODED_PORT = 1811 |
46 | 40 |
FIRST_DRBD_PORT = 11000 |
47 | 41 |
LAST_DRBD_PORT = 14999 |
... | ... | |
84 | 78 |
DISK_TEMPLATES = frozenset([DT_DISKLESS, DT_PLAIN, |
85 | 79 |
DT_LOCAL_RAID1, DT_REMOTE_RAID1]) |
86 | 80 |
|
87 |
# file groups |
|
88 |
CLUSTER_CONF_FILES = ["/etc/hosts", |
|
89 |
"/etc/ssh/ssh_known_hosts", |
|
90 |
"/etc/ssh/ssh_host_dsa_key", |
|
91 |
"/etc/ssh/ssh_host_dsa_key.pub", |
|
92 |
"/etc/ssh/ssh_host_rsa_key", |
|
93 |
"/etc/ssh/ssh_host_rsa_key.pub", |
|
94 |
"/root/.ssh/authorized_keys", |
|
95 |
"/root/.ssh/id_dsa", |
|
96 |
"/root/.ssh/id_dsa.pub", |
|
97 |
CLUSTER_CONF_FILE, |
|
98 |
SSL_CERT_FILE, |
|
99 |
MASTER_CRON_FILE, |
|
100 |
] |
|
101 |
|
|
102 |
MASTER_CONFIGFILES = [MASTER_CRON_LINK,] |
|
103 |
|
|
104 |
NODE_CONFIGFILES = [NODE_INITD_SCRIPT, |
|
105 |
"/etc/rc2.d/S20%s" % NODE_INITD_NAME, |
|
106 |
"/etc/rc0.d/K80%s" % NODE_INITD_NAME] |
|
107 |
|
|
108 | 81 |
# import/export config options |
109 | 82 |
INISECT_EXP = "export" |
110 | 83 |
INISECT_INS = "instance" |
b/lib/rpc.py | ||
---|---|---|
451 | 451 |
return c.getresult() |
452 | 452 |
|
453 | 453 |
|
454 |
def call_configfile_list(node_list): |
|
455 |
"""Return list of existing configuration files. |
|
456 |
|
|
457 |
This is a multi-node call. |
|
458 |
|
|
459 |
""" |
|
460 |
c = Client("configfile_list", []) |
|
461 |
c.connect_list(node_list) |
|
462 |
c.run() |
|
463 |
return c.getresult() |
|
464 |
|
|
465 | 454 |
def call_blockdev_create(node, bdev, size, on_primary): |
466 | 455 |
"""Request creation of a given block device. |
467 | 456 |
|
Also available in: Unified diff