Separate checks for std spec compliance
[ganeti-local] / lib / opcodes.py
index 969fe71..ee4da31 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
 
@@ -954,10 +974,10 @@ class OpClusterSetParams(OpCode):
      " ``%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_storage_types", None,
-     ht.TMaybe(ht.TAnd(ht.TListOf(ht.TElemOf(constants.VALID_STORAGE_TYPES)),
+    ("enabled_disk_templates", None,
+     ht.TMaybe(ht.TAnd(ht.TListOf(ht.TElemOf(constants.DISK_TEMPLATES)),
                        ht.TTrue)),
-     "List of enabled storage types"),
+     "List of enabled disk templates"),
     ]
   OP_RESULT = ht.TNone
 
@@ -1465,7 +1485,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 +1664,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 +1687,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"
@@ -1684,6 +1705,7 @@ class OpInstanceSetParams(OpCode):
      "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,