diff --git a/Makefile.am b/Makefile.am index c24d682b21adb6708aa67a9601244292e1085cb3..9e84594cad203a26d089d06e09bf8e70a4f9b76f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -503,7 +503,7 @@ nodist_sbin_SCRIPTS = \ $(PYTHON_BOOTSTRAP_SBIN) \ daemons/ganeti-cleaner -dist_tools_PYTHON = \ +python_scripts = \ tools/burnin \ tools/cfgshell \ tools/cfgupgrade \ @@ -515,7 +515,7 @@ dist_tools_PYTHON = \ tools/sanitize-config dist_tools_SCRIPTS = \ - $(dist_tools_PYTHON) \ + $(python_scripts) \ tools/kvm-console-wrapper \ tools/xm-console-wrapper @@ -729,7 +729,7 @@ TESTS_ENVIRONMENT = \ all_python_code = \ $(dist_sbin_SCRIPTS) \ - $(dist_tools_PYTHON) \ + $(python_scripts) \ $(pkglib_python_scripts) \ $(nodist_pkglib_python_scripts) \ $(python_tests) \ @@ -766,7 +766,7 @@ lint_python_code = \ ganeti \ ganeti/http/server.py \ $(dist_sbin_SCRIPTS) \ - $(dist_tools_PYTHON) \ + $(python_scripts) \ $(pkglib_python_scripts) \ $(BUILD_BASH_COMPLETION) \ $(DOCPP) \ @@ -776,7 +776,7 @@ pep8_python_code = \ ganeti \ ganeti/http/server.py \ $(dist_sbin_SCRIPTS) \ - $(dist_tools_PYTHON) \ + $(python_scripts) \ $(pkglib_python_scripts) \ $(BUILD_BASH_COMPLETION) \ $(DOCPP) \ diff --git a/devel/upload.in b/devel/upload.in index 885a51d220598ae187f8eeed70a977e410020fd9..91682859a91707fdd59acea48ae96025a227219c 100644 --- a/devel/upload.in +++ b/devel/upload.in @@ -76,6 +76,9 @@ else make_args= fi +# Make sure that directories will get correct permissions +umask 0022 + # install ganeti as a real tree make $make_args install DESTDIR="$TXD" diff --git a/lib/client/gnt_node.py b/lib/client/gnt_node.py index 0fe37c7ad2b3b5264390ebeed6c155f14f0c14db..4858b0854adc91977531935c8016ad29296fda84 100644 --- a/lib/client/gnt_node.py +++ b/lib/client/gnt_node.py @@ -1,7 +1,7 @@ # # -# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Google Inc. +# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Google Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -865,8 +865,7 @@ commands = { [FORCE_OPT, IALLOCATOR_OPT, NEW_SECONDARY_OPT, EARLY_RELEASE_OPT, PRIORITY_OPT, PRIMARY_ONLY_OPT, SECONDARY_ONLY_OPT], "[-f] {-I <iallocator> | -n <dst>} <node>", - "Relocate the secondary instances from a node" - " to other nodes"), + "Relocate the primary and/or secondary instances from a node"), "failover": ( FailoverNode, ARGS_ONE_NODE, [FORCE_OPT, IGNORE_CONSIST_OPT, IALLOCATOR_OPT, PRIORITY_OPT], diff --git a/lib/cmdlib.py b/lib/cmdlib.py index ea282119060f34058e91d05e7c2dd6c64f6227ca..c65da1d600320f2e8c262f7c2e59e33bab679677 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -1704,7 +1704,8 @@ class LUClusterVerifyGroup(LogicalUnit, _VerifyErrors): self.group_uuid = self.cfg.LookupNodeGroup(self.op.group_name) # Get instances in node group; this is unsafe and needs verification later - inst_names = self.cfg.GetNodeGroupInstances(self.group_uuid) + inst_names = \ + self.cfg.GetNodeGroupInstances(self.group_uuid, primary_only=True) self.needed_locks = { locking.LEVEL_INSTANCE: inst_names, @@ -1738,7 +1739,8 @@ class LUClusterVerifyGroup(LogicalUnit, _VerifyErrors): self.group_info = self.cfg.GetNodeGroup(self.group_uuid) group_nodes = set(self.group_info.members) - group_instances = self.cfg.GetNodeGroupInstances(self.group_uuid) + group_instances = \ + self.cfg.GetNodeGroupInstances(self.group_uuid, primary_only=True) unlocked_nodes = \ group_nodes.difference(self.owned_locks(locking.LEVEL_NODE)) @@ -1748,11 +1750,13 @@ class LUClusterVerifyGroup(LogicalUnit, _VerifyErrors): if unlocked_nodes: raise errors.OpPrereqError("Missing lock for nodes: %s" % - utils.CommaJoin(unlocked_nodes)) + utils.CommaJoin(unlocked_nodes), + errors.ECODE_STATE) if unlocked_instances: raise errors.OpPrereqError("Missing lock for instances: %s" % - utils.CommaJoin(unlocked_instances)) + utils.CommaJoin(unlocked_instances), + errors.ECODE_STATE) self.all_node_info = self.cfg.GetAllNodesInfo() self.all_inst_info = self.cfg.GetAllInstancesInfo() @@ -1772,17 +1776,17 @@ class LUClusterVerifyGroup(LogicalUnit, _VerifyErrors): for inst in self.my_inst_info.values(): if inst.disk_template in constants.DTS_INT_MIRROR: - group = self.my_node_info[inst.primary_node].group - for nname in inst.secondary_nodes: - if self.all_node_info[nname].group != group: + for nname in inst.all_nodes: + if self.all_node_info[nname].group != self.group_uuid: extra_lv_nodes.add(nname) unlocked_lv_nodes = \ extra_lv_nodes.difference(self.owned_locks(locking.LEVEL_NODE)) if unlocked_lv_nodes: - raise errors.OpPrereqError("these nodes could be locked: %s" % - utils.CommaJoin(unlocked_lv_nodes)) + raise errors.OpPrereqError("Missing node locks for LV check: %s" % + utils.CommaJoin(unlocked_lv_nodes), + errors.ECODE_STATE) self.extra_lv_nodes = list(extra_lv_nodes) def _VerifyNode(self, ninfo, nresult): @@ -2052,7 +2056,8 @@ class LUClusterVerifyGroup(LogicalUnit, _VerifyErrors): """ for node, n_img in node_image.items(): - if n_img.offline or n_img.rpc_fail or n_img.lvm_fail: + if (n_img.offline or n_img.rpc_fail or n_img.lvm_fail or + self.all_node_info[node].group != self.group_uuid): # skip non-healthy nodes continue for volume in n_img.volumes: @@ -2079,11 +2084,11 @@ class LUClusterVerifyGroup(LogicalUnit, _VerifyErrors): # WARNING: we currently take into account down instances as well # as up ones, considering that even if they're down someone # might want to start them even in the event of a node failure. - if n_img.offline: - # we're skipping offline nodes from the N+1 warning, since - # most likely we don't have good memory infromation from them; - # we already list instances living on such nodes, and that's - # enough warning + if n_img.offline or self.all_node_info[node].group != self.group_uuid: + # we're skipping nodes marked offline and nodes in other groups from + # the N+1 warning, since most likely we don't have good memory + # infromation from them; we already list instances living on such + # nodes, and that's enough warning continue for prinode, instances in n_img.sbp.items(): needed_mem = 0 diff --git a/lib/opcodes.py b/lib/opcodes.py index 6a922c9467e51b266cbc356f840fce1083363085..3b348a249a8644968ae79fb3706222cc8a2db29a 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -811,7 +811,7 @@ class OpQuery(OpCode): _PUseLocking, ("fields", ht.NoDefault, ht.TListOf(ht.TNonEmptyString), "Requested fields"), - ("filter", None, ht.TOr(ht.TNone, ht.TListOf), + ("filter", None, ht.TOr(ht.TNone, ht.TList), "Query filter"), ] diff --git a/man/gnt-node.rst b/man/gnt-node.rst index 7cfe9cecfe43b396a62090197a5b0d994dada728..f94da9909b966f535a420175b713cf61fb156bc1 100644 --- a/man/gnt-node.rst +++ b/man/gnt-node.rst @@ -118,7 +118,12 @@ potential recovery). Note that this command is equivalent to using per-instance commands for each affected instance individually: -- ``--primary-only`` is equivalent to ``gnt-instance failover/migration`` +- ``--primary-only`` is equivalent to ``gnt-instance + failover/migration`` for non-DRBD instances, but for DRBD instances + it's different, and usually is a slow process (it will change the + primary to another node while keeping the secondary, this requiring + data copies, whereas failover/migrate will only toggle the + primary/secondary roles, a fast process) - ``--secondary-only`` is equivalent to ``gnt-instance replace-disks`` in the secondary node change mode (only valid for DRBD instances) - when neither of the above is done a combination of the two cases is run