direct-io.hg

view tools/python/xen/xend/XendVDI.py @ 14449:e2f302488983

Add VBD.runtime_properties dictionary, and use that to implement xm block-list
through the Xen-API. Implement xm block-attach and xm block-detach also.

Signed-off-by: Tom Wilkie <tom.wilkie@gmail.com>
author Ewan Mellor <ewan@xensource.com>
date Tue Mar 20 11:45:44 2007 +0000 (2007-03-20)
parents 2adbc1d22fe7
children aa640601575f
line source
1 #!/usr/bin/python
2 #============================================================================
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of version 2.1 of the GNU Lesser General Public
5 # License as published by the Free Software Foundation.
6 #
7 # This library is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 # Lesser General Public License for more details.
11 #
12 # You should have received a copy of the GNU Lesser General Public
13 # License along with this library; if not, write to the Free Software
14 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 #============================================================================
16 # Copyright (C) 2006 XenSource Ltd.
17 #============================================================================
18 #
19 # Representation of a Xen API VDI
20 #
22 import os
24 from xen.util.xmlrpclib2 import stringify
25 from xmlrpclib import dumps, loads
27 KB = 1024
28 MB = 1024 * 1024
30 class AutoSaveObject(object):
32 def __init__(self):
33 self.cfg_path = None
34 self.auto_save = True
35 object
37 def save_config(self, cfg_file = None):
38 raise NotImplementedError()
40 def __setattr__(self, name, value):
41 """A very simple way of making sure all attribute changes are
42 flushed to disk.
43 """
44 object.__setattr__(self, name, value)
45 if name != 'auto_save' and getattr(self, 'auto_save', False):
46 self.save_config()
48 class XendVDI(AutoSaveObject):
49 """Generic Xen API compatible VDI representation.
51 @cvar SAVED_CFG: list of configuration attributes to save.
52 @cvar SAVED_CFG_INT: list of configurations that should be ints.
53 """
55 SAVED_CFG = ['name_label',
56 'name_description',
57 'virtual_size',
58 'physical_utilisation',
59 'sharable',
60 'read_only']
62 SAVED_CFG_INT = ['sector_size', 'virtual_size', 'physical_utilisation']
64 def __init__(self, uuid, sr_uuid):
65 self.uuid = uuid
66 self.sr_uuid = sr_uuid
67 self.name_label = ""
68 self.name_description = ""
69 self.virtual_size = 0
70 self.physical_utilisation = 0
71 self.sharable = False
72 self.read_only = False
73 self.type = "system"
74 self.other_config = {}
75 self.vbds = []
77 def addVBD(self, vbd_ref):
78 self.vbds.append(vbd_ref)
80 def removeVBD(self, vbd_ref):
81 self.vbds.remove(vbd_ref)
83 def getVBDs(self):
84 return self.vbds
86 def load_config_dict(self, cfg):
87 """Loads configuration into the object from a dict.
89 @param cfg: configuration dict
90 @type cfg: dict
91 """
92 self.auto_save = False
93 for key in self.SAVED_CFG:
94 if key in cfg:
95 if key in self.SAVED_CFG_INT:
96 setattr(self, key, int(cfg[key]))
97 else:
98 setattr(self, key, cfg[key])
99 self.auto_save = True
101 def load_config(self, cfg_path):
102 """Loads configuration from an XMLRPC parameter format.
104 @param cfg_path: configuration file path
105 @type cfg_path: type
106 @rtype: bool
107 @return: Successful or not.
108 """
109 try:
110 cfg, _ = loads(open(cfg_path).read())
111 cfg = cfg[0]
112 self.load_config_dict(cfg)
113 self.cfg_path = cfg_path
114 except IOError, e:
115 return False
117 return True
119 def save_config(self, cfg_path = None):
120 """Saves configuration at give path in XMLRPC parameter format.
122 If cfg_path is not give, it defaults to the where the VDI
123 configuration as loaded if it load_config was called.
125 @keyword cfg_path: optional configuration file path
126 @rtype: bool
127 @return: Successful or not.
128 """
129 try:
130 if not cfg_path and not self.cfg_path:
131 return False
133 if not cfg_path:
134 cfg_path = self.cfg_path
136 cfg = {}
137 for key in self.SAVED_CFG:
138 try:
139 cfg[key] = getattr(self, key)
140 except AttributeError:
141 pass
142 open(cfg_path, 'w').write(dumps((stringify(cfg),),
143 allow_none = True))
144 except IOError, e:
145 return False
147 return True
149 def get_record(self, transient = True):
150 return {'uuid': self.uuid,
151 'name_label': self.name_label,
152 'name_description': self.name_description,
153 'virtual_size': self.virtual_size,
154 'physical_utilisation': self.physical_utilisation,
155 'sharable': False,
156 'readonly': False,
157 'SR': self.sr_uuid,
158 'other_config': self.other_config,
159 'VBDs': []}
161 def get_location(self):
162 raise NotImplementedError()
165 class XendQCoWVDI(XendVDI):
166 def __init__(self, uuid, sr_uuid, qcow_path, cfg_path, vsize, psize):
167 XendVDI.__init__(self, uuid, sr_uuid)
168 self.auto_save = False
169 self.qcow_path = qcow_path
170 self.cfg_path = cfg_path
171 self.physical_utilisation = psize
172 self.virtual_size = vsize
173 self.auto_save = True
174 self.other_config['location'] = 'tap:qcow:%s' % self.qcow_path
176 def get_location(self):
177 return self.other_config['location']
179 class XendLocalVDI(XendVDI):
180 def __init__(self, vdi_struct):
181 vdi_uuid = vdi_struct['uuid']
182 sr_uuid = vdi_struct['SR']
183 XendVDI.__init__(self, vdi_uuid, sr_uuid)
185 self.auto_save = False
186 self.cfg_path = None
187 self.name_label = vdi_struct.get('name_label','')
188 self.name_description = vdi_struct.get('name_description', '')
189 self.physical_utilisation = 0
190 self.virtual_size = 0
191 self.type = vdi_struct.get('type', '')
192 self.sharable = vdi_struct.get('sharable', False)
193 self.read_only = vdi_struct.get('read_only', False)
194 self.other_config = vdi_struct.get('other_config', {})
196 def get_location(self):
197 return self.other_config['location']