diff --git a/daemons/ganeti-masterd b/daemons/ganeti-masterd index e5f291a4767e59da39293ffa5548112b957ba2cb..1ba7e5dec416e0b8e9a8ad09cd2f4d1f235d41c4 100755 --- a/daemons/ganeti-masterd +++ b/daemons/ganeti-masterd @@ -525,7 +525,7 @@ def main(): try: # activate ip master_node = ssconf.SimpleConfigReader().GetMasterNode() - result = rpc.RpcRunner.call_node_start_master(master_node, False) + result = rpc.RpcRunner.call_node_start_master(master_node, False, False) msg = result.RemoteFailMsg() if msg: logging.error("Can't activate master IP address: %s", msg) diff --git a/daemons/ganeti-noded b/daemons/ganeti-noded index c1dfa1f08ae6300bc298f4b58f43d68b7c212d3f..876321d4ba82ba9e09faf52a5693f3b69d9016da 100755 --- a/daemons/ganeti-noded +++ b/daemons/ganeti-noded @@ -529,7 +529,7 @@ class NodeHttpServer(http.server.HttpServer): """Promote this node to master status. """ - return backend.StartMaster(params[0]) + return backend.StartMaster(params[0], params[1]) @staticmethod def perspective_node_stop_master(params): diff --git a/lib/backend.py b/lib/backend.py index 456ba69e65246d958f3737b712cc45c3b9b6fadc..e7c4787013fb7db348f3bd3b122788b26c07740a 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -177,7 +177,7 @@ def GetMasterInfo(): return (master_netdev, master_ip, master_node) -def StartMaster(start_daemons): +def StartMaster(start_daemons, no_voting): """Activate local node as master node. The function will always try activate the IP address of the master @@ -187,6 +187,9 @@ def StartMaster(start_daemons): @type start_daemons: boolean @param start_daemons: whether to also start the master daemons (ganeti-masterd and ganeti-rapi) + @type no_voting: boolean + @param no_voting: whether to start ganeti-masterd without a node vote + (if start_daemons is True), but still non-interactively @rtype: None """ @@ -217,8 +220,17 @@ def StartMaster(start_daemons): # and now start the master and rapi daemons if start_daemons: - for daemon in 'ganeti-masterd', 'ganeti-rapi': - result = utils.RunCmd([daemon]) + daemons_params = { + 'ganeti-masterd': [], + 'ganeti-rapi': [], + } + if no_voting: + daemons_params['ganeti-masterd'].append('--no-voting') + daemons_params['ganeti-masterd'].append('--yes-do-it') + for daemon in daemons_params: + cmd = [daemon] + cmd.extend(daemons_params[daemon]) + result = utils.RunCmd(cmd) if result.failed: msg = "Can't start daemon %s: %s" % (daemon, result.output) logging.error(msg) diff --git a/lib/bootstrap.py b/lib/bootstrap.py index e576c93524aca2e618f9123430d6c720645da9dc..0ec6bd4c00221ad5e0c0d54cff2637b9bf4bf982 100644 --- a/lib/bootstrap.py +++ b/lib/bootstrap.py @@ -275,7 +275,7 @@ def InitCluster(cluster_name, mac_prefix, # start the master ip # TODO: Review rpc call from bootstrap # TODO: Warn on failed start master - rpc.RpcRunner.call_node_start_master(hostname.name, True) + rpc.RpcRunner.call_node_start_master(hostname.name, True, False) def InitConfig(version, cluster_config, master_node_config, @@ -457,8 +457,7 @@ def MasterFailover(no_voting=False): # cluster info cfg.Update(cluster_info) - # 2.0.X: Don't start the master if no_voting is true - result = rpc.RpcRunner.call_node_start_master(new_master, not no_voting) + result = rpc.RpcRunner.call_node_start_master(new_master, True, no_voting) msg = result.RemoteFailMsg() if msg: logging.error("Could not start the master role on the new master" diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 25e598bd0d4c53c58d48b7a27c2f54ee249fd631..c79dcddaf1643ffbdeb31a8e2f200a50f12ae7b7 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -1440,7 +1440,7 @@ class LURenameCluster(LogicalUnit): self.proc.LogWarning(msg) finally: - result = self.rpc.call_node_start_master(master, False) + result = self.rpc.call_node_start_master(master, False, False) msg = result.fail_msg if msg: self.LogWarning("Could not re-enable the master role on" diff --git a/lib/rpc.py b/lib/rpc.py index ed11ae4e41e0ac4af682306bf2a6ce7d4baabc42..b02cc1afb084bf93856c57b45c61965c0d4f5fdb 100644 --- a/lib/rpc.py +++ b/lib/rpc.py @@ -676,14 +676,14 @@ class RpcRunner(object): [checkdict, cluster_name]) @classmethod - def call_node_start_master(cls, node, start_daemons): + def call_node_start_master(cls, node, start_daemons, no_voting): """Tells a node to activate itself as a master. This is a single-node call. """ return cls._StaticSingleNodeCall(node, "node_start_master", - [start_daemons]) + [start_daemons, no_voting]) @classmethod def call_node_stop_master(cls, node, stop_daemons): diff --git a/man/gnt-cluster.sgml b/man/gnt-cluster.sgml index 2634adb2e4e7970beafe0853d31a80c937ad0f5b..220b3c90bfedd235dd519b30d075106143d25923 100644 --- a/man/gnt-cluster.sgml +++ b/man/gnt-cluster.sgml @@ -483,14 +483,6 @@ and gnt-cluster redist-conf to make sure the cluster is consistent again. </para> - <para> - In version 2.0.X ganeti-masterd will not be able to start if - masterfailover is called with the --no-voting option (which, again, - should only be used on 2 nodes clusters with the former master being - down). In that case just start it manually passing --no-voting to it - as well, until you have restored cluster redundancy. - </para> - </refsect2> <refsect2>