direct-io.hg

view tools/python/xen/xend/XendAPI.py @ 14109:d81c0b55e248

Fix typo in host record.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Sun Feb 25 21:53:39 2007 +0000 (2007-02-25)
parents 02f32a4df8db
children 532a25342a30
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-2007 XenSource Ltd.
16 #============================================================================
18 import inspect
19 import os
20 import string
21 import sys
22 import traceback
23 import threading
25 from xen.xend import XendDomain, XendDomainInfo, XendNode, XendDmesg
26 from xen.xend import XendLogging, XendTaskManager
28 from xen.xend.XendAPIVersion import *
29 from xen.xend.XendAuthSessions import instance as auth_manager
30 from xen.xend.XendError import *
31 from xen.xend.XendClient import ERROR_INVALID_DOMAIN
32 from xen.xend.XendLogging import log
33 from xen.xend.XendTask import XendTask
35 from xen.xend.XendAPIConstants import *
36 from xen.util.xmlrpclib2 import stringify
38 AUTH_NONE = 'none'
39 AUTH_PAM = 'pam'
41 argcounts = {}
43 # ------------------------------------------
44 # Utility Methods for Xen API Implementation
45 # ------------------------------------------
47 def xen_api_success(value):
48 """Wraps a return value in XenAPI format."""
49 if value is None:
50 s = ''
51 else:
52 s = stringify(value)
53 return {"Status": "Success", "Value": s}
55 def xen_api_success_void():
56 """Return success, but caller expects no return value."""
57 return xen_api_success("")
59 def xen_api_error(error):
60 """Wraps an error value in XenAPI format."""
61 if type(error) == tuple:
62 error = list(error)
63 if type(error) != list:
64 error = [error]
65 if len(error) == 0:
66 error = ['INTERNAL_ERROR', 'Empty list given to xen_api_error']
68 return { "Status": "Failure",
69 "ErrorDescription": [str(x) for x in error] }
72 def xen_api_todo():
73 """Temporary method to make sure we track down all the TODOs"""
74 return {"Status": "Error", "ErrorDescription": XEND_ERROR_TODO}
76 # ---------------------------------------------------
77 # Python Method Decorators for input value validation
78 # ---------------------------------------------------
80 def trace(func, api_name = ''):
81 """Decorator to trace XMLRPC Xen API methods.
83 @param func: function with any parameters
84 @param api_name: name of the api call for debugging.
85 """
86 if hasattr(func, 'api'):
87 api_name = func.api
88 def trace_func(self, *args, **kwargs):
89 log.debug('%s: %s' % (api_name, args))
90 return func(self, *args, **kwargs)
91 trace_func.api = api_name
92 return trace_func
95 def catch_typeerror(func):
96 """Decorator to catch any TypeErrors and translate them into Xen-API
97 errors.
99 @param func: function with params: (self, ...)
100 @rtype: callable object
101 """
102 def f(self, *args, **kwargs):
103 try:
104 return func(self, *args, **kwargs)
105 except TypeError, exn:
106 #log.exception('catch_typeerror')
107 if hasattr(func, 'api') and func.api in argcounts:
108 # Assume that if the argument count was wrong and if the
109 # exception was thrown inside this file, then it is due to an
110 # invalid call from the client, otherwise it's an internal
111 # error (which will be handled further up).
112 expected = argcounts[func.api]
113 actual = len(args) + len(kwargs)
114 if expected != actual:
115 tb = sys.exc_info()[2]
116 try:
117 sourcefile = traceback.extract_tb(tb)[-1][0]
118 if sourcefile == inspect.getsourcefile(XendAPI):
119 return xen_api_error(
120 ['MESSAGE_PARAMETER_COUNT_MISMATCH',
121 func.api, expected, actual])
122 finally:
123 del tb
124 raise
126 return f
129 def session_required(func):
130 """Decorator to verify if session is valid before calling method.
132 @param func: function with params: (self, session, ...)
133 @rtype: callable object
134 """
135 def check_session(self, session, *args, **kwargs):
136 if auth_manager().is_session_valid(session):
137 return func(self, session, *args, **kwargs)
138 else:
139 return xen_api_error(['SESSION_INVALID', session])
141 return check_session
144 def _is_valid_ref(ref, validator):
145 return type(ref) == str and validator(ref)
147 def _check_ref(validator, clas, func, api, session, ref, *args, **kwargs):
148 if _is_valid_ref(ref, validator):
149 return func(api, session, ref, *args, **kwargs)
150 else:
151 return xen_api_error(['HANDLE_INVALID', clas, ref])
154 def valid_host(func):
155 """Decorator to verify if host_ref is valid before calling method.
157 @param func: function with params: (self, session, host_ref, ...)
158 @rtype: callable object
159 """
160 return lambda *args, **kwargs: \
161 _check_ref(XendNode.instance().is_valid_host,
162 'host', func, *args, **kwargs)
164 def valid_host_metrics(func):
165 """Decorator to verify if host_metrics_ref is valid before calling
166 method.
168 @param func: function with params: (self, session, host_metrics_ref)
169 @rtype: callable object
170 """
171 return lambda *args, **kwargs: \
172 _check_ref(lambda r: r == XendNode.instance().host_metrics_uuid,
173 'host_metrics', func, *args, **kwargs)
175 def valid_host_cpu(func):
176 """Decorator to verify if host_cpu_ref is valid before calling method.
178 @param func: function with params: (self, session, host_cpu_ref, ...)
179 @rtype: callable object
180 """
181 return lambda *args, **kwargs: \
182 _check_ref(XendNode.instance().is_valid_cpu,
183 'host_cpu', func, *args, **kwargs)
185 def valid_vm(func):
186 """Decorator to verify if vm_ref is valid before calling method.
188 @param func: function with params: (self, session, vm_ref, ...)
189 @rtype: callable object
190 """
191 return lambda *args, **kwargs: \
192 _check_ref(XendDomain.instance().is_valid_vm,
193 'VM', func, *args, **kwargs)
195 def valid_network(func):
196 """Decorator to verify if network_ref is valid before calling method.
198 @param func: function with params: (self, session, network_ref, ...)
199 @rtype: callable object
200 """
201 return lambda *args, **kwargs: \
202 _check_ref(XendNode.instance().is_valid_network,
203 'network', func, *args, **kwargs)
205 def valid_vbd(func):
206 """Decorator to verify if vbd_ref is valid before calling method.
208 @param func: function with params: (self, session, vbd_ref, ...)
209 @rtype: callable object
210 """
211 return lambda *args, **kwargs: \
212 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vbd', r),
213 'VBD', func, *args, **kwargs)
215 def valid_vbd_metrics(func):
216 """Decorator to verify if ref is valid before calling method.
218 @param func: function with params: (self, session, ref, ...)
219 @rtype: callable object
220 """
221 return lambda *args, **kwargs: \
222 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vbd', r),
223 'VBD_metrics', func, *args, **kwargs)
225 def valid_vif(func):
226 """Decorator to verify if vif_ref is valid before calling method.
228 @param func: function with params: (self, session, vif_ref, ...)
229 @rtype: callable object
230 """
231 return lambda *args, **kwargs: \
232 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vif', r),
233 'VIF', func, *args, **kwargs)
235 def valid_vif_metrics(func):
236 """Decorator to verify if ref is valid before calling method.
238 @param func: function with params: (self, session, ref, ...)
239 @rtype: callable object
240 """
241 return lambda *args, **kwargs: \
242 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vif', r),
243 'VIF_metrics', func, *args, **kwargs)
245 def valid_vdi(func):
246 """Decorator to verify if vdi_ref is valid before calling method.
248 @param func: function with params: (self, session, vdi_ref, ...)
249 @rtype: callable object
250 """
251 return lambda *args, **kwargs: \
252 _check_ref(XendNode.instance().is_valid_vdi,
253 'VDI', func, *args, **kwargs)
255 def valid_vtpm(func):
256 """Decorator to verify if vtpm_ref is valid before calling method.
258 @param func: function with params: (self, session, vtpm_ref, ...)
259 @rtype: callable object
260 """
261 return lambda *args, **kwargs: \
262 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vtpm', r),
263 'VTPM', func, *args, **kwargs)
266 def valid_console(func):
267 """Decorator to verify if console_ref is valid before calling method.
269 @param func: function with params: (self, session, console_ref, ...)
270 @rtype: callable object
271 """
272 return lambda *args, **kwargs: \
273 _check_ref(lambda r: XendDomain.instance().is_valid_dev('console',
274 r),
275 'console', func, *args, **kwargs)
277 def valid_sr(func):
278 """Decorator to verify if sr_ref is valid before calling method.
280 @param func: function with params: (self, session, sr_ref, ...)
281 @rtype: callable object
282 """
283 return lambda *args, **kwargs: \
284 _check_ref(lambda r: XendNode.instance().is_valid_sr,
285 'SR', func, *args, **kwargs)
287 def valid_pif(func):
288 """Decorator to verify if pif_ref is valid before calling
289 method.
291 @param func: function with params: (self, session, pif_ref)
292 @rtype: callable object
293 """
294 return lambda *args, **kwargs: \
295 _check_ref(lambda r: r in XendNode.instance().pifs,
296 'PIF', func, *args, **kwargs)
298 def valid_pif_metrics(func):
299 """Decorator to verify if pif_metrics_ref is valid before calling
300 method.
302 @param func: function with params: (self, session, pif_metrics_ref)
303 @rtype: callable object
304 """
305 return lambda *args, **kwargs: \
306 _check_ref(lambda r: r in XendNode.instance().pif_metrics,
307 'PIF_metrics', func, *args, **kwargs)
309 def valid_task(func):
310 """Decorator to verify if task_ref is valid before calling
311 method.
313 @param func: function with params: (self, session, task_ref)
314 @rtype: callable object
315 """
316 return lambda *args, **kwargs: \
317 _check_ref(XendTaskManager.get_task,
318 'task', func, *args, **kwargs)
320 def valid_debug(func):
321 """Decorator to verify if task_ref is valid before calling
322 method.
324 @param func: function with params: (self, session, task_ref)
325 @rtype: callable object
326 """
327 return lambda *args, **kwargs: \
328 _check_ref(lambda r: r in XendAPI._debug,
329 'debug', func, *args, **kwargs)
331 # -----------------------------
332 # Bridge to Legacy XM API calls
333 # -----------------------------
335 def do_vm_func(fn_name, vm_ref, *args, **kwargs):
336 """Helper wrapper func to abstract away from repetitive code.
338 @param fn_name: function name for XendDomain instance
339 @type fn_name: string
340 @param vm_ref: vm_ref
341 @type vm_ref: string
342 @param *args: more arguments
343 @type *args: tuple
344 """
345 try:
346 xendom = XendDomain.instance()
347 fn = getattr(xendom, fn_name)
348 xendom.do_legacy_api_with_uuid(fn, vm_ref, *args, **kwargs)
349 return xen_api_success_void()
350 except VMBadState, exn:
351 return xen_api_error(['VM_BAD_POWER_STATE', vm_ref, exn.expected,
352 exn.actual])
355 class XendAPI(object):
356 """Implementation of the Xen-API in Xend. Expects to be
357 used via XMLRPCServer.
359 All methods that need a valid session are marked with
360 a L{session_required} decorator that will
361 transparently perform the required session authentication.
363 We need to support Python <2.4, so we use the old decorator syntax.
365 All XMLRPC accessible methods require an 'api' attribute and
366 is set to the XMLRPC function name which the method implements.
367 """
369 __decorated__ = False
370 __init_lock__ = threading.Lock()
371 _debug = {}
373 def __new__(cls, *args, **kwds):
374 """ Override __new__ to decorate the class only once.
376 Lock to make sure the classes are not decorated twice.
377 """
378 cls.__init_lock__.acquire()
379 try:
380 if not cls.__decorated__:
381 cls._decorate()
382 cls.__decorated__ = True
384 return object.__new__(cls, *args, **kwds)
385 finally:
386 cls.__init_lock__.release()
388 def _decorate(cls):
389 """ Decorate all the object methods to have validators
390 and appropriate function attributes.
392 This should only be executed once for the duration of the
393 server.
394 """
395 global_validators = [session_required, catch_typeerror]
396 classes = {
397 'session' : None,
398 'host' : valid_host,
399 'host_cpu' : valid_host_cpu,
400 'host_metrics' : valid_host_metrics,
401 'network' : valid_network,
402 'VM' : valid_vm,
403 'VBD' : valid_vbd,
404 'VBD_metrics' : valid_vbd_metrics,
405 'VIF' : valid_vif,
406 'VIF_metrics' : valid_vif_metrics,
407 'VDI' : valid_vdi,
408 'VTPM' : valid_vtpm,
409 'console' : valid_console,
410 'SR' : valid_sr,
411 'PIF' : valid_pif,
412 'PIF_metrics' : valid_pif_metrics,
413 'task' : valid_task,
414 'debug' : valid_debug,
415 }
417 # Cheat methods
418 # -------------
419 # Methods that have a trivial implementation for all classes.
420 # 1. get_by_uuid == getting by ref, so just return uuid for
421 # all get_by_uuid() methods.
423 for api_cls in classes.keys():
424 if api_cls == 'session':
425 continue
427 get_by_uuid = '%s_get_by_uuid' % api_cls
428 get_uuid = '%s_get_uuid' % api_cls
429 def _get_by_uuid(_1, _2, ref):
430 return xen_api_success(ref)
432 def _get_uuid(_1, _2, ref):
433 return xen_api_success(ref)
435 setattr(cls, get_by_uuid, _get_by_uuid)
436 setattr(cls, get_uuid, _get_uuid)
438 # Wrapping validators around XMLRPC calls
439 # ---------------------------------------
441 for api_cls, validator in classes.items():
442 def doit(n, takes_instance, async_support = False,
443 return_type = None):
444 n_ = n.replace('.', '_')
445 try:
446 f = getattr(cls, n_)
447 argcounts[n] = f.func_code.co_argcount - 1
449 validators = takes_instance and validator and \
450 [validator] or []
452 validators += global_validators
453 for v in validators:
454 f = v(f)
455 f.api = n
456 f.async = async_support
457 if return_type:
458 f.return_type = return_type
460 setattr(cls, n_, f)
461 except AttributeError:
462 log.warn("API call: %s not found" % n)
465 ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
466 rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
467 methods = getattr(cls, '%s_methods' % api_cls, [])
468 funcs = getattr(cls, '%s_funcs' % api_cls, [])
470 # wrap validators around readable class attributes
471 for attr_name in ro_attrs + rw_attrs + cls.Base_attr_ro:
472 doit('%s.get_%s' % (api_cls, attr_name), True,
473 async_support = False)
475 # wrap validators around writable class attrributes
476 for attr_name in rw_attrs + cls.Base_attr_rw:
477 doit('%s.set_%s' % (api_cls, attr_name), True,
478 async_support = False)
480 # wrap validators around methods
481 for method_name, return_type in methods + cls.Base_methods:
482 doit('%s.%s' % (api_cls, method_name), True,
483 async_support = True)
485 # wrap validators around class functions
486 for func_name, return_type in funcs + cls.Base_funcs:
487 doit('%s.%s' % (api_cls, func_name), False, async_support = True,
488 return_type = return_type)
490 _decorate = classmethod(_decorate)
492 def __init__(self, auth):
493 self.auth = auth
495 Base_attr_ro = ['uuid']
496 Base_attr_rw = []
497 Base_methods = [('destroy', None), ('get_record', 'Struct')]
498 Base_funcs = [('get_all', 'Set'), ('get_by_uuid', None)]
500 # Xen API: Class Session
501 # ----------------------------------------------------------------
502 # NOTE: Left unwrapped by __init__
504 session_attr_ro = ['this_host', 'this_user']
505 session_methods = [('logout', None)]
507 def session_login_with_password(self, *args):
508 if len(args) != 2:
509 return xen_api_error(
510 ['MESSAGE_PARAMETER_COUNT_MISMATCH',
511 'session.login_with_password', 2, len(args)])
512 username = args[0]
513 password = args[1]
514 try:
515 session = (self.auth == AUTH_NONE and
516 auth_manager().login_unconditionally(username) or
517 auth_manager().login_with_password(username, password))
518 return xen_api_success(session)
519 except XendError, e:
520 return xen_api_error(['SESSION_AUTHENTICATION_FAILED'])
521 session_login_with_password.api = 'session.login_with_password'
523 # object methods
524 def session_logout(self, session):
525 auth_manager().logout(session)
526 return xen_api_success_void()
527 def session_get_record(self, session):
528 record = {'uuid' : session,
529 'this_host': XendNode.instance().uuid,
530 'this_user': auth_manager().get_user(session)}
531 return xen_api_success(record)
533 def session_get_uuid(self, session):
534 return xen_api_success(session)
536 def session_get_by_uuid(self, session):
537 return xen_api_success(session)
539 # attributes (ro)
540 def session_get_this_host(self, session):
541 return xen_api_success(XendNode.instance().uuid)
542 def session_get_this_user(self, session):
543 user = auth_manager().get_user(session)
544 if user:
545 return xen_api_success(user)
546 return xen_api_error(['SESSION_INVALID', session])
549 # Xen API: Class User
550 # ----------------------------------------------------------------
551 # TODO: NOT IMPLEMENTED YET
553 # Xen API: Class Tasks
554 # ----------------------------------------------------------------
556 task_attr_ro = ['name_label',
557 'name_description',
558 'status',
559 'progress',
560 'type',
561 'result',
562 'error_code',
563 'error_info',
564 'allowed_operations',
565 'session'
566 ]
568 task_attr_rw = []
570 task_funcs = [('get_by_name_label', 'Set(task)'),
571 ('cancel', None)]
573 def task_get_name_label(self, session, task_ref):
574 task = XendTaskManager.get_task(task_ref)
575 return xen_api_success(task.name_label)
577 def task_get_name_description(self, session, task_ref):
578 task = XendTaskManager.get_task(task_ref)
579 return xen_api_success(task.name_description)
581 def task_get_status(self, session, task_ref):
582 task = XendTaskManager.get_task(task_ref)
583 return xen_api_success(task.get_status())
585 def task_get_progress(self, session, task_ref):
586 task = XendTaskManager.get_task(task_ref)
587 return xen_api_success(task.progress)
589 def task_get_type(self, session, task_ref):
590 task = XendTaskManager.get_task(task_ref)
591 return xen_api_success(task.type)
593 def task_get_result(self, session, task_ref):
594 task = XendTaskManager.get_task(task_ref)
595 return xen_api_success(task.result)
597 def task_get_error_code(self, session, task_ref):
598 task = XendTaskManager.get_task(task_ref)
599 return xen_api_success(task.error_code)
601 def task_get_error_info(self, session, task_ref):
602 task = XendTaskManager.get_task(task_ref)
603 return xen_api_success(task.error_info)
605 def task_get_allowed_operations(self, session, task_ref):
606 return xen_api_success({})
608 def task_get_session(self, session, task_ref):
609 task = XendTaskManager.get_task(task_ref)
610 return xen_api_success(task.session)
612 def task_get_all(self, session):
613 tasks = XendTaskManager.get_all_tasks()
614 return xen_api_success(tasks)
616 def task_get_record(self, session, task_ref):
617 task = XendTaskManager.get_task(task_ref)
618 return xen_api_success(task.get_record())
620 def task_cancel(self, session, task_ref):
621 return xen_api_error('OPERATION_NOT_ALLOWED')
623 def task_get_by_name_label(self, session, name):
624 return xen_api_success(XendTaskManager.get_task_by_name(name))
626 # Xen API: Class host
627 # ----------------------------------------------------------------
629 host_attr_ro = ['software_version',
630 'resident_VMs',
631 'host_CPUs',
632 'metrics',
633 'supported_bootloaders',
634 'API_version_major',
635 'API_version_minor',
636 'API_version_vendor',
637 'API_version_vendor_implementation']
639 host_attr_rw = ['name_label',
640 'name_description',
641 'other_config']
643 host_methods = [('disable', None),
644 ('enable', None),
645 ('reboot', None),
646 ('shutdown', None),
647 ('add_to_other_config', None),
648 ('remove_from_other_config', None),
649 ('dmesg', 'String')]
651 host_funcs = [('get_by_name_label', 'Set(host)')]
653 # attributes
654 def host_get_name_label(self, session, host_ref):
655 return xen_api_success(XendNode.instance().name)
656 def host_set_name_label(self, session, host_ref, new_name):
657 XendNode.instance().set_name(new_name)
658 return xen_api_success_void()
659 def host_get_name_description(self, session, host_ref):
660 return xen_api_success(XendNode.instance().description)
661 def host_set_name_description(self, session, host_ref, new_desc):
662 XendNode.instance().set_description(new_desc)
663 return xen_api_success_void()
664 def host_get_other_config(self, session, host_ref):
665 return xen_api_success(XendNode.instance().other_config)
666 def host_set_other_config(self, session, host_ref, other_config):
667 node = XendNode.instance()
668 node.other_config = dict(other_config)
669 node.save()
670 return xen_api_success_void()
671 def host_add_to_other_config(self, session, host_ref, key, value):
672 node = XendNode.instance()
673 node.other_config[key] = value
674 node.save()
675 return xen_api_success_void()
676 def host_remove_from_other_config(self, session, host_ref, key):
677 node = XendNode.instance()
678 del node.other_config[key]
679 node.save()
680 return xen_api_success_void()
681 def host_get_API_version_major(self, _, ref):
682 return xen_api_success(XEN_API_VERSION_MAJOR)
683 def host_get_API_version_minor(self, _, ref):
684 return xen_api_success(XEN_API_VERSION_MINOR)
685 def host_get_API_version_vendor(self, _, ref):
686 return xen_api_success(XEN_API_VERSION_VENDOR)
687 def host_get_API_version_vendor_implementation(self, _, ref):
688 return xen_api_success(XEN_API_VERSION_VENDOR_IMPLEMENTATION)
689 def host_get_software_version(self, session, host_ref):
690 return xen_api_success(XendNode.instance().xen_version())
691 def host_get_resident_VMs(self, session, host_ref):
692 return xen_api_success(XendDomain.instance().get_domain_refs())
693 def host_get_host_CPUs(self, session, host_ref):
694 return xen_api_success(XendNode.instance().get_host_cpu_refs())
695 def host_get_metrics(self, _, ref):
696 return xen_api_success(XendNode.instance().host_metrics_uuid)
697 def host_get_supported_bootloaders(self, session, host_ref):
698 return xen_api_success(['pygrub'])
700 # object methods
701 def host_disable(self, session, host_ref):
702 XendDomain.instance().set_allow_new_domains(False)
703 return xen_api_success_void()
704 def host_enable(self, session, host_ref):
705 XendDomain.instance().set_allow_new_domains(True)
706 return xen_api_success_void()
707 def host_reboot(self, session, host_ref):
708 if not XendDomain.instance().allow_new_domains():
709 return xen_api_error(XEND_ERROR_HOST_RUNNING)
710 return xen_api_error(XEND_ERROR_UNSUPPORTED)
711 def host_shutdown(self, session, host_ref):
712 if not XendDomain.instance().allow_new_domains():
713 return xen_api_error(XEND_ERROR_HOST_RUNNING)
714 return xen_api_error(XEND_ERROR_UNSUPPORTED)
716 def host_dmesg(self, session, host_ref):
717 return xen_api_success(XendDmesg.instance().info())
719 def host_get_record(self, session, host_ref):
720 node = XendNode.instance()
721 dom = XendDomain.instance()
722 record = {'uuid': node.uuid,
723 'name_label': node.name,
724 'name_description': '',
725 'API_version_major': XEN_API_VERSION_MAJOR,
726 'API_version_minor': XEN_API_VERSION_MINOR,
727 'API_version_vendor': XEN_API_VERSION_VENDOR,
728 'API_version_vendor_implementation':
729 XEN_API_VERSION_VENDOR_IMPLEMENTATION,
730 'software_version': node.xen_version(),
731 'other_config': node.other_config,
732 'resident_VMs': dom.get_domain_refs(),
733 'host_CPUs': node.get_host_cpu_refs(),
734 'metrics': node.host_metrics_uuid,
735 'supported_bootloaders': 'pygrub'}
736 return xen_api_success(record)
738 # class methods
739 def host_get_all(self, session):
740 return xen_api_success((XendNode.instance().uuid,))
741 def host_get_by_name_label(self, session, name):
742 if XendNode.instance().name == name:
743 return xen_api_success((XendNode.instance().uuid,))
744 return xen_api_success([])
747 # Xen API: Class host_CPU
748 # ----------------------------------------------------------------
750 host_cpu_attr_ro = ['host',
751 'number',
752 'utilisation']
754 # attributes
755 def host_cpu_get_host(self, session, host_cpu_ref):
756 return xen_api_success(XendNode.instance().uuid)
757 def host_cpu_get_utilisation(self, session, host_cpu_ref):
758 util = XendNode.instance().get_host_cpu_load(host_cpu_ref)
759 return xen_api_success(util)
760 def host_cpu_get_number(self, session, host_cpu_ref):
761 num = XendNode.instance().get_host_cpu_number(host_cpu_ref)
762 return xen_api_success(num)
764 # object methods
765 def host_cpu_destroy(self, session, host_cpu_ref):
766 return xen_api_error(XEND_ERROR_UNSUPPORTED)
767 def host_cpu_get_record(self, session, host_cpu_ref):
768 node = XendNode.instance()
769 record = {'uuid': host_cpu_ref,
770 'host': node.uuid,
771 'number': node.get_host_cpu_number(host_cpu_ref),
772 'utilisation': node.get_host_cpu_load(host_cpu_ref)}
773 return xen_api_success(record)
775 # class methods
776 def host_cpu_get_all(self, session):
777 return xen_api_success(XendNode.instance().get_host_cpu_refs())
780 # Xen API: Class host_metrics
781 # ----------------------------------------------------------------
783 host_metrics_attr_ro = ['memory_total',
784 'memory_free',
785 'host']
786 host_metrics_attr_rw = []
787 host_metrics_methods = []
789 def _host_metrics_get(self, ref, f):
790 return xen_api_success(getattr(node, f)())
792 def host_metrics_get_record(self, _, ref):
793 return xen_api_success({
794 'uuid' : ref,
795 'host' : XendNode.instance().uuid,
796 'memory_total' : self._host_metrics_get_memory_total(),
797 'memory_free' : self._host_metrics_get_memory_free(),
798 })
800 def host_metrics_get_host(self, _, ref):
801 return xen_api_success(XendNode.instance().uuid)
803 def host_metrics_get_memory_total(self, _, ref):
804 return xen_api_success(self._host_metrics_get_memory_total())
806 def host_metrics_get_memory_free(self, _, ref):
807 return xen_api_success(self._host_metrics_get_memory_free())
809 def _host_metrics_get_memory_total(self):
810 node = XendNode.instance()
811 return node.xc.physinfo()['total_memory'] * 1024
813 def _host_metrics_get_memory_free(self):
814 node = XendNode.instance()
815 return node.xc.physinfo()['free_memory'] * 1024
818 # Xen API: Class network
819 # ----------------------------------------------------------------
821 network_attr_ro = ['VIFs', 'PIFs']
822 network_attr_rw = ['name_label',
823 'name_description',
824 'default_gateway',
825 'default_netmask']
827 network_funcs = [('create', 'network')]
829 def network_create(self, _, name_label, name_description,
830 default_gateway, default_netmask):
831 return xen_api_success(
832 XendNode.instance().network_create(name_label, name_description,
833 default_gateway,
834 default_netmask))
836 def network_destroy(self, _, ref):
837 return xen_api_success(XendNode.instance().network_destroy(ref))
839 def _get_network(self, ref):
840 return XendNode.instance().get_network(ref)
842 def network_get_all(self, _):
843 return xen_api_success(XendNode.instance().get_network_refs())
845 def network_get_record(self, _, ref):
846 return xen_api_success(
847 XendNode.instance().get_network(ref).get_record())
849 def network_get_name_label(self, _, ref):
850 return xen_api_success(self._get_network(ref).name_label)
852 def network_get_name_description(self, _, ref):
853 return xen_api_success(self._get_network(ref).name_description)
855 def network_get_default_gateway(self, _, ref):
856 return xen_api_success(self._get_network(ref).default_gateway)
858 def network_get_default_netmask(self, _, ref):
859 return xen_api_success(self._get_network(ref).default_netmask)
861 def network_get_VIFs(self, _, ref):
862 return xen_api_success(self._get_network(ref).get_VIF_UUIDs())
864 def network_get_PIFs(self, session, ref):
865 return xen_api_success(self._get_network(ref).get_PIF_UUIDs())
867 def network_set_name_label(self, _, ref, val):
868 return xen_api_success(self._get_network(ref).set_name_label(val))
870 def network_set_name_description(self, _, ref, val):
871 return xen_api_success(self._get_network(ref).set_name_description(val))
873 def network_set_default_gateway(self, _, ref, val):
874 return xen_api_success(self._get_network(ref).set_default_gateway(val))
876 def network_set_default_netmask(self, _, ref, val):
877 return xen_api_success(self._get_network(ref).set_default_netmask(val))
880 # Xen API: Class PIF
881 # ----------------------------------------------------------------
883 PIF_attr_ro = ['metrics']
884 PIF_attr_rw = ['device',
885 'network',
886 'host',
887 'MAC',
888 'MTU',
889 'VLAN']
891 PIF_attr_inst = PIF_attr_rw
893 PIF_methods = [('create_VLAN', 'int')]
895 def _get_PIF(self, ref):
896 return XendNode.instance().pifs[ref]
898 def PIF_destroy(self, _, ref):
899 try:
900 return xen_api_success(XendNode.instance().PIF_destroy(ref))
901 except PIFIsPhysical, exn:
902 return xen_api_error(['PIF_IS_PHYSICAL', ref])
904 # object methods
905 def PIF_get_record(self, _, ref):
906 return xen_api_success(self._get_PIF(ref).get_record())
908 def PIF_get_all(self, _):
909 return xen_api_success(XendNode.instance().pifs.keys())
911 def PIF_get_metrics(self, _, ref):
912 return xen_api_success(self._get_PIF(ref).metrics.uuid)
914 def PIF_get_device(self, _, ref):
915 return xen_api_success(self._get_PIF(ref).device)
917 def PIF_get_network(self, _, ref):
918 return xen_api_success(self._get_PIF(ref).network.uuid)
920 def PIF_get_host(self, _, ref):
921 return xen_api_success(self._get_PIF(ref).host.uuid)
923 def PIF_get_MAC(self, _, ref):
924 return xen_api_success(self._get_PIF(ref).mac)
926 def PIF_get_MTU(self, _, ref):
927 return xen_api_success(self._get_PIF(ref).mtu)
929 def PIF_get_VLAN(self, _, ref):
930 return xen_api_success(self._get_PIF(ref).vlan)
932 def PIF_set_device(self, _, ref, device):
933 return xen_api_success(self._get_PIF(ref).set_device(device))
935 def PIF_set_MAC(self, _, ref, mac):
936 return xen_api_success(self._get_PIF(ref).set_mac(mac))
938 def PIF_set_MTU(self, _, ref, mtu):
939 return xen_api_success(self._get_PIF(ref).set_mtu(mtu))
941 def PIF_create_VLAN(self, _, ref, network, vlan):
942 try:
943 vlan = int(vlan)
944 except:
945 return xen_api_error(['VLAN_TAG_INVALID', vlan])
947 try:
948 node = XendNode.instance()
950 if _is_valid_ref(network, node.is_valid_network):
951 return xen_api_success(
952 node.PIF_create_VLAN(ref, network, vlan))
953 else:
954 return xen_api_error(['HANDLE_INVALID', 'network', network])
955 except NetworkAlreadyConnected, exn:
956 return xen_api_error(['NETWORK_ALREADY_CONNECTED',
957 network, exn.pif_uuid])
958 except VLANTagInvalid:
959 return xen_api_error(['VLAN_TAG_INVALID', vlan])
962 # Xen API: Class PIF_metrics
963 # ----------------------------------------------------------------
965 PIF_metrics_attr_ro = ['PIF',
966 'io_read_kbs',
967 'io_write_kbs']
968 PIF_metrics_attr_rw = []
969 PIF_methods = []
971 def _PIF_metrics_get(self, ref):
972 return XendNode.instance().pif_metrics[ref]
974 def PIF_metrics_get_record(self, _, ref):
975 return xen_api_success(self._PIF_metrics_get(ref).get_record())
977 def PIF_metrics_get_PIF(self, _, ref):
978 return xen_api_success(self._PIF_metrics_get(ref).pif.uuid)
980 def PIF_metrics_get_io_read_kbs(self, _, ref):
981 return xen_api_success(self._PIF_metrics_get(ref).get_io_read_kbs())
983 def PIF_metrics_get_io_write_kbs(self, _, ref):
984 return xen_api_success(self._PIF_metrics_get(ref).get_io_write_kbs())
987 # Xen API: Class VM
988 # ----------------------------------------------------------------
990 VM_attr_ro = ['power_state',
991 'resident_on',
992 'memory_actual',
993 'memory_static_max',
994 'memory_static_min',
995 'VCPUs_number',
996 'VCPUs_utilisation',
997 'consoles',
998 'VIFs',
999 'VBDs',
1000 'VTPMs',
1001 'PCI_bus',
1002 'tools_version',
1003 'is_control_domain',
1006 VM_attr_rw = ['name_label',
1007 'name_description',
1008 'user_version',
1009 'is_a_template',
1010 'auto_power_on',
1011 'memory_dynamic_max',
1012 'memory_dynamic_min',
1013 'VCPUs_policy',
1014 'VCPUs_params',
1015 'actions_after_shutdown',
1016 'actions_after_reboot',
1017 'actions_after_suspend',
1018 'actions_after_crash',
1019 'PV_bootloader',
1020 'PV_kernel',
1021 'PV_ramdisk',
1022 'PV_args',
1023 'PV_bootloader_args',
1024 'HVM_boot_policy',
1025 'HVM_boot_params',
1026 'platform_std_VGA',
1027 'platform_serial',
1028 'platform_localtime',
1029 'platform_clock_offset',
1030 'platform_enable_audio',
1031 'platform_keymap',
1032 'other_config']
1034 VM_methods = [('clone', 'VM'),
1035 ('start', None),
1036 ('pause', None),
1037 ('unpause', None),
1038 ('clean_shutdown', None),
1039 ('clean_reboot', None),
1040 ('hard_shutdown', None),
1041 ('hard_reboot', None),
1042 ('suspend', None),
1043 ('resume', None),
1044 ('add_to_other_config', None),
1045 ('remove_from_other_config', None)]
1047 VM_funcs = [('create', 'VM'),
1048 ('get_by_name_label', 'Set(VM)')]
1050 # parameters required for _create()
1051 VM_attr_inst = [
1052 'name_label',
1053 'name_description',
1054 'user_version',
1055 'is_a_template',
1056 'memory_static_max',
1057 'memory_dynamic_max',
1058 'memory_dynamic_min',
1059 'memory_static_min',
1060 'VCPUs_policy',
1061 'VCPUs_params',
1062 'actions_after_shutdown',
1063 'actions_after_reboot',
1064 'actions_after_suspend',
1065 'actions_after_crash',
1066 'PV_bootloader',
1067 'PV_kernel',
1068 'PV_ramdisk',
1069 'PV_args',
1070 'PV_bootloader_args',
1071 'HVM_boot_policy',
1072 'HVM_boot_params',
1073 'platform_std_VGA',
1074 'platform_serial',
1075 'platform_localtime',
1076 'platform_clock_offset',
1077 'platform_enable_audio',
1078 'platform_keymap',
1079 'grub_cmdline',
1080 'PCI_bus',
1081 'other_config']
1083 def VM_get(self, name, session, vm_ref):
1084 return xen_api_success(
1085 XendDomain.instance().get_vm_by_uuid(vm_ref).info[name])
1087 def VM_set(self, name, session, vm_ref, value):
1088 xd = XendDomain.instance()
1089 dominfo = xd.get_vm_by_uuid(vm_ref)
1090 dominfo.info[name] = value
1091 xd.managed_config_save(dominfo)
1092 return xen_api_success_void()
1094 # attributes (ro)
1095 def VM_get_power_state(self, session, vm_ref):
1096 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1097 return xen_api_success(dom.get_power_state())
1099 def VM_get_resident_on(self, session, vm_ref):
1100 return xen_api_success(XendNode.instance().uuid)
1102 def VM_get_memory_actual(self, session, vm_ref):
1103 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1104 return xen_api_todo() # unsupported by xc
1106 def VM_get_memory_static_max(self, session, vm_ref):
1107 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1108 return xen_api_success(dom.get_memory_static_max())
1110 def VM_get_memory_static_min(self, session, vm_ref):
1111 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1112 return xen_api_success(dom.get_memory_static_min())
1114 def VM_get_VCPUs_number(self, session, vm_ref):
1115 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1116 return xen_api_success(dom.getVCpuCount())
1118 def VM_get_VCPUs_utilisation(self, session, vm_ref):
1119 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1120 return xen_api_success(dom.get_vcpus_util())
1122 def VM_get_VIFs(self, session, vm_ref):
1123 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1124 return xen_api_success(dom.get_vifs())
1126 def VM_get_VBDs(self, session, vm_ref):
1127 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1128 return xen_api_success(dom.get_vbds())
1130 def VM_get_VTPMs(self, session, vm_ref):
1131 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1132 return xen_api_success(dom.get_vtpms())
1134 def VM_get_consoles(self, session, vm_ref):
1135 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1136 return xen_api_success(dom.get_consoles())
1138 def VM_get_PCI_bus(self, session, vm_ref):
1139 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1140 return dom.get_pci_bus()
1142 def VM_get_tools_version(self, session, vm_ref):
1143 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1144 return dom.get_tools_version()
1146 # attributes (rw)
1147 def VM_get_name_label(self, session, vm_ref):
1148 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1149 return xen_api_success(dom.getName())
1151 def VM_get_name_description(self, session, vm_ref):
1152 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1153 return xen_api_todo()
1155 def VM_get_user_version(self, session, vm_ref):
1156 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1157 return xen_api_todo()
1159 def VM_get_is_a_template(self, session, vm_ref):
1160 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1161 return xen_api_todo()
1163 def VM_get_memory_dynamic_max(self, session, vm_ref):
1164 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1165 return xen_api_success(dom.get_memory_dynamic_max())
1167 def VM_get_memory_dynamic_min(self, session, vm_ref):
1168 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1169 return xen_api_success(dom.get_memory_dynamic_min())
1171 def VM_get_VCPUs_policy(self, session, vm_ref):
1172 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1173 return xen_api_success(dom.get_vcpus_policy())
1175 def VM_get_VCPUs_params(self, session, vm_ref):
1176 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1177 return xen_api_success(dom.get_vcpus_params())
1179 def VM_get_actions_after_shutdown(self, session, vm_ref):
1180 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1181 return xen_api_success(dom.get_on_shutdown())
1183 def VM_get_actions_after_reboot(self, session, vm_ref):
1184 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1185 return xen_api_success(dom.get_on_reboot())
1187 def VM_get_actions_after_suspend(self, session, vm_ref):
1188 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1189 return xen_api_success(dom.get_on_suspend())
1191 def VM_get_actions_after_crash(self, session, vm_ref):
1192 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1193 return xen_api_success(dom.get_on_crash())
1195 def VM_get_PV_bootloader(self, session, vm_ref):
1196 return self.VM_get('PV_bootloader', session, vm_ref)
1198 def VM_get_PV_kernel(self, session, vm_ref):
1199 return self.VM_get('PV_kernel', session, vm_ref)
1201 def VM_get_PV_ramdisk(self, session, vm_ref):
1202 return self.VM_get('PV_ramdisk', session, vm_ref)
1204 def VM_get_PV_args(self, session, vm_ref):
1205 return self.VM_get('PV_args', session, vm_ref)
1207 def VM_get_PV_bootloader_args(self, session, vm_ref):
1208 return self.VM_get('PV_bootloader_args', session, vm_ref)
1210 def VM_get_HVM_boot_policy(self, session, vm_ref):
1211 return self.VM_get('HVM_boot_policy', session, vm_ref)
1213 def VM_get_HVM_boot_params(self, session, vm_ref):
1214 return self.VM_get('HVM_boot_params', session, vm_ref)
1216 def VM_get_platform_std_VGA(self, session, vm_ref):
1217 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1218 return xen_api_success(dom.get_platform_std_vga())
1220 def VM_get_platform_serial(self, session, vm_ref):
1221 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1222 return xen_api_success(dom.get_platform_serial())
1224 def VM_get_platform_localtime(self, session, vm_ref):
1225 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1226 return xen_api_success(dom.get_platform_localtime())
1228 def VM_get_platform_clock_offset(self, session, vm_ref):
1229 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1230 return xen_api_success(dom.get_platform_clock_offset())
1232 def VM_get_platform_enable_audio(self, session, vm_ref):
1233 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1234 return xen_api_success(dom.get_platform_enable_audio())
1236 def VM_get_platform_keymap(self, session, vm_ref):
1237 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1238 return xen_api_success(dom.get_platform_keymap())
1240 def VM_get_other_config(self, session, vm_ref):
1241 return self.VM_get('other_config', session, vm_ref)
1243 def VM_get_is_control_domain(self, session, vm_ref):
1244 xd = XendDomain.instance()
1245 return xen_api_success(
1246 xd.get_vm_by_uuid(vm_ref) == xd.privilegedDomain())
1248 def VM_set_name_label(self, session, vm_ref, label):
1249 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1250 dom.setName(label)
1251 return xen_api_success_void()
1253 def VM_set_name_description(self, session, vm_ref, desc):
1254 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1255 return xen_api_todo()
1257 def VM_set_user_version(self, session, vm_ref, ver):
1258 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1259 return xen_api_todo()
1261 def VM_set_is_a_template(self, session, vm_ref, is_template):
1262 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1263 return xen_api_todo()
1265 def VM_set_memory_dynamic_max(self, session, vm_ref, mem):
1266 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1267 return xen_api_todo()
1269 def VM_set_memory_dynamic_min(self, session, vm_ref, mem):
1270 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1271 return xen_api_todo()
1273 def VM_set_VCPUs_policy(self, session, vm_ref, policy):
1274 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1275 return xen_api_todo()
1277 def VM_set_VCPUs_params(self, session, vm_ref, params):
1278 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1279 return xen_api_todo()
1281 def VM_set_actions_after_shutdown(self, session, vm_ref, action):
1282 if action not in XEN_API_ON_NORMAL_EXIST:
1283 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1284 return self.VM_set('actions_after_shutdown', session, vm_ref, action)
1286 def VM_set_actions_after_reboot(self, session, vm_ref, action):
1287 if action not in XEN_API_ON_NORMAL_EXIST:
1288 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1289 return self.VM_set('actions_after_reboot', session, vm_ref, action)
1291 def VM_set_actions_after_suspend(self, session, vm_ref, action):
1292 if action not in XEN_API_ON_NORMAL_EXIT:
1293 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1294 return self.VM_set('actions_after_suspend', session, vm_ref, action)
1296 def VM_set_actions_after_crash(self, session, vm_ref, action):
1297 if action not in XEN_API_ON_CRASH_BEHAVIOUR:
1298 return xen_api_error(['VM_ON_CRASH_BEHAVIOUR_INVALID', vm_ref])
1299 return self.VM_set('actions_after_crash', session, vm_ref, action)
1301 def VM_set_HVM_boot_policy(self, session, vm_ref, value):
1302 if value != "" and value != "BIOS order":
1303 return xen_api_error(
1304 ['VALUE_NOT_SUPPORTED', 'VM.HVM_boot_policy', value,
1305 'Xend supports only the "BIOS order" boot policy.'])
1306 else:
1307 return self.VM_set('HVM_boot_policy', session, vm_ref, value)
1309 def VM_set_HVM_boot_params(self, session, vm_ref, value):
1310 return self.VM_set('HVM_boot_params', session, vm_ref, value)
1312 def VM_add_to_HVM_boot_params(self, session, vm_ref, key, value):
1313 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1314 if 'HVM_boot_params' not in dom.info:
1315 dom.info['HVM_boot_params'] = {}
1316 dom.info['HVM_boot_params'][key] = value
1317 return xen_api_success_void()
1319 def VM_remove_from_HVM_boot_params(self, session, vm_ref, key):
1320 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1321 if 'HVM_boot_params' in dom.info \
1322 and key in dom.info['HVM_boot_params']:
1323 del dom.info['HVM_boot_params'][key]
1324 return xen_api_success_void()
1326 def VM_set_PV_bootloader(self, session, vm_ref, value):
1327 return self.VM_set('PV_bootloader', session, vm_ref, value)
1329 def VM_set_PV_kernel(self, session, vm_ref, value):
1330 return self.VM_set('PV_kernel', session, vm_ref, value)
1332 def VM_set_PV_ramdisk(self, session, vm_ref, value):
1333 return self.VM_set('PV_ramdisk', session, vm_ref, value)
1335 def VM_set_PV_args(self, session, vm_ref, value):
1336 return self.VM_set('PV_args', session, vm_ref, value)
1338 def VM_set_PV_bootloader_args(self, session, vm_ref, value):
1339 return self.VM_set('PV_bootloader_args', session, vm_ref, value)
1341 def VM_set_platform_std_VGA(self, session, vm_ref, value):
1342 return self.VM_set('platform_std_vga', session, vm_ref, value)
1344 def VM_set_platform_serial(self, session, vm_ref, value):
1345 return self.VM_set('platform_serial', session, vm_ref, value)
1347 def VM_set_platform_keymap(self, session, vm_ref, value):
1348 return self.VM_set('platform_keymap', session, vm_ref, value)
1350 def VM_set_platform_localtime(self, session, vm_ref, value):
1351 return self.VM_set('platform_localtime', session, vm_ref, value)
1353 def VM_set_platform_clock_offset(self, session, vm_ref, value):
1354 return self.VM_set('platform_clock_offset', session, vm_ref, value)
1356 def VM_set_platform_enable_audio(self, session, vm_ref, value):
1357 return self.VM_set('platform_enable_audio', session, vm_ref, value)
1359 def VM_set_other_config(self, session, vm_ref, value):
1360 return self.VM_set('otherconfig', session, vm_ref, value)
1362 def VM_add_to_other_config(self, session, vm_ref, key, value):
1363 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1364 if dom and 'otherconfig' in dom.info:
1365 dom.info['otherconfig'][key] = value
1366 return xen_api_success_void()
1368 def VM_remove_from_other_config(self, session, vm_ref, key):
1369 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1370 if dom and 'otherconfig' in dom.info \
1371 and key in dom.info['otherconfig']:
1372 del dom.info['otherconfig'][key]
1373 return xen_api_success_void()
1375 # class methods
1376 def VM_get_all(self, session):
1377 refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
1378 return xen_api_success(refs)
1380 def VM_get_by_name_label(self, session, label):
1381 xendom = XendDomain.instance()
1382 dom = xendom.domain_lookup_nr(label)
1383 if dom:
1384 return xen_api_success([dom.get_uuid()])
1385 return xen_api_success([])
1387 def VM_create(self, session, vm_struct):
1388 xendom = XendDomain.instance()
1389 domuuid = XendTask.log_progress(0, 100,
1390 xendom.create_domain, vm_struct)
1391 return xen_api_success(domuuid)
1393 # object methods
1394 def VM_get_record(self, session, vm_ref):
1395 xendom = XendDomain.instance()
1396 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1397 if not xeninfo:
1398 return xen_api_error(['HANDLE_INVALID', 'VM', vm_ref])
1400 record = {
1401 'uuid': xeninfo.get_uuid(),
1402 'power_state': xeninfo.get_power_state(),
1403 'name_label': xeninfo.getName(),
1404 'name_description': xeninfo.getName(),
1405 'user_version': 1,
1406 'is_a_template': False,
1407 'auto_power_on': False,
1408 'resident_on': XendNode.instance().uuid,
1409 'memory_static_min': xeninfo.get_memory_static_min(),
1410 'memory_static_max': xeninfo.get_memory_static_max(),
1411 'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
1412 'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
1413 'memory_actual': xeninfo.get_memory_static_min(),
1414 'VCPUs_policy': xeninfo.get_vcpus_policy(),
1415 'VCPUs_params': xeninfo.get_vcpus_params(),
1416 'VCPUs_number': xeninfo.getVCpuCount(),
1417 'VCPUs_utilisation': xeninfo.get_vcpus_util(),
1418 'actions_after_shutdown': xeninfo.get_on_shutdown(),
1419 'actions_after_reboot': xeninfo.get_on_reboot(),
1420 'actions_after_suspend': xeninfo.get_on_suspend(),
1421 'actions_after_crash': xeninfo.get_on_crash(),
1422 'consoles': xeninfo.get_consoles(),
1423 'VIFs': xeninfo.get_vifs(),
1424 'VBDs': xeninfo.get_vbds(),
1425 'VTPMs': xeninfo.get_vtpms(),
1426 'PV_bootloader': xeninfo.info.get('PV_bootloader'),
1427 'PV_kernel': xeninfo.info.get('PV_kernel'),
1428 'PV_ramdisk': xeninfo.info.get('PV_ramdisk'),
1429 'PV_args': xeninfo.info.get('PV_args'),
1430 'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
1431 'HVM_boot_policy': xeninfo.info.get('HVM_boot_policy'),
1432 'HVM_boot_params': xeninfo.info.get('HVM_boot_params'),
1433 'platform_std_VGA': xeninfo.get_platform_std_vga(),
1434 'platform_serial': xeninfo.get_platform_serial(),
1435 'platform_localtime': xeninfo.get_platform_localtime(),
1436 'platform_clock_offset': xeninfo.get_platform_clock_offset(),
1437 'platform_enable_audio': xeninfo.get_platform_enable_audio(),
1438 'platform_keymap': xeninfo.get_platform_keymap(),
1439 'PCI_bus': xeninfo.get_pci_bus(),
1440 'tools_version': xeninfo.get_tools_version(),
1441 'other_config': xeninfo.info.get('other_config', {}),
1442 'is_control_domain': xeninfo == xendom.privilegedDomain(),
1444 return xen_api_success(record)
1446 def VM_clean_reboot(self, session, vm_ref):
1447 xendom = XendDomain.instance()
1448 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1449 XendTask.log_progress(0, 100, xeninfo.shutdown, "reboot")
1450 return xen_api_success_void()
1452 def VM_clean_shutdown(self, session, vm_ref):
1453 xendom = XendDomain.instance()
1454 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1455 XendTask.log_progress(0, 100, xeninfo.shutdown, "poweroff")
1456 return xen_api_success_void()
1458 def VM_clone(self, session, vm_ref):
1459 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1461 def VM_destroy(self, session, vm_ref):
1462 return XendTask.log_progress(0, 100, do_vm_func,
1463 "domain_delete", vm_ref)
1465 def VM_hard_reboot(self, session, vm_ref):
1466 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1468 def VM_hard_shutdown(self, session, vm_ref):
1469 return XendTask.log_progress(0, 100, do_vm_func,
1470 "domain_destroy", vm_ref)
1471 def VM_pause(self, session, vm_ref):
1472 return XendTask.log_progress(0, 100, do_vm_func,
1473 "domain_pause", vm_ref)
1475 def VM_resume(self, session, vm_ref, start_paused):
1476 return XendTask.log_progress(0, 100, do_vm_func,
1477 "domain_resume", vm_ref,
1478 start_paused = start_paused)
1480 def VM_start(self, session, vm_ref, start_paused):
1481 return XendTask.log_progress(0, 100, do_vm_func,
1482 "domain_start", vm_ref,
1483 start_paused = start_paused)
1485 def VM_suspend(self, session, vm_ref):
1486 return XendTask.log_progress(0, 100, do_vm_func,
1487 "domain_suspend", vm_ref)
1489 def VM_unpause(self, session, vm_ref):
1490 return XendTask.log_progress(0, 100, do_vm_func,
1491 "domain_unpause", vm_ref)
1493 # Xen API: Class VBD
1494 # ----------------------------------------------------------------
1496 VBD_attr_ro = ['metrics']
1497 VBD_attr_rw = ['VM',
1498 'VDI',
1499 'device',
1500 'bootable',
1501 'mode',
1502 'type']
1504 VBD_attr_inst = VBD_attr_rw
1506 VBD_methods = [('media_change', None)]
1507 VBD_funcs = [('create', 'VBD')]
1509 # object methods
1510 def VBD_get_record(self, session, vbd_ref):
1511 xendom = XendDomain.instance()
1512 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1513 if not vm:
1514 return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
1515 cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
1516 if not cfg:
1517 return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
1519 valid_vbd_keys = self.VBD_attr_ro + self.VBD_attr_rw + \
1520 self.Base_attr_ro + self.Base_attr_rw
1522 return_cfg = {}
1523 for k in cfg.keys():
1524 if k in valid_vbd_keys:
1525 return_cfg[k] = cfg[k]
1527 return_cfg['metrics'] = vbd_ref
1529 return xen_api_success(return_cfg)
1531 def VBD_media_change(self, session, vbd_ref, vdi_ref):
1532 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1534 # class methods
1535 def VBD_create(self, session, vbd_struct):
1536 xendom = XendDomain.instance()
1537 if not xendom.is_valid_vm(vbd_struct['VM']):
1538 return xen_api_error(['HANDLE_INVALID', 'VM', vbd_struct['VM']])
1540 dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
1541 vbd_ref = ''
1542 try:
1543 # new VBD via VDI/SR
1544 vdi_ref = vbd_struct.get('VDI')
1545 vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
1546 if not vdi:
1547 return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
1548 vdi_image = vdi.get_location()
1549 vbd_ref = XendTask.log_progress(0, 100,
1550 dom.create_vbd,
1551 vbd_struct, vdi_image)
1552 except XendError:
1553 return xen_api_todo()
1555 xendom.managed_config_save(dom)
1556 return xen_api_success(vbd_ref)
1559 def VBD_destroy(self, session, vbd_ref):
1560 xendom = XendDomain.instance()
1561 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1562 if not vm:
1563 return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
1565 XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref)
1566 return xen_api_success_void()
1568 def _VBD_get(self, vbd_ref, prop):
1569 return xen_api_success(
1570 XendDomain.instance().get_dev_property_by_uuid(
1571 'vbd', vbd_ref, prop))
1573 # attributes (ro)
1574 def VBD_get_metrics(self, _, vbd_ref):
1575 return xen_api_success(vbd_ref)
1577 # attributes (rw)
1578 def VBD_get_VM(self, session, vbd_ref):
1579 return self._VBD_get(vbd_ref, 'VM')
1581 def VBD_get_VDI(self, session, vbd_ref):
1582 return self._VBD_get(vbd_ref, 'VDI')
1584 def VBD_get_device(self, session, vbd_ref):
1585 return self._VBD_get(vbd_ref, 'device')
1587 def VBD_get_bootable(self, session, vbd_ref):
1588 return self._VBD_get(vbd_ref, 'bootable')
1590 def VBD_get_mode(self, session, vbd_ref):
1591 return self._VBD_get(vbd_ref, 'mode')
1593 def VBD_get_type(self, session, vbd_ref):
1594 return self._VBD_get(vbd_ref, 'type')
1596 def VBD_set_bootable(self, session, vbd_ref, bootable):
1597 bootable = bool(bootable)
1598 xd = XendDomain.instance()
1599 vm = xd.get_vm_with_dev_uuid('vbd', vbd_ref)
1600 vm.set_dev_property('vbd', vbd_ref, 'bootable', bootable)
1601 xd.managed_config_save(vm)
1602 return xen_api_success_void()
1604 def VBD_get_all(self, session):
1605 xendom = XendDomain.instance()
1606 vbds = [d.get_vbds() for d in XendDomain.instance().list('all')]
1607 vbds = reduce(lambda x, y: x + y, vbds)
1608 return xen_api_success(vbds)
1611 # Xen API: Class VBD_metrics
1612 # ----------------------------------------------------------------
1614 VBD_metrics_attr_ro = ['io_read_kbs',
1615 'io_write_kbs']
1616 VBD_metrics_attr_rw = []
1617 VBD_methods = []
1619 def VBD_metrics_get_record(self, _, ref):
1620 vm = XendDomain.instance().get_vm_with_dev_uuid('vbd', ref)
1621 if not vm:
1622 return xen_api_error(['HANDLE_INVALID', 'VBD_metrics', ref])
1623 return xen_api_success(
1624 { 'io_read_kbs' : vm.get_dev_property('vbd', ref, 'io_read_kbs'),
1625 'io_write_kbs' : vm.get_dev_property('vbd', ref, 'io_write_kbs') })
1627 def VBD_metrics_get_io_read_kbs(self, _, ref):
1628 return self._VBD_get(ref, 'io_read_kbs')
1630 def VBD_metrics_get_io_write_kbs(self, session, ref):
1631 return self._VBD_get(ref, 'io_write_kbs')
1634 # Xen API: Class VIF
1635 # ----------------------------------------------------------------
1637 VIF_attr_ro = ['metrics']
1638 VIF_attr_rw = ['device',
1639 'network',
1640 'VM',
1641 'MAC',
1642 'MTU']
1644 VIF_attr_inst = VIF_attr_rw
1646 VIF_funcs = [('create', 'VIF')]
1649 # object methods
1650 def VIF_get_record(self, session, vif_ref):
1651 xendom = XendDomain.instance()
1652 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1653 if not vm:
1654 return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
1655 cfg = vm.get_dev_xenapi_config('vif', vif_ref)
1656 if not cfg:
1657 return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
1659 valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
1660 self.Base_attr_ro + self.Base_attr_rw
1662 return_cfg = {}
1663 for k in cfg.keys():
1664 if k in valid_vif_keys:
1665 return_cfg[k] = cfg[k]
1667 return_cfg['metrics'] = vif_ref
1669 return xen_api_success(return_cfg)
1671 # class methods
1672 def VIF_create(self, session, vif_struct):
1673 xendom = XendDomain.instance()
1674 if xendom.is_valid_vm(vif_struct['VM']):
1675 dom = xendom.get_vm_by_uuid(vif_struct['VM'])
1676 try:
1677 vif_ref = dom.create_vif(vif_struct)
1678 xendom.managed_config_save(dom)
1679 return xen_api_success(vif_ref)
1680 except XendError:
1681 return xen_api_error(XEND_ERROR_TODO)
1682 else:
1683 return xen_api_error(['HANDLE_INVALID', 'VM', vif_struct['VM']])
1686 def VIF_destroy(self, session, vif_ref):
1687 xendom = XendDomain.instance()
1688 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1689 if not vm:
1690 return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
1692 vm.destroy_vif(vif_ref)
1693 return xen_api_success_void()
1695 def _VIF_get(self, ref, prop):
1696 return xen_api_success(
1697 XendDomain.instance().get_dev_property_by_uuid('vif', ref, prop))
1699 # getters/setters
1700 def VIF_get_metrics(self, _, vif_ref):
1701 return xen_api_success(vif_ref)
1703 def VIF_get_VM(self, session, vif_ref):
1704 xendom = XendDomain.instance()
1705 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1706 return xen_api_success(vm.get_uuid())
1708 def VIF_get_MTU(self, session, vif_ref):
1709 return self._VIF_get(vif_ref, 'MTU')
1711 def VIF_get_MAC(self, session, vif_ref):
1712 return self._VIF_get(vif_ref, 'MAC')
1714 def VIF_get_device(self, session, vif_ref):
1715 return self._VIF_get(vif_ref, 'device')
1717 def VIF_get_all(self, session):
1718 xendom = XendDomain.instance()
1719 vifs = [d.get_vifs() for d in XendDomain.instance().list('all')]
1720 vifs = reduce(lambda x, y: x + y, vifs)
1721 return xen_api_success(vifs)
1724 # Xen API: Class VIF_metrics
1725 # ----------------------------------------------------------------
1727 VIF_metrics_attr_ro = ['io_read_kbs',
1728 'io_write_kbs']
1729 VIF_metrics_attr_rw = []
1730 VIF_methods = []
1732 def VIF_metrics_get_record(self, _, ref):
1733 vm = XendDomain.instance().get_vm_with_dev_uuid('vif', ref)
1734 if not vm:
1735 return xen_api_error(['HANDLE_INVALID', 'VIF_metrics', ref])
1736 return xen_api_success(
1737 { 'io_read_kbs' : vm.get_dev_property('vif', ref, 'io_read_kbs'),
1738 'io_write_kbs' : vm.get_dev_property('vif', ref, 'io_write_kbs') })
1740 def VIF_metrics_get_io_read_kbs(self, _, ref):
1741 return self._VIF_get(ref, 'io_read_kbs')
1743 def VIF_metrics_get_io_write_kbs(self, session, ref):
1744 return self._VIF_get(ref, 'io_write_kbs')
1747 # Xen API: Class VDI
1748 # ----------------------------------------------------------------
1749 VDI_attr_ro = ['VBDs',
1750 'physical_utilisation',
1751 'sector_size',
1752 'type']
1753 VDI_attr_rw = ['name_label',
1754 'name_description',
1755 'SR',
1756 'virtual_size',
1757 'sharable',
1758 'read_only']
1759 VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
1761 VDI_methods = [('snapshot', 'VDI')]
1762 VDI_funcs = [('create', 'VDI'),
1763 ('get_by_name_label', 'Set(VDI)')]
1765 def _get_VDI(self, ref):
1766 return XendNode.instance().get_vdi_by_uuid(ref)
1768 def VDI_get_VBDs(self, session, vdi_ref):
1769 return xen_api_todo()
1771 def VDI_get_physical_utilisation(self, session, vdi_ref):
1772 return xen_api_success(self._get_VDI(vdi_ref).
1773 get_physical_utilisation())
1775 def VDI_get_sector_size(self, session, vdi_ref):
1776 return xen_api_success(self._get_VDI(vdi_ref).sector_size)
1778 def VDI_get_type(self, session, vdi_ref):
1779 return xen_api_success(self._get_VDI(vdi_ref).type)
1781 def VDI_get_name_label(self, session, vdi_ref):
1782 return xen_api_success(self._get_VDI(vdi_ref).name_label)
1784 def VDI_get_name_description(self, session, vdi_ref):
1785 return xen_api_success(self._get_VDI(vdi_ref).name_description)
1787 def VDI_get_SR(self, session, vdi_ref):
1788 return xen_api_success(self._get_VDI(vdi_ref).sr_uuid)
1790 def VDI_get_virtual_size(self, session, vdi_ref):
1791 return xen_api_success(self._get_VDI(vdi_ref).virtual_size)
1793 def VDI_get_sharable(self, session, vdi_ref):
1794 return xen_api_success(self._get_VDI(vdi_ref).sharable)
1796 def VDI_get_read_only(self, session, vdi_ref):
1797 return xen_api_success(self._get_VDI(vdi_ref).read_only)
1799 def VDI_set_name_label(self, session, vdi_ref, value):
1800 self._get_VDI(vdi_ref).name_label = value
1801 return xen_api_success_void()
1803 def VDI_set_name_description(self, session, vdi_ref, value):
1804 self._get_VDI(vdi_ref).name_description = value
1805 return xen_api_success_void()
1807 def VDI_set_SR(self, session, vdi_ref, value):
1808 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1810 def VDI_set_virtual_size(self, session, vdi_ref, value):
1811 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1813 def VDI_set_sharable(self, session, vdi_ref, value):
1814 self._get_VDI(vdi_ref).sharable = bool(value)
1815 return xen_api_success_void()
1817 def VDI_set_read_only(self, session, vdi_ref, value):
1818 self._get_VDI(vdi_ref).read_only = bool(value)
1819 return xen_api_success_void()
1821 # Object Methods
1822 def VDI_snapshot(self, session, vdi_ref):
1823 return xen_api_todo()
1825 def VDI_destroy(self, session, vdi_ref):
1826 sr = XendNode.instance().get_sr_containing_vdi(vdi_ref)
1827 sr.destroy_vdi(vdi_ref)
1828 return xen_api_success_void()
1830 def VDI_get_record(self, session, vdi_ref):
1831 image = XendNode.instance().get_vdi_by_uuid(vdi_ref)
1832 return xen_api_success({
1833 'uuid': vdi_ref,
1834 'name_label': image.name_label,
1835 'name_description': image.name_description,
1836 'SR': image.sr_uuid,
1837 'VBDs': [], # TODO
1838 'virtual_size': image.virtual_size,
1839 'physical_utilisation': image.physical_utilisation,
1840 'sector_size': image.sector_size,
1841 'type': image.type,
1842 'sharable': image.sharable,
1843 'read_only': image.read_only,
1844 })
1846 # Class Functions
1847 def VDI_create(self, session, vdi_struct):
1848 sr_ref = vdi_struct.get('SR')
1849 xennode = XendNode.instance()
1850 if not xennode.is_valid_sr(sr_ref):
1851 return xen_api_error(['HANDLE_INVALID', 'SR', sr_ref])
1853 vdi_uuid = xennode.srs[sr_ref].create_vdi(vdi_struct)
1854 return xen_api_success(vdi_uuid)
1856 def VDI_get_all(self, session):
1857 xennode = XendNode.instance()
1858 vdis = [sr.get_vdis() for sr in xennode.srs.values()]
1859 return xen_api_success(reduce(lambda x, y: x + y, vdis))
1861 def VDI_get_by_name_label(self, session, name):
1862 xennode = XendNode.instance()
1863 return xen_api_success(xennode.get_vdi_by_name_label(name))
1866 # Xen API: Class VTPM
1867 # ----------------------------------------------------------------
1869 VTPM_attr_rw = [ ]
1870 VTPM_attr_ro = ['VM',
1871 'backend']
1873 VTPM_attr_inst = VTPM_attr_rw
1875 VTPM_funcs = [('create', 'VTPM')]
1877 # object methods
1878 def VTPM_get_record(self, session, vtpm_ref):
1879 xendom = XendDomain.instance()
1880 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1881 if not vm:
1882 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
1883 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1884 if not cfg:
1885 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
1886 valid_vtpm_keys = self.VTPM_attr_ro + self.VTPM_attr_rw + \
1887 self.Base_attr_ro + self.Base_attr_rw
1888 return_cfg = {}
1889 for k in cfg.keys():
1890 if k in valid_vtpm_keys:
1891 return_cfg[k] = cfg[k]
1893 return xen_api_success(return_cfg)
1895 # Class Functions
1896 def VTPM_get_backend(self, session, vtpm_ref):
1897 xendom = XendDomain.instance()
1898 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1899 if not vm:
1900 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
1901 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1902 if not cfg:
1903 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
1904 if not cfg.has_key('backend'):
1905 return xen_api_error(['VTPM backend not set'])
1906 return xen_api_success(cfg['backend'])
1908 def VTPM_get_VM(self, session, vtpm_ref):
1909 xendom = XendDomain.instance()
1910 return xen_api_success(xendom.get_dev_property_by_uuid('vtpm',
1911 vtpm_ref, 'VM'))
1913 def VTPM_destroy(self, session, vtpm_ref):
1914 xendom = XendDomain.instance()
1915 dom = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1916 if dom:
1917 if dom.state != XEN_API_VM_POWER_STATE_HALTED:
1918 vm_ref = dom.get_dev_property('vtpm', vtpm_ref, 'VM')
1919 return xen_api_error(['VM_BAD_POWER_STATE', vm_ref,
1920 XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_HALTED],
1921 XendDomain.POWER_STATE_NAMES[dom.state]])
1922 from xen.xend.server import tpmif
1923 tpmif.destroy_vtpmstate(dom.getName())
1924 return xen_api_success(True)
1925 else:
1926 return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']])
1928 # class methods
1929 def VTPM_create(self, session, vtpm_struct):
1930 xendom = XendDomain.instance()
1931 if xendom.is_valid_vm(vtpm_struct['VM']):
1932 dom = xendom.get_vm_by_uuid(vtpm_struct['VM'])
1933 try:
1934 vtpm_ref = dom.create_vtpm(vtpm_struct)
1935 xendom.managed_config_save(dom)
1936 return xen_api_success(vtpm_ref)
1937 except XendError:
1938 return xen_api_error(XEND_ERROR_TODO)
1939 else:
1940 return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']])
1942 def VTPM_get_all(self, session):
1943 xendom = XendDomain.instance()
1944 vtpms = [d.get_vtpms() for d in XendDomain.instance().list('all')]
1945 vtpms = reduce(lambda x, y: x + y, vtpms)
1946 return xen_api_success(vtpms)
1948 # Xen API: Class console
1949 # ----------------------------------------------------------------
1952 console_attr_ro = ['location', 'protocol', 'VM']
1953 console_attr_rw = ['other_config']
1954 console_funcs = [('create', 'console')]
1956 def console_get_all(self, session):
1957 xendom = XendDomain.instance()
1958 cons = [d.get_consoles() for d in XendDomain.instance().list('all')]
1959 cons = reduce(lambda x, y: x + y, cons)
1960 return xen_api_success(cons)
1962 def console_get_location(self, session, console_ref):
1963 return xen_api_success(xendom.get_dev_property_by_uuid('console',
1964 console_ref,
1965 'location'))
1967 def console_get_protocol(self, session, console_ref):
1968 return xen_api_success(xendom.get_dev_property_by_uuid('console',
1969 console_ref,
1970 'protocol'))
1972 def console_get_VM(self, session, console_ref):
1973 xendom = XendDomain.instance()
1974 vm = xendom.get_vm_with_dev_uuid('console', console_ref)
1975 return xen_api_success(vm.get_uuid())
1977 # object methods
1978 def console_get_record(self, session, console_ref):
1979 xendom = XendDomain.instance()
1980 vm = xendom.get_vm_with_dev_uuid('console', console_ref)
1981 if not vm:
1982 return xen_api_error(['HANDLE_INVALID', 'console', console_ref])
1983 cfg = vm.get_dev_xenapi_config('console', console_ref)
1984 if not cfg:
1985 return xen_api_error(['HANDLE_INVALID', 'console', console_ref])
1987 valid_console_keys = self.console_attr_ro + self.console_attr_rw + \
1988 self.Base_attr_ro + self.Base_attr_rw
1990 return_cfg = {}
1991 for k in cfg.keys():
1992 if k in valid_console_keys:
1993 return_cfg[k] = cfg[k]
1995 return xen_api_success(return_cfg)
1997 def console_create(self, session, console_struct):
1998 xendom = XendDomain.instance()
1999 if not xendom.is_valid_vm(console_struct['VM']):
2000 return xen_api_error(['HANDLE_INVALID', 'VM',
2001 console_struct['VM']])
2003 dom = xendom.get_vm_by_uuid(console_struct['VM'])
2004 try:
2005 if 'protocol' not in console_struct:
2006 return xen_api_error(['CONSOLE_PROTOCOL_INVALID',
2007 'No protocol specified'])
2009 console_ref = dom.create_console(console_struct)
2010 xendom.managed_config_save(dom)
2011 return xen_api_success(console_ref)
2012 except XendError, e:
2013 return xen_api_error([XEND_ERROR_TODO, str(e)])
2015 # Xen API: Class SR
2016 # ----------------------------------------------------------------
2017 SR_attr_ro = ['VDIs',
2018 'virtual_allocation',
2019 'physical_utilisation',
2020 'physical_size',
2021 'type',
2022 'location']
2024 SR_attr_rw = ['name_label',
2025 'name_description']
2027 SR_attr_inst = ['physical_size',
2028 'type',
2029 'location',
2030 'name_label',
2031 'name_description']
2033 SR_methods = [('clone', 'SR')]
2034 SR_funcs = [('get_by_name_label', 'Set(SR)'),
2035 ('get_by_uuid', 'SR')]
2037 # Class Functions
2038 def SR_get_all(self, session):
2039 return xen_api_success(XendNode.instance().get_all_sr_uuid())
2041 def SR_get_by_name_label(self, session, label):
2042 return xen_api_success(XendNode.instance().get_sr_by_name(label))
2044 def SR_create(self, session):
2045 return xen_api_error(XEND_ERROR_UNSUPPORTED)
2047 # Class Methods
2048 def SR_clone(self, session, sr_ref):
2049 return xen_api_error(XEND_ERROR_UNSUPPORTED)
2051 def SR_destroy(self, session, sr_ref):
2052 return xen_api_error(XEND_ERROR_UNSUPPORTED)
2054 def SR_get_record(self, session, sr_ref):
2055 sr = XendNode.instance().get_sr(sr_ref)
2056 if sr:
2057 return xen_api_success(sr.get_record())
2058 return xen_api_error(['HANDLE_INVALID', 'SR', sr_ref])
2060 # Attribute acceess
2062 def _get_SR_func(self, sr_ref, func):
2063 return xen_api_success(getattr(XendNode.instance().get_sr(sr_ref),
2064 func)())
2066 def _get_SR_attr(self, sr_ref, attr):
2067 return xen_api_success(getattr(XendNode.instance().get_sr(sr_ref),
2068 attr))
2070 def SR_get_VDIs(self, _, ref):
2071 return self._get_SR_func(ref, 'list_images')
2073 def SR_get_virtual_allocation(self, _, ref):
2074 return self._get_SR_func(ref, 'virtual_allocation')
2076 def SR_get_physical_utilisation(self, _, ref):
2077 return self._get_SR_func(ref, 'physical_utilisation')
2079 def SR_get_physical_size(self, _, ref):
2080 return self._get_SR_func(ref, 'physical_size')
2082 def SR_get_type(self, _, ref):
2083 return self._get_SR_attr(ref, 'type')
2085 def SR_get_location(self, _, ref):
2086 return self._get_SR_attr(ref, 'location')
2088 def SR_get_name_label(self, _, ref):
2089 return self._get_SR_attr(ref, 'name_label')
2091 def SR_get_name_description(self, _, ref):
2092 return self._get_SR_attr(ref, 'name_description')
2094 def SR_set_name_label(self, session, sr_ref, value):
2095 sr = XendNode.instance.get_sr(sr_ref)
2096 if sr:
2097 sr.name_label = value
2098 XendNode.instance().save()
2099 return xen_api_success_void()
2101 def SR_set_name_description(self, session, sr_ref, value):
2102 sr = XendNode.instance.get_sr(sr_ref)
2103 if sr:
2104 sr.name_description = value
2105 XendNode.instance().save()
2106 return xen_api_success_void()
2109 # Xen API: Class debug
2110 # ----------------------------------------------------------------
2112 debug_methods = [('destroy', None),
2113 ('get_record', 'debug')]
2114 debug_funcs = [('wait', None),
2115 ('return_failure', None)]
2117 def debug_wait(self, session, wait_secs):
2118 import time
2119 prog_units = 100/float(wait_secs)
2120 for i in range(int(wait_secs)):
2121 XendTask.log_progress(prog_units * i, prog_units * (i + 1),
2122 time.sleep, 1)
2123 return xen_api_success_void()
2126 def debug_return_failure(self, session):
2127 return xen_api_error(['DEBUG_FAIL', session])
2129 def debug_create(self, session):
2130 debug_uuid = uuid.createString()
2131 self._debug[debug_uuid] = None
2132 return xen_api_success(debug_uuid)
2134 def debug_destroy(self, session, debug_ref):
2135 del self._debug[debug_ref]
2136 return xen_api_success_void()
2138 def debug_get_record(self, session, debug_ref):
2139 return xen_api_success({'uuid': debug_ref})
2142 def list_all_methods(self, _):
2143 def _funcs():
2144 return [getattr(XendAPI, x) for x in XendAPI.__dict__]
2146 return xen_api_success([x.api for x in _funcs()
2147 if hasattr(x, 'api')])
2148 list_all_methods.api = '_UNSUPPORTED_list_all_methods'
2151 class XendAPIAsyncProxy:
2152 """ A redirector for Async.Class.function calls to XendAPI
2153 but wraps the call for use with the XendTaskManager.
2155 @ivar xenapi: Xen API instance
2156 @ivar method_map: Mapping from XMLRPC method name to callable objects.
2157 """
2159 method_prefix = 'Async.'
2161 def __init__(self, xenapi):
2162 """Initialises the Async Proxy by making a map of all
2163 implemented Xen API methods for use with XendTaskManager.
2165 @param xenapi: XendAPI instance
2166 """
2167 self.xenapi = xenapi
2168 self.method_map = {}
2169 for method_name in dir(self.xenapi):
2170 method = getattr(self.xenapi, method_name)
2171 if method_name[0] != '_' and hasattr(method, 'async') \
2172 and method.async == True:
2173 self.method_map[method.api] = method
2175 def _dispatch(self, method, args):
2176 """Overridden method so that SimpleXMLRPCServer will
2177 resolve methods through this method rather than through
2178 inspection.
2180 @param method: marshalled method name from XMLRPC.
2181 @param args: marshalled arguments from XMLRPC.
2182 """
2184 # Only deal with method names that start with "Async."
2185 if not method.startswith(self.method_prefix):
2186 return xen_api_error(['MESSAGE_METHOD_UNKNOWN', method])
2188 # Lookup synchronous version of the method
2189 synchronous_method_name = method[len(self.method_prefix):]
2190 if synchronous_method_name not in self.method_map:
2191 return xen_api_error(['MESSAGE_METHOD_UNKNOWN', method])
2193 method = self.method_map[synchronous_method_name]
2195 # Check that we've got enough arguments before issuing a task ID.
2196 needed = argcounts[method.api]
2197 if len(args) != needed:
2198 return xen_api_error(['MESSAGE_PARAMETER_COUNT_MISMATCH',
2199 self.method_prefix + method.api, needed,
2200 len(args)])
2202 # Validate the session before proceeding
2203 session = args[0]
2204 if not auth_manager().is_session_valid(session):
2205 return xen_api_error(['SESSION_INVALID', session])
2207 # create and execute the task, and return task_uuid
2208 return_type = getattr(method, 'return_type', None)
2209 task_uuid = XendTaskManager.create_task(method, args,
2210 synchronous_method_name,
2211 return_type,
2212 synchronous_method_name,
2213 session)
2214 return xen_api_success(task_uuid)
2217 # Auto generate some stubs based on XendAPI introspection
2219 if __name__ == "__main__":
2220 def output(line):
2221 print ' ' + line
2223 classes = ['VDI', 'SR']
2224 for cls in classes:
2225 ro_attrs = getattr(XendAPI, '%s_attr_ro' % cls, [])
2226 rw_attrs = getattr(XendAPI, '%s_attr_rw' % cls, [])
2227 methods = getattr(XendAPI, '%s_methods' % cls, [])
2228 funcs = getattr(XendAPI, '%s_funcs' % cls, [])
2230 ref = '%s_ref' % cls
2232 for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
2233 getter_name = '%s_get_%s' % (cls, attr_name)
2234 output('def %s(self, session, %s):' % (getter_name, ref))
2235 output(' return xen_api_todo()')
2237 for attr_name in rw_attrs + XendAPI.Base_attr_rw:
2238 setter_name = '%s_set_%s' % (cls, attr_name)
2239 output('def %s(self, session, %s, value):' % (setter_name, ref))
2240 output(' return xen_api_todo()')
2242 for method_name in methods + XendAPI.Base_methods:
2243 method_full_name = '%s_%s' % (cls,method_name)
2244 output('def %s(self, session, %s):' % (method_full_name, ref))
2245 output(' return xen_api_todo()')
2247 for func_name in funcs + XendAPI.Base_funcs:
2248 func_full_name = '%s_%s' % (cls, func_name)
2249 output('def %s(self, session):' % func_full_name)
2250 output(' return xen_api_todo()')