ia64/xen-unstable

view tools/python/xen/xend/XendAPI.py @ 14048:e0e300fda3f0

Remove host.create and host.destroy -- these never made any sense.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Tue Feb 20 22:46:21 2007 +0000 (2007-02-20)
parents 0aa6755159d5
children ee3ea729f5de
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.XendAuthSessions import instance as auth_manager
29 from xen.xend.XendError import *
30 from xen.xend.XendClient import ERROR_INVALID_DOMAIN
31 from xen.xend.XendLogging import log
32 from xen.xend.XendTask import XendTask
34 from xen.xend.XendAPIConstants import *
35 from xen.util.xmlrpclib2 import stringify
37 AUTH_NONE = 'none'
38 AUTH_PAM = 'pam'
40 argcounts = {}
42 # ------------------------------------------
43 # Utility Methods for Xen API Implementation
44 # ------------------------------------------
46 def xen_api_success(value):
47 """Wraps a return value in XenAPI format."""
48 if value is None:
49 s = ''
50 else:
51 s = stringify(value)
52 return {"Status": "Success", "Value": s}
54 def xen_api_success_void():
55 """Return success, but caller expects no return value."""
56 return xen_api_success("")
58 def xen_api_error(error):
59 """Wraps an error value in XenAPI format."""
60 if type(error) == tuple:
61 error = list(error)
62 if type(error) != list:
63 error = [error]
64 if len(error) == 0:
65 error = ['INTERNAL_ERROR', 'Empty list given to xen_api_error']
67 return { "Status": "Failure",
68 "ErrorDescription": [str(x) for x in error] }
71 def xen_api_todo():
72 """Temporary method to make sure we track down all the TODOs"""
73 return {"Status": "Error", "ErrorDescription": XEND_ERROR_TODO}
75 # ---------------------------------------------------
76 # Python Method Decorators for input value validation
77 # ---------------------------------------------------
79 def trace(func, api_name = ''):
80 """Decorator to trace XMLRPC Xen API methods.
82 @param func: function with any parameters
83 @param api_name: name of the api call for debugging.
84 """
85 if hasattr(func, 'api'):
86 api_name = func.api
87 def trace_func(self, *args, **kwargs):
88 log.debug('%s: %s' % (api_name, args))
89 return func(self, *args, **kwargs)
90 trace_func.api = api_name
91 return trace_func
94 def catch_typeerror(func):
95 """Decorator to catch any TypeErrors and translate them into Xen-API
96 errors.
98 @param func: function with params: (self, ...)
99 @rtype: callable object
100 """
101 def f(self, *args, **kwargs):
102 try:
103 return func(self, *args, **kwargs)
104 except TypeError, exn:
105 #log.exception('catch_typeerror')
106 if hasattr(func, 'api') and func.api in argcounts:
107 # Assume that if the exception was thrown inside this
108 # file, then it is due to an invalid call from the client,
109 # but if it was thrown elsewhere, then it's an internal
110 # error (which will be handled further up).
111 tb = sys.exc_info()[2]
112 try:
113 sourcefile = traceback.extract_tb(tb)[-1][0]
114 if sourcefile == inspect.getsourcefile(XendAPI):
115 return xen_api_error(
116 ['MESSAGE_PARAMETER_COUNT_MISMATCH',
117 func.api, argcounts[func.api],
118 len(args) + len(kwargs)])
119 finally:
120 del tb
121 raise
123 return f
126 def session_required(func):
127 """Decorator to verify if session is valid before calling method.
129 @param func: function with params: (self, session, ...)
130 @rtype: callable object
131 """
132 def check_session(self, session, *args, **kwargs):
133 if auth_manager().is_session_valid(session):
134 return func(self, session, *args, **kwargs)
135 else:
136 return xen_api_error(['SESSION_INVALID', session])
138 return check_session
141 def _is_valid_ref(ref, validator):
142 return type(ref) == str and validator(ref)
144 def _check_ref(validator, clas, func, api, session, ref, *args, **kwargs):
145 if _is_valid_ref(ref, validator):
146 return func(api, session, ref, *args, **kwargs)
147 else:
148 return xen_api_error(['HANDLE_INVALID', clas, ref])
151 def valid_host(func):
152 """Decorator to verify if host_ref is valid before calling method.
154 @param func: function with params: (self, session, host_ref, ...)
155 @rtype: callable object
156 """
157 return lambda *args, **kwargs: \
158 _check_ref(XendNode.instance().is_valid_host,
159 'host', func, *args, **kwargs)
161 def valid_host_metrics(func):
162 """Decorator to verify if host_metrics_ref is valid before calling
163 method.
165 @param func: function with params: (self, session, host_metrics_ref)
166 @rtype: callable object
167 """
168 return lambda *args, **kwargs: \
169 _check_ref(lambda r: r == XendNode.instance().host_metrics_uuid,
170 'host_metrics', func, *args, **kwargs)
172 def valid_host_cpu(func):
173 """Decorator to verify if host_cpu_ref is valid before calling method.
175 @param func: function with params: (self, session, host_cpu_ref, ...)
176 @rtype: callable object
177 """
178 return lambda *args, **kwargs: \
179 _check_ref(XendNode.instance().is_valid_cpu,
180 'host_cpu', func, *args, **kwargs)
182 def valid_vm(func):
183 """Decorator to verify if vm_ref is valid before calling method.
185 @param func: function with params: (self, session, vm_ref, ...)
186 @rtype: callable object
187 """
188 return lambda *args, **kwargs: \
189 _check_ref(XendDomain.instance().is_valid_vm,
190 'VM', func, *args, **kwargs)
192 def valid_network(func):
193 """Decorator to verify if network_ref is valid before calling method.
195 @param func: function with params: (self, session, network_ref, ...)
196 @rtype: callable object
197 """
198 return lambda *args, **kwargs: \
199 _check_ref(XendNode.instance().is_valid_network,
200 'network', func, *args, **kwargs)
202 def valid_vbd(func):
203 """Decorator to verify if vbd_ref is valid before calling method.
205 @param func: function with params: (self, session, vbd_ref, ...)
206 @rtype: callable object
207 """
208 return lambda *args, **kwargs: \
209 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vbd', r),
210 'VBD', func, *args, **kwargs)
212 def valid_vbd_metrics(func):
213 """Decorator to verify if ref is valid before calling method.
215 @param func: function with params: (self, session, ref, ...)
216 @rtype: callable object
217 """
218 return lambda *args, **kwargs: \
219 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vbd', r),
220 'VBD_metrics', func, *args, **kwargs)
222 def valid_vif(func):
223 """Decorator to verify if vif_ref is valid before calling method.
225 @param func: function with params: (self, session, vif_ref, ...)
226 @rtype: callable object
227 """
228 return lambda *args, **kwargs: \
229 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vif', r),
230 'VIF', func, *args, **kwargs)
232 def valid_vif_metrics(func):
233 """Decorator to verify if ref is valid before calling method.
235 @param func: function with params: (self, session, ref, ...)
236 @rtype: callable object
237 """
238 return lambda *args, **kwargs: \
239 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vif', r),
240 'VIF_metrics', func, *args, **kwargs)
242 def valid_vdi(func):
243 """Decorator to verify if vdi_ref is valid before calling method.
245 @param func: function with params: (self, session, vdi_ref, ...)
246 @rtype: callable object
247 """
248 return lambda *args, **kwargs: \
249 _check_ref(XendNode.instance().is_valid_vdi,
250 'VDI', func, *args, **kwargs)
252 def valid_vtpm(func):
253 """Decorator to verify if vtpm_ref is valid before calling method.
255 @param func: function with params: (self, session, vtpm_ref, ...)
256 @rtype: callable object
257 """
258 return lambda *args, **kwargs: \
259 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vtpm', r),
260 'VTPM', func, *args, **kwargs)
263 def valid_console(func):
264 """Decorator to verify if console_ref is valid before calling method.
266 @param func: function with params: (self, session, console_ref, ...)
267 @rtype: callable object
268 """
269 return lambda *args, **kwargs: \
270 _check_ref(lambda r: XendDomain.instance().is_valid_dev('console',
271 r),
272 'console', func, *args, **kwargs)
274 def valid_sr(func):
275 """Decorator to verify if sr_ref is valid before calling method.
277 @param func: function with params: (self, session, sr_ref, ...)
278 @rtype: callable object
279 """
280 return lambda *args, **kwargs: \
281 _check_ref(lambda r: XendNode.instance().is_valid_sr,
282 'SR', func, *args, **kwargs)
284 def valid_pif(func):
285 """Decorator to verify if pif_ref is valid before calling
286 method.
288 @param func: function with params: (self, session, pif_ref)
289 @rtype: callable object
290 """
291 return lambda *args, **kwargs: \
292 _check_ref(lambda r: r in XendNode.instance().pifs,
293 'PIF', func, *args, **kwargs)
295 def valid_pif_metrics(func):
296 """Decorator to verify if pif_metrics_ref is valid before calling
297 method.
299 @param func: function with params: (self, session, pif_metrics_ref)
300 @rtype: callable object
301 """
302 return lambda *args, **kwargs: \
303 _check_ref(lambda r: r in XendNode.instance().pif_metrics,
304 'PIF_metrics', func, *args, **kwargs)
306 def valid_task(func):
307 """Decorator to verify if task_ref is valid before calling
308 method.
310 @param func: function with params: (self, session, task_ref)
311 @rtype: callable object
312 """
313 return lambda *args, **kwargs: \
314 _check_ref(XendTaskManager.get_task,
315 'task', func, *args, **kwargs)
317 def valid_debug(func):
318 """Decorator to verify if task_ref is valid before calling
319 method.
321 @param func: function with params: (self, session, task_ref)
322 @rtype: callable object
323 """
324 return lambda *args, **kwargs: \
325 _check_ref(lambda r: r in XendAPI._debug,
326 'debug', func, *args, **kwargs)
328 # -----------------------------
329 # Bridge to Legacy XM API calls
330 # -----------------------------
332 def do_vm_func(fn_name, vm_ref, *args, **kwargs):
333 """Helper wrapper func to abstract away from repetitive code.
335 @param fn_name: function name for XendDomain instance
336 @type fn_name: string
337 @param vm_ref: vm_ref
338 @type vm_ref: string
339 @param *args: more arguments
340 @type *args: tuple
341 """
342 try:
343 xendom = XendDomain.instance()
344 fn = getattr(xendom, fn_name)
345 xendom.do_legacy_api_with_uuid(fn, vm_ref, *args, **kwargs)
346 return xen_api_success_void()
347 except VMBadState, exn:
348 return xen_api_error(['VM_BAD_POWER_STATE', vm_ref, exn.expected,
349 exn.actual])
352 class XendAPI(object):
353 """Implementation of the Xen-API in Xend. Expects to be
354 used via XMLRPCServer.
356 All methods that need a valid session are marked with
357 a L{session_required} decorator that will
358 transparently perform the required session authentication.
360 We need to support Python <2.4, so we use the old decorator syntax.
362 All XMLRPC accessible methods require an 'api' attribute and
363 is set to the XMLRPC function name which the method implements.
364 """
366 __decorated__ = False
367 __init_lock__ = threading.Lock()
368 _debug = {}
370 def __new__(cls, *args, **kwds):
371 """ Override __new__ to decorate the class only once.
373 Lock to make sure the classes are not decorated twice.
374 """
375 cls.__init_lock__.acquire()
376 try:
377 if not cls.__decorated__:
378 cls._decorate()
379 cls.__decorated__ = True
381 return object.__new__(cls, *args, **kwds)
382 finally:
383 cls.__init_lock__.release()
385 def _decorate(cls):
386 """ Decorate all the object methods to have validators
387 and appropriate function attributes.
389 This should only be executed once for the duration of the
390 server.
391 """
392 global_validators = [session_required, catch_typeerror]
393 classes = {
394 'session' : None,
395 'host' : valid_host,
396 'host_cpu' : valid_host_cpu,
397 'host_metrics' : valid_host_metrics,
398 'network' : valid_network,
399 'VM' : valid_vm,
400 'VBD' : valid_vbd,
401 'VBD_metrics' : valid_vbd_metrics,
402 'VIF' : valid_vif,
403 'VIF_metrics' : valid_vif_metrics,
404 'VDI' : valid_vdi,
405 'VTPM' : valid_vtpm,
406 'console' : valid_console,
407 'SR' : valid_sr,
408 'PIF' : valid_pif,
409 'PIF_metrics' : valid_pif_metrics,
410 'task' : valid_task,
411 'debug' : valid_debug,
412 }
414 # Cheat methods
415 # -------------
416 # Methods that have a trivial implementation for all classes.
417 # 1. get_by_uuid == getting by ref, so just return uuid for
418 # all get_by_uuid() methods.
420 for api_cls in classes.keys():
421 if api_cls == 'session':
422 continue
424 get_by_uuid = '%s_get_by_uuid' % api_cls
425 get_uuid = '%s_get_uuid' % api_cls
426 def _get_by_uuid(_1, _2, ref):
427 return xen_api_success(ref)
429 def _get_uuid(_1, _2, ref):
430 return xen_api_success(ref)
432 setattr(cls, get_by_uuid, _get_by_uuid)
433 setattr(cls, get_uuid, _get_uuid)
435 # Wrapping validators around XMLRPC calls
436 # ---------------------------------------
438 for api_cls, validator in classes.items():
439 def doit(n, takes_instance, async_support = False,
440 return_type = None):
441 n_ = n.replace('.', '_')
442 try:
443 f = getattr(cls, n_)
444 argcounts[n] = f.func_code.co_argcount - 1
446 validators = takes_instance and validator and \
447 [validator] or []
449 validators += global_validators
450 for v in validators:
451 f = v(f)
452 f.api = n
453 f.async = async_support
454 if return_type:
455 f.return_type = return_type
457 setattr(cls, n_, f)
458 except AttributeError:
459 log.warn("API call: %s not found" % n)
462 ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
463 rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
464 methods = getattr(cls, '%s_methods' % api_cls, [])
465 funcs = getattr(cls, '%s_funcs' % api_cls, [])
467 # wrap validators around readable class attributes
468 for attr_name in ro_attrs + rw_attrs + cls.Base_attr_ro:
469 doit('%s.get_%s' % (api_cls, attr_name), True,
470 async_support = False)
472 # wrap validators around writable class attrributes
473 for attr_name in rw_attrs + cls.Base_attr_rw:
474 doit('%s.set_%s' % (api_cls, attr_name), True,
475 async_support = False)
477 # wrap validators around methods
478 for method_name, return_type in methods + cls.Base_methods:
479 doit('%s.%s' % (api_cls, method_name), True,
480 async_support = True)
482 # wrap validators around class functions
483 for func_name, return_type in funcs + cls.Base_funcs:
484 doit('%s.%s' % (api_cls, func_name), False, async_support = True,
485 return_type = return_type)
487 _decorate = classmethod(_decorate)
489 def __init__(self, auth):
490 self.auth = auth
492 Base_attr_ro = ['uuid']
493 Base_attr_rw = []
494 Base_methods = [('destroy', None), ('get_record', 'Struct')]
495 Base_funcs = [('get_all', 'Set'), ('get_by_uuid', None)]
497 # Xen API: Class Session
498 # ----------------------------------------------------------------
499 # NOTE: Left unwrapped by __init__
501 session_attr_ro = ['this_host', 'this_user']
502 session_methods = [('logout', None)]
504 def session_login_with_password(self, *args):
505 if len(args) != 2:
506 return xen_api_error(
507 ['MESSAGE_PARAMETER_COUNT_MISMATCH',
508 'session.login_with_password', 2, len(args)])
509 username = args[0]
510 password = args[1]
511 try:
512 session = (self.auth == AUTH_NONE and
513 auth_manager().login_unconditionally(username) or
514 auth_manager().login_with_password(username, password))
515 return xen_api_success(session)
516 except XendError, e:
517 return xen_api_error(['SESSION_AUTHENTICATION_FAILED'])
518 session_login_with_password.api = 'session.login_with_password'
520 # object methods
521 def session_logout(self, session):
522 auth_manager().logout(session)
523 return xen_api_success_void()
524 def session_get_record(self, session):
525 record = {'uuid' : session,
526 'this_host': XendNode.instance().uuid,
527 'this_user': auth_manager().get_user(session)}
528 return xen_api_success(record)
530 def session_get_uuid(self, session):
531 return xen_api_success(session)
533 def session_get_by_uuid(self, session):
534 return xen_api_success(session)
536 # attributes (ro)
537 def session_get_this_host(self, session):
538 return xen_api_success(XendNode.instance().uuid)
539 def session_get_this_user(self, session):
540 user = auth_manager().get_user(session)
541 if user:
542 return xen_api_success(user)
543 return xen_api_error(['SESSION_INVALID', session])
546 # Xen API: Class User
547 # ----------------------------------------------------------------
548 # TODO: NOT IMPLEMENTED YET
550 # Xen API: Class Tasks
551 # ----------------------------------------------------------------
553 task_attr_ro = ['name_label',
554 'name_description',
555 'status',
556 'progress',
557 'type',
558 'result',
559 'error_code',
560 'error_info',
561 'allowed_operations',
562 'session'
563 ]
565 task_attr_rw = []
567 task_funcs = [('get_by_name_label', 'Set(task)'),
568 ('cancel', None)]
570 def task_get_name_label(self, session, task_ref):
571 task = XendTaskManager.get_task(task_ref)
572 return xen_api_success(task.name_label)
574 def task_get_name_description(self, session, task_ref):
575 task = XendTaskManager.get_task(task_ref)
576 return xen_api_success(task.name_description)
578 def task_get_status(self, session, task_ref):
579 task = XendTaskManager.get_task(task_ref)
580 return xen_api_success(task.get_status())
582 def task_get_progress(self, session, task_ref):
583 task = XendTaskManager.get_task(task_ref)
584 return xen_api_success(task.progress)
586 def task_get_type(self, session, task_ref):
587 task = XendTaskManager.get_task(task_ref)
588 return xen_api_success(task.type)
590 def task_get_result(self, session, task_ref):
591 task = XendTaskManager.get_task(task_ref)
592 return xen_api_success(task.result)
594 def task_get_error_code(self, session, task_ref):
595 task = XendTaskManager.get_task(task_ref)
596 return xen_api_success(task.error_code)
598 def task_get_error_info(self, session, task_ref):
599 task = XendTaskManager.get_task(task_ref)
600 return xen_api_success(task.error_info)
602 def task_get_allowed_operations(self, session, task_ref):
603 return xen_api_success({})
605 def task_get_session(self, session, task_ref):
606 task = XendTaskManager.get_task(task_ref)
607 return xen_api_success(task.session)
609 def task_get_all(self, session):
610 tasks = XendTaskManager.get_all_tasks()
611 return xen_api_success(tasks)
613 def task_get_record(self, session, task_ref):
614 task = XendTaskManager.get_task(task_ref)
615 return xen_api_success(task.get_record())
617 def task_cancel(self, session, task_ref):
618 return xen_api_error('OPERATION_NOT_ALLOWED')
620 def task_get_by_name_label(self, session, name):
621 return xen_api_success(XendTaskManager.get_task_by_name(name))
623 # Xen API: Class host
624 # ----------------------------------------------------------------
626 host_attr_ro = ['software_version',
627 'resident_VMs',
628 'host_CPUs',
629 'metrics']
631 host_attr_rw = ['name_label',
632 'name_description',
633 'other_config']
635 host_methods = [('disable', None),
636 ('enable', None),
637 ('reboot', None),
638 ('shutdown', None),
639 ('add_to_other_config', None),
640 ('remove_from_other_config', None),
641 ('dmesg', 'String')]
643 host_funcs = [('get_by_name_label', 'Set(host)')]
645 # attributes
646 def host_get_name_label(self, session, host_ref):
647 return xen_api_success(XendNode.instance().name)
648 def host_set_name_label(self, session, host_ref, new_name):
649 XendNode.instance().set_name(new_name)
650 return xen_api_success_void()
651 def host_get_name_description(self, session, host_ref):
652 return xen_api_success(XendNode.instance().description)
653 def host_set_name_description(self, session, host_ref, new_desc):
654 XendNode.instance().set_description(new_desc)
655 return xen_api_success_void()
656 def host_get_other_config(self, session, host_ref):
657 return xen_api_success(XendNode.instance().other_config)
658 def host_set_other_config(self, session, host_ref, other_config):
659 node = XendNode.instance()
660 node.other_config = dict(other_config)
661 node.save()
662 return xen_api_success_void()
663 def host_add_to_other_config(self, session, host_ref, key, value):
664 node = XendNode.instance()
665 node.other_config[key] = value
666 node.save()
667 return xen_api_success_void()
668 def host_remove_from_other_config(self, session, host_ref, key):
669 node = XendNode.instance()
670 del node.other_config[key]
671 node.save()
672 return xen_api_success_void()
673 def host_get_software_version(self, session, host_ref):
674 return xen_api_success(XendNode.instance().xen_version())
675 def host_get_resident_VMs(self, session, host_ref):
676 return xen_api_success(XendDomain.instance().get_domain_refs())
677 def host_get_host_CPUs(self, session, host_ref):
678 return xen_api_success(XendNode.instance().get_host_cpu_refs())
679 def host_get_metrics(self, _, ref):
680 return xen_api_success(XendNode.instance().host_metrics_uuid)
682 # object methods
683 def host_disable(self, session, host_ref):
684 XendDomain.instance().set_allow_new_domains(False)
685 return xen_api_success_void()
686 def host_enable(self, session, host_ref):
687 XendDomain.instance().set_allow_new_domains(True)
688 return xen_api_success_void()
689 def host_reboot(self, session, host_ref):
690 if not XendDomain.instance().allow_new_domains():
691 return xen_api_error(XEND_ERROR_HOST_RUNNING)
692 return xen_api_error(XEND_ERROR_UNSUPPORTED)
693 def host_shutdown(self, session, host_ref):
694 if not XendDomain.instance().allow_new_domains():
695 return xen_api_error(XEND_ERROR_HOST_RUNNING)
696 return xen_api_error(XEND_ERROR_UNSUPPORTED)
698 def host_dmesg(self, session, host_ref):
699 return xen_api_success(XendDmesg.instance().info())
701 def host_get_record(self, session, host_ref):
702 node = XendNode.instance()
703 dom = XendDomain.instance()
704 record = {'uuid': node.uuid,
705 'name_label': node.name,
706 'name_description': '',
707 'software_version': node.xen_version(),
708 'resident_VMs': dom.get_domain_refs(),
709 'host_CPUs': node.get_host_cpu_refs(),
710 'metrics': node.host_metrics_uuid}
711 return xen_api_success(record)
713 # class methods
714 def host_get_all(self, session):
715 return xen_api_success((XendNode.instance().uuid,))
716 def host_get_by_name_label(self, session, name):
717 if XendNode.instance().name == name:
718 return xen_api_success((XendNode.instance().uuid,))
719 return xen_api_success([])
722 # Xen API: Class host_CPU
723 # ----------------------------------------------------------------
725 host_cpu_attr_ro = ['host',
726 'number',
727 'utilisation']
729 # attributes
730 def host_cpu_get_host(self, session, host_cpu_ref):
731 return xen_api_success(XendNode.instance().uuid)
732 def host_cpu_get_utilisation(self, session, host_cpu_ref):
733 util = XendNode.instance().get_host_cpu_load(host_cpu_ref)
734 return xen_api_success(util)
735 def host_cpu_get_number(self, session, host_cpu_ref):
736 num = XendNode.instance().get_host_cpu_number(host_cpu_ref)
737 return xen_api_success(num)
739 # object methods
740 def host_cpu_destroy(self, session, host_cpu_ref):
741 return xen_api_error(XEND_ERROR_UNSUPPORTED)
742 def host_cpu_get_record(self, session, host_cpu_ref):
743 node = XendNode.instance()
744 record = {'uuid': host_cpu_ref,
745 'host': node.uuid,
746 'number': node.get_host_cpu_number(host_cpu_ref),
747 'utilisation': node.get_host_cpu_load(host_cpu_ref)}
748 return xen_api_success(record)
750 # class methods
751 def host_cpu_get_all(self, session):
752 return xen_api_success(XendNode.instance().get_host_cpu_refs())
755 # Xen API: Class host_metrics
756 # ----------------------------------------------------------------
758 host_metrics_attr_ro = ['memory_total',
759 'memory_free',
760 'host']
761 host_metrics_attr_rw = []
762 host_metrics_methods = []
764 def _host_metrics_get(self, ref, f):
765 return xen_api_success(getattr(node, f)())
767 def host_metrics_get_record(self, _, ref):
768 return xen_api_success({
769 'uuid' : ref,
770 'host' : XendNode.instance().uuid,
771 'memory_total' : self._host_metrics_get_memory_total(),
772 'memory_free' : self._host_metrics_get_memory_free(),
773 })
775 def host_metrics_get_host(self, _, ref):
776 return xen_api_success(XendNode.instance().uuid)
778 def host_metrics_get_memory_total(self, _, ref):
779 return xen_api_success(self._host_metrics_get_memory_total())
781 def host_metrics_get_memory_free(self, _, ref):
782 return xen_api_success(self._host_metrics_get_memory_free())
784 def _host_metrics_get_memory_total(self):
785 node = XendNode.instance()
786 return node.xc.physinfo()['total_memory'] * 1024
788 def _host_metrics_get_memory_free(self):
789 node = XendNode.instance()
790 return node.xc.physinfo()['free_memory'] * 1024
793 # Xen API: Class network
794 # ----------------------------------------------------------------
796 network_attr_ro = ['VIFs', 'PIFs']
797 network_attr_rw = ['name_label',
798 'name_description',
799 'default_gateway',
800 'default_netmask']
802 network_funcs = [('create', 'network')]
804 def network_create(self, _, name_label, name_description,
805 default_gateway, default_netmask):
806 return xen_api_success(
807 XendNode.instance().network_create(name_label, name_description,
808 default_gateway,
809 default_netmask))
811 def network_destroy(self, _, ref):
812 return xen_api_success(XendNode.instance().network_destroy(ref))
814 def _get_network(self, ref):
815 return XendNode.instance().get_network(ref)
817 def network_get_all(self, _):
818 return xen_api_success(XendNode.instance().get_network_refs())
820 def network_get_record(self, _, ref):
821 return xen_api_success(
822 XendNode.instance().get_network(ref).get_record())
824 def network_get_name_label(self, _, ref):
825 return xen_api_success(self._get_network(ref).name_label)
827 def network_get_name_description(self, _, ref):
828 return xen_api_success(self._get_network(ref).name_description)
830 def network_get_default_gateway(self, _, ref):
831 return xen_api_success(self._get_network(ref).default_gateway)
833 def network_get_default_netmask(self, _, ref):
834 return xen_api_success(self._get_network(ref).default_netmask)
836 def network_get_VIFs(self, _, ref):
837 return xen_api_success(self._get_network(ref).get_VIF_UUIDs())
839 def network_get_PIFs(self, session, ref):
840 return xen_api_success(self._get_network(ref).get_PIF_UUIDs())
842 def network_set_name_label(self, _, ref, val):
843 return xen_api_success(self._get_network(ref).set_name_label(val))
845 def network_set_name_description(self, _, ref, val):
846 return xen_api_success(self._get_network(ref).set_name_description(val))
848 def network_set_default_gateway(self, _, ref, val):
849 return xen_api_success(self._get_network(ref).set_default_gateway(val))
851 def network_set_default_netmask(self, _, ref, val):
852 return xen_api_success(self._get_network(ref).set_default_netmask(val))
855 # Xen API: Class PIF
856 # ----------------------------------------------------------------
858 PIF_attr_ro = ['metrics']
859 PIF_attr_rw = ['device',
860 'network',
861 'host',
862 'MAC',
863 'MTU',
864 'VLAN']
866 PIF_attr_inst = PIF_attr_rw
868 PIF_methods = [('create_VLAN', 'int')]
870 def _get_PIF(self, ref):
871 return XendNode.instance().pifs[ref]
873 def PIF_destroy(self, _, ref):
874 try:
875 return xen_api_success(XendNode.instance().PIF_destroy(ref))
876 except PIFIsPhysical, exn:
877 return xen_api_error(['PIF_IS_PHYSICAL', ref])
879 # object methods
880 def PIF_get_record(self, _, ref):
881 return xen_api_success(self._get_PIF(ref).get_record())
883 def PIF_get_all(self, _):
884 return xen_api_success(XendNode.instance().pifs.keys())
886 def PIF_get_metrics(self, _, ref):
887 return xen_api_success(self._get_PIF(ref).metrics.uuid)
889 def PIF_get_device(self, _, ref):
890 return xen_api_success(self._get_PIF(ref).device)
892 def PIF_get_network(self, _, ref):
893 return xen_api_success(self._get_PIF(ref).network.uuid)
895 def PIF_get_host(self, _, ref):
896 return xen_api_success(self._get_PIF(ref).host.uuid)
898 def PIF_get_MAC(self, _, ref):
899 return xen_api_success(self._get_PIF(ref).mac)
901 def PIF_get_MTU(self, _, ref):
902 return xen_api_success(self._get_PIF(ref).mtu)
904 def PIF_get_VLAN(self, _, ref):
905 return xen_api_success(self._get_PIF(ref).vlan)
907 def PIF_set_device(self, _, ref, device):
908 return xen_api_success(self._get_PIF(ref).set_device(device))
910 def PIF_set_MAC(self, _, ref, mac):
911 return xen_api_success(self._get_PIF(ref).set_mac(mac))
913 def PIF_set_MTU(self, _, ref, mtu):
914 return xen_api_success(self._get_PIF(ref).set_mtu(mtu))
916 def PIF_create_VLAN(self, _, ref, network, vlan):
917 try:
918 vlan = int(vlan)
919 except:
920 return xen_api_error(['VLAN_TAG_INVALID', vlan])
922 try:
923 node = XendNode.instance()
925 if _is_valid_ref(network, node.is_valid_network):
926 return xen_api_success(
927 node.PIF_create_VLAN(ref, network, vlan))
928 else:
929 return xen_api_error(['HANDLE_INVALID', 'network', network])
930 except NetworkAlreadyConnected, exn:
931 return xen_api_error(['NETWORK_ALREADY_CONNECTED',
932 network, exn.pif_uuid])
933 except VLANTagInvalid:
934 return xen_api_error(['VLAN_TAG_INVALID', vlan])
937 # Xen API: Class PIF_metrics
938 # ----------------------------------------------------------------
940 PIF_metrics_attr_ro = ['PIF',
941 'io_read_kbs',
942 'io_write_kbs']
943 PIF_metrics_attr_rw = []
944 PIF_methods = []
946 def _PIF_metrics_get(self, ref):
947 return XendNode.instance().pif_metrics[ref]
949 def PIF_metrics_get_record(self, _, ref):
950 return xen_api_success(self._PIF_metrics_get(ref).get_record())
952 def PIF_metrics_get_PIF(self, _, ref):
953 return xen_api_success(self._PIF_metrics_get(ref).pif.uuid)
955 def PIF_metrics_get_io_read_kbs(self, _, ref):
956 return xen_api_success(self._PIF_metrics_get(ref).get_io_read_kbs())
958 def PIF_metrics_get_io_write_kbs(self, _, ref):
959 return xen_api_success(self._PIF_metrics_get(ref).get_io_write_kbs())
962 # Xen API: Class VM
963 # ----------------------------------------------------------------
965 VM_attr_ro = ['power_state',
966 'resident_on',
967 'memory_actual',
968 'memory_static_max',
969 'memory_static_min',
970 'VCPUs_number',
971 'VCPUs_utilisation',
972 'consoles',
973 'VIFs',
974 'VBDs',
975 'VTPMs',
976 'PCI_bus',
977 'tools_version',
978 'is_control_domain',
979 ]
981 VM_attr_rw = ['name_label',
982 'name_description',
983 'user_version',
984 'is_a_template',
985 'auto_power_on',
986 'memory_dynamic_max',
987 'memory_dynamic_min',
988 'VCPUs_policy',
989 'VCPUs_params',
990 'actions_after_shutdown',
991 'actions_after_reboot',
992 'actions_after_suspend',
993 'actions_after_crash',
994 'PV_bootloader',
995 'PV_kernel',
996 'PV_ramdisk',
997 'PV_args',
998 'PV_bootloader_args',
999 'HVM_boot_policy',
1000 'HVM_boot_params',
1001 'platform_std_VGA',
1002 'platform_serial',
1003 'platform_localtime',
1004 'platform_clock_offset',
1005 'platform_enable_audio',
1006 'platform_keymap',
1007 'other_config']
1009 VM_methods = [('clone', 'VM'),
1010 ('start', None),
1011 ('pause', None),
1012 ('unpause', None),
1013 ('clean_shutdown', None),
1014 ('clean_reboot', None),
1015 ('hard_shutdown', None),
1016 ('hard_reboot', None),
1017 ('suspend', None),
1018 ('resume', None),
1019 ('add_to_other_config', None),
1020 ('remove_from_other_config', None)]
1022 VM_funcs = [('create', 'VM'),
1023 ('get_by_name_label', 'Set(VM)')]
1025 # parameters required for _create()
1026 VM_attr_inst = [
1027 'name_label',
1028 'name_description',
1029 'user_version',
1030 'is_a_template',
1031 'memory_static_max',
1032 'memory_dynamic_max',
1033 'memory_dynamic_min',
1034 'memory_static_min',
1035 'VCPUs_policy',
1036 'VCPUs_params',
1037 'actions_after_shutdown',
1038 'actions_after_reboot',
1039 'actions_after_suspend',
1040 'actions_after_crash',
1041 'PV_bootloader',
1042 'PV_kernel',
1043 'PV_ramdisk',
1044 'PV_args',
1045 'PV_bootloader_args',
1046 'HVM_boot_policy',
1047 'HVM_boot_params',
1048 'platform_std_VGA',
1049 'platform_serial',
1050 'platform_localtime',
1051 'platform_clock_offset',
1052 'platform_enable_audio',
1053 'platform_keymap',
1054 'grub_cmdline',
1055 'PCI_bus',
1056 'other_config']
1058 def VM_get(self, name, session, vm_ref):
1059 return xen_api_success(
1060 XendDomain.instance().get_vm_by_uuid(vm_ref).info[name])
1062 def VM_set(self, name, session, vm_ref, value):
1063 xd = XendDomain.instance()
1064 dominfo = xd.get_vm_by_uuid(vm_ref)
1065 dominfo.info[name] = value
1066 xd.managed_config_save(dominfo)
1067 return xen_api_success_void()
1069 # attributes (ro)
1070 def VM_get_power_state(self, session, vm_ref):
1071 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1072 return xen_api_success(dom.get_power_state())
1074 def VM_get_resident_on(self, session, vm_ref):
1075 return xen_api_success(XendNode.instance().uuid)
1077 def VM_get_memory_actual(self, session, vm_ref):
1078 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1079 return xen_api_todo() # unsupported by xc
1081 def VM_get_memory_static_max(self, session, vm_ref):
1082 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1083 return xen_api_success(dom.get_memory_static_max())
1085 def VM_get_memory_static_min(self, session, vm_ref):
1086 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1087 return xen_api_success(dom.get_memory_static_min())
1089 def VM_get_VCPUs_number(self, session, vm_ref):
1090 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1091 return xen_api_success(dom.getVCpuCount())
1093 def VM_get_VCPUs_utilisation(self, session, vm_ref):
1094 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1095 return xen_api_success(dom.get_vcpus_util())
1097 def VM_get_VIFs(self, session, vm_ref):
1098 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1099 return xen_api_success(dom.get_vifs())
1101 def VM_get_VBDs(self, session, vm_ref):
1102 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1103 return xen_api_success(dom.get_vbds())
1105 def VM_get_VTPMs(self, session, vm_ref):
1106 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1107 return xen_api_success(dom.get_vtpms())
1109 def VM_get_consoles(self, session, vm_ref):
1110 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1111 return xen_api_success(dom.get_consoles())
1113 def VM_get_PCI_bus(self, session, vm_ref):
1114 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1115 return dom.get_pci_bus()
1117 def VM_get_tools_version(self, session, vm_ref):
1118 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1119 return dom.get_tools_version()
1121 # attributes (rw)
1122 def VM_get_name_label(self, session, vm_ref):
1123 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1124 return xen_api_success(dom.getName())
1126 def VM_get_name_description(self, session, vm_ref):
1127 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1128 return xen_api_todo()
1130 def VM_get_user_version(self, session, vm_ref):
1131 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1132 return xen_api_todo()
1134 def VM_get_is_a_template(self, session, vm_ref):
1135 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1136 return xen_api_todo()
1138 def VM_get_memory_dynamic_max(self, session, vm_ref):
1139 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1140 return xen_api_success(dom.get_memory_dynamic_max())
1142 def VM_get_memory_dynamic_min(self, session, vm_ref):
1143 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1144 return xen_api_success(dom.get_memory_dynamic_min())
1146 def VM_get_VCPUs_policy(self, session, vm_ref):
1147 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1148 return xen_api_success(dom.get_vcpus_policy())
1150 def VM_get_VCPUs_params(self, session, vm_ref):
1151 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1152 return xen_api_success(dom.get_vcpus_params())
1154 def VM_get_actions_after_shutdown(self, session, vm_ref):
1155 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1156 return xen_api_success(dom.get_on_shutdown())
1158 def VM_get_actions_after_reboot(self, session, vm_ref):
1159 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1160 return xen_api_success(dom.get_on_reboot())
1162 def VM_get_actions_after_suspend(self, session, vm_ref):
1163 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1164 return xen_api_success(dom.get_on_suspend())
1166 def VM_get_actions_after_crash(self, session, vm_ref):
1167 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1168 return xen_api_success(dom.get_on_crash())
1170 def VM_get_PV_bootloader(self, session, vm_ref):
1171 return self.VM_get('PV_bootloader', session, vm_ref)
1173 def VM_get_PV_kernel(self, session, vm_ref):
1174 return self.VM_get('PV_kernel', session, vm_ref)
1176 def VM_get_PV_ramdisk(self, session, vm_ref):
1177 return self.VM_get('PV_ramdisk', session, vm_ref)
1179 def VM_get_PV_args(self, session, vm_ref):
1180 return self.VM_get('PV_args', session, vm_ref)
1182 def VM_get_PV_bootloader_args(self, session, vm_ref):
1183 return self.VM_get('PV_bootloader_args', session, vm_ref)
1185 def VM_get_HVM_boot_policy(self, session, vm_ref):
1186 return self.VM_get('HVM_boot_policy', session, vm_ref)
1188 def VM_get_HVM_boot_params(self, session, vm_ref):
1189 return self.VM_get('HVM_boot_params', session, vm_ref)
1191 def VM_get_platform_std_VGA(self, session, vm_ref):
1192 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1193 return xen_api_success(dom.get_platform_std_vga())
1195 def VM_get_platform_serial(self, session, vm_ref):
1196 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1197 return xen_api_success(dom.get_platform_serial())
1199 def VM_get_platform_localtime(self, session, vm_ref):
1200 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1201 return xen_api_success(dom.get_platform_localtime())
1203 def VM_get_platform_clock_offset(self, session, vm_ref):
1204 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1205 return xen_api_success(dom.get_platform_clock_offset())
1207 def VM_get_platform_enable_audio(self, session, vm_ref):
1208 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1209 return xen_api_success(dom.get_platform_enable_audio())
1211 def VM_get_platform_keymap(self, session, vm_ref):
1212 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1213 return xen_api_success(dom.get_platform_keymap())
1215 def VM_get_other_config(self, session, vm_ref):
1216 return self.VM_get('other_config', session, vm_ref)
1218 def VM_get_is_control_domain(self, session, vm_ref):
1219 xd = XendDomain.instance()
1220 return xen_api_success(
1221 xd.get_vm_by_uuid(vm_ref) == xd.privilegedDomain())
1223 def VM_set_name_label(self, session, vm_ref, label):
1224 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1225 dom.setName(label)
1226 return xen_api_success_void()
1228 def VM_set_name_description(self, session, vm_ref, desc):
1229 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1230 return xen_api_todo()
1232 def VM_set_user_version(self, session, vm_ref, ver):
1233 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1234 return xen_api_todo()
1236 def VM_set_is_a_template(self, session, vm_ref, is_template):
1237 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1238 return xen_api_todo()
1240 def VM_set_memory_dynamic_max(self, session, vm_ref, mem):
1241 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1242 return xen_api_todo()
1244 def VM_set_memory_dynamic_min(self, session, vm_ref, mem):
1245 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1246 return xen_api_todo()
1248 def VM_set_VCPUs_policy(self, session, vm_ref, policy):
1249 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1250 return xen_api_todo()
1252 def VM_set_VCPUs_params(self, session, vm_ref, params):
1253 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1254 return xen_api_todo()
1256 def VM_set_actions_after_shutdown(self, session, vm_ref, action):
1257 if action not in XEN_API_ON_NORMAL_EXIST:
1258 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1259 return self.VM_set('actions_after_shutdown', session, vm_ref, action)
1261 def VM_set_actions_after_reboot(self, session, vm_ref, action):
1262 if action not in XEN_API_ON_NORMAL_EXIST:
1263 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1264 return self.VM_set('actions_after_reboot', session, vm_ref, action)
1266 def VM_set_actions_after_suspend(self, session, vm_ref, action):
1267 if action not in XEN_API_ON_NORMAL_EXIT:
1268 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1269 return self.VM_set('actions_after_suspend', session, vm_ref, action)
1271 def VM_set_actions_after_crash(self, session, vm_ref, action):
1272 if action not in XEN_API_ON_CRASH_BEHAVIOUR:
1273 return xen_api_error(['VM_ON_CRASH_BEHAVIOUR_INVALID', vm_ref])
1274 return self.VM_set('actions_after_crash', session, vm_ref, action)
1276 def VM_set_HVM_boot_policy(self, session, vm_ref, value):
1277 if value != "" and value != "BIOS order":
1278 return xen_api_error(
1279 ['VALUE_NOT_SUPPORTED', 'VM.HVM_boot_policy', value,
1280 'Xend supports only the "BIOS order" boot policy.'])
1281 else:
1282 return self.VM_set('HVM_boot_policy', session, vm_ref, value)
1284 def VM_set_HVM_boot_params(self, session, vm_ref, value):
1285 return self.VM_set('HVM_boot_params', session, vm_ref, value)
1287 def VM_add_to_HVM_boot_params(self, session, vm_ref, key, value):
1288 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1289 if 'HVM_boot_params' not in dom.info:
1290 dom.info['HVM_boot_params'] = {}
1291 dom.info['HVM_boot_params'][key] = value
1292 return xen_api_success_void()
1294 def VM_remove_from_HVM_boot_params(self, session, vm_ref, key):
1295 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1296 if 'HVM_boot_params' in dom.info \
1297 and key in dom.info['HVM_boot_params']:
1298 del dom.info['HVM_boot_params'][key]
1299 return xen_api_success_void()
1301 def VM_set_PV_bootloader(self, session, vm_ref, value):
1302 return self.VM_set('PV_bootloader', session, vm_ref, value)
1304 def VM_set_PV_kernel(self, session, vm_ref, value):
1305 return self.VM_set('PV_kernel', session, vm_ref, value)
1307 def VM_set_PV_ramdisk(self, session, vm_ref, value):
1308 return self.VM_set('PV_ramdisk', session, vm_ref, value)
1310 def VM_set_PV_args(self, session, vm_ref, value):
1311 return self.VM_set('PV_args', session, vm_ref, value)
1313 def VM_set_PV_bootloader_args(self, session, vm_ref, value):
1314 return self.VM_set('PV_bootloader_args', session, vm_ref, value)
1316 def VM_set_platform_std_VGA(self, session, vm_ref, value):
1317 return self.VM_set('platform_std_vga', session, vm_ref, value)
1319 def VM_set_platform_serial(self, session, vm_ref, value):
1320 return self.VM_set('platform_serial', session, vm_ref, value)
1322 def VM_set_platform_keymap(self, session, vm_ref, value):
1323 return self.VM_set('platform_keymap', session, vm_ref, value)
1325 def VM_set_platform_localtime(self, session, vm_ref, value):
1326 return self.VM_set('platform_localtime', session, vm_ref, value)
1328 def VM_set_platform_clock_offset(self, session, vm_ref, value):
1329 return self.VM_set('platform_clock_offset', session, vm_ref, value)
1331 def VM_set_platform_enable_audio(self, session, vm_ref, value):
1332 return self.VM_set('platform_enable_audio', session, vm_ref, value)
1334 def VM_set_other_config(self, session, vm_ref, value):
1335 return self.VM_set('otherconfig', session, vm_ref, value)
1337 def VM_add_to_other_config(self, session, vm_ref, key, value):
1338 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1339 if dom and 'otherconfig' in dom.info:
1340 dom.info['otherconfig'][key] = value
1341 return xen_api_success_void()
1343 def VM_remove_from_other_config(self, session, vm_ref, key):
1344 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1345 if dom and 'otherconfig' in dom.info \
1346 and key in dom.info['otherconfig']:
1347 del dom.info['otherconfig'][key]
1348 return xen_api_success_void()
1350 # class methods
1351 def VM_get_all(self, session):
1352 refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
1353 return xen_api_success(refs)
1355 def VM_get_by_name_label(self, session, label):
1356 xendom = XendDomain.instance()
1357 dom = xendom.domain_lookup_nr(label)
1358 if dom:
1359 return xen_api_success([dom.get_uuid()])
1360 return xen_api_success([])
1362 def VM_create(self, session, vm_struct):
1363 xendom = XendDomain.instance()
1364 domuuid = XendTask.log_progress(0, 100,
1365 xendom.create_domain, vm_struct)
1366 return xen_api_success(domuuid)
1368 # object methods
1369 def VM_get_record(self, session, vm_ref):
1370 xendom = XendDomain.instance()
1371 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1372 if not xeninfo:
1373 return xen_api_error(['HANDLE_INVALID', 'VM', vm_ref])
1375 record = {
1376 'uuid': xeninfo.get_uuid(),
1377 'power_state': xeninfo.get_power_state(),
1378 'name_label': xeninfo.getName(),
1379 'name_description': xeninfo.getName(),
1380 'user_version': 1,
1381 'is_a_template': False,
1382 'auto_power_on': False,
1383 'resident_on': XendNode.instance().uuid,
1384 'memory_static_min': xeninfo.get_memory_static_min(),
1385 'memory_static_max': xeninfo.get_memory_static_max(),
1386 'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
1387 'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
1388 'memory_actual': xeninfo.get_memory_static_min(),
1389 'VCPUs_policy': xeninfo.get_vcpus_policy(),
1390 'VCPUs_params': xeninfo.get_vcpus_params(),
1391 'VCPUs_number': xeninfo.getVCpuCount(),
1392 'VCPUs_utilisation': xeninfo.get_vcpus_util(),
1393 'actions_after_shutdown': xeninfo.get_on_shutdown(),
1394 'actions_after_reboot': xeninfo.get_on_reboot(),
1395 'actions_after_suspend': xeninfo.get_on_suspend(),
1396 'actions_after_crash': xeninfo.get_on_crash(),
1397 'consoles': xeninfo.get_consoles(),
1398 'VIFs': xeninfo.get_vifs(),
1399 'VBDs': xeninfo.get_vbds(),
1400 'VTPMs': xeninfo.get_vtpms(),
1401 'PV_bootloader': xeninfo.info.get('PV_bootloader'),
1402 'PV_kernel': xeninfo.info.get('PV_kernel'),
1403 'PV_ramdisk': xeninfo.info.get('PV_ramdisk'),
1404 'PV_args': xeninfo.info.get('PV_args'),
1405 'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
1406 'HVM_boot_policy': xeninfo.info.get('HVM_boot_policy'),
1407 'HVM_boot_params': xeninfo.info.get('HVM_boot_params'),
1408 'platform_std_VGA': xeninfo.get_platform_std_vga(),
1409 'platform_serial': xeninfo.get_platform_serial(),
1410 'platform_localtime': xeninfo.get_platform_localtime(),
1411 'platform_clock_offset': xeninfo.get_platform_clock_offset(),
1412 'platform_enable_audio': xeninfo.get_platform_enable_audio(),
1413 'platform_keymap': xeninfo.get_platform_keymap(),
1414 'PCI_bus': xeninfo.get_pci_bus(),
1415 'tools_version': xeninfo.get_tools_version(),
1416 'other_config': xeninfo.info.get('other_config', {}),
1417 'is_control_domain': xeninfo == xendom.privilegedDomain(),
1419 return xen_api_success(record)
1421 def VM_clean_reboot(self, session, vm_ref):
1422 xendom = XendDomain.instance()
1423 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1424 XendTask.log_progress(0, 100, xeninfo.shutdown, "reboot")
1425 return xen_api_success_void()
1427 def VM_clean_shutdown(self, session, vm_ref):
1428 xendom = XendDomain.instance()
1429 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1430 XendTask.log_progress(0, 100, xeninfo.shutdown, "poweroff")
1431 return xen_api_success_void()
1433 def VM_clone(self, session, vm_ref):
1434 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1436 def VM_destroy(self, session, vm_ref):
1437 return XendTask.log_progress(0, 100, do_vm_func,
1438 "domain_delete", vm_ref)
1440 def VM_hard_reboot(self, session, vm_ref):
1441 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1443 def VM_hard_shutdown(self, session, vm_ref):
1444 return XendTask.log_progress(0, 100, do_vm_func,
1445 "domain_destroy", vm_ref)
1446 def VM_pause(self, session, vm_ref):
1447 return XendTask.log_progress(0, 100, do_vm_func,
1448 "domain_pause", vm_ref)
1450 def VM_resume(self, session, vm_ref, start_paused):
1451 return XendTask.log_progress(0, 100, do_vm_func,
1452 "domain_resume", vm_ref,
1453 start_paused = start_paused)
1455 def VM_start(self, session, vm_ref, start_paused):
1456 return XendTask.log_progress(0, 100, do_vm_func,
1457 "domain_start", vm_ref,
1458 start_paused = start_paused)
1460 def VM_suspend(self, session, vm_ref):
1461 return XendTask.log_progress(0, 100, do_vm_func,
1462 "domain_suspend", vm_ref)
1464 def VM_unpause(self, session, vm_ref):
1465 return XendTask.log_progress(0, 100, do_vm_func,
1466 "domain_unpause", vm_ref)
1468 # Xen API: Class VBD
1469 # ----------------------------------------------------------------
1471 VBD_attr_ro = ['metrics']
1472 VBD_attr_rw = ['VM',
1473 'VDI',
1474 'device',
1475 'bootable',
1476 'mode',
1477 'type']
1479 VBD_attr_inst = VBD_attr_rw
1481 VBD_methods = [('media_change', None)]
1482 VBD_funcs = [('create', 'VBD')]
1484 # object methods
1485 def VBD_get_record(self, session, vbd_ref):
1486 xendom = XendDomain.instance()
1487 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1488 if not vm:
1489 return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
1490 cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
1491 if not cfg:
1492 return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
1494 valid_vbd_keys = self.VBD_attr_ro + self.VBD_attr_rw + \
1495 self.Base_attr_ro + self.Base_attr_rw
1497 return_cfg = {}
1498 for k in cfg.keys():
1499 if k in valid_vbd_keys:
1500 return_cfg[k] = cfg[k]
1502 return_cfg['metrics'] = vbd_ref
1504 return xen_api_success(return_cfg)
1506 def VBD_media_change(self, session, vbd_ref, vdi_ref):
1507 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1509 # class methods
1510 def VBD_create(self, session, vbd_struct):
1511 xendom = XendDomain.instance()
1512 if not xendom.is_valid_vm(vbd_struct['VM']):
1513 return xen_api_error(['HANDLE_INVALID', 'VM', vbd_struct['VM']])
1515 dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
1516 vbd_ref = ''
1517 try:
1518 # new VBD via VDI/SR
1519 vdi_ref = vbd_struct.get('VDI')
1520 vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
1521 if not vdi:
1522 return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
1523 vdi_image = vdi.get_location()
1524 vbd_ref = XendTask.log_progress(0, 100,
1525 dom.create_vbd,
1526 vbd_struct, vdi_image)
1527 except XendError:
1528 return xen_api_todo()
1530 xendom.managed_config_save(dom)
1531 return xen_api_success(vbd_ref)
1534 def VBD_destroy(self, session, vbd_ref):
1535 xendom = XendDomain.instance()
1536 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1537 if not vm:
1538 return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
1540 XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref)
1541 return xen_api_success_void()
1543 def _VBD_get(self, vbd_ref, prop):
1544 return xen_api_success(
1545 XendDomain.instance().get_dev_property_by_uuid(
1546 'vbd', vbd_ref, prop))
1548 # attributes (ro)
1549 def VBD_get_metrics(self, _, vbd_ref):
1550 return xen_api_success(vbd_ref)
1552 # attributes (rw)
1553 def VBD_get_VM(self, session, vbd_ref):
1554 return self._VBD_get(vbd_ref, 'VM')
1556 def VBD_get_VDI(self, session, vbd_ref):
1557 return self._VBD_get(vbd_ref, 'VDI')
1559 def VBD_get_device(self, session, vbd_ref):
1560 return self._VBD_get(vbd_ref, 'device')
1562 def VBD_get_bootable(self, session, vbd_ref):
1563 return self._VBD_get(vbd_ref, 'bootable')
1565 def VBD_get_mode(self, session, vbd_ref):
1566 return self._VBD_get(vbd_ref, 'mode')
1568 def VBD_get_type(self, session, vbd_ref):
1569 return self._VBD_get(vbd_ref, 'type')
1571 def VBD_set_bootable(self, session, vbd_ref, bootable):
1572 bootable = bool(bootable)
1573 xd = XendDomain.instance()
1574 vm = xd.get_vm_with_dev_uuid('vbd', vbd_ref)
1575 vm.set_dev_property('vbd', vbd_ref, 'bootable', bootable)
1576 xd.managed_config_save(vm)
1577 return xen_api_success_void()
1579 def VBD_get_all(self, session):
1580 xendom = XendDomain.instance()
1581 vbds = [d.get_vbds() for d in XendDomain.instance().list('all')]
1582 vbds = reduce(lambda x, y: x + y, vbds)
1583 return xen_api_success(vbds)
1586 # Xen API: Class VBD_metrics
1587 # ----------------------------------------------------------------
1589 VBD_metrics_attr_ro = ['io_read_kbs',
1590 'io_write_kbs']
1591 VBD_metrics_attr_rw = []
1592 VBD_methods = []
1594 def VBD_metrics_get_record(self, _, ref):
1595 vm = XendDomain.instance().get_vm_with_dev_uuid('vbd', ref)
1596 if not vm:
1597 return xen_api_error(['HANDLE_INVALID', 'VBD_metrics', ref])
1598 return xen_api_success(
1599 { 'io_read_kbs' : vm.get_dev_property('vbd', ref, 'io_read_kbs'),
1600 'io_write_kbs' : vm.get_dev_property('vbd', ref, 'io_write_kbs') })
1602 def VBD_metrics_get_io_read_kbs(self, _, ref):
1603 return self._VBD_get(ref, 'io_read_kbs')
1605 def VBD_metrics_get_io_write_kbs(self, session, ref):
1606 return self._VBD_get(ref, 'io_write_kbs')
1609 # Xen API: Class VIF
1610 # ----------------------------------------------------------------
1612 VIF_attr_ro = ['metrics']
1613 VIF_attr_rw = ['device',
1614 'network',
1615 'VM',
1616 'MAC',
1617 'MTU']
1619 VIF_attr_inst = VIF_attr_rw
1621 VIF_funcs = [('create', 'VIF')]
1624 # object methods
1625 def VIF_get_record(self, session, vif_ref):
1626 xendom = XendDomain.instance()
1627 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1628 if not vm:
1629 return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
1630 cfg = vm.get_dev_xenapi_config('vif', vif_ref)
1631 if not cfg:
1632 return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
1634 valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
1635 self.Base_attr_ro + self.Base_attr_rw
1637 return_cfg = {}
1638 for k in cfg.keys():
1639 if k in valid_vif_keys:
1640 return_cfg[k] = cfg[k]
1642 return_cfg['metrics'] = vif_ref
1644 return xen_api_success(return_cfg)
1646 # class methods
1647 def VIF_create(self, session, vif_struct):
1648 xendom = XendDomain.instance()
1649 if xendom.is_valid_vm(vif_struct['VM']):
1650 dom = xendom.get_vm_by_uuid(vif_struct['VM'])
1651 try:
1652 vif_ref = dom.create_vif(vif_struct)
1653 xendom.managed_config_save(dom)
1654 return xen_api_success(vif_ref)
1655 except XendError:
1656 return xen_api_error(XEND_ERROR_TODO)
1657 else:
1658 return xen_api_error(['HANDLE_INVALID', 'VM', vif_struct['VM']])
1661 def VIF_destroy(self, session, vif_ref):
1662 xendom = XendDomain.instance()
1663 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1664 if not vm:
1665 return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
1667 vm.destroy_vif(vif_ref)
1668 return xen_api_success_void()
1670 def _VIF_get(self, ref, prop):
1671 return xen_api_success(
1672 XendDomain.instance().get_dev_property_by_uuid('vif', ref, prop))
1674 # getters/setters
1675 def VIF_get_metrics(self, _, vif_ref):
1676 return xen_api_success(vif_ref)
1678 def VIF_get_VM(self, session, vif_ref):
1679 xendom = XendDomain.instance()
1680 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1681 return xen_api_success(vm.get_uuid())
1683 def VIF_get_MTU(self, session, vif_ref):
1684 return self._VIF_get(vif_ref, 'MTU')
1686 def VIF_get_MAC(self, session, vif_ref):
1687 return self._VIF_get(vif_ref, 'MAC')
1689 def VIF_get_device(self, session, vif_ref):
1690 return self._VIF_get(vif_ref, 'device')
1692 def VIF_get_all(self, session):
1693 xendom = XendDomain.instance()
1694 vifs = [d.get_vifs() for d in XendDomain.instance().list('all')]
1695 vifs = reduce(lambda x, y: x + y, vifs)
1696 return xen_api_success(vifs)
1699 # Xen API: Class VIF_metrics
1700 # ----------------------------------------------------------------
1702 VIF_metrics_attr_ro = ['io_read_kbs',
1703 'io_write_kbs']
1704 VIF_metrics_attr_rw = []
1705 VIF_methods = []
1707 def VIF_metrics_get_record(self, _, ref):
1708 vm = XendDomain.instance().get_vm_with_dev_uuid('vif', ref)
1709 if not vm:
1710 return xen_api_error(['HANDLE_INVALID', 'VIF_metrics', ref])
1711 return xen_api_success(
1712 { 'io_read_kbs' : vm.get_dev_property('vif', ref, 'io_read_kbs'),
1713 'io_write_kbs' : vm.get_dev_property('vif', ref, 'io_write_kbs') })
1715 def VIF_metrics_get_io_read_kbs(self, _, ref):
1716 return self._VIF_get(ref, 'io_read_kbs')
1718 def VIF_metrics_get_io_write_kbs(self, session, ref):
1719 return self._VIF_get(ref, 'io_write_kbs')
1722 # Xen API: Class VDI
1723 # ----------------------------------------------------------------
1724 VDI_attr_ro = ['VBDs',
1725 'physical_utilisation',
1726 'sector_size',
1727 'type']
1728 VDI_attr_rw = ['name_label',
1729 'name_description',
1730 'SR',
1731 'virtual_size',
1732 'sharable',
1733 'read_only']
1734 VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
1736 VDI_methods = [('snapshot', 'VDI')]
1737 VDI_funcs = [('create', 'VDI'),
1738 ('get_by_name_label', 'Set(VDI)')]
1740 def _get_VDI(self, ref):
1741 return XendNode.instance().get_vdi_by_uuid(ref)
1743 def VDI_get_VBDs(self, session, vdi_ref):
1744 return xen_api_todo()
1746 def VDI_get_physical_utilisation(self, session, vdi_ref):
1747 return xen_api_success(self._get_VDI(vdi_ref).
1748 get_physical_utilisation())
1750 def VDI_get_sector_size(self, session, vdi_ref):
1751 return xen_api_success(self._get_VDI(vdi_ref).sector_size)
1753 def VDI_get_type(self, session, vdi_ref):
1754 return xen_api_success(self._get_VDI(vdi_ref).type)
1756 def VDI_get_name_label(self, session, vdi_ref):
1757 return xen_api_success(self._get_VDI(vdi_ref).name_label)
1759 def VDI_get_name_description(self, session, vdi_ref):
1760 return xen_api_success(self._get_VDI(vdi_ref).name_description)
1762 def VDI_get_SR(self, session, vdi_ref):
1763 return xen_api_success(self._get_VDI(vdi_ref).sr_uuid)
1765 def VDI_get_virtual_size(self, session, vdi_ref):
1766 return xen_api_success(self._get_VDI(vdi_ref).virtual_size)
1768 def VDI_get_sharable(self, session, vdi_ref):
1769 return xen_api_success(self._get_VDI(vdi_ref).sharable)
1771 def VDI_get_read_only(self, session, vdi_ref):
1772 return xen_api_success(self._get_VDI(vdi_ref).read_only)
1774 def VDI_set_name_label(self, session, vdi_ref, value):
1775 self._get_VDI(vdi_ref).name_label = value
1776 return xen_api_success_void()
1778 def VDI_set_name_description(self, session, vdi_ref, value):
1779 self._get_VDI(vdi_ref).name_description = value
1780 return xen_api_success_void()
1782 def VDI_set_SR(self, session, vdi_ref, value):
1783 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1785 def VDI_set_virtual_size(self, session, vdi_ref, value):
1786 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1788 def VDI_set_sharable(self, session, vdi_ref, value):
1789 self._get_VDI(vdi_ref).sharable = bool(value)
1790 return xen_api_success_void()
1792 def VDI_set_read_only(self, session, vdi_ref, value):
1793 self._get_VDI(vdi_ref).read_only = bool(value)
1794 return xen_api_success_void()
1796 # Object Methods
1797 def VDI_snapshot(self, session, vdi_ref):
1798 return xen_api_todo()
1800 def VDI_destroy(self, session, vdi_ref):
1801 sr = XendNode.instance().get_sr_containing_vdi(vdi_ref)
1802 sr.destroy_vdi(vdi_ref)
1803 return xen_api_success_void()
1805 def VDI_get_record(self, session, vdi_ref):
1806 image = XendNode.instance().get_vdi_by_uuid(vdi_ref)
1807 return xen_api_success({
1808 'uuid': vdi_ref,
1809 'name_label': image.name_label,
1810 'name_description': image.name_description,
1811 'SR': image.sr_uuid,
1812 'VBDs': [], # TODO
1813 'virtual_size': image.virtual_size,
1814 'physical_utilisation': image.physical_utilisation,
1815 'sector_size': image.sector_size,
1816 'type': image.type,
1817 'sharable': image.sharable,
1818 'read_only': image.read_only,
1819 })
1821 # Class Functions
1822 def VDI_create(self, session, vdi_struct):
1823 sr_ref = vdi_struct.get('SR')
1824 xennode = XendNode.instance()
1825 if not xennode.is_valid_sr(sr_ref):
1826 return xen_api_error(['HANDLE_INVALID', 'SR', sr_ref])
1828 vdi_uuid = xennode.srs[sr_ref].create_vdi(vdi_struct)
1829 return xen_api_success(vdi_uuid)
1831 def VDI_get_all(self, session):
1832 xennode = XendNode.instance()
1833 vdis = [sr.get_vdis() for sr in xennode.srs.values()]
1834 return xen_api_success(reduce(lambda x, y: x + y, vdis))
1836 def VDI_get_by_name_label(self, session, name):
1837 xennode = XendNode.instance()
1838 return xen_api_success(xennode.get_vdi_by_name_label(name))
1841 # Xen API: Class VTPM
1842 # ----------------------------------------------------------------
1844 VTPM_attr_rw = [ ]
1845 VTPM_attr_ro = ['VM',
1846 'backend']
1848 VTPM_attr_inst = VTPM_attr_rw
1850 VTPM_funcs = [('create', 'VTPM')]
1852 # object methods
1853 def VTPM_get_record(self, session, vtpm_ref):
1854 xendom = XendDomain.instance()
1855 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1856 if not vm:
1857 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
1858 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1859 if not cfg:
1860 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
1861 valid_vtpm_keys = self.VTPM_attr_ro + self.VTPM_attr_rw + \
1862 self.Base_attr_ro + self.Base_attr_rw
1863 return_cfg = {}
1864 for k in cfg.keys():
1865 if k in valid_vtpm_keys:
1866 return_cfg[k] = cfg[k]
1868 return xen_api_success(return_cfg)
1870 # Class Functions
1871 def VTPM_get_backend(self, session, vtpm_ref):
1872 xendom = XendDomain.instance()
1873 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1874 if not vm:
1875 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
1876 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1877 if not cfg:
1878 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
1879 if not cfg.has_key('backend'):
1880 return xen_api_error(['VTPM backend not set'])
1881 return xen_api_success(cfg['backend'])
1883 def VTPM_get_VM(self, session, vtpm_ref):
1884 xendom = XendDomain.instance()
1885 return xen_api_success(xendom.get_dev_property_by_uuid('vtpm',
1886 vtpm_ref, 'VM'))
1888 def VTPM_destroy(self, session, vtpm_ref):
1889 xendom = XendDomain.instance()
1890 dom = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1891 if dom:
1892 if dom.state != XEN_API_VM_POWER_STATE_HALTED:
1893 vm_ref = dom.get_dev_property('vtpm', vtpm_ref, 'VM')
1894 return xen_api_error(['VM_BAD_POWER_STATE', vm_ref,
1895 XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_HALTED],
1896 XendDomain.POWER_STATE_NAMES[dom.state]])
1897 from xen.xend.server import tpmif
1898 tpmif.destroy_vtpmstate(dom.getName())
1899 return xen_api_success(True)
1900 else:
1901 return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']])
1903 # class methods
1904 def VTPM_create(self, session, vtpm_struct):
1905 xendom = XendDomain.instance()
1906 if xendom.is_valid_vm(vtpm_struct['VM']):
1907 dom = xendom.get_vm_by_uuid(vtpm_struct['VM'])
1908 try:
1909 vtpm_ref = dom.create_vtpm(vtpm_struct)
1910 xendom.managed_config_save(dom)
1911 return xen_api_success(vtpm_ref)
1912 except XendError:
1913 return xen_api_error(XEND_ERROR_TODO)
1914 else:
1915 return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']])
1917 def VTPM_get_all(self, session):
1918 xendom = XendDomain.instance()
1919 vtpms = [d.get_vtpms() for d in XendDomain.instance().list('all')]
1920 vtpms = reduce(lambda x, y: x + y, vtpms)
1921 return xen_api_success(vtpms)
1923 # Xen API: Class console
1924 # ----------------------------------------------------------------
1927 console_attr_ro = ['location', 'protocol', 'VM']
1928 console_attr_rw = ['other_config']
1929 console_funcs = [('create', 'console')]
1931 def console_get_all(self, session):
1932 xendom = XendDomain.instance()
1933 cons = [d.get_consoles() for d in XendDomain.instance().list('all')]
1934 cons = reduce(lambda x, y: x + y, cons)
1935 return xen_api_success(cons)
1937 def console_get_location(self, session, console_ref):
1938 return xen_api_success(xendom.get_dev_property_by_uuid('console',
1939 console_ref,
1940 'location'))
1942 def console_get_protocol(self, session, console_ref):
1943 return xen_api_success(xendom.get_dev_property_by_uuid('console',
1944 console_ref,
1945 'protocol'))
1947 def console_get_VM(self, session, console_ref):
1948 xendom = XendDomain.instance()
1949 vm = xendom.get_vm_with_dev_uuid('console', console_ref)
1950 return xen_api_success(vm.get_uuid())
1952 # object methods
1953 def console_get_record(self, session, console_ref):
1954 xendom = XendDomain.instance()
1955 vm = xendom.get_vm_with_dev_uuid('console', console_ref)
1956 if not vm:
1957 return xen_api_error(['HANDLE_INVALID', 'console', console_ref])
1958 cfg = vm.get_dev_xenapi_config('console', console_ref)
1959 if not cfg:
1960 return xen_api_error(['HANDLE_INVALID', 'console', console_ref])
1962 valid_console_keys = self.console_attr_ro + self.console_attr_rw + \
1963 self.Base_attr_ro + self.Base_attr_rw
1965 return_cfg = {}
1966 for k in cfg.keys():
1967 if k in valid_console_keys:
1968 return_cfg[k] = cfg[k]
1970 return xen_api_success(return_cfg)
1972 def console_create(self, session, console_struct):
1973 xendom = XendDomain.instance()
1974 if not xendom.is_valid_vm(console_struct['VM']):
1975 return xen_api_error(['HANDLE_INVALID', 'VM',
1976 console_struct['VM']])
1978 dom = xendom.get_vm_by_uuid(console_struct['VM'])
1979 try:
1980 if 'protocol' not in console_struct:
1981 return xen_api_error(['CONSOLE_PROTOCOL_INVALID',
1982 'No protocol specified'])
1984 console_ref = dom.create_console(console_struct)
1985 xendom.managed_config_save(dom)
1986 return xen_api_success(console_ref)
1987 except XendError, e:
1988 return xen_api_error([XEND_ERROR_TODO, str(e)])
1990 # Xen API: Class SR
1991 # ----------------------------------------------------------------
1992 SR_attr_ro = ['VDIs',
1993 'virtual_allocation',
1994 'physical_utilisation',
1995 'physical_size',
1996 'type',
1997 'location']
1999 SR_attr_rw = ['name_label',
2000 'name_description']
2002 SR_attr_inst = ['physical_size',
2003 'type',
2004 'location',
2005 'name_label',
2006 'name_description']
2008 SR_methods = [('clone', 'SR')]
2009 SR_funcs = [('get_by_name_label', 'Set(SR)'),
2010 ('get_by_uuid', 'SR')]
2012 # Class Functions
2013 def SR_get_all(self, session):
2014 return xen_api_success(XendNode.instance().get_all_sr_uuid())
2016 def SR_get_by_name_label(self, session, label):
2017 return xen_api_success(XendNode.instance().get_sr_by_name(label))
2019 def SR_create(self, session):
2020 return xen_api_error(XEND_ERROR_UNSUPPORTED)
2022 # Class Methods
2023 def SR_clone(self, session, sr_ref):
2024 return xen_api_error(XEND_ERROR_UNSUPPORTED)
2026 def SR_destroy(self, session, sr_ref):
2027 return xen_api_error(XEND_ERROR_UNSUPPORTED)
2029 def SR_get_record(self, session, sr_ref):
2030 sr = XendNode.instance().get_sr(sr_ref)
2031 if sr:
2032 return xen_api_success(sr.get_record())
2033 return xen_api_error(['HANDLE_INVALID', 'SR', sr_ref])
2035 # Attribute acceess
2037 def _get_SR_func(self, sr_ref, func):
2038 return xen_api_success(getattr(XendNode.instance().get_sr(sr_ref),
2039 func)())
2041 def _get_SR_attr(self, sr_ref, attr):
2042 return xen_api_success(getattr(XendNode.instance().get_sr(sr_ref),
2043 attr))
2045 def SR_get_VDIs(self, _, ref):
2046 return self._get_SR_func(ref, 'list_images')
2048 def SR_get_virtual_allocation(self, _, ref):
2049 return self._get_SR_func(ref, 'virtual_allocation')
2051 def SR_get_physical_utilisation(self, _, ref):
2052 return self._get_SR_func(ref, 'physical_utilisation')
2054 def SR_get_physical_size(self, _, ref):
2055 return self._get_SR_func(ref, 'physical_size')
2057 def SR_get_type(self, _, ref):
2058 return self._get_SR_attr(ref, 'type')
2060 def SR_get_location(self, _, ref):
2061 return self._get_SR_attr(ref, 'location')
2063 def SR_get_name_label(self, _, ref):
2064 return self._get_SR_attr(ref, 'name_label')
2066 def SR_get_name_description(self, _, ref):
2067 return self._get_SR_attr(ref, 'name_description')
2069 def SR_set_name_label(self, session, sr_ref, value):
2070 sr = XendNode.instance.get_sr(sr_ref)
2071 if sr:
2072 sr.name_label = value
2073 XendNode.instance().save()
2074 return xen_api_success_void()
2076 def SR_set_name_description(self, session, sr_ref, value):
2077 sr = XendNode.instance.get_sr(sr_ref)
2078 if sr:
2079 sr.name_description = value
2080 XendNode.instance().save()
2081 return xen_api_success_void()
2084 # Xen API: Class debug
2085 # ----------------------------------------------------------------
2087 debug_methods = [('destroy', None),
2088 ('get_record', 'debug')]
2089 debug_funcs = [('wait', None),
2090 ('return_failure', None)]
2092 def debug_wait(self, session, wait_secs):
2093 import time
2094 prog_units = 100/float(wait_secs)
2095 for i in range(int(wait_secs)):
2096 XendTask.log_progress(prog_units * i, prog_units * (i + 1),
2097 time.sleep, 1)
2098 return xen_api_success_void()
2101 def debug_return_failure(self, session):
2102 return xen_api_error(['DEBUG_FAIL', session])
2104 def debug_create(self, session):
2105 debug_uuid = uuid.createString()
2106 self._debug[debug_uuid] = None
2107 return xen_api_success(debug_uuid)
2109 def debug_destroy(self, session, debug_ref):
2110 del self._debug[debug_ref]
2111 return xen_api_success_void()
2113 def debug_get_record(self, session, debug_ref):
2114 return xen_api_success({'uuid': debug_ref})
2118 class XendAPIAsyncProxy:
2119 """ A redirector for Async.Class.function calls to XendAPI
2120 but wraps the call for use with the XendTaskManager.
2122 @ivar xenapi: Xen API instance
2123 @ivar method_map: Mapping from XMLRPC method name to callable objects.
2124 """
2126 method_prefix = 'Async.'
2128 def __init__(self, xenapi):
2129 """Initialises the Async Proxy by making a map of all
2130 implemented Xen API methods for use with XendTaskManager.
2132 @param xenapi: XendAPI instance
2133 """
2134 self.xenapi = xenapi
2135 self.method_map = {}
2136 for method_name in dir(self.xenapi):
2137 method = getattr(self.xenapi, method_name)
2138 if method_name[0] != '_' and hasattr(method, 'async') \
2139 and method.async == True:
2140 self.method_map[method.api] = method
2142 def _dispatch(self, method, args):
2143 """Overridden method so that SimpleXMLRPCServer will
2144 resolve methods through this method rather than through
2145 inspection.
2147 @param method: marshalled method name from XMLRPC.
2148 @param args: marshalled arguments from XMLRPC.
2149 """
2151 # Only deal with method names that start with "Async."
2152 if not method.startswith(self.method_prefix):
2153 return xen_api_error(['MESSAGE_METHOD_UNKNOWN', method])
2155 # Lookup synchronous version of the method
2156 synchronous_method_name = method[len(self.method_prefix):]
2157 if synchronous_method_name not in self.method_map:
2158 return xen_api_error(['MESSAGE_METHOD_UNKNOWN', method])
2160 method = self.method_map[synchronous_method_name]
2162 # Check that we've got enough arguments before issuing a task ID.
2163 needed = argcounts[method.api]
2164 if len(args) != needed:
2165 return xen_api_error(['MESSAGE_PARAMETER_COUNT_MISMATCH',
2166 self.method_prefix + method.api, needed,
2167 len(args)])
2169 # Validate the session before proceeding
2170 session = args[0]
2171 if not auth_manager().is_session_valid(session):
2172 return xen_api_error(['SESSION_INVALID', session])
2174 # create and execute the task, and return task_uuid
2175 return_type = getattr(method, 'return_type', None)
2176 task_uuid = XendTaskManager.create_task(method, args,
2177 synchronous_method_name,
2178 return_type,
2179 synchronous_method_name,
2180 session)
2181 return xen_api_success(task_uuid)
2184 # Auto generate some stubs based on XendAPI introspection
2186 if __name__ == "__main__":
2187 def output(line):
2188 print ' ' + line
2190 classes = ['VDI', 'SR']
2191 for cls in classes:
2192 ro_attrs = getattr(XendAPI, '%s_attr_ro' % cls, [])
2193 rw_attrs = getattr(XendAPI, '%s_attr_rw' % cls, [])
2194 methods = getattr(XendAPI, '%s_methods' % cls, [])
2195 funcs = getattr(XendAPI, '%s_funcs' % cls, [])
2197 ref = '%s_ref' % cls
2199 for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
2200 getter_name = '%s_get_%s' % (cls, attr_name)
2201 output('def %s(self, session, %s):' % (getter_name, ref))
2202 output(' return xen_api_todo()')
2204 for attr_name in rw_attrs + XendAPI.Base_attr_rw:
2205 setter_name = '%s_set_%s' % (cls, attr_name)
2206 output('def %s(self, session, %s, value):' % (setter_name, ref))
2207 output(' return xen_api_todo()')
2209 for method_name in methods + XendAPI.Base_methods:
2210 method_full_name = '%s_%s' % (cls,method_name)
2211 output('def %s(self, session, %s):' % (method_full_name, ref))
2212 output(' return xen_api_todo()')
2214 for func_name in funcs + XendAPI.Base_funcs:
2215 func_full_name = '%s_%s' % (cls, func_name)
2216 output('def %s(self, session):' % func_full_name)
2217 output(' return xen_api_todo()')