+class _QaInstance(object):
+ __slots__ = [
+ "name",
+ "nicmac",
+ "_used",
+ "_disk_template",
+ ]
+
+ def __init__(self, name, nicmac):
+ """Initializes instances of this class.
+
+ """
+ self.name = name
+ self.nicmac = nicmac
+ self._used = None
+ self._disk_template = None
+
+ @classmethod
+ def FromDict(cls, data):
+ """Creates instance object from JSON dictionary.
+
+ """
+ nicmac = []
+
+ macaddr = data.get("nic.mac/0")
+ if macaddr:
+ nicmac.append(macaddr)
+
+ return cls(name=data["name"], nicmac=nicmac)
+
+ def __repr__(self):
+ status = [
+ "%s.%s" % (self.__class__.__module__, self.__class__.__name__),
+ "name=%s" % self.name,
+ "nicmac=%s" % self.nicmac,
+ "used=%s" % self._used,
+ "disk_template=%s" % self._disk_template,
+ ]
+
+ return "<%s at %#x>" % (" ".join(status), id(self))
+
+ def Use(self):
+ """Marks instance as being in use.
+
+ """
+ assert not self._used
+ assert self._disk_template is None
+
+ self._used = True
+
+ def Release(self):
+ """Releases instance and makes it available again.
+
+ """
+ assert self._used, \
+ ("Instance '%s' was never acquired or released more than once" %
+ self.name)
+
+ self._used = False
+ self._disk_template = None
+
+ def GetNicMacAddr(self, idx, default):
+ """Returns MAC address for NIC.
+
+ @type idx: int
+ @param idx: NIC index
+ @param default: Default value
+
+ """
+ if len(self.nicmac) > idx:
+ return self.nicmac[idx]
+ else:
+ return default
+
+ def SetDiskTemplate(self, template):
+ """Set the disk template.
+
+ """
+ assert template in constants.DISK_TEMPLATES
+
+ self._disk_template = template
+
+ @property
+ def used(self):
+ """Returns boolean denoting whether instance is in use.
+
+ """
+ return self._used
+
+ @property
+ def disk_template(self):
+ """Returns the current disk template.
+
+ """
+ return self._disk_template
+
+
+class _QaNode(object):
+ __slots__ = [
+ "primary",
+ "secondary",
+ "_added",
+ "_use_count",
+ ]
+
+ def __init__(self, primary, secondary):
+ """Initializes instances of this class.
+
+ """
+ self.primary = primary
+ self.secondary = secondary
+ self._added = False
+ self._use_count = 0
+
+ @classmethod
+ def FromDict(cls, data):
+ """Creates node object from JSON dictionary.
+
+ """
+ return cls(primary=data["primary"], secondary=data.get("secondary"))
+
+ def __repr__(self):
+ status = [
+ "%s.%s" % (self.__class__.__module__, self.__class__.__name__),
+ "primary=%s" % self.primary,
+ "secondary=%s" % self.secondary,
+ "added=%s" % self._added,
+ "use_count=%s" % self._use_count,
+ ]
+
+ return "<%s at %#x>" % (" ".join(status), id(self))
+
+ def Use(self):
+ """Marks a node as being in use.
+
+ """
+ assert self._use_count >= 0
+
+ self._use_count += 1
+
+ return self
+
+ def Release(self):
+ """Release a node (opposite of L{Use}).
+
+ """
+ assert self.use_count > 0
+
+ self._use_count -= 1
+
+ def MarkAdded(self):
+ """Marks node as having been added to a cluster.
+
+ """
+ assert not self._added
+ self._added = True
+
+ def MarkRemoved(self):
+ """Marks node as having been removed from a cluster.
+
+ """
+ assert self._added
+ self._added = False
+
+ @property
+ def added(self):
+ """Returns whether a node is part of a cluster.
+
+ """
+ return self._added
+
+ @property
+ def use_count(self):
+ """Returns number of current uses (controlled by L{Use} and L{Release}).
+
+ """
+ return self._use_count
+
+
+_RESOURCE_CONVERTER = {
+ "instances": _QaInstance.FromDict,
+ "nodes": _QaNode.FromDict,
+ }
+
+
+def _ConvertResources((key, value)):
+ """Converts cluster resources in configuration to Python objects.
+
+ """
+ fn = _RESOURCE_CONVERTER.get(key, None)
+ if fn:
+ return (key, map(fn, value))
+ else:
+ return (key, value)
+
+