import logging
import re
-import operator
+from ganeti import compat
from ganeti import constants
from ganeti import errors
from ganeti import ht
_PStartupPaused = ("startup_paused", False, ht.TBool,
"Pause instance at startup")
+_PVerbose = ("verbose", False, ht.TBool, "Verbose mode")
+
+# Parameters for cluster verification
+_PDebugSimulateErrors = ("debug_simulate_errors", False, ht.TBool,
+ "Whether to simulate errors (useful for debugging)")
+_PErrorCodes = ("error_codes", False, ht.TBool, "Error codes")
+_PSkipChecks = ("skip_checks", ht.EmptyList,
+ ht.TListOf(ht.TElemOf(constants.VERIFY_OPTIONAL_CHECKS)),
+ "Which checks to skip")
#: OP_ID conversion regular expression
_OPID_RE = re.compile("([a-z])([A-Z])")
#: Utility function for L{OpClusterSetParams}
_TestClusterOsList = ht.TOr(ht.TNone,
ht.TListOf(ht.TAnd(ht.TList, ht.TIsLength(2),
- ht.TMap(ht.WithDesc("GetFirstItem")(operator.itemgetter(0)),
+ ht.TMap(ht.WithDesc("GetFirstItem")(compat.fst),
ht.TElemOf(constants.DDMS_VALUES)))))
_TestNicDef = ht.TDictOf(ht.TElemOf(constants.INIC_PARAMS),
ht.TOr(ht.TNone, ht.TNonEmptyString))
+_TSetParamsResultItemItems = [
+ ht.Comment("name of changed parameter")(ht.TNonEmptyString),
+ ht.TAny,
+ ]
+
+_TSetParamsResult = \
+ ht.TListOf(ht.TAnd(ht.TIsLength(len(_TSetParamsResultItemItems)),
+ ht.TItems(_TSetParamsResultItemItems)))
+
_SUMMARY_PREFIX = {
"CLUSTER_": "C_",
"GROUP_": "G_",
TNoRelativeJobDependencies = _BuildJobDepCheck(False)
#: List of submission status and job ID as returned by C{SubmitManyJobs}
-TJobIdList = ht.TListOf(ht.TItems([ht.TBool, ht.TOr(ht.TString, ht.TJobId)]))
+_TJobIdListItem = \
+ ht.TAnd(ht.TIsLength(2),
+ ht.TItems([ht.Comment("success")(ht.TBool),
+ ht.Comment("Job ID if successful, error message"
+ " otherwise")(ht.TOr(ht.TString,
+ ht.TJobId))]))
+TJobIdList = ht.TListOf(_TJobIdListItem)
+
+#: Result containing only list of submitted jobs
+TJobIdListOnly = ht.TStrictDict(True, True, {
+ constants.JOB_IDS_KEY: ht.Comment("List of submitted jobs")(TJobIdList),
+ })
class OpCode(BaseOpCode):
"""Query cluster information."""
+class OpClusterVerify(OpCode):
+ """Submits all jobs necessary to verify the cluster.
+
+ """
+ OP_PARAMS = [
+ _PDebugSimulateErrors,
+ _PErrorCodes,
+ _PSkipChecks,
+ _PVerbose,
+ ("group_name", None, ht.TMaybeString, "Group to verify")
+ ]
+ OP_RESULT = TJobIdListOnly
+
+
class OpClusterVerifyConfig(OpCode):
"""Verify the cluster config.
"""
OP_PARAMS = [
- ("verbose", False, ht.TBool, None),
- ("error_codes", False, ht.TBool, None),
- ("debug_simulate_errors", False, ht.TBool, None),
+ _PDebugSimulateErrors,
+ _PErrorCodes,
+ _PVerbose,
]
+ OP_RESULT = ht.TBool
class OpClusterVerifyGroup(OpCode):
"""
OP_DSC_FIELD = "group_name"
OP_PARAMS = [
- ("group_name", ht.NoDefault, ht.TNonEmptyString, None),
- ("skip_checks", ht.EmptyList,
- ht.TListOf(ht.TElemOf(constants.VERIFY_OPTIONAL_CHECKS)), None),
- ("verbose", False, ht.TBool, None),
- ("error_codes", False, ht.TBool, None),
- ("debug_simulate_errors", False, ht.TBool, None),
+ _PGroupName,
+ _PDebugSimulateErrors,
+ _PErrorCodes,
+ _PSkipChecks,
+ _PVerbose,
]
+ OP_RESULT = ht.TBool
class OpClusterVerifyDisks(OpCode):
"""Verify the cluster disks.
"""
- OP_RESULT = ht.TStrictDict(True, True, {
- constants.JOB_IDS_KEY: TJobIdList,
- })
+ OP_RESULT = TJobIdListOnly
class OpGroupVerifyDisks(OpCode):
@ivar filter: Query filter
"""
+ OP_DSC_FIELD = "what"
OP_PARAMS = [
_PQueryWhat,
+ _PUseLocking,
("fields", ht.NoDefault, ht.TListOf(ht.TNonEmptyString),
"Requested fields"),
("filter", None, ht.TOr(ht.TNone, ht.TListOf),
@ivar fields: List of fields to retrieve
"""
+ OP_DSC_FIELD = "what"
OP_PARAMS = [
_PQueryWhat,
("fields", None, ht.TOr(ht.TNone, ht.TListOf(ht.TNonEmptyString)),
("powered", None, ht.TMaybeBool,
"Whether the node should be marked as powered"),
]
+ OP_RESULT = _TSetParamsResult
class OpNodePowercycle(OpCode):
("mode", ht.NoDefault, ht.TElemOf(constants.IALLOCATOR_NEVAC_MODES),
"Node evacuation mode"),
]
+ OP_RESULT = TJobIdListOnly
# instance opcodes
("start", True, ht.TBool, "Whether to start instance after creation"),
("tags", ht.EmptyList, ht.TListOf(ht.TNonEmptyString), "Instance tags"),
]
+ OP_RESULT = ht.Comment("instance nodes")(ht.TListOf(ht.TNonEmptyString))
class OpInstanceReinstall(OpCode):
("new_name", ht.NoDefault, ht.TNonEmptyString, "New instance name"),
("ip_check", False, ht.TBool, _PIpCheckDoc),
]
+ OP_RESULT = ht.Comment("New instance name")(ht.TNonEmptyString)
class OpInstanceStartup(OpCode):
("wait_for_sync", True, ht.TBool,
"Whether to wait for the disk to synchronize, when changing template"),
]
+ OP_RESULT = _TSetParamsResult
class OpInstanceGrowDisk(OpCode):
]
+class OpInstanceChangeGroup(OpCode):
+ """Moves an instance to another node group."""
+ OP_DSC_FIELD = "instance_name"
+ OP_PARAMS = [
+ _PInstanceName,
+ _PEarlyRelease,
+ ("iallocator", None, ht.TMaybeString, "Iallocator for computing solution"),
+ ("target_groups", None, ht.TOr(ht.TNone, ht.TListOf(ht.TNonEmptyString)),
+ "Destination group names or UUIDs (defaults to \"all but current group\""),
+ ]
+ OP_RESULT = TJobIdListOnly
+
+
# Node group opcodes
class OpGroupAdd(OpCode):
_PNodeGroupAllocPolicy,
_PGroupNodeParams,
]
+ OP_RESULT = _TSetParamsResult
class OpGroupRemove(OpCode):
_PGroupName,
("new_name", ht.NoDefault, ht.TNonEmptyString, "New group name"),
]
+ OP_RESULT = ht.Comment("New group name")(ht.TNonEmptyString)
class OpGroupEvacuate(OpCode):
("target_groups", None, ht.TOr(ht.TNone, ht.TListOf(ht.TNonEmptyString)),
"Destination group names or UUIDs"),
]
+ OP_RESULT = TJobIdListOnly
# OS opcodes
("vcpus", None, ht.TOr(ht.TNone, ht.TPositiveInt), None),
("os", None, ht.TMaybeString, None),
("disk_template", None, ht.TMaybeString, None),
- ("evac_nodes", None, ht.TOr(ht.TNone, ht.TListOf(ht.TNonEmptyString)),
- None),
("instances", None, ht.TOr(ht.TNone, ht.TListOf(ht.TNonEmptyString)),
None),
("evac_mode", None,