ia64/xen-unstable

view tools/python/xen/xend/XendAPI.py @ 13782:f63e1244b48d

[XEND] Fix VCPU_params to return string map.

Signed-off-by: Alastair Tse <atse@xensource.com>
author Alastair Tse <atse@xensource.com>
date Wed Jan 31 15:01:09 2007 +0000 (2007-01-31)
parents 3cccf8e64296
children 3291a7b48731
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
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, errcode, 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([errcode, 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_HANDLE_INVALID', 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_HANDLE_INVALID', 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_HANDLE_INVALID', 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_HANDLE_INVALID', 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_HANDLE_INVALID', 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_HANDLE_INVALID', func, *args, **kwargs)
212 def valid_vif(func):
213 """Decorator to verify if vif_ref is valid before calling method.
215 @param func: function with params: (self, session, vif_ref, ...)
216 @rtype: callable object
217 """
218 return lambda *args, **kwargs: \
219 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vif', r),
220 'VIF_HANDLE_INVALID', func, *args, **kwargs)
222 def valid_vdi(func):
223 """Decorator to verify if vdi_ref is valid before calling method.
225 @param func: function with params: (self, session, vdi_ref, ...)
226 @rtype: callable object
227 """
228 return lambda *args, **kwargs: \
229 _check_ref(XendNode.instance().is_valid_vdi,
230 'VDI_HANDLE_INVALID', func, *args, **kwargs)
232 def valid_vtpm(func):
233 """Decorator to verify if vtpm_ref is valid before calling method.
235 @param func: function with params: (self, session, vtpm_ref, ...)
236 @rtype: callable object
237 """
238 return lambda *args, **kwargs: \
239 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vtpm', r),
240 'VTPM_HANDLE_INVALID', func, *args, **kwargs)
243 def valid_console(func):
244 """Decorator to verify if console_ref is valid before calling method.
246 @param func: function with params: (self, session, console_ref, ...)
247 @rtype: callable object
248 """
249 return lambda *args, **kwargs: \
250 _check_ref(lambda r: XendDomain.instance().is_valid_dev('console',
251 r),
252 'CONSOLE_HANDLE_INVALID', func, *args, **kwargs)
254 def valid_sr(func):
255 """Decorator to verify if sr_ref is valid before calling method.
257 @param func: function with params: (self, session, sr_ref, ...)
258 @rtype: callable object
259 """
260 return lambda *args, **kwargs: \
261 _check_ref(lambda r: XendNode.instance().is_valid_sr,
262 'SR_HANDLE_INVALID', func, *args, **kwargs)
264 def valid_pif(func):
265 """Decorator to verify if pif_ref is valid before calling
266 method.
268 @param func: function with params: (self, session, pif_ref)
269 @rtype: callable object
270 """
271 return lambda *args, **kwargs: \
272 _check_ref(lambda r: r in XendNode.instance().pifs,
273 'PIF_HANDLE_INVALID', func, *args, **kwargs)
275 def valid_pif_metrics(func):
276 """Decorator to verify if pif_metrics_ref is valid before calling
277 method.
279 @param func: function with params: (self, session, pif_metrics_ref)
280 @rtype: callable object
281 """
282 return lambda *args, **kwargs: \
283 _check_ref(lambda r: r in XendNode.instance().pif_metrics,
284 'PIF_METRICS_HANDLE_INVALID', func, *args, **kwargs)
286 def valid_task(func):
287 """Decorator to verify if task_ref is valid before calling
288 method.
290 @param func: function with params: (self, session, task_ref)
291 @rtype: callable object
292 """
293 return lambda *args, **kwargs: \
294 _check_ref(XendTaskManager.get_task,
295 'TASK_HANDLE_INVALID', func, *args, **kwargs)
297 def valid_debug(func):
298 """Decorator to verify if task_ref is valid before calling
299 method.
301 @param func: function with params: (self, session, task_ref)
302 @rtype: callable object
303 """
304 return lambda *args, **kwargs: \
305 _check_ref(lambda r: r in XendAPI._debug,
306 'TASK_HANDLE_INVALID', func, *args, **kwargs)
308 # -----------------------------
309 # Bridge to Legacy XM API calls
310 # -----------------------------
312 def do_vm_func(fn_name, vm_ref, *args, **kwargs):
313 """Helper wrapper func to abstract away from repetitive code.
315 @param fn_name: function name for XendDomain instance
316 @type fn_name: string
317 @param vm_ref: vm_ref
318 @type vm_ref: string
319 @param *args: more arguments
320 @type *args: tuple
321 """
322 try:
323 xendom = XendDomain.instance()
324 fn = getattr(xendom, fn_name)
325 xendom.do_legacy_api_with_uuid(fn, vm_ref, *args, **kwargs)
326 return xen_api_success_void()
327 except VMBadState, exn:
328 return xen_api_error(['VM_BAD_POWER_STATE', vm_ref, exn.expected,
329 exn.actual])
332 class XendAPI(object):
333 """Implementation of the Xen-API in Xend. Expects to be
334 used via XMLRPCServer.
336 All methods that need a valid session are marked with
337 a L{session_required} decorator that will
338 transparently perform the required session authentication.
340 We need to support Python <2.4, so we use the old decorator syntax.
342 All XMLRPC accessible methods require an 'api' attribute and
343 is set to the XMLRPC function name which the method implements.
344 """
346 __decorated__ = False
347 __init_lock__ = threading.Lock()
348 _debug = {}
350 def __new__(cls, *args, **kwds):
351 """ Override __new__ to decorate the class only once.
353 Lock to make sure the classes are not decorated twice.
354 """
355 cls.__init_lock__.acquire()
356 try:
357 if not cls.__decorated__:
358 cls._decorate()
359 cls.__decorated__ = True
361 return object.__new__(cls, *args, **kwds)
362 finally:
363 cls.__init_lock__.release()
365 def _decorate(cls):
366 """ Decorate all the object methods to have validators
367 and appropriate function attributes.
369 This should only be executed once for the duration of the
370 server.
371 """
372 global_validators = [session_required, catch_typeerror]
373 classes = {
374 'session' : None,
375 'host' : valid_host,
376 'host_cpu' : valid_host_cpu,
377 'host_metrics' : valid_host_metrics,
378 'network' : valid_network,
379 'VM' : valid_vm,
380 'VBD' : valid_vbd,
381 'VIF' : valid_vif,
382 'VDI' : valid_vdi,
383 'VTPM' : valid_vtpm,
384 'console' : valid_console,
385 'SR' : valid_sr,
386 'PIF' : valid_pif,
387 'PIF_metrics' : valid_pif_metrics,
388 'task' : valid_task,
389 'debug' : valid_debug,
390 }
392 # Cheat methods
393 # -------------
394 # Methods that have a trivial implementation for all classes.
395 # 1. get_by_uuid == getting by ref, so just return uuid for
396 # all get_by_uuid() methods.
398 for api_cls in classes.keys():
399 if api_cls == 'session':
400 continue
402 get_by_uuid = '%s_get_by_uuid' % api_cls
403 get_uuid = '%s_get_uuid' % api_cls
404 def _get_by_uuid(_1, _2, ref):
405 return xen_api_success(ref)
407 def _get_uuid(_1, _2, ref):
408 return xen_api_success(ref)
410 setattr(cls, get_by_uuid, _get_by_uuid)
411 setattr(cls, get_uuid, _get_uuid)
413 # Wrapping validators around XMLRPC calls
414 # ---------------------------------------
416 for api_cls, validator in classes.items():
417 def doit(n, takes_instance, async_support = False,
418 return_type = None):
419 n_ = n.replace('.', '_')
420 try:
421 f = getattr(cls, n_)
422 argcounts[n] = f.func_code.co_argcount - 1
424 validators = takes_instance and validator and \
425 [validator] or []
427 validators += global_validators
428 for v in validators:
429 f = v(f)
430 f.api = n
431 f.async = async_support
432 if return_type:
433 f.return_type = return_type
435 setattr(cls, n_, f)
436 except AttributeError:
437 log.warn("API call: %s not found" % n)
440 ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
441 rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
442 methods = getattr(cls, '%s_methods' % api_cls, [])
443 funcs = getattr(cls, '%s_funcs' % api_cls, [])
445 # wrap validators around readable class attributes
446 for attr_name in ro_attrs + rw_attrs + cls.Base_attr_ro:
447 doit('%s.get_%s' % (api_cls, attr_name), True,
448 async_support = False)
450 # wrap validators around writable class attrributes
451 for attr_name in rw_attrs + cls.Base_attr_rw:
452 doit('%s.set_%s' % (api_cls, attr_name), True,
453 async_support = False)
455 # wrap validators around methods
456 for method_name, return_type in methods + cls.Base_methods:
457 doit('%s.%s' % (api_cls, method_name), True,
458 async_support = True)
460 # wrap validators around class functions
461 for func_name, return_type in funcs + cls.Base_funcs:
462 doit('%s.%s' % (api_cls, func_name), False, async_support = True,
463 return_type = return_type)
465 _decorate = classmethod(_decorate)
467 def __init__(self, auth):
468 self.auth = auth
470 Base_attr_ro = ['uuid']
471 Base_attr_rw = []
472 Base_methods = [('destroy', None), ('get_record', 'Struct')]
473 Base_funcs = [('get_all', 'Set'), ('get_by_uuid', None)]
475 # Xen API: Class Session
476 # ----------------------------------------------------------------
477 # NOTE: Left unwrapped by __init__
479 session_attr_ro = ['this_host', 'this_user']
480 session_methods = [('logout', None)]
482 def session_login_with_password(self, *args):
483 if len(args) != 2:
484 return xen_api_error(
485 ['MESSAGE_PARAMETER_COUNT_MISMATCH',
486 'session.login_with_password', 2, len(args)])
487 username = args[0]
488 password = args[1]
489 try:
490 session = (self.auth == AUTH_NONE and
491 auth_manager().login_unconditionally(username) or
492 auth_manager().login_with_password(username, password))
493 return xen_api_success(session)
494 except XendError, e:
495 return xen_api_error(['SESSION_AUTHENTICATION_FAILED'])
496 session_login_with_password.api = 'session.login_with_password'
498 # object methods
499 def session_logout(self, session):
500 auth_manager().logout(session)
501 return xen_api_success_void()
502 def session_get_record(self, session):
503 record = {'uuid' : session,
504 'this_host': XendNode.instance().uuid,
505 'this_user': auth_manager().get_user(session)}
506 return xen_api_success(record)
508 def session_get_uuid(self, session):
509 return xen_api_success(session)
511 def session_get_by_uuid(self, session):
512 return xen_api_success(session)
514 # attributes (ro)
515 def session_get_this_host(self, session):
516 return xen_api_success(XendNode.instance().uuid)
517 def session_get_this_user(self, session):
518 user = auth_manager().get_user(session)
519 if user:
520 return xen_api_success(user)
521 return xen_api_error(['SESSION_INVALID', session])
524 # Xen API: Class User
525 # ----------------------------------------------------------------
526 # TODO: NOT IMPLEMENTED YET
528 # Xen API: Class Tasks
529 # ----------------------------------------------------------------
531 task_attr_ro = ['name_label',
532 'name_description',
533 'status',
534 'progress',
535 'type',
536 'result',
537 'error_code',
538 'error_info',
539 'allowed_operations',
540 'session'
541 ]
543 task_attr_rw = []
545 task_funcs = [('get_by_name_label', 'Set(task)'),
546 ('cancel', None)]
548 def task_get_name_label(self, session, task_ref):
549 task = XendTaskManager.get_task(task_ref)
550 return xen_api_success(task.name_label)
552 def task_get_name_description(self, session, task_ref):
553 task = XendTaskManager.get_task(task_ref)
554 return xen_api_success(task.name_description)
556 def task_get_status(self, session, task_ref):
557 task = XendTaskManager.get_task(task_ref)
558 return xen_api_success(task.get_status())
560 def task_get_progress(self, session, task_ref):
561 task = XendTaskManager.get_task(task_ref)
562 return xen_api_success(task.progress)
564 def task_get_type(self, session, task_ref):
565 task = XendTaskManager.get_task(task_ref)
566 return xen_api_success(task.type)
568 def task_get_result(self, session, task_ref):
569 task = XendTaskManager.get_task(task_ref)
570 return xen_api_success(task.result)
572 def task_get_error_code(self, session, task_ref):
573 task = XendTaskManager.get_task(task_ref)
574 return xen_api_success(task.error_code)
576 def task_get_error_info(self, session, task_ref):
577 task = XendTaskManager.get_task(task_ref)
578 return xen_api_success(task.error_info)
580 def task_get_allowed_operations(self, session, task_ref):
581 return xen_api_success({})
583 def task_get_session(self, session, task_ref):
584 task = XendTaskManager.get_task(task_ref)
585 return xen_api_success(task.session)
587 def task_get_all(self, session):
588 tasks = XendTaskManager.get_all_tasks()
589 return xen_api_success(tasks)
591 def task_get_record(self, session, task_ref):
592 task = XendTaskManager.get_task(task_ref)
593 return xen_api_success(task.get_record())
595 def task_cancel(self, session, task_ref):
596 return xen_api_error('OPERATION_NOT_ALLOWED')
598 def task_get_by_name_label(self, session, name):
599 return xen_api_success(XendTaskManager.get_task_by_name(name))
601 # Xen API: Class host
602 # ----------------------------------------------------------------
604 host_attr_ro = ['software_version',
605 'resident_VMs',
606 'host_CPUs',
607 'metrics']
609 host_attr_rw = ['name_label',
610 'name_description',
611 'other_config']
613 host_methods = [('disable', None),
614 ('enable', None),
615 ('reboot', None),
616 ('shutdown', None),
617 ('add_to_other_config', None),
618 ('remove_from_other_config', None)]
620 host_funcs = [('get_by_name_label', 'Set(host)')]
622 # attributes
623 def host_get_name_label(self, session, host_ref):
624 return xen_api_success(XendNode.instance().name)
625 def host_set_name_label(self, session, host_ref, new_name):
626 XendNode.instance().set_name(new_name)
627 return xen_api_success_void()
628 def host_get_name_description(self, session, host_ref):
629 return xen_api_success(XendNode.instance().description)
630 def host_set_name_description(self, session, host_ref, new_desc):
631 XendNode.instance().set_description(new_desc)
632 return xen_api_success_void()
633 def host_get_other_config(self, session, host_ref):
634 return xen_api_success(XendNode.instance().other_config)
635 def host_set_other_config(self, session, host_ref, other_config):
636 node = XendNode.instance()
637 node.other_config = dict(other_config)
638 node.save()
639 return xen_api_success_void()
640 def host_add_to_other_config(self, session, host_ref, key, value):
641 node = XendNode.instance()
642 node.other_config[key] = value
643 node.save()
644 return xen_api_success_void()
645 def host_remove_from_other_config(self, session, host_ref, key):
646 node = XendNode.instance()
647 del node.other_config[key]
648 node.save()
649 return xen_api_success_void()
650 def host_get_software_version(self, session, host_ref):
651 return xen_api_success(XendNode.instance().xen_version())
652 def host_get_resident_VMs(self, session, host_ref):
653 return xen_api_success(XendDomain.instance().get_domain_refs())
654 def host_get_host_CPUs(self, session, host_ref):
655 return xen_api_success(XendNode.instance().get_host_cpu_refs())
656 def host_get_metrics(self, _, ref):
657 return xen_api_success(XendNode.instance().host_metrics_uuid)
659 # object methods
660 def host_destroy(self, session, host_ref):
661 return xen_api_error(XEND_ERROR_UNSUPPORTED)
662 def host_disable(self, session, host_ref):
663 XendDomain.instance().set_allow_new_domains(False)
664 return xen_api_success_void()
665 def host_enable(self, session, host_ref):
666 XendDomain.instance().set_allow_new_domains(True)
667 return xen_api_success_void()
668 def host_reboot(self, session, host_ref):
669 if not XendDomain.instance().allow_new_domains():
670 return xen_api_error(XEND_ERROR_HOST_RUNNING)
671 return xen_api_error(XEND_ERROR_UNSUPPORTED)
672 def host_shutdown(self, session, host_ref):
673 if not XendDomain.instance().allow_new_domains():
674 return xen_api_error(XEND_ERROR_HOST_RUNNING)
675 return xen_api_error(XEND_ERROR_UNSUPPORTED)
677 def host_get_record(self, session, host_ref):
678 node = XendNode.instance()
679 dom = XendDomain.instance()
680 record = {'uuid': node.uuid,
681 'name_label': node.name,
682 'name_description': '',
683 'software_version': node.xen_version(),
684 'resident_VMs': dom.get_domain_refs(),
685 'host_CPUs': node.get_host_cpu_refs(),
686 'metrics': node.host_metrics_uuid}
687 return xen_api_success(record)
689 # class methods
690 def host_get_all(self, session):
691 return xen_api_success((XendNode.instance().uuid,))
692 def host_create(self, session, struct):
693 return xen_api_error(XEND_ERROR_UNSUPPORTED)
694 def host_get_by_name_label(self, session, name):
695 if XendNode.instance().name == name:
696 return xen_api_success((XendNode.instance().uuid,))
697 return xen_api_success([])
700 # Xen API: Class host_CPU
701 # ----------------------------------------------------------------
703 host_cpu_attr_ro = ['host',
704 'number',
705 'utilisation']
707 # attributes
708 def host_cpu_get_host(self, session, host_cpu_ref):
709 return xen_api_success(XendNode.instance().uuid)
710 def host_cpu_get_utilisation(self, session, host_cpu_ref):
711 util = XendNode.instance().get_host_cpu_load(host_cpu_ref)
712 return xen_api_success(util)
713 def host_cpu_get_number(self, session, host_cpu_ref):
714 num = XendNode.instance().get_host_cpu_number(host_cpu_ref)
715 return xen_api_success(num)
717 # object methods
718 def host_cpu_destroy(self, session, host_cpu_ref):
719 return xen_api_error(XEND_ERROR_UNSUPPORTED)
720 def host_cpu_get_record(self, session, host_cpu_ref):
721 node = XendNode.instance()
722 record = {'uuid': host_cpu_ref,
723 'host': node.uuid,
724 'number': node.get_host_cpu_number(host_cpu_ref),
725 'utilisation': node.get_host_cpu_load(host_cpu_ref)}
726 return xen_api_success(record)
728 # class methods
729 def host_cpu_get_all(self, session):
730 return xen_api_success(XendNode.instance().get_host_cpu_refs())
733 # Xen API: Class host_metrics
734 # ----------------------------------------------------------------
736 host_metrics_attr_ro = ['memory_total',
737 'memory_free',
738 'host']
739 host_metrics_attr_rw = []
740 host_methods = []
742 def _host_metrics_get(self, ref, f):
743 return xen_api_success(getattr(node, f)())
745 def host_metrics_get_record(self, _, ref):
746 return xen_api_success({
747 'uuid' : ref,
748 'host' : XendNode.instance().uuid,
749 'memory_total' : self._host_metrics_get_memory_total(),
750 'memory_free' : self._host_metrics_get_memory_free(),
751 })
753 def host_metrics_get_host(self, _, ref):
754 return xen_api_success(XendNode.instance().uuid)
756 def host_metrics_get_memory_total(self, _, ref):
757 return xen_api_success(self._host_metrics_get_memory_total())
759 def host_metrics_get_memory_free(self, _, ref):
760 return xen_api_success(self._host_metrics_get_memory_free())
762 def _host_metrics_get_memory_total(self):
763 node = XendNode.instance()
764 return node.xc.physinfo()['total_memory'] * 1024
766 def _host_metrics_get_memory_free(self):
767 node = XendNode.instance()
768 return node.xc.physinfo()['free_memory'] * 1024
771 # Xen API: Class network
772 # ----------------------------------------------------------------
774 network_attr_ro = ['VIFs', 'PIFs']
775 network_attr_rw = ['name_label',
776 'name_description',
777 'default_gateway',
778 'default_netmask']
780 network_funcs = [('create', 'network')]
782 def network_create(self, _, name_label, name_description,
783 default_gateway, default_netmask):
784 return xen_api_success(
785 XendNode.instance().network_create(name_label, name_description,
786 default_gateway,
787 default_netmask))
789 def network_destroy(self, _, ref):
790 return xen_api_success(XendNode.instance().network_destroy(ref))
792 def _get_network(self, ref):
793 return XendNode.instance().get_network(ref)
795 def network_get_all(self, _):
796 return xen_api_success(XendNode.instance().get_network_refs())
798 def network_get_record(self, _, ref):
799 return xen_api_success(
800 XendNode.instance().get_network(ref).get_record())
802 def network_get_name_label(self, _, ref):
803 return xen_api_success(self._get_network(ref).name_label)
805 def network_get_name_description(self, _, ref):
806 return xen_api_success(self._get_network(ref).name_description)
808 def network_get_default_gateway(self, _, ref):
809 return xen_api_success(self._get_network(ref).default_gateway)
811 def network_get_default_netmask(self, _, ref):
812 return xen_api_success(self._get_network(ref).default_netmask)
814 def network_get_VIFs(self, _, ref):
815 return xen_api_success(self._get_network(ref).get_VIF_UUIDs())
817 def network_get_PIFs(self, session, ref):
818 return xen_api_success(self._get_network(ref).get_PIF_UUIDs())
820 def network_set_name_label(self, _, ref, val):
821 return xen_api_success(self._get_network(ref).set_name_label(val))
823 def network_set_name_description(self, _, ref, val):
824 return xen_api_success(self._get_network(ref).set_name_description(val))
826 def network_set_default_gateway(self, _, ref, val):
827 return xen_api_success(self._get_network(ref).set_default_gateway(val))
829 def network_set_default_netmask(self, _, ref, val):
830 return xen_api_success(self._get_network(ref).set_default_netmask(val))
833 # Xen API: Class PIF
834 # ----------------------------------------------------------------
836 PIF_attr_ro = ['metrics']
837 PIF_attr_rw = ['device',
838 'network',
839 'host',
840 'MAC',
841 'MTU',
842 'VLAN']
844 PIF_attr_inst = PIF_attr_rw
846 PIF_methods = [('create_VLAN', 'int')]
848 def _get_PIF(self, ref):
849 return XendNode.instance().pifs[ref]
851 def PIF_destroy(self, _, ref):
852 try:
853 return xen_api_success(XendNode.instance().PIF_destroy(ref))
854 except PIFIsPhysical, exn:
855 return xen_api_error(['PIF_IS_PHYSICAL', ref])
857 # object methods
858 def PIF_get_record(self, _, ref):
859 return xen_api_success(self._get_PIF(ref).get_record())
861 def PIF_get_all(self, _):
862 return xen_api_success(XendNode.instance().pifs.keys())
864 def PIF_get_metrics(self, _, ref):
865 return xen_api_success(self._get_PIF(ref).metrics.uuid)
867 def PIF_get_device(self, _, ref):
868 return xen_api_success(self._get_PIF(ref).device)
870 def PIF_get_network(self, _, ref):
871 return xen_api_success(self._get_PIF(ref).network.uuid)
873 def PIF_get_host(self, _, ref):
874 return xen_api_success(self._get_PIF(ref).host.uuid)
876 def PIF_get_MAC(self, _, ref):
877 return xen_api_success(self._get_PIF(ref).mac)
879 def PIF_get_MTU(self, _, ref):
880 return xen_api_success(self._get_PIF(ref).mtu)
882 def PIF_get_VLAN(self, _, ref):
883 return xen_api_success(self._get_PIF(ref).vlan)
885 def PIF_set_device(self, _, ref, device):
886 return xen_api_success(self._get_PIF(ref).set_device(device))
888 def PIF_set_MAC(self, _, ref, mac):
889 return xen_api_success(self._get_PIF(ref).set_mac(mac))
891 def PIF_set_MTU(self, _, ref, mtu):
892 return xen_api_success(self._get_PIF(ref).set_mtu(mtu))
894 def PIF_create_VLAN(self, _, ref, network, vlan):
895 try:
896 vlan = int(vlan)
897 except:
898 return xen_api_error(['VLAN_TAG_INVALID', vlan])
900 try:
901 node = XendNode.instance()
903 if _is_valid_ref(network, node.is_valid_network):
904 return xen_api_success(
905 node.PIF_create_VLAN(ref, network, vlan))
906 else:
907 return xen_api_error(['NETWORK_HANDLE_INVALID', network])
908 except NetworkAlreadyConnected, exn:
909 return xen_api_error(['NETWORK_ALREADY_CONNECTED',
910 network, exn.pif_uuid])
911 except VLANTagInvalid:
912 return xen_api_error(['VLAN_TAG_INVALID', vlan])
915 # Xen API: Class PIF_metrics
916 # ----------------------------------------------------------------
918 PIF_metrics_attr_ro = ['PIF',
919 'io_read_kbs',
920 'io_write_kbs']
921 PIF_metrics_attr_rw = []
922 PIF_methods = []
924 def _PIF_metrics_get(self, ref):
925 return XendNode.instance().pif_metrics[ref]
927 def PIF_metrics_get_record(self, _, ref):
928 return xen_api_success(self._PIF_metrics_get(ref).get_record())
930 def PIF_metrics_get_PIF(self, _, ref):
931 return xen_api_success(self._PIF_metrics_get(ref).pif.uuid)
933 def PIF_metrics_get_io_read_kbs(self, _, ref):
934 return xen_api_success(self._PIF_metrics_get(ref).get_io_read_kbs())
936 def PIF_metrics_get_io_write_kbs(self, _, ref):
937 return xen_api_success(self._PIF_metrics_get(ref).get_io_write_kbs())
940 # Xen API: Class VM
941 # ----------------------------------------------------------------
943 VM_attr_ro = ['power_state',
944 'resident_on',
945 'memory_actual',
946 'memory_static_max',
947 'memory_static_min',
948 'VCPUs_number',
949 'VCPUs_utilisation',
950 'consoles',
951 'VIFs',
952 'VBDs',
953 'VTPMs',
954 'PCI_bus',
955 'tools_version',
956 'is_control_domain',
957 ]
959 VM_attr_rw = ['name_label',
960 'name_description',
961 'user_version',
962 'is_a_template',
963 'auto_power_on',
964 'memory_dynamic_max',
965 'memory_dynamic_min',
966 'VCPUs_policy',
967 'VCPUs_params',
968 'actions_after_shutdown',
969 'actions_after_reboot',
970 'actions_after_suspend',
971 'actions_after_crash',
972 'PV_bootloader',
973 'PV_kernel',
974 'PV_ramdisk',
975 'PV_args',
976 'PV_bootloader_args',
977 'HVM_boot',
978 'platform_std_VGA',
979 'platform_serial',
980 'platform_localtime',
981 'platform_clock_offset',
982 'platform_enable_audio',
983 'platform_keymap',
984 'other_config']
986 VM_methods = [('clone', 'VM'),
987 ('start', None),
988 ('pause', None),
989 ('unpause', None),
990 ('clean_shutdown', None),
991 ('clean_reboot', None),
992 ('hard_shutdown', None),
993 ('hard_reboot', None),
994 ('suspend', None),
995 ('resume', None),
996 ('add_to_other_config', None),
997 ('remove_from_other_config', None)]
999 VM_funcs = [('create', 'VM'),
1000 ('get_by_name_label', 'Set(VM)')]
1002 # parameters required for _create()
1003 VM_attr_inst = [
1004 'name_label',
1005 'name_description',
1006 'user_version',
1007 'is_a_template',
1008 'memory_static_max',
1009 'memory_dynamic_max',
1010 'memory_dynamic_min',
1011 'memory_static_min',
1012 'VCPUs_policy',
1013 'VCPUs_params',
1014 'actions_after_shutdown',
1015 'actions_after_reboot',
1016 'actions_after_suspend',
1017 'actions_after_crash',
1018 'PV_bootloader',
1019 'PV_kernel',
1020 'PV_ramdisk',
1021 'PV_args',
1022 'PV_bootloader_args',
1023 'HVM_boot',
1024 'platform_std_VGA',
1025 'platform_serial',
1026 'platform_localtime',
1027 'platform_clock_offset',
1028 'platform_enable_audio',
1029 'platform_keymap',
1030 'grub_cmdline',
1031 'PCI_bus',
1032 'other_config']
1034 def VM_get(self, name, session, vm_ref):
1035 return xen_api_success(
1036 XendDomain.instance().get_vm_by_uuid(vm_ref).info[name])
1038 def VM_set(self, name, session, vm_ref, value):
1039 xd = XendDomain.instance()
1040 dominfo = xd.get_vm_by_uuid(vm_ref)
1041 dominfo.info[name] = value
1042 xd.managed_config_save(dominfo)
1043 return xen_api_success_void()
1045 # attributes (ro)
1046 def VM_get_power_state(self, session, vm_ref):
1047 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1048 return xen_api_success(dom.get_power_state())
1050 def VM_get_resident_on(self, session, vm_ref):
1051 return xen_api_success(XendNode.instance().uuid)
1053 def VM_get_memory_actual(self, session, vm_ref):
1054 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1055 return xen_api_todo() # unsupported by xc
1057 def VM_get_memory_static_max(self, session, vm_ref):
1058 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1059 return xen_api_success(dom.get_memory_static_max())
1061 def VM_get_memory_static_min(self, session, vm_ref):
1062 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1063 return xen_api_success(dom.get_memory_static_min())
1065 def VM_get_VCPUs_number(self, session, vm_ref):
1066 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1067 return xen_api_success(dom.getVCpuCount())
1069 def VM_get_VCPUs_utilisation(self, session, vm_ref):
1070 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1071 return xen_api_success(dom.get_vcpus_util())
1073 def VM_get_VIFs(self, session, vm_ref):
1074 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1075 return xen_api_success(dom.get_vifs())
1077 def VM_get_VBDs(self, session, vm_ref):
1078 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1079 return xen_api_success(dom.get_vbds())
1081 def VM_get_VTPMs(self, session, vm_ref):
1082 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1083 return xen_api_success(dom.get_vtpms())
1085 def VM_get_consoles(self, session, vm_ref):
1086 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1087 return xen_api_success(dom.get_consoles())
1089 def VM_get_PCI_bus(self, session, vm_ref):
1090 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1091 return dom.get_pci_bus()
1093 def VM_get_tools_version(self, session, vm_ref):
1094 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1095 return dom.get_tools_version()
1097 # attributes (rw)
1098 def VM_get_name_label(self, session, vm_ref):
1099 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1100 return xen_api_success(dom.getName())
1102 def VM_get_name_description(self, session, vm_ref):
1103 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1104 return xen_api_todo()
1106 def VM_get_user_version(self, session, vm_ref):
1107 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1108 return xen_api_todo()
1110 def VM_get_is_a_template(self, session, vm_ref):
1111 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1112 return xen_api_todo()
1114 def VM_get_memory_dynamic_max(self, session, vm_ref):
1115 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1116 return xen_api_success(dom.get_memory_dynamic_max())
1118 def VM_get_memory_dynamic_min(self, session, vm_ref):
1119 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1120 return xen_api_success(dom.get_memory_dynamic_min())
1122 def VM_get_VCPUs_policy(self, session, vm_ref):
1123 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1124 return xen_api_success(dom.get_vcpus_policy())
1126 def VM_get_VCPUs_params(self, session, vm_ref):
1127 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1128 return xen_api_success(dom.get_vcpus_params())
1130 def VM_get_actions_after_shutdown(self, session, vm_ref):
1131 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1132 return xen_api_success(dom.get_on_shutdown())
1134 def VM_get_actions_after_reboot(self, session, vm_ref):
1135 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1136 return xen_api_success(dom.get_on_reboot())
1138 def VM_get_actions_after_suspend(self, session, vm_ref):
1139 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1140 return xen_api_success(dom.get_on_suspend())
1142 def VM_get_actions_after_crash(self, session, vm_ref):
1143 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1144 return xen_api_success(dom.get_on_crash())
1146 def VM_get_PV_bootloader(self, session, vm_ref):
1147 return self.VM_get('PV_bootloader', session, vm_ref)
1149 def VM_get_PV_kernel(self, session, vm_ref):
1150 return self.VM_get('PV_kernel', session, vm_ref)
1152 def VM_get_PV_ramdisk(self, session, vm_ref):
1153 return self.VM_get('PV_ramdisk', session, vm_ref)
1155 def VM_get_PV_args(self, session, vm_ref):
1156 return self.VM_get('PV_args', session, vm_ref)
1158 def VM_get_PV_bootloader_args(self, session, vm_ref):
1159 return self.VM_get('PV_bootloader_args', session, vm_ref)
1161 def VM_get_HVM_boot(self, session, vm_ref):
1162 return self.VM_get('HVM_boot', session, vm_ref)
1164 def VM_get_platform_std_VGA(self, session, vm_ref):
1165 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1166 return xen_api_success(dom.get_platform_std_vga())
1168 def VM_get_platform_serial(self, session, vm_ref):
1169 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1170 return xen_api_success(dom.get_platform_serial())
1172 def VM_get_platform_localtime(self, session, vm_ref):
1173 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1174 return xen_api_success(dom.get_platform_localtime())
1176 def VM_get_platform_clock_offset(self, session, vm_ref):
1177 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1178 return xen_api_success(dom.get_platform_clock_offset())
1180 def VM_get_platform_enable_audio(self, session, vm_ref):
1181 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1182 return xen_api_success(dom.get_platform_enable_audio())
1184 def VM_get_platform_keymap(self, session, vm_ref):
1185 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1186 return xen_api_success(dom.get_platform_keymap())
1188 def VM_get_other_config(self, session, vm_ref):
1189 return self.VM_get('otherconfig', session, vm_ref)
1191 def VM_get_is_control_domain(self, session, vm_ref):
1192 xd = XendDomain.instance()
1193 return xen_api_success(
1194 xd.get_vm_by_uuid(vm_ref) == xd.privilegedDomain())
1196 def VM_set_name_label(self, session, vm_ref, label):
1197 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1198 dom.setName(label)
1199 return xen_api_success_void()
1201 def VM_set_name_description(self, session, vm_ref, desc):
1202 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1203 return xen_api_todo()
1205 def VM_set_user_version(self, session, vm_ref, ver):
1206 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1207 return xen_api_todo()
1209 def VM_set_is_a_template(self, session, vm_ref, is_template):
1210 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1211 return xen_api_todo()
1213 def VM_set_memory_dynamic_max(self, session, vm_ref, mem):
1214 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1215 return xen_api_todo()
1217 def VM_set_memory_dynamic_min(self, session, vm_ref, mem):
1218 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1219 return xen_api_todo()
1221 def VM_set_VCPUs_policy(self, session, vm_ref, policy):
1222 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1223 return xen_api_todo()
1225 def VM_set_VCPUs_params(self, session, vm_ref, params):
1226 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1227 return xen_api_todo()
1229 def VM_set_actions_after_shutdown(self, session, vm_ref, action):
1230 if action not in XEN_API_ON_NORMAL_EXIST:
1231 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1232 return self.VM_set('actions_after_shutdown', session, vm_ref, action)
1234 def VM_set_actions_after_reboot(self, session, vm_ref, action):
1235 if action not in XEN_API_ON_NORMAL_EXIST:
1236 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1237 return self.VM_set('actions_after_reboot', session, vm_ref, action)
1239 def VM_set_actions_after_suspend(self, session, vm_ref, action):
1240 if action not in XEN_API_ON_NORMAL_EXIT:
1241 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1242 return self.VM_set('actions_after_suspend', session, vm_ref, action)
1244 def VM_set_actions_after_crash(self, session, vm_ref, action):
1245 if action not in XEN_API_ON_CRASH_BEHAVIOUR:
1246 return xen_api_error(['VM_ON_CRASH_BEHAVIOUR_INVALID', vm_ref])
1247 return self.VM_set('actions_after_crash', session, vm_ref, action)
1249 def VM_set_HVM_boot(self, session, vm_ref, value):
1250 return self.VM_set('HVM_boot', session, vm_ref, value)
1252 def VM_set_PV_bootloader(self, session, vm_ref, value):
1253 return self.VM_set('PV_bootloader', session, vm_ref, value)
1255 def VM_set_PV_kernel(self, session, vm_ref, value):
1256 return self.VM_set('PV_kernel', session, vm_ref, value)
1258 def VM_set_PV_ramdisk(self, session, vm_ref, value):
1259 return self.VM_set('PV_ramdisk', session, vm_ref, value)
1261 def VM_set_PV_args(self, session, vm_ref, value):
1262 return self.VM_set('PV_args', session, vm_ref, value)
1264 def VM_set_PV_bootloader_args(self, session, vm_ref, value):
1265 return self.VM_set('PV_bootloader_args', session, vm_ref, value)
1267 def VM_set_platform_std_VGA(self, session, vm_ref, value):
1268 return self.VM_set('platform_std_vga', session, vm_ref, value)
1270 def VM_set_platform_serial(self, session, vm_ref, value):
1271 return self.VM_set('platform_serial', session, vm_ref, value)
1273 def VM_set_platform_keymap(self, session, vm_ref, value):
1274 return self.VM_set('platform_keymap', session, vm_ref, value)
1276 def VM_set_platform_localtime(self, session, vm_ref, value):
1277 return self.VM_set('platform_localtime', session, vm_ref, value)
1279 def VM_set_platform_clock_offset(self, session, vm_ref, value):
1280 return self.VM_set('platform_clock_offset', session, vm_ref, value)
1282 def VM_set_platform_enable_audio(self, session, vm_ref, value):
1283 return self.VM_set('platform_enable_audio', session, vm_ref, value)
1285 def VM_set_other_config(self, session, vm_ref, value):
1286 return self.VM_set('otherconfig', session, vm_ref, value)
1288 def VM_add_to_other_config(self, session, vm_ref, key, value):
1289 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1290 if dom and 'otherconfig' in dom.info:
1291 dom.info['otherconfig'][key] = value
1292 return xen_api_success_void()
1294 def VM_remove_from_other_config(self, session, vm_ref, key):
1295 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1296 if dom and 'otherconfig' in dom.info \
1297 and key in dom.info['otherconfig']:
1298 del dom.info['otherconfig'][key]
1299 return xen_api_success_void()
1301 # class methods
1302 def VM_get_all(self, session):
1303 refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
1304 return xen_api_success(refs)
1306 def VM_get_by_name_label(self, session, label):
1307 xendom = XendDomain.instance()
1308 dom = xendom.domain_lookup_nr(label)
1309 if dom:
1310 return xen_api_success([dom.get_uuid()])
1311 return xen_api_success([])
1313 def VM_create(self, session, vm_struct):
1314 xendom = XendDomain.instance()
1315 domuuid = XendTask.log_progress(0, 100,
1316 xendom.create_domain, vm_struct)
1317 return xen_api_success(domuuid)
1319 # object methods
1320 def VM_get_record(self, session, vm_ref):
1321 xendom = XendDomain.instance()
1322 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1323 if not xeninfo:
1324 return xen_api_error(['VM_HANDLE_INVALID', vm_ref])
1326 record = {
1327 'uuid': xeninfo.get_uuid(),
1328 'power_state': xeninfo.get_power_state(),
1329 'name_label': xeninfo.getName(),
1330 'name_description': xeninfo.getName(),
1331 'user_version': 1,
1332 'is_a_template': False,
1333 'auto_power_on': False,
1334 'resident_on': XendNode.instance().uuid,
1335 'memory_static_min': xeninfo.get_memory_static_min(),
1336 'memory_static_max': xeninfo.get_memory_static_max(),
1337 'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
1338 'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
1339 'memory_actual': xeninfo.get_memory_static_min(),
1340 'VCPUs_policy': xeninfo.get_vcpus_policy(),
1341 'VCPUs_params': xeninfo.get_vcpus_params(),
1342 'VCPUs_number': xeninfo.getVCpuCount(),
1343 'VCPUs_utilisation': xeninfo.get_vcpus_util(),
1344 'actions_after_shutdown': xeninfo.get_on_shutdown(),
1345 'actions_after_reboot': xeninfo.get_on_reboot(),
1346 'actions_after_suspend': xeninfo.get_on_suspend(),
1347 'actions_after_crash': xeninfo.get_on_crash(),
1348 'consoles': xeninfo.get_consoles(),
1349 'VIFs': xeninfo.get_vifs(),
1350 'VBDs': xeninfo.get_vbds(),
1351 'VTPMs': xeninfo.get_vtpms(),
1352 'PV_bootloader': xeninfo.info.get('PV_bootloader'),
1353 'PV_kernel': xeninfo.info.get('PV_kernel'),
1354 'PV_ramdisk': xeninfo.info.get('PV_ramdisk'),
1355 'PV_args': xeninfo.info.get('PV_args'),
1356 'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
1357 'HVM_boot': xeninfo.info.get('HVM_boot'),
1358 'platform_std_VGA': xeninfo.get_platform_std_vga(),
1359 'platform_serial': xeninfo.get_platform_serial(),
1360 'platform_localtime': xeninfo.get_platform_localtime(),
1361 'platform_clock_offset': xeninfo.get_platform_clock_offset(),
1362 'platform_enable_audio': xeninfo.get_platform_enable_audio(),
1363 'platform_keymap': xeninfo.get_platform_keymap(),
1364 'PCI_bus': xeninfo.get_pci_bus(),
1365 'tools_version': xeninfo.get_tools_version(),
1366 'other_config': xeninfo.info.get('otherconfig'),
1367 'is_control_domain': xeninfo == xendom.privilegedDomain(),
1369 return xen_api_success(record)
1371 def VM_clean_reboot(self, session, vm_ref):
1372 xendom = XendDomain.instance()
1373 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1374 XendTask.log_progress(0, 100, xeninfo.shutdown, "reboot")
1375 return xen_api_success_void()
1377 def VM_clean_shutdown(self, session, vm_ref):
1378 xendom = XendDomain.instance()
1379 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1380 XendTask.log_progress(0, 100, xeninfo.shutdown, "poweroff")
1381 return xen_api_success_void()
1383 def VM_clone(self, session, vm_ref):
1384 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1386 def VM_destroy(self, session, vm_ref):
1387 return XendTask.log_progress(0, 100, do_vm_func,
1388 "domain_delete", vm_ref)
1390 def VM_hard_reboot(self, session, vm_ref):
1391 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1393 def VM_hard_shutdown(self, session, vm_ref):
1394 return XendTask.log_progress(0, 100, do_vm_func,
1395 "domain_destroy", vm_ref)
1396 def VM_pause(self, session, vm_ref):
1397 return XendTask.log_progress(0, 100, do_vm_func,
1398 "domain_pause", vm_ref)
1400 def VM_resume(self, session, vm_ref, start_paused):
1401 return XendTask.log_progress(0, 100, do_vm_func,
1402 "domain_resume", vm_ref,
1403 start_paused = start_paused)
1405 def VM_start(self, session, vm_ref, start_paused):
1406 return XendTask.log_progress(0, 100, do_vm_func,
1407 "domain_start", vm_ref,
1408 start_paused = start_paused)
1410 def VM_suspend(self, session, vm_ref):
1411 return XendTask.log_progress(0, 100, do_vm_func,
1412 "domain_suspend", vm_ref)
1414 def VM_unpause(self, session, vm_ref):
1415 return XendTask.log_progress(0, 100, do_vm_func,
1416 "domain_unpause", vm_ref)
1418 # Xen API: Class VBD
1419 # ----------------------------------------------------------------
1421 VBD_attr_ro = ['io_read_kbs',
1422 'io_write_kbs']
1423 VBD_attr_rw = ['VM',
1424 'VDI',
1425 'device',
1426 'bootable',
1427 'mode',
1428 'type']
1430 VBD_attr_inst = VBD_attr_rw
1432 VBD_methods = [('media_change', None)]
1433 VBD_funcs = [('create', 'VBD')]
1435 # object methods
1436 def VBD_get_record(self, session, vbd_ref):
1437 xendom = XendDomain.instance()
1438 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1439 if not vm:
1440 return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref])
1441 cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
1442 if not cfg:
1443 return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref])
1445 valid_vbd_keys = self.VBD_attr_ro + self.VBD_attr_rw + \
1446 self.Base_attr_ro + self.Base_attr_rw
1448 return_cfg = {}
1449 for k in cfg.keys():
1450 if k in valid_vbd_keys:
1451 return_cfg[k] = cfg[k]
1453 return xen_api_success(return_cfg)
1455 def VBD_media_change(self, session, vbd_ref, vdi_ref):
1456 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1458 # class methods
1459 def VBD_create(self, session, vbd_struct):
1460 xendom = XendDomain.instance()
1461 if not xendom.is_valid_vm(vbd_struct['VM']):
1462 return xen_api_error(['VM_HANDLE_INVALID', vbd_struct['VM']])
1464 dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
1465 vbd_ref = ''
1466 try:
1467 # new VBD via VDI/SR
1468 vdi_ref = vbd_struct.get('VDI')
1469 vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
1470 if not vdi:
1471 return xen_api_error(['VDI_HANDLE_INVALID', vdi_ref])
1472 vdi_image = vdi.get_image_uri()
1473 vbd_ref = XendTask.log_progress(0, 100,
1474 dom.create_vbd,
1475 vbd_struct, vdi_image)
1476 except XendError:
1477 return xen_api_todo()
1479 xendom.managed_config_save(dom)
1480 return xen_api_success(vbd_ref)
1483 def VBD_destroy(self, session, vbd_ref):
1484 xendom = XendDomain.instance()
1485 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1486 if not vm:
1487 return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref])
1489 XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref)
1490 return xen_api_success_void()
1492 # attributes (rw)
1493 def _VBD_get(self, vbd_ref, prop):
1494 return xen_api_success(
1495 XendDomain.instance().get_dev_property_by_uuid(
1496 'vbd', vbd_ref, prop))
1498 def VBD_get_VM(self, session, vbd_ref):
1499 return self._VBD_get(vbd_ref, 'VM')
1501 def VBD_get_VDI(self, session, vbd_ref):
1502 return self._VBD_get(vbd_ref, 'VDI')
1504 def VBD_get_device(self, session, vbd_ref):
1505 return self._VBD_get(vbd_ref, 'device')
1507 def VBD_get_bootable(self, session, vbd_ref):
1508 return self._VBD_get(vbd_ref, 'bootable')
1510 def VBD_get_mode(self, session, vbd_ref):
1511 return self._VBD_get(vbd_ref, 'mode')
1513 def VBD_get_type(self, session, vbd_ref):
1514 return self._VBD_get(vbd_ref, 'type')
1516 def VBD_get_io_read_kbs(self, session, vbd_ref):
1517 return self._VBD_get(vbd_ref, 'io_read_kbs')
1519 def VBD_get_io_write_kbs(self, session, vbd_ref):
1520 return self._VBD_get(vbd_ref, 'io_write_kbs')
1522 def VBD_set_bootable(self, session, vbd_ref, bootable):
1523 bootable = bool(bootable)
1524 xd = XendDomain.instance()
1525 vm = xd.get_vm_with_dev_uuid('vbd', vbd_ref)
1526 vm.set_dev_property('vbd', vbd_ref, 'bootable', bootable)
1527 xd.managed_config_save(vm)
1528 return xen_api_success_void()
1530 def VBD_get_all(self, session):
1531 xendom = XendDomain.instance()
1532 vbds = [d.get_vbds() for d in XendDomain.instance().list('all')]
1533 vbds = reduce(lambda x, y: x + y, vbds)
1534 return xen_api_success(vbds)
1536 # Xen API: Class VIF
1537 # ----------------------------------------------------------------
1539 VIF_attr_ro = ['io_read_kbs',
1540 'io_write_kbs']
1541 VIF_attr_rw = ['device',
1542 'network',
1543 'VM',
1544 'MAC',
1545 'MTU']
1547 VIF_attr_inst = VIF_attr_rw
1549 VIF_funcs = [('create', 'VIF')]
1552 # object methods
1553 def VIF_get_record(self, session, vif_ref):
1554 xendom = XendDomain.instance()
1555 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1556 if not vm:
1557 return xen_api_error(['VIF_HANDLE_INVALID', vif_ref])
1558 cfg = vm.get_dev_xenapi_config('vif', vif_ref)
1559 if not cfg:
1560 return xen_api_error(['VIF_HANDLE_INVALID', vif_ref])
1562 valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
1563 self.Base_attr_ro + self.Base_attr_rw
1565 return_cfg = {}
1566 for k in cfg.keys():
1567 if k in valid_vif_keys:
1568 return_cfg[k] = cfg[k]
1570 return xen_api_success(return_cfg)
1572 # class methods
1573 def VIF_create(self, session, vif_struct):
1574 xendom = XendDomain.instance()
1575 if xendom.is_valid_vm(vif_struct['VM']):
1576 dom = xendom.get_vm_by_uuid(vif_struct['VM'])
1577 try:
1578 vif_ref = dom.create_vif(vif_struct)
1579 xendom.managed_config_save(dom)
1580 return xen_api_success(vif_ref)
1581 except XendError:
1582 return xen_api_error(XEND_ERROR_TODO)
1583 else:
1584 return xen_api_error(['VM_HANDLE_INVALID', vif_struct['VM']])
1587 def VIF_destroy(self, session, vif_ref):
1588 xendom = XendDomain.instance()
1589 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1590 if not vm:
1591 return xen_api_error(['VIF_HANDLE_INVALID', vif_ref])
1593 vm.destroy_vif(vif_ref)
1594 return xen_api_success_void()
1596 # getters/setters
1597 def VIF_get_VM(self, session, vif_ref):
1598 xendom = XendDomain.instance()
1599 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1600 return xen_api_success(vm.get_uuid())
1602 def VIF_get_MTU(self, session, vif_ref):
1603 xendom = XendDomain.instance()
1604 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1605 'MTU'))
1606 def VIF_get_MAC(self, session, vif_ref):
1607 xendom = XendDomain.instance()
1608 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1609 'MAC'))
1611 def VIF_get_device(self, session, vif_ref):
1612 xendom = XendDomain.instance()
1613 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1614 'device'))
1616 def VIF_get_io_read_kbs(self, session, vif_ref):
1617 xendom = XendDomain.instance()
1618 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1619 'io_read_kbs'))
1621 def VIF_get_io_write_kbs(self, session, vif_ref):
1622 xendom = XendDomain.instance()
1623 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1624 'io_write_kbs'))
1626 def VIF_get_all(self, session):
1627 xendom = XendDomain.instance()
1628 vifs = [d.get_vifs() for d in XendDomain.instance().list('all')]
1629 vifs = reduce(lambda x, y: x + y, vifs)
1630 return xen_api_success(vifs)
1633 # Xen API: Class VDI
1634 # ----------------------------------------------------------------
1635 VDI_attr_ro = ['VBDs',
1636 'physical_utilisation',
1637 'sector_size',
1638 'type']
1639 VDI_attr_rw = ['name_label',
1640 'name_description',
1641 'SR',
1642 'virtual_size',
1643 'sharable',
1644 'read_only']
1645 VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
1647 VDI_methods = [('snapshot', 'VDI')]
1648 VDI_funcs = [('create', 'VDI'),
1649 ('get_by_name_label', 'Set(VDI)')]
1651 def _get_VDI(self, ref):
1652 return XendNode.instance().get_vdi_by_uuid(ref)
1654 def VDI_get_VBDs(self, session, vdi_ref):
1655 return xen_api_todo()
1657 def VDI_get_physical_utilisation(self, session, vdi_ref):
1658 return xen_api_success(self._get_VDI(vdi_ref).
1659 get_physical_utilisation())
1661 def VDI_get_sector_size(self, session, vdi_ref):
1662 return xen_api_success(self._get_VDI(vdi_ref).sector_size)
1664 def VDI_get_type(self, session, vdi_ref):
1665 return xen_api_success(self._get_VDI(vdi_ref).type)
1667 def VDI_get_name_label(self, session, vdi_ref):
1668 return xen_api_success(self._get_VDI(vdi_ref).name_label)
1670 def VDI_get_name_description(self, session, vdi_ref):
1671 return xen_api_success(self._get_VDI(vdi_ref).name_description)
1673 def VDI_get_SR(self, session, vdi_ref):
1674 return xen_api_success(self._get_VDI(vdi_ref).sr_uuid)
1676 def VDI_get_virtual_size(self, session, vdi_ref):
1677 return xen_api_success(self._get_VDI(vdi_ref).virtual_size)
1679 def VDI_get_sharable(self, session, vdi_ref):
1680 return xen_api_success(self._get_VDI(vdi_ref).sharable)
1682 def VDI_get_read_only(self, session, vdi_ref):
1683 return xen_api_success(self._get_VDI(vdi_ref).read_only)
1685 def VDI_set_name_label(self, session, vdi_ref, value):
1686 self._get_VDI(vdi_ref).name_label = value
1687 return xen_api_success_void()
1689 def VDI_set_name_description(self, session, vdi_ref, value):
1690 self._get_VDI(vdi_ref).name_description = value
1691 return xen_api_success_void()
1693 def VDI_set_SR(self, session, vdi_ref, value):
1694 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1696 def VDI_set_virtual_size(self, session, vdi_ref, value):
1697 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1699 def VDI_set_sharable(self, session, vdi_ref, value):
1700 self._get_VDI(vdi_ref).sharable = bool(value)
1701 return xen_api_success_void()
1703 def VDI_set_read_only(self, session, vdi_ref, value):
1704 self._get_VDI(vdi_ref).read_only = bool(value)
1705 return xen_api_success_void()
1707 # Object Methods
1708 def VDI_snapshot(self, session, vdi_ref):
1709 return xen_api_todo()
1711 def VDI_destroy(self, session, vdi_ref):
1712 sr = XendNode.instance().get_sr_containing_vdi(vdi_ref)
1713 sr.destroy_vdi(vdi_ref)
1714 return xen_api_success_void()
1716 def VDI_get_record(self, session, vdi_ref):
1717 image = XendNode.instance().get_vdi_by_uuid(vdi_ref)
1718 return xen_api_success({
1719 'uuid': vdi_ref,
1720 'name_label': image.name_label,
1721 'name_description': image.name_description,
1722 'SR': image.sr_uuid,
1723 'VBDs': [], # TODO
1724 'virtual_size': image.virtual_size,
1725 'physical_utilisation': image.physical_utilisation,
1726 'sector_size': image.sector_size,
1727 'type': image.type,
1728 'sharable': image.sharable,
1729 'read_only': image.read_only,
1730 })
1732 # Class Functions
1733 def VDI_create(self, session, vdi_struct):
1734 sr_ref = vdi_struct.get('SR')
1735 xennode = XendNode.instance()
1736 if not xennode.is_valid_sr(sr_ref):
1737 return xen_api_error(['SR_HANDLE_INVALID', sr_ref])
1739 vdi_uuid = xennode.srs[sr_ref].create_vdi(vdi_struct)
1740 return xen_api_success(vdi_uuid)
1742 def VDI_get_all(self, session):
1743 xennode = XendNode.instance()
1744 vdis = [sr.get_vdis() for sr in xennode.srs.values()]
1745 return xen_api_success(reduce(lambda x, y: x + y, vdis))
1747 def VDI_get_by_name_label(self, session, name):
1748 xennode = XendNode.instance()
1749 return xen_api_success(xennode.get_vdi_by_name_label(name))
1752 # Xen API: Class VTPM
1753 # ----------------------------------------------------------------
1755 VTPM_attr_rw = [ ]
1756 VTPM_attr_ro = ['VM',
1757 'backend']
1759 VTPM_attr_inst = VTPM_attr_rw
1761 VTPM_funcs = [('create', 'VTPM')]
1763 # object methods
1764 def VTPM_get_record(self, session, vtpm_ref):
1765 xendom = XendDomain.instance()
1766 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1767 if not vm:
1768 return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
1769 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1770 if not cfg:
1771 return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
1772 valid_vtpm_keys = self.VTPM_attr_ro + self.VTPM_attr_rw + \
1773 self.Base_attr_ro + self.Base_attr_rw
1774 return_cfg = {}
1775 for k in cfg.keys():
1776 if k in valid_vtpm_keys:
1777 return_cfg[k] = cfg[k]
1779 return xen_api_success(return_cfg)
1781 # Class Functions
1782 def VTPM_get_backend(self, session, vtpm_ref):
1783 xendom = XendDomain.instance()
1784 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1785 if not vm:
1786 return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
1787 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1788 if not cfg:
1789 return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
1790 if not cfg.has_key('backend'):
1791 return xen_api_error(['VTPM backend not set'])
1792 return xen_api_success(cfg['backend'])
1794 def VTPM_get_VM(self, session, vtpm_ref):
1795 xendom = XendDomain.instance()
1796 return xen_api_success(xendom.get_dev_property_by_uuid('vtpm',
1797 vtpm_ref, 'VM'))
1799 def VTPM_destroy(self, session, vtpm_ref):
1800 xendom = XendDomain.instance()
1801 dom = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1802 if dom:
1803 if dom.state != XEN_API_VM_POWER_STATE_HALTED:
1804 vm_ref = dom.get_dev_property('vtpm', vtpm_ref, 'VM')
1805 return xen_api_error(['VM_BAD_POWER_STATE', vm_ref,
1806 XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_HALTED],
1807 XendDomain.POWER_STATE_NAMES[dom.state]])
1808 from xen.xend.server import tpmif
1809 tpmif.destroy_vtpmstate(dom.getName())
1810 return xen_api_success(True)
1811 else:
1812 return xen_api_error(['VM_HANDLE_INVALID', vtpm_struct['VM']])
1814 # class methods
1815 def VTPM_create(self, session, vtpm_struct):
1816 xendom = XendDomain.instance()
1817 if xendom.is_valid_vm(vtpm_struct['VM']):
1818 dom = xendom.get_vm_by_uuid(vtpm_struct['VM'])
1819 try:
1820 vtpm_ref = dom.create_vtpm(vtpm_struct)
1821 xendom.managed_config_save(dom)
1822 return xen_api_success(vtpm_ref)
1823 except XendError:
1824 return xen_api_error(XEND_ERROR_TODO)
1825 else:
1826 return xen_api_error(['VM_HANDLE_INVALID', vtpm_struct['VM']])
1828 def VTPM_get_all(self, session):
1829 xendom = XendDomain.instance()
1830 vtpms = [d.get_vtpms() for d in XendDomain.instance().list('all')]
1831 vtpms = reduce(lambda x, y: x + y, vtpms)
1832 return xen_api_success(vtpms)
1834 # Xen API: Class console
1835 # ----------------------------------------------------------------
1838 console_attr_ro = ['location', 'protocol', 'VM']
1839 console_attr_rw = ['other_config']
1840 console_funcs = [('create', 'console')]
1842 def console_get_all(self, session):
1843 xendom = XendDomain.instance()
1844 cons = [d.get_consoles() for d in XendDomain.instance().list('all')]
1845 cons = reduce(lambda x, y: x + y, cons)
1846 return xen_api_success(cons)
1848 def console_get_location(self, session, console_ref):
1849 return xen_api_success(xendom.get_dev_property_by_uuid('console',
1850 console_ref,
1851 'location'))
1853 def console_get_protocol(self, session, console_ref):
1854 return xen_api_success(xendom.get_dev_property_by_uuid('console',
1855 console_ref,
1856 'protocol'))
1858 def console_get_VM(self, session, console_ref):
1859 xendom = XendDomain.instance()
1860 vm = xendom.get_vm_with_dev_uuid('console', console_ref)
1861 return xen_api_success(vm.get_uuid())
1863 # object methods
1864 def console_get_record(self, session, console_ref):
1865 xendom = XendDomain.instance()
1866 vm = xendom.get_vm_with_dev_uuid('console', console_ref)
1867 if not vm:
1868 return xen_api_error(['CONSOLE_HANDLE_INVALID', console_ref])
1869 cfg = vm.get_dev_xenapi_config('console', console_ref)
1870 if not cfg:
1871 return xen_api_error(['CONSOLE_HANDLE_INVALID', console_ref])
1873 valid_console_keys = self.console_attr_ro + self.console_attr_rw + \
1874 self.Base_attr_ro + self.Base_attr_rw
1876 return_cfg = {}
1877 for k in cfg.keys():
1878 if k in valid_console_keys:
1879 return_cfg[k] = cfg[k]
1881 return xen_api_success(return_cfg)
1883 def console_create(self, session, console_struct):
1884 xendom = XendDomain.instance()
1885 if not xendom.is_valid_vm(console_struct['VM']):
1886 return xen_api_error(['VM_HANDLE_INVALID', console_struct['VM']])
1888 dom = xendom.get_vm_by_uuid(console_struct['VM'])
1889 try:
1890 if 'protocol' not in console_struct:
1891 return xen_api_error(['CONSOLE_PROTOCOL_INVALID',
1892 'No protocol specified'])
1894 console_ref = dom.create_console(console_struct)
1895 xendom.managed_config_save(dom)
1896 return xen_api_success(console_ref)
1897 except XendError, e:
1898 return xen_api_error([XEND_ERROR_TODO, str(e)])
1900 # Xen API: Class SR
1901 # ----------------------------------------------------------------
1902 SR_attr_ro = ['VDIs',
1903 'virtual_allocation',
1904 'physical_utilisation',
1905 'physical_size',
1906 'type',
1907 'location']
1909 SR_attr_rw = ['name_label',
1910 'name_description']
1912 SR_attr_inst = ['physical_size',
1913 'type',
1914 'location',
1915 'name_label',
1916 'name_description']
1918 SR_methods = [('clone', 'SR')]
1919 SR_funcs = [('get_by_name_label', 'Set(SR)'),
1920 ('get_by_uuid', 'SR')]
1922 # Class Functions
1923 def SR_get_all(self, session):
1924 return xen_api_success(XendNode.instance().get_all_sr_uuid())
1926 def SR_get_by_name_label(self, session, label):
1927 return xen_api_success(XendNode.instance().get_sr_by_name(label))
1929 def SR_create(self, session):
1930 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1932 # Class Methods
1933 def SR_clone(self, session, sr_ref):
1934 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1936 def SR_destroy(self, session, sr_ref):
1937 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1939 def SR_get_record(self, session, sr_ref):
1940 sr = XendNode.instance().get_sr(sr_ref)
1941 if sr:
1942 return xen_api_success(sr.get_record())
1943 return xen_api_error(['SR_HANDLE_INVALID', sr_ref])
1945 # Attribute acceess
1947 def _get_SR_func(self, sr_ref, func):
1948 return xen_api_success(getattr(XendNode.instance().get_sr(sr_ref),
1949 func)())
1951 def _get_SR_attr(self, sr_ref, attr):
1952 return xen_api_success(getattr(XendNode.instance().get_sr(sr_ref),
1953 attr))
1955 def SR_get_VDIs(self, _, ref):
1956 return self._get_SR_func(ref, 'list_images')
1958 def SR_get_virtual_allocation(self, _, ref):
1959 return self._get_SR_func(ref, 'virtual_allocation')
1961 def SR_get_physical_utilisation(self, _, ref):
1962 return self._get_SR_func(ref, 'physical_utilisation')
1964 def SR_get_physical_size(self, _, ref):
1965 return self._get_SR_func(ref, 'physical_size')
1967 def SR_get_type(self, _, ref):
1968 return self._get_SR_attr(ref, 'type')
1970 def SR_get_location(self, _, ref):
1971 return self._get_SR_attr(ref, 'location')
1973 def SR_get_name_label(self, _, ref):
1974 return self._get_SR_attr(ref, 'name_label')
1976 def SR_get_name_description(self, _, ref):
1977 return self._get_SR_attr(ref, 'name_description')
1979 def SR_set_name_label(self, session, sr_ref, value):
1980 sr = XendNode.instance.get_sr(sr_ref)
1981 if sr:
1982 sr.name_label = value
1983 XendNode.instance().save()
1984 return xen_api_success_void()
1986 def SR_set_name_description(self, session, sr_ref, value):
1987 sr = XendNode.instance.get_sr(sr_ref)
1988 if sr:
1989 sr.name_description = value
1990 XendNode.instance().save()
1991 return xen_api_success_void()
1994 # Xen API: Class debug
1995 # ----------------------------------------------------------------
1997 debug_methods = [('destroy', None),
1998 ('get_record', 'debug')]
1999 debug_funcs = [('wait', None),
2000 ('return_failure', None)]
2002 def debug_wait(self, session, wait_secs):
2003 import time
2004 prog_units = 100/float(wait_secs)
2005 for i in range(int(wait_secs)):
2006 XendTask.log_progress(prog_units * i, prog_units * (i + 1),
2007 time.sleep, 1)
2008 return xen_api_success_void()
2011 def debug_return_failure(self, session):
2012 return xen_api_error(['DEBUG_FAIL', session])
2014 def debug_create(self, session):
2015 debug_uuid = uuid.createString()
2016 self._debug[debug_uuid] = None
2017 return xen_api_success(debug_uuid)
2019 def debug_destroy(self, session, debug_ref):
2020 del self._debug[debug_ref]
2021 return xen_api_success_void()
2023 def debug_get_record(self, session, debug_ref):
2024 return xen_api_success({'uuid': debug_ref})
2028 class XendAPIAsyncProxy:
2029 """ A redirector for Async.Class.function calls to XendAPI
2030 but wraps the call for use with the XendTaskManager.
2032 @ivar xenapi: Xen API instance
2033 @ivar method_map: Mapping from XMLRPC method name to callable objects.
2034 """
2036 method_prefix = 'Async.'
2038 def __init__(self, xenapi):
2039 """Initialises the Async Proxy by making a map of all
2040 implemented Xen API methods for use with XendTaskManager.
2042 @param xenapi: XendAPI instance
2043 """
2044 self.xenapi = xenapi
2045 self.method_map = {}
2046 for method_name in dir(self.xenapi):
2047 method = getattr(self.xenapi, method_name)
2048 if method_name[0] != '_' and hasattr(method, 'async') \
2049 and method.async == True:
2050 self.method_map[method.api] = method
2052 def _dispatch(self, method, args):
2053 """Overridden method so that SimpleXMLRPCServer will
2054 resolve methods through this method rather than through
2055 inspection.
2057 @param method: marshalled method name from XMLRPC.
2058 @param args: marshalled arguments from XMLRPC.
2059 """
2061 # Only deal with method names that start with "Async."
2062 if not method.startswith(self.method_prefix):
2063 return xen_api_error(['MESSAGE_METHOD_UNKNOWN', method])
2065 # Lookup synchronous version of the method
2066 synchronous_method_name = method[len(self.method_prefix):]
2067 if synchronous_method_name not in self.method_map:
2068 return xen_api_error(['MESSAGE_METHOD_UNKNOWN', method])
2070 method = self.method_map[synchronous_method_name]
2072 # Check that we've got enough arguments before issuing a task ID.
2073 needed = argcounts[method.api]
2074 if len(args) != needed:
2075 return xen_api_error(['MESSAGE_PARAMETER_COUNT_MISMATCH',
2076 self.method_prefix + method.api, needed,
2077 len(args)])
2079 # Validate the session before proceeding
2080 session = args[0]
2081 if not auth_manager().is_session_valid(session):
2082 return xen_api_error(['SESSION_INVALID', session])
2084 # create and execute the task, and return task_uuid
2085 return_type = getattr(method, 'return_type', None)
2086 task_uuid = XendTaskManager.create_task(method, args,
2087 synchronous_method_name,
2088 return_type,
2089 synchronous_method_name,
2090 session)
2091 return xen_api_success(task_uuid)
2094 # Auto generate some stubs based on XendAPI introspection
2096 if __name__ == "__main__":
2097 def output(line):
2098 print ' ' + line
2100 classes = ['VDI', 'SR']
2101 for cls in classes:
2102 ro_attrs = getattr(XendAPI, '%s_attr_ro' % cls, [])
2103 rw_attrs = getattr(XendAPI, '%s_attr_rw' % cls, [])
2104 methods = getattr(XendAPI, '%s_methods' % cls, [])
2105 funcs = getattr(XendAPI, '%s_funcs' % cls, [])
2107 ref = '%s_ref' % cls
2109 for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
2110 getter_name = '%s_get_%s' % (cls, attr_name)
2111 output('def %s(self, session, %s):' % (getter_name, ref))
2112 output(' return xen_api_todo()')
2114 for attr_name in rw_attrs + XendAPI.Base_attr_rw:
2115 setter_name = '%s_set_%s' % (cls, attr_name)
2116 output('def %s(self, session, %s, value):' % (setter_name, ref))
2117 output(' return xen_api_todo()')
2119 for method_name in methods + XendAPI.Base_methods:
2120 method_full_name = '%s_%s' % (cls,method_name)
2121 output('def %s(self, session, %s):' % (method_full_name, ref))
2122 output(' return xen_api_todo()')
2124 for func_name in funcs + XendAPI.Base_funcs:
2125 func_full_name = '%s_%s' % (cls, func_name)
2126 output('def %s(self, session):' % func_full_name)
2127 output(' return xen_api_todo()')