ia64/xen-unstable

view tools/python/xen/xend/XendAPI.py @ 19460:2269d8704139

XenAPI: Implement {get,set}_auto_power_on

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 31 11:48:07 2009 +0100 (2009-03-31)
parents 5ae8ed54e2cd
children cc2267c6d53b
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 Queue
21 import sets
22 import string
23 import sys
24 import traceback
25 import threading
26 import time
27 import xmlrpclib
29 import XendDomain, XendDomainInfo, XendNode, XendDmesg
30 import XendLogging, XendTaskManager, XendAPIStore
32 from xen.xend import uuid as genuuid
33 from XendAPIVersion import *
34 from XendAuthSessions import instance as auth_manager
35 from XendError import *
36 from XendClient import ERROR_INVALID_DOMAIN
37 from XendLogging import log
38 from XendNetwork import XendNetwork
39 from XendTask import XendTask
40 from XendPIFMetrics import XendPIFMetrics
41 from XendVMMetrics import XendVMMetrics
42 from XendPIF import XendPIF
43 from XendPBD import XendPBD
44 from XendPPCI import XendPPCI
45 from XendDPCI import XendDPCI
46 from XendPSCSI import XendPSCSI
47 from XendDSCSI import XendDSCSI
48 from XendXSPolicy import XendXSPolicy, XendACMPolicy
50 from XendAPIConstants import *
51 from xen.util.xmlrpclib2 import stringify
53 from xen.util.blkif import blkdev_name_to_number
54 from xen.util import xsconstants
57 AUTH_NONE = 'none'
58 AUTH_PAM = 'pam'
60 argcounts = {}
62 # ------------------------------------------
63 # Utility Methods for Xen API Implementation
64 # ------------------------------------------
66 def xen_api_success(value):
67 """Wraps a return value in XenAPI format."""
68 if value is None:
69 s = ''
70 else:
71 s = stringify(value)
72 return {"Status": "Success", "Value": s}
74 def xen_api_success_void():
75 """Return success, but caller expects no return value."""
76 return xen_api_success("")
78 def xen_api_error(error):
79 """Wraps an error value in XenAPI format."""
80 if type(error) == tuple:
81 error = list(error)
82 if type(error) != list:
83 error = [error]
84 if len(error) == 0:
85 error = ['INTERNAL_ERROR', 'Empty list given to xen_api_error']
87 return { "Status": "Failure",
88 "ErrorDescription": [str(x) for x in error] }
91 def xen_api_todo():
92 """Temporary method to make sure we track down all the TODOs"""
93 return {"Status": "Error", "ErrorDescription": XEND_ERROR_TODO}
96 def now():
97 return datetime()
100 def datetime(when = None):
101 """Marshall the given time as a Xen-API DateTime.
103 @param when The time in question, given as seconds since the epoch, UTC.
104 May be None, in which case the current time is used.
105 """
106 if when is None:
107 return xmlrpclib.DateTime(time.gmtime())
108 else:
109 return xmlrpclib.DateTime(time.gmtime(when))
112 # ---------------------------------------------------
113 # Event dispatch
114 # ---------------------------------------------------
116 EVENT_QUEUE_LENGTH = 50
117 event_registrations = {}
119 def event_register(session, reg_classes):
120 if session not in event_registrations:
121 event_registrations[session] = {
122 'classes' : sets.Set(),
123 'queue' : Queue.Queue(EVENT_QUEUE_LENGTH),
124 'next-id' : 1
125 }
126 if not reg_classes:
127 reg_classes = classes
128 event_registrations[session]['classes'].union_update(reg_classes)
131 def event_unregister(session, unreg_classes):
132 if session not in event_registrations:
133 return
135 if unreg_classes:
136 event_registrations[session]['classes'].intersection_update(
137 unreg_classes)
138 if len(event_registrations[session]['classes']) == 0:
139 del event_registrations[session]
140 else:
141 del event_registrations[session]
144 def event_next(session):
145 if session not in event_registrations:
146 return xen_api_error(['SESSION_NOT_REGISTERED', session])
147 queue = event_registrations[session]['queue']
148 events = [queue.get()]
149 try:
150 while True:
151 events.append(queue.get(False))
152 except Queue.Empty:
153 pass
155 return xen_api_success(events)
158 def _ctor_event_dispatch(xenapi, ctor, api_cls, session, args):
159 result = ctor(xenapi, session, *args)
160 if result['Status'] == 'Success':
161 ref = result['Value']
162 event_dispatch('add', api_cls, ref, '')
163 return result
166 def _dtor_event_dispatch(xenapi, dtor, api_cls, session, ref, args):
167 result = dtor(xenapi, session, ref, *args)
168 if result['Status'] == 'Success':
169 event_dispatch('del', api_cls, ref, '')
170 return result
173 def _setter_event_dispatch(xenapi, setter, api_cls, attr_name, session, ref,
174 args):
175 result = setter(xenapi, session, ref, *args)
176 if result['Status'] == 'Success':
177 event_dispatch('mod', api_cls, ref, attr_name)
178 return result
181 def event_dispatch(operation, api_cls, ref, attr_name):
182 assert operation in ['add', 'del', 'mod']
183 event = {
184 'timestamp' : now(),
185 'class' : api_cls,
186 'operation' : operation,
187 'ref' : ref,
188 'obj_uuid' : ref,
189 'field' : attr_name,
190 }
191 for reg in event_registrations.values():
192 if api_cls in reg['classes']:
193 event['id'] = reg['next-id']
194 reg['next-id'] += 1
195 reg['queue'].put(event)
198 # ---------------------------------------------------
199 # Python Method Decorators for input value validation
200 # ---------------------------------------------------
202 def trace(func, api_name = ''):
203 """Decorator to trace XMLRPC Xen API methods.
205 @param func: function with any parameters
206 @param api_name: name of the api call for debugging.
207 """
208 if hasattr(func, 'api'):
209 api_name = func.api
210 def trace_func(self, *args, **kwargs):
211 log.debug('%s: %s' % (api_name, args))
212 return func(self, *args, **kwargs)
213 trace_func.api = api_name
214 return trace_func
217 def catch_typeerror(func):
218 """Decorator to catch any TypeErrors and translate them into Xen-API
219 errors.
221 @param func: function with params: (self, ...)
222 @rtype: callable object
223 """
224 def f(self, *args, **kwargs):
225 try:
226 return func(self, *args, **kwargs)
227 except TypeError, exn:
228 #log.exception('catch_typeerror')
229 if hasattr(func, 'api') and func.api in argcounts:
230 # Assume that if the argument count was wrong and if the
231 # exception was thrown inside this file, then it is due to an
232 # invalid call from the client, otherwise it's an internal
233 # error (which will be handled further up).
234 expected = argcounts[func.api]
235 actual = len(args) + len(kwargs)
236 if expected != actual:
237 tb = sys.exc_info()[2]
238 try:
239 sourcefile = traceback.extract_tb(tb)[-1][0]
240 if sourcefile == inspect.getsourcefile(XendAPI):
241 return xen_api_error(
242 ['MESSAGE_PARAMETER_COUNT_MISMATCH',
243 func.api, expected, actual])
244 finally:
245 del tb
246 raise
247 except XendAPIError, exn:
248 return xen_api_error(exn.get_api_error())
250 return f
253 def session_required(func):
254 """Decorator to verify if session is valid before calling method.
256 @param func: function with params: (self, session, ...)
257 @rtype: callable object
258 """
259 def check_session(self, session, *args, **kwargs):
260 if auth_manager().is_session_valid(session):
261 return func(self, session, *args, **kwargs)
262 else:
263 return xen_api_error(['SESSION_INVALID', session])
265 return check_session
268 def _is_valid_ref(ref, validator):
269 return type(ref) == str and validator(ref)
271 def _check_ref(validator, clas, func, api, session, ref, *args, **kwargs):
272 if _is_valid_ref(ref, validator):
273 return func(api, session, ref, *args, **kwargs)
274 else:
275 return xen_api_error(['HANDLE_INVALID', clas, ref])
278 def valid_host(func):
279 """Decorator to verify if host_ref is valid before calling method.
281 @param func: function with params: (self, session, host_ref, ...)
282 @rtype: callable object
283 """
284 return lambda *args, **kwargs: \
285 _check_ref(XendNode.instance().is_valid_host,
286 'host', func, *args, **kwargs)
288 def valid_host_metrics(func):
289 """Decorator to verify if host_metrics_ref is valid before calling
290 method.
292 @param func: function with params: (self, session, host_metrics_ref)
293 @rtype: callable object
294 """
295 return lambda *args, **kwargs: \
296 _check_ref(lambda r: r == XendNode.instance().host_metrics_uuid,
297 'host_metrics', func, *args, **kwargs)
299 def valid_host_cpu(func):
300 """Decorator to verify if host_cpu_ref is valid before calling method.
302 @param func: function with params: (self, session, host_cpu_ref, ...)
303 @rtype: callable object
304 """
305 return lambda *args, **kwargs: \
306 _check_ref(XendNode.instance().is_valid_cpu,
307 'host_cpu', func, *args, **kwargs)
309 def valid_vm(func):
310 """Decorator to verify if vm_ref is valid before calling method.
312 @param func: function with params: (self, session, vm_ref, ...)
313 @rtype: callable object
314 """
315 return lambda *args, **kwargs: \
316 _check_ref(XendDomain.instance().is_valid_vm,
317 'VM', func, *args, **kwargs)
319 def valid_vbd(func):
320 """Decorator to verify if vbd_ref is valid before calling method.
322 @param func: function with params: (self, session, vbd_ref, ...)
323 @rtype: callable object
324 """
325 return lambda *args, **kwargs: \
326 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vbd', r),
327 'VBD', func, *args, **kwargs)
329 def valid_vbd_metrics(func):
330 """Decorator to verify if ref is valid before calling method.
332 @param func: function with params: (self, session, ref, ...)
333 @rtype: callable object
334 """
335 return lambda *args, **kwargs: \
336 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vbd', r),
337 'VBD_metrics', func, *args, **kwargs)
339 def valid_vif(func):
340 """Decorator to verify if vif_ref is valid before calling method.
342 @param func: function with params: (self, session, vif_ref, ...)
343 @rtype: callable object
344 """
345 return lambda *args, **kwargs: \
346 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vif', r),
347 'VIF', func, *args, **kwargs)
349 def valid_vif_metrics(func):
350 """Decorator to verify if ref is valid before calling method.
352 @param func: function with params: (self, session, ref, ...)
353 @rtype: callable object
354 """
355 return lambda *args, **kwargs: \
356 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vif', r),
357 'VIF_metrics', func, *args, **kwargs)
359 def valid_vdi(func):
360 """Decorator to verify if vdi_ref is valid before calling method.
362 @param func: function with params: (self, session, vdi_ref, ...)
363 @rtype: callable object
364 """
365 return lambda *args, **kwargs: \
366 _check_ref(XendNode.instance().is_valid_vdi,
367 'VDI', func, *args, **kwargs)
369 def valid_vtpm(func):
370 """Decorator to verify if vtpm_ref is valid before calling method.
372 @param func: function with params: (self, session, vtpm_ref, ...)
373 @rtype: callable object
374 """
375 return lambda *args, **kwargs: \
376 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vtpm', r),
377 'VTPM', func, *args, **kwargs)
380 def valid_console(func):
381 """Decorator to verify if console_ref is valid before calling method.
383 @param func: function with params: (self, session, console_ref, ...)
384 @rtype: callable object
385 """
386 return lambda *args, **kwargs: \
387 _check_ref(lambda r: XendDomain.instance().is_valid_dev('console',
388 r),
389 'console', func, *args, **kwargs)
391 def valid_sr(func):
392 """Decorator to verify if sr_ref is valid before calling method.
394 @param func: function with params: (self, session, sr_ref, ...)
395 @rtype: callable object
396 """
397 return lambda *args, **kwargs: \
398 _check_ref(lambda r: XendNode.instance().is_valid_sr,
399 'SR', func, *args, **kwargs)
401 def valid_task(func):
402 """Decorator to verify if task_ref is valid before calling
403 method.
405 @param func: function with params: (self, session, task_ref)
406 @rtype: callable object
407 """
408 return lambda *args, **kwargs: \
409 _check_ref(XendTaskManager.get_task,
410 'task', func, *args, **kwargs)
412 def valid_debug(func):
413 """Decorator to verify if task_ref is valid before calling
414 method.
416 @param func: function with params: (self, session, task_ref)
417 @rtype: callable object
418 """
419 return lambda *args, **kwargs: \
420 _check_ref(lambda r: r in XendAPI._debug,
421 'debug', func, *args, **kwargs)
424 def valid_object(class_name):
425 """Decorator to verify if object is valid before calling
426 method.
428 @param func: function with params: (self, session, pif_ref)
429 @rtype: callable object
430 """
431 return lambda func: \
432 lambda *args, **kwargs: \
433 _check_ref(lambda r: \
434 XendAPIStore.get(r, class_name) is not None,
435 class_name, func, *args, **kwargs)
437 # -----------------------------
438 # Bridge to Legacy XM API calls
439 # -----------------------------
441 def do_vm_func(fn_name, vm_ref, *args, **kwargs):
442 """Helper wrapper func to abstract away from repetitive code.
444 @param fn_name: function name for XendDomain instance
445 @type fn_name: string
446 @param vm_ref: vm_ref
447 @type vm_ref: string
448 @param *args: more arguments
449 @type *args: tuple
450 """
451 try:
452 xendom = XendDomain.instance()
453 fn = getattr(xendom, fn_name)
454 xendom.do_legacy_api_with_uuid(fn, vm_ref, *args, **kwargs)
455 return xen_api_success_void()
456 except VMBadState, exn:
457 return xen_api_error(['VM_BAD_POWER_STATE', vm_ref, exn.expected,
458 exn.actual])
461 classes = {
462 'session' : None,
463 'event' : None,
464 'host' : valid_host,
465 'host_cpu' : valid_host_cpu,
466 'host_metrics' : valid_host_metrics,
467 'VM' : valid_vm,
468 'VBD' : valid_vbd,
469 'VBD_metrics' : valid_vbd_metrics,
470 'VIF' : valid_vif,
471 'VIF_metrics' : valid_vif_metrics,
472 'VDI' : valid_vdi,
473 'VTPM' : valid_vtpm,
474 'console' : valid_console,
475 'SR' : valid_sr,
476 'task' : valid_task,
477 'XSPolicy' : valid_object("XSPolicy"),
478 'ACMPolicy' : valid_object("ACMPolicy"),
479 'debug' : valid_debug,
480 'network' : valid_object("network"),
481 'PIF' : valid_object("PIF"),
482 'VM_metrics' : valid_object("VM_metrics"),
483 'PBD' : valid_object("PBD"),
484 'PIF_metrics' : valid_object("PIF_metrics"),
485 'PPCI' : valid_object("PPCI"),
486 'DPCI' : valid_object("DPCI"),
487 'PSCSI' : valid_object("PSCSI"),
488 'DSCSI' : valid_object("DSCSI")
489 }
491 autoplug_classes = {
492 'network' : XendNetwork,
493 'PIF' : XendPIF,
494 'VM_metrics' : XendVMMetrics,
495 'PBD' : XendPBD,
496 'PIF_metrics' : XendPIFMetrics,
497 'PPCI' : XendPPCI,
498 'DPCI' : XendDPCI,
499 'PSCSI' : XendPSCSI,
500 'DSCSI' : XendDSCSI,
501 'XSPolicy' : XendXSPolicy,
502 'ACMPolicy' : XendACMPolicy,
503 }
505 class XendAPI(object):
506 """Implementation of the Xen-API in Xend. Expects to be
507 used via XMLRPCServer.
509 All methods that need a valid session are marked with
510 a L{session_required} decorator that will
511 transparently perform the required session authentication.
513 We need to support Python <2.4, so we use the old decorator syntax.
515 All XMLRPC accessible methods require an 'api' attribute and
516 is set to the XMLRPC function name which the method implements.
517 """
519 __decorated__ = False
520 __init_lock__ = threading.Lock()
521 _debug = {}
523 def __new__(cls, *args, **kwds):
524 """ Override __new__ to decorate the class only once.
526 Lock to make sure the classes are not decorated twice.
527 """
528 cls.__init_lock__.acquire()
529 try:
530 if not cls.__decorated__:
531 cls._decorate()
532 cls.__decorated__ = True
534 return object.__new__(cls, *args, **kwds)
535 finally:
536 cls.__init_lock__.release()
538 def _decorate(cls):
539 """ Decorate all the object methods to have validators
540 and appropriate function attributes.
542 This should only be executed once for the duration of the
543 server.
544 """
545 global_validators = [session_required, catch_typeerror]
548 # Cheat methods
549 # -------------
550 # Methods that have a trivial implementation for all classes.
551 # 1. get_by_uuid == getting by ref, so just return uuid for
552 # all get_by_uuid() methods.
554 for api_cls in classes.keys():
555 # We'll let the autoplug classes implement these functions
556 # themselves - its much cleaner to do it in the base class
557 if api_cls == 'session' or api_cls in autoplug_classes.keys():
558 continue
560 get_by_uuid = '%s_get_by_uuid' % api_cls
561 get_uuid = '%s_get_uuid' % api_cls
562 get_all_records = '%s_get_all_records' % api_cls
564 def _get_by_uuid(_1, _2, ref):
565 return xen_api_success(ref)
567 def _get_uuid(_1, _2, ref):
568 return xen_api_success(ref)
570 def unpack(v):
571 return v.get('Value')
573 def _get_all_records(_api_cls):
574 return lambda s, session: \
575 xen_api_success(dict([(ref, unpack(getattr(cls, '%s_get_record' % _api_cls)(s, session, ref)))\
576 for ref in unpack(getattr(cls, '%s_get_all' % _api_cls)(s, session))]))
578 setattr(cls, get_by_uuid, _get_by_uuid)
579 setattr(cls, get_uuid, _get_uuid)
580 setattr(cls, get_all_records, _get_all_records(api_cls))
582 # Autoplugging classes
583 # --------------------
584 # These have all of their methods grabbed out from the implementation
585 # class, and wrapped up to be compatible with the Xen-API.
587 def getter(ref, type):
588 return XendAPIStore.get(ref, type)
590 for api_cls, impl_cls in autoplug_classes.items():
591 def doit(n):
592 dot_n = '%s.%s' % (api_cls, n)
593 full_n = '%s_%s' % (api_cls, n)
594 if not hasattr(cls, full_n):
595 f = getattr(impl_cls, n)
596 argcounts[dot_n] = f.func_code.co_argcount + 1
597 g = lambda api_cls: \
598 setattr(cls, full_n, \
599 lambda s, session, ref, *args: \
600 xen_api_success( \
601 f(getter(ref, api_cls), *args)))
602 g(api_cls) # Force api_cls to be captured
604 def doit_func(n):
605 dot_n = '%s.%s' % (api_cls, n)
606 full_n = '%s_%s' % (api_cls, n)
607 if not hasattr(cls, full_n):
608 f = getattr(impl_cls, n)
609 argcounts[dot_n] = f.func_code.co_argcount
610 setattr(cls, full_n, \
611 lambda s, session, *args: \
612 xen_api_success( \
613 f(*args)))
615 ro_attrs = impl_cls.getAttrRO()
616 rw_attrs = impl_cls.getAttrRW()
617 methods = impl_cls.getMethods()
618 funcs = impl_cls.getFuncs()
620 for attr_name in ro_attrs + rw_attrs:
621 doit('get_%s' % attr_name)
622 for attr_name in rw_attrs:
623 doit('set_%s' % attr_name)
624 for method in methods:
625 doit('%s' % method)
626 for func in funcs:
627 doit_func('%s' % func)
629 def wrap_method(name, new_f):
630 try:
631 f = getattr(cls, name)
632 wrapped_f = (lambda *args: new_f(f, *args))
633 wrapped_f.api = f.api
634 wrapped_f.async = f.async
635 setattr(cls, name, wrapped_f)
636 except AttributeError:
637 # Logged below (API call: %s not found)
638 pass
641 def setter_event_wrapper(api_cls, attr_name):
642 setter_name = '%s_set_%s' % (api_cls, attr_name)
643 wrap_method(
644 setter_name,
645 lambda setter, s, session, ref, *args:
646 _setter_event_dispatch(s, setter, api_cls, attr_name,
647 session, ref, args))
650 def ctor_event_wrapper(api_cls):
651 ctor_name = '%s_create' % api_cls
652 wrap_method(
653 ctor_name,
654 lambda ctor, s, session, *args:
655 _ctor_event_dispatch(s, ctor, api_cls, session, args))
658 def dtor_event_wrapper(api_cls):
659 dtor_name = '%s_destroy' % api_cls
660 wrap_method(
661 dtor_name,
662 lambda dtor, s, session, ref, *args:
663 _dtor_event_dispatch(s, dtor, api_cls, session, ref, args))
666 # Wrapping validators around XMLRPC calls
667 # ---------------------------------------
669 for api_cls, validator in classes.items():
670 def doit(n, takes_instance, async_support = False,
671 return_type = None):
672 n_ = n.replace('.', '_')
673 try:
674 f = getattr(cls, n_)
675 if n not in argcounts:
676 argcounts[n] = f.func_code.co_argcount - 1
678 validators = takes_instance and validator and \
679 [validator] or []
681 validators += global_validators
682 for v in validators:
683 f = v(f)
684 f.api = n
685 f.async = async_support
686 if return_type:
687 f.return_type = return_type
689 setattr(cls, n_, f)
690 except AttributeError:
691 log.warn("API call: %s not found" % n)
693 if api_cls in autoplug_classes.keys():
694 impl_cls = autoplug_classes[api_cls]
695 ro_attrs = impl_cls.getAttrRO()
696 rw_attrs = impl_cls.getAttrRW()
697 methods = map(lambda x: (x, ""), impl_cls.getMethods())
698 funcs = map(lambda x: (x, ""), impl_cls.getFuncs())
699 else:
700 ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, []) \
701 + cls.Base_attr_ro
702 rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, []) \
703 + cls.Base_attr_rw
704 methods = getattr(cls, '%s_methods' % api_cls, []) \
705 + cls.Base_methods
706 funcs = getattr(cls, '%s_funcs' % api_cls, []) \
707 + cls.Base_funcs
709 # wrap validators around readable class attributes
710 for attr_name in ro_attrs + rw_attrs:
711 doit('%s.get_%s' % (api_cls, attr_name), True,
712 async_support = False)
714 # wrap validators around writable class attrributes
715 for attr_name in rw_attrs:
716 doit('%s.set_%s' % (api_cls, attr_name), True,
717 async_support = False)
718 setter_event_wrapper(api_cls, attr_name)
720 # wrap validators around methods
721 for method_name, return_type in methods:
722 doit('%s.%s' % (api_cls, method_name), True,
723 async_support = True)
725 # wrap validators around class functions
726 for func_name, return_type in funcs:
727 doit('%s.%s' % (api_cls, func_name), False,
728 async_support = True,
729 return_type = return_type)
731 ctor_event_wrapper(api_cls)
732 dtor_event_wrapper(api_cls)
735 _decorate = classmethod(_decorate)
737 def __init__(self, auth):
738 self.auth = auth
740 Base_attr_ro = ['uuid']
741 Base_attr_rw = []
742 Base_methods = [('get_record', 'Struct')]
743 Base_funcs = [('get_all', 'Set'), ('get_by_uuid', None), ('get_all_records', 'Set')]
745 # Xen API: Class Session
746 # ----------------------------------------------------------------
747 # NOTE: Left unwrapped by __init__
749 session_attr_ro = ['this_host', 'this_user', 'last_active']
750 session_methods = [('logout', None)]
752 def session_get_all(self, session):
753 return xen_api_success([session])
755 def session_login_with_password(self, *args):
756 if len(args) != 2:
757 return xen_api_error(
758 ['MESSAGE_PARAMETER_COUNT_MISMATCH',
759 'session.login_with_password', 2, len(args)])
760 username = args[0]
761 password = args[1]
762 try:
763 session = ((self.auth == AUTH_NONE and
764 auth_manager().login_unconditionally(username)) or
765 auth_manager().login_with_password(username, password))
766 return xen_api_success(session)
767 except XendError, e:
768 return xen_api_error(['SESSION_AUTHENTICATION_FAILED'])
769 session_login_with_password.api = 'session.login_with_password'
771 # object methods
772 def session_logout(self, session):
773 auth_manager().logout(session)
774 return xen_api_success_void()
776 def session_get_record(self, session, self_session):
777 if self_session != session:
778 return xen_api_error(['PERMISSION_DENIED'])
779 record = {'uuid' : session,
780 'this_host' : XendNode.instance().uuid,
781 'this_user' : auth_manager().get_user(session),
782 'last_active': now()}
783 return xen_api_success(record)
785 def session_get_uuid(self, session, self_session):
786 return xen_api_success(self_session)
788 def session_get_by_uuid(self, session, self_session):
789 return xen_api_success(self_session)
791 # attributes (ro)
792 def session_get_this_host(self, session, self_session):
793 if self_session != session:
794 return xen_api_error(['PERMISSION_DENIED'])
795 return xen_api_success(XendNode.instance().uuid)
797 def session_get_this_user(self, session, self_session):
798 if self_session != session:
799 return xen_api_error(['PERMISSION_DENIED'])
800 user = auth_manager().get_user(session)
801 if user is not None:
802 return xen_api_success(user)
803 return xen_api_error(['SESSION_INVALID', session])
805 def session_get_last_active(self, session, self_session):
806 if self_session != session:
807 return xen_api_error(['PERMISSION_DENIED'])
808 return xen_api_success(now())
811 # Xen API: Class User
812 # ----------------------------------------------------------------
813 # TODO: NOT IMPLEMENTED YET
815 # Xen API: Class Tasks
816 # ----------------------------------------------------------------
818 task_attr_ro = ['name_label',
819 'name_description',
820 'status',
821 'progress',
822 'type',
823 'result',
824 'error_info',
825 'allowed_operations',
826 'session'
827 ]
829 task_attr_rw = []
831 task_funcs = [('get_by_name_label', 'Set(task)'),
832 ('cancel', None)]
834 def task_get_name_label(self, session, task_ref):
835 task = XendTaskManager.get_task(task_ref)
836 return xen_api_success(task.name_label)
838 def task_get_name_description(self, session, task_ref):
839 task = XendTaskManager.get_task(task_ref)
840 return xen_api_success(task.name_description)
842 def task_get_status(self, session, task_ref):
843 task = XendTaskManager.get_task(task_ref)
844 return xen_api_success(task.get_status())
846 def task_get_progress(self, session, task_ref):
847 task = XendTaskManager.get_task(task_ref)
848 return xen_api_success(task.progress)
850 def task_get_type(self, session, task_ref):
851 task = XendTaskManager.get_task(task_ref)
852 return xen_api_success(task.type)
854 def task_get_result(self, session, task_ref):
855 task = XendTaskManager.get_task(task_ref)
856 return xen_api_success(task.result)
858 def task_get_error_info(self, session, task_ref):
859 task = XendTaskManager.get_task(task_ref)
860 return xen_api_success(task.error_info)
862 def task_get_allowed_operations(self, session, task_ref):
863 return xen_api_success({})
865 def task_get_session(self, session, task_ref):
866 task = XendTaskManager.get_task(task_ref)
867 return xen_api_success(task.session)
869 def task_get_all(self, session):
870 tasks = XendTaskManager.get_all_tasks()
871 return xen_api_success(tasks)
873 def task_get_record(self, session, task_ref):
874 task = XendTaskManager.get_task(task_ref)
875 return xen_api_success(task.get_record())
877 def task_cancel(self, session, task_ref):
878 return xen_api_error('OPERATION_NOT_ALLOWED')
880 def task_get_by_name_label(self, session, name):
881 return xen_api_success(XendTaskManager.get_task_by_name(name))
883 # Xen API: Class host
884 # ----------------------------------------------------------------
886 host_attr_ro = ['software_version',
887 'resident_VMs',
888 'PBDs',
889 'PIFs',
890 'PPCIs',
891 'PSCSIs',
892 'host_CPUs',
893 'cpu_configuration',
894 'metrics',
895 'capabilities',
896 'supported_bootloaders',
897 'sched_policy',
898 'API_version_major',
899 'API_version_minor',
900 'API_version_vendor',
901 'API_version_vendor_implementation',
902 'enabled']
904 host_attr_rw = ['name_label',
905 'name_description',
906 'other_config',
907 'logging']
909 host_methods = [('disable', None),
910 ('enable', None),
911 ('reboot', None),
912 ('shutdown', None),
913 ('add_to_other_config', None),
914 ('remove_from_other_config', None),
915 ('dmesg', 'String'),
916 ('dmesg_clear', 'String'),
917 ('get_log', 'String'),
918 ('send_debug_keys', None)]
920 host_funcs = [('get_by_name_label', None),
921 ('list_methods', None)]
923 # attributes
924 def host_get_name_label(self, session, host_ref):
925 return xen_api_success(XendNode.instance().name)
926 def host_set_name_label(self, session, host_ref, new_name):
927 XendNode.instance().set_name(new_name)
928 return xen_api_success_void()
929 def host_get_name_description(self, session, host_ref):
930 return xen_api_success(XendNode.instance().get_description())
931 def host_set_name_description(self, session, host_ref, new_desc):
932 XendNode.instance().set_description(new_desc)
933 return xen_api_success_void()
934 def host_get_other_config(self, session, host_ref):
935 return xen_api_success(XendNode.instance().other_config)
936 def host_set_other_config(self, session, host_ref, other_config):
937 node = XendNode.instance()
938 node.other_config = dict(other_config)
939 node.save()
940 return xen_api_success_void()
941 def host_add_to_other_config(self, session, host_ref, key, value):
942 node = XendNode.instance()
943 node.other_config[key] = value
944 node.save()
945 return xen_api_success_void()
946 def host_remove_from_other_config(self, session, host_ref, key):
947 node = XendNode.instance()
948 if key in node.other_config:
949 del node.other_config[key]
950 node.save()
951 return xen_api_success_void()
952 def host_get_API_version_major(self, _, ref):
953 return xen_api_success(XEN_API_VERSION_MAJOR)
954 def host_get_API_version_minor(self, _, ref):
955 return xen_api_success(XEN_API_VERSION_MINOR)
956 def host_get_API_version_vendor(self, _, ref):
957 return xen_api_success(XEN_API_VERSION_VENDOR)
958 def host_get_API_version_vendor_implementation(self, _, ref):
959 return xen_api_success(XEN_API_VERSION_VENDOR_IMPLEMENTATION)
960 def host_get_software_version(self, session, host_ref):
961 return xen_api_success(XendNode.instance().xen_version())
962 def host_get_enabled(self, _1, _2):
963 return xen_api_success(XendDomain.instance().allow_new_domains())
964 def host_get_resident_VMs(self, session, host_ref):
965 return xen_api_success(XendDomain.instance().get_domain_refs())
966 def host_get_PBDs(self, _, ref):
967 return xen_api_success(XendPBD.get_all())
968 def host_get_PIFs(self, session, ref):
969 return xen_api_success(XendNode.instance().get_PIF_refs())
970 def host_get_PPCIs(self, session, ref):
971 return xen_api_success(XendNode.instance().get_PPCI_refs())
972 def host_get_PSCSIs(self, session, ref):
973 return xen_api_success(XendNode.instance().get_PSCSI_refs())
974 def host_get_host_CPUs(self, session, host_ref):
975 return xen_api_success(XendNode.instance().get_host_cpu_refs())
976 def host_get_metrics(self, _, ref):
977 return xen_api_success(XendNode.instance().host_metrics_uuid)
978 def host_get_capabilities(self, session, host_ref):
979 return xen_api_success(XendNode.instance().get_capabilities())
980 def host_get_supported_bootloaders(self, session, host_ref):
981 return xen_api_success(['pygrub'])
982 def host_get_sched_policy(self, _, host_ref):
983 return xen_api_success(XendNode.instance().get_vcpus_policy())
984 def host_get_cpu_configuration(self, _, host_ref):
985 return xen_api_success(XendNode.instance().get_cpu_configuration())
986 def host_set_logging(self, _, host_ref, logging):
987 return xen_api_todo()
988 def host_get_logging(self, _, host_ref):
989 return xen_api_todo()
991 # object methods
992 def host_disable(self, session, host_ref):
993 XendDomain.instance().set_allow_new_domains(False)
994 return xen_api_success_void()
995 def host_enable(self, session, host_ref):
996 XendDomain.instance().set_allow_new_domains(True)
997 return xen_api_success_void()
998 def host_reboot(self, session, host_ref):
999 if not XendDomain.instance().allow_new_domains():
1000 return xen_api_error(XEND_ERROR_HOST_RUNNING)
1001 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1002 def host_shutdown(self, session, host_ref):
1003 if not XendDomain.instance().allow_new_domains():
1004 return xen_api_error(XEND_ERROR_HOST_RUNNING)
1005 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1007 def host_dmesg(self, session, host_ref):
1008 return xen_api_success(XendDmesg.instance().info())
1010 def host_dmesg_clear(self, session, host_ref):
1011 return xen_api_success(XendDmesg.instance().clear())
1013 def host_get_log(self, session, host_ref):
1014 log_file = open(XendLogging.getLogFilename())
1015 log_buffer = log_file.read()
1016 log_buffer = log_buffer.replace('\b', ' ')
1017 log_buffer = log_buffer.replace('\f', '\n')
1018 log_file.close()
1019 return xen_api_success(log_buffer)
1021 def host_send_debug_keys(self, _, host_ref, keys):
1022 node = XendNode.instance()
1023 node.send_debug_keys(keys)
1024 return xen_api_success_void()
1026 def host_get_record(self, session, host_ref):
1027 node = XendNode.instance()
1028 dom = XendDomain.instance()
1029 record = {'uuid': node.uuid,
1030 'name_label': node.name,
1031 'name_description': '',
1032 'API_version_major': XEN_API_VERSION_MAJOR,
1033 'API_version_minor': XEN_API_VERSION_MINOR,
1034 'API_version_vendor': XEN_API_VERSION_VENDOR,
1035 'API_version_vendor_implementation':
1036 XEN_API_VERSION_VENDOR_IMPLEMENTATION,
1037 'software_version': node.xen_version(),
1038 'enabled': XendDomain.instance().allow_new_domains(),
1039 'other_config': node.other_config,
1040 'resident_VMs': dom.get_domain_refs(),
1041 'host_CPUs': node.get_host_cpu_refs(),
1042 'cpu_configuration': node.get_cpu_configuration(),
1043 'metrics': node.host_metrics_uuid,
1044 'capabilities': node.get_capabilities(),
1045 'supported_bootloaders': ['pygrub'],
1046 'sched_policy': node.get_vcpus_policy(),
1047 'logging': {},
1048 'PIFs': XendPIF.get_all(),
1049 'PBDs': XendPBD.get_all(),
1050 'PPCIs': XendPPCI.get_all(),
1051 'PSCSIs': XendPSCSI.get_all()}
1052 return xen_api_success(record)
1054 # class methods
1055 def host_get_all(self, session):
1056 return xen_api_success((XendNode.instance().uuid,))
1057 def host_get_by_name_label(self, session, name):
1058 if XendNode.instance().name == name:
1059 return xen_api_success((XendNode.instance().uuid,))
1060 return xen_api_success([])
1062 def host_list_methods(self, _):
1063 def _funcs():
1064 return [getattr(XendAPI, x) for x in XendAPI.__dict__]
1066 return xen_api_success([x.api for x in _funcs()
1067 if hasattr(x, 'api')])
1069 # Xen API: Class host_CPU
1070 # ----------------------------------------------------------------
1072 host_cpu_attr_ro = ['host',
1073 'number',
1074 'vendor',
1075 'speed',
1076 'modelname',
1077 'stepping',
1078 'flags',
1079 'utilisation',
1080 'features']
1082 # attributes
1083 def _host_cpu_get(self, ref, field):
1084 return xen_api_success(
1085 XendNode.instance().get_host_cpu_field(ref, field))
1087 def host_cpu_get_host(self, _, ref):
1088 return xen_api_success(XendNode.instance().uuid)
1089 def host_cpu_get_features(self, _, ref):
1090 return self._host_cpu_get(ref, 'features')
1091 def host_cpu_get_number(self, _, ref):
1092 return self._host_cpu_get(ref, 'number')
1093 def host_cpu_get_vendor(self, _, ref):
1094 return self._host_cpu_get(ref, 'vendor')
1095 def host_cpu_get_speed(self, _, ref):
1096 return self._host_cpu_get(ref, 'speed')
1097 def host_cpu_get_modelname(self, _, ref):
1098 return self._host_cpu_get(ref, 'modelname')
1099 def host_cpu_get_stepping(self, _, ref):
1100 return self._host_cpu_get(ref, 'stepping')
1101 def host_cpu_get_flags(self, _, ref):
1102 return self._host_cpu_get(ref, 'flags')
1103 def host_cpu_get_utilisation(self, _, ref):
1104 return xen_api_success(XendNode.instance().get_host_cpu_load(ref))
1106 # object methods
1107 def host_cpu_get_record(self, _, ref):
1108 node = XendNode.instance()
1109 record = dict([(f, node.get_host_cpu_field(ref, f))
1110 for f in self.host_cpu_attr_ro
1111 if f not in ['uuid', 'host', 'utilisation']])
1112 record['uuid'] = ref
1113 record['host'] = node.uuid
1114 record['utilisation'] = node.get_host_cpu_load(ref)
1115 return xen_api_success(record)
1117 # class methods
1118 def host_cpu_get_all(self, session):
1119 return xen_api_success(XendNode.instance().get_host_cpu_refs())
1122 # Xen API: Class host_metrics
1123 # ----------------------------------------------------------------
1125 host_metrics_attr_ro = ['memory_total',
1126 'memory_free',
1127 'last_updated']
1128 host_metrics_attr_rw = []
1129 host_metrics_methods = []
1131 def host_metrics_get_all(self, _):
1132 return xen_api_success([XendNode.instance().host_metrics_uuid])
1134 def _host_metrics_get(self, ref, f):
1135 return xen_api_success(getattr(node, f)())
1137 def host_metrics_get_record(self, _, ref):
1138 return xen_api_success({
1139 'uuid' : ref,
1140 'memory_total' : self._host_metrics_get_memory_total(),
1141 'memory_free' : self._host_metrics_get_memory_free(),
1142 'last_updated' : now(),
1143 })
1145 def host_metrics_get_memory_total(self, _1, _2):
1146 return xen_api_success(self._host_metrics_get_memory_total())
1148 def host_metrics_get_memory_free(self, _1, _2):
1149 return xen_api_success(self._host_metrics_get_memory_free())
1151 def host_metrics_get_last_updated(self, _1, _2):
1152 return xen_api_success(now())
1154 def _host_metrics_get_memory_total(self):
1155 node = XendNode.instance()
1156 return node.xc.physinfo()['total_memory'] * 1024
1158 def _host_metrics_get_memory_free(self):
1159 node = XendNode.instance()
1160 return node.xc.physinfo()['free_memory'] * 1024
1162 # Xen API: Class VM
1163 # ----------------------------------------------------------------
1165 VM_attr_ro = ['power_state',
1166 'resident_on',
1167 'consoles',
1168 'VIFs',
1169 'VBDs',
1170 'VTPMs',
1171 'DPCIs',
1172 'DSCSIs',
1173 'tools_version',
1174 'domid',
1175 'is_control_domain',
1176 'metrics',
1177 'crash_dumps',
1180 VM_attr_rw = ['name_label',
1181 'name_description',
1182 'user_version',
1183 'is_a_template',
1184 'auto_power_on',
1185 'memory_dynamic_max',
1186 'memory_dynamic_min',
1187 'memory_static_max',
1188 'memory_static_min',
1189 'VCPUs_max',
1190 'VCPUs_at_startup',
1191 'VCPUs_params',
1192 'actions_after_shutdown',
1193 'actions_after_reboot',
1194 'actions_after_suspend',
1195 'actions_after_crash',
1196 'PV_bootloader',
1197 'PV_kernel',
1198 'PV_ramdisk',
1199 'PV_args',
1200 'PV_bootloader_args',
1201 'HVM_boot_policy',
1202 'HVM_boot_params',
1203 'platform',
1204 'PCI_bus',
1205 'other_config',
1206 'security_label']
1208 VM_methods = [('clone', 'VM'),
1209 ('start', None),
1210 ('pause', None),
1211 ('unpause', None),
1212 ('clean_shutdown', None),
1213 ('clean_reboot', None),
1214 ('hard_shutdown', None),
1215 ('hard_reboot', None),
1216 ('suspend', None),
1217 ('resume', None),
1218 ('send_sysrq', None),
1219 ('set_VCPUs_number_live', None),
1220 ('add_to_HVM_boot_params', None),
1221 ('remove_from_HVM_boot_params', None),
1222 ('add_to_VCPUs_params', None),
1223 ('add_to_VCPUs_params_live', None),
1224 ('remove_from_VCPUs_params', None),
1225 ('add_to_platform', None),
1226 ('remove_from_platform', None),
1227 ('add_to_other_config', None),
1228 ('remove_from_other_config', None),
1229 ('save', None),
1230 ('set_memory_dynamic_max_live', None),
1231 ('set_memory_dynamic_min_live', None),
1232 ('send_trigger', None),
1233 ('migrate', None),
1234 ('destroy', None)]
1236 VM_funcs = [('create', 'VM'),
1237 ('restore', None),
1238 ('get_by_name_label', 'Set(VM)')]
1240 # parameters required for _create()
1241 VM_attr_inst = [
1242 'name_label',
1243 'name_description',
1244 'user_version',
1245 'is_a_template',
1246 'memory_static_max',
1247 'memory_dynamic_max',
1248 'memory_dynamic_min',
1249 'memory_static_min',
1250 'VCPUs_max',
1251 'VCPUs_at_startup',
1252 'VCPUs_params',
1253 'actions_after_shutdown',
1254 'actions_after_reboot',
1255 'actions_after_suspend',
1256 'actions_after_crash',
1257 'PV_bootloader',
1258 'PV_kernel',
1259 'PV_ramdisk',
1260 'PV_args',
1261 'PV_bootloader_args',
1262 'HVM_boot_policy',
1263 'HVM_boot_params',
1264 'platform',
1265 'PCI_bus',
1266 'other_config',
1267 'security_label']
1269 def VM_get(self, name, session, vm_ref):
1270 return xen_api_success(
1271 XendDomain.instance().get_vm_by_uuid(vm_ref).info[name])
1273 def VM_set(self, name, session, vm_ref, value):
1274 xd = XendDomain.instance()
1275 dominfo = xd.get_vm_by_uuid(vm_ref)
1276 dominfo.info[name] = value
1277 return self._VM_save(dominfo)
1279 def _VM_save(self, dominfo):
1280 XendDomain.instance().managed_config_save(dominfo)
1281 return xen_api_success_void()
1283 # attributes (ro)
1284 def VM_get_power_state(self, session, vm_ref):
1285 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1286 return xen_api_success(dom.get_power_state())
1288 def VM_get_resident_on(self, session, vm_ref):
1289 return xen_api_success(XendNode.instance().uuid)
1291 def VM_get_memory_static_max(self, session, vm_ref):
1292 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1293 return xen_api_success(dom.get_memory_static_max())
1295 def VM_get_memory_static_min(self, session, vm_ref):
1296 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1297 return xen_api_success(dom.get_memory_static_min())
1299 def VM_get_VIFs(self, session, vm_ref):
1300 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1301 return xen_api_success(dom.get_vifs())
1303 def VM_get_VBDs(self, session, vm_ref):
1304 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1305 return xen_api_success(dom.get_vbds())
1307 def VM_get_VTPMs(self, session, vm_ref):
1308 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1309 return xen_api_success(dom.get_vtpms())
1311 def VM_get_consoles(self, session, vm_ref):
1312 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1313 return xen_api_success(dom.get_consoles())
1315 def VM_get_DPCIs(self, session, vm_ref):
1316 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1317 return xen_api_success(dom.get_dpcis())
1319 def VM_get_DSCSIs(self, session, vm_ref):
1320 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1321 return xen_api_success(dom.get_dscsis())
1323 def VM_get_tools_version(self, session, vm_ref):
1324 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1325 return dom.get_tools_version()
1327 def VM_get_metrics(self, _, vm_ref):
1328 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1329 return xen_api_success(dom.get_metrics())
1331 def VM_get_VCPUs_max(self, _, vm_ref):
1332 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1333 return xen_api_todo()
1335 def VM_get_VCPUs_at_startup(self, _, vm_ref):
1336 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1337 return xen_api_todo()
1339 # attributes (rw)
1340 def VM_get_name_label(self, session, vm_ref):
1341 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1342 return xen_api_success(dom.getName())
1344 def VM_get_name_description(self, session, vm_ref):
1345 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1346 return xen_api_todo()
1348 def VM_get_user_version(self, session, vm_ref):
1349 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1350 return xen_api_todo()
1352 def VM_get_is_a_template(self, session, ref):
1353 return self.VM_get('is_a_template', session, ref)
1355 def VM_get_auto_power_on(self, session, vm_ref):
1356 return self.VM_get('auto_power_on', session, vm_ref)
1358 def VM_get_memory_dynamic_max(self, session, vm_ref):
1359 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1360 return xen_api_success(dom.get_memory_dynamic_max())
1362 def VM_get_memory_dynamic_min(self, session, vm_ref):
1363 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1364 return xen_api_success(dom.get_memory_dynamic_min())
1366 def VM_get_VCPUs_params(self, session, vm_ref):
1367 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1368 return xen_api_success(dom.get_vcpus_params())
1370 def VM_get_actions_after_shutdown(self, session, vm_ref):
1371 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1372 return xen_api_success(dom.get_on_shutdown())
1374 def VM_get_actions_after_reboot(self, session, vm_ref):
1375 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1376 return xen_api_success(dom.get_on_reboot())
1378 def VM_get_actions_after_suspend(self, session, vm_ref):
1379 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1380 return xen_api_success(dom.get_on_suspend())
1382 def VM_get_actions_after_crash(self, session, vm_ref):
1383 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1384 return xen_api_success(dom.get_on_crash())
1386 def VM_get_PV_bootloader(self, session, vm_ref):
1387 return self.VM_get('PV_bootloader', session, vm_ref)
1389 def VM_get_PV_kernel(self, session, vm_ref):
1390 return self.VM_get('PV_kernel', session, vm_ref)
1392 def VM_get_PV_ramdisk(self, session, vm_ref):
1393 return self.VM_get('PV_ramdisk', session, vm_ref)
1395 def VM_get_PV_args(self, session, vm_ref):
1396 return self.VM_get('PV_args', session, vm_ref)
1398 def VM_get_PV_bootloader_args(self, session, vm_ref):
1399 return self.VM_get('PV_bootloader_args', session, vm_ref)
1401 def VM_get_HVM_boot_policy(self, session, vm_ref):
1402 return self.VM_get('HVM_boot_policy', session, vm_ref)
1404 def VM_get_HVM_boot_params(self, session, vm_ref):
1405 return self.VM_get('HVM_boot_params', session, vm_ref)
1407 def VM_get_platform(self, session, vm_ref):
1408 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1409 return xen_api_success(dom.get_platform())
1411 def VM_get_PCI_bus(self, session, vm_ref):
1412 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1413 return dom.get_pci_bus()
1415 def VM_set_PCI_bus(self, session, vm_ref, val):
1416 return self.VM_set('PCI_bus', session, vm_ref, val)
1418 def VM_get_other_config(self, session, vm_ref):
1419 return self.VM_get('other_config', session, vm_ref)
1421 def VM_get_domid(self, _, ref):
1422 domid = XendDomain.instance().get_vm_by_uuid(ref).getDomid()
1423 return xen_api_success(domid is None and -1 or domid)
1425 def VM_get_is_control_domain(self, session, vm_ref):
1426 xd = XendDomain.instance()
1427 return xen_api_success(
1428 xd.get_vm_by_uuid(vm_ref) == xd.privilegedDomain())
1430 def VM_set_name_label(self, session, vm_ref, label):
1431 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1432 dom.setName(label)
1433 return self._VM_save(dom)
1435 def VM_set_name_description(self, session, vm_ref, desc):
1436 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1437 return xen_api_todo()
1439 def VM_set_user_version(self, session, vm_ref, ver):
1440 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1441 return xen_api_todo()
1443 def VM_set_is_a_template(self, session, vm_ref, is_template):
1444 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1445 return xen_api_todo()
1447 def VM_set_auto_power_on(self, session, vm_ref, val):
1448 return self.VM_set('auto_power_on', session, vm_ref, val)
1450 def VM_set_memory_dynamic_max(self, session, vm_ref, mem):
1451 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1452 dom.set_memory_dynamic_max(int(mem))
1453 return self._VM_save(dom)
1455 def VM_set_memory_dynamic_min(self, session, vm_ref, mem):
1456 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1457 dom.set_memory_dynamic_min(int(mem))
1458 return self._VM_save(dom)
1460 def VM_set_memory_static_max(self, session, vm_ref, mem):
1461 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1462 dom.set_memory_static_max(int(mem))
1463 return self._VM_save(dom)
1465 def VM_set_memory_static_min(self, session, vm_ref, mem):
1466 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1467 dom.set_memory_static_min(int(mem))
1468 return self._VM_save(dom)
1470 def VM_set_memory_dynamic_max_live(self, session, vm_ref, mem):
1471 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1472 dom.set_memory_dynamic_max(int(mem))
1473 # need to pass target as MiB
1474 dom.setMemoryTarget(int(mem)/1024/1024)
1475 return xen_api_success_void()
1477 def VM_set_memory_dynamic_min_live(self, session, vm_ref, mem):
1478 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1479 dom.set_memory_dynamic_min(int(mem))
1480 # need to pass target as MiB
1481 dom.setMemoryTarget(int(mem)/1024/1024)
1482 return xen_api_success_void()
1484 def VM_set_VCPUs_params(self, session, vm_ref, value):
1485 return self.VM_set('vcpus_params', session, vm_ref, value)
1487 def VM_add_to_VCPUs_params(self, session, vm_ref, key, value):
1488 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1489 if 'vcpus_params' not in dom.info:
1490 dom.info['vcpus_params'] = {}
1491 dom.info['vcpus_params'][key] = value
1492 return self._VM_save(dom)
1494 def VM_add_to_VCPUs_params_live(self, session, vm_ref, key, value):
1495 self.VM_add_to_VCPUs_params(session, vm_ref, key, value)
1496 self._VM_VCPUs_params_refresh(vm_ref)
1497 return xen_api_success_void()
1499 def _VM_VCPUs_params_refresh(self, vm_ref):
1500 xendom = XendDomain.instance()
1501 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1503 #update the cpumaps
1504 for key, value in xeninfo.info['vcpus_params'].items():
1505 if key.startswith("cpumap"):
1506 vcpu = int(key[6:])
1507 try:
1508 cpus = map(int, value.split(","))
1509 xendom.domain_pincpu(xeninfo.getDomid(), vcpu, cpus)
1510 except Exception, ex:
1511 log.exception(ex)
1513 #need to update sched params aswell
1514 if 'weight' in xeninfo.info['vcpus_params'] \
1515 and 'cap' in xeninfo.info['vcpus_params']:
1516 weight = xeninfo.info['vcpus_params']['weight']
1517 cap = xeninfo.info['vcpus_params']['cap']
1518 xendom.domain_sched_credit_set(xeninfo.getDomid(), weight, cap)
1520 def VM_set_VCPUs_number_live(self, _, vm_ref, num):
1521 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1522 dom.setVCpuCount(int(num))
1523 return xen_api_success_void()
1525 def VM_remove_from_VCPUs_params(self, session, vm_ref, key):
1526 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1527 if 'vcpus_params' in dom.info \
1528 and key in dom.info['vcpus_params']:
1529 del dom.info['vcpus_params'][key]
1530 return self._VM_save(dom)
1531 else:
1532 return xen_api_success_void()
1534 def VM_set_VCPUs_at_startup(self, session, vm_ref, num):
1535 return self.VM_set('VCPUs_at_startup', session, vm_ref, num)
1537 def VM_set_VCPUs_max(self, session, vm_ref, num):
1538 return self.VM_set('VCPUs_max', session, vm_ref, num)
1540 def VM_set_actions_after_shutdown(self, session, vm_ref, action):
1541 if action not in XEN_API_ON_NORMAL_EXIT:
1542 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1543 return self.VM_set('actions_after_shutdown', session, vm_ref, action)
1545 def VM_set_actions_after_reboot(self, session, vm_ref, action):
1546 if action not in XEN_API_ON_NORMAL_EXIT:
1547 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1548 return self.VM_set('actions_after_reboot', session, vm_ref, action)
1550 def VM_set_actions_after_suspend(self, session, vm_ref, action):
1551 if action not in XEN_API_ON_NORMAL_EXIT:
1552 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1553 return self.VM_set('actions_after_suspend', session, vm_ref, action)
1555 def VM_set_actions_after_crash(self, session, vm_ref, action):
1556 if action not in XEN_API_ON_CRASH_BEHAVIOUR:
1557 return xen_api_error(['VM_ON_CRASH_BEHAVIOUR_INVALID', vm_ref])
1558 return self.VM_set('actions_after_crash', session, vm_ref, action)
1560 def VM_set_HVM_boot_policy(self, session, vm_ref, value):
1561 if value != "" and value != "BIOS order":
1562 return xen_api_error(
1563 ['VALUE_NOT_SUPPORTED', 'VM.HVM_boot_policy', value,
1564 'Xend supports only the "BIOS order" boot policy.'])
1565 else:
1566 return self.VM_set('HVM_boot_policy', session, vm_ref, value)
1568 def VM_set_HVM_boot_params(self, session, vm_ref, value):
1569 return self.VM_set('HVM_boot_params', session, vm_ref, value)
1571 def VM_add_to_HVM_boot_params(self, session, vm_ref, key, value):
1572 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1573 if 'HVM_boot_params' not in dom.info:
1574 dom.info['HVM_boot_params'] = {}
1575 dom.info['HVM_boot_params'][key] = value
1576 return self._VM_save(dom)
1578 def VM_remove_from_HVM_boot_params(self, session, vm_ref, key):
1579 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1580 if 'HVM_boot_params' in dom.info \
1581 and key in dom.info['HVM_boot_params']:
1582 del dom.info['HVM_boot_params'][key]
1583 return self._VM_save(dom)
1584 else:
1585 return xen_api_success_void()
1587 def VM_set_PV_bootloader(self, session, vm_ref, value):
1588 return self.VM_set('PV_bootloader', session, vm_ref, value)
1590 def VM_set_PV_kernel(self, session, vm_ref, value):
1591 return self.VM_set('PV_kernel', session, vm_ref, value)
1593 def VM_set_PV_ramdisk(self, session, vm_ref, value):
1594 return self.VM_set('PV_ramdisk', session, vm_ref, value)
1596 def VM_set_PV_args(self, session, vm_ref, value):
1597 return self.VM_set('PV_args', session, vm_ref, value)
1599 def VM_set_PV_bootloader_args(self, session, vm_ref, value):
1600 return self.VM_set('PV_bootloader_args', session, vm_ref, value)
1602 def VM_set_platform(self, session, vm_ref, value):
1603 return self.VM_set('platform', session, vm_ref, value)
1605 def VM_add_to_platform(self, session, vm_ref, key, value):
1606 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1607 plat = dom.get_platform()
1608 plat[key] = value
1609 return self.VM_set_platform(session, vm_ref, plat)
1611 def VM_remove_from_platform(self, session, vm_ref, key):
1612 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1613 plat = dom.get_platform()
1614 if key in plat:
1615 del plat[key]
1616 return self.VM_set_platform(session, vm_ref, plat)
1617 else:
1618 return xen_api_success_void()
1620 def VM_set_other_config(self, session, vm_ref, value):
1621 return self.VM_set('other_config', session, vm_ref, value)
1623 def VM_add_to_other_config(self, session, vm_ref, key, value):
1624 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1625 if dom and 'other_config' in dom.info:
1626 dom.info['other_config'][key] = value
1627 return self._VM_save(dom)
1629 def VM_remove_from_other_config(self, session, vm_ref, key):
1630 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1631 if dom and 'other_config' in dom.info \
1632 and key in dom.info['other_config']:
1633 del dom.info['other_config'][key]
1634 return self._VM_save(dom)
1635 else:
1636 return xen_api_success_void()
1638 def VM_get_crash_dumps(self, _, vm_ref):
1639 return xen_api_todo()
1641 # class methods
1642 def VM_get_all(self, session):
1643 refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
1644 return xen_api_success(refs)
1646 def VM_get_by_name_label(self, session, label):
1647 xendom = XendDomain.instance()
1648 dom = xendom.domain_lookup_nr(label)
1649 if dom:
1650 return xen_api_success([dom.get_uuid()])
1651 return xen_api_success([])
1653 def VM_get_security_label(self, session, vm_ref):
1654 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1655 label = dom.get_security_label()
1656 return xen_api_success(label)
1658 def VM_set_security_label(self, session, vm_ref, sec_label, old_label):
1659 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1660 (rc, errors, oldlabel, new_ssidref) = \
1661 dom.set_security_label(sec_label, old_label)
1662 if rc != xsconstants.XSERR_SUCCESS:
1663 return xen_api_error(['SECURITY_ERROR', rc,
1664 xsconstants.xserr2string(-rc)])
1665 if rc == 0:
1666 rc = new_ssidref
1667 return xen_api_success(rc)
1669 def VM_create(self, session, vm_struct):
1670 xendom = XendDomain.instance()
1671 domuuid = XendTask.log_progress(0, 100,
1672 xendom.create_domain, vm_struct)
1673 return xen_api_success(domuuid)
1675 # object methods
1676 def VM_get_record(self, session, vm_ref):
1677 xendom = XendDomain.instance()
1678 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1679 if not xeninfo:
1680 return xen_api_error(['HANDLE_INVALID', 'VM', vm_ref])
1682 domid = xeninfo.getDomid()
1684 record = {
1685 'uuid': xeninfo.get_uuid(),
1686 'power_state': xeninfo.get_power_state(),
1687 'name_label': xeninfo.getName(),
1688 'name_description': xeninfo.getName(),
1689 'user_version': 1,
1690 'is_a_template': xeninfo.info['is_a_template'],
1691 'auto_power_on': xeninfo.info['auto_power_on'],
1692 'resident_on': XendNode.instance().uuid,
1693 'memory_static_min': xeninfo.get_memory_static_min(),
1694 'memory_static_max': xeninfo.get_memory_static_max(),
1695 'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
1696 'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
1697 'VCPUs_params': xeninfo.get_vcpus_params(),
1698 'VCPUs_at_startup': xeninfo.getVCpuCount(),
1699 'VCPUs_max': xeninfo.getVCpuCount(),
1700 'actions_after_shutdown': xeninfo.get_on_shutdown(),
1701 'actions_after_reboot': xeninfo.get_on_reboot(),
1702 'actions_after_suspend': xeninfo.get_on_suspend(),
1703 'actions_after_crash': xeninfo.get_on_crash(),
1704 'consoles': xeninfo.get_consoles(),
1705 'VIFs': xeninfo.get_vifs(),
1706 'VBDs': xeninfo.get_vbds(),
1707 'VTPMs': xeninfo.get_vtpms(),
1708 'DPCIs': xeninfo.get_dpcis(),
1709 'DSCSIs': xeninfo.get_dscsis(),
1710 'PV_bootloader': xeninfo.info.get('PV_bootloader'),
1711 'PV_kernel': xeninfo.info.get('PV_kernel'),
1712 'PV_ramdisk': xeninfo.info.get('PV_ramdisk'),
1713 'PV_args': xeninfo.info.get('PV_args'),
1714 'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
1715 'HVM_boot_policy': xeninfo.info.get('HVM_boot_policy'),
1716 'HVM_boot_params': xeninfo.info.get('HVM_boot_params'),
1717 'platform': xeninfo.get_platform(),
1718 'PCI_bus': xeninfo.get_pci_bus(),
1719 'tools_version': xeninfo.get_tools_version(),
1720 'other_config': xeninfo.info.get('other_config', {}),
1721 'domid': domid is None and -1 or domid,
1722 'is_control_domain': xeninfo.info['is_control_domain'],
1723 'metrics': xeninfo.get_metrics(),
1724 'security_label': xeninfo.get_security_label(),
1725 'crash_dumps': []
1727 return xen_api_success(record)
1729 def VM_clean_reboot(self, session, vm_ref):
1730 xendom = XendDomain.instance()
1731 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1732 XendTask.log_progress(0, 100, xeninfo.shutdown, "reboot")
1733 return xen_api_success_void()
1735 def VM_clean_shutdown(self, session, vm_ref):
1736 xendom = XendDomain.instance()
1737 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1738 XendTask.log_progress(0, 100, xeninfo.shutdown, "poweroff")
1739 return xen_api_success_void()
1741 def VM_clone(self, session, vm_ref):
1742 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1744 def VM_destroy(self, session, vm_ref):
1745 return XendTask.log_progress(0, 100, do_vm_func,
1746 "domain_delete", vm_ref)
1748 def VM_hard_reboot(self, session, vm_ref):
1749 return XendTask.log_progress(0, 100, do_vm_func,
1750 "domain_reset", vm_ref)
1752 def VM_hard_shutdown(self, session, vm_ref):
1753 return XendTask.log_progress(0, 100, do_vm_func,
1754 "domain_destroy", vm_ref)
1756 def VM_pause(self, session, vm_ref):
1757 return XendTask.log_progress(0, 100, do_vm_func,
1758 "domain_pause", vm_ref)
1760 def VM_resume(self, session, vm_ref, start_paused):
1761 return XendTask.log_progress(0, 100, do_vm_func,
1762 "domain_resume", vm_ref,
1763 start_paused = start_paused)
1765 def VM_start(self, session, vm_ref, start_paused):
1766 try:
1767 return XendTask.log_progress(0, 100, do_vm_func,
1768 "domain_start", vm_ref,
1769 start_paused = start_paused)
1770 except HVMRequired, exn:
1771 return xen_api_error(['VM_HVM_REQUIRED', vm_ref])
1773 def VM_suspend(self, session, vm_ref):
1774 return XendTask.log_progress(0, 100, do_vm_func,
1775 "domain_suspend", vm_ref)
1777 def VM_unpause(self, session, vm_ref):
1778 return XendTask.log_progress(0, 100, do_vm_func,
1779 "domain_unpause", vm_ref)
1781 def VM_send_sysrq(self, _, vm_ref, req):
1782 xeninfo = XendDomain.instance().get_vm_by_uuid(vm_ref)
1783 if xeninfo.state == XEN_API_VM_POWER_STATE_RUNNING \
1784 or xeninfo.state == XEN_API_VM_POWER_STATE_PAUSED:
1785 xeninfo.send_sysrq(req)
1786 return xen_api_success_void()
1787 else:
1788 return xen_api_error(
1789 ['VM_BAD_POWER_STATE', vm_ref,
1790 XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_RUNNING],
1791 XendDomain.POWER_STATE_NAMES[xeninfo.state]])
1793 def VM_send_trigger(self, _, vm_ref, trigger, vcpu):
1794 xendom = XendDomain.instance()
1795 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1796 xendom.domain_send_trigger(xeninfo.getDomid(), trigger, vcpu)
1797 return xen_api_success_void()
1799 def VM_migrate(self, _, vm_ref, destination_url, live, other_config):
1800 xendom = XendDomain.instance()
1801 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1803 port = other_config.get("port", 0)
1804 node = other_config.get("node", -1)
1805 ssl = other_config.get("ssl", None)
1807 xendom.domain_migrate(xeninfo.getDomid(), destination_url,
1808 bool(live), port, node, ssl)
1809 return xen_api_success_void()
1811 def VM_save(self, _, vm_ref, dest, checkpoint):
1812 xendom = XendDomain.instance()
1813 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1814 xendom.domain_save(xeninfo.getDomid(), dest, checkpoint)
1815 return xen_api_success_void()
1817 def VM_restore(self, _, src, paused):
1818 xendom = XendDomain.instance()
1819 xendom.domain_restore(src, bool(paused))
1820 return xen_api_success_void()
1823 # Xen API: Class VBD
1824 # ----------------------------------------------------------------
1826 VBD_attr_ro = ['VM',
1827 'VDI',
1828 'metrics',
1829 'runtime_properties']
1830 VBD_attr_rw = ['device',
1831 'bootable',
1832 'mode',
1833 'type']
1835 VBD_attr_inst = VBD_attr_rw
1837 VBD_methods = [('media_change', None), ('destroy', None)]
1838 VBD_funcs = [('create', 'VBD')]
1840 # object methods
1841 def VBD_get_record(self, session, vbd_ref):
1842 xendom = XendDomain.instance()
1843 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1844 if not vm:
1845 return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
1846 cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
1847 if not cfg:
1848 return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
1850 valid_vbd_keys = self.VBD_attr_ro + self.VBD_attr_rw + \
1851 self.Base_attr_ro + self.Base_attr_rw
1853 return_cfg = {}
1854 for k in cfg.keys():
1855 if k in valid_vbd_keys:
1856 return_cfg[k] = cfg[k]
1858 return_cfg['metrics'] = vbd_ref
1859 return_cfg['runtime_properties'] = {} #todo
1861 return xen_api_success(return_cfg)
1863 def VBD_media_change(self, session, vbd_ref, vdi_ref):
1864 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1866 # class methods
1867 def VBD_create(self, session, vbd_struct):
1868 xendom = XendDomain.instance()
1869 xennode = XendNode.instance()
1871 if not xendom.is_valid_vm(vbd_struct['VM']):
1872 return xen_api_error(['HANDLE_INVALID', 'VM', vbd_struct['VM']])
1874 dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
1875 vdi = xennode.get_vdi_by_uuid(vbd_struct['VDI'])
1876 if not vdi:
1877 return xen_api_error(['HANDLE_INVALID', 'VDI', vbd_struct['VDI']])
1879 # new VBD via VDI/SR
1880 vdi_image = vdi.get_location()
1882 try:
1883 vbd_ref = XendTask.log_progress(0, 100,
1884 dom.create_vbd,
1885 vbd_struct, vdi_image)
1886 except XendError, e:
1887 log.exception("Error in VBD_create")
1888 return xen_api_error(['INTERNAL_ERROR', str(e)])
1890 vdi.addVBD(vbd_ref)
1892 xendom.managed_config_save(dom)
1893 return xen_api_success(vbd_ref)
1896 def VBD_destroy(self, session, vbd_ref):
1897 xendom = XendDomain.instance()
1898 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1899 if not vm:
1900 return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
1902 vdi_ref = XendDomain.instance()\
1903 .get_dev_property_by_uuid('vbd', vbd_ref, "VDI")
1904 vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
1906 XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref)
1908 vdi.removeVBD(vbd_ref)
1910 return xen_api_success_void()
1912 def _VBD_get(self, vbd_ref, prop):
1913 return xen_api_success(
1914 XendDomain.instance().get_dev_property_by_uuid(
1915 'vbd', vbd_ref, prop))
1917 # attributes (ro)
1918 def VBD_get_metrics(self, _, vbd_ref):
1919 return xen_api_success(vbd_ref)
1921 def VBD_get_runtime_properties(self, _, vbd_ref):
1922 xendom = XendDomain.instance()
1923 dominfo = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1924 device = dominfo.get_dev_config_by_uuid('vbd', vbd_ref)
1926 try:
1927 devid = int(device['id'])
1928 device_sxps = dominfo.getDeviceSxprs('vbd')
1929 device_dicts = [dict(device_sxp[1][0:]) for device_sxp in device_sxps]
1930 device_dict = [device_dict
1931 for device_dict in device_dicts
1932 if int(device_dict['virtual-device']) == devid][0]
1934 return xen_api_success(device_dict)
1935 except Exception, exn:
1936 log.exception(exn)
1937 return xen_api_success({})
1939 # attributes (rw)
1940 def VBD_get_VM(self, session, vbd_ref):
1941 return self._VBD_get(vbd_ref, 'VM')
1943 def VBD_get_VDI(self, session, vbd_ref):
1944 return self._VBD_get(vbd_ref, 'VDI')
1946 def VBD_get_device(self, session, vbd_ref):
1947 return self._VBD_get(vbd_ref, 'device')
1949 def VBD_get_bootable(self, session, vbd_ref):
1950 return self._VBD_get(vbd_ref, 'bootable')
1952 def VBD_get_mode(self, session, vbd_ref):
1953 return self._VBD_get(vbd_ref, 'mode')
1955 def VBD_get_type(self, session, vbd_ref):
1956 return self._VBD_get(vbd_ref, 'type')
1958 def VBD_set_bootable(self, session, vbd_ref, bootable):
1959 bootable = bool(bootable)
1960 xd = XendDomain.instance()
1961 vm = xd.get_vm_with_dev_uuid('vbd', vbd_ref)
1962 vm.set_dev_property('vbd', vbd_ref, 'bootable', bootable)
1963 xd.managed_config_save(vm)
1964 return xen_api_success_void()
1966 def VBD_set_mode(self, session, vbd_ref, mode):
1967 if mode == 'RW':
1968 mode = 'w'
1969 else:
1970 mode = 'r'
1971 xd = XendDomain.instance()
1972 vm = xd.get_vm_with_dev_uuid('vbd', vbd_ref)
1973 vm.set_dev_property('vbd', vbd_ref, 'mode', mode)
1974 xd.managed_config_save(vm)
1975 return xen_api_success_void()
1977 def VBD_get_all(self, session):
1978 xendom = XendDomain.instance()
1979 vbds = [d.get_vbds() for d in XendDomain.instance().list('all')]
1980 vbds = reduce(lambda x, y: x + y, vbds)
1981 return xen_api_success(vbds)
1984 # Xen API: Class VBD_metrics
1985 # ----------------------------------------------------------------
1987 VBD_metrics_attr_ro = ['io_read_kbs',
1988 'io_write_kbs',
1989 'last_updated']
1990 VBD_metrics_attr_rw = []
1991 VBD_metrics_methods = []
1993 def VBD_metrics_get_all(self, session):
1994 return self.VBD_get_all(session)
1996 def VBD_metrics_get_record(self, _, ref):
1997 vm = XendDomain.instance().get_vm_with_dev_uuid('vbd', ref)
1998 if not vm:
1999 return xen_api_error(['HANDLE_INVALID', 'VBD_metrics', ref])
2000 return xen_api_success(
2001 { 'io_read_kbs' : vm.get_dev_property('vbd', ref, 'io_read_kbs'),
2002 'io_write_kbs' : vm.get_dev_property('vbd', ref, 'io_write_kbs'),
2003 'last_updated' : now()
2004 })
2006 def VBD_metrics_get_io_read_kbs(self, _, ref):
2007 return self._VBD_get(ref, 'io_read_kbs')
2009 def VBD_metrics_get_io_write_kbs(self, session, ref):
2010 return self._VBD_get(ref, 'io_write_kbs')
2012 def VBD_metrics_get_last_updated(self, _1, _2):
2013 return xen_api_success(now())
2016 # Xen API: Class VIF
2017 # ----------------------------------------------------------------
2019 VIF_attr_ro = ['network',
2020 'VM',
2021 'metrics',
2022 'runtime_properties']
2023 VIF_attr_rw = ['device',
2024 'MAC',
2025 'MTU',
2026 'security_label']
2028 VIF_attr_inst = VIF_attr_rw
2030 VIF_methods = [('destroy', None)]
2031 VIF_funcs = [('create', 'VIF')]
2034 # object methods
2035 def VIF_get_record(self, session, vif_ref):
2036 xendom = XendDomain.instance()
2037 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
2038 if not vm:
2039 return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
2040 cfg = vm.get_dev_xenapi_config('vif', vif_ref)
2041 if not cfg:
2042 return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
2044 valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
2045 self.Base_attr_ro + self.Base_attr_rw
2047 return_cfg = {}
2048 for k in cfg.keys():
2049 if k in valid_vif_keys:
2050 return_cfg[k] = cfg[k]
2052 return_cfg['metrics'] = vif_ref
2054 return xen_api_success(return_cfg)
2056 # class methods
2057 def VIF_create(self, session, vif_struct):
2058 xendom = XendDomain.instance()
2059 if not xendom.is_valid_vm(vif_struct['VM']):
2060 return xen_api_error(['HANDLE_INVALID', 'VM', vif_struct['VM']])
2062 dom = xendom.get_vm_by_uuid(vif_struct['VM'])
2063 try:
2064 vif_ref = dom.create_vif(vif_struct)
2065 xendom.managed_config_save(dom)
2066 return xen_api_success(vif_ref)
2067 except XendError, exn:
2068 return xen_api_error(['INTERNAL_ERROR', str(exn)])
2070 def VIF_destroy(self, session, vif_ref):
2071 xendom = XendDomain.instance()
2072 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
2073 if not vm:
2074 return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
2076 vm.destroy_vif(vif_ref)
2077 return xen_api_success_void()
2079 def _VIF_get(self, ref, prop):
2080 return xen_api_success(
2081 XendDomain.instance().get_dev_property_by_uuid('vif', ref, prop))
2083 # getters/setters
2084 def VIF_get_metrics(self, _, vif_ref):
2085 return xen_api_success(vif_ref)
2087 def VIF_get_VM(self, session, vif_ref):
2088 xendom = XendDomain.instance()
2089 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
2090 return xen_api_success(vm.get_uuid())
2092 def VIF_get_MTU(self, session, vif_ref):
2093 return self._VIF_get(vif_ref, 'MTU')
2095 def VIF_get_MAC(self, session, vif_ref):
2096 return self._VIF_get(vif_ref, 'MAC')
2098 def VIF_get_device(self, session, vif_ref):
2099 return self._VIF_get(vif_ref, 'device')
2101 def VIF_get_all(self, session):
2102 xendom = XendDomain.instance()
2103 vifs = [d.get_vifs() for d in XendDomain.instance().list('all')]
2104 vifs = reduce(lambda x, y: x + y, vifs)
2105 return xen_api_success(vifs)
2107 def VIF_get_runtime_properties(self, _, vif_ref):
2108 xendom = XendDomain.instance()
2109 dominfo = xendom.get_vm_with_dev_uuid('vif', vif_ref)
2110 device = dominfo.get_dev_config_by_uuid('vif', vif_ref)
2112 try:
2113 devid = int(device['id'])
2115 device_sxps = dominfo.getDeviceSxprs('vif')
2116 device_dicts = [dict(device_sxp[1][1:])
2117 for device_sxp in device_sxps]
2119 device_dict = [device_dict
2120 for device_dict in device_dicts
2121 if int(device_dict['handle']) == devid][0]
2123 return xen_api_success(device_dict)
2125 except Exception, exn:
2126 log.exception(exn)
2127 return xen_api_success({})
2129 def VIF_get_security_label(self, session, vif_ref):
2130 return self._VIF_get(vif_ref, 'security_label')
2132 def _VIF_set(self, ref, prop, val, old_val):
2133 return XendDomain.instance().set_dev_property_by_uuid(
2134 'vif', ref, prop, val, old_val)
2136 def VIF_set_security_label(self, session, vif_ref, sec_lab, old_lab):
2137 xendom = XendDomain.instance()
2138 dom = xendom.get_vm_with_dev_uuid('vif', vif_ref)
2139 if not dom:
2140 return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
2142 if dom._stateGet() == XEN_API_VM_POWER_STATE_RUNNING:
2143 raise SecurityError(-xsconstants.XSERR_RESOURCE_IN_USE)
2145 rc = self._VIF_set(vif_ref, 'security_label', sec_lab, old_lab)
2146 if rc == False:
2147 raise SecurityError(-xsconstants.XSERR_BAD_LABEL)
2148 return xen_api_success(xsconstants.XSERR_SUCCESS)
2151 # Xen API: Class VIF_metrics
2152 # ----------------------------------------------------------------
2154 VIF_metrics_attr_ro = ['io_read_kbs',
2155 'io_write_kbs',
2156 'io_total_read_kbs',
2157 'io_total_write_kbs',
2158 'last_updated']
2159 VIF_metrics_attr_rw = []
2160 VIF_metrics_methods = []
2162 def VIF_metrics_get_all(self, session):
2163 return self.VIF_get_all(session)
2165 def VIF_metrics_get_record(self, _, ref):
2166 vm = XendDomain.instance().get_vm_with_dev_uuid('vif', ref)
2167 if not vm:
2168 return xen_api_error(['HANDLE_INVALID', 'VIF_metrics', ref])
2169 return xen_api_success(
2170 { 'io_read_kbs' : vm.get_dev_property('vif', ref, 'io_read_kbs'),
2171 'io_write_kbs' : vm.get_dev_property('vif', ref, 'io_write_kbs'),
2172 'io_total_read_kbs' : vm.get_dev_property('vif', ref, 'io_total_read_kbs'),
2173 'io_total_write_kbs' : vm.get_dev_property('vif', ref, 'io_total_write_kbs'),
2174 'last_updated' : now()
2175 })
2177 def VIF_metrics_get_io_read_kbs(self, _, ref):
2178 return self._VIF_get(ref, 'io_read_kbs')
2180 def VIF_metrics_get_io_write_kbs(self, session, ref):
2181 return self._VIF_get(ref, 'io_write_kbs')
2183 def VIF_metrics_get_io_total_read_kbs(self, _, ref):
2184 return self._VIF_get(ref, 'io_total_read_kbs')
2186 def VIF_metrics_get_io_total_write_kbs(self, session, ref):
2187 return self._VIF_get(ref, 'io_total_write_kbs')
2189 def VIF_metrics_get_last_updated(self, _1, _2):
2190 return xen_api_success(now())
2193 # Xen API: Class VDI
2194 # ----------------------------------------------------------------
2195 VDI_attr_ro = ['SR',
2196 'VBDs',
2197 'physical_utilisation',
2198 'type']
2199 VDI_attr_rw = ['name_label',
2200 'name_description',
2201 'virtual_size',
2202 'sharable',
2203 'read_only',
2204 'other_config',
2205 'security_label']
2206 VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
2208 VDI_methods = [('destroy', None)]
2209 VDI_funcs = [('create', 'VDI'),
2210 ('get_by_name_label', 'Set(VDI)')]
2212 def _get_VDI(self, ref):
2213 return XendNode.instance().get_vdi_by_uuid(ref)
2215 def VDI_get_VBDs(self, session, vdi_ref):
2216 vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
2217 return xen_api_success(vdi.getVBDs())
2219 def VDI_get_physical_utilisation(self, session, vdi_ref):
2220 return xen_api_success(self._get_VDI(vdi_ref).
2221 get_physical_utilisation())
2223 def VDI_get_type(self, session, vdi_ref):
2224 return xen_api_success(self._get_VDI(vdi_ref).type)
2226 def VDI_get_name_label(self, session, vdi_ref):
2227 return xen_api_success(self._get_VDI(vdi_ref).name_label)
2229 def VDI_get_name_description(self, session, vdi_ref):
2230 return xen_api_success(self._get_VDI(vdi_ref).name_description)
2232 def VDI_get_SR(self, session, vdi_ref):
2233 return xen_api_success(self._get_VDI(vdi_ref).sr_uuid)
2235 def VDI_get_virtual_size(self, session, vdi_ref):
2236 return xen_api_success(self._get_VDI(vdi_ref).virtual_size)
2238 def VDI_get_sharable(self, session, vdi_ref):
2239 return xen_api_success(self._get_VDI(vdi_ref).sharable)
2241 def VDI_get_read_only(self, session, vdi_ref):
2242 return xen_api_success(self._get_VDI(vdi_ref).read_only)
2244 def VDI_set_name_label(self, session, vdi_ref, value):
2245 self._get_VDI(vdi_ref).name_label = value
2246 return xen_api_success_void()
2248 def VDI_set_name_description(self, session, vdi_ref, value):
2249 self._get_VDI(vdi_ref).name_description = value
2250 return xen_api_success_void()
2252 def VDI_set_virtual_size(self, session, vdi_ref, value):
2253 return xen_api_error(XEND_ERROR_UNSUPPORTED)
2255 def VDI_set_sharable(self, session, vdi_ref, value):
2256 self._get_VDI(vdi_ref).sharable = bool(value)
2257 return xen_api_success_void()
2259 def VDI_set_read_only(self, session, vdi_ref, value):
2260 self._get_VDI(vdi_ref).read_only = bool(value)
2261 return xen_api_success_void()
2263 def VDI_get_other_config(self, session, vdi_ref):
2264 return xen_api_success(
2265 self._get_VDI(vdi_ref).other_config)
2267 def VDI_set_other_config(self, session, vdi_ref, other_config):
2268 self._get_VDI(vdi_ref).other_config = other_config
2269 return xen_api_success_void()
2271 # Object Methods
2273 def VDI_destroy(self, session, vdi_ref):
2274 sr = XendNode.instance().get_sr_containing_vdi(vdi_ref)
2275 sr.destroy_vdi(vdi_ref)
2276 return xen_api_success_void()
2278 def VDI_get_record(self, session, vdi_ref):
2279 image = XendNode.instance().get_vdi_by_uuid(vdi_ref)
2280 return xen_api_success({
2281 'uuid': vdi_ref,
2282 'name_label': image.name_label,
2283 'name_description': image.name_description,
2284 'SR': image.sr_uuid,
2285 'VBDs': image.getVBDs(),
2286 'virtual_size': image.virtual_size,
2287 'physical_utilisation': image.physical_utilisation,
2288 'type': image.type,
2289 'sharable': image.sharable,
2290 'read_only': image.read_only,
2291 'other_config': image.other_config,
2292 'security_label' : image.get_security_label()
2293 })
2295 # Class Functions
2296 def VDI_create(self, session, vdi_struct):
2297 sr_ref = vdi_struct.get('SR')
2298 xennode = XendNode.instance()
2299 if not xennode.is_valid_sr(sr_ref):
2300 return xen_api_error(['HANDLE_INVALID', 'SR', sr_ref])
2302 vdi_uuid = xennode.srs[sr_ref].create_vdi(vdi_struct)
2303 return xen_api_success(vdi_uuid)
2305 def VDI_get_all(self, session):
2306 xennode = XendNode.instance()
2307 vdis = [sr.get_vdis() for sr in xennode.srs.values()]
2308 return xen_api_success(reduce(lambda x, y: x + y, vdis))
2310 def VDI_get_by_name_label(self, session, name):
2311 xennode = XendNode.instance()
2312 return xen_api_success(xennode.get_vdi_by_name_label(name))
2314 def VDI_set_security_label(self, session, vdi_ref, sec_lab, old_lab):
2315 vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
2316 rc = vdi.set_security_label(sec_lab, old_lab)
2317 if rc < 0:
2318 return xen_api_error(['SECURITY_ERROR', rc,
2319 xsconstants.xserr2string(-rc)])
2320 return xen_api_success(rc)
2322 def VDI_get_security_label(self, session, vdi_ref):
2323 vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
2324 return xen_api_success(vdi.get_security_label())
2326 # Xen API: Class VTPM
2327 # ----------------------------------------------------------------
2329 VTPM_attr_rw = ['other_config']
2330 VTPM_attr_ro = ['VM',
2331 'backend',
2332 'runtime_properties' ]
2334 VTPM_attr_inst = VTPM_attr_rw
2336 VTPM_methods = [('destroy', None)]
2337 VTPM_funcs = [('create', 'VTPM')]
2339 def VTPM_get_other_config(self, session, vtpm_ref):
2340 xendom = XendDomain.instance()
2341 return xen_api_success(xendom.get_dev_property_by_uuid('vtpm',
2342 vtpm_ref,
2343 'other_config'))
2345 def VTPM_set_other_config(self, session, vtpm_ref, other_config):
2346 xendom = XendDomain.instance()
2347 xendom.set_dev_property_by_uuid('vtpm',
2348 vtpm_ref,
2349 'other_config',
2350 other_config)
2351 return xen_api_success_void()
2353 # object methods
2354 def VTPM_get_record(self, session, vtpm_ref):
2355 xendom = XendDomain.instance()
2356 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
2357 if not vm:
2358 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
2359 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
2360 if not cfg:
2361 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
2362 valid_vtpm_keys = self.VTPM_attr_ro + self.VTPM_attr_rw + \
2363 self.Base_attr_ro + self.Base_attr_rw
2364 return_cfg = {}
2365 for k in cfg.keys():
2366 if k in valid_vtpm_keys:
2367 return_cfg[k] = cfg[k]
2369 return xen_api_success(return_cfg)
2371 # Class Functions
2372 def VTPM_get_backend(self, session, vtpm_ref):
2373 xendom = XendDomain.instance()
2374 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
2375 if not vm:
2376 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
2377 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
2378 if not cfg:
2379 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
2380 if not cfg.has_key('backend'):
2381 return xen_api_error(['INTERNAL_ERROR', 'VTPM backend not set'])
2382 return xen_api_success(cfg['backend'])
2384 def VTPM_get_VM(self, session, vtpm_ref):
2385 xendom = XendDomain.instance()
2386 return xen_api_success(xendom.get_dev_property_by_uuid('vtpm',
2387 vtpm_ref, 'VM'))
2389 def VTPM_destroy(self, session, vtpm_ref):
2390 xendom = XendDomain.instance()
2391 dom = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
2392 if dom:
2393 if dom.state != XEN_API_VM_POWER_STATE_HALTED:
2394 vm_ref = dom.get_dev_property('vtpm', vtpm_ref, 'VM')
2395 return xen_api_error(['VM_BAD_POWER_STATE', vm_ref,
2396 XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_HALTED],
2397 XendDomain.POWER_STATE_NAMES[dom.state]])
2398 from xen.xend.server import tpmif
2399 tpmif.destroy_vtpmstate(dom.getName())
2400 return xen_api_success_void()
2401 else:
2402 return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
2404 # class methods
2405 def VTPM_create(self, session, vtpm_struct):
2406 xendom = XendDomain.instance()
2407 if xendom.is_valid_vm(vtpm_struct['VM']):
2408 dom = xendom.get_vm_by_uuid(vtpm_struct['VM'])
2409 try:
2410 vtpm_ref = dom.create_vtpm(vtpm_struct)
2411 xendom.managed_config_save(dom)
2412 return xen_api_success(vtpm_ref)
2413 except XendError, exn:
2414 return xen_api_error(['INTERNAL_ERROR', str(exn)])
2415 else:
2416 return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']])
2418 def VTPM_get_all(self, session):
2419 xendom = XendDomain.instance()
2420 vtpms = [d.get_vtpms() for d in XendDomain.instance().list('all')]
2421 vtpms = reduce(lambda x, y: x + y, vtpms)
2422 return xen_api_success(vtpms)
2424 def VTPM_get_runtime_properties(self, _, vtpm_ref):
2425 xendom = XendDomain.instance()
2426 dominfo = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
2427 device = dominfo.get_dev_config_by_uuid('vtpm', vtpm_ref)
2429 try:
2430 device_sxps = dominfo.getDeviceSxprs('vtpm')
2431 device_dict = dict(device_sxps[0][1])
2432 return xen_api_success(device_dict)
2433 except:
2434 return xen_api_success({})
2436 # Xen API: Class console
2437 # ----------------------------------------------------------------
2440 console_attr_ro = ['location', 'protocol', 'VM']
2441 console_attr_rw = ['other_config']
2442 console_funcs = [('create', 'console')]
2444 def console_get_all(self, session):
2445 xendom = XendDomain.instance()
2446 cons = [d.get_consoles() for d in XendDomain.instance().list('all')]
2447 cons = reduce(lambda x, y: x + y, cons)
2448 return xen_api_success(cons)
2450 def console_get_location(self, session, console_ref):
2451 xendom = XendDomain.instance()
2452 return xen_api_success(xendom.get_dev_property_by_uuid('console',
2453 console_ref,
2454 'location'))
2456 def console_get_protocol(self, session, console_ref):
2457 xendom = XendDomain.instance()
2458 return xen_api_success(xendom.get_dev_property_by_uuid('console',
2459 console_ref,
2460 'protocol'))
2462 def console_get_VM(self, session, console_ref):
2463 xendom = XendDomain.instance()
2464 vm = xendom.get_vm_with_dev_uuid('console', console_ref)
2465 return xen_api_success(vm.get_uuid())
2467 def console_get_other_config(self, session, console_ref):
2468 xendom = XendDomain.instance()
2469 return xen_api_success(xendom.get_dev_property_by_uuid('console',
2470 console_ref,
2471 'other_config'))
2473 # object methods
2474 def console_get_record(self, session, console_ref):
2475 xendom = XendDomain.instance()
2476 vm = xendom.get_vm_with_dev_uuid('console', console_ref)
2477 if not vm:
2478 return xen_api_error(['HANDLE_INVALID', 'console', console_ref])
2479 cfg = vm.get_dev_xenapi_config('console', console_ref)
2480 if not cfg:
2481 return xen_api_error(['HANDLE_INVALID', 'console', console_ref])
2483 valid_console_keys = self.console_attr_ro + self.console_attr_rw + \
2484 self.Base_attr_ro + self.Base_attr_rw
2486 return_cfg = {}
2487 for k in cfg.keys():
2488 if k in valid_console_keys:
2489 return_cfg[k] = cfg[k]
2491 return xen_api_success(return_cfg)
2493 def console_create(self, session, console_struct):
2494 xendom = XendDomain.instance()
2495 if not xendom.is_valid_vm(console_struct['VM']):
2496 return xen_api_error(['HANDLE_INVALID', 'VM',
2497 console_struct['VM']])
2499 dom = xendom.get_vm_by_uuid(console_struct['VM'])
2500 try:
2501 if 'protocol' not in console_struct:
2502 return xen_api_error(['CONSOLE_PROTOCOL_INVALID',
2503 'No protocol specified'])
2505 console_ref = dom.create_console(console_struct)
2506 xendom.managed_config_save(dom)
2507 return xen_api_success(console_ref)
2508 except XendError, exn:
2509 return xen_api_error(['INTERNAL_ERROR', str(exn)])
2511 def console_set_other_config(self, session, console_ref, other_config):
2512 xd = XendDomain.instance()
2513 vm = xd.get_vm_with_dev_uuid('console', console_ref)
2514 vm.set_console_other_config(console_ref, other_config)
2515 xd.managed_config_save(vm)
2516 return xen_api_success_void()
2518 # Xen API: Class SR
2519 # ----------------------------------------------------------------
2520 SR_attr_ro = ['VDIs',
2521 'PBDs',
2522 'virtual_allocation',
2523 'physical_utilisation',
2524 'physical_size',
2525 'type',
2526 'content_type']
2528 SR_attr_rw = ['name_label',
2529 'name_description']
2531 SR_attr_inst = ['physical_size',
2532 'type',
2533 'name_label',
2534 'name_description']
2536 SR_methods = []
2537 SR_funcs = [('get_by_name_label', 'Set(SR)'),
2538 ('get_by_uuid', 'SR')]
2540 # Class Functions
2541 def SR_get_all(self, session):
2542 return xen_api_success(XendNode.instance().get_all_sr_uuid())
2544 def SR_get_by_name_label(self, session, label):
2545 return xen_api_success(XendNode.instance().get_sr_by_name(label))
2547 def SR_get_supported_types(self, _):
2548 return xen_api_success(['local', 'qcow_file'])
2550 # Class Methods
2552 def SR_get_record(self, session, sr_ref):
2553 sr = XendNode.instance().get_sr(sr_ref)
2554 if sr:
2555 return xen_api_success(sr.get_record())
2556 return xen_api_error(['HANDLE_INVALID', 'SR', sr_ref])
2558 # Attribute acceess
2560 def _get_SR_func(self, sr_ref, func):
2561 return xen_api_success(getattr(XendNode.instance().get_sr(sr_ref),
2562 func)())
2564 def _get_SR_attr(self, sr_ref, attr):
2565 return xen_api_success(getattr(XendNode.instance().get_sr(sr_ref),
2566 attr))
2568 def SR_get_VDIs(self, _, ref):
2569 return self._get_SR_func(ref, 'list_images')
2571 def SR_get_PBDs(self, _, ref):
2572 return xen_api_success(XendPBD.get_by_SR(ref))
2574 def SR_get_virtual_allocation(self, _, ref):
2575 return self._get_SR_func(ref, 'virtual_allocation')
2577 def SR_get_physical_utilisation(self, _, ref):
2578 return self._get_SR_func(ref, 'physical_utilisation')
2580 def SR_get_physical_size(self, _, ref):
2581 return self._get_SR_attr(ref, 'physical_size')
2583 def SR_get_type(self, _, ref):
2584 return self._get_SR_attr(ref, 'type')
2586 def SR_get_content_type(self, _, ref):
2587 return self._get_SR_attr(ref, 'content_type')
2589 def SR_get_name_label(self, _, ref):
2590 return self._get_SR_attr(ref, 'name_label')
2592 def SR_get_name_description(self, _, ref):
2593 return self._get_SR_attr(ref, 'name_description')
2595 def SR_set_name_label(self, session, sr_ref, value):
2596 sr = XendNode.instance.get_sr(sr_ref)
2597 if sr:
2598 sr.name_label = value
2599 XendNode.instance().save()
2600 return xen_api_success_void()
2602 def SR_set_name_description(self, session, sr_ref, value):
2603 sr = XendNode.instance.get_sr(sr_ref)
2604 if sr:
2605 sr.name_description = value
2606 XendNode.instance().save()
2607 return xen_api_success_void()
2610 # Xen API: Class event
2611 # ----------------------------------------------------------------
2613 event_attr_ro = []
2614 event_attr_rw = []
2615 event_funcs = [('register', None),
2616 ('unregister', None),
2617 ('next', None)]
2619 def event_register(self, session, reg_classes):
2620 event_register(session, reg_classes)
2621 return xen_api_success_void()
2623 def event_unregister(self, session, unreg_classes):
2624 event_unregister(session, unreg_classes)
2625 return xen_api_success_void()
2627 def event_next(self, session):
2628 return event_next(session)
2630 # Xen API: Class debug
2631 # ----------------------------------------------------------------
2633 debug_methods = [('destroy', None),
2634 ('get_record', 'debug')]
2635 debug_funcs = [('wait', None),
2636 ('return_failure', None)]
2638 def debug_wait(self, session, wait_secs):
2639 import time
2640 prog_units = 100/float(wait_secs)
2641 for i in range(int(wait_secs)):
2642 XendTask.log_progress(prog_units * i, prog_units * (i + 1),
2643 time.sleep, 1)
2644 return xen_api_success_void()
2647 def debug_return_failure(self, session):
2648 return xen_api_error(['DEBUG_FAIL', session])
2650 def debug_create(self, session):
2651 debug_uuid = genuuid.createString()
2652 self._debug[debug_uuid] = None
2653 return xen_api_success(debug_uuid)
2655 def debug_destroy(self, session, debug_ref):
2656 del self._debug[debug_ref]
2657 return xen_api_success_void()
2659 def debug_get_record(self, session, debug_ref):
2660 return xen_api_success({'uuid': debug_ref})
2663 class XendAPIAsyncProxy:
2664 """ A redirector for Async.Class.function calls to XendAPI
2665 but wraps the call for use with the XendTaskManager.
2667 @ivar xenapi: Xen API instance
2668 @ivar method_map: Mapping from XMLRPC method name to callable objects.
2669 """
2671 method_prefix = 'Async.'
2673 def __init__(self, xenapi):
2674 """Initialises the Async Proxy by making a map of all
2675 implemented Xen API methods for use with XendTaskManager.
2677 @param xenapi: XendAPI instance
2678 """
2679 self.xenapi = xenapi
2680 self.method_map = {}
2681 for method_name in dir(self.xenapi):
2682 method = getattr(self.xenapi, method_name)
2683 if method_name[0] != '_' and hasattr(method, 'async') \
2684 and method.async == True:
2685 self.method_map[method.api] = method
2687 def _dispatch(self, method, args):
2688 """Overridden method so that SimpleXMLRPCServer will
2689 resolve methods through this method rather than through
2690 inspection.
2692 @param method: marshalled method name from XMLRPC.
2693 @param args: marshalled arguments from XMLRPC.
2694 """
2696 # Only deal with method names that start with "Async."
2697 if not method.startswith(self.method_prefix):
2698 return xen_api_error(['MESSAGE_METHOD_UNKNOWN', method])
2700 # Lookup synchronous version of the method
2701 synchronous_method_name = method[len(self.method_prefix):]
2702 if synchronous_method_name not in self.method_map:
2703 return xen_api_error(['MESSAGE_METHOD_UNKNOWN', method])
2705 method = self.method_map[synchronous_method_name]
2707 # Check that we've got enough arguments before issuing a task ID.
2708 needed = argcounts[method.api]
2709 if len(args) != needed:
2710 return xen_api_error(['MESSAGE_PARAMETER_COUNT_MISMATCH',
2711 self.method_prefix + method.api, needed,
2712 len(args)])
2714 # Validate the session before proceeding
2715 session = args[0]
2716 if not auth_manager().is_session_valid(session):
2717 return xen_api_error(['SESSION_INVALID', session])
2719 # create and execute the task, and return task_uuid
2720 return_type = getattr(method, 'return_type', None)
2721 task_uuid = XendTaskManager.create_task(method, args,
2722 synchronous_method_name,
2723 return_type,
2724 synchronous_method_name,
2725 session)
2726 return xen_api_success(task_uuid)