ia64/xen-unstable

view tools/python/xen/xend/XendAPI.py @ 12642:33951d547223

Plumb the "start_paused" flag through for VM.start and VM.resume. Do not
unpause the VM on start by default. This should fix problems seen recently
whereby devices are not attached to the VM by the time they boot, as
xm create was expecting to be able to wait for the devices before unpausing.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Tue Nov 28 17:28:43 2006 +0000 (2006-11-28)
parents 1fce8221d473
children 5bed7bc05c8a
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2006 XenSource Ltd.
16 #============================================================================
18 from xen.xend import XendDomain, XendDomainInfo, XendNode
19 from xen.xend import XendLogging
21 from xen.xend.XendAuthSessions import instance as auth_manager
22 from xen.xend.XendAuthSessions import session_required
23 from xen.xend.XendError import *
24 from xen.xend.XendClient import ERROR_INVALID_DOMAIN
25 from xen.xend.XendLogging import log
27 from xen.xend.XendAPIConstants import *
28 from xen.util.xmlrpclib2 import stringify
30 AUTH_NONE = 'none'
31 AUTH_PAM = 'pam'
33 # ------------------------------------------
34 # Utility Methods for Xen API Implementation
35 # ------------------------------------------
37 def xen_api_success(value):
38 """Wraps a return value in XenAPI format."""
39 return {"Status": "Success", "Value": stringify(value)}
41 def xen_api_success_void():
42 """Return success, but caller expects no return value."""
43 return xen_api_success("")
45 def xen_api_error(error):
46 """Wraps an error value in XenAPI format."""
47 return {"Status": "Error", "ErrorDescription": error}
49 def xen_api_todo():
50 """Temporary method to make sure we track down all the TODOs"""
51 return {"Status": "Error", "ErrorDescription": XEND_ERROR_TODO}
53 # ---------------------------------------------------
54 # Python Method Decorators for input value validation
55 # ---------------------------------------------------
57 def trace(func, api_name = ''):
58 """Decorator to trace XMLRPC Xen API methods.
60 @param func: function with any parameters
61 @param api_name: name of the api call for debugging.
62 """
63 if hasattr(func, 'api'):
64 api_name = func.api
65 def trace_func(self, *args, **kwargs):
66 log.debug('%s: %s' % (api_name, args))
67 return func(self, *args, **kwargs)
68 trace_func.api = api_name
69 return trace_func
71 def valid_host(func):
72 """Decorator to verify if host_ref is valid before calling
73 method.
75 @param func: function with params: (self, session, host_ref)
76 @rtype: callable object
77 """
78 def check_host_ref(self, session, host_ref, *args, **kwargs):
79 xennode = XendNode.instance()
80 if type(host_ref) == type(str()) and xennode.is_valid_host(host_ref):
81 return func(self, session, host_ref, *args, **kwargs)
82 else:
83 return {'Status': 'Failure',
84 'ErrorDescription': XEND_ERROR_HOST_INVALID}
86 # make sure we keep the 'api' attribute
87 if hasattr(func, 'api'):
88 check_host_ref.api = func.api
90 return check_host_ref
92 def valid_host_cpu(func):
93 """Decorator to verify if host_cpu_ref is valid before calling
94 method.
96 @param func: function with params: (self, session, host_cpu_ref)
97 @rtype: callable object
98 """
99 def check_host_cpu_ref(self, session, host_cpu_ref, *args, **kwargs):
100 xennode = XendNode.instance()
101 if type(host_cpu_ref) == type(str()) and \
102 xennode.is_valid_cpu(host_cpu_ref):
103 return func(self, session, host_cpu_ref, *args, **kwargs)
104 else:
105 return {'Status': 'Failure',
106 'ErrorDescription': XEND_ERROR_HOST_CPU_INVALID}
108 # make sure we keep the 'api' attribute
109 if hasattr(func, 'api'):
110 check_host_cpu_ref.api = func.api
112 return check_host_cpu_ref
114 def valid_vm(func):
115 """Decorator to verify if vm_ref is valid before calling
116 method.
118 @param func: function with params: (self, session, vm_ref)
119 @rtype: callable object
120 """
121 def check_vm_ref(self, session, vm_ref, *args, **kwargs):
122 xendom = XendDomain.instance()
123 if type(vm_ref) == type(str()) and \
124 xendom.is_valid_vm(vm_ref):
125 return func(self, session, vm_ref, *args, **kwargs)
126 else:
127 return {'Status': 'Failure',
128 'ErrorDescription': XEND_ERROR_VM_INVALID}
130 # make sure we keep the 'api' attribute
131 if hasattr(func, 'api'):
132 check_vm_ref.api = func.api
134 return check_vm_ref
136 def valid_vbd(func):
137 """Decorator to verify if vbd_ref is valid before calling
138 method.
140 @param func: function with params: (self, session, vbd_ref)
141 @rtype: callable object
142 """
143 def check_vbd_ref(self, session, vbd_ref, *args, **kwargs):
144 xendom = XendDomain.instance()
145 if type(vbd_ref) == type(str()) and \
146 xendom.is_valid_dev('vbd', vbd_ref):
147 return func(self, session, vbd_ref, *args, **kwargs)
148 else:
149 return {'Status': 'Failure',
150 'ErrorDescription': XEND_ERROR_VBD_INVALID}
152 # make sure we keep the 'api' attribute
153 if hasattr(func, 'api'):
154 check_vbd_ref.api = func.api
156 return check_vbd_ref
158 def valid_vif(func):
159 """Decorator to verify if vif_ref is valid before calling
160 method.
162 @param func: function with params: (self, session, vif_ref)
163 @rtype: callable object
164 """
165 def check_vif_ref(self, session, vif_ref, *args, **kwargs):
166 xendom = XendDomain.instance()
167 if type(vif_ref) == type(str()) and \
168 xendom.is_valid_dev('vif', vif_ref):
169 return func(self, session, vif_ref, *args, **kwargs)
170 else:
171 return {'Status': 'Failure',
172 'ErrorDescription': XEND_ERROR_VIF_INVALID}
174 # make sure we keep the 'api' attribute
175 if hasattr(func, 'api'):
176 check_vif_ref.api = func.api
178 return check_vif_ref
181 def valid_vdi(func):
182 """Decorator to verify if vdi_ref is valid before calling
183 method.
185 @param func: function with params: (self, session, vdi_ref)
186 @rtype: callable object
187 """
188 def check_vdi_ref(self, session, vdi_ref, *args, **kwargs):
189 xennode = XendNode.instance()
190 if type(vdi_ref) == type(str()) and \
191 xennode.get_sr().is_valid_vdi(vdi_ref):
192 return func(self, session, vdi_ref, *args, **kwargs)
193 else:
194 return {'Status': 'Failure',
195 'ErrorDescription': XEND_ERROR_VDI_INVALID}
197 # make sure we keep the 'api' attribute
198 if hasattr(func, 'api'):
199 check_vdi_ref.api = func.api
201 return check_vdi_ref
203 def valid_vtpm(func):
204 """Decorator to verify if vtpm_ref is valid before calling
205 method.
207 @param func: function with params: (self, session, vtpm_ref)
208 @rtype: callable object
209 """
210 def check_vtpm_ref(self, session, vtpm_ref, *args, **kwargs):
211 xendom = XendDomain.instance()
212 if type(vtpm_ref) == type(str()) and \
213 xendom.is_valid_dev('vtpm', vtpm_ref):
214 return func(self, session, vtpm_ref, *args, **kwargs)
215 else:
216 return {'Status': 'Failure',
217 'ErrorDescription': XEND_ERROR_VTPM_INVALID}
219 # make sure we keep the 'api' attribute
220 if hasattr(func, 'api'):
221 check_vtpm_ref.api = func.api
223 return check_vtpm_ref
225 def valid_sr(func):
226 """Decorator to verify if sr_ref is valid before calling
227 method.
229 @param func: function with params: (self, session, sr_ref)
230 @rtype: callable object
231 """
232 def check_sr_ref(self, session, sr_ref, *args, **kwargs):
233 xennode = XendNode.instance()
234 if type(sr_ref) == type(str()) and \
235 xennode.get_sr().uuid == sr_ref:
236 return func(self, session, sr_ref, *args, **kwargs)
237 else:
238 return {'Status': 'Failure',
239 'ErrorDescription': XEND_ERROR_SR_INVALID}
241 # make sure we keep the 'api' attribute
242 if hasattr(func, 'api'):
243 check_sr_ref.api = func.api
245 return check_sr_ref
247 # -----------------------------
248 # Bridge to Legacy XM API calls
249 # -----------------------------
251 def do_vm_func(fn_name, vm_ref, *args, **kwargs):
252 """Helper wrapper func to abstract away from repetitive code.
254 @param fn_name: function name for XendDomain instance
255 @type fn_name: string
256 @param vm_ref: vm_ref
257 @type vm_ref: string
258 @param *args: more arguments
259 @type *args: tuple
260 """
261 xendom = XendDomain.instance()
262 fn = getattr(xendom, fn_name)
263 xendom.do_legacy_api_with_uuid(fn, vm_ref, *args, **kwargs)
264 return xen_api_success_void()
267 class XendAPI:
268 """Implementation of the Xen-API in Xend. Expects to be
269 used via XMLRPCServer.
271 All methods that need a valid session are marked with
272 a L{XendAuthManager.session_required} decorator that will
273 transparently perform the required session authentication.
275 We need to support Python <2.4, so we use the old decorator syntax.
277 All XMLRPC accessible methods require an 'api' attribute and
278 is set to the XMLRPC function name which the method implements.
279 """
281 def __init__(self, auth):
282 """Initialised Xen API wrapper by making sure all functions
283 have the correct validation decorators such as L{valid_host}
284 and L{session_required}.
285 """
286 self.auth = auth
288 classes = {
289 'session': (session_required,),
290 'host': (valid_host, session_required),
291 'host_cpu': (valid_host_cpu, session_required),
292 'VM': (valid_vm, session_required),
293 'VBD': (valid_vbd, session_required),
294 'VIF': (valid_vif, session_required),
295 'VDI': (valid_vdi, session_required),
296 'VTPM':(valid_vtpm, session_required),
297 'SR': (valid_sr, session_required)}
299 # Cheat methods
300 # -------------
301 # Methods that have a trivial implementation for all classes.
302 # 1. get_by_uuid == getting by ref, so just return uuid for
303 # all get_by_uuid() methods.
305 for cls in classes.keys():
306 get_by_uuid = '%s_get_by_uuid' % cls.lower()
307 get_uuid = '%s_get_uuid' % cls.lower()
308 setattr(XendAPI, get_by_uuid,
309 lambda s, sess, obj_ref: xen_api_success(obj_ref))
310 setattr(XendAPI, get_uuid,
311 lambda s, sess, obj_ref: xen_api_success(obj_ref))
313 # 2. get_record is just getting all the attributes, so provide
314 # a fake template implementation.
315 #
316 # TODO: ...
319 # Wrapping validators around XMLRPC calls
320 # ---------------------------------------
322 for cls, validators in classes.items():
323 ro_attrs = getattr(self, '%s_attr_ro' % cls, [])
324 rw_attrs = getattr(self, '%s_attr_rw' % cls, [])
325 methods = getattr(self, '%s_methods' % cls, [])
326 funcs = getattr(self, '%s_funcs' % cls, [])
328 # wrap validators around readable class attributes
329 for attr_name in ro_attrs + rw_attrs + self.Base_attr_ro:
330 getter_name = '%s_get_%s' % (cls.lower(), attr_name)
331 try:
332 getter = getattr(XendAPI, getter_name)
333 for validator in validators:
334 getter = validator(getter)
335 getter.api = '%s.get_%s' % (cls, attr_name)
336 setattr(XendAPI, getter_name, getter)
337 except AttributeError:
338 pass
339 #log.warn("API call: %s not found" % getter_name)
341 # wrap validators around writable class attrributes
342 for attr_name in rw_attrs + self.Base_attr_rw:
343 setter_name = '%s_set_%s' % (cls.lower(), attr_name)
344 try:
345 setter = getattr(XendAPI, setter_name)
346 for validator in validators:
347 setter = validator(setter)
348 setter.api = '%s.set_%s' % (cls, attr_name)
349 setattr(XendAPI, setter_name, setter)
350 except AttributeError:
351 pass
352 #log.warn("API call: %s not found" % setter_name)
354 # wrap validators around methods
355 for method_name in methods + self.Base_methods:
356 method_full_name = '%s_%s' % (cls.lower(), method_name)
357 try:
358 method = getattr(XendAPI, method_full_name)
359 for validator in validators:
360 method = validator(method)
361 method.api = '%s.%s' % (cls, method_name)
362 setattr(XendAPI, method_full_name, method)
363 except AttributeError:
364 pass
365 #log.warn('API call: %s not found' % method_full_name)
367 # wrap validators around class functions
368 for func_name in funcs + self.Base_funcs:
369 func_full_name = '%s_%s' % (cls.lower(), func_name)
370 try:
371 method = getattr(XendAPI, func_full_name)
372 method = session_required(method)
373 method.api = '%s.%s' % (cls, func_name)
374 setattr(XendAPI, func_full_name, method)
375 except AttributeError:
376 pass
377 #log.warn('API call: %s not found' % func_full_name)
380 Base_attr_ro = ['uuid']
381 Base_attr_rw = []
382 Base_methods = ['destroy', 'to_XML', 'get_record']
383 Base_funcs = ['create', 'get_by_uuid', 'get_all']
385 # Xen API: Class Session
386 # ----------------------------------------------------------------
387 # NOTE: Left unwrapped by __init__
389 session_attr_ro = ['this_host', 'this_user']
390 session_methods = ['logout']
391 # session_funcs = ['login_with_password']
393 def session_login_with_password(self, username, password):
394 try:
395 session = (self.auth == AUTH_NONE and
396 auth_manager().login_unconditionally(username) or
397 auth_manager().login_with_password(username, password))
398 return xen_api_success(session)
399 except XendError, e:
400 return xen_api_error(XEND_ERROR_AUTHENTICATION_FAILED)
401 session_login_with_password.api = 'session.login_with_password'
404 # object methods
405 def session_logout(self, session):
406 auth_manager().logout(session)
407 return xen_api_success_void()
408 def session_destroy(self, session):
409 return xen_api_error(XEND_ERROR_UNSUPPORTED)
410 def session_get_record(self, session):
411 record = {'this_host': XendNode.instance().uuid,
412 'this_user': auth_manager().get_user(session)}
413 return xen_api_success(record)
414 def session_to_XML(self, session):
415 return xen_api_todo()
417 # attributes (ro)
418 def session_get_this_host(self, session):
419 return xen_api_success(XendNode.instance().uuid)
420 def session_get_this_user(self, session):
421 user = auth_manager().get_user(session)
422 if user:
423 return xen_api_success(user)
424 return xen_api_error(XEND_ERROR_SESSION_INVALID)
427 # Xen API: Class User
428 # ----------------------------------------------------------------
429 # TODO: NOT IMPLEMENTED YET
431 # Xen API: Class Tasks
432 # ----------------------------------------------------------------
433 # TODO: NOT IMPLEMENTED YET
435 # Xen API: Class Host
436 # ----------------------------------------------------------------
438 host_attr_ro = ['software_version',
439 'resident_VMs',
440 'host_CPUs']
442 host_attr_rw = ['name_label',
443 'name_description']
445 host_methods = ['disable',
446 'enable',
447 'reboot',
448 'shutdown']
450 host_funcs = ['get_by_name_label']
452 # attributes
453 def host_get_name_label(self, session, host_ref):
454 return xen_api_success(XendNode.instance().name)
455 def host_set_name_label(self, session, host_ref, new_name):
456 XendNode.instance().set_name(new_name)
457 return xen_api_success_void()
458 def host_get_name_description(self, session, host_ref):
459 return xen_api_success(XendNode.instance().description)
460 def host_set_name_description(self, session, host_ref, new_desc):
461 XendNode.instance().set_description(new_desc)
462 return xen_api_success_void()
463 def host_get_software_version(self, session, host_ref):
464 return xen_api_success(XendNode.instance().xen_version())
465 def host_get_resident_VMs(self, session, host_ref):
466 return xen_api_success(XendDomain.instance().get_domain_refs())
467 def host_get_host_CPUs(self, session, host_ref):
468 return xen_api_success(XendNode.instance().get_host_cpu_refs())
470 # object methods
471 def host_destroy(self, session, host_ref):
472 return xen_api_error(XEND_ERROR_UNSUPPORTED)
473 def host_disable(self, session, host_ref):
474 XendDomain.instance().set_allow_new_domains(False)
475 return xen_api_success_void()
476 def host_enable(self, session, host_ref):
477 XendDomain.instance().set_allow_new_domains(True)
478 return xen_api_success_void()
479 def host_reboot(self, session, host_ref):
480 if not XendDomain.instance().allow_new_domains():
481 return xen_api_error(XEND_ERROR_HOST_RUNNING)
482 return xen_api_error(XEND_ERROR_UNSUPPORTED)
483 def host_shutdown(self, session, host_ref):
484 if not XendDomain.instance().allow_new_domains():
485 return xen_api_error(XEND_ERROR_HOST_RUNNING)
486 return xen_api_error(XEND_ERROR_UNSUPPORTED)
487 def host_get_record(self, session, host_ref):
488 node = XendNode.instance()
489 dom = XendDomain.instance()
490 record = {'uuid': node.uuid,
491 'name_label': node.name,
492 'name_description': '',
493 'software_version': node.xen_version(),
494 'resident_VMs': dom.get_domain_refs(),
495 'host_CPUs': node.get_host_cpu_refs()}
496 return xen_api_success(record)
498 # class methods
499 def host_get_all(self, session):
500 return xen_api_success((XendNode.instance().uuid,))
501 def host_create(self, session, struct):
502 return xen_api_error(XEND_ERROR_UNSUPPORTED)
504 # Xen API: Class Host_CPU
505 # ----------------------------------------------------------------
507 host_cpu_attr_ro = ['host',
508 'number',
509 'features',
510 'utilisation']
512 # attributes
513 def host_cpu_get_uuid(self, session, host_cpu_ref):
514 uuid = XendNode.instance().get_host_cpu_uuid(host_cpu_ref)
515 return xen_api_success(uuid)
516 def host_cpu_get_host(self, session, host_cpu_ref):
517 return xen_api_success(XendNode.instance().uuid)
518 def host_cpu_get_features(self, session, host_cpu_ref):
519 features = XendNode.instance().get_host_cpu_features(host_cpu_ref)
520 return xen_api_success(features)
521 def host_cpu_get_utilisation(self, session, host_cpu_ref):
522 util = XendNode.instance().get_host_cpu_load(host_cpu_ref)
523 return xen_api_success(util)
524 def host_cpu_get_number(self, session, host_cpu_ref):
525 num = XendNode.instance().get_host_cpu_number(host_cpu_ref)
526 return xen_api_success(num)
528 # object methods
529 def host_cpu_destroy(self, session, host_cpu_ref):
530 return xen_api_error(XEND_ERROR_UNSUPPORTED)
531 def host_cpu_get_record(self, session, host_cpu_ref):
532 node = XendNode.instance()
533 record = {'uuid': host_cpu_ref,
534 'host': node.uuid,
535 'number': node.get_host_cpu_number(host_cpu_ref),
536 'features': node.get_host_cpu_features(host_cpu_ref),
537 'utilisation': node.get_host_cpu_load(host_cpu_ref)}
538 return xen_api_success(record)
539 def host_cpu_to_XML(self, session, host_cpu_ref):
540 return xen_api_todo()
542 # class methods
543 def host_cpu_get_all(self, session):
544 return xen_api_success(XendNode.instance().get_host_cpu_refs())
545 def host_cpu_create(self, session, struct):
546 return xen_api_error(XEND_ERROR_UNSUPPORTED)
549 # Xen API: Class Network
550 # ----------------------------------------------------------------
551 # TODO: NOT IMPLEMENTED
553 Network_attr_ro = ['VIFs']
554 Network_attr_rw = ['name_label',
555 'name_description',
556 'NIC',
557 'VLAN',
558 'default_gateway',
559 'default_netmask']
561 # Xen API: Class VM
562 # ----------------------------------------------------------------
564 VM_attr_ro = ['power_state',
565 'resident_on',
566 'memory_actual',
567 'memory_static_max',
568 'memory_static_min',
569 'VCPUs_number',
570 'VCPUs_utilisation',
571 'VCPUs_features_required',
572 'VCPUs_can_use',
573 'VIFs',
574 'VBDs',
575 'VTPMs',
576 'PCI_bus',
577 'tools_version',
578 ]
580 VM_attr_rw = ['name_label',
581 'name_description',
582 'user_version',
583 'is_a_template',
584 'memory_dynamic_max',
585 'memory_dynamic_min',
586 'VCPUs_policy',
587 'VCPUs_params',
588 'VCPUs_features_force_on',
589 'VCPUs_features_force_off',
590 'actions_after_shutdown',
591 'actions_after_reboot',
592 'actions_after_suspend',
593 'actions_after_crash',
594 'bios_boot',
595 'platform_std_VGA',
596 'platform_serial',
597 'platform_localtime',
598 'platform_clock_offset',
599 'platform_enable_audio',
600 'platform_keymap',
601 'builder',
602 'boot_method',
603 'kernel_kernel',
604 'kernel_initrd',
605 'kernel_args',
606 'grub_cmdline',
607 'otherConfig']
609 VM_methods = ['clone',
610 'start',
611 'pause',
612 'unpause',
613 'clean_shutdown',
614 'clean_reboot',
615 'hard_shutdown',
616 'hard_reboot',
617 'suspend',
618 'resume']
620 VM_funcs = ['get_by_name_label']
622 # parameters required for _create()
623 VM_attr_inst = [
624 'name_label',
625 'name_description',
626 'user_version',
627 'is_a_template',
628 'memory_static_max',
629 'memory_dynamic_max',
630 'memory_dynamic_min',
631 'memory_static_min',
632 'VCPUs_policy',
633 'VCPUs_params',
634 'VCPUs_features_required',
635 'VCPUs_features_can_use',
636 'VCPUs_features_force_on',
637 'VCPUs_features_force_off',
638 'actions_after_shutdown',
639 'actions_after_reboot',
640 'actions_after_suspend',
641 'actions_after_crash',
642 'bios_boot',
643 'platform_std_VGA',
644 'platform_serial',
645 'platform_localtime',
646 'platform_clock_offset',
647 'platform_enable_audio',
648 'platform_keymap',
649 'builder',
650 'boot_method',
651 'kernel_kernel',
652 'kernel_initrd',
653 'kernel_args',
654 'grub_cmdline',
655 'PCI_bus',
656 'otherConfig']
658 # attributes (ro)
659 def vm_get_power_state(self, session, vm_ref):
660 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
661 return xen_api_success(dom.state)
663 def vm_get_resident_on(self, session, vm_ref):
664 return xen_api_success(XendNode.instance().uuid)
666 def vm_get_memory_actual(self, session, vm_ref):
667 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
668 return xen_api_todo() # unsupported by xc
670 def vm_get_memory_static_max(self, session, vm_ref):
671 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
672 return xen_api_success(dom.get_memory_static_max())
674 def vm_get_memory_static_min(self, session, vm_ref):
675 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
676 return xen_api_success(dom.get_memory_static_min())
678 def vm_get_VCPUs_number(self, session, vm_ref):
679 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
680 return xen_api_success(dom.getVCpuCount())
682 def vm_get_VCPUs_utilisation(self, session, vm_ref):
683 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
684 return xen_api_success(dom.get_vcpus_util())
686 def vm_get_VCPUs_features_required(self, session, vm_ref):
687 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
688 return xen_api_todo() # unsupported by xc
690 def vm_get_VCPUs_can_use(self, session, vm_ref):
691 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
692 return xen_api_todo() # unsupported by xc
694 def vm_get_VIFs(self, session, vm_ref):
695 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
696 return xen_api_success(dom.get_vifs())
698 def vm_get_VBDs(self, session, vm_ref):
699 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
700 return xen_api_success(dom.get_vbds())
702 def vm_get_VTPMs(self, session, vm_ref):
703 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
704 return xen_api_success(dom.get_vtpms())
706 def vm_get_PCI_bus(self, session, vm_ref):
707 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
708 return xen_api_todo() # unsupported by xc
710 def vm_get_tools_version(self, session, vm_ref):
711 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
712 return xen_api_todo()
714 # attributes (rw)
715 def vm_get_name_label(self, session, vm_ref):
716 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
717 return xen_api_success(dom.getName())
719 def vm_get_name_description(self, session, vm_ref):
720 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
721 return xen_api_todo()
723 def vm_get_user_version(self, session, vm_ref):
724 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
725 return xen_api_todo()
727 def vm_get_is_a_template(self, session, vm_ref):
728 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
729 return xen_api_todo()
731 def vm_get_memory_dynamic_max(self, session, vm_ref):
732 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
733 return xen_api_todo()
735 def vm_get_memory_dynamic_min(self, session, vm_ref):
736 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
737 return xen_api_todo()
739 def vm_get_VCPUs_policy(self, session, vm_ref):
740 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
741 return xen_api_todo() # need to access scheduler
743 def vm_get_VCPUs_params(self, session, vm_ref):
744 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
745 return xen_api_todo() # need access to scheduler
747 def vm_get_VCPUs_features_force_on(self, session, vm_ref):
748 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
749 return xen_api_todo()
751 def vm_get_VCPUs_features_force_off(self, session, vm_ref):
752 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
753 return xen_api_todo()
755 def vm_get_actions_after_shutdown(self, session, vm_ref):
756 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
757 return xen_api_success(dom.get_on_shutdown())
759 def vm_get_actions_after_reboot(self, session, vm_ref):
760 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
761 return xen_api_success(dom.get_on_reboot())
763 def vm_get_actions_after_suspend(self, session, vm_ref):
764 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
765 return xen_api_success(dom.get_on_suspend())
767 def vm_get_actions_after_crash(self, session, vm_ref):
768 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
769 return xen_api_success(dom.get_on_crash())
771 def vm_get_bios_boot(self, session, vm_ref):
772 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
773 return xen_api_success(dom.get_bios_boot())
775 def vm_get_platform_std_VGA(self, session, vm_ref):
776 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
777 return xen_api_todo()
779 def vm_get_platform_serial(self, session, vm_ref):
780 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
781 return xen_api_todo()
783 def vm_get_platform_localtime(self, session, vm_ref):
784 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
785 return xen_api_todo()
787 def vm_get_platform_clock_offset(self, session, vm_ref):
788 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
789 return xen_api_todo()
791 def vm_get_platform_enable_audio(self, session, vm_ref):
792 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
793 return xen_api_todo()
795 def vm_get_platform_keymap(self, session, vm_ref):
796 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
797 return xen_api_todo()
799 def vm_get_builder(self, session, vm_ref):
800 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
801 return xen_api_todo()
803 def vm_get_boot_method(self, session, vm_ref):
804 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
805 return xen_api_success('')
807 def vm_get_kernel_kernel(self, session, vm_ref):
808 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
809 return xen_api_success('')
811 def vm_get_kernel_initrd(self, session, vm_ref):
812 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
813 return xen_api_success('')
815 def vm_get_kernel_args(self, session, vm_ref):
816 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
817 return xen_api_success('')
819 def vm_get_grub_cmdline(self, session, vm_ref):
820 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
821 return xen_api_success('')
823 def vm_get_otherConfig(self, session, vm_ref):
824 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
825 return xen_api_todo()
827 def vm_set_name_label(self, session, vm_ref):
828 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
829 return xen_api_success_void()
831 def vm_set_name_description(self, session, vm_ref):
832 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
833 return xen_api_success_void()
835 def vm_set_user_version(self, session, vm_ref):
836 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
837 return xen_api_success_void()
839 def vm_set_is_a_template(self, session, vm_ref):
840 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
841 return xen_api_success_void()
843 def vm_set_memory_dynamic_max(self, session, vm_ref):
844 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
845 return xen_api_success_void()
847 def vm_set_memory_dynamic_min(self, session, vm_ref):
848 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
849 return xen_api_success_void()
851 def vm_set_VCPUs_policy(self, session, vm_ref):
852 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
853 return xen_api_success_void()
855 def vm_set_VCPUs_params(self, session, vm_ref):
856 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
857 return xen_api_success_void()
859 def vm_set_VCPUs_features_force_on(self, session, vm_ref):
860 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
861 return xen_api_success_void()
863 def vm_set_VCPUs_features_force_off(self, session, vm_ref):
864 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
865 return xen_api_success_void()
867 def vm_set_actions_after_shutdown(self, session, vm_ref):
868 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
869 return xen_api_success_void()
871 def vm_set_actions_after_reboot(self, session, vm_ref):
872 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
873 return xen_api_success_void()
875 def vm_set_actions_after_suspend(self, session, vm_ref):
876 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
877 return xen_api_success_void()
879 def vm_set_actions_after_crash(self, session, vm_ref):
880 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
881 return xen_api_success_void()
883 def vm_set_bios_boot(self, session, vm_ref):
884 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
885 return xen_api_success_void()
887 def vm_set_platform_std_VGA(self, session, vm_ref):
888 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
889 return xen_api_success_void()
891 def vm_set_platform_serial(self, session, vm_ref):
892 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
893 return xen_api_success_void()
895 def vm_set_platform_localtime(self, session, vm_ref):
896 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
897 return xen_api_success_void()
899 def vm_set_platform_clock_offset(self, session, vm_ref):
900 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
901 return xen_api_success_void()
903 def vm_set_platform_enable_audio(self, session, vm_ref):
904 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
905 return xen_api_success_void()
907 def vm_set_builder(self, session, vm_ref):
908 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
909 return xen_api_success_void()
911 def vm_set_boot_method(self, session, vm_ref):
912 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
913 return xen_api_success_void()
915 def vm_set_kernel_kernel(self, session, vm_ref):
916 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
917 return xen_api_success_void()
919 def vm_set_kernel_initrd(self, session, vm_ref):
920 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
921 return xen_api_success_void()
923 def vm_set_kernel_args(self, session, vm_ref):
924 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
925 return xen_api_success_void()
927 def vm_set_grub_cmdline(self, session, vm_ref):
928 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
929 return xen_api_success_void()
931 def vm_set_otherConfig(self, session, vm_ref):
932 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
933 return xen_api_success_void()
935 # class methods
936 def vm_get_all(self, session):
937 refs = [d.get_uuid() for d in XendDomain.instance().list()]
938 return xen_api_success(refs)
940 def vm_get_by_name_label(self, session, label):
941 xendom = XendDomain.instance()
942 dom = xendom.domain_lookup_nr(label)
943 if dom:
944 return xen_api_success([dom.get_uuid()])
945 return xen_api_error(XEND_ERROR_VM_INVALID)
947 def vm_create(self, session, vm_struct):
948 xendom = XendDomain.instance()
949 domuuid = xendom.create_domain(vm_struct)
950 return xen_api_success(domuuid)
952 # object methods
953 def vm_to_XML(self, session, vm_ref):
954 return xen_api_todo()
956 def vm_get_record(self, session, vm_ref):
957 xendom = XendDomain.instance()
958 xeninfo = xendom.get_vm_by_uuid(vm_ref)
959 if not xeninfo:
960 return xen_api_error(XEND_ERROR_VM_INVALID)
962 record = {
963 'uuid': xeninfo.get_uuid(),
964 'power_state': xeninfo.get_power_state(),
965 'name_label': xeninfo.getName(),
966 'name_description': xeninfo.getName(),
967 'user_version': 1,
968 'is_a_template': False,
969 'resident_on': XendNode.instance().uuid,
970 'memory_static_min': xeninfo.get_memory_static_min(),
971 'memory_static_max': xeninfo.get_memory_static_max(),
972 'memory_dynamic_min': xeninfo.get_memory_static_min(),
973 'memory_dynamic_max': xeninfo.get_memory_static_max(),
974 'memory_actual': xeninfo.get_memory_static_min(),
975 'vcpus_policy': xeninfo.get_vcpus_policy(),
976 'vcpus_params': xeninfo.get_vcpus_params(),
977 'vcpus_number': xeninfo.getVCpuCount(),
978 'vcpus_utilisation': xeninfo.get_vcpus_util(),
979 'vcpus_features_required': [],
980 'vcpus_features_can_use': [],
981 'vcpus_features_force_on': [],
982 'vcpus_features_force_off': [],
983 'actions_after_shutdown': xeninfo.get_on_shutdown(),
984 'actions_after_reboot': xeninfo.get_on_reboot(),
985 'actions_after_suspend': xeninfo.get_on_suspend(),
986 'actions_after_crash': xeninfo.get_on_crash(),
987 'VIFs': xeninfo.get_vifs(),
988 'VBDs': xeninfo.get_vbds(),
989 'VTPMs': xeninfo.get_vtpms(),
990 'bios_boot': xeninfo.get_bios_boot(),
991 'platform_std_VGA': xeninfo.get_platform_std_vga(),
992 'platform_serial': xeninfo.get_platform_serial(),
993 'platform_localtime': xeninfo.get_platform_localtime(),
994 'platform_clock_offset': xeninfo.get_platform_clock_offset(),
995 'platform_enable_audio': xeninfo.get_platform_enable_audio(),
996 'platform_keymap': xeninfo.get_platform_keymap(),
997 'builder': xeninfo.get_builder(),
998 'boot_method': xeninfo.get_boot_method(),
999 'kernel_kernel': xeninfo.get_kernel_image(),
1000 'kernel_initrd': xeninfo.get_kernel_initrd(),
1001 'kernel_args': xeninfo.get_kernel_args(),
1002 'grub_cmdline': xeninfo.get_grub_cmdline(),
1003 'PCI_bus': xeninfo.get_pci_bus(),
1004 'tools_version': xeninfo.get_tools_version(),
1005 'otherConfig': xeninfo.get_other_config()
1007 return xen_api_success(record)
1009 def vm_clean_reboot(self, session, vm_ref):
1010 xendom = XendDomain.instance()
1011 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1012 xeninfo.shutdown("reboot")
1013 return xen_api_success_void()
1014 def vm_clean_shutdown(self, session, vm_ref):
1015 xendom = XendDomain.instance()
1016 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1017 xeninfo.shutdown("poweroff")
1018 return xen_api_success_void()
1019 def vm_clone(self, session, vm_ref):
1020 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1021 def vm_destroy(self, session, vm_ref):
1022 return do_vm_func("domain_delete", vm_ref)
1023 def vm_hard_reboot(self, session, vm_ref):
1024 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1025 def vm_hard_shutdown(self, session, vm_ref):
1026 return do_vm_func("domain_destroy", vm_ref)
1027 def vm_pause(self, session, vm_ref):
1028 return do_vm_func("domain_pause", vm_ref)
1029 def vm_resume(self, session, vm_ref, start_paused):
1030 return do_vm_func("domain_resume", vm_ref, start_paused = start_paused)
1031 def vm_start(self, session, vm_ref, start_paused):
1032 return do_vm_func("domain_start", vm_ref, start_paused = start_paused)
1033 def vm_suspend(self, session, vm_ref):
1034 return do_vm_func("domain_suspend", vm_ref)
1035 def vm_unpause(self, session, vm_ref):
1036 return do_vm_func("domain_unpause", vm_ref)
1038 # Xen API: Class VDI
1039 # ----------------------------------------------------------------
1040 # TODO: NOT IMPLEMENTED.
1042 # Xen API: Class VBD
1043 # ----------------------------------------------------------------
1045 VBD_attr_ro = ['image',
1046 'IO_bandwidth_incoming_kbs',
1047 'IO_bandwidth_outgoing_kbs']
1048 VBD_attr_rw = ['VM',
1049 'VDI',
1050 'device',
1051 'mode',
1052 'driver']
1054 VBD_attr_inst = VBD_attr_rw + ['image']
1056 # object methods
1057 def vbd_get_record(self, session, vbd_ref):
1058 xendom = XendDomain.instance()
1059 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1060 if not vm:
1061 return xen_api_error(XEND_ERROR_VBD_INVALID)
1062 cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
1063 if not cfg:
1064 return xen_api_error(XEND_ERROR_VBD_INVALID)
1065 return xen_api_success(cfg)
1067 # class methods
1068 def vbd_create(self, session, vbd_struct):
1069 xendom = XendDomain.instance()
1070 if not xendom.is_valid_vm(vbd_struct['VM']):
1071 return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
1073 dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
1074 vbd_ref = ''
1075 try:
1076 if not vbd_struct.get('VDI', None):
1077 # this is a traditional VBD without VDI and SR
1078 vbd_ref = dom.create_vbd(vbd_struct)
1079 else:
1080 # new VBD via VDI/SR
1081 vdi_ref = vbd_struct.get('VDI')
1082 sr = XendNode.instance().get_sr()
1083 vdi_image = sr.xen_api_get_by_uuid(vdi_ref)
1084 if not vdi_image:
1085 return xen_api_error(XEND_ERROR_VDI_INVALID)
1086 vdi_image = vdi_image.qcow_path
1087 vbd_ref = dom.create_vbd_with_vdi(vbd_struct, vdi_image)
1088 except XendError:
1089 return xen_api_todo()
1091 xendom.managed_config_save(dom)
1092 return xen_api_success(vbd_ref)
1094 # attributes (rw)
1095 def vbd_get_VM(self, session, vbd_ref):
1096 xendom = XendDomain.instance()
1097 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'VM'))
1099 def vbd_get_VDI(self, session, vbd_ref):
1100 return xen_api_todo()
1102 def vbd_get_device(self, session, vbd_ref):
1103 xendom = XendDomain.instance()
1104 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
1105 'device'))
1106 def vbd_get_mode(self, session, vbd_ref):
1107 xendom = XendDomain.instance()
1108 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
1109 'mode'))
1110 def vbd_get_driver(self, session, vbd_ref):
1111 xendom = XendDomain.instance()
1112 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
1113 'driver'))
1115 # Xen API: Class VIF
1116 # ----------------------------------------------------------------
1118 VIF_attr_ro = ['network_read_kbs',
1119 'network_write_kbs',
1120 'IO_bandwidth_incoming_kbs',
1121 'IO_bandwidth_outgoing_kbs']
1122 VIF_attr_rw = ['name',
1123 'type',
1124 'device',
1125 'network',
1126 'VM',
1127 'MAC',
1128 'MTU']
1130 VIF_attr_inst = VIF_attr_rw
1132 # object methods
1133 def vif_get_record(self, session, vif_ref):
1134 xendom = XendDomain.instance()
1135 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1136 if not vm:
1137 return xen_api_error(XEND_ERROR_VIF_INVALID)
1138 cfg = vm.get_dev_xenapi_config('vif', vif_ref)
1139 if not cfg:
1140 return xen_api_error(XEND_ERROR_VIF_INVALID)
1141 valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
1142 self.Base_attr_ro + self.Base_attr_rw
1143 for k in cfg.keys():
1144 if k not in valid_vif_keys:
1145 del cfg[k]
1147 return xen_api_success(cfg)
1149 # class methods
1150 def vif_create(self, session, vif_struct):
1151 xendom = XendDomain.instance()
1152 if xendom.is_valid_vm(vif_struct['VM']):
1153 dom = xendom.get_vm_by_uuid(vif_struct['VM'])
1154 try:
1155 vif_ref = dom.create_vif(vif_struct)
1156 xendom.managed_config_save(dom)
1157 return xen_api_success(vif_ref)
1158 except XendError:
1159 return xen_api_error(XEND_ERROR_TODO)
1160 else:
1161 return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
1164 # Xen API: Class VDI
1165 # ----------------------------------------------------------------
1166 VDI_attr_ro = ['VBDs',
1167 'physical_utilisation',
1168 'sector_size',
1169 'type',
1170 'parent',
1171 'children']
1172 VDI_attr_rw = ['name_label',
1173 'name_description',
1174 'SR',
1175 'virtual_size',
1176 'sharable',
1177 'read_only']
1178 VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
1180 VDI_methods = ['snapshot']
1181 VDI_funcs = ['get_by_name_label']
1183 def vdi_get_VBDs(self, session, vdi_ref):
1184 return xen_api_todo()
1186 def vdi_get_physical_utilisation(self, session, vdi_ref):
1187 sr = XendNode.instance().get_sr()
1188 image = sr.xen_api_get_by_uuid(vdi_ref)
1189 return xen_api_success(image.get_physical_utilisation())
1191 def vdi_get_sector_size(self, session, vdi_ref):
1192 sr = XendNode.instance().get_sr()
1193 image = sr.xen_api_get_by_uuid(vdi_ref)
1194 return xen_api_success(image.sector_size)
1196 def vdi_get_type(self, session, vdi_ref):
1197 sr = XendNode.instance().get_sr()
1198 image = sr.xen_api_get_by_uuid(vdi_ref)
1199 return xen_api_success(image.type)
1201 def vdi_get_parent(self, session, vdi_ref):
1202 sr = XendNode.instance().get_sr()
1203 image = sr.xen_api_get_by_uuid(vdi_ref)
1204 return xen_api_success(image.parent)
1206 def vdi_get_children(self, session, vdi_ref):
1207 sr = XendNode.instance().get_sr()
1208 image = sr.xen_api_get_by_uuid(vdi_ref)
1209 return xen_api_success(image.children)
1211 def vdi_get_name_label(self, session, vdi_ref):
1212 sr = XendNode.instance().get_sr()
1213 image = sr.xen_api_get_by_uuid(vdi_ref)
1214 return xen_api_success(image.name_label)
1216 def vdi_get_name_description(self, session, vdi_ref):
1217 sr = XendNode.instance().get_sr()
1218 image = sr.xen_api_get_by_uuid(vdi_ref)
1219 return xen_api_success(image.name_description)
1221 def vdi_get_SR(self, session, vdi_ref):
1222 sr = XendNode.instance().get_sr()
1223 return xen_api_success(sr.uuid)
1225 def vdi_get_virtual_size(self, session, vdi_ref):
1226 sr = XendNode.instance().get_sr()
1227 image = sr.xen_api_get_by_uuid(vdi_ref)
1228 return xen_api_success(image.virtual_size)
1230 def vdi_get_sharable(self, session, vdi_ref):
1231 sr = XendNode.instance().get_sr()
1232 image = sr.xen_api_get_by_uuid(vdi_ref)
1233 return xen_api_success(image.sharable)
1235 def vdi_get_read_only(self, session, vdi_ref):
1236 sr = XendNode.instance().get_sr()
1237 image = sr.xen_api_get_by_uuid(vdi_ref)
1238 return xen_api_success(image.sharable)
1240 def vdi_set_name_label(self, session, vdi_ref, value):
1241 sr = XendNode.instance().get_sr()
1242 image = sr.xen_api_get_by_uuid(vdi_ref)
1243 image.name_label = value
1244 return xen_api_success_void()
1246 def vdi_set_name_description(self, session, vdi_ref, value):
1247 sr = XendNode.instance().get_sr()
1248 image = sr.xen_api_get_by_uuid(vdi_ref)
1249 image.name_description = value
1250 return xen_api_success_void()
1252 def vdi_set_SR(self, session, vdi_ref, value):
1253 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1255 def vdi_set_virtual_size(self, session, vdi_ref, value):
1256 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1258 def vdi_set_sharable(self, session, vdi_ref, value):
1259 return xen_api_todo()
1260 def vdi_set_read_only(self, session, vdi_ref, value):
1261 return xen_api_todo()
1263 # Object Methods
1264 def vdi_snapshot(self, session, vdi_ref):
1265 return xen_api_todo()
1267 def vdi_destroy(self, session, vdi_ref):
1268 sr = XendNode.instance().get_sr()
1269 sr.destroy_image(vdi_ref)
1270 return xen_api_success_void()
1272 def vdi_to_XML(self, session, vdi_ref):
1273 return xen_api_todo()
1275 def vdi_get_record(self, session, vdi_ref):
1276 sr = XendNode.instance().get_sr()
1277 image = sr.xen_api_get_by_uuid(vdi_ref)
1278 if image:
1279 return xen_api_success({
1280 'uuid': vdi_ref,
1281 'name_label': image.name_label,
1282 'name_description': image.name_description,
1283 'SR': sr.uuid,
1284 'VBDs': [], # TODO
1285 'virtual_size': image.virtual_size,
1286 'physical_utilisation': image.physical_utilisation,
1287 'sector_size': image.sector_size,
1288 'type': image.type,
1289 'parent': image.parent,
1290 'children': image.children,
1291 'sharable': image.sharable,
1292 'read_only': image.read_only,
1293 })
1295 return xen_api_error(XEND_ERROR_VDI_INVALID)
1297 # Class Functions
1298 def vdi_create(self, session, vdi_struct):
1299 sr = XendNode.instance().get_sr()
1300 sr_ref = vdi_struct['SR']
1301 if sr.uuid != sr_ref:
1302 return xen_api_error(XEND_ERROR_SR_INVALID)
1304 vdi_uuid = sr.create_image(vdi_struct)
1305 return xen_api_success(vdi_uuid)
1307 def vdi_get_all(self, session):
1308 sr = XendNode.instance().get_sr()
1309 return xen_api_success(sr.list_images())
1311 def vdi_get_by_name_label(self, session, name):
1312 sr = XendNode.instance().get_sr()
1313 image_uuid = sr.xen_api_get_by_name_label(name)
1314 if image_uuid:
1315 return xen_api_success(image_uuid)
1317 return xen_api_error(XEND_ERROR_VDI_INVALID)
1320 # Xen API: Class VTPM
1321 # ----------------------------------------------------------------
1323 VTPM_attr_rw = [ ]
1324 VTPM_attr_ro = ['VM',
1325 'backend',
1326 'instance',
1327 'driver']
1329 VTPM_attr_inst = VTPM_attr_rw
1331 # object methods
1332 def vtpm_get_record(self, session, vtpm_ref):
1333 xendom = XendDomain.instance()
1334 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1335 if not vm:
1336 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1337 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1338 if not cfg:
1339 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1340 valid_vtpm_keys = self.VTPM_attr_ro + self.VTPM_attr_rw + \
1341 self.Base_attr_ro + self.Base_attr_rw
1342 for k in cfg.keys():
1343 if k not in valid_vtpm_keys:
1344 del cfg[k]
1346 return xen_api_success(cfg)
1348 # Class Functions
1349 def vtpm_get_instance(self, session, vtpm_ref):
1350 xendom = XendDomain.instance()
1351 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1352 if not vm:
1353 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1354 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1355 if not cfg:
1356 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1357 if cfg.has_key('instance'):
1358 instance = cfg['instance']
1359 else:
1360 instance = -1
1361 return xen_api_success(instance)
1363 def vtpm_get_driver(self, session, vtpm_ref):
1364 xendom = XendDomain.instance()
1365 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1366 if not vm:
1367 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1368 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1369 if not cfg:
1370 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1371 if cfg.has_key('type'):
1372 driver = cfg['type']
1373 else:
1374 driver = "Unknown"
1375 return xen_api_success(driver)
1377 def vtpm_get_backend(self, session, vtpm_ref):
1378 xendom = XendDomain.instance()
1379 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1380 if not vm:
1381 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1382 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1383 if not cfg:
1384 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1385 if cfg.has_key('backend'):
1386 backend = cfg['backend']
1387 else:
1388 backend = "Domain-0"
1389 return xen_api_success(backend)
1391 def vtpm_get_VM(self, session, vtpm_ref):
1392 xendom = XendDomain.instance()
1393 return xen_api_success(xendom.get_dev_property('vtpm', vtpm_ref, 'VM'))
1395 # class methods
1396 def vtpm_create(self, session, vtpm_struct):
1397 xendom = XendDomain.instance()
1398 if xendom.is_valid_vm(vtpm_struct['VM']):
1399 dom = xendom.get_vm_by_uuid(vtpm_struct['VM'])
1400 try:
1401 vtpm_ref = dom.create_vtpm(vtpm_struct)
1402 xendom.managed_config_save(dom)
1403 return xen_api_success(vtpm_ref)
1404 except XendError:
1405 return xen_api_error(XEND_ERROR_TODO)
1406 else:
1407 return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
1410 # Xen API: Class SR
1411 # ----------------------------------------------------------------
1412 SR_attr_ro = ['VDIs',
1413 'virtual_allocation',
1414 'physical_utilisation',
1415 'physical_size',
1416 'type',
1417 'location']
1419 SR_attr_rw = ['name_label',
1420 'name_description']
1422 SR_attr_inst = ['physical_size',
1423 'type',
1424 'location',
1425 'name_label',
1426 'name_description']
1428 SR_methods = ['clone']
1429 SR_funcs = ['get_by_name_label']
1431 # Class Functions
1432 def sr_get_all(self, session):
1433 sr = XendNode.instance().get_sr()
1434 return xen_api_success([sr.uuid])
1436 def sr_get_by_name_label(self, session, label):
1437 sr = XendNode.instance().get_sr()
1438 if sr.name_label != label:
1439 return xen_api_error(XEND_ERROR_SR_INVALID)
1440 return xen_api_success([sr.uuid])
1442 def sr_create(self, session):
1443 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1445 def sr_get_by_uuid(self, session):
1446 return xen_api_success(XendNode.instance().get_sr().uuid)
1448 # Class Methods
1449 def sr_clone(self, session, sr_ref):
1450 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1451 def sr_destroy(self, session, sr_ref):
1452 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1454 def sr_to_XML(self, session, sr_ref):
1455 return xen_api_todo()
1457 def sr_get_record(self, session, sr_ref):
1458 sr = XendNode.instance().get_sr()
1459 return xen_api_success({
1460 'uuid': sr.uuid,
1461 'name_label': sr.name_label,
1462 'name_description': sr.name_description,
1463 'VDIs': sr.list_images(),
1464 'virtual_allocation': sr.used_space_bytes(),
1465 'physical_utilisation': sr.used_space_bytes(),
1466 'physical_size': sr.total_space_bytes(),
1467 'type': sr.type,
1468 'location': sr.location
1469 })
1471 # Attribute acceess
1472 def sr_get_VDIs(self, session, sr_ref):
1473 sr = XendNode.instance().get_sr()
1474 return xen_api_success(sr.list_images())
1476 def sr_get_virtual_allocation(self, session, sr_ref):
1477 sr = XendNode.instance().get_sr()
1478 return sr.used_space_bytes()
1480 def sr_get_physical_utilisation(self, session, sr_ref):
1481 sr = XendNode.instance().get_sr()
1482 return sr.used_space_bytes()
1484 def sr_get_physical_size(self, session, sr_ref):
1485 sr = XendNode.instance().get_sr()
1486 return sr.total_space_bytes()
1488 def sr_get_type(self, session, sr_ref):
1489 sr = XendNode.instance().get_sr()
1490 return xen_api_success(sr.type)
1492 def sr_get_location(self, session, sr_ref):
1493 sr = XendNode.instance().get_sr()
1494 return xen_api_success(sr.location)
1496 def sr_get_name_label(self, session, sr_ref):
1497 sr = XendNode.instance().get_sr()
1498 return xen_api_success(sr.name_label)
1500 def sr_get_name_description(self, session, sr_ref):
1501 sr = XendNode.instance().get_sr()
1502 return xen_api_success(sr.name_description)
1504 def sr_set_name_label(self, session, sr_ref, value):
1505 sr = XendNode.instance().get_sr()
1506 sr.name_label = value
1507 return xen_api_success_void()
1509 def sr_set_name_description(self, session, sr_ref, value):
1510 sr = XendNode.instance().get_sr()
1511 sr.name_description = value
1512 return xen_api_success_void()
1515 # Auto generate some stubs based on XendAPI introspection
1517 if __name__ == "__main__":
1518 def output(line):
1519 print ' ' + line
1521 classes = ['VDI', 'SR']
1522 for cls in classes:
1523 ro_attrs = getattr(XendAPI, '%s_attr_ro' % cls, [])
1524 rw_attrs = getattr(XendAPI, '%s_attr_rw' % cls, [])
1525 methods = getattr(XendAPI, '%s_methods' % cls, [])
1526 funcs = getattr(XendAPI, '%s_funcs' % cls, [])
1528 ref = '%s_ref' % cls.lower()
1530 for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
1531 getter_name = '%s_get_%s' % (cls.lower(), attr_name.lower())
1532 output('def %s(self, session, %s):' % (getter_name, ref))
1533 output(' return xen_api_todo()')
1535 for attr_name in rw_attrs + XendAPI.Base_attr_rw:
1536 setter_name = '%s_set_%s' % (cls.lower(), attr_name.lower())
1537 output('def %s(self, session, %s, value):' % (setter_name, ref))
1538 output(' return xen_api_todo()')
1540 for method_name in methods + XendAPI.Base_methods:
1541 method_full_name = '%s_%s' % (cls.lower(),method_name.lower())
1542 output('def %s(self, session, %s):' % (method_full_name, ref))
1543 output(' return xen_api_todo()')
1545 for func_name in funcs + XendAPI.Base_funcs:
1546 func_full_name = '%s_%s' % (cls.lower(), func_name.lower())
1547 output('def %s(self, session):' % func_full_name)
1548 output(' return xen_api_todo()')