ia64/xen-unstable

view tools/python/xen/xend/XendAPI.py @ 13056:54eee6fabbee

Fix VM.get_power_state API. On the xend side an integer representation of the power state was being returned instead of a string representation as specified by the XenAPI spec.

On the c-bindings side the marshalling code converts the string representation to an enum value. A subsequent attempt to convert the enum from a string to an enum was causing a seg fault.

Signed-off-by: Jim Fehlig <jfehlig@novell.com>
author jfehlig@jfehlig2.provo.novell.com
date Wed Dec 13 18:06:48 2006 -0700 (2006-12-13)
parents 0ee4e33b4401
children 63e72c3254da
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, *args, **kwargs):
122 if len(args) == 0:
123 return {'Status': 'Failure',
124 'ErrorDescription': XEND_ERROR_VM_INVALID}
126 vm_ref = args[0]
127 xendom = XendDomain.instance()
128 if type(vm_ref) == type(str()) and \
129 xendom.is_valid_vm(vm_ref):
130 return func(self, session, *args, **kwargs)
131 else:
132 return {'Status': 'Failure',
133 'ErrorDescription': XEND_ERROR_VM_INVALID}
135 # make sure we keep the 'api' attribute
136 if hasattr(func, 'api'):
137 check_vm_ref.api = func.api
139 return check_vm_ref
141 def valid_vbd(func):
142 """Decorator to verify if vbd_ref is valid before calling
143 method.
145 @param func: function with params: (self, session, vbd_ref)
146 @rtype: callable object
147 """
148 def check_vbd_ref(self, session, vbd_ref, *args, **kwargs):
149 xendom = XendDomain.instance()
150 if type(vbd_ref) == type(str()) and \
151 xendom.is_valid_dev('vbd', vbd_ref):
152 return func(self, session, vbd_ref, *args, **kwargs)
153 else:
154 return {'Status': 'Failure',
155 'ErrorDescription': XEND_ERROR_VBD_INVALID}
157 # make sure we keep the 'api' attribute
158 if hasattr(func, 'api'):
159 check_vbd_ref.api = func.api
161 return check_vbd_ref
163 def valid_vif(func):
164 """Decorator to verify if vif_ref is valid before calling
165 method.
167 @param func: function with params: (self, session, vif_ref)
168 @rtype: callable object
169 """
170 def check_vif_ref(self, session, vif_ref, *args, **kwargs):
171 xendom = XendDomain.instance()
172 if type(vif_ref) == type(str()) and \
173 xendom.is_valid_dev('vif', vif_ref):
174 return func(self, session, vif_ref, *args, **kwargs)
175 else:
176 return {'Status': 'Failure',
177 'ErrorDescription': XEND_ERROR_VIF_INVALID}
179 # make sure we keep the 'api' attribute
180 if hasattr(func, 'api'):
181 check_vif_ref.api = func.api
183 return check_vif_ref
186 def valid_vdi(func):
187 """Decorator to verify if vdi_ref is valid before calling
188 method.
190 @param func: function with params: (self, session, vdi_ref)
191 @rtype: callable object
192 """
193 def check_vdi_ref(self, session, vdi_ref, *args, **kwargs):
194 xennode = XendNode.instance()
195 if type(vdi_ref) == type(str()) and \
196 xennode.get_sr().is_valid_vdi(vdi_ref):
197 return func(self, session, vdi_ref, *args, **kwargs)
198 else:
199 return {'Status': 'Failure',
200 'ErrorDescription': XEND_ERROR_VDI_INVALID}
202 # make sure we keep the 'api' attribute
203 if hasattr(func, 'api'):
204 check_vdi_ref.api = func.api
206 return check_vdi_ref
208 def valid_vtpm(func):
209 """Decorator to verify if vtpm_ref is valid before calling
210 method.
212 @param func: function with params: (self, session, vtpm_ref)
213 @rtype: callable object
214 """
215 def check_vtpm_ref(self, session, vtpm_ref, *args, **kwargs):
216 xendom = XendDomain.instance()
217 if type(vtpm_ref) == type(str()) and \
218 xendom.is_valid_dev('vtpm', vtpm_ref):
219 return func(self, session, vtpm_ref, *args, **kwargs)
220 else:
221 return {'Status': 'Failure',
222 'ErrorDescription': XEND_ERROR_VTPM_INVALID}
224 # make sure we keep the 'api' attribute
225 if hasattr(func, 'api'):
226 check_vtpm_ref.api = func.api
228 return check_vtpm_ref
230 def valid_sr(func):
231 """Decorator to verify if sr_ref is valid before calling
232 method.
234 @param func: function with params: (self, session, sr_ref)
235 @rtype: callable object
236 """
237 def check_sr_ref(self, session, sr_ref, *args, **kwargs):
238 xennode = XendNode.instance()
239 if type(sr_ref) == type(str()) and \
240 xennode.get_sr().uuid == sr_ref:
241 return func(self, session, sr_ref, *args, **kwargs)
242 else:
243 return {'Status': 'Failure',
244 'ErrorDescription': XEND_ERROR_SR_INVALID}
246 # make sure we keep the 'api' attribute
247 if hasattr(func, 'api'):
248 check_sr_ref.api = func.api
250 return check_sr_ref
252 # -----------------------------
253 # Bridge to Legacy XM API calls
254 # -----------------------------
256 def do_vm_func(fn_name, vm_ref, *args, **kwargs):
257 """Helper wrapper func to abstract away from repetitive code.
259 @param fn_name: function name for XendDomain instance
260 @type fn_name: string
261 @param vm_ref: vm_ref
262 @type vm_ref: string
263 @param *args: more arguments
264 @type *args: tuple
265 """
266 xendom = XendDomain.instance()
267 fn = getattr(xendom, fn_name)
268 xendom.do_legacy_api_with_uuid(fn, vm_ref, *args, **kwargs)
269 return xen_api_success_void()
272 class XendAPI:
273 """Implementation of the Xen-API in Xend. Expects to be
274 used via XMLRPCServer.
276 All methods that need a valid session are marked with
277 a L{XendAuthManager.session_required} decorator that will
278 transparently perform the required session authentication.
280 We need to support Python <2.4, so we use the old decorator syntax.
282 All XMLRPC accessible methods require an 'api' attribute and
283 is set to the XMLRPC function name which the method implements.
284 """
286 def __init__(self, auth):
287 """Initialised Xen API wrapper by making sure all functions
288 have the correct validation decorators such as L{valid_host}
289 and L{session_required}.
290 """
291 self.auth = auth
293 classes = {
294 'session': (session_required,),
295 'host': (valid_host, session_required),
296 'host_cpu': (valid_host_cpu, session_required),
297 'VM': (valid_vm, session_required),
298 'VBD': (valid_vbd, session_required),
299 'VIF': (valid_vif, session_required),
300 'VDI': (valid_vdi, session_required),
301 'VTPM':(valid_vtpm, session_required),
302 'SR': (valid_sr, session_required)}
304 # Cheat methods
305 # -------------
306 # Methods that have a trivial implementation for all classes.
307 # 1. get_by_uuid == getting by ref, so just return uuid for
308 # all get_by_uuid() methods.
310 for cls in classes.keys():
311 get_by_uuid = '%s_get_by_uuid' % cls
312 get_uuid = '%s_get_uuid' % cls
313 setattr(XendAPI, get_by_uuid,
314 lambda s, sess, obj_ref: xen_api_success(obj_ref))
315 setattr(XendAPI, get_uuid,
316 lambda s, sess, obj_ref: xen_api_success(obj_ref))
318 # 2. get_record is just getting all the attributes, so provide
319 # a fake template implementation.
320 #
321 # TODO: ...
324 # Wrapping validators around XMLRPC calls
325 # ---------------------------------------
327 for cls, validators in classes.items():
328 ro_attrs = getattr(self, '%s_attr_ro' % cls, [])
329 rw_attrs = getattr(self, '%s_attr_rw' % cls, [])
330 methods = getattr(self, '%s_methods' % cls, [])
331 funcs = getattr(self, '%s_funcs' % cls, [])
333 # wrap validators around readable class attributes
334 for attr_name in ro_attrs + rw_attrs + self.Base_attr_ro:
335 getter_name = '%s_get_%s' % (cls, attr_name)
336 try:
337 getter = getattr(XendAPI, getter_name)
338 for validator in validators:
339 getter = validator(getter)
340 getter.api = '%s.get_%s' % (cls, attr_name)
341 setattr(XendAPI, getter_name, getter)
342 except AttributeError:
343 pass
344 #log.warn("API call: %s not found" % getter_name)
346 # wrap validators around writable class attrributes
347 for attr_name in rw_attrs + self.Base_attr_rw:
348 setter_name = '%s_set_%s' % (cls, attr_name)
349 try:
350 setter = getattr(XendAPI, setter_name)
351 for validator in validators:
352 setter = validator(setter)
353 setter.api = '%s.set_%s' % (cls, attr_name)
354 setattr(XendAPI, setter_name, setter)
355 except AttributeError:
356 pass
357 #log.warn("API call: %s not found" % setter_name)
359 # wrap validators around methods
360 for method_name in methods + self.Base_methods:
361 method_full_name = '%s_%s' % (cls, method_name)
363 try:
364 method = getattr(XendAPI, method_full_name)
365 for validator in validators:
366 method = validator(method)
367 method.api = '%s.%s' % (cls, method_name)
368 setattr(XendAPI, method_full_name, method)
369 except AttributeError:
370 pass
371 #log.warn('API call: %s not found' % method_full_name)
373 # wrap validators around class functions
374 for func_name in funcs + self.Base_funcs:
375 func_full_name = '%s_%s' % (cls, func_name)
376 try:
377 method = getattr(XendAPI, func_full_name)
378 method = session_required(method)
379 method.api = '%s.%s' % (cls, func_name)
380 setattr(XendAPI, func_full_name, method)
381 except AttributeError:
382 pass
383 #log.warn('API call: %s not found' % func_full_name)
386 Base_attr_ro = ['uuid']
387 Base_attr_rw = []
388 Base_methods = ['destroy', 'get_record']
389 Base_funcs = ['create', 'get_by_uuid', 'get_all']
391 # Xen API: Class Session
392 # ----------------------------------------------------------------
393 # NOTE: Left unwrapped by __init__
395 session_attr_ro = ['this_host', 'this_user']
396 session_methods = ['logout']
397 # session_funcs = ['login_with_password']
399 def session_login_with_password(self, username, password):
400 try:
401 session = (self.auth == AUTH_NONE and
402 auth_manager().login_unconditionally(username) or
403 auth_manager().login_with_password(username, password))
404 return xen_api_success(session)
405 except XendError, e:
406 return xen_api_error(XEND_ERROR_AUTHENTICATION_FAILED)
407 session_login_with_password.api = 'session.login_with_password'
410 # object methods
411 def session_logout(self, session):
412 auth_manager().logout(session)
413 return xen_api_success_void()
414 def session_destroy(self, session):
415 return xen_api_error(XEND_ERROR_UNSUPPORTED)
416 def session_get_record(self, session):
417 record = {'this_host': XendNode.instance().uuid,
418 'this_user': auth_manager().get_user(session)}
419 return xen_api_success(record)
421 # attributes (ro)
422 def session_get_this_host(self, session):
423 return xen_api_success(XendNode.instance().uuid)
424 def session_get_this_user(self, session):
425 user = auth_manager().get_user(session)
426 if user:
427 return xen_api_success(user)
428 return xen_api_error(XEND_ERROR_SESSION_INVALID)
431 # Xen API: Class User
432 # ----------------------------------------------------------------
433 # TODO: NOT IMPLEMENTED YET
435 # Xen API: Class Tasks
436 # ----------------------------------------------------------------
437 # TODO: NOT IMPLEMENTED YET
439 # Xen API: Class Host
440 # ----------------------------------------------------------------
442 host_attr_ro = ['software_version',
443 'resident_VMs',
444 'host_CPUs']
446 host_attr_rw = ['name_label',
447 'name_description']
449 host_methods = ['disable',
450 'enable',
451 'reboot',
452 'shutdown']
454 host_funcs = ['get_by_name_label']
456 # attributes
457 def host_get_name_label(self, session, host_ref):
458 return xen_api_success(XendNode.instance().name)
459 def host_set_name_label(self, session, host_ref, new_name):
460 XendNode.instance().set_name(new_name)
461 return xen_api_success_void()
462 def host_get_name_description(self, session, host_ref):
463 return xen_api_success(XendNode.instance().description)
464 def host_set_name_description(self, session, host_ref, new_desc):
465 XendNode.instance().set_description(new_desc)
466 return xen_api_success_void()
467 def host_get_software_version(self, session, host_ref):
468 return xen_api_success(XendNode.instance().xen_version())
469 def host_get_resident_VMs(self, session, host_ref):
470 return xen_api_success(XendDomain.instance().get_domain_refs())
471 def host_get_host_CPUs(self, session, host_ref):
472 return xen_api_success(XendNode.instance().get_host_cpu_refs())
474 # object methods
475 def host_destroy(self, session, host_ref):
476 return xen_api_error(XEND_ERROR_UNSUPPORTED)
477 def host_disable(self, session, host_ref):
478 XendDomain.instance().set_allow_new_domains(False)
479 return xen_api_success_void()
480 def host_enable(self, session, host_ref):
481 XendDomain.instance().set_allow_new_domains(True)
482 return xen_api_success_void()
483 def host_reboot(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_shutdown(self, session, host_ref):
488 if not XendDomain.instance().allow_new_domains():
489 return xen_api_error(XEND_ERROR_HOST_RUNNING)
490 return xen_api_error(XEND_ERROR_UNSUPPORTED)
491 def host_get_record(self, session, host_ref):
492 node = XendNode.instance()
493 dom = XendDomain.instance()
494 record = {'uuid': node.uuid,
495 'name_label': node.name,
496 'name_description': '',
497 'software_version': node.xen_version(),
498 'resident_VMs': dom.get_domain_refs(),
499 'host_CPUs': node.get_host_cpu_refs()}
500 return xen_api_success(record)
502 # class methods
503 def host_get_all(self, session):
504 return xen_api_success((XendNode.instance().uuid,))
505 def host_create(self, session, struct):
506 return xen_api_error(XEND_ERROR_UNSUPPORTED)
508 # Xen API: Class Host_CPU
509 # ----------------------------------------------------------------
511 host_cpu_attr_ro = ['host',
512 'number',
513 'features',
514 'utilisation']
516 # attributes
517 def host_cpu_get_uuid(self, session, host_cpu_ref):
518 uuid = XendNode.instance().get_host_cpu_uuid(host_cpu_ref)
519 return xen_api_success(uuid)
520 def host_cpu_get_host(self, session, host_cpu_ref):
521 return xen_api_success(XendNode.instance().uuid)
522 def host_cpu_get_features(self, session, host_cpu_ref):
523 features = XendNode.instance().get_host_cpu_features(host_cpu_ref)
524 return xen_api_success(features)
525 def host_cpu_get_utilisation(self, session, host_cpu_ref):
526 util = XendNode.instance().get_host_cpu_load(host_cpu_ref)
527 return xen_api_success(util)
528 def host_cpu_get_number(self, session, host_cpu_ref):
529 num = XendNode.instance().get_host_cpu_number(host_cpu_ref)
530 return xen_api_success(num)
532 # object methods
533 def host_cpu_destroy(self, session, host_cpu_ref):
534 return xen_api_error(XEND_ERROR_UNSUPPORTED)
535 def host_cpu_get_record(self, session, host_cpu_ref):
536 node = XendNode.instance()
537 record = {'uuid': host_cpu_ref,
538 'host': node.uuid,
539 'number': node.get_host_cpu_number(host_cpu_ref),
540 'features': node.get_host_cpu_features(host_cpu_ref),
541 'utilisation': node.get_host_cpu_load(host_cpu_ref)}
542 return xen_api_success(record)
544 # class methods
545 def host_cpu_get_all(self, session):
546 return xen_api_success(XendNode.instance().get_host_cpu_refs())
547 def host_cpu_create(self, session, struct):
548 return xen_api_error(XEND_ERROR_UNSUPPORTED)
551 # Xen API: Class Network
552 # ----------------------------------------------------------------
553 # TODO: NOT IMPLEMENTED
555 Network_attr_ro = ['VIFs']
556 Network_attr_rw = ['name_label',
557 'name_description',
558 'NIC',
559 'VLAN',
560 'default_gateway',
561 'default_netmask']
563 # Xen API: Class VM
564 # ----------------------------------------------------------------
566 VM_attr_ro = ['power_state',
567 'resident_on',
568 'memory_actual',
569 'memory_static_max',
570 'memory_static_min',
571 'VCPUs_number',
572 'VCPUs_utilisation',
573 'VCPUs_features_required',
574 'VCPUs_can_use',
575 'consoles',
576 'VIFs',
577 'VBDs',
578 'VTPMs',
579 'PCI_bus',
580 'tools_version',
581 ]
583 VM_attr_rw = ['name_label',
584 'name_description',
585 'user_version',
586 'is_a_template',
587 'auto_power_on',
588 'memory_dynamic_max',
589 'memory_dynamic_min',
590 'VCPUs_policy',
591 'VCPUs_params',
592 'VCPUs_features_force_on',
593 'VCPUs_features_force_off',
594 'actions_after_shutdown',
595 'actions_after_reboot',
596 'actions_after_suspend',
597 'actions_after_crash',
598 'PV_bootloader',
599 'PV_kernel',
600 'PV_ramdisk',
601 'PV_args',
602 'PV_bootloader_args',
603 'HVM_boot',
604 'platform_std_VGA',
605 'platform_serial',
606 'platform_localtime',
607 'platform_clock_offset',
608 'platform_enable_audio',
609 'platform_keymap',
610 'otherConfig']
612 VM_methods = ['clone',
613 'start',
614 'pause',
615 'unpause',
616 'clean_shutdown',
617 'clean_reboot',
618 'hard_shutdown',
619 'hard_reboot',
620 'suspend',
621 'resume']
623 VM_funcs = ['get_by_name_label']
625 # parameters required for _create()
626 VM_attr_inst = [
627 'name_label',
628 'name_description',
629 'user_version',
630 'is_a_template',
631 'memory_static_max',
632 'memory_dynamic_max',
633 'memory_dynamic_min',
634 'memory_static_min',
635 'VCPUs_policy',
636 'VCPUs_params',
637 'VCPUs_features_required',
638 'VCPUs_features_can_use',
639 'VCPUs_features_force_on',
640 'VCPUs_features_force_off',
641 'actions_after_shutdown',
642 'actions_after_reboot',
643 'actions_after_suspend',
644 'actions_after_crash',
645 'PV_bootloader',
646 'PV_kernel',
647 'PV_ramdisk',
648 'PV_args',
649 'PV_bootloader_args',
650 'HVM_boot',
651 'platform_std_VGA',
652 'platform_serial',
653 'platform_localtime',
654 'platform_clock_offset',
655 'platform_enable_audio',
656 'platform_keymap',
657 'grub_cmdline',
658 'PCI_bus',
659 'otherConfig']
661 def VM_get(self, name, session, vm_ref):
662 return xen_api_success(
663 XendDomain.instance().get_vm_by_uuid(vm_ref).info[name])
665 def VM_set(self, name, session, vm_ref, value):
666 XendDomain.instance().get_vm_by_uuid(vm_ref).info[name] = value
667 return xen_api_success_void()
669 # attributes (ro)
670 def VM_get_power_state(self, session, vm_ref):
671 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
672 return xen_api_success(dom.get_power_state())
674 def VM_get_resident_on(self, session, vm_ref):
675 return xen_api_success(XendNode.instance().uuid)
677 def VM_get_memory_actual(self, session, vm_ref):
678 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
679 return xen_api_todo() # unsupported by xc
681 def VM_get_memory_static_max(self, session, vm_ref):
682 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
683 return xen_api_success(dom.get_memory_static_max())
685 def VM_get_memory_static_min(self, session, vm_ref):
686 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
687 return xen_api_success(dom.get_memory_static_min())
689 def VM_get_VCPUs_number(self, session, vm_ref):
690 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
691 return xen_api_success(dom.getVCpuCount())
693 def VM_get_VCPUs_utilisation(self, session, vm_ref):
694 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
695 return xen_api_success(dom.get_vcpus_util())
697 def VM_get_VCPUs_features_required(self, session, vm_ref):
698 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
699 return xen_api_todo() # unsupported by xc
701 def VM_get_VCPUs_can_use(self, session, vm_ref):
702 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
703 return xen_api_todo() # unsupported by xc
705 def VM_get_VIFs(self, session, vm_ref):
706 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
707 return xen_api_success(dom.get_vifs())
709 def VM_get_VBDs(self, session, vm_ref):
710 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
711 return xen_api_success(dom.get_vbds())
713 def VM_get_VTPMs(self, session, vm_ref):
714 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
715 return xen_api_success(dom.get_vtpms())
717 def VM_get_PCI_bus(self, session, vm_ref):
718 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
719 return xen_api_todo() # unsupported by xc
721 def VM_get_tools_version(self, session, vm_ref):
722 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
723 return xen_api_todo()
725 # attributes (rw)
726 def VM_get_name_label(self, session, vm_ref):
727 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
728 return xen_api_success(dom.getName())
730 def VM_get_name_description(self, session, vm_ref):
731 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
732 return xen_api_todo()
734 def VM_get_user_version(self, session, vm_ref):
735 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
736 return xen_api_todo()
738 def VM_get_is_a_template(self, session, vm_ref):
739 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
740 return xen_api_todo()
742 def VM_get_memory_dynamic_max(self, session, vm_ref):
743 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
744 return xen_api_success(dom.get_memory_dynamic_max())
746 def VM_get_memory_dynamic_min(self, session, vm_ref):
747 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
748 return xen_api_success(dom.get_memory_dynamic_min())
750 def VM_get_VCPUs_policy(self, session, vm_ref):
751 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
752 return xen_api_todo() # need to access scheduler
754 def VM_get_VCPUs_params(self, session, vm_ref):
755 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
756 return xen_api_todo() # need access to scheduler
758 def VM_get_VCPUs_features_force_on(self, session, vm_ref):
759 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
760 return xen_api_todo()
762 def VM_get_VCPUs_features_force_off(self, session, vm_ref):
763 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
764 return xen_api_todo()
766 def VM_get_actions_after_shutdown(self, session, vm_ref):
767 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
768 return xen_api_success(dom.get_on_shutdown())
770 def VM_get_actions_after_reboot(self, session, vm_ref):
771 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
772 return xen_api_success(dom.get_on_reboot())
774 def VM_get_actions_after_suspend(self, session, vm_ref):
775 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
776 return xen_api_success(dom.get_on_suspend())
778 def VM_get_actions_after_crash(self, session, vm_ref):
779 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
780 return xen_api_success(dom.get_on_crash())
782 def VM_get_PV_bootloader(self, session, vm_ref):
783 return self.VM_get('PV_bootloader', session, vm_ref)
785 def VM_get_PV_kernel(self, session, vm_ref):
786 return self.VM_get('PV_kernel', session, vm_ref)
788 def VM_get_PV_ramdisk(self, session, vm_ref):
789 return self.VM_get('PV_ramdisk', session, vm_ref)
791 def VM_get_PV_args(self, session, vm_ref):
792 return self.VM_get('PV_args', session, vm_ref)
794 def VM_get_PV_bootloader_args(self, session, vm_ref):
795 return self.VM_get('PV_bootloader_args', session, vm_ref)
797 def VM_get_HVM_boot(self, session, vm_ref):
798 return self.VM_get('HVM_boot', session, vm_ref)
800 def VM_get_platform_std_VGA(self, session, vm_ref):
801 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
802 return xen_api_todo()
804 def VM_get_platform_serial(self, session, vm_ref):
805 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
806 return xen_api_todo()
808 def VM_get_platform_localtime(self, session, vm_ref):
809 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
810 return xen_api_todo()
812 def VM_get_platform_clock_offset(self, session, vm_ref):
813 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
814 return xen_api_todo()
816 def VM_get_platform_enable_audio(self, session, vm_ref):
817 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
818 return xen_api_todo()
820 def VM_get_platform_keymap(self, session, vm_ref):
821 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
822 return xen_api_todo()
824 def VM_get_otherConfig(self, session, vm_ref):
825 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
826 return xen_api_todo()
828 def VM_set_name_label(self, session, vm_ref, label):
829 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
830 dom.setName(label)
831 return xen_api_success_void()
833 def VM_set_name_description(self, session, vm_ref):
834 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
835 return xen_api_success_void()
837 def VM_set_user_version(self, session, vm_ref):
838 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
839 return xen_api_success_void()
841 def VM_set_is_a_template(self, session, vm_ref):
842 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
843 return xen_api_success_void()
845 def VM_set_memory_dynamic_max(self, session, vm_ref):
846 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
847 return xen_api_success_void()
849 def VM_set_memory_dynamic_min(self, session, vm_ref):
850 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
851 return xen_api_success_void()
853 def VM_set_VCPUs_policy(self, session, vm_ref):
854 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
855 return xen_api_success_void()
857 def VM_set_VCPUs_params(self, session, vm_ref):
858 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
859 return xen_api_success_void()
861 def VM_set_VCPUs_features_force_on(self, session, vm_ref):
862 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
863 return xen_api_success_void()
865 def VM_set_VCPUs_features_force_off(self, session, vm_ref):
866 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
867 return xen_api_success_void()
869 def VM_set_actions_after_shutdown(self, session, vm_ref):
870 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
871 return xen_api_success_void()
873 def VM_set_actions_after_reboot(self, session, vm_ref):
874 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
875 return xen_api_success_void()
877 def VM_set_actions_after_suspend(self, session, vm_ref):
878 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
879 return xen_api_success_void()
881 def VM_set_actions_after_crash(self, session, vm_ref):
882 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
883 return xen_api_success_void()
885 def VM_set_HVM_boot(self, session, vm_ref, value):
886 return self.VM_set('HVM_boot', session, vm_ref, value)
888 def VM_set_PV_bootloader(self, session, vm_ref, value):
889 return self.VM_set('PV_bootloader', session, vm_ref, value)
891 def VM_set_PV_kernel(self, session, vm_ref, value):
892 return self.VM_set('PV_kernel', session, vm_ref, value)
894 def VM_set_PV_ramdisk(self, session, vm_ref, value):
895 return self.VM_set('PV_ramdisk', session, vm_ref, value)
897 def VM_set_PV_args(self, session, vm_ref, value):
898 return self.VM_set('PV_args', session, vm_ref, value)
900 def VM_set_PV_bootloader_args(self, session, vm_ref, value):
901 return self.VM_set('PV_bootloader_args', session, vm_ref, value)
903 def VM_set_platform_std_VGA(self, session, vm_ref):
904 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
905 return xen_api_success_void()
907 def VM_set_platform_serial(self, session, vm_ref):
908 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
909 return xen_api_success_void()
911 def VM_set_platform_localtime(self, session, vm_ref):
912 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
913 return xen_api_success_void()
915 def VM_set_platform_clock_offset(self, session, vm_ref):
916 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
917 return xen_api_success_void()
919 def VM_set_platform_enable_audio(self, session, vm_ref):
920 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
921 return xen_api_success_void()
923 def VM_set_otherConfig(self, session, vm_ref):
924 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
925 return xen_api_success_void()
927 # class methods
928 def VM_get_all(self, session):
929 refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
930 return xen_api_success(refs)
932 def VM_get_by_name_label(self, session, label):
933 xendom = XendDomain.instance()
934 dom = xendom.domain_lookup_nr(label)
935 if dom:
936 return xen_api_success([dom.get_uuid()])
937 return xen_api_error(XEND_ERROR_VM_INVALID)
939 def VM_create(self, session, vm_struct):
940 xendom = XendDomain.instance()
941 domuuid = xendom.create_domain(vm_struct)
942 return xen_api_success(domuuid)
944 # object methods
945 def VM_get_record(self, session, vm_ref):
946 xendom = XendDomain.instance()
947 xeninfo = xendom.get_vm_by_uuid(vm_ref)
948 if not xeninfo:
949 return xen_api_error(XEND_ERROR_VM_INVALID)
951 record = {
952 'uuid': xeninfo.get_uuid(),
953 'power_state': xeninfo.get_power_state(),
954 'name_label': xeninfo.getName(),
955 'name_description': xeninfo.getName(),
956 'user_version': 1,
957 'is_a_template': False,
958 'auto_power_on': False,
959 'resident_on': XendNode.instance().uuid,
960 'memory_static_min': xeninfo.get_memory_static_min(),
961 'memory_static_max': xeninfo.get_memory_static_max(),
962 'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
963 'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
964 'memory_actual': xeninfo.get_memory_static_min(),
965 'VCPUs_policy': xeninfo.get_vcpus_policy(),
966 'VCPUs_params': xeninfo.get_vcpus_params(),
967 'VCPUs_number': xeninfo.getVCpuCount(),
968 'VCPUs_utilisation': xeninfo.get_vcpus_util(),
969 'VCPUs_features_required': [],
970 'VCPUs_features_can_use': [],
971 'VCPUs_features_force_on': [],
972 'VCPUs_features_force_off': [],
973 'actions_after_shutdown': xeninfo.get_on_shutdown(),
974 'actions_after_reboot': xeninfo.get_on_reboot(),
975 'actions_after_suspend': xeninfo.get_on_suspend(),
976 'actions_after_crash': xeninfo.get_on_crash(),
977 'consoles': xeninfo.get_consoles(),
978 'VIFs': xeninfo.get_vifs(),
979 'VBDs': xeninfo.get_vbds(),
980 'VTPMs': xeninfo.get_vtpms(),
981 'PV_bootloader': xeninfo.info.get('PV_bootloader'),
982 'PV_kernel': xeninfo.info.get('PV_kernel'),
983 'PV_ramdisk': xeninfo.info.get('PV_ramdisk'),
984 'PV_args': xeninfo.info.get('PV_args'),
985 'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
986 'HVM_boot': xeninfo.info.get('HVM_boot'),
987 'platform_std_VGA': xeninfo.get_platform_std_vga(),
988 'platform_serial': xeninfo.get_platform_serial(),
989 'platform_localtime': xeninfo.get_platform_localtime(),
990 'platform_clock_offset': xeninfo.get_platform_clock_offset(),
991 'platform_enable_audio': xeninfo.get_platform_enable_audio(),
992 'platform_keymap': xeninfo.get_platform_keymap(),
993 'PCI_bus': xeninfo.get_pci_bus(),
994 'tools_version': xeninfo.get_tools_version(),
995 'otherConfig': xeninfo.get_other_config()
996 }
997 return xen_api_success(record)
999 def VM_clean_reboot(self, session, vm_ref):
1000 xendom = XendDomain.instance()
1001 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1002 xeninfo.shutdown("reboot")
1003 return xen_api_success_void()
1004 def VM_clean_shutdown(self, session, vm_ref):
1005 xendom = XendDomain.instance()
1006 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1007 xeninfo.shutdown("poweroff")
1008 return xen_api_success_void()
1009 def VM_clone(self, session, vm_ref):
1010 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1011 def VM_destroy(self, session, vm_ref):
1012 return do_vm_func("domain_delete", vm_ref)
1013 def VM_hard_reboot(self, session, vm_ref):
1014 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1015 def VM_hard_shutdown(self, session, vm_ref):
1016 return do_vm_func("domain_destroy", vm_ref)
1017 def VM_pause(self, session, vm_ref):
1018 return do_vm_func("domain_pause", vm_ref)
1019 def VM_resume(self, session, vm_ref, start_paused):
1020 return do_vm_func("domain_resume", vm_ref, start_paused = start_paused)
1021 def VM_start(self, session, vm_ref, start_paused):
1022 return do_vm_func("domain_start", vm_ref, start_paused = start_paused)
1023 def VM_suspend(self, session, vm_ref):
1024 return do_vm_func("domain_suspend", vm_ref)
1025 def VM_unpause(self, session, vm_ref):
1026 return do_vm_func("domain_unpause", vm_ref)
1028 # Xen API: Class VBD
1029 # ----------------------------------------------------------------
1030 # Note: accepts a non-API standard 'image' attribute to emulate
1031 # regular xm created VBDs
1033 VBD_attr_ro = ['image',
1034 'io_read_kbs',
1035 'io_write_kbs']
1036 VBD_attr_rw = ['VM',
1037 'VDI',
1038 'device',
1039 'mode',
1040 'driver']
1042 VBD_attr_inst = VBD_attr_rw + ['image']
1044 VBD_methods = ['media_change']
1046 # object methods
1047 def VBD_get_record(self, session, vbd_ref):
1048 xendom = XendDomain.instance()
1049 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1050 if not vm:
1051 return xen_api_error(XEND_ERROR_VBD_INVALID)
1052 cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
1053 if not cfg:
1054 return xen_api_error(XEND_ERROR_VBD_INVALID)
1056 valid_vbd_keys = self.VBD_attr_ro + self.VBD_attr_rw + \
1057 self.Base_attr_ro + self.Base_attr_rw
1059 return_cfg = {}
1060 for k in cfg.keys():
1061 if k in valid_vbd_keys:
1062 return_cfg[k] = cfg[k]
1064 return xen_api_success(return_cfg)
1066 def VBD_media_change(self, session, vbd_ref, vdi_ref):
1067 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1069 # class methods
1070 def VBD_create(self, session, vbd_struct):
1071 xendom = XendDomain.instance()
1072 if not xendom.is_valid_vm(vbd_struct['VM']):
1073 return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
1075 dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
1076 vbd_ref = ''
1077 try:
1078 if not vbd_struct.get('VDI', None):
1079 # this is a traditional VBD without VDI and SR
1080 vbd_ref = dom.create_vbd(vbd_struct)
1081 else:
1082 # new VBD via VDI/SR
1083 vdi_ref = vbd_struct.get('VDI')
1084 sr = XendNode.instance().get_sr()
1085 vdi_image = sr.xen_api_get_by_uuid(vdi_ref)
1086 if not vdi_image:
1087 return xen_api_error(XEND_ERROR_VDI_INVALID)
1088 vdi_image = vdi_image.qcow_path
1089 vbd_ref = dom.create_vbd_with_vdi(vbd_struct, vdi_image)
1090 except XendError:
1091 return xen_api_todo()
1093 xendom.managed_config_save(dom)
1094 return xen_api_success(vbd_ref)
1096 # attributes (rw)
1097 def VBD_get_VM(self, session, vbd_ref):
1098 xendom = XendDomain.instance()
1099 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'VM'))
1101 def VBD_get_VDI(self, session, vbd_ref):
1102 return xen_api_todo()
1104 def VBD_get_device(self, session, vbd_ref):
1105 xendom = XendDomain.instance()
1106 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
1107 'device'))
1108 def VBD_get_mode(self, session, vbd_ref):
1109 xendom = XendDomain.instance()
1110 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
1111 'mode'))
1112 def VBD_get_driver(self, session, vbd_ref):
1113 xendom = XendDomain.instance()
1114 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
1115 'driver'))
1117 # Xen API: Class VIF
1118 # ----------------------------------------------------------------
1120 VIF_attr_ro = ['io_read_kbs',
1121 'io_write_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)
1142 valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
1143 self.Base_attr_ro + self.Base_attr_rw
1145 return_cfg = {}
1146 for k in cfg.keys():
1147 if k in valid_vif_keys:
1148 return_cfg[k] = cfg[k]
1150 return xen_api_success(return_cfg)
1152 # class methods
1153 def VIF_create(self, session, vif_struct):
1154 xendom = XendDomain.instance()
1155 if xendom.is_valid_vm(vif_struct['VM']):
1156 dom = xendom.get_vm_by_uuid(vif_struct['VM'])
1157 try:
1158 vif_ref = dom.create_vif(vif_struct)
1159 xendom.managed_config_save(dom)
1160 return xen_api_success(vif_ref)
1161 except XendError:
1162 return xen_api_error(XEND_ERROR_TODO)
1163 else:
1164 return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
1167 # Xen API: Class VDI
1168 # ----------------------------------------------------------------
1169 VDI_attr_ro = ['VBDs',
1170 'physical_utilisation',
1171 'sector_size',
1172 'type',
1173 'parent',
1174 'children']
1175 VDI_attr_rw = ['name_label',
1176 'name_description',
1177 'SR',
1178 'virtual_size',
1179 'sharable',
1180 'read_only']
1181 VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
1183 VDI_methods = ['snapshot']
1184 VDI_funcs = ['get_by_name_label']
1186 def VDI_get_VBDs(self, session, vdi_ref):
1187 return xen_api_todo()
1189 def VDI_get_physical_utilisation(self, session, vdi_ref):
1190 sr = XendNode.instance().get_sr()
1191 image = sr.xen_api_get_by_uuid(vdi_ref)
1192 return xen_api_success(image.get_physical_utilisation())
1194 def VDI_get_sector_size(self, session, vdi_ref):
1195 sr = XendNode.instance().get_sr()
1196 image = sr.xen_api_get_by_uuid(vdi_ref)
1197 return xen_api_success(image.sector_size)
1199 def VDI_get_type(self, session, vdi_ref):
1200 sr = XendNode.instance().get_sr()
1201 image = sr.xen_api_get_by_uuid(vdi_ref)
1202 return xen_api_success(image.type)
1204 def VDI_get_parent(self, session, vdi_ref):
1205 sr = XendNode.instance().get_sr()
1206 image = sr.xen_api_get_by_uuid(vdi_ref)
1207 return xen_api_success(image.parent)
1209 def VDI_get_children(self, session, vdi_ref):
1210 sr = XendNode.instance().get_sr()
1211 image = sr.xen_api_get_by_uuid(vdi_ref)
1212 return xen_api_success(image.children)
1214 def VDI_get_name_label(self, session, vdi_ref):
1215 sr = XendNode.instance().get_sr()
1216 image = sr.xen_api_get_by_uuid(vdi_ref)
1217 return xen_api_success(image.name_label)
1219 def VDI_get_name_description(self, session, vdi_ref):
1220 sr = XendNode.instance().get_sr()
1221 image = sr.xen_api_get_by_uuid(vdi_ref)
1222 return xen_api_success(image.name_description)
1224 def VDI_get_SR(self, session, vdi_ref):
1225 sr = XendNode.instance().get_sr()
1226 return xen_api_success(sr.uuid)
1228 def VDI_get_virtual_size(self, session, vdi_ref):
1229 sr = XendNode.instance().get_sr()
1230 image = sr.xen_api_get_by_uuid(vdi_ref)
1231 return xen_api_success(image.virtual_size)
1233 def VDI_get_sharable(self, session, vdi_ref):
1234 sr = XendNode.instance().get_sr()
1235 image = sr.xen_api_get_by_uuid(vdi_ref)
1236 return xen_api_success(image.sharable)
1238 def VDI_get_read_only(self, session, vdi_ref):
1239 sr = XendNode.instance().get_sr()
1240 image = sr.xen_api_get_by_uuid(vdi_ref)
1241 return xen_api_success(image.sharable)
1243 def VDI_set_name_label(self, session, vdi_ref, value):
1244 sr = XendNode.instance().get_sr()
1245 image = sr.xen_api_get_by_uuid(vdi_ref)
1246 image.name_label = value
1247 return xen_api_success_void()
1249 def VDI_set_name_description(self, session, vdi_ref, value):
1250 sr = XendNode.instance().get_sr()
1251 image = sr.xen_api_get_by_uuid(vdi_ref)
1252 image.name_description = value
1253 return xen_api_success_void()
1255 def VDI_set_SR(self, session, vdi_ref, value):
1256 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1258 def VDI_set_virtual_size(self, session, vdi_ref, value):
1259 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1261 def VDI_set_sharable(self, session, vdi_ref, value):
1262 return xen_api_todo()
1263 def VDI_set_read_only(self, session, vdi_ref, value):
1264 return xen_api_todo()
1266 # Object Methods
1267 def VDI_snapshot(self, session, vdi_ref):
1268 return xen_api_todo()
1270 def VDI_destroy(self, session, vdi_ref):
1271 sr = XendNode.instance().get_sr()
1272 sr.destroy_image(vdi_ref)
1273 return xen_api_success_void()
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)
1452 def SR_destroy(self, session, sr_ref):
1453 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1455 def SR_get_record(self, session, sr_ref):
1456 sr = XendNode.instance().get_sr()
1457 return xen_api_success({
1458 'uuid': sr.uuid,
1459 'name_label': sr.name_label,
1460 'name_description': sr.name_description,
1461 'VDIs': sr.list_images(),
1462 'virtual_allocation': sr.used_space_bytes(),
1463 'physical_utilisation': sr.used_space_bytes(),
1464 'physical_size': sr.total_space_bytes(),
1465 'type': sr.type,
1466 'location': sr.location
1467 })
1469 # Attribute acceess
1470 def SR_get_VDIs(self, session, sr_ref):
1471 sr = XendNode.instance().get_sr()
1472 return xen_api_success(sr.list_images())
1474 def SR_get_virtual_allocation(self, session, sr_ref):
1475 sr = XendNode.instance().get_sr()
1476 return sr.used_space_bytes()
1478 def SR_get_physical_utilisation(self, session, sr_ref):
1479 sr = XendNode.instance().get_sr()
1480 return sr.used_space_bytes()
1482 def SR_get_physical_size(self, session, sr_ref):
1483 sr = XendNode.instance().get_sr()
1484 return sr.total_space_bytes()
1486 def SR_get_type(self, session, sr_ref):
1487 sr = XendNode.instance().get_sr()
1488 return xen_api_success(sr.type)
1490 def SR_get_location(self, session, sr_ref):
1491 sr = XendNode.instance().get_sr()
1492 return xen_api_success(sr.location)
1494 def SR_get_name_label(self, session, sr_ref):
1495 sr = XendNode.instance().get_sr()
1496 return xen_api_success(sr.name_label)
1498 def SR_get_name_description(self, session, sr_ref):
1499 sr = XendNode.instance().get_sr()
1500 return xen_api_success(sr.name_description)
1502 def SR_set_name_label(self, session, sr_ref, value):
1503 sr = XendNode.instance().get_sr()
1504 sr.name_label = value
1505 return xen_api_success_void()
1507 def SR_set_name_description(self, session, sr_ref, value):
1508 sr = XendNode.instance().get_sr()
1509 sr.name_description = value
1510 return xen_api_success_void()
1513 # Auto generate some stubs based on XendAPI introspection
1515 if __name__ == "__main__":
1516 def output(line):
1517 print ' ' + line
1519 classes = ['VDI', 'SR']
1520 for cls in classes:
1521 ro_attrs = getattr(XendAPI, '%s_attr_ro' % cls, [])
1522 rw_attrs = getattr(XendAPI, '%s_attr_rw' % cls, [])
1523 methods = getattr(XendAPI, '%s_methods' % cls, [])
1524 funcs = getattr(XendAPI, '%s_funcs' % cls, [])
1526 ref = '%s_ref' % cls
1528 for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
1529 getter_name = '%s_get_%s' % (cls, attr_name)
1530 output('def %s(self, session, %s):' % (getter_name, ref))
1531 output(' return xen_api_todo()')
1533 for attr_name in rw_attrs + XendAPI.Base_attr_rw:
1534 setter_name = '%s_set_%s' % (cls, attr_name)
1535 output('def %s(self, session, %s, value):' % (setter_name, ref))
1536 output(' return xen_api_todo()')
1538 for method_name in methods + XendAPI.Base_methods:
1539 method_full_name = '%s_%s' % (cls,method_name)
1540 output('def %s(self, session, %s):' % (method_full_name, ref))
1541 output(' return xen_api_todo()')
1543 for func_name in funcs + XendAPI.Base_funcs:
1544 func_full_name = '%s_%s' % (cls, func_name)
1545 output('def %s(self, session):' % func_full_name)
1546 output(' return xen_api_todo()')