Skip to content

Commit 5f5f62b

Browse files
committed
Dev: bootstrap: Enhance stage validation
- All stages on join side require -c option to specify cluster node - Move stange validation to a separate function
1 parent 2d6bc73 commit 5f5f62b

File tree

2 files changed

+35
-25
lines changed

2 files changed

+35
-25
lines changed

crmsh/bootstrap.py

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,11 @@
7474
"/etc/drbd.conf", "/etc/drbd.d", "/etc/ha.d/ldirectord.cf", "/etc/lvm/lvm.conf", "/etc/multipath.conf",
7575
"/etc/samba/smb.conf", SYSCONFIG_NFS, SYSCONFIG_PCMK, SYSCONFIG_SBD, PCMK_REMOTE_AUTH, WATCHDOG_CFG,
7676
PROFILES_FILE, CRM_CFG, SBD_SYSTEMD_DELAY_START_DIR)
77-
INIT_STAGES = ("ssh", "csync2", "csync2_remote", "qnetd_remote", "corosync", "remote_auth", "sbd", "cluster", "ocfs2", "admin", "qdevice")
77+
78+
INIT_STAGES_EXTERNAL = ("ssh", "csync2", "corosync", "sbd", "cluster", "ocfs2", "admin", "qdevice")
79+
INIT_STAGES_INTERNAL = ("csync2_remote", "qnetd_remote", "remote_auth")
80+
INIT_STAGES_ALL = INIT_STAGES_EXTERNAL + INIT_STAGES_INTERNAL
81+
JOIN_STAGES_EXTERNAL = ("ssh", "csync2", "ssh_merge", "cluster")
7882

7983

8084
class Context(object):
@@ -247,15 +251,40 @@ def _validate_cluster_node(self):
247251
"""
248252
Validate cluster_node on join side
249253
"""
250-
if self.cluster_node and self.type == 'join':
254+
if self.type == "join" and self.cluster_node:
251255
user, node = _parse_user_at_host(self.cluster_node, None)
252256
try:
253257
# self.cluster_node might be hostname or IP address
254258
ip_addr = socket.gethostbyname(node)
255259
if utils.InterfacesInfo.ip_in_local(ip_addr):
256260
utils.fatal("Please specify peer node's hostname or IP address")
257261
except socket.gaierror as err:
258-
utils.fatal("\"{}\": {}".format(node, err))
262+
utils.fatal(f"\"{node}\": {err}")
263+
264+
def _validate_stage(self):
265+
"""
266+
Validate stage argument
267+
"""
268+
if not self.stage:
269+
if self.cluster_is_running:
270+
utils.fatal("Cluster is already running!")
271+
return
272+
273+
if self.type == "init":
274+
if self.stage not in INIT_STAGES_ALL:
275+
utils.fatal(f"Invalid stage: {self.stage}(available stages: {', '.join(INIT_STAGES_EXTERNAL)})")
276+
if self.stage in ("admin", "qdevice", "ocfs2") and not self.cluster_is_running:
277+
utils.fatal(f"Cluster is inactive, can't run '{self.stage}' stage")
278+
if self.stage in ("corosync", "cluster") and self.cluster_is_running:
279+
utils.fatal(f"Cluster is active, can't run '{self.stage}' stage")
280+
281+
elif self.type == "join":
282+
if self.stage not in JOIN_STAGES_EXTERNAL:
283+
utils.fatal(f"Invalid stage: {self.stage}(available stages: {', '.join(JOIN_STAGES_EXTERNAL)})")
284+
if self.stage and self.cluster_node is None:
285+
utils.fatal(f"Can't use stage({self.stage}) without specifying cluster node")
286+
if self.stage in ("cluster", ) and self.cluster_is_running:
287+
utils.fatal(f"Cluster is active, can't run '{self.stage}' stage")
259288

260289
def validate_option(self):
261290
"""
@@ -269,6 +298,7 @@ def validate_option(self):
269298
self.skip_csync2 = utils.get_boolean(os.getenv("SKIP_CSYNC2_SYNC"))
270299
if self.skip_csync2 and self.stage:
271300
utils.fatal("-x option or SKIP_CSYNC2_SYNC can't be used with any stage")
301+
self._validate_stage()
272302
self._validate_network_options()
273303
self._validate_cluster_node()
274304
self._validate_nodes_option()
@@ -2112,23 +2142,10 @@ def bootstrap_init(context):
21122142
"""
21132143
global _context
21142144
_context = context
2145+
stage = _context.stage
21152146

21162147
init()
21172148

2118-
stage = _context.stage
2119-
if stage is None:
2120-
stage = ""
2121-
2122-
if stage in ("admin", "qdevice", "ocfs2"):
2123-
if not _context.cluster_is_running:
2124-
utils.fatal("Cluster is inactive - can't run %s stage" % (stage))
2125-
elif stage == "":
2126-
if _context.cluster_is_running:
2127-
utils.fatal("Cluster is currently active - can't run")
2128-
elif stage not in ("ssh", "csync2", "csync2_remote", "qnetd_remote", "sbd", "ocfs2"):
2129-
if _context.cluster_is_running:
2130-
utils.fatal("Cluster is currently active - can't run %s stage" % (stage))
2131-
21322149
_context.load_profiles()
21332150
_context.init_sbd_manager()
21342151

@@ -2228,10 +2245,6 @@ def bootstrap_join(context):
22282245

22292246
check_tty()
22302247

2231-
corosync_active = ServiceManager(sh.ClusterShellAdaptorForLocalShell(sh.LocalShell())).service_is_active("corosync.service")
2232-
if corosync_active and _context.stage != "ssh":
2233-
utils.fatal("Abort: Cluster is currently active. Run this command on a node joining the cluster.")
2234-
22352248
if not check_prereqs("join"):
22362249
return
22372250

crmsh/ui_cluster.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,6 @@ def looks_like_hostnames(lst):
457457
stage = ""
458458
if len(args):
459459
stage = args[0]
460-
if stage not in bootstrap.INIT_STAGES and stage != "":
461-
parser.error("Invalid stage (%s)" % (stage))
462460

463461
if options.qnetd_addr_input:
464462
if not ServiceManager().service_is_available("corosync-qdevice.service"):
@@ -531,12 +529,11 @@ def do_join(self, context, *args):
531529
stage = ""
532530
if len(args) == 1:
533531
stage = args[0]
534-
if stage not in ("ssh", "csync2", "ssh_merge", "cluster", ""):
535-
parser.error("Invalid stage (%s)" % (stage))
536532

537533
join_context = bootstrap.Context.set_context(options)
538534
join_context.ui_context = context
539535
join_context.stage = stage
536+
join_context.cluster_is_running = ServiceManager(sh.ClusterShellAdaptorForLocalShell(sh.LocalShell())).service_is_active("pacemaker.service")
540537
join_context.type = "join"
541538
join_context.validate_option()
542539

0 commit comments

Comments
 (0)