ia64/xen-unstable

view tools/python/xen/xend/XendAPI.py @ 14045:7819d9332fba

Split the VBD I/O statistics out into a VBD_metrics class. Document the
VBD.type field, and add it to the C bindings (this was already in Xend).

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Tue Feb 20 21:28:19 2007 +0000 (2007-02-20)
parents 8bcd71c3b495
children 0aa6755159d5
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_vdi(func):
233 """Decorator to verify if vdi_ref is valid before calling method.
235 @param func: function with params: (self, session, vdi_ref, ...)
236 @rtype: callable object
237 """
238 return lambda *args, **kwargs: \
239 _check_ref(XendNode.instance().is_valid_vdi,
240 'VDI', func, *args, **kwargs)
242 def valid_vtpm(func):
243 """Decorator to verify if vtpm_ref is valid before calling method.
245 @param func: function with params: (self, session, vtpm_ref, ...)
246 @rtype: callable object
247 """
248 return lambda *args, **kwargs: \
249 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vtpm', r),
250 'VTPM', func, *args, **kwargs)
253 def valid_console(func):
254 """Decorator to verify if console_ref is valid before calling method.
256 @param func: function with params: (self, session, console_ref, ...)
257 @rtype: callable object
258 """
259 return lambda *args, **kwargs: \
260 _check_ref(lambda r: XendDomain.instance().is_valid_dev('console',
261 r),
262 'console', func, *args, **kwargs)
264 def valid_sr(func):
265 """Decorator to verify if sr_ref is valid before calling method.
267 @param func: function with params: (self, session, sr_ref, ...)
268 @rtype: callable object
269 """
270 return lambda *args, **kwargs: \
271 _check_ref(lambda r: XendNode.instance().is_valid_sr,
272 'SR', func, *args, **kwargs)
274 def valid_pif(func):
275 """Decorator to verify if pif_ref is valid before calling
276 method.
278 @param func: function with params: (self, session, pif_ref)
279 @rtype: callable object
280 """
281 return lambda *args, **kwargs: \
282 _check_ref(lambda r: r in XendNode.instance().pifs,
283 'PIF', func, *args, **kwargs)
285 def valid_pif_metrics(func):
286 """Decorator to verify if pif_metrics_ref is valid before calling
287 method.
289 @param func: function with params: (self, session, pif_metrics_ref)
290 @rtype: callable object
291 """
292 return lambda *args, **kwargs: \
293 _check_ref(lambda r: r in XendNode.instance().pif_metrics,
294 'PIF_metrics', func, *args, **kwargs)
296 def valid_task(func):
297 """Decorator to verify if task_ref is valid before calling
298 method.
300 @param func: function with params: (self, session, task_ref)
301 @rtype: callable object
302 """
303 return lambda *args, **kwargs: \
304 _check_ref(XendTaskManager.get_task,
305 'task', func, *args, **kwargs)
307 def valid_debug(func):
308 """Decorator to verify if task_ref is valid before calling
309 method.
311 @param func: function with params: (self, session, task_ref)
312 @rtype: callable object
313 """
314 return lambda *args, **kwargs: \
315 _check_ref(lambda r: r in XendAPI._debug,
316 'debug', func, *args, **kwargs)
318 # -----------------------------
319 # Bridge to Legacy XM API calls
320 # -----------------------------
322 def do_vm_func(fn_name, vm_ref, *args, **kwargs):
323 """Helper wrapper func to abstract away from repetitive code.
325 @param fn_name: function name for XendDomain instance
326 @type fn_name: string
327 @param vm_ref: vm_ref
328 @type vm_ref: string
329 @param *args: more arguments
330 @type *args: tuple
331 """
332 try:
333 xendom = XendDomain.instance()
334 fn = getattr(xendom, fn_name)
335 xendom.do_legacy_api_with_uuid(fn, vm_ref, *args, **kwargs)
336 return xen_api_success_void()
337 except VMBadState, exn:
338 return xen_api_error(['VM_BAD_POWER_STATE', vm_ref, exn.expected,
339 exn.actual])
342 class XendAPI(object):
343 """Implementation of the Xen-API in Xend. Expects to be
344 used via XMLRPCServer.
346 All methods that need a valid session are marked with
347 a L{session_required} decorator that will
348 transparently perform the required session authentication.
350 We need to support Python <2.4, so we use the old decorator syntax.
352 All XMLRPC accessible methods require an 'api' attribute and
353 is set to the XMLRPC function name which the method implements.
354 """
356 __decorated__ = False
357 __init_lock__ = threading.Lock()
358 _debug = {}
360 def __new__(cls, *args, **kwds):
361 """ Override __new__ to decorate the class only once.
363 Lock to make sure the classes are not decorated twice.
364 """
365 cls.__init_lock__.acquire()
366 try:
367 if not cls.__decorated__:
368 cls._decorate()
369 cls.__decorated__ = True
371 return object.__new__(cls, *args, **kwds)
372 finally:
373 cls.__init_lock__.release()
375 def _decorate(cls):
376 """ Decorate all the object methods to have validators
377 and appropriate function attributes.
379 This should only be executed once for the duration of the
380 server.
381 """
382 global_validators = [session_required, catch_typeerror]
383 classes = {
384 'session' : None,
385 'host' : valid_host,
386 'host_cpu' : valid_host_cpu,
387 'host_metrics' : valid_host_metrics,
388 'network' : valid_network,
389 'VM' : valid_vm,
390 'VBD' : valid_vbd,
391 'VBD_metrics' : valid_vbd_metrics,
392 'VIF' : valid_vif,
393 'VDI' : valid_vdi,
394 'VTPM' : valid_vtpm,
395 'console' : valid_console,
396 'SR' : valid_sr,
397 'PIF' : valid_pif,
398 'PIF_metrics' : valid_pif_metrics,
399 'task' : valid_task,
400 'debug' : valid_debug,
401 }
403 # Cheat methods
404 # -------------
405 # Methods that have a trivial implementation for all classes.
406 # 1. get_by_uuid == getting by ref, so just return uuid for
407 # all get_by_uuid() methods.
409 for api_cls in classes.keys():
410 if api_cls == 'session':
411 continue
413 get_by_uuid = '%s_get_by_uuid' % api_cls
414 get_uuid = '%s_get_uuid' % api_cls
415 def _get_by_uuid(_1, _2, ref):
416 return xen_api_success(ref)
418 def _get_uuid(_1, _2, ref):
419 return xen_api_success(ref)
421 setattr(cls, get_by_uuid, _get_by_uuid)
422 setattr(cls, get_uuid, _get_uuid)
424 # Wrapping validators around XMLRPC calls
425 # ---------------------------------------
427 for api_cls, validator in classes.items():
428 def doit(n, takes_instance, async_support = False,
429 return_type = None):
430 n_ = n.replace('.', '_')
431 try:
432 f = getattr(cls, n_)
433 argcounts[n] = f.func_code.co_argcount - 1
435 validators = takes_instance and validator and \
436 [validator] or []
438 validators += global_validators
439 for v in validators:
440 f = v(f)
441 f.api = n
442 f.async = async_support
443 if return_type:
444 f.return_type = return_type
446 setattr(cls, n_, f)
447 except AttributeError:
448 log.warn("API call: %s not found" % n)
451 ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
452 rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
453 methods = getattr(cls, '%s_methods' % api_cls, [])
454 funcs = getattr(cls, '%s_funcs' % api_cls, [])
456 # wrap validators around readable class attributes
457 for attr_name in ro_attrs + rw_attrs + cls.Base_attr_ro:
458 doit('%s.get_%s' % (api_cls, attr_name), True,
459 async_support = False)
461 # wrap validators around writable class attrributes
462 for attr_name in rw_attrs + cls.Base_attr_rw:
463 doit('%s.set_%s' % (api_cls, attr_name), True,
464 async_support = False)
466 # wrap validators around methods
467 for method_name, return_type in methods + cls.Base_methods:
468 doit('%s.%s' % (api_cls, method_name), True,
469 async_support = True)
471 # wrap validators around class functions
472 for func_name, return_type in funcs + cls.Base_funcs:
473 doit('%s.%s' % (api_cls, func_name), False, async_support = True,
474 return_type = return_type)
476 _decorate = classmethod(_decorate)
478 def __init__(self, auth):
479 self.auth = auth
481 Base_attr_ro = ['uuid']
482 Base_attr_rw = []
483 Base_methods = [('destroy', None), ('get_record', 'Struct')]
484 Base_funcs = [('get_all', 'Set'), ('get_by_uuid', None)]
486 # Xen API: Class Session
487 # ----------------------------------------------------------------
488 # NOTE: Left unwrapped by __init__
490 session_attr_ro = ['this_host', 'this_user']
491 session_methods = [('logout', None)]
493 def session_login_with_password(self, *args):
494 if len(args) != 2:
495 return xen_api_error(
496 ['MESSAGE_PARAMETER_COUNT_MISMATCH',
497 'session.login_with_password', 2, len(args)])
498 username = args[0]
499 password = args[1]
500 try:
501 session = (self.auth == AUTH_NONE and
502 auth_manager().login_unconditionally(username) or
503 auth_manager().login_with_password(username, password))
504 return xen_api_success(session)
505 except XendError, e:
506 return xen_api_error(['SESSION_AUTHENTICATION_FAILED'])
507 session_login_with_password.api = 'session.login_with_password'
509 # object methods
510 def session_logout(self, session):
511 auth_manager().logout(session)
512 return xen_api_success_void()
513 def session_get_record(self, session):
514 record = {'uuid' : session,
515 'this_host': XendNode.instance().uuid,
516 'this_user': auth_manager().get_user(session)}
517 return xen_api_success(record)
519 def session_get_uuid(self, session):
520 return xen_api_success(session)
522 def session_get_by_uuid(self, session):
523 return xen_api_success(session)
525 # attributes (ro)
526 def session_get_this_host(self, session):
527 return xen_api_success(XendNode.instance().uuid)
528 def session_get_this_user(self, session):
529 user = auth_manager().get_user(session)
530 if user:
531 return xen_api_success(user)
532 return xen_api_error(['SESSION_INVALID', session])
535 # Xen API: Class User
536 # ----------------------------------------------------------------
537 # TODO: NOT IMPLEMENTED YET
539 # Xen API: Class Tasks
540 # ----------------------------------------------------------------
542 task_attr_ro = ['name_label',
543 'name_description',
544 'status',
545 'progress',
546 'type',
547 'result',
548 'error_code',
549 'error_info',
550 'allowed_operations',
551 'session'
552 ]
554 task_attr_rw = []
556 task_funcs = [('get_by_name_label', 'Set(task)'),
557 ('cancel', None)]
559 def task_get_name_label(self, session, task_ref):
560 task = XendTaskManager.get_task(task_ref)
561 return xen_api_success(task.name_label)
563 def task_get_name_description(self, session, task_ref):
564 task = XendTaskManager.get_task(task_ref)
565 return xen_api_success(task.name_description)
567 def task_get_status(self, session, task_ref):
568 task = XendTaskManager.get_task(task_ref)
569 return xen_api_success(task.get_status())
571 def task_get_progress(self, session, task_ref):
572 task = XendTaskManager.get_task(task_ref)
573 return xen_api_success(task.progress)
575 def task_get_type(self, session, task_ref):
576 task = XendTaskManager.get_task(task_ref)
577 return xen_api_success(task.type)
579 def task_get_result(self, session, task_ref):
580 task = XendTaskManager.get_task(task_ref)
581 return xen_api_success(task.result)
583 def task_get_error_code(self, session, task_ref):
584 task = XendTaskManager.get_task(task_ref)
585 return xen_api_success(task.error_code)
587 def task_get_error_info(self, session, task_ref):
588 task = XendTaskManager.get_task(task_ref)
589 return xen_api_success(task.error_info)
591 def task_get_allowed_operations(self, session, task_ref):
592 return xen_api_success({})
594 def task_get_session(self, session, task_ref):
595 task = XendTaskManager.get_task(task_ref)
596 return xen_api_success(task.session)
598 def task_get_all(self, session):
599 tasks = XendTaskManager.get_all_tasks()
600 return xen_api_success(tasks)
602 def task_get_record(self, session, task_ref):
603 task = XendTaskManager.get_task(task_ref)
604 return xen_api_success(task.get_record())
606 def task_cancel(self, session, task_ref):
607 return xen_api_error('OPERATION_NOT_ALLOWED')
609 def task_get_by_name_label(self, session, name):
610 return xen_api_success(XendTaskManager.get_task_by_name(name))
612 # Xen API: Class host
613 # ----------------------------------------------------------------
615 host_attr_ro = ['software_version',
616 'resident_VMs',
617 'host_CPUs',
618 'metrics']
620 host_attr_rw = ['name_label',
621 'name_description',
622 'other_config']
624 host_methods = [('disable', None),
625 ('enable', None),
626 ('reboot', None),
627 ('shutdown', None),
628 ('add_to_other_config', None),
629 ('remove_from_other_config', None),
630 ('dmesg', 'String')]
632 host_funcs = [('get_by_name_label', 'Set(host)')]
634 # attributes
635 def host_get_name_label(self, session, host_ref):
636 return xen_api_success(XendNode.instance().name)
637 def host_set_name_label(self, session, host_ref, new_name):
638 XendNode.instance().set_name(new_name)
639 return xen_api_success_void()
640 def host_get_name_description(self, session, host_ref):
641 return xen_api_success(XendNode.instance().description)
642 def host_set_name_description(self, session, host_ref, new_desc):
643 XendNode.instance().set_description(new_desc)
644 return xen_api_success_void()
645 def host_get_other_config(self, session, host_ref):
646 return xen_api_success(XendNode.instance().other_config)
647 def host_set_other_config(self, session, host_ref, other_config):
648 node = XendNode.instance()
649 node.other_config = dict(other_config)
650 node.save()
651 return xen_api_success_void()
652 def host_add_to_other_config(self, session, host_ref, key, value):
653 node = XendNode.instance()
654 node.other_config[key] = value
655 node.save()
656 return xen_api_success_void()
657 def host_remove_from_other_config(self, session, host_ref, key):
658 node = XendNode.instance()
659 del node.other_config[key]
660 node.save()
661 return xen_api_success_void()
662 def host_get_software_version(self, session, host_ref):
663 return xen_api_success(XendNode.instance().xen_version())
664 def host_get_resident_VMs(self, session, host_ref):
665 return xen_api_success(XendDomain.instance().get_domain_refs())
666 def host_get_host_CPUs(self, session, host_ref):
667 return xen_api_success(XendNode.instance().get_host_cpu_refs())
668 def host_get_metrics(self, _, ref):
669 return xen_api_success(XendNode.instance().host_metrics_uuid)
671 # object methods
672 def host_destroy(self, session, host_ref):
673 return xen_api_error(XEND_ERROR_UNSUPPORTED)
674 def host_disable(self, session, host_ref):
675 XendDomain.instance().set_allow_new_domains(False)
676 return xen_api_success_void()
677 def host_enable(self, session, host_ref):
678 XendDomain.instance().set_allow_new_domains(True)
679 return xen_api_success_void()
680 def host_reboot(self, session, host_ref):
681 if not XendDomain.instance().allow_new_domains():
682 return xen_api_error(XEND_ERROR_HOST_RUNNING)
683 return xen_api_error(XEND_ERROR_UNSUPPORTED)
684 def host_shutdown(self, session, host_ref):
685 if not XendDomain.instance().allow_new_domains():
686 return xen_api_error(XEND_ERROR_HOST_RUNNING)
687 return xen_api_error(XEND_ERROR_UNSUPPORTED)
689 def host_dmesg(self, session, host_ref):
690 return xen_api_success(XendDmesg.instance().info())
692 def host_get_record(self, session, host_ref):
693 node = XendNode.instance()
694 dom = XendDomain.instance()
695 record = {'uuid': node.uuid,
696 'name_label': node.name,
697 'name_description': '',
698 'software_version': node.xen_version(),
699 'resident_VMs': dom.get_domain_refs(),
700 'host_CPUs': node.get_host_cpu_refs(),
701 'metrics': node.host_metrics_uuid}
702 return xen_api_success(record)
704 # class methods
705 def host_get_all(self, session):
706 return xen_api_success((XendNode.instance().uuid,))
707 def host_create(self, session, struct):
708 return xen_api_error(XEND_ERROR_UNSUPPORTED)
709 def host_get_by_name_label(self, session, name):
710 if XendNode.instance().name == name:
711 return xen_api_success((XendNode.instance().uuid,))
712 return xen_api_success([])
715 # Xen API: Class host_CPU
716 # ----------------------------------------------------------------
718 host_cpu_attr_ro = ['host',
719 'number',
720 'utilisation']
722 # attributes
723 def host_cpu_get_host(self, session, host_cpu_ref):
724 return xen_api_success(XendNode.instance().uuid)
725 def host_cpu_get_utilisation(self, session, host_cpu_ref):
726 util = XendNode.instance().get_host_cpu_load(host_cpu_ref)
727 return xen_api_success(util)
728 def host_cpu_get_number(self, session, host_cpu_ref):
729 num = XendNode.instance().get_host_cpu_number(host_cpu_ref)
730 return xen_api_success(num)
732 # object methods
733 def host_cpu_destroy(self, session, host_cpu_ref):
734 return xen_api_error(XEND_ERROR_UNSUPPORTED)
735 def host_cpu_get_record(self, session, host_cpu_ref):
736 node = XendNode.instance()
737 record = {'uuid': host_cpu_ref,
738 'host': node.uuid,
739 'number': node.get_host_cpu_number(host_cpu_ref),
740 'utilisation': node.get_host_cpu_load(host_cpu_ref)}
741 return xen_api_success(record)
743 # class methods
744 def host_cpu_get_all(self, session):
745 return xen_api_success(XendNode.instance().get_host_cpu_refs())
748 # Xen API: Class host_metrics
749 # ----------------------------------------------------------------
751 host_metrics_attr_ro = ['memory_total',
752 'memory_free',
753 'host']
754 host_metrics_attr_rw = []
755 host_metrics_methods = []
757 def _host_metrics_get(self, ref, f):
758 return xen_api_success(getattr(node, f)())
760 def host_metrics_get_record(self, _, ref):
761 return xen_api_success({
762 'uuid' : ref,
763 'host' : XendNode.instance().uuid,
764 'memory_total' : self._host_metrics_get_memory_total(),
765 'memory_free' : self._host_metrics_get_memory_free(),
766 })
768 def host_metrics_get_host(self, _, ref):
769 return xen_api_success(XendNode.instance().uuid)
771 def host_metrics_get_memory_total(self, _, ref):
772 return xen_api_success(self._host_metrics_get_memory_total())
774 def host_metrics_get_memory_free(self, _, ref):
775 return xen_api_success(self._host_metrics_get_memory_free())
777 def _host_metrics_get_memory_total(self):
778 node = XendNode.instance()
779 return node.xc.physinfo()['total_memory'] * 1024
781 def _host_metrics_get_memory_free(self):
782 node = XendNode.instance()
783 return node.xc.physinfo()['free_memory'] * 1024
786 # Xen API: Class network
787 # ----------------------------------------------------------------
789 network_attr_ro = ['VIFs', 'PIFs']
790 network_attr_rw = ['name_label',
791 'name_description',
792 'default_gateway',
793 'default_netmask']
795 network_funcs = [('create', 'network')]
797 def network_create(self, _, name_label, name_description,
798 default_gateway, default_netmask):
799 return xen_api_success(
800 XendNode.instance().network_create(name_label, name_description,
801 default_gateway,
802 default_netmask))
804 def network_destroy(self, _, ref):
805 return xen_api_success(XendNode.instance().network_destroy(ref))
807 def _get_network(self, ref):
808 return XendNode.instance().get_network(ref)
810 def network_get_all(self, _):
811 return xen_api_success(XendNode.instance().get_network_refs())
813 def network_get_record(self, _, ref):
814 return xen_api_success(
815 XendNode.instance().get_network(ref).get_record())
817 def network_get_name_label(self, _, ref):
818 return xen_api_success(self._get_network(ref).name_label)
820 def network_get_name_description(self, _, ref):
821 return xen_api_success(self._get_network(ref).name_description)
823 def network_get_default_gateway(self, _, ref):
824 return xen_api_success(self._get_network(ref).default_gateway)
826 def network_get_default_netmask(self, _, ref):
827 return xen_api_success(self._get_network(ref).default_netmask)
829 def network_get_VIFs(self, _, ref):
830 return xen_api_success(self._get_network(ref).get_VIF_UUIDs())
832 def network_get_PIFs(self, session, ref):
833 return xen_api_success(self._get_network(ref).get_PIF_UUIDs())
835 def network_set_name_label(self, _, ref, val):
836 return xen_api_success(self._get_network(ref).set_name_label(val))
838 def network_set_name_description(self, _, ref, val):
839 return xen_api_success(self._get_network(ref).set_name_description(val))
841 def network_set_default_gateway(self, _, ref, val):
842 return xen_api_success(self._get_network(ref).set_default_gateway(val))
844 def network_set_default_netmask(self, _, ref, val):
845 return xen_api_success(self._get_network(ref).set_default_netmask(val))
848 # Xen API: Class PIF
849 # ----------------------------------------------------------------
851 PIF_attr_ro = ['metrics']
852 PIF_attr_rw = ['device',
853 'network',
854 'host',
855 'MAC',
856 'MTU',
857 'VLAN']
859 PIF_attr_inst = PIF_attr_rw
861 PIF_methods = [('create_VLAN', 'int')]
863 def _get_PIF(self, ref):
864 return XendNode.instance().pifs[ref]
866 def PIF_destroy(self, _, ref):
867 try:
868 return xen_api_success(XendNode.instance().PIF_destroy(ref))
869 except PIFIsPhysical, exn:
870 return xen_api_error(['PIF_IS_PHYSICAL', ref])
872 # object methods
873 def PIF_get_record(self, _, ref):
874 return xen_api_success(self._get_PIF(ref).get_record())
876 def PIF_get_all(self, _):
877 return xen_api_success(XendNode.instance().pifs.keys())
879 def PIF_get_metrics(self, _, ref):
880 return xen_api_success(self._get_PIF(ref).metrics.uuid)
882 def PIF_get_device(self, _, ref):
883 return xen_api_success(self._get_PIF(ref).device)
885 def PIF_get_network(self, _, ref):
886 return xen_api_success(self._get_PIF(ref).network.uuid)
888 def PIF_get_host(self, _, ref):
889 return xen_api_success(self._get_PIF(ref).host.uuid)
891 def PIF_get_MAC(self, _, ref):
892 return xen_api_success(self._get_PIF(ref).mac)
894 def PIF_get_MTU(self, _, ref):
895 return xen_api_success(self._get_PIF(ref).mtu)
897 def PIF_get_VLAN(self, _, ref):
898 return xen_api_success(self._get_PIF(ref).vlan)
900 def PIF_set_device(self, _, ref, device):
901 return xen_api_success(self._get_PIF(ref).set_device(device))
903 def PIF_set_MAC(self, _, ref, mac):
904 return xen_api_success(self._get_PIF(ref).set_mac(mac))
906 def PIF_set_MTU(self, _, ref, mtu):
907 return xen_api_success(self._get_PIF(ref).set_mtu(mtu))
909 def PIF_create_VLAN(self, _, ref, network, vlan):
910 try:
911 vlan = int(vlan)
912 except:
913 return xen_api_error(['VLAN_TAG_INVALID', vlan])
915 try:
916 node = XendNode.instance()
918 if _is_valid_ref(network, node.is_valid_network):
919 return xen_api_success(
920 node.PIF_create_VLAN(ref, network, vlan))
921 else:
922 return xen_api_error(['HANDLE_INVALID', 'network', network])
923 except NetworkAlreadyConnected, exn:
924 return xen_api_error(['NETWORK_ALREADY_CONNECTED',
925 network, exn.pif_uuid])
926 except VLANTagInvalid:
927 return xen_api_error(['VLAN_TAG_INVALID', vlan])
930 # Xen API: Class PIF_metrics
931 # ----------------------------------------------------------------
933 PIF_metrics_attr_ro = ['PIF',
934 'io_read_kbs',
935 'io_write_kbs']
936 PIF_metrics_attr_rw = []
937 PIF_methods = []
939 def _PIF_metrics_get(self, ref):
940 return XendNode.instance().pif_metrics[ref]
942 def PIF_metrics_get_record(self, _, ref):
943 return xen_api_success(self._PIF_metrics_get(ref).get_record())
945 def PIF_metrics_get_PIF(self, _, ref):
946 return xen_api_success(self._PIF_metrics_get(ref).pif.uuid)
948 def PIF_metrics_get_io_read_kbs(self, _, ref):
949 return xen_api_success(self._PIF_metrics_get(ref).get_io_read_kbs())
951 def PIF_metrics_get_io_write_kbs(self, _, ref):
952 return xen_api_success(self._PIF_metrics_get(ref).get_io_write_kbs())
955 # Xen API: Class VM
956 # ----------------------------------------------------------------
958 VM_attr_ro = ['power_state',
959 'resident_on',
960 'memory_actual',
961 'memory_static_max',
962 'memory_static_min',
963 'VCPUs_number',
964 'VCPUs_utilisation',
965 'consoles',
966 'VIFs',
967 'VBDs',
968 'VTPMs',
969 'PCI_bus',
970 'tools_version',
971 'is_control_domain',
972 ]
974 VM_attr_rw = ['name_label',
975 'name_description',
976 'user_version',
977 'is_a_template',
978 'auto_power_on',
979 'memory_dynamic_max',
980 'memory_dynamic_min',
981 'VCPUs_policy',
982 'VCPUs_params',
983 'actions_after_shutdown',
984 'actions_after_reboot',
985 'actions_after_suspend',
986 'actions_after_crash',
987 'PV_bootloader',
988 'PV_kernel',
989 'PV_ramdisk',
990 'PV_args',
991 'PV_bootloader_args',
992 'HVM_boot_policy',
993 'HVM_boot_params',
994 'platform_std_VGA',
995 'platform_serial',
996 'platform_localtime',
997 'platform_clock_offset',
998 'platform_enable_audio',
999 'platform_keymap',
1000 'other_config']
1002 VM_methods = [('clone', 'VM'),
1003 ('start', None),
1004 ('pause', None),
1005 ('unpause', None),
1006 ('clean_shutdown', None),
1007 ('clean_reboot', None),
1008 ('hard_shutdown', None),
1009 ('hard_reboot', None),
1010 ('suspend', None),
1011 ('resume', None),
1012 ('add_to_other_config', None),
1013 ('remove_from_other_config', None)]
1015 VM_funcs = [('create', 'VM'),
1016 ('get_by_name_label', 'Set(VM)')]
1018 # parameters required for _create()
1019 VM_attr_inst = [
1020 'name_label',
1021 'name_description',
1022 'user_version',
1023 'is_a_template',
1024 'memory_static_max',
1025 'memory_dynamic_max',
1026 'memory_dynamic_min',
1027 'memory_static_min',
1028 'VCPUs_policy',
1029 'VCPUs_params',
1030 'actions_after_shutdown',
1031 'actions_after_reboot',
1032 'actions_after_suspend',
1033 'actions_after_crash',
1034 'PV_bootloader',
1035 'PV_kernel',
1036 'PV_ramdisk',
1037 'PV_args',
1038 'PV_bootloader_args',
1039 'HVM_boot_policy',
1040 'HVM_boot_params',
1041 'platform_std_VGA',
1042 'platform_serial',
1043 'platform_localtime',
1044 'platform_clock_offset',
1045 'platform_enable_audio',
1046 'platform_keymap',
1047 'grub_cmdline',
1048 'PCI_bus',
1049 'other_config']
1051 def VM_get(self, name, session, vm_ref):
1052 return xen_api_success(
1053 XendDomain.instance().get_vm_by_uuid(vm_ref).info[name])
1055 def VM_set(self, name, session, vm_ref, value):
1056 xd = XendDomain.instance()
1057 dominfo = xd.get_vm_by_uuid(vm_ref)
1058 dominfo.info[name] = value
1059 xd.managed_config_save(dominfo)
1060 return xen_api_success_void()
1062 # attributes (ro)
1063 def VM_get_power_state(self, session, vm_ref):
1064 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1065 return xen_api_success(dom.get_power_state())
1067 def VM_get_resident_on(self, session, vm_ref):
1068 return xen_api_success(XendNode.instance().uuid)
1070 def VM_get_memory_actual(self, session, vm_ref):
1071 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1072 return xen_api_todo() # unsupported by xc
1074 def VM_get_memory_static_max(self, session, vm_ref):
1075 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1076 return xen_api_success(dom.get_memory_static_max())
1078 def VM_get_memory_static_min(self, session, vm_ref):
1079 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1080 return xen_api_success(dom.get_memory_static_min())
1082 def VM_get_VCPUs_number(self, session, vm_ref):
1083 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1084 return xen_api_success(dom.getVCpuCount())
1086 def VM_get_VCPUs_utilisation(self, session, vm_ref):
1087 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1088 return xen_api_success(dom.get_vcpus_util())
1090 def VM_get_VIFs(self, session, vm_ref):
1091 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1092 return xen_api_success(dom.get_vifs())
1094 def VM_get_VBDs(self, session, vm_ref):
1095 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1096 return xen_api_success(dom.get_vbds())
1098 def VM_get_VTPMs(self, session, vm_ref):
1099 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1100 return xen_api_success(dom.get_vtpms())
1102 def VM_get_consoles(self, session, vm_ref):
1103 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1104 return xen_api_success(dom.get_consoles())
1106 def VM_get_PCI_bus(self, session, vm_ref):
1107 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1108 return dom.get_pci_bus()
1110 def VM_get_tools_version(self, session, vm_ref):
1111 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1112 return dom.get_tools_version()
1114 # attributes (rw)
1115 def VM_get_name_label(self, session, vm_ref):
1116 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1117 return xen_api_success(dom.getName())
1119 def VM_get_name_description(self, session, vm_ref):
1120 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1121 return xen_api_todo()
1123 def VM_get_user_version(self, session, vm_ref):
1124 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1125 return xen_api_todo()
1127 def VM_get_is_a_template(self, session, vm_ref):
1128 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1129 return xen_api_todo()
1131 def VM_get_memory_dynamic_max(self, session, vm_ref):
1132 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1133 return xen_api_success(dom.get_memory_dynamic_max())
1135 def VM_get_memory_dynamic_min(self, session, vm_ref):
1136 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1137 return xen_api_success(dom.get_memory_dynamic_min())
1139 def VM_get_VCPUs_policy(self, session, vm_ref):
1140 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1141 return xen_api_success(dom.get_vcpus_policy())
1143 def VM_get_VCPUs_params(self, session, vm_ref):
1144 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1145 return xen_api_success(dom.get_vcpus_params())
1147 def VM_get_actions_after_shutdown(self, session, vm_ref):
1148 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1149 return xen_api_success(dom.get_on_shutdown())
1151 def VM_get_actions_after_reboot(self, session, vm_ref):
1152 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1153 return xen_api_success(dom.get_on_reboot())
1155 def VM_get_actions_after_suspend(self, session, vm_ref):
1156 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1157 return xen_api_success(dom.get_on_suspend())
1159 def VM_get_actions_after_crash(self, session, vm_ref):
1160 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1161 return xen_api_success(dom.get_on_crash())
1163 def VM_get_PV_bootloader(self, session, vm_ref):
1164 return self.VM_get('PV_bootloader', session, vm_ref)
1166 def VM_get_PV_kernel(self, session, vm_ref):
1167 return self.VM_get('PV_kernel', session, vm_ref)
1169 def VM_get_PV_ramdisk(self, session, vm_ref):
1170 return self.VM_get('PV_ramdisk', session, vm_ref)
1172 def VM_get_PV_args(self, session, vm_ref):
1173 return self.VM_get('PV_args', session, vm_ref)
1175 def VM_get_PV_bootloader_args(self, session, vm_ref):
1176 return self.VM_get('PV_bootloader_args', session, vm_ref)
1178 def VM_get_HVM_boot_policy(self, session, vm_ref):
1179 return self.VM_get('HVM_boot_policy', session, vm_ref)
1181 def VM_get_HVM_boot_params(self, session, vm_ref):
1182 return self.VM_get('HVM_boot_params', session, vm_ref)
1184 def VM_get_platform_std_VGA(self, session, vm_ref):
1185 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1186 return xen_api_success(dom.get_platform_std_vga())
1188 def VM_get_platform_serial(self, session, vm_ref):
1189 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1190 return xen_api_success(dom.get_platform_serial())
1192 def VM_get_platform_localtime(self, session, vm_ref):
1193 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1194 return xen_api_success(dom.get_platform_localtime())
1196 def VM_get_platform_clock_offset(self, session, vm_ref):
1197 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1198 return xen_api_success(dom.get_platform_clock_offset())
1200 def VM_get_platform_enable_audio(self, session, vm_ref):
1201 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1202 return xen_api_success(dom.get_platform_enable_audio())
1204 def VM_get_platform_keymap(self, session, vm_ref):
1205 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1206 return xen_api_success(dom.get_platform_keymap())
1208 def VM_get_other_config(self, session, vm_ref):
1209 return self.VM_get('other_config', session, vm_ref)
1211 def VM_get_is_control_domain(self, session, vm_ref):
1212 xd = XendDomain.instance()
1213 return xen_api_success(
1214 xd.get_vm_by_uuid(vm_ref) == xd.privilegedDomain())
1216 def VM_set_name_label(self, session, vm_ref, label):
1217 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1218 dom.setName(label)
1219 return xen_api_success_void()
1221 def VM_set_name_description(self, session, vm_ref, desc):
1222 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1223 return xen_api_todo()
1225 def VM_set_user_version(self, session, vm_ref, ver):
1226 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1227 return xen_api_todo()
1229 def VM_set_is_a_template(self, session, vm_ref, is_template):
1230 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1231 return xen_api_todo()
1233 def VM_set_memory_dynamic_max(self, session, vm_ref, mem):
1234 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1235 return xen_api_todo()
1237 def VM_set_memory_dynamic_min(self, session, vm_ref, mem):
1238 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1239 return xen_api_todo()
1241 def VM_set_VCPUs_policy(self, session, vm_ref, policy):
1242 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1243 return xen_api_todo()
1245 def VM_set_VCPUs_params(self, session, vm_ref, params):
1246 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1247 return xen_api_todo()
1249 def VM_set_actions_after_shutdown(self, session, vm_ref, action):
1250 if action not in XEN_API_ON_NORMAL_EXIST:
1251 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1252 return self.VM_set('actions_after_shutdown', session, vm_ref, action)
1254 def VM_set_actions_after_reboot(self, session, vm_ref, action):
1255 if action not in XEN_API_ON_NORMAL_EXIST:
1256 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1257 return self.VM_set('actions_after_reboot', session, vm_ref, action)
1259 def VM_set_actions_after_suspend(self, session, vm_ref, action):
1260 if action not in XEN_API_ON_NORMAL_EXIT:
1261 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1262 return self.VM_set('actions_after_suspend', session, vm_ref, action)
1264 def VM_set_actions_after_crash(self, session, vm_ref, action):
1265 if action not in XEN_API_ON_CRASH_BEHAVIOUR:
1266 return xen_api_error(['VM_ON_CRASH_BEHAVIOUR_INVALID', vm_ref])
1267 return self.VM_set('actions_after_crash', session, vm_ref, action)
1269 def VM_set_HVM_boot_policy(self, session, vm_ref, value):
1270 if value != "" and value != "BIOS order":
1271 return xen_api_error(
1272 ['VALUE_NOT_SUPPORTED', 'VM.HVM_boot_policy', value,
1273 'Xend supports only the "BIOS order" boot policy.'])
1274 else:
1275 return self.VM_set('HVM_boot_policy', session, vm_ref, value)
1277 def VM_set_HVM_boot_params(self, session, vm_ref, value):
1278 return self.VM_set('HVM_boot_params', session, vm_ref, value)
1280 def VM_add_to_HVM_boot_params(self, session, vm_ref, key, value):
1281 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1282 if 'HVM_boot_params' not in dom.info:
1283 dom.info['HVM_boot_params'] = {}
1284 dom.info['HVM_boot_params'][key] = value
1285 return xen_api_success_void()
1287 def VM_remove_from_HVM_boot_params(self, session, vm_ref, key):
1288 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1289 if 'HVM_boot_params' in dom.info \
1290 and key in dom.info['HVM_boot_params']:
1291 del dom.info['HVM_boot_params'][key]
1292 return xen_api_success_void()
1294 def VM_set_PV_bootloader(self, session, vm_ref, value):
1295 return self.VM_set('PV_bootloader', session, vm_ref, value)
1297 def VM_set_PV_kernel(self, session, vm_ref, value):
1298 return self.VM_set('PV_kernel', session, vm_ref, value)
1300 def VM_set_PV_ramdisk(self, session, vm_ref, value):
1301 return self.VM_set('PV_ramdisk', session, vm_ref, value)
1303 def VM_set_PV_args(self, session, vm_ref, value):
1304 return self.VM_set('PV_args', session, vm_ref, value)
1306 def VM_set_PV_bootloader_args(self, session, vm_ref, value):
1307 return self.VM_set('PV_bootloader_args', session, vm_ref, value)
1309 def VM_set_platform_std_VGA(self, session, vm_ref, value):
1310 return self.VM_set('platform_std_vga', session, vm_ref, value)
1312 def VM_set_platform_serial(self, session, vm_ref, value):
1313 return self.VM_set('platform_serial', session, vm_ref, value)
1315 def VM_set_platform_keymap(self, session, vm_ref, value):
1316 return self.VM_set('platform_keymap', session, vm_ref, value)
1318 def VM_set_platform_localtime(self, session, vm_ref, value):
1319 return self.VM_set('platform_localtime', session, vm_ref, value)
1321 def VM_set_platform_clock_offset(self, session, vm_ref, value):
1322 return self.VM_set('platform_clock_offset', session, vm_ref, value)
1324 def VM_set_platform_enable_audio(self, session, vm_ref, value):
1325 return self.VM_set('platform_enable_audio', session, vm_ref, value)
1327 def VM_set_other_config(self, session, vm_ref, value):
1328 return self.VM_set('otherconfig', session, vm_ref, value)
1330 def VM_add_to_other_config(self, session, vm_ref, key, value):
1331 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1332 if dom and 'otherconfig' in dom.info:
1333 dom.info['otherconfig'][key] = value
1334 return xen_api_success_void()
1336 def VM_remove_from_other_config(self, session, vm_ref, key):
1337 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1338 if dom and 'otherconfig' in dom.info \
1339 and key in dom.info['otherconfig']:
1340 del dom.info['otherconfig'][key]
1341 return xen_api_success_void()
1343 # class methods
1344 def VM_get_all(self, session):
1345 refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
1346 return xen_api_success(refs)
1348 def VM_get_by_name_label(self, session, label):
1349 xendom = XendDomain.instance()
1350 dom = xendom.domain_lookup_nr(label)
1351 if dom:
1352 return xen_api_success([dom.get_uuid()])
1353 return xen_api_success([])
1355 def VM_create(self, session, vm_struct):
1356 xendom = XendDomain.instance()
1357 domuuid = XendTask.log_progress(0, 100,
1358 xendom.create_domain, vm_struct)
1359 return xen_api_success(domuuid)
1361 # object methods
1362 def VM_get_record(self, session, vm_ref):
1363 xendom = XendDomain.instance()
1364 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1365 if not xeninfo:
1366 return xen_api_error(['HANDLE_INVALID', 'VM', vm_ref])
1368 record = {
1369 'uuid': xeninfo.get_uuid(),
1370 'power_state': xeninfo.get_power_state(),
1371 'name_label': xeninfo.getName(),
1372 'name_description': xeninfo.getName(),
1373 'user_version': 1,
1374 'is_a_template': False,
1375 'auto_power_on': False,
1376 'resident_on': XendNode.instance().uuid,
1377 'memory_static_min': xeninfo.get_memory_static_min(),
1378 'memory_static_max': xeninfo.get_memory_static_max(),
1379 'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
1380 'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
1381 'memory_actual': xeninfo.get_memory_static_min(),
1382 'VCPUs_policy': xeninfo.get_vcpus_policy(),
1383 'VCPUs_params': xeninfo.get_vcpus_params(),
1384 'VCPUs_number': xeninfo.getVCpuCount(),
1385 'VCPUs_utilisation': xeninfo.get_vcpus_util(),
1386 'actions_after_shutdown': xeninfo.get_on_shutdown(),
1387 'actions_after_reboot': xeninfo.get_on_reboot(),
1388 'actions_after_suspend': xeninfo.get_on_suspend(),
1389 'actions_after_crash': xeninfo.get_on_crash(),
1390 'consoles': xeninfo.get_consoles(),
1391 'VIFs': xeninfo.get_vifs(),
1392 'VBDs': xeninfo.get_vbds(),
1393 'VTPMs': xeninfo.get_vtpms(),
1394 'PV_bootloader': xeninfo.info.get('PV_bootloader'),
1395 'PV_kernel': xeninfo.info.get('PV_kernel'),
1396 'PV_ramdisk': xeninfo.info.get('PV_ramdisk'),
1397 'PV_args': xeninfo.info.get('PV_args'),
1398 'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
1399 'HVM_boot_policy': xeninfo.info.get('HVM_boot_policy'),
1400 'HVM_boot_params': xeninfo.info.get('HVM_boot_params'),
1401 'platform_std_VGA': xeninfo.get_platform_std_vga(),
1402 'platform_serial': xeninfo.get_platform_serial(),
1403 'platform_localtime': xeninfo.get_platform_localtime(),
1404 'platform_clock_offset': xeninfo.get_platform_clock_offset(),
1405 'platform_enable_audio': xeninfo.get_platform_enable_audio(),
1406 'platform_keymap': xeninfo.get_platform_keymap(),
1407 'PCI_bus': xeninfo.get_pci_bus(),
1408 'tools_version': xeninfo.get_tools_version(),
1409 'other_config': xeninfo.info.get('other_config', {}),
1410 'is_control_domain': xeninfo == xendom.privilegedDomain(),
1412 return xen_api_success(record)
1414 def VM_clean_reboot(self, session, vm_ref):
1415 xendom = XendDomain.instance()
1416 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1417 XendTask.log_progress(0, 100, xeninfo.shutdown, "reboot")
1418 return xen_api_success_void()
1420 def VM_clean_shutdown(self, session, vm_ref):
1421 xendom = XendDomain.instance()
1422 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1423 XendTask.log_progress(0, 100, xeninfo.shutdown, "poweroff")
1424 return xen_api_success_void()
1426 def VM_clone(self, session, vm_ref):
1427 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1429 def VM_destroy(self, session, vm_ref):
1430 return XendTask.log_progress(0, 100, do_vm_func,
1431 "domain_delete", vm_ref)
1433 def VM_hard_reboot(self, session, vm_ref):
1434 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1436 def VM_hard_shutdown(self, session, vm_ref):
1437 return XendTask.log_progress(0, 100, do_vm_func,
1438 "domain_destroy", vm_ref)
1439 def VM_pause(self, session, vm_ref):
1440 return XendTask.log_progress(0, 100, do_vm_func,
1441 "domain_pause", vm_ref)
1443 def VM_resume(self, session, vm_ref, start_paused):
1444 return XendTask.log_progress(0, 100, do_vm_func,
1445 "domain_resume", vm_ref,
1446 start_paused = start_paused)
1448 def VM_start(self, session, vm_ref, start_paused):
1449 return XendTask.log_progress(0, 100, do_vm_func,
1450 "domain_start", vm_ref,
1451 start_paused = start_paused)
1453 def VM_suspend(self, session, vm_ref):
1454 return XendTask.log_progress(0, 100, do_vm_func,
1455 "domain_suspend", vm_ref)
1457 def VM_unpause(self, session, vm_ref):
1458 return XendTask.log_progress(0, 100, do_vm_func,
1459 "domain_unpause", vm_ref)
1461 # Xen API: Class VBD
1462 # ----------------------------------------------------------------
1464 VBD_attr_ro = ['metrics']
1465 VBD_attr_rw = ['VM',
1466 'VDI',
1467 'device',
1468 'bootable',
1469 'mode',
1470 'type']
1472 VBD_attr_inst = VBD_attr_rw
1474 VBD_methods = [('media_change', None)]
1475 VBD_funcs = [('create', 'VBD')]
1477 # object methods
1478 def VBD_get_record(self, session, vbd_ref):
1479 xendom = XendDomain.instance()
1480 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1481 if not vm:
1482 return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
1483 cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
1484 if not cfg:
1485 return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
1487 valid_vbd_keys = self.VBD_attr_ro + self.VBD_attr_rw + \
1488 self.Base_attr_ro + self.Base_attr_rw
1490 return_cfg = {}
1491 for k in cfg.keys():
1492 if k in valid_vbd_keys:
1493 return_cfg[k] = cfg[k]
1495 return_cfg['metrics'] = vbd_ref
1497 return xen_api_success(return_cfg)
1499 def VBD_media_change(self, session, vbd_ref, vdi_ref):
1500 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1502 # class methods
1503 def VBD_create(self, session, vbd_struct):
1504 xendom = XendDomain.instance()
1505 if not xendom.is_valid_vm(vbd_struct['VM']):
1506 return xen_api_error(['HANDLE_INVALID', 'VM', vbd_struct['VM']])
1508 dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
1509 vbd_ref = ''
1510 try:
1511 # new VBD via VDI/SR
1512 vdi_ref = vbd_struct.get('VDI')
1513 vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
1514 if not vdi:
1515 return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
1516 vdi_image = vdi.get_location()
1517 vbd_ref = XendTask.log_progress(0, 100,
1518 dom.create_vbd,
1519 vbd_struct, vdi_image)
1520 except XendError:
1521 return xen_api_todo()
1523 xendom.managed_config_save(dom)
1524 return xen_api_success(vbd_ref)
1527 def VBD_destroy(self, session, vbd_ref):
1528 xendom = XendDomain.instance()
1529 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1530 if not vm:
1531 return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
1533 XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref)
1534 return xen_api_success_void()
1536 def _VBD_get(self, vbd_ref, prop):
1537 return xen_api_success(
1538 XendDomain.instance().get_dev_property_by_uuid(
1539 'vbd', vbd_ref, prop))
1541 # attributes (ro)
1542 def VBD_get_metrics(self, _, vbd_ref):
1543 return xen_api_success(vbd_ref)
1545 # attributes (rw)
1546 def VBD_get_VM(self, session, vbd_ref):
1547 return self._VBD_get(vbd_ref, 'VM')
1549 def VBD_get_VDI(self, session, vbd_ref):
1550 return self._VBD_get(vbd_ref, 'VDI')
1552 def VBD_get_device(self, session, vbd_ref):
1553 return self._VBD_get(vbd_ref, 'device')
1555 def VBD_get_bootable(self, session, vbd_ref):
1556 return self._VBD_get(vbd_ref, 'bootable')
1558 def VBD_get_mode(self, session, vbd_ref):
1559 return self._VBD_get(vbd_ref, 'mode')
1561 def VBD_get_type(self, session, vbd_ref):
1562 return self._VBD_get(vbd_ref, 'type')
1564 def VBD_set_bootable(self, session, vbd_ref, bootable):
1565 bootable = bool(bootable)
1566 xd = XendDomain.instance()
1567 vm = xd.get_vm_with_dev_uuid('vbd', vbd_ref)
1568 vm.set_dev_property('vbd', vbd_ref, 'bootable', bootable)
1569 xd.managed_config_save(vm)
1570 return xen_api_success_void()
1572 def VBD_get_all(self, session):
1573 xendom = XendDomain.instance()
1574 vbds = [d.get_vbds() for d in XendDomain.instance().list('all')]
1575 vbds = reduce(lambda x, y: x + y, vbds)
1576 return xen_api_success(vbds)
1579 # Xen API: Class VBD_metrics
1580 # ----------------------------------------------------------------
1582 VBD_metrics_attr_ro = ['io_read_kbs',
1583 'io_write_kbs']
1584 VBD_metrics_attr_rw = []
1585 VBD_methods = []
1587 def VBD_metrics_get_record(self, _, ref):
1588 vm = XendDomain.instance().get_vm_with_dev_uuid('vbd', ref)
1589 if not vm:
1590 return xen_api_error(['HANDLE_INVALID', 'VBD_metrics', ref])
1591 return xen_api_success(
1592 { 'io_read_kbs' : vm.get_dev_property('vbd', ref, 'io_read_kbs'),
1593 'io_write_kbs' : vm.get_dev_property('vbd', ref, 'io_write_kbs') })
1595 def VBD_metrics_get_io_write_kbs(self, _, ref):
1596 return self._VBD_get(ref, 'io_read_kbs')
1598 def VBD_metrics_get_io_write_kbs(self, session, vbd_ref):
1599 return self._VBD_get(ref, 'io_write_kbs')
1602 # Xen API: Class VIF
1603 # ----------------------------------------------------------------
1605 VIF_attr_ro = ['io_read_kbs',
1606 'io_write_kbs']
1607 VIF_attr_rw = ['device',
1608 'network',
1609 'VM',
1610 'MAC',
1611 'MTU']
1613 VIF_attr_inst = VIF_attr_rw
1615 VIF_funcs = [('create', 'VIF')]
1618 # object methods
1619 def VIF_get_record(self, session, vif_ref):
1620 xendom = XendDomain.instance()
1621 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1622 if not vm:
1623 return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
1624 cfg = vm.get_dev_xenapi_config('vif', vif_ref)
1625 if not cfg:
1626 return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
1628 valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
1629 self.Base_attr_ro + self.Base_attr_rw
1631 return_cfg = {}
1632 for k in cfg.keys():
1633 if k in valid_vif_keys:
1634 return_cfg[k] = cfg[k]
1636 return xen_api_success(return_cfg)
1638 # class methods
1639 def VIF_create(self, session, vif_struct):
1640 xendom = XendDomain.instance()
1641 if xendom.is_valid_vm(vif_struct['VM']):
1642 dom = xendom.get_vm_by_uuid(vif_struct['VM'])
1643 try:
1644 vif_ref = dom.create_vif(vif_struct)
1645 xendom.managed_config_save(dom)
1646 return xen_api_success(vif_ref)
1647 except XendError:
1648 return xen_api_error(XEND_ERROR_TODO)
1649 else:
1650 return xen_api_error(['HANDLE_INVALID', 'VM', vif_struct['VM']])
1653 def VIF_destroy(self, session, vif_ref):
1654 xendom = XendDomain.instance()
1655 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1656 if not vm:
1657 return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
1659 vm.destroy_vif(vif_ref)
1660 return xen_api_success_void()
1662 # getters/setters
1663 def VIF_get_VM(self, session, vif_ref):
1664 xendom = XendDomain.instance()
1665 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1666 return xen_api_success(vm.get_uuid())
1668 def VIF_get_MTU(self, session, vif_ref):
1669 xendom = XendDomain.instance()
1670 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1671 'MTU'))
1672 def VIF_get_MAC(self, session, vif_ref):
1673 xendom = XendDomain.instance()
1674 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1675 'MAC'))
1677 def VIF_get_device(self, session, vif_ref):
1678 xendom = XendDomain.instance()
1679 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1680 'device'))
1682 def VIF_get_io_read_kbs(self, session, vif_ref):
1683 xendom = XendDomain.instance()
1684 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1685 'io_read_kbs'))
1687 def VIF_get_io_write_kbs(self, session, vif_ref):
1688 xendom = XendDomain.instance()
1689 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1690 'io_write_kbs'))
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 VDI
1700 # ----------------------------------------------------------------
1701 VDI_attr_ro = ['VBDs',
1702 'physical_utilisation',
1703 'sector_size',
1704 'type']
1705 VDI_attr_rw = ['name_label',
1706 'name_description',
1707 'SR',
1708 'virtual_size',
1709 'sharable',
1710 'read_only']
1711 VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
1713 VDI_methods = [('snapshot', 'VDI')]
1714 VDI_funcs = [('create', 'VDI'),
1715 ('get_by_name_label', 'Set(VDI)')]
1717 def _get_VDI(self, ref):
1718 return XendNode.instance().get_vdi_by_uuid(ref)
1720 def VDI_get_VBDs(self, session, vdi_ref):
1721 return xen_api_todo()
1723 def VDI_get_physical_utilisation(self, session, vdi_ref):
1724 return xen_api_success(self._get_VDI(vdi_ref).
1725 get_physical_utilisation())
1727 def VDI_get_sector_size(self, session, vdi_ref):
1728 return xen_api_success(self._get_VDI(vdi_ref).sector_size)
1730 def VDI_get_type(self, session, vdi_ref):
1731 return xen_api_success(self._get_VDI(vdi_ref).type)
1733 def VDI_get_name_label(self, session, vdi_ref):
1734 return xen_api_success(self._get_VDI(vdi_ref).name_label)
1736 def VDI_get_name_description(self, session, vdi_ref):
1737 return xen_api_success(self._get_VDI(vdi_ref).name_description)
1739 def VDI_get_SR(self, session, vdi_ref):
1740 return xen_api_success(self._get_VDI(vdi_ref).sr_uuid)
1742 def VDI_get_virtual_size(self, session, vdi_ref):
1743 return xen_api_success(self._get_VDI(vdi_ref).virtual_size)
1745 def VDI_get_sharable(self, session, vdi_ref):
1746 return xen_api_success(self._get_VDI(vdi_ref).sharable)
1748 def VDI_get_read_only(self, session, vdi_ref):
1749 return xen_api_success(self._get_VDI(vdi_ref).read_only)
1751 def VDI_set_name_label(self, session, vdi_ref, value):
1752 self._get_VDI(vdi_ref).name_label = value
1753 return xen_api_success_void()
1755 def VDI_set_name_description(self, session, vdi_ref, value):
1756 self._get_VDI(vdi_ref).name_description = value
1757 return xen_api_success_void()
1759 def VDI_set_SR(self, session, vdi_ref, value):
1760 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1762 def VDI_set_virtual_size(self, session, vdi_ref, value):
1763 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1765 def VDI_set_sharable(self, session, vdi_ref, value):
1766 self._get_VDI(vdi_ref).sharable = bool(value)
1767 return xen_api_success_void()
1769 def VDI_set_read_only(self, session, vdi_ref, value):
1770 self._get_VDI(vdi_ref).read_only = bool(value)
1771 return xen_api_success_void()
1773 # Object Methods
1774 def VDI_snapshot(self, session, vdi_ref):
1775 return xen_api_todo()
1777 def VDI_destroy(self, session, vdi_ref):
1778 sr = XendNode.instance().get_sr_containing_vdi(vdi_ref)
1779 sr.destroy_vdi(vdi_ref)
1780 return xen_api_success_void()
1782 def VDI_get_record(self, session, vdi_ref):
1783 image = XendNode.instance().get_vdi_by_uuid(vdi_ref)
1784 return xen_api_success({
1785 'uuid': vdi_ref,
1786 'name_label': image.name_label,
1787 'name_description': image.name_description,
1788 'SR': image.sr_uuid,
1789 'VBDs': [], # TODO
1790 'virtual_size': image.virtual_size,
1791 'physical_utilisation': image.physical_utilisation,
1792 'sector_size': image.sector_size,
1793 'type': image.type,
1794 'sharable': image.sharable,
1795 'read_only': image.read_only,
1796 })
1798 # Class Functions
1799 def VDI_create(self, session, vdi_struct):
1800 sr_ref = vdi_struct.get('SR')
1801 xennode = XendNode.instance()
1802 if not xennode.is_valid_sr(sr_ref):
1803 return xen_api_error(['HANDLE_INVALID', 'SR', sr_ref])
1805 vdi_uuid = xennode.srs[sr_ref].create_vdi(vdi_struct)
1806 return xen_api_success(vdi_uuid)
1808 def VDI_get_all(self, session):
1809 xennode = XendNode.instance()
1810 vdis = [sr.get_vdis() for sr in xennode.srs.values()]
1811 return xen_api_success(reduce(lambda x, y: x + y, vdis))
1813 def VDI_get_by_name_label(self, session, name):
1814 xennode = XendNode.instance()
1815 return xen_api_success(xennode.get_vdi_by_name_label(name))
1818 # Xen API: Class VTPM
1819 # ----------------------------------------------------------------
1821 VTPM_attr_rw = [ ]
1822 VTPM_attr_ro = ['VM',
1823 'backend']
1825 VTPM_attr_inst = VTPM_attr_rw
1827 VTPM_funcs = [('create', 'VTPM')]
1829 # object methods
1830 def VTPM_get_record(self, session, vtpm_ref):
1831 xendom = XendDomain.instance()
1832 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1833 if not vm:
1834 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
1835 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1836 if not cfg:
1837 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
1838 valid_vtpm_keys = self.VTPM_attr_ro + self.VTPM_attr_rw + \
1839 self.Base_attr_ro + self.Base_attr_rw
1840 return_cfg = {}
1841 for k in cfg.keys():
1842 if k in valid_vtpm_keys:
1843 return_cfg[k] = cfg[k]
1845 return xen_api_success(return_cfg)
1847 # Class Functions
1848 def VTPM_get_backend(self, session, vtpm_ref):
1849 xendom = XendDomain.instance()
1850 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1851 if not vm:
1852 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
1853 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1854 if not cfg:
1855 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
1856 if not cfg.has_key('backend'):
1857 return xen_api_error(['VTPM backend not set'])
1858 return xen_api_success(cfg['backend'])
1860 def VTPM_get_VM(self, session, vtpm_ref):
1861 xendom = XendDomain.instance()
1862 return xen_api_success(xendom.get_dev_property_by_uuid('vtpm',
1863 vtpm_ref, 'VM'))
1865 def VTPM_destroy(self, session, vtpm_ref):
1866 xendom = XendDomain.instance()
1867 dom = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1868 if dom:
1869 if dom.state != XEN_API_VM_POWER_STATE_HALTED:
1870 vm_ref = dom.get_dev_property('vtpm', vtpm_ref, 'VM')
1871 return xen_api_error(['VM_BAD_POWER_STATE', vm_ref,
1872 XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_HALTED],
1873 XendDomain.POWER_STATE_NAMES[dom.state]])
1874 from xen.xend.server import tpmif
1875 tpmif.destroy_vtpmstate(dom.getName())
1876 return xen_api_success(True)
1877 else:
1878 return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']])
1880 # class methods
1881 def VTPM_create(self, session, vtpm_struct):
1882 xendom = XendDomain.instance()
1883 if xendom.is_valid_vm(vtpm_struct['VM']):
1884 dom = xendom.get_vm_by_uuid(vtpm_struct['VM'])
1885 try:
1886 vtpm_ref = dom.create_vtpm(vtpm_struct)
1887 xendom.managed_config_save(dom)
1888 return xen_api_success(vtpm_ref)
1889 except XendError:
1890 return xen_api_error(XEND_ERROR_TODO)
1891 else:
1892 return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']])
1894 def VTPM_get_all(self, session):
1895 xendom = XendDomain.instance()
1896 vtpms = [d.get_vtpms() for d in XendDomain.instance().list('all')]
1897 vtpms = reduce(lambda x, y: x + y, vtpms)
1898 return xen_api_success(vtpms)
1900 # Xen API: Class console
1901 # ----------------------------------------------------------------
1904 console_attr_ro = ['location', 'protocol', 'VM']
1905 console_attr_rw = ['other_config']
1906 console_funcs = [('create', 'console')]
1908 def console_get_all(self, session):
1909 xendom = XendDomain.instance()
1910 cons = [d.get_consoles() for d in XendDomain.instance().list('all')]
1911 cons = reduce(lambda x, y: x + y, cons)
1912 return xen_api_success(cons)
1914 def console_get_location(self, session, console_ref):
1915 return xen_api_success(xendom.get_dev_property_by_uuid('console',
1916 console_ref,
1917 'location'))
1919 def console_get_protocol(self, session, console_ref):
1920 return xen_api_success(xendom.get_dev_property_by_uuid('console',
1921 console_ref,
1922 'protocol'))
1924 def console_get_VM(self, session, console_ref):
1925 xendom = XendDomain.instance()
1926 vm = xendom.get_vm_with_dev_uuid('console', console_ref)
1927 return xen_api_success(vm.get_uuid())
1929 # object methods
1930 def console_get_record(self, session, console_ref):
1931 xendom = XendDomain.instance()
1932 vm = xendom.get_vm_with_dev_uuid('console', console_ref)
1933 if not vm:
1934 return xen_api_error(['HANDLE_INVALID', 'console', console_ref])
1935 cfg = vm.get_dev_xenapi_config('console', console_ref)
1936 if not cfg:
1937 return xen_api_error(['HANDLE_INVALID', 'console', console_ref])
1939 valid_console_keys = self.console_attr_ro + self.console_attr_rw + \
1940 self.Base_attr_ro + self.Base_attr_rw
1942 return_cfg = {}
1943 for k in cfg.keys():
1944 if k in valid_console_keys:
1945 return_cfg[k] = cfg[k]
1947 return xen_api_success(return_cfg)
1949 def console_create(self, session, console_struct):
1950 xendom = XendDomain.instance()
1951 if not xendom.is_valid_vm(console_struct['VM']):
1952 return xen_api_error(['HANDLE_INVALID', 'VM',
1953 console_struct['VM']])
1955 dom = xendom.get_vm_by_uuid(console_struct['VM'])
1956 try:
1957 if 'protocol' not in console_struct:
1958 return xen_api_error(['CONSOLE_PROTOCOL_INVALID',
1959 'No protocol specified'])
1961 console_ref = dom.create_console(console_struct)
1962 xendom.managed_config_save(dom)
1963 return xen_api_success(console_ref)
1964 except XendError, e:
1965 return xen_api_error([XEND_ERROR_TODO, str(e)])
1967 # Xen API: Class SR
1968 # ----------------------------------------------------------------
1969 SR_attr_ro = ['VDIs',
1970 'virtual_allocation',
1971 'physical_utilisation',
1972 'physical_size',
1973 'type',
1974 'location']
1976 SR_attr_rw = ['name_label',
1977 'name_description']
1979 SR_attr_inst = ['physical_size',
1980 'type',
1981 'location',
1982 'name_label',
1983 'name_description']
1985 SR_methods = [('clone', 'SR')]
1986 SR_funcs = [('get_by_name_label', 'Set(SR)'),
1987 ('get_by_uuid', 'SR')]
1989 # Class Functions
1990 def SR_get_all(self, session):
1991 return xen_api_success(XendNode.instance().get_all_sr_uuid())
1993 def SR_get_by_name_label(self, session, label):
1994 return xen_api_success(XendNode.instance().get_sr_by_name(label))
1996 def SR_create(self, session):
1997 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1999 # Class Methods
2000 def SR_clone(self, session, sr_ref):
2001 return xen_api_error(XEND_ERROR_UNSUPPORTED)
2003 def SR_destroy(self, session, sr_ref):
2004 return xen_api_error(XEND_ERROR_UNSUPPORTED)
2006 def SR_get_record(self, session, sr_ref):
2007 sr = XendNode.instance().get_sr(sr_ref)
2008 if sr:
2009 return xen_api_success(sr.get_record())
2010 return xen_api_error(['HANDLE_INVALID', 'SR', sr_ref])
2012 # Attribute acceess
2014 def _get_SR_func(self, sr_ref, func):
2015 return xen_api_success(getattr(XendNode.instance().get_sr(sr_ref),
2016 func)())
2018 def _get_SR_attr(self, sr_ref, attr):
2019 return xen_api_success(getattr(XendNode.instance().get_sr(sr_ref),
2020 attr))
2022 def SR_get_VDIs(self, _, ref):
2023 return self._get_SR_func(ref, 'list_images')
2025 def SR_get_virtual_allocation(self, _, ref):
2026 return self._get_SR_func(ref, 'virtual_allocation')
2028 def SR_get_physical_utilisation(self, _, ref):
2029 return self._get_SR_func(ref, 'physical_utilisation')
2031 def SR_get_physical_size(self, _, ref):
2032 return self._get_SR_func(ref, 'physical_size')
2034 def SR_get_type(self, _, ref):
2035 return self._get_SR_attr(ref, 'type')
2037 def SR_get_location(self, _, ref):
2038 return self._get_SR_attr(ref, 'location')
2040 def SR_get_name_label(self, _, ref):
2041 return self._get_SR_attr(ref, 'name_label')
2043 def SR_get_name_description(self, _, ref):
2044 return self._get_SR_attr(ref, 'name_description')
2046 def SR_set_name_label(self, session, sr_ref, value):
2047 sr = XendNode.instance.get_sr(sr_ref)
2048 if sr:
2049 sr.name_label = value
2050 XendNode.instance().save()
2051 return xen_api_success_void()
2053 def SR_set_name_description(self, session, sr_ref, value):
2054 sr = XendNode.instance.get_sr(sr_ref)
2055 if sr:
2056 sr.name_description = value
2057 XendNode.instance().save()
2058 return xen_api_success_void()
2061 # Xen API: Class debug
2062 # ----------------------------------------------------------------
2064 debug_methods = [('destroy', None),
2065 ('get_record', 'debug')]
2066 debug_funcs = [('wait', None),
2067 ('return_failure', None)]
2069 def debug_wait(self, session, wait_secs):
2070 import time
2071 prog_units = 100/float(wait_secs)
2072 for i in range(int(wait_secs)):
2073 XendTask.log_progress(prog_units * i, prog_units * (i + 1),
2074 time.sleep, 1)
2075 return xen_api_success_void()
2078 def debug_return_failure(self, session):
2079 return xen_api_error(['DEBUG_FAIL', session])
2081 def debug_create(self, session):
2082 debug_uuid = uuid.createString()
2083 self._debug[debug_uuid] = None
2084 return xen_api_success(debug_uuid)
2086 def debug_destroy(self, session, debug_ref):
2087 del self._debug[debug_ref]
2088 return xen_api_success_void()
2090 def debug_get_record(self, session, debug_ref):
2091 return xen_api_success({'uuid': debug_ref})
2095 class XendAPIAsyncProxy:
2096 """ A redirector for Async.Class.function calls to XendAPI
2097 but wraps the call for use with the XendTaskManager.
2099 @ivar xenapi: Xen API instance
2100 @ivar method_map: Mapping from XMLRPC method name to callable objects.
2101 """
2103 method_prefix = 'Async.'
2105 def __init__(self, xenapi):
2106 """Initialises the Async Proxy by making a map of all
2107 implemented Xen API methods for use with XendTaskManager.
2109 @param xenapi: XendAPI instance
2110 """
2111 self.xenapi = xenapi
2112 self.method_map = {}
2113 for method_name in dir(self.xenapi):
2114 method = getattr(self.xenapi, method_name)
2115 if method_name[0] != '_' and hasattr(method, 'async') \
2116 and method.async == True:
2117 self.method_map[method.api] = method
2119 def _dispatch(self, method, args):
2120 """Overridden method so that SimpleXMLRPCServer will
2121 resolve methods through this method rather than through
2122 inspection.
2124 @param method: marshalled method name from XMLRPC.
2125 @param args: marshalled arguments from XMLRPC.
2126 """
2128 # Only deal with method names that start with "Async."
2129 if not method.startswith(self.method_prefix):
2130 return xen_api_error(['MESSAGE_METHOD_UNKNOWN', method])
2132 # Lookup synchronous version of the method
2133 synchronous_method_name = method[len(self.method_prefix):]
2134 if synchronous_method_name not in self.method_map:
2135 return xen_api_error(['MESSAGE_METHOD_UNKNOWN', method])
2137 method = self.method_map[synchronous_method_name]
2139 # Check that we've got enough arguments before issuing a task ID.
2140 needed = argcounts[method.api]
2141 if len(args) != needed:
2142 return xen_api_error(['MESSAGE_PARAMETER_COUNT_MISMATCH',
2143 self.method_prefix + method.api, needed,
2144 len(args)])
2146 # Validate the session before proceeding
2147 session = args[0]
2148 if not auth_manager().is_session_valid(session):
2149 return xen_api_error(['SESSION_INVALID', session])
2151 # create and execute the task, and return task_uuid
2152 return_type = getattr(method, 'return_type', None)
2153 task_uuid = XendTaskManager.create_task(method, args,
2154 synchronous_method_name,
2155 return_type,
2156 synchronous_method_name,
2157 session)
2158 return xen_api_success(task_uuid)
2161 # Auto generate some stubs based on XendAPI introspection
2163 if __name__ == "__main__":
2164 def output(line):
2165 print ' ' + line
2167 classes = ['VDI', 'SR']
2168 for cls in classes:
2169 ro_attrs = getattr(XendAPI, '%s_attr_ro' % cls, [])
2170 rw_attrs = getattr(XendAPI, '%s_attr_rw' % cls, [])
2171 methods = getattr(XendAPI, '%s_methods' % cls, [])
2172 funcs = getattr(XendAPI, '%s_funcs' % cls, [])
2174 ref = '%s_ref' % cls
2176 for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
2177 getter_name = '%s_get_%s' % (cls, attr_name)
2178 output('def %s(self, session, %s):' % (getter_name, ref))
2179 output(' return xen_api_todo()')
2181 for attr_name in rw_attrs + XendAPI.Base_attr_rw:
2182 setter_name = '%s_set_%s' % (cls, attr_name)
2183 output('def %s(self, session, %s, value):' % (setter_name, ref))
2184 output(' return xen_api_todo()')
2186 for method_name in methods + XendAPI.Base_methods:
2187 method_full_name = '%s_%s' % (cls,method_name)
2188 output('def %s(self, session, %s):' % (method_full_name, ref))
2189 output(' return xen_api_todo()')
2191 for func_name in funcs + XendAPI.Base_funcs:
2192 func_full_name = '%s_%s' % (cls, func_name)
2193 output('def %s(self, session):' % func_full_name)
2194 output(' return xen_api_todo()')