ia64/xen-unstable

view tools/python/xen/xend/XendAPI.py @ 12756:dc9a47212ac4

[XEND] Fix case mismatch in VM.get_record for Xen API

Also make VM.get_all return halted domains too.

Signed-off-by: Alastair Tse <atse@xensource.com>
author Alastair Tse <atse@xensource.com>
date Fri Dec 01 17:21:19 2006 +0000 (2006-12-01)
parents 09c29e91e3cd
children 795a87426e48
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
307 get_uuid = '%s_get_uuid' % cls
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, 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, 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, method_name)
358 try:
359 method = getattr(XendAPI, method_full_name)
360 for validator in validators:
361 method = validator(method)
362 method.api = '%s.%s' % (cls, method_name)
363 setattr(XendAPI, method_full_name, method)
364 except AttributeError:
365 pass
366 #log.warn('API call: %s not found' % method_full_name)
368 # wrap validators around class functions
369 for func_name in funcs + self.Base_funcs:
370 func_full_name = '%s_%s' % (cls, func_name)
371 try:
372 method = getattr(XendAPI, func_full_name)
373 method = session_required(method)
374 method.api = '%s.%s' % (cls, func_name)
375 setattr(XendAPI, func_full_name, method)
376 except AttributeError:
377 pass
378 #log.warn('API call: %s not found' % func_full_name)
381 Base_attr_ro = ['uuid']
382 Base_attr_rw = []
383 Base_methods = ['destroy', 'get_record']
384 Base_funcs = ['create', 'get_by_uuid', 'get_all']
386 # Xen API: Class Session
387 # ----------------------------------------------------------------
388 # NOTE: Left unwrapped by __init__
390 session_attr_ro = ['this_host', 'this_user']
391 session_methods = ['logout']
392 # session_funcs = ['login_with_password']
394 def session_login_with_password(self, username, password):
395 try:
396 session = (self.auth == AUTH_NONE and
397 auth_manager().login_unconditionally(username) or
398 auth_manager().login_with_password(username, password))
399 return xen_api_success(session)
400 except XendError, e:
401 return xen_api_error(XEND_ERROR_AUTHENTICATION_FAILED)
402 session_login_with_password.api = 'session.login_with_password'
405 # object methods
406 def session_logout(self, session):
407 auth_manager().logout(session)
408 return xen_api_success_void()
409 def session_destroy(self, session):
410 return xen_api_error(XEND_ERROR_UNSUPPORTED)
411 def session_get_record(self, session):
412 record = {'this_host': XendNode.instance().uuid,
413 'this_user': auth_manager().get_user(session)}
414 return xen_api_success(record)
416 # attributes (ro)
417 def session_get_this_host(self, session):
418 return xen_api_success(XendNode.instance().uuid)
419 def session_get_this_user(self, session):
420 user = auth_manager().get_user(session)
421 if user:
422 return xen_api_success(user)
423 return xen_api_error(XEND_ERROR_SESSION_INVALID)
426 # Xen API: Class User
427 # ----------------------------------------------------------------
428 # TODO: NOT IMPLEMENTED YET
430 # Xen API: Class Tasks
431 # ----------------------------------------------------------------
432 # TODO: NOT IMPLEMENTED YET
434 # Xen API: Class Host
435 # ----------------------------------------------------------------
437 host_attr_ro = ['software_version',
438 'resident_VMs',
439 'host_CPUs']
441 host_attr_rw = ['name_label',
442 'name_description']
444 host_methods = ['disable',
445 'enable',
446 'reboot',
447 'shutdown']
449 host_funcs = ['get_by_name_label']
451 # attributes
452 def host_get_name_label(self, session, host_ref):
453 return xen_api_success(XendNode.instance().name)
454 def host_set_name_label(self, session, host_ref, new_name):
455 XendNode.instance().set_name(new_name)
456 return xen_api_success_void()
457 def host_get_name_description(self, session, host_ref):
458 return xen_api_success(XendNode.instance().description)
459 def host_set_name_description(self, session, host_ref, new_desc):
460 XendNode.instance().set_description(new_desc)
461 return xen_api_success_void()
462 def host_get_software_version(self, session, host_ref):
463 return xen_api_success(XendNode.instance().xen_version())
464 def host_get_resident_VMs(self, session, host_ref):
465 return xen_api_success(XendDomain.instance().get_domain_refs())
466 def host_get_host_CPUs(self, session, host_ref):
467 return xen_api_success(XendNode.instance().get_host_cpu_refs())
469 # object methods
470 def host_destroy(self, session, host_ref):
471 return xen_api_error(XEND_ERROR_UNSUPPORTED)
472 def host_disable(self, session, host_ref):
473 XendDomain.instance().set_allow_new_domains(False)
474 return xen_api_success_void()
475 def host_enable(self, session, host_ref):
476 XendDomain.instance().set_allow_new_domains(True)
477 return xen_api_success_void()
478 def host_reboot(self, session, host_ref):
479 if not XendDomain.instance().allow_new_domains():
480 return xen_api_error(XEND_ERROR_HOST_RUNNING)
481 return xen_api_error(XEND_ERROR_UNSUPPORTED)
482 def host_shutdown(self, session, host_ref):
483 if not XendDomain.instance().allow_new_domains():
484 return xen_api_error(XEND_ERROR_HOST_RUNNING)
485 return xen_api_error(XEND_ERROR_UNSUPPORTED)
486 def host_get_record(self, session, host_ref):
487 node = XendNode.instance()
488 dom = XendDomain.instance()
489 record = {'uuid': node.uuid,
490 'name_label': node.name,
491 'name_description': '',
492 'software_version': node.xen_version(),
493 'resident_VMs': dom.get_domain_refs(),
494 'host_CPUs': node.get_host_cpu_refs()}
495 return xen_api_success(record)
497 # class methods
498 def host_get_all(self, session):
499 return xen_api_success((XendNode.instance().uuid,))
500 def host_create(self, session, struct):
501 return xen_api_error(XEND_ERROR_UNSUPPORTED)
503 # Xen API: Class Host_CPU
504 # ----------------------------------------------------------------
506 host_cpu_attr_ro = ['host',
507 'number',
508 'features',
509 'utilisation']
511 # attributes
512 def host_cpu_get_uuid(self, session, host_cpu_ref):
513 uuid = XendNode.instance().get_host_cpu_uuid(host_cpu_ref)
514 return xen_api_success(uuid)
515 def host_cpu_get_host(self, session, host_cpu_ref):
516 return xen_api_success(XendNode.instance().uuid)
517 def host_cpu_get_features(self, session, host_cpu_ref):
518 features = XendNode.instance().get_host_cpu_features(host_cpu_ref)
519 return xen_api_success(features)
520 def host_cpu_get_utilisation(self, session, host_cpu_ref):
521 util = XendNode.instance().get_host_cpu_load(host_cpu_ref)
522 return xen_api_success(util)
523 def host_cpu_get_number(self, session, host_cpu_ref):
524 num = XendNode.instance().get_host_cpu_number(host_cpu_ref)
525 return xen_api_success(num)
527 # object methods
528 def host_cpu_destroy(self, session, host_cpu_ref):
529 return xen_api_error(XEND_ERROR_UNSUPPORTED)
530 def host_cpu_get_record(self, session, host_cpu_ref):
531 node = XendNode.instance()
532 record = {'uuid': host_cpu_ref,
533 'host': node.uuid,
534 'number': node.get_host_cpu_number(host_cpu_ref),
535 'features': node.get_host_cpu_features(host_cpu_ref),
536 'utilisation': node.get_host_cpu_load(host_cpu_ref)}
537 return xen_api_success(record)
539 # class methods
540 def host_cpu_get_all(self, session):
541 return xen_api_success(XendNode.instance().get_host_cpu_refs())
542 def host_cpu_create(self, session, struct):
543 return xen_api_error(XEND_ERROR_UNSUPPORTED)
546 # Xen API: Class Network
547 # ----------------------------------------------------------------
548 # TODO: NOT IMPLEMENTED
550 Network_attr_ro = ['VIFs']
551 Network_attr_rw = ['name_label',
552 'name_description',
553 'NIC',
554 'VLAN',
555 'default_gateway',
556 'default_netmask']
558 # Xen API: Class VM
559 # ----------------------------------------------------------------
561 VM_attr_ro = ['power_state',
562 'resident_on',
563 'memory_actual',
564 'memory_static_max',
565 'memory_static_min',
566 'VCPUs_number',
567 'VCPUs_utilisation',
568 'VCPUs_features_required',
569 'VCPUs_can_use',
570 'VIFs',
571 'VBDs',
572 'VTPMs',
573 'PCI_bus',
574 'tools_version',
575 ]
577 VM_attr_rw = ['name_label',
578 'name_description',
579 'user_version',
580 'is_a_template',
581 'memory_dynamic_max',
582 'memory_dynamic_min',
583 'VCPUs_policy',
584 'VCPUs_params',
585 'VCPUs_features_force_on',
586 'VCPUs_features_force_off',
587 'actions_after_shutdown',
588 'actions_after_reboot',
589 'actions_after_suspend',
590 'actions_after_crash',
591 'bios_boot',
592 'platform_std_VGA',
593 'platform_serial',
594 'platform_localtime',
595 'platform_clock_offset',
596 'platform_enable_audio',
597 'platform_keymap',
598 'builder',
599 'boot_method',
600 'kernel_kernel',
601 'kernel_initrd',
602 'kernel_args',
603 'grub_cmdline',
604 'otherConfig']
606 VM_methods = ['clone',
607 'start',
608 'pause',
609 'unpause',
610 'clean_shutdown',
611 'clean_reboot',
612 'hard_shutdown',
613 'hard_reboot',
614 'suspend',
615 'resume']
617 VM_funcs = ['get_by_name_label']
619 # parameters required for _create()
620 VM_attr_inst = [
621 'name_label',
622 'name_description',
623 'user_version',
624 'is_a_template',
625 'memory_static_max',
626 'memory_dynamic_max',
627 'memory_dynamic_min',
628 'memory_static_min',
629 'VCPUs_policy',
630 'VCPUs_params',
631 'VCPUs_features_required',
632 'VCPUs_features_can_use',
633 'VCPUs_features_force_on',
634 'VCPUs_features_force_off',
635 'actions_after_shutdown',
636 'actions_after_reboot',
637 'actions_after_suspend',
638 'actions_after_crash',
639 'bios_boot',
640 'platform_std_VGA',
641 'platform_serial',
642 'platform_localtime',
643 'platform_clock_offset',
644 'platform_enable_audio',
645 'platform_keymap',
646 'builder',
647 'boot_method',
648 'kernel_kernel',
649 'kernel_initrd',
650 'kernel_args',
651 'grub_cmdline',
652 'PCI_bus',
653 'otherConfig']
655 # attributes (ro)
656 def VM_get_power_state(self, session, vm_ref):
657 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
658 return xen_api_success(dom.state)
660 def VM_get_resident_on(self, session, vm_ref):
661 return xen_api_success(XendNode.instance().uuid)
663 def VM_get_memory_actual(self, session, vm_ref):
664 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
665 return xen_api_todo() # unsupported by xc
667 def VM_get_memory_static_max(self, session, vm_ref):
668 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
669 return xen_api_success(dom.get_memory_static_max())
671 def VM_get_memory_static_min(self, session, vm_ref):
672 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
673 return xen_api_success(dom.get_memory_static_min())
675 def VM_get_VCPUs_number(self, session, vm_ref):
676 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
677 return xen_api_success(dom.getVCpuCount())
679 def VM_get_VCPUs_utilisation(self, session, vm_ref):
680 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
681 return xen_api_success(dom.get_vcpus_util())
683 def VM_get_VCPUs_features_required(self, session, vm_ref):
684 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
685 return xen_api_todo() # unsupported by xc
687 def VM_get_VCPUs_can_use(self, session, vm_ref):
688 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
689 return xen_api_todo() # unsupported by xc
691 def VM_get_VIFs(self, session, vm_ref):
692 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
693 return xen_api_success(dom.get_vifs())
695 def VM_get_VBDs(self, session, vm_ref):
696 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
697 return xen_api_success(dom.get_vbds())
699 def VM_get_VTPMs(self, session, vm_ref):
700 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
701 return xen_api_success(dom.get_vtpms())
703 def VM_get_PCI_bus(self, session, vm_ref):
704 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
705 return xen_api_todo() # unsupported by xc
707 def VM_get_tools_version(self, session, vm_ref):
708 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
709 return xen_api_todo()
711 # attributes (rw)
712 def VM_get_name_label(self, session, vm_ref):
713 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
714 return xen_api_success(dom.getName())
716 def VM_get_name_description(self, session, vm_ref):
717 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
718 return xen_api_todo()
720 def VM_get_user_version(self, session, vm_ref):
721 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
722 return xen_api_todo()
724 def VM_get_is_a_template(self, session, vm_ref):
725 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
726 return xen_api_todo()
728 def VM_get_memory_dynamic_max(self, session, vm_ref):
729 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
730 return xen_api_success(dom.get_memory_dynamic_max())
732 def VM_get_memory_dynamic_min(self, session, vm_ref):
733 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
734 return xen_api_success(dom.get_memory_dynamic_min())
736 def VM_get_VCPUs_policy(self, session, vm_ref):
737 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
738 return xen_api_todo() # need to access scheduler
740 def VM_get_VCPUs_params(self, session, vm_ref):
741 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
742 return xen_api_todo() # need access to scheduler
744 def VM_get_VCPUs_features_force_on(self, session, vm_ref):
745 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
746 return xen_api_todo()
748 def VM_get_VCPUs_features_force_off(self, session, vm_ref):
749 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
750 return xen_api_todo()
752 def VM_get_actions_after_shutdown(self, session, vm_ref):
753 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
754 return xen_api_success(dom.get_on_shutdown())
756 def VM_get_actions_after_reboot(self, session, vm_ref):
757 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
758 return xen_api_success(dom.get_on_reboot())
760 def VM_get_actions_after_suspend(self, session, vm_ref):
761 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
762 return xen_api_success(dom.get_on_suspend())
764 def VM_get_actions_after_crash(self, session, vm_ref):
765 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
766 return xen_api_success(dom.get_on_crash())
768 def VM_get_bios_boot(self, session, vm_ref):
769 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
770 return xen_api_success(dom.get_bios_boot())
772 def VM_get_platform_std_VGA(self, session, vm_ref):
773 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
774 return xen_api_todo()
776 def VM_get_platform_serial(self, session, vm_ref):
777 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
778 return xen_api_todo()
780 def VM_get_platform_localtime(self, session, vm_ref):
781 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
782 return xen_api_todo()
784 def VM_get_platform_clock_offset(self, session, vm_ref):
785 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
786 return xen_api_todo()
788 def VM_get_platform_enable_audio(self, session, vm_ref):
789 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
790 return xen_api_todo()
792 def VM_get_platform_keymap(self, session, vm_ref):
793 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
794 return xen_api_todo()
796 def VM_get_builder(self, session, vm_ref):
797 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
798 return xen_api_success(dom.get_builder())
800 def VM_get_boot_method(self, session, vm_ref):
801 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
802 return xen_api_success(dom.get_boot_method())
804 def VM_get_kernel_kernel(self, session, vm_ref):
805 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
806 return xen_api_success('')
808 def VM_get_kernel_initrd(self, session, vm_ref):
809 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
810 return xen_api_success('')
812 def VM_get_kernel_args(self, session, vm_ref):
813 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
814 return xen_api_success('')
816 def VM_get_grub_cmdline(self, session, vm_ref):
817 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
818 return xen_api_success('')
820 def VM_get_otherConfig(self, session, vm_ref):
821 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
822 return xen_api_todo()
824 def VM_set_name_label(self, session, vm_ref):
825 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
826 return xen_api_success_void()
828 def VM_set_name_description(self, session, vm_ref):
829 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
830 return xen_api_success_void()
832 def VM_set_user_version(self, session, vm_ref):
833 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
834 return xen_api_success_void()
836 def VM_set_is_a_template(self, session, vm_ref):
837 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
838 return xen_api_success_void()
840 def VM_set_memory_dynamic_max(self, session, vm_ref):
841 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
842 return xen_api_success_void()
844 def VM_set_memory_dynamic_min(self, session, vm_ref):
845 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
846 return xen_api_success_void()
848 def VM_set_VCPUs_policy(self, session, vm_ref):
849 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
850 return xen_api_success_void()
852 def VM_set_VCPUs_params(self, session, vm_ref):
853 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
854 return xen_api_success_void()
856 def VM_set_VCPUs_features_force_on(self, session, vm_ref):
857 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
858 return xen_api_success_void()
860 def VM_set_VCPUs_features_force_off(self, session, vm_ref):
861 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
862 return xen_api_success_void()
864 def VM_set_actions_after_shutdown(self, session, vm_ref):
865 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
866 return xen_api_success_void()
868 def VM_set_actions_after_reboot(self, session, vm_ref):
869 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
870 return xen_api_success_void()
872 def VM_set_actions_after_suspend(self, session, vm_ref):
873 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
874 return xen_api_success_void()
876 def VM_set_actions_after_crash(self, session, vm_ref):
877 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
878 return xen_api_success_void()
880 def VM_set_bios_boot(self, session, vm_ref):
881 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
882 return xen_api_success_void()
884 def VM_set_platform_std_VGA(self, session, vm_ref):
885 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
886 return xen_api_success_void()
888 def VM_set_platform_serial(self, session, vm_ref):
889 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
890 return xen_api_success_void()
892 def VM_set_platform_localtime(self, session, vm_ref):
893 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
894 return xen_api_success_void()
896 def VM_set_platform_clock_offset(self, session, vm_ref):
897 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
898 return xen_api_success_void()
900 def VM_set_platform_enable_audio(self, session, vm_ref):
901 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
902 return xen_api_success_void()
904 def VM_set_builder(self, session, vm_ref):
905 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
906 return xen_api_success_void()
908 def VM_set_boot_method(self, session, vm_ref):
909 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
910 return xen_api_success_void()
912 def VM_set_kernel_kernel(self, session, vm_ref):
913 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
914 return xen_api_success_void()
916 def VM_set_kernel_initrd(self, session, vm_ref):
917 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
918 return xen_api_success_void()
920 def VM_set_kernel_args(self, session, vm_ref):
921 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
922 return xen_api_success_void()
924 def VM_set_grub_cmdline(self, session, vm_ref):
925 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
926 return xen_api_success_void()
928 def VM_set_otherConfig(self, session, vm_ref):
929 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
930 return xen_api_success_void()
932 # class methods
933 def VM_get_all(self, session):
934 refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
935 return xen_api_success(refs)
937 def VM_get_by_name_label(self, session, label):
938 xendom = XendDomain.instance()
939 dom = xendom.domain_lookup_nr(label)
940 if dom:
941 return xen_api_success([dom.get_uuid()])
942 return xen_api_error(XEND_ERROR_VM_INVALID)
944 def VM_create(self, session, vm_struct):
945 xendom = XendDomain.instance()
946 domuuid = xendom.create_domain(vm_struct)
947 return xen_api_success(domuuid)
949 # object methods
950 def VM_get_record(self, session, vm_ref):
951 xendom = XendDomain.instance()
952 xeninfo = xendom.get_vm_by_uuid(vm_ref)
953 if not xeninfo:
954 return xen_api_error(XEND_ERROR_VM_INVALID)
956 record = {
957 'uuid': xeninfo.get_uuid(),
958 'power_state': xeninfo.get_power_state(),
959 'name_label': xeninfo.getName(),
960 'name_description': xeninfo.getName(),
961 'user_version': 1,
962 'is_a_template': False,
963 'resident_on': XendNode.instance().uuid,
964 'memory_static_min': xeninfo.get_memory_static_min(),
965 'memory_static_max': xeninfo.get_memory_static_max(),
966 'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
967 'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
968 'memory_actual': xeninfo.get_memory_static_min(),
969 'VCPUs_policy': xeninfo.get_vcpus_policy(),
970 'VCPUs_params': xeninfo.get_vcpus_params(),
971 'VCPUs_number': xeninfo.getVCpuCount(),
972 'VCPUs_utilisation': xeninfo.get_vcpus_util(),
973 'VCPUs_features_required': [],
974 'VCPUs_features_can_use': [],
975 'VCPUs_features_force_on': [],
976 'VCPUs_features_force_off': [],
977 'actions_after_shutdown': xeninfo.get_on_shutdown(),
978 'actions_after_reboot': xeninfo.get_on_reboot(),
979 'actions_after_suspend': xeninfo.get_on_suspend(),
980 'actions_after_crash': xeninfo.get_on_crash(),
981 'VIFs': xeninfo.get_vifs(),
982 'VBDs': xeninfo.get_vbds(),
983 'VTPMs': xeninfo.get_vtpms(),
984 'bios_boot': xeninfo.get_bios_boot(),
985 'platform_std_VGA': xeninfo.get_platform_std_vga(),
986 'platform_serial': xeninfo.get_platform_serial(),
987 'platform_localtime': xeninfo.get_platform_localtime(),
988 'platform_clock_offset': xeninfo.get_platform_clock_offset(),
989 'platform_enable_audio': xeninfo.get_platform_enable_audio(),
990 'platform_keymap': xeninfo.get_platform_keymap(),
991 'builder': xeninfo.get_builder(),
992 'boot_method': xeninfo.get_boot_method(),
993 'kernel_kernel': xeninfo.get_kernel_image(),
994 'kernel_initrd': xeninfo.get_kernel_initrd(),
995 'kernel_args': xeninfo.get_kernel_args(),
996 'grub_cmdline': xeninfo.get_grub_cmdline(),
997 'PCI_bus': xeninfo.get_pci_bus(),
998 'tools_version': xeninfo.get_tools_version(),
999 'otherConfig': xeninfo.get_other_config()
1001 return xen_api_success(record)
1003 def VM_clean_reboot(self, session, vm_ref):
1004 xendom = XendDomain.instance()
1005 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1006 xeninfo.shutdown("reboot")
1007 return xen_api_success_void()
1008 def VM_clean_shutdown(self, session, vm_ref):
1009 xendom = XendDomain.instance()
1010 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1011 xeninfo.shutdown("poweroff")
1012 return xen_api_success_void()
1013 def VM_clone(self, session, vm_ref):
1014 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1015 def VM_destroy(self, session, vm_ref):
1016 return do_vm_func("domain_delete", vm_ref)
1017 def VM_hard_reboot(self, session, vm_ref):
1018 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1019 def VM_hard_shutdown(self, session, vm_ref):
1020 return do_vm_func("domain_destroy", vm_ref)
1021 def VM_pause(self, session, vm_ref):
1022 return do_vm_func("domain_pause", vm_ref)
1023 def VM_resume(self, session, vm_ref, start_paused):
1024 return do_vm_func("domain_resume", vm_ref, start_paused = start_paused)
1025 def VM_start(self, session, vm_ref, start_paused):
1026 return do_vm_func("domain_start", vm_ref, start_paused = start_paused)
1027 def VM_suspend(self, session, vm_ref):
1028 return do_vm_func("domain_suspend", vm_ref)
1029 def VM_unpause(self, session, vm_ref):
1030 return do_vm_func("domain_unpause", vm_ref)
1032 # Xen API: Class VBD
1033 # ----------------------------------------------------------------
1034 # Note: accepts a non-API standard 'image' attribute to emulate
1035 # regular xm created VBDs
1037 VBD_attr_ro = ['image',
1038 'IO_bandwidth_incoming_kbs',
1039 'IO_bandwidth_outgoing_kbs']
1040 VBD_attr_rw = ['VM',
1041 'VDI',
1042 'device',
1043 'mode',
1044 'driver']
1046 VBD_attr_inst = VBD_attr_rw + ['image']
1048 VBD_methods = ['media_change']
1050 # object methods
1051 def VBD_get_record(self, session, vbd_ref):
1052 xendom = XendDomain.instance()
1053 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1054 if not vm:
1055 return xen_api_error(XEND_ERROR_VBD_INVALID)
1056 cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
1057 if not cfg:
1058 return xen_api_error(XEND_ERROR_VBD_INVALID)
1059 return xen_api_success(cfg)
1061 def VBD_media_change(self, session, vbd_ref, vdi_ref):
1062 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1064 # class methods
1065 def VBD_create(self, session, vbd_struct):
1066 xendom = XendDomain.instance()
1067 if not xendom.is_valid_vm(vbd_struct['VM']):
1068 return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
1070 dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
1071 vbd_ref = ''
1072 try:
1073 if not vbd_struct.get('VDI', None):
1074 # this is a traditional VBD without VDI and SR
1075 vbd_ref = dom.create_vbd(vbd_struct)
1076 else:
1077 # new VBD via VDI/SR
1078 vdi_ref = vbd_struct.get('VDI')
1079 sr = XendNode.instance().get_sr()
1080 vdi_image = sr.xen_api_get_by_uuid(vdi_ref)
1081 if not vdi_image:
1082 return xen_api_error(XEND_ERROR_VDI_INVALID)
1083 vdi_image = vdi_image.qcow_path
1084 vbd_ref = dom.create_vbd_with_vdi(vbd_struct, vdi_image)
1085 except XendError:
1086 return xen_api_todo()
1088 xendom.managed_config_save(dom)
1089 return xen_api_success(vbd_ref)
1091 # attributes (rw)
1092 def VBD_get_VM(self, session, vbd_ref):
1093 xendom = XendDomain.instance()
1094 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'VM'))
1096 def VBD_get_VDI(self, session, vbd_ref):
1097 return xen_api_todo()
1099 def VBD_get_device(self, session, vbd_ref):
1100 xendom = XendDomain.instance()
1101 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
1102 'device'))
1103 def VBD_get_mode(self, session, vbd_ref):
1104 xendom = XendDomain.instance()
1105 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
1106 'mode'))
1107 def VBD_get_driver(self, session, vbd_ref):
1108 xendom = XendDomain.instance()
1109 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
1110 'driver'))
1112 # Xen API: Class VIF
1113 # ----------------------------------------------------------------
1115 VIF_attr_ro = ['network_read_kbs',
1116 'network_write_kbs',
1117 'IO_bandwidth_incoming_kbs',
1118 'IO_bandwidth_outgoing_kbs']
1119 VIF_attr_rw = ['name',
1120 'type',
1121 'device',
1122 'network',
1123 'VM',
1124 'MAC',
1125 'MTU']
1127 VIF_attr_inst = VIF_attr_rw
1129 # object methods
1130 def VIF_get_record(self, session, vif_ref):
1131 xendom = XendDomain.instance()
1132 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1133 if not vm:
1134 return xen_api_error(XEND_ERROR_VIF_INVALID)
1135 cfg = vm.get_dev_xenapi_config('vif', vif_ref)
1136 if not cfg:
1137 return xen_api_error(XEND_ERROR_VIF_INVALID)
1138 valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
1139 self.Base_attr_ro + self.Base_attr_rw
1140 for k in cfg.keys():
1141 if k not in valid_vif_keys:
1142 del cfg[k]
1144 return xen_api_success(cfg)
1146 # class methods
1147 def VIF_create(self, session, vif_struct):
1148 xendom = XendDomain.instance()
1149 if xendom.is_valid_vm(vif_struct['VM']):
1150 dom = xendom.get_vm_by_uuid(vif_struct['VM'])
1151 try:
1152 vif_ref = dom.create_vif(vif_struct)
1153 xendom.managed_config_save(dom)
1154 return xen_api_success(vif_ref)
1155 except XendError:
1156 return xen_api_error(XEND_ERROR_TODO)
1157 else:
1158 return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
1161 # Xen API: Class VDI
1162 # ----------------------------------------------------------------
1163 VDI_attr_ro = ['VBDs',
1164 'physical_utilisation',
1165 'sector_size',
1166 'type',
1167 'parent',
1168 'children']
1169 VDI_attr_rw = ['name_label',
1170 'name_description',
1171 'SR',
1172 'virtual_size',
1173 'sharable',
1174 'read_only']
1175 VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
1177 VDI_methods = ['snapshot']
1178 VDI_funcs = ['get_by_name_label']
1180 def VDI_get_VBDs(self, session, vdi_ref):
1181 return xen_api_todo()
1183 def VDI_get_physical_utilisation(self, session, vdi_ref):
1184 sr = XendNode.instance().get_sr()
1185 image = sr.xen_api_get_by_uuid(vdi_ref)
1186 return xen_api_success(image.get_physical_utilisation())
1188 def VDI_get_sector_size(self, session, vdi_ref):
1189 sr = XendNode.instance().get_sr()
1190 image = sr.xen_api_get_by_uuid(vdi_ref)
1191 return xen_api_success(image.sector_size)
1193 def VDI_get_type(self, session, vdi_ref):
1194 sr = XendNode.instance().get_sr()
1195 image = sr.xen_api_get_by_uuid(vdi_ref)
1196 return xen_api_success(image.type)
1198 def VDI_get_parent(self, session, vdi_ref):
1199 sr = XendNode.instance().get_sr()
1200 image = sr.xen_api_get_by_uuid(vdi_ref)
1201 return xen_api_success(image.parent)
1203 def VDI_get_children(self, session, vdi_ref):
1204 sr = XendNode.instance().get_sr()
1205 image = sr.xen_api_get_by_uuid(vdi_ref)
1206 return xen_api_success(image.children)
1208 def VDI_get_name_label(self, session, vdi_ref):
1209 sr = XendNode.instance().get_sr()
1210 image = sr.xen_api_get_by_uuid(vdi_ref)
1211 return xen_api_success(image.name_label)
1213 def VDI_get_name_description(self, session, vdi_ref):
1214 sr = XendNode.instance().get_sr()
1215 image = sr.xen_api_get_by_uuid(vdi_ref)
1216 return xen_api_success(image.name_description)
1218 def VDI_get_SR(self, session, vdi_ref):
1219 sr = XendNode.instance().get_sr()
1220 return xen_api_success(sr.uuid)
1222 def VDI_get_virtual_size(self, session, vdi_ref):
1223 sr = XendNode.instance().get_sr()
1224 image = sr.xen_api_get_by_uuid(vdi_ref)
1225 return xen_api_success(image.virtual_size)
1227 def VDI_get_sharable(self, session, vdi_ref):
1228 sr = XendNode.instance().get_sr()
1229 image = sr.xen_api_get_by_uuid(vdi_ref)
1230 return xen_api_success(image.sharable)
1232 def VDI_get_read_only(self, session, vdi_ref):
1233 sr = XendNode.instance().get_sr()
1234 image = sr.xen_api_get_by_uuid(vdi_ref)
1235 return xen_api_success(image.sharable)
1237 def VDI_set_name_label(self, session, vdi_ref, value):
1238 sr = XendNode.instance().get_sr()
1239 image = sr.xen_api_get_by_uuid(vdi_ref)
1240 image.name_label = value
1241 return xen_api_success_void()
1243 def VDI_set_name_description(self, session, vdi_ref, value):
1244 sr = XendNode.instance().get_sr()
1245 image = sr.xen_api_get_by_uuid(vdi_ref)
1246 image.name_description = value
1247 return xen_api_success_void()
1249 def VDI_set_SR(self, session, vdi_ref, value):
1250 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1252 def VDI_set_virtual_size(self, session, vdi_ref, value):
1253 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1255 def VDI_set_sharable(self, session, vdi_ref, value):
1256 return xen_api_todo()
1257 def VDI_set_read_only(self, session, vdi_ref, value):
1258 return xen_api_todo()
1260 # Object Methods
1261 def VDI_snapshot(self, session, vdi_ref):
1262 return xen_api_todo()
1264 def VDI_destroy(self, session, vdi_ref):
1265 sr = XendNode.instance().get_sr()
1266 sr.destroy_image(vdi_ref)
1267 return xen_api_success_void()
1269 def VDI_get_record(self, session, vdi_ref):
1270 sr = XendNode.instance().get_sr()
1271 image = sr.xen_api_get_by_uuid(vdi_ref)
1272 if image:
1273 return xen_api_success({
1274 'uuid': vdi_ref,
1275 'name_label': image.name_label,
1276 'name_description': image.name_description,
1277 'SR': sr.uuid,
1278 'VBDs': [], # TODO
1279 'virtual_size': image.virtual_size,
1280 'physical_utilisation': image.physical_utilisation,
1281 'sector_size': image.sector_size,
1282 'type': image.type,
1283 'parent': image.parent,
1284 'children': image.children,
1285 'sharable': image.sharable,
1286 'read_only': image.read_only,
1287 })
1289 return xen_api_error(XEND_ERROR_VDI_INVALID)
1291 # Class Functions
1292 def VDI_create(self, session, vdi_struct):
1293 sr = XendNode.instance().get_sr()
1294 sr_ref = vdi_struct['SR']
1295 if sr.uuid != sr_ref:
1296 return xen_api_error(XEND_ERROR_SR_INVALID)
1298 vdi_uuid = sr.create_image(vdi_struct)
1299 return xen_api_success(vdi_uuid)
1301 def VDI_get_all(self, session):
1302 sr = XendNode.instance().get_sr()
1303 return xen_api_success(sr.list_images())
1305 def VDI_get_by_name_label(self, session, name):
1306 sr = XendNode.instance().get_sr()
1307 image_uuid = sr.xen_api_get_by_name_label(name)
1308 if image_uuid:
1309 return xen_api_success(image_uuid)
1311 return xen_api_error(XEND_ERROR_VDI_INVALID)
1314 # Xen API: Class VTPM
1315 # ----------------------------------------------------------------
1317 VTPM_attr_rw = [ ]
1318 VTPM_attr_ro = ['VM',
1319 'backend',
1320 'instance',
1321 'driver']
1323 VTPM_attr_inst = VTPM_attr_rw
1325 # object methods
1326 def VTPM_get_record(self, session, vtpm_ref):
1327 xendom = XendDomain.instance()
1328 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1329 if not vm:
1330 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1331 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1332 if not cfg:
1333 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1334 valid_vtpm_keys = self.VTPM_attr_ro + self.VTPM_attr_rw + \
1335 self.Base_attr_ro + self.Base_attr_rw
1336 for k in cfg.keys():
1337 if k not in valid_vtpm_keys:
1338 del cfg[k]
1340 return xen_api_success(cfg)
1342 # Class Functions
1343 def VTPM_get_instance(self, session, vtpm_ref):
1344 xendom = XendDomain.instance()
1345 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1346 if not vm:
1347 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1348 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1349 if not cfg:
1350 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1351 if cfg.has_key('instance'):
1352 instance = cfg['instance']
1353 else:
1354 instance = -1
1355 return xen_api_success(instance)
1357 def VTPM_get_driver(self, session, vtpm_ref):
1358 xendom = XendDomain.instance()
1359 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1360 if not vm:
1361 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1362 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1363 if not cfg:
1364 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1365 if cfg.has_key('type'):
1366 driver = cfg['type']
1367 else:
1368 driver = "Unknown"
1369 return xen_api_success(driver)
1371 def VTPM_get_backend(self, session, vtpm_ref):
1372 xendom = XendDomain.instance()
1373 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1374 if not vm:
1375 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1376 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1377 if not cfg:
1378 return xen_api_error(XEND_ERROR_VTPM_INVALID)
1379 if cfg.has_key('backend'):
1380 backend = cfg['backend']
1381 else:
1382 backend = "Domain-0"
1383 return xen_api_success(backend)
1385 def VTPM_get_VM(self, session, vtpm_ref):
1386 xendom = XendDomain.instance()
1387 return xen_api_success(xendom.get_dev_property('vtpm', vtpm_ref, 'VM'))
1389 # class methods
1390 def VTPM_create(self, session, vtpm_struct):
1391 xendom = XendDomain.instance()
1392 if xendom.is_valid_vm(vtpm_struct['VM']):
1393 dom = xendom.get_vm_by_uuid(vtpm_struct['VM'])
1394 try:
1395 vtpm_ref = dom.create_vtpm(vtpm_struct)
1396 xendom.managed_config_save(dom)
1397 return xen_api_success(vtpm_ref)
1398 except XendError:
1399 return xen_api_error(XEND_ERROR_TODO)
1400 else:
1401 return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
1404 # Xen API: Class SR
1405 # ----------------------------------------------------------------
1406 SR_attr_ro = ['VDIs',
1407 'virtual_allocation',
1408 'physical_utilisation',
1409 'physical_size',
1410 'type',
1411 'location']
1413 SR_attr_rw = ['name_label',
1414 'name_description']
1416 SR_attr_inst = ['physical_size',
1417 'type',
1418 'location',
1419 'name_label',
1420 'name_description']
1422 SR_methods = ['clone']
1423 SR_funcs = ['get_by_name_label']
1425 # Class Functions
1426 def SR_get_all(self, session):
1427 sr = XendNode.instance().get_sr()
1428 return xen_api_success([sr.uuid])
1430 def SR_get_by_name_label(self, session, label):
1431 sr = XendNode.instance().get_sr()
1432 if sr.name_label != label:
1433 return xen_api_error(XEND_ERROR_SR_INVALID)
1434 return xen_api_success([sr.uuid])
1436 def SR_create(self, session):
1437 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1439 def SR_get_by_uuid(self, session):
1440 return xen_api_success(XendNode.instance().get_sr().uuid)
1442 # Class Methods
1443 def SR_clone(self, session, sr_ref):
1444 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1446 def SR_destroy(self, session, sr_ref):
1447 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1449 def SR_get_record(self, session, sr_ref):
1450 sr = XendNode.instance().get_sr()
1451 return xen_api_success({
1452 'uuid': sr.uuid,
1453 'name_label': sr.name_label,
1454 'name_description': sr.name_description,
1455 'VDIs': sr.list_images(),
1456 'virtual_allocation': sr.used_space_bytes(),
1457 'physical_utilisation': sr.used_space_bytes(),
1458 'physical_size': sr.total_space_bytes(),
1459 'type': sr.type,
1460 'location': sr.location
1461 })
1463 # Attribute acceess
1464 def SR_get_VDIs(self, session, sr_ref):
1465 sr = XendNode.instance().get_sr()
1466 return xen_api_success(sr.list_images())
1468 def SR_get_virtual_allocation(self, session, sr_ref):
1469 sr = XendNode.instance().get_sr()
1470 return sr.used_space_bytes()
1472 def SR_get_physical_utilisation(self, session, sr_ref):
1473 sr = XendNode.instance().get_sr()
1474 return sr.used_space_bytes()
1476 def SR_get_physical_size(self, session, sr_ref):
1477 sr = XendNode.instance().get_sr()
1478 return sr.total_space_bytes()
1480 def SR_get_type(self, session, sr_ref):
1481 sr = XendNode.instance().get_sr()
1482 return xen_api_success(sr.type)
1484 def SR_get_location(self, session, sr_ref):
1485 sr = XendNode.instance().get_sr()
1486 return xen_api_success(sr.location)
1488 def SR_get_name_label(self, session, sr_ref):
1489 sr = XendNode.instance().get_sr()
1490 return xen_api_success(sr.name_label)
1492 def SR_get_name_description(self, session, sr_ref):
1493 sr = XendNode.instance().get_sr()
1494 return xen_api_success(sr.name_description)
1496 def SR_set_name_label(self, session, sr_ref, value):
1497 sr = XendNode.instance().get_sr()
1498 sr.name_label = value
1499 return xen_api_success_void()
1501 def SR_set_name_description(self, session, sr_ref, value):
1502 sr = XendNode.instance().get_sr()
1503 sr.name_description = value
1504 return xen_api_success_void()
1507 # Auto generate some stubs based on XendAPI introspection
1509 if __name__ == "__main__":
1510 def output(line):
1511 print ' ' + line
1513 classes = ['VDI', 'SR']
1514 for cls in classes:
1515 ro_attrs = getattr(XendAPI, '%s_attr_ro' % cls, [])
1516 rw_attrs = getattr(XendAPI, '%s_attr_rw' % cls, [])
1517 methods = getattr(XendAPI, '%s_methods' % cls, [])
1518 funcs = getattr(XendAPI, '%s_funcs' % cls, [])
1520 ref = '%s_ref' % cls
1522 for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
1523 getter_name = '%s_get_%s' % (cls, attr_name)
1524 output('def %s(self, session, %s):' % (getter_name, ref))
1525 output(' return xen_api_todo()')
1527 for attr_name in rw_attrs + XendAPI.Base_attr_rw:
1528 setter_name = '%s_set_%s' % (cls, attr_name)
1529 output('def %s(self, session, %s, value):' % (setter_name, ref))
1530 output(' return xen_api_todo()')
1532 for method_name in methods + XendAPI.Base_methods:
1533 method_full_name = '%s_%s' % (cls,method_name)
1534 output('def %s(self, session, %s):' % (method_full_name, ref))
1535 output(' return xen_api_todo()')
1537 for func_name in funcs + XendAPI.Base_funcs:
1538 func_full_name = '%s_%s' % (cls, func_name)
1539 output('def %s(self, session):' % func_full_name)
1540 output(' return xen_api_todo()')