Improve error message for when adding inotify watcher fails
[ganeti-local] / lib / opcodes.py
index d0dc45f..47216cc 100644 (file)
@@ -159,6 +159,12 @@ _PDiskParams = \
 _PHvState = ("hv_state", None, ht.TMaybeDict, "Set hypervisor states")
 _PDiskState = ("disk_state", None, ht.TMaybeDict, "Set disk states")
 
+#: Opportunistic locking
+_POpportunisticLocking = \
+  ("opportunistic_locking", False, ht.TBool,
+   ("Whether to employ opportunistic locking for nodes, meaning nodes"
+    " already locked by another opcode won't be considered for instance"
+    " allocation (only when an iallocator is used)"))
 
 _PIgnoreIpolicy = ("ignore_ipolicy", False, ht.TBool,
                    "Whether to ignore ipolicy violations")
@@ -167,6 +173,9 @@ _PIgnoreIpolicy = ("ignore_ipolicy", False, ht.TBool,
 _PAllowRuntimeChgs = ("allow_runtime_changes", True, ht.TBool,
                       "Allow runtime changes (eg. memory ballooning)")
 
+#: IAllocator field builder
+_PIAllocFromDesc = lambda desc: ("iallocator", None, ht.TMaybeString, desc)
+
 #: a required network name
 _PNetworkName = ("network_name", ht.NoDefault, ht.TNonEmptyString,
                  "Set network name")
@@ -348,10 +357,6 @@ _PStorageType = ("storage_type", ht.NoDefault, _CheckStorageType,
 
 _CheckNetworkType = ht.TElemOf(constants.NETWORK_VALID_TYPES)
 
-#: Network type parameter
-_PNetworkType = ("network_type", None, ht.TMaybe(_CheckNetworkType),
-                 "Network type")
-
 
 @ht.WithDesc("IPv4 network")
 def _CheckCIDRNetNotation(value):
@@ -555,7 +560,8 @@ def _BuildJobDepCheck(relative):
     job_id = ht.TJobId
 
   job_dep = \
-    ht.TAnd(ht.TIsLength(2),
+    ht.TAnd(ht.TOr(ht.TList, ht.TTuple),
+            ht.TIsLength(2),
             ht.TItems([job_id,
                        ht.TListOf(ht.TElemOf(constants.JOBS_FINALIZED))]))
 
@@ -1200,8 +1206,8 @@ class OpNodeMigrate(OpCode):
     _PMigrationTargetNode,
     _PAllowRuntimeChgs,
     _PIgnoreIpolicy,
-    ("iallocator", None, ht.TMaybeString,
-     "Iallocator for deciding the target node for shared-storage instances"),
+    _PIAllocFromDesc("Iallocator for deciding the target node"
+                     " for shared-storage instances"),
     ]
   OP_RESULT = TJobIdListOnly
 
@@ -1213,7 +1219,7 @@ class OpNodeEvacuate(OpCode):
     _PEarlyRelease,
     _PNodeName,
     ("remote_node", None, ht.TMaybeString, "New secondary node"),
-    ("iallocator", None, ht.TMaybeString, "Iallocator for computing solution"),
+    _PIAllocFromDesc("Iallocator for computing solution"),
     ("mode", ht.NoDefault, ht.TElemOf(constants.NODE_EVAC_MODES),
      "Node evacuation mode"),
     ]
@@ -1241,6 +1247,7 @@ class OpInstanceCreate(OpCode):
     _PWaitForSync,
     _PNameCheck,
     _PIgnoreIpolicy,
+    _POpportunisticLocking,
     ("beparams", ht.EmptyDict, ht.TDict, "Backend parameters for instance"),
     ("disks", ht.NoDefault, ht.TListOf(_TDiskParams),
      "Disk descriptions, for example ``[{\"%s\": 100}, {\"%s\": 5}]``;"
@@ -1259,8 +1266,7 @@ class OpInstanceCreate(OpCode):
     ("hvparams", ht.EmptyDict, ht.TDict,
      "Hypervisor parameters for instance, hypervisor-dependent"),
     ("hypervisor", None, ht.TMaybeString, "Hypervisor"),
-    ("iallocator", None, ht.TMaybeString,
-     "Iallocator for deciding which node(s) to use"),
+    _PIAllocFromDesc("Iallocator for deciding which node(s) to use"),
     ("identify_defaults", False, ht.TBool,
      "Reset instance parameters to default if equal"),
     ("ip_check", True, ht.TBool, _PIpCheckDoc),
@@ -1301,9 +1307,9 @@ class OpInstanceMultiAlloc(OpCode):
 
   """
   OP_PARAMS = [
-    ("iallocator", None, ht.TMaybeString,
-     "Iallocator used to allocate all the instances"),
-    ("instances", [], ht.TListOf(ht.TInstanceOf(OpInstanceCreate)),
+    _POpportunisticLocking,
+    _PIAllocFromDesc("Iallocator used to allocate all the instances"),
+    ("instances", ht.EmptyList, ht.TListOf(ht.TInstanceOf(OpInstanceCreate)),
      "List of instance create opcodes describing the instances to allocate"),
     ]
   _JOB_LIST = ht.Comment("List of submitted jobs")(TJobIdList)
@@ -1340,8 +1346,8 @@ class OpInstanceMultiAlloc(OpCode):
                        type(state))
 
     if "instances" in state:
-      insts = [OpCode.LoadOpCode(inst) for inst in state["instances"]]
-      state["instances"] = insts
+      state["instances"] = map(OpCode.LoadOpCode, state["instances"])
+
     return OpCode.__setstate__(self, state)
 
   def Validate(self, set_defaults):
@@ -1446,8 +1452,7 @@ class OpInstanceReplaceDisks(OpCode):
     ("disks", ht.EmptyList, ht.TListOf(ht.TNonNegativeInt),
      "Disk indexes"),
     ("remote_node", None, ht.TMaybeString, "New secondary node"),
-    ("iallocator", None, ht.TMaybeString,
-     "Iallocator for deciding new secondary node"),
+    _PIAllocFromDesc("Iallocator for deciding new secondary node"),
     ]
   OP_RESULT = ht.TNone
 
@@ -1461,8 +1466,8 @@ class OpInstanceFailover(OpCode):
     _PIgnoreConsistency,
     _PMigrationTargetNode,
     _PIgnoreIpolicy,
-    ("iallocator", None, ht.TMaybeString,
-     "Iallocator for deciding the target node for shared-storage instances"),
+    _PIAllocFromDesc("Iallocator for deciding the target node for"
+                     " shared-storage instances"),
     ]
   OP_RESULT = ht.TNone
 
@@ -1487,8 +1492,8 @@ class OpInstanceMigrate(OpCode):
     _PIgnoreIpolicy,
     ("cleanup", False, ht.TBool,
      "Whether a previously failed migration should be cleaned up"),
-    ("iallocator", None, ht.TMaybeString,
-     "Iallocator for deciding the target node for shared-storage instances"),
+    _PIAllocFromDesc("Iallocator for deciding the target node for"
+                     " shared-storage instances"),
     ("allow_failover", False, ht.TBool,
      "Whether we can fallback to failover if migration is not possible"),
     ]
@@ -1565,8 +1570,7 @@ class OpInstanceRecreateDisks(OpCode):
      " index and a possibly empty dictionary with disk parameter changes"),
     ("nodes", ht.EmptyList, ht.TListOf(ht.TNonEmptyString),
      "New instance nodes, if relocation is desired"),
-    ("iallocator", None, ht.TMaybeString,
-     "Iallocator for deciding new nodes"),
+    _PIAllocFromDesc("Iallocator for deciding new nodes"),
     ]
   OP_RESULT = ht.TNone
 
@@ -1684,7 +1688,7 @@ class OpInstanceChangeGroup(OpCode):
   OP_PARAMS = [
     _PInstanceName,
     _PEarlyRelease,
-    ("iallocator", None, ht.TMaybeString, "Iallocator for computing solution"),
+    _PIAllocFromDesc("Iallocator for computing solution"),
     ("target_groups", None, ht.TMaybeListOf(ht.TNonEmptyString),
      "Destination group names or UUIDs (defaults to \"all but current group\""),
     ]
@@ -1770,7 +1774,7 @@ class OpGroupEvacuate(OpCode):
   OP_PARAMS = [
     _PGroupName,
     _PEarlyRelease,
-    ("iallocator", None, ht.TMaybeString, "Iallocator for computing solution"),
+    _PIAllocFromDesc("Iallocator for computing solution"),
     ("target_groups", None, ht.TMaybeListOf(ht.TNonEmptyString),
      "Destination group names or UUIDs"),
     ]
@@ -1820,11 +1824,12 @@ class OpBackupPrepare(OpCode):
 class OpBackupExport(OpCode):
   """Export an instance.
 
-  For local exports, the export destination is the node name. For remote
-  exports, the export destination is a list of tuples, each consisting of
-  hostname/IP address, port, HMAC and HMAC salt. The HMAC is calculated using
-  the cluster domain secret over the value "${index}:${hostname}:${port}". The
-  destination X509 CA must be a signed certificate.
+  For local exports, the export destination is the node name. For
+  remote exports, the export destination is a list of tuples, each
+  consisting of hostname/IP address, port, magic, HMAC and HMAC
+  salt. The HMAC is calculated using the cluster domain secret over
+  the value "${index}:${hostname}:${port}". The destination X509 CA
+  must be a signed certificate.
 
   @ivar mode: Export mode (one of L{constants.EXPORT_MODES})
   @ivar target_node: Export destination
@@ -1963,7 +1968,7 @@ class OpTestAllocator(OpCode):
       return the allocator output (direction 'out')
 
   """
-  OP_DSC_FIELD = "allocator"
+  OP_DSC_FIELD = "iallocator"
   OP_PARAMS = [
     ("direction", ht.NoDefault,
      ht.TElemOf(constants.VALID_IALLOCATOR_DIRECTIONS), None),
@@ -1977,7 +1982,7 @@ class OpTestAllocator(OpCode):
      None),
     ("disks", ht.NoDefault, ht.TMaybe(ht.TList), None),
     ("hypervisor", None, ht.TMaybeString, None),
-    ("allocator", None, ht.TMaybeString, None),
+    _PIAllocFromDesc(None),
     ("tags", ht.EmptyList, ht.TListOf(ht.TNonEmptyString), None),
     ("memory", None, ht.TMaybe(ht.TNonNegativeInt), None),
     ("vcpus", None, ht.TMaybe(ht.TNonNegativeInt), None),
@@ -2024,7 +2029,7 @@ class OpNetworkAdd(OpCode):
   OP_DSC_FIELD = "network_name"
   OP_PARAMS = [
     _PNetworkName,
-    _PNetworkType,
+    ("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"),
@@ -2033,6 +2038,8 @@ class OpNetworkAdd(OpCode):
      "MAC address prefix that overrides cluster one"),
     ("add_reserved_ips", None, _TMaybeAddr4List,
      "Which IP addresses to reserve"),
+    ("conflicts_check", True, ht.TBool,
+     "Whether to check for conflicting IP addresses"),
     ("tags", ht.EmptyList, ht.TListOf(ht.TNonEmptyString), "Network tags"),
     ]
   OP_RESULT = ht.TNone
@@ -2056,11 +2063,12 @@ class OpNetworkSetParams(OpCode):
   OP_DSC_FIELD = "network_name"
   OP_PARAMS = [
     _PNetworkName,
-    _PNetworkType,
-    ("gateway", None, ht.TMaybe(_TIpAddress4), "IPv4 gateway"),
-    ("network6", None, ht.TMaybe(_TIpNetwork6), "IPv6 subnet"),
-    ("gateway6", None, ht.TMaybe(_TIpAddress6), "IPv6 gateway"),
-    ("mac_prefix", None, ht.TMaybeString,
+    ("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"),
+    ("mac_prefix", None, ht.TMaybeValueNone(ht.TString),
      "MAC address prefix that overrides cluster one"),
     ("add_reserved_ips", None, _TMaybeAddr4List,
      "Which external IP addresses to reserve"),