X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/24d6d3e2f20f83b66451bdb21a6445fb1aed71c9..958d01f8f739093f752bff4af259f3e9bb7ff4c7:/lib/objects.py diff --git a/lib/objects.py b/lib/objects.py index 06a8dc2..c72bd4a 100644 --- a/lib/objects.py +++ b/lib/objects.py @@ -1,7 +1,7 @@ # # -# Copyright (C) 2006, 2007, 2008, 2009, 2010 Google Inc. +# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 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 @@ -528,6 +528,28 @@ class Disk(ConfigObject): # be different) return result + def ComputeGrowth(self, amount): + """Compute the per-VG growth requirements. + + This only works for VG-based disks. + + @type amount: integer + @param amount: the desired increase in (user-visible) disk space + @rtype: dict + @return: a dictionary of volume-groups and the required size + + """ + if self.dev_type == constants.LD_LV: + return {self.logical_id[0]: amount} + elif self.dev_type == constants.LD_DRBD8: + if self.children: + return self.children[0].ComputeGrowth(amount) + else: + return {} + else: + # Other disk types do not require VG space + return {} + def RecordGrow(self, amount): """Update the size of this disk after growth. @@ -808,7 +830,7 @@ class Instance(TaggableObject): errors.ECODE_INVAL) except IndexError: raise errors.OpPrereqError("Invalid disk index: %d (instace has disks" - " 0 to %d" % (idx, len(self.disks)), + " 0 to %d" % (idx, len(self.disks) - 1), errors.ECODE_INVAL) def ToDict(self): @@ -931,6 +953,7 @@ class Node(TaggableObject): "master_capable", "vm_capable", "ndparams", + "powered", ] + _TIMESTAMPS + _UUID def UpgradeConfig(self): @@ -948,6 +971,9 @@ class Node(TaggableObject): if self.ndparams is None: self.ndparams = {} + if self.powered is None: + self.powered = True + class NodeGroup(ConfigObject): """Config object representing a node group.""" @@ -956,6 +982,7 @@ class NodeGroup(ConfigObject): "members", "ndparams", "serial_no", + "alloc_policy", ] + _TIMESTAMPS + _UUID def ToDict(self): @@ -990,6 +1017,9 @@ class NodeGroup(ConfigObject): if self.serial_no is None: self.serial_no = 1 + if self.alloc_policy is None: + self.alloc_policy = constants.ALLOC_POLICY_PREFERRED + # We only update mtime, and not ctime, since we would not be able to provide # a correct value for creation time. if self.mtime is None: @@ -1093,7 +1123,7 @@ class Cluster(TaggableObject): if self.modify_ssh_setup is None: self.modify_ssh_setup = True - # default_bridge is no longer used it 2.1. The slot is left there to + # default_bridge is no longer used in 2.1. The slot is left there to # support auto-upgrading. It can be removed once we decide to deprecate # upgrading straight from 2.0. if self.default_bridge is not None: @@ -1332,6 +1362,7 @@ class ImportExportOptions(ConfigObject): @ivar compress: Compression method (one of L{constants.IEC_ALL}) @ivar magic: Used to ensure the connection goes to the right disk @ivar ipv6: Whether to use IPv6 + @ivar connect_timeout: Number of seconds for establishing connection """ __slots__ = [ @@ -1340,6 +1371,7 @@ class ImportExportOptions(ConfigObject): "compress", "magic", "ipv6", + "connect_timeout", ] @@ -1392,6 +1424,29 @@ class QueryFieldDefinition(ConfigObject): ] +class _QueryResponseBase(ConfigObject): + __slots__ = [ + "fields", + ] + + def ToDict(self): + """Custom function for serializing. + + """ + mydict = super(_QueryResponseBase, self).ToDict() + mydict["fields"] = self._ContainerToDicts(mydict["fields"]) + return mydict + + @classmethod + def FromDict(cls, val): + """Custom function for de-serializing. + + """ + obj = super(_QueryResponseBase, cls).FromDict(val) + obj.fields = cls._ContainerFromDicts(obj.fields, list, QueryFieldDefinition) + return obj + + class QueryRequest(ConfigObject): """Object holding a query request. @@ -1403,7 +1458,7 @@ class QueryRequest(ConfigObject): ] -class QueryResponse(ConfigObject): +class QueryResponse(_QueryResponseBase): """Object holding the response to a query. @ivar fields: List of L{QueryFieldDefinition} objects @@ -1411,7 +1466,6 @@ class QueryResponse(ConfigObject): """ __slots__ = [ - "fields", "data", ] @@ -1426,17 +1480,50 @@ class QueryFieldsRequest(ConfigObject): ] -class QueryFieldsResponse(ConfigObject): +class QueryFieldsResponse(_QueryResponseBase): """Object holding the response to a query for fields. @ivar fields: List of L{QueryFieldDefinition} objects """ __slots__ = [ - "fields", ] +class InstanceConsole(ConfigObject): + """Object describing how to access the console of an instance. + + """ + __slots__ = [ + "instance", + "kind", + "message", + "host", + "port", + "user", + "command", + "display", + ] + + def Validate(self): + """Validates contents of this object. + + """ + assert self.kind in constants.CONS_ALL, "Unknown console type" + assert self.instance, "Missing instance name" + assert self.message or self.kind in [constants.CONS_SSH, constants.CONS_VNC] + assert self.host or self.kind == constants.CONS_MESSAGE + assert self.port or self.kind in [constants.CONS_MESSAGE, + constants.CONS_SSH] + assert self.user or self.kind in [constants.CONS_MESSAGE, + constants.CONS_VNC] + assert self.command or self.kind in [constants.CONS_MESSAGE, + constants.CONS_VNC] + assert self.display or self.kind in [constants.CONS_MESSAGE, + constants.CONS_SSH] + return True + + class SerializableConfigParser(ConfigParser.SafeConfigParser): """Simple wrapper over ConfigParse that allows serialization.