#
#
-# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Google Inc.
+# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 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
from ganeti import errors
from ganeti import ht
from ganeti import objects
-from ganeti import objectutils
+from ganeti import outils
# Common opcode attributes
COMMENT_ATTR = "comment"
-def _NameToId(name):
- """Convert an opcode class name to an OP_ID.
+def _NameComponents(name):
+ """Split an opcode class name into its components
@type name: string
@param name: the class name, as OpXxxYyy
- @rtype: string
- @return: the name in the OP_XXXX_YYYY format
+ @rtype: array of strings
+ @return: the components of the name
"""
- if not name.startswith("Op"):
- return None
+ assert name.startswith("Op")
# Note: (?<=[a-z])(?=[A-Z]) would be ideal, since it wouldn't
# consume any input, and hence we would just have all the elements
# in the list, one by one; but it seems that split doesn't work on
# bit
name = _OPID_RE.sub(r"\1,\2", name)
elems = name.split(",")
- return "_".join(n.upper() for n in elems)
+ return elems
+
+
+def _NameToId(name):
+ """Convert an opcode class name to an OP_ID.
+
+ @type name: string
+ @param name: the class name, as OpXxxYyy
+ @rtype: string
+ @return: the name in the OP_XXXX_YYYY format
+
+ """
+ if not name.startswith("Op"):
+ return None
+ return "_".join(n.upper() for n in _NameComponents(name))
+
+
+def NameToReasonSrc(name):
+ """Convert an opcode class name to a source string for the reason trail
+
+ @type name: string
+ @param name: the class name, as OpXxxYyy
+ @rtype: string
+ @return: the name in the OP_XXXX_YYYY format
+
+ """
+ if not name.startswith("Op"):
+ return None
+ return "%s:%s" % (constants.OPCODE_REASON_SRC_OPCODE,
+ "_".join(n.lower() for n in _NameComponents(name)))
def _GenerateObjectTypeCheck(obj, fields_types):
_PStorageType = ("storage_type", ht.NoDefault, _CheckStorageType,
"Storage type")
-_CheckNetworkType = ht.TElemOf(constants.NETWORK_VALID_TYPES)
-
@ht.WithDesc("IPv4 network")
def _CheckCIDRNetNotation(value):
_TMaybeAddr4List = ht.TMaybe(ht.TListOf(_TIpAddress4))
-class _AutoOpParamSlots(objectutils.AutoSlots):
+class _AutoOpParamSlots(outils.AutoSlots):
"""Meta class for opcode definitions.
"""
attrs["OP_ID"] = _NameToId(name)
- return objectutils.AutoSlots.__new__(mcs, name, bases, attrs)
+ return outils.AutoSlots.__new__(mcs, name, bases, attrs)
@classmethod
def _GetSlots(mcs, attrs):
return [pname for (pname, _, _, _) in params]
-class BaseOpCode(objectutils.ValidatedSlots):
+class BaseOpCode(outils.ValidatedSlots):
"""A simple serializable object.
This object serves as a parent class for OpCode without any custom
" for details"),
(COMMENT_ATTR, None, ht.TMaybeString,
"Comment describing the purpose of the opcode"),
+ (constants.OPCODE_REASON, None, ht.TMaybeList,
+ "The reason trail, describing why the OpCode is executed"),
]
OP_RESULT = None
"""
OP_PARAMS = [
+ _PForce,
_PHvState,
_PDiskState,
("vg_name", None, ht.TMaybe(ht.TString), "Volume group name"),
" ``%s`` or ``%s``" % (constants.DDM_ADD, constants.DDM_REMOVE)),
("use_external_mip_script", None, ht.TMaybeBool,
"Whether to use an external master IP address setup script"),
+ ("enabled_disk_templates", None,
+ ht.TMaybe(ht.TAnd(ht.TListOf(ht.TElemOf(constants.DISK_TEMPLATES)),
+ ht.TTrue)),
+ "List of enabled disk templates"),
+ ("modify_etc_hosts", None, ht.TMaybeBool,
+ "Whether the cluster can modify and keep in sync the /etc/hosts files"),
]
OP_RESULT = ht.TNone
mod_item_fn = \
ht.TAnd(ht.TIsLength(3), ht.TItems([
ht.TElemOf(constants.DDMS_VALUES_WITH_MODIFY),
- ht.Comment("Disk index, can be negative, e.g. -1 for last disk")(ht.TInt),
+ ht.Comment("Device index, can be negative, e.g. -1 for last disk")
+ (ht.TOr(ht.TInt, ht.TString)),
fn,
]))
_PForceVariant,
_PIgnoreIpolicy,
("nics", ht.EmptyList, TestNicModifications,
- "List of NIC changes: each item is of the form ``(op, index, settings)``,"
- " ``op`` is one of ``%s``, ``%s`` or ``%s``, ``index`` can be either -1"
- " to refer to the last position, or a zero-based index number; a"
+ "List of NIC changes: each item is of the form"
+ " ``(op, identifier, settings)``, ``op`` is one of ``%s``, ``%s`` or"
+ " ``%s``, ``identifier`` can be a zero-based index number (or -1 to refer"
+ " to the last position), the NIC's UUID of the NIC's name; a"
" deprecated version of this parameter used the form ``(op, settings)``,"
" where ``op`` can be ``%s`` to add a new NIC with the specified"
" settings, ``%s`` to remove the last NIC or a number to modify the"
"Per-instance hypervisor parameters, hypervisor-dependent"),
("disk_template", None, ht.TMaybe(_BuildDiskTemplateCheck(False)),
"Disk template for instance"),
+ ("pnode", None, ht.TMaybeString, "New primary node"),
("remote_node", None, ht.TMaybeString,
"Secondary node (used when changing disk template)"),
("os_name", None, ht.TMaybeString,
This is used just for debugging and testing.
Parameters:
- - duration: the time to sleep
+ - duration: the time to sleep, in seconds
- on_master: if true, sleep on the master
- on_nodes: list of nodes in which to sleep
OP_DSC_FIELD = "network_name"
OP_PARAMS = [
_PNetworkName,
- ("network_type", None, ht.TMaybe(_CheckNetworkType), "Network type"),
("network", ht.NoDefault, _TIpNetwork4, "IPv4 subnet"),
("gateway", None, ht.TMaybe(_TIpAddress4), "IPv4 gateway"),
("network6", None, ht.TMaybe(_TIpNetwork6), "IPv6 subnet"),
OP_DSC_FIELD = "network_name"
OP_PARAMS = [
_PNetworkName,
- ("network_type", None, ht.TMaybeValueNone(_CheckNetworkType),
- "Network type"),
("gateway", None, ht.TMaybeValueNone(_TIpAddress4), "IPv4 gateway"),
("network6", None, ht.TMaybeValueNone(_TIpNetwork6), "IPv6 subnet"),
("gateway6", None, ht.TMaybeValueNone(_TIpAddress6), "IPv6 gateway"),
OP_PARAMS = [
_PGroupName,
_PNetworkName,
- ("conflicts_check", True, ht.TBool, "Whether to check for conflicting IPs"),
]
OP_RESULT = ht.TNone