Allow modify_etc_hosts to be changed
[ganeti-local] / lib / opcodes.py
index 0978ee5..113f9b0 100644 (file)
@@ -184,16 +184,6 @@ _PTargetGroups = \
   ("target_groups", None, ht.TMaybeListOf(ht.TNonEmptyString),
    "Destination group names or UUIDs (defaults to \"all but current group\")")
 
-# The reason for a state change of an instance
-_PReason = \
-  ("reason", (constants.INSTANCE_REASON_SOURCE_UNKNOWN, None),
-   ht.TAnd(ht.TIsLength(2),
-           ht.TItems([
-             ht.TElemOf(constants.INSTANCE_REASON_SOURCES),
-             ht.TMaybeString,
-           ])),
-   "The reason why the state of the instance is changing")
-
 #: OP_ID conversion regular expression
 _OPID_RE = re.compile("([a-z])([A-Z])")
 
@@ -255,17 +245,16 @@ DEPEND_ATTR = "depends"
 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
@@ -273,7 +262,36 @@ def _NameToId(name):
   # 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):
@@ -641,6 +659,8 @@ class OpCode(BaseOpCode):
      " 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
 
@@ -898,6 +918,7 @@ class OpClusterSetParams(OpCode):
 
   """
   OP_PARAMS = [
+    _PForce,
     _PHvState,
     _PDiskState,
     ("vg_name", None, ht.TMaybe(ht.TString), "Volume group name"),
@@ -958,6 +979,8 @@ class OpClusterSetParams(OpCode):
      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
 
@@ -1465,7 +1488,6 @@ class OpInstanceReboot(OpCode):
      "Whether to start the instance even if secondary disks are failing"),
     ("reboot_type", ht.NoDefault, ht.TElemOf(constants.REBOOT_TYPES),
      "How to reboot instance"),
-    _PReason,
     ]
   OP_RESULT = ht.TNone
 
@@ -1645,7 +1667,8 @@ def _TestInstSetParamsModList(fn):
   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,
       ]))
 
@@ -1667,9 +1690,10 @@ class OpInstanceSetParams(OpCode):
     _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"