Revision b989b9d9
b/NEWS | ||
---|---|---|
85 | 85 |
- Reimplemented bash completion script to be more complete |
86 | 86 |
- Improved burnin |
87 | 87 |
- Added option to specify maximum timeout on instance shutdown |
88 |
- Added ``--no-ssh-init`` option to ``gnt-cluster init`` |
|
88 | 89 |
|
89 | 90 |
|
90 | 91 |
Version 2.0.4 |
b/daemons/ganeti-noded | ||
---|---|---|
593 | 593 |
"""Cleanup after leaving a cluster. |
594 | 594 |
|
595 | 595 |
""" |
596 |
return backend.LeaveCluster() |
|
596 |
return backend.LeaveCluster(params[0])
|
|
597 | 597 |
|
598 | 598 |
@staticmethod |
599 | 599 |
def perspective_node_volumes(params): |
b/lib/backend.py | ||
---|---|---|
351 | 351 |
utils.RunCmd([constants.SSH_INITD_SCRIPT, "restart"]) |
352 | 352 |
|
353 | 353 |
|
354 |
def LeaveCluster(): |
|
354 |
def LeaveCluster(modify_ssh_setup):
|
|
355 | 355 |
"""Cleans up and remove the current node. |
356 | 356 |
|
357 | 357 |
This function cleans up and prepares the current node to be removed |
... | ... | |
361 | 361 |
L{errors.QuitGanetiException} which is used as a special case to |
362 | 362 |
shutdown the node daemon. |
363 | 363 |
|
364 |
@param modify_ssh_setup: boolean |
|
365 |
|
|
364 | 366 |
""" |
365 | 367 |
_CleanDirectory(constants.DATA_DIR) |
366 | 368 |
JobQueuePurge() |
367 | 369 |
|
368 |
try: |
|
369 |
priv_key, pub_key, auth_keys = ssh.GetUserFiles(constants.GANETI_RUNAS) |
|
370 |
if modify_ssh_setup: |
|
371 |
try: |
|
372 |
priv_key, pub_key, auth_keys = ssh.GetUserFiles(constants.GANETI_RUNAS) |
|
370 | 373 |
|
371 |
utils.RemoveAuthorizedKey(auth_keys, utils.ReadFile(pub_key)) |
|
374 |
utils.RemoveAuthorizedKey(auth_keys, utils.ReadFile(pub_key))
|
|
372 | 375 |
|
373 |
utils.RemoveFile(priv_key) |
|
374 |
utils.RemoveFile(pub_key) |
|
375 |
except errors.OpExecError: |
|
376 |
logging.exception("Error while processing ssh files") |
|
376 |
utils.RemoveFile(priv_key)
|
|
377 |
utils.RemoveFile(pub_key)
|
|
378 |
except errors.OpExecError:
|
|
379 |
logging.exception("Error while processing ssh files")
|
|
377 | 380 |
|
378 | 381 |
try: |
379 | 382 |
utils.RemoveFile(constants.HMAC_CLUSTER_KEY) |
b/lib/bootstrap.py | ||
---|---|---|
138 | 138 |
master_netdev, file_storage_dir, candidate_pool_size, |
139 | 139 |
secondary_ip=None, vg_name=None, beparams=None, |
140 | 140 |
nicparams=None, hvparams=None, enabled_hypervisors=None, |
141 |
modify_etc_hosts=True): |
|
141 |
modify_etc_hosts=True, modify_ssh_setup=True):
|
|
142 | 142 |
"""Initialise the cluster. |
143 | 143 |
|
144 | 144 |
@type candidate_pool_size: int |
... | ... | |
250 | 250 |
if modify_etc_hosts: |
251 | 251 |
utils.AddHostToEtcHosts(hostname.name) |
252 | 252 |
|
253 |
_InitSSHSetup() |
|
253 |
if modify_ssh_setup: |
|
254 |
_InitSSHSetup() |
|
254 | 255 |
|
255 | 256 |
now = time.time() |
256 | 257 |
|
... | ... | |
273 | 274 |
hvparams=hvparams, |
274 | 275 |
candidate_pool_size=candidate_pool_size, |
275 | 276 |
modify_etc_hosts=modify_etc_hosts, |
277 |
modify_ssh_setup=modify_ssh_setup, |
|
276 | 278 |
ctime=now, |
277 | 279 |
mtime=now, |
278 | 280 |
uuid=utils.NewUUID(), |
... | ... | |
335 | 337 |
begun in cmdlib.LUDestroyOpcode. |
336 | 338 |
|
337 | 339 |
""" |
340 |
cfg = config.ConfigWriter() |
|
341 |
modify_ssh_setup = cfg.GetClusterInfo().modify_ssh_setup |
|
338 | 342 |
result = rpc.RpcRunner.call_node_stop_master(master, True) |
339 | 343 |
msg = result.fail_msg |
340 | 344 |
if msg: |
341 | 345 |
logging.warning("Could not disable the master role: %s" % msg) |
342 |
result = rpc.RpcRunner.call_node_leave_cluster(master) |
|
346 |
result = rpc.RpcRunner.call_node_leave_cluster(master, modify_ssh_setup)
|
|
343 | 347 |
msg = result.fail_msg |
344 | 348 |
if msg: |
345 | 349 |
logging.warning("Could not shutdown the node daemon and cleanup" |
b/lib/cli.py | ||
---|---|---|
84 | 84 |
"NOIPCHECK_OPT", |
85 | 85 |
"NOLVM_STORAGE_OPT", |
86 | 86 |
"NOMODIFY_ETCHOSTS_OPT", |
87 |
"NOMODIFY_SSH_SETUP_OPT", |
|
87 | 88 |
"NONICS_OPT", |
88 | 89 |
"NONLIVE_OPT", |
89 | 90 |
"NONPLUS1_OPT", |
... | ... | |
794 | 795 |
help="Don't modify /etc/hosts", |
795 | 796 |
action="store_false", default=True) |
796 | 797 |
|
798 |
NOMODIFY_SSH_SETUP_OPT = cli_option("--no-ssh-init", dest="modify_ssh_setup", |
|
799 |
help="Don't initialize SSH keys", |
|
800 |
action="store_false", default=True) |
|
801 |
|
|
797 | 802 |
ERROR_CODES_OPT = cli_option("--error-codes", dest="error_codes", |
798 | 803 |
help="Enable parseable error messages", |
799 | 804 |
action="store_true", default=False) |
b/lib/cmdlib.py | ||
---|---|---|
867 | 867 |
|
868 | 868 |
""" |
869 | 869 |
master = self.cfg.GetMasterNode() |
870 |
modify_ssh_setup = self.cfg.GetClusterInfo().modify_ssh_setup |
|
870 | 871 |
|
871 | 872 |
# Run post hooks on master node before it's removed |
872 | 873 |
hm = self.proc.hmclass(self.rpc.call_hooks_runner, self) |
... | ... | |
877 | 878 |
|
878 | 879 |
result = self.rpc.call_node_stop_master(master, False) |
879 | 880 |
result.Raise("Could not disable the master role") |
880 |
priv_key, pub_key, _ = ssh.GetUserFiles(constants.GANETI_RUNAS) |
|
881 |
utils.CreateBackup(priv_key) |
|
882 |
utils.CreateBackup(pub_key) |
|
881 |
|
|
882 |
if modify_ssh_setup: |
|
883 |
priv_key, pub_key, _ = ssh.GetUserFiles(constants.GANETI_RUNAS) |
|
884 |
utils.CreateBackup(priv_key) |
|
885 |
utils.CreateBackup(pub_key) |
|
886 |
|
|
883 | 887 |
return master |
884 | 888 |
|
885 | 889 |
|
... | ... | |
2340 | 2344 |
logging.info("Stopping the node daemon and removing configs from node %s", |
2341 | 2345 |
node.name) |
2342 | 2346 |
|
2347 |
modify_ssh_setup = self.cfg.GetClusterInfo().modify_ssh_setup |
|
2348 |
|
|
2343 | 2349 |
# Promote nodes to master candidate as needed |
2344 | 2350 |
_AdjustCandidatePool(self, exceptions=[node.name]) |
2345 | 2351 |
self.context.RemoveNode(node.name) |
... | ... | |
2351 | 2357 |
except: |
2352 | 2358 |
self.LogWarning("Errors occurred running hooks on %s" % node.name) |
2353 | 2359 |
|
2354 |
result = self.rpc.call_node_leave_cluster(node.name) |
|
2360 |
result = self.rpc.call_node_leave_cluster(node.name, modify_ssh_setup)
|
|
2355 | 2361 |
msg = result.fail_msg |
2356 | 2362 |
if msg: |
2357 | 2363 |
self.LogWarning("Errors encountered on the remote node while leaving" |
... | ... | |
2900 | 2906 |
(constants.PROTOCOL_VERSION, result.payload)) |
2901 | 2907 |
|
2902 | 2908 |
# setup ssh on node |
2903 |
logging.info("Copy ssh key to node %s", node) |
|
2904 |
priv_key, pub_key, _ = ssh.GetUserFiles(constants.GANETI_RUNAS) |
|
2905 |
keyarray = [] |
|
2906 |
keyfiles = [constants.SSH_HOST_DSA_PRIV, constants.SSH_HOST_DSA_PUB, |
|
2907 |
constants.SSH_HOST_RSA_PRIV, constants.SSH_HOST_RSA_PUB, |
|
2908 |
priv_key, pub_key] |
|
2909 |
|
|
2910 |
for i in keyfiles: |
|
2911 |
keyarray.append(utils.ReadFile(i)) |
|
2912 |
|
|
2913 |
result = self.rpc.call_node_add(node, keyarray[0], keyarray[1], |
|
2914 |
keyarray[2], |
|
2915 |
keyarray[3], keyarray[4], keyarray[5]) |
|
2916 |
result.Raise("Cannot transfer ssh keys to the new node") |
|
2909 |
if self.cfg.GetClusterInfo().modify_ssh_setup: |
|
2910 |
logging.info("Copy ssh key to node %s", node) |
|
2911 |
priv_key, pub_key, _ = ssh.GetUserFiles(constants.GANETI_RUNAS) |
|
2912 |
keyarray = [] |
|
2913 |
keyfiles = [constants.SSH_HOST_DSA_PRIV, constants.SSH_HOST_DSA_PUB, |
|
2914 |
constants.SSH_HOST_RSA_PRIV, constants.SSH_HOST_RSA_PUB, |
|
2915 |
priv_key, pub_key] |
|
2916 |
|
|
2917 |
for i in keyfiles: |
|
2918 |
keyarray.append(utils.ReadFile(i)) |
|
2919 |
|
|
2920 |
result = self.rpc.call_node_add(node, keyarray[0], keyarray[1], |
|
2921 |
keyarray[2], keyarray[3], keyarray[4], |
|
2922 |
keyarray[5]) |
|
2923 |
result.Raise("Cannot transfer ssh keys to the new node") |
|
2917 | 2924 |
|
2918 | 2925 |
# Add node to our /etc/hosts, and add key to known_hosts |
2919 | 2926 |
if self.cfg.GetClusterInfo().modify_etc_hosts: |
b/lib/objects.py | ||
---|---|---|
825 | 825 |
"nicparams", |
826 | 826 |
"candidate_pool_size", |
827 | 827 |
"modify_etc_hosts", |
828 |
"modify_ssh_setup", |
|
828 | 829 |
] + _TIMESTAMPS + _UUID |
829 | 830 |
|
830 | 831 |
def UpgradeConfig(self): |
... | ... | |
850 | 851 |
if self.modify_etc_hosts is None: |
851 | 852 |
self.modify_etc_hosts = True |
852 | 853 |
|
854 |
if self.modify_ssh_setup is None: |
|
855 |
self.modify_ssh_setup = True |
|
856 |
|
|
853 | 857 |
# default_bridge is no longer used it 2.1. The slot is left there to |
854 | 858 |
# support auto-upgrading, but will be removed in 2.2 |
855 | 859 |
if self.default_bridge is not None: |
b/lib/rpc.py | ||
---|---|---|
1044 | 1044 |
return self._SingleNodeCall(node, "export_remove", [export]) |
1045 | 1045 |
|
1046 | 1046 |
@classmethod |
1047 |
def call_node_leave_cluster(cls, node): |
|
1047 |
def call_node_leave_cluster(cls, node, modify_ssh_setup):
|
|
1048 | 1048 |
"""Requests a node to clean the cluster information it has. |
1049 | 1049 |
|
1050 | 1050 |
This will remove the configuration information from the ganeti data |
... | ... | |
1053 | 1053 |
This is a single-node call. |
1054 | 1054 |
|
1055 | 1055 |
""" |
1056 |
return cls._StaticSingleNodeCall(node, "node_leave_cluster", []) |
|
1056 |
return cls._StaticSingleNodeCall(node, "node_leave_cluster", |
|
1057 |
[modify_ssh_setup]) |
|
1057 | 1058 |
|
1058 | 1059 |
def call_node_volumes(self, node_list): |
1059 | 1060 |
"""Gets all volumes on node(s). |
b/man/gnt-cluster.sgml | ||
---|---|---|
221 | 221 |
<sbr> |
222 | 222 |
<arg>--no-lvm-storage</arg> |
223 | 223 |
<sbr> |
224 |
<arg>--no-etc-hosts</arg> |
|
225 |
<sbr> |
|
226 |
<arg>--no-ssh-init</arg> |
|
227 |
<sbr> |
|
224 | 228 |
<arg>--file-storage-dir <replaceable>dir</replaceable></arg> |
225 | 229 |
<sbr> |
226 | 230 |
<arg>--enabled-hypervisors <replaceable>hypervisors</replaceable></arg> |
... | ... | |
296 | 300 |
</para> |
297 | 301 |
|
298 | 302 |
<para> |
299 |
The <option>--no-lvm-storage</option> allows you to initialize the
|
|
300 |
cluster without lvm support. This means that only instances using |
|
303 |
The <option>--no-lvm-storage</option> option allows you to initialize
|
|
304 |
the cluster without lvm support. This means that only instances using
|
|
301 | 305 |
files as storage backend will be possible to create. Once the cluster |
302 | 306 |
is initialized you can change this setup with the |
303 | 307 |
<command>modify</command> command. |
304 | 308 |
</para> |
305 | 309 |
|
306 | 310 |
<para> |
311 |
The <option>--no-etc-hosts</option> option allows you to initialize the |
|
312 |
cluster without modifying the <filename>/etc/hosts</filename> file. |
|
313 |
</para> |
|
314 |
|
|
315 |
<para> |
|
316 |
The <option>--no-ssh-init</option> option allows you to initialize the |
|
317 |
cluster without creating or distributing SSH key pairs. |
|
318 |
</para> |
|
319 |
|
|
320 |
<para> |
|
307 | 321 |
The <option>--file-storage-dir</option> option allows you |
308 | 322 |
set the directory to use for storing the instance disk |
309 | 323 |
files when using file storage as backend for instance disks. |
b/scripts/gnt-cluster | ||
---|---|---|
99 | 99 |
nicparams=nicparams, |
100 | 100 |
candidate_pool_size=opts.candidate_pool_size, |
101 | 101 |
modify_etc_hosts=opts.modify_etc_hosts, |
102 |
modify_ssh_setup=opts.modify_ssh_setup, |
|
102 | 103 |
) |
103 | 104 |
op = opcodes.OpPostInitCluster() |
104 | 105 |
SubmitOpCode(op) |
... | ... | |
600 | 601 |
InitCluster, [ArgHost(min=1, max=1)], |
601 | 602 |
[BACKEND_OPT, CP_SIZE_OPT, ENABLED_HV_OPT, GLOBAL_FILEDIR_OPT, |
602 | 603 |
HVLIST_OPT, MAC_PREFIX_OPT, MASTER_NETDEV_OPT, NIC_PARAMS_OPT, |
603 |
NOLVM_STORAGE_OPT, NOMODIFY_ETCHOSTS_OPT, SECONDARY_IP_OPT, VG_NAME_OPT], |
|
604 |
NOLVM_STORAGE_OPT, NOMODIFY_ETCHOSTS_OPT, NOMODIFY_SSH_SETUP_OPT, |
|
605 |
SECONDARY_IP_OPT, VG_NAME_OPT], |
|
604 | 606 |
"[opts...] <cluster_name>", "Initialises a new cluster configuration"), |
605 | 607 |
'destroy': ( |
606 | 608 |
DestroyCluster, ARGS_NONE, [YES_DOIT_OPT], |
Also available in: Unified diff