X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/02691904fad3df9d657d65b980dfca6893b6e3f4..4040a7847ecaa9a163a2132c52831fbd38dc92de:/scripts/gnt-cluster diff --git a/scripts/gnt-cluster b/scripts/gnt-cluster index d150966..09c1eb2 100755 --- a/scripts/gnt-cluster +++ b/scripts/gnt-cluster @@ -36,12 +36,16 @@ from ganeti import bootstrap from ganeti import ssh +@UsesRPC def InitCluster(opts, args): """Initialize the cluster. - Args: - opts - class with options as members - args - list of arguments, expected to be [clustername] + @param opts: the command line options selected by the user + @type args: list + @param args: should contain only one element, the desired + cluster name + @rtype: int + @return: the desired exit code """ if not opts.lvm_storage and opts.vg_name: @@ -56,13 +60,14 @@ def InitCluster(opts, args): if hvlist is not None: hvlist = hvlist.split(",") else: - hvlist = [constants.DEFAULT_ENABLED_HYPERVISOR] + hvlist = [opts.default_hypervisor] # avoid an impossible situation - if opts.default_hypervisor in hvlist: - default_hypervisor = opts.default_hypervisor - else: - default_hypervisor = hvlist[0] + if opts.default_hypervisor not in hvlist: + ToStderr("The default hypervisor requested (%s) is not" + " within the enabled hypervisor list (%s)" % + (opts.default_hypervisor, hvlist)) + return 1 hvparams = opts.hvparams if hvparams: @@ -76,7 +81,7 @@ def InitCluster(opts, args): # check for invalid parameters for parameter in beparams: if parameter not in constants.BES_PARAMETERS: - print "Invalid backend parameter: %s" % parameter + ToStderr("Invalid backend parameter: %s", parameter) return 1 # prepare beparams dict @@ -88,10 +93,12 @@ def InitCluster(opts, args): try: beparams[constants.BE_VCPUS] = int(beparams[constants.BE_VCPUS]) except ValueError: - print "%s must be an integer" % constants.BE_VCPUS + ToStderr("%s must be an integer", constants.BE_VCPUS) return 1 - beparams[constants.BE_MEMORY] = utils.ParseUnit(beparams[constants.BE_MEMORY]) + if not isinstance(beparams[constants.BE_MEMORY], int): + beparams[constants.BE_MEMORY] = utils.ParseUnit( + beparams[constants.BE_MEMORY]) # prepare hvparams dict for hv in constants.HYPER_TYPES: @@ -103,7 +110,7 @@ def InitCluster(opts, args): for hv in hvlist: if hv not in constants.HYPER_TYPES: - print "invalid hypervisor: %s" % hv + ToStderr("invalid hypervisor: %s", hv) return 1 bootstrap.InitCluster(cluster_name=args[0], @@ -114,17 +121,23 @@ def InitCluster(opts, args): master_netdev=opts.master_netdev, file_storage_dir=opts.file_storage_dir, enabled_hypervisors=hvlist, - default_hypervisor=default_hypervisor, + default_hypervisor=opts.default_hypervisor, hvparams=hvparams, - beparams=beparams) + beparams=beparams, + candidate_pool_size=opts.candidate_pool_size, + ) return 0 +@UsesRPC def DestroyCluster(opts, args): """Destroy the cluster. - Args: - opts - class with options as members + @param opts: the command line options selected by the user + @type args: list + @param args: should be an empty list + @rtype: int + @return: the desired exit code """ if not opts.yes_do_it: @@ -143,9 +156,11 @@ def DestroyCluster(opts, args): def RenameCluster(opts, args): """Rename the cluster. - Args: - opts - class with options as members, we use force only - args - list of arguments, expected to be [new_name] + @param opts: the command line options selected by the user + @type args: list + @param args: should contain only one element, the new cluster name + @rtype: int + @return: the desired exit code """ name = args[0] @@ -162,11 +177,29 @@ def RenameCluster(opts, args): return 0 +def RedistributeConfig(opts, args): + """Forces push of the cluster configuration. + + @param opts: the command line options selected by the user + @type args: list + @param args: empty list + @rtype: int + @return: the desired exit code + + """ + op = opcodes.OpRedistributeConf() + SubmitOrSend(op, opts) + return 0 + + def ShowClusterVersion(opts, args): """Write version of ganeti software to the standard output. - Args: - opts - class with options as members + @param opts: the command line options selected by the user + @type args: list + @param args: should be an empty list + @rtype: int + @return: the desired exit code """ op = opcodes.OpQueryClusterInfo() @@ -182,8 +215,11 @@ def ShowClusterVersion(opts, args): def ShowClusterMaster(opts, args): """Write name of master node to the standard output. - Args: - opts - class with options as members + @param opts: the command line options selected by the user + @type args: list + @param args: should be an empty list + @rtype: int + @return: the desired exit code """ ToStdout("%s", GetClient().QueryConfigValues(["master_node"])[0]) @@ -193,6 +229,12 @@ def ShowClusterMaster(opts, args): def ShowClusterConfig(opts, args): """Shows cluster information. + @param opts: the command line options selected by the user + @type args: list + @param args: should be an empty list + @rtype: int + @return: the desired exit code + """ op = opcodes.OpQueryClusterInfo() result = SubmitOpCode(op) @@ -214,6 +256,9 @@ def ShowClusterConfig(opts, args): ToStdout(" %s: %s", item, val) ToStdout("Cluster parameters:") + ToStdout(" - candidate pool size: %s", result["candidate_pool_size"]) + + ToStdout("Default instance parameters:") for gr_name, gr_dict in result["beparams"].items(): ToStdout(" - %s:", gr_name) for item, val in gr_dict.iteritems(): @@ -225,11 +270,12 @@ def ShowClusterConfig(opts, args): def ClusterCopyFile(opts, args): """Copy a file from master to some nodes. - Args: - opts - class with options as members - args - list containing a single element, the file name - Opts used: - nodes - list containing the name of target nodes; if empty, all nodes + @param opts: the command line options selected by the user + @type args: list + @param args: should contain only one element, the path of + the file to be copied + @rtype: int + @return: the desired exit code """ filename = args[0] @@ -242,8 +288,8 @@ def ClusterCopyFile(opts, args): cluster_name = cl.QueryConfigValues(["cluster_name"])[0] - op = opcodes.OpQueryNodes(output_fields=["name"], names=opts.nodes) - results = [row[0] for row in SubmitOpCode(op, cl=cl) if row[0] != myname] + results = GetOnlineNodes(nodes=opts.nodes, cl=cl) + results = [name for name in results if name != myname] srun = ssh.SshRunner(cluster_name=cluster_name) for node in results: @@ -256,18 +302,18 @@ def ClusterCopyFile(opts, args): def RunClusterCommand(opts, args): """Run a command on some nodes. - Args: - opts - class with options as members - args - the command list as a list - Opts used: - nodes: list containing the name of target nodes; if empty, all nodes + @param opts: the command line options selected by the user + @type args: list + @param args: should contain the command to be run and its arguments + @rtype: int + @return: the desired exit code """ cl = GetClient() command = " ".join(args) - op = opcodes.OpQueryNodes(output_fields=["name"], names=opts.nodes) - nodes = [row[0] for row in SubmitOpCode(op, cl=cl)] + + nodes = GetOnlineNodes(nodes=opts.nodes, cl=cl) cluster_name, master_node = cl.QueryConfigValues(["cluster_name", "master_node"]) @@ -292,8 +338,11 @@ def RunClusterCommand(opts, args): def VerifyCluster(opts, args): """Verify integrity of cluster, performing various test on nodes. - Args: - opts - class with options as members + @param opts: the command line options selected by the user + @type args: list + @param args: should be an empty list + @rtype: int + @return: the desired exit code """ skip_checks = [] @@ -309,8 +358,11 @@ def VerifyCluster(opts, args): def VerifyDisks(opts, args): """Verify integrity of cluster disks. - Args: - opts - class with options as members + @param opts: the command line options selected by the user + @type args: list + @param args: should be an empty list + @rtype: int + @return: the desired exit code """ op = opcodes.OpVerifyDisks() @@ -367,6 +419,7 @@ def VerifyDisks(opts, args): return retcode +@UsesRPC def MasterFailover(opts, args): """Failover the master node. @@ -374,6 +427,12 @@ def MasterFailover(opts, args): master to cease being master, and the non-master to become new master. + @param opts: the command line options selected by the user + @type args: list + @param args: should be an empty list + @rtype: int + @return: the desired exit code + """ return bootstrap.MasterFailover() @@ -381,6 +440,12 @@ def MasterFailover(opts, args): def SearchTags(opts, args): """Searches the tags on all the cluster. + @param opts: the command line options selected by the user + @type args: list + @param args: should contain only one element, the tag pattern + @rtype: int + @return: the desired exit code + """ op = opcodes.OpSearchTags(pattern=args[0]) result = SubmitOpCode(op) @@ -395,13 +460,16 @@ def SearchTags(opts, args): def SetClusterParams(opts, args): """Modify the cluster. - Args: - opts - class with options as members + @param opts: the command line options selected by the user + @type args: list + @param args: should be an empty list + @rtype: int + @return: the desired exit code """ if not (not opts.lvm_storage or opts.vg_name or opts.enabled_hypervisors or opts.hvparams or - opts.beparams): + opts.beparams or opts.candidate_pool_size is not None): ToStderr("Please give at least one of the parameters.") return 1 @@ -424,7 +492,8 @@ def SetClusterParams(opts, args): op = opcodes.OpSetClusterParams(vg_name=opts.vg_name, enabled_hypervisors=hvlist, hvparams=hvparams, - beparams=beparams) + beparams=beparams, + candidate_pool_size=opts.candidate_pool_size) SubmitOpCode(op) return 0 @@ -432,6 +501,12 @@ def SetClusterParams(opts, args): def QueueOps(opts, args): """Queue operations. + @param opts: the command line options selected by the user + @type args: list + @param args: should contain only one element, the subcommand + @rtype: int + @return: the desired exit code + """ command = args[0] client = GetClient() @@ -512,6 +587,10 @@ commands = { keyval_option("-B", "--backend-parameters", dest="beparams", type="keyval", default={}, help="Backend parameters"), + make_option("-C", "--candidate-pool-size", + default=constants.MASTER_POOL_SIZE_DEFAULT, + help="Set the candidate pool size", + dest="candidate_pool_size", type="int"), ], "[opts...] ", "Initialises a new cluster configuration"), @@ -525,6 +604,10 @@ commands = { 'rename': (RenameCluster, ARGS_ONE, [DEBUG_OPT, FORCE_OPT], "", "Renames the cluster"), + 'redist-conf': (RedistributeConfig, ARGS_NONE, [DEBUG_OPT, SUBMIT_OPT], + "", + "Forces a push of the configuration file and ssconf files" + " to the nodes in the cluster"), 'verify': (VerifyCluster, ARGS_NONE, [DEBUG_OPT, make_option("--no-nplus1-mem", dest="skip_nplusone_mem", help="Skip N+1 memory redundancy tests", @@ -583,6 +666,9 @@ commands = { keyval_option("-B", "--backend-parameters", dest="beparams", type="keyval", default={}, help="Backend parameters"), + make_option("-C", "--candidate-pool-size", default=None, + help="Set the candidate pool size", + dest="candidate_pool_size", type="int"), ], "[opts...]", "Alters the parameters of the cluster"),