direct-io.hg

view tools/python/xen/xend/XendAPI.py @ 13683:a7fc9cc9a51f

Fix the handling of MESSAGE_METHOD_UNKNOWN, MESSAGE_PARAMETER_COUNT_MISMATCH,
through the AsyncProxy.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Sun Jan 28 18:37:42 2007 +0000 (2007-01-28)
parents 58344c358aa0
children c2f1bb01bca3
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 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_cpu(func):
162 """Decorator to verify if host_cpu_ref is valid before calling method.
164 @param func: function with params: (self, session, host_cpu_ref, ...)
165 @rtype: callable object
166 """
167 return lambda *args, **kwargs: \
168 _check_ref(XendNode.instance().is_valid_cpu,
169 'HOST_CPU_HANDLE_INVALID', func, *args, **kwargs)
171 def valid_vm(func):
172 """Decorator to verify if vm_ref is valid before calling method.
174 @param func: function with params: (self, session, vm_ref, ...)
175 @rtype: callable object
176 """
177 return lambda *args, **kwargs: \
178 _check_ref(XendDomain.instance().is_valid_vm,
179 'VM_HANDLE_INVALID', func, *args, **kwargs)
181 def valid_network(func):
182 """Decorator to verify if network_ref is valid before calling method.
184 @param func: function with params: (self, session, network_ref, ...)
185 @rtype: callable object
186 """
187 return lambda *args, **kwargs: \
188 _check_ref(XendNode.instance().is_valid_network,
189 'NETWORK_HANDLE_INVALID', func, *args, **kwargs)
191 def valid_vbd(func):
192 """Decorator to verify if vbd_ref is valid before calling method.
194 @param func: function with params: (self, session, vbd_ref, ...)
195 @rtype: callable object
196 """
197 return lambda *args, **kwargs: \
198 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vbd', r),
199 'VBD_HANDLE_INVALID', func, *args, **kwargs)
201 def valid_vif(func):
202 """Decorator to verify if vif_ref is valid before calling method.
204 @param func: function with params: (self, session, vif_ref, ...)
205 @rtype: callable object
206 """
207 return lambda *args, **kwargs: \
208 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vif', r),
209 'VIF_HANDLE_INVALID', func, *args, **kwargs)
211 def valid_vdi(func):
212 """Decorator to verify if vdi_ref is valid before calling method.
214 @param func: function with params: (self, session, vdi_ref, ...)
215 @rtype: callable object
216 """
217 return lambda *args, **kwargs: \
218 _check_ref(XendNode.instance().is_valid_vdi,
219 'VDI_HANDLE_INVALID', func, *args, **kwargs)
221 def valid_vtpm(func):
222 """Decorator to verify if vtpm_ref is valid before calling method.
224 @param func: function with params: (self, session, vtpm_ref, ...)
225 @rtype: callable object
226 """
227 return lambda *args, **kwargs: \
228 _check_ref(lambda r: XendDomain.instance().is_valid_dev('vtpm', r),
229 'VTPM_HANDLE_INVALID', func, *args, **kwargs)
232 def valid_console(func):
233 """Decorator to verify if console_ref is valid before calling method.
235 @param func: function with params: (self, session, console_ref, ...)
236 @rtype: callable object
237 """
238 return lambda *args, **kwargs: \
239 _check_ref(lambda r: XendDomain.instance().is_valid_dev('console',
240 r),
241 'CONSOLE_HANDLE_INVALID', func, *args, **kwargs)
243 def valid_sr(func):
244 """Decorator to verify if sr_ref is valid before calling method.
246 @param func: function with params: (self, session, sr_ref, ...)
247 @rtype: callable object
248 """
249 return lambda *args, **kwargs: \
250 _check_ref(lambda r: XendNode.instance().is_valid_sr,
251 'SR_HANDLE_INVALID', func, *args, **kwargs)
253 def valid_pif(func):
254 """Decorator to verify if pif_ref is valid before calling
255 method.
257 @param func: function with params: (self, session, pif_ref)
258 @rtype: callable object
259 """
260 return lambda *args, **kwargs: \
261 _check_ref(lambda r: r in XendNode.instance().pifs,
262 'PIF_HANDLE_INVALID', func, *args, **kwargs)
264 def valid_task(func):
265 """Decorator to verify if task_ref is valid before calling
266 method.
268 @param func: function with params: (self, session, task_ref)
269 @rtype: callable object
270 """
271 return lambda *args, **kwargs: \
272 _check_ref(XendTaskManager.get_task,
273 'TASK_HANDLE_INVALID', func, *args, **kwargs)
275 def valid_debug(func):
276 """Decorator to verify if task_ref is valid before calling
277 method.
279 @param func: function with params: (self, session, task_ref)
280 @rtype: callable object
281 """
282 return lambda *args, **kwargs: \
283 _check_ref(lambda r: r in XendAPI._debug,
284 'TASK_HANDLE_INVALID', func, *args, **kwargs)
286 # -----------------------------
287 # Bridge to Legacy XM API calls
288 # -----------------------------
290 def do_vm_func(fn_name, vm_ref, *args, **kwargs):
291 """Helper wrapper func to abstract away from repetitive code.
293 @param fn_name: function name for XendDomain instance
294 @type fn_name: string
295 @param vm_ref: vm_ref
296 @type vm_ref: string
297 @param *args: more arguments
298 @type *args: tuple
299 """
300 try:
301 xendom = XendDomain.instance()
302 fn = getattr(xendom, fn_name)
303 xendom.do_legacy_api_with_uuid(fn, vm_ref, *args, **kwargs)
304 return xen_api_success_void()
305 except VMBadState, exn:
306 return xen_api_error(['VM_BAD_POWER_STATE', vm_ref, exn.expected,
307 exn.actual])
310 class XendAPI(object):
311 """Implementation of the Xen-API in Xend. Expects to be
312 used via XMLRPCServer.
314 All methods that need a valid session are marked with
315 a L{session_required} decorator that will
316 transparently perform the required session authentication.
318 We need to support Python <2.4, so we use the old decorator syntax.
320 All XMLRPC accessible methods require an 'api' attribute and
321 is set to the XMLRPC function name which the method implements.
322 """
324 __decorated__ = False
325 __init_lock__ = threading.Lock()
326 _debug = {}
328 def __new__(cls, *args, **kwds):
329 """ Override __new__ to decorate the class only once.
331 Lock to make sure the classes are not decorated twice.
332 """
333 cls.__init_lock__.acquire()
334 try:
335 if not cls.__decorated__:
336 cls._decorate()
337 cls.__decorated__ = True
339 return object.__new__(cls, *args, **kwds)
340 finally:
341 cls.__init_lock__.release()
343 def _decorate(cls):
344 """ Decorate all the object methods to have validators
345 and appropriate function attributes.
347 This should only be executed once for the duration of the
348 server.
349 """
350 global_validators = [session_required, catch_typeerror]
351 classes = {
352 'session' : None,
353 'host' : valid_host,
354 'host_cpu': valid_host_cpu,
355 'network' : valid_network,
356 'VM' : valid_vm,
357 'VBD' : valid_vbd,
358 'VIF' : valid_vif,
359 'VDI' : valid_vdi,
360 'VTPM' : valid_vtpm,
361 'console' : valid_console,
362 'SR' : valid_sr,
363 'PIF' : valid_pif,
364 'task' : valid_task,
365 'debug' : valid_debug,
366 }
368 # Cheat methods
369 # -------------
370 # Methods that have a trivial implementation for all classes.
371 # 1. get_by_uuid == getting by ref, so just return uuid for
372 # all get_by_uuid() methods.
374 for api_cls in classes.keys():
375 get_by_uuid = '%s_get_by_uuid' % api_cls
376 get_uuid = '%s_get_uuid' % api_cls
377 def _get_by_uuid(_1, _2, ref):
378 return xen_api_success(ref)
380 def _get_uuid(_1, _2, ref):
381 return xen_api_success(ref)
383 setattr(cls, get_by_uuid, _get_by_uuid)
384 setattr(cls, get_uuid, _get_uuid)
386 # Wrapping validators around XMLRPC calls
387 # ---------------------------------------
389 for api_cls, validator in classes.items():
390 def doit(n, takes_instance, async_support = False,
391 return_type = None):
392 n_ = n.replace('.', '_')
393 try:
394 f = getattr(cls, n_)
395 argcounts[n] = f.func_code.co_argcount - 1
397 validators = takes_instance and validator and \
398 [validator] or []
400 validators += global_validators
401 for v in validators:
402 f = v(f)
403 f.api = n
404 f.async = async_support
405 if return_type:
406 f.return_type = return_type
408 setattr(cls, n_, f)
409 except AttributeError:
410 log.warn("API call: %s not found" % n)
413 ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
414 rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
415 methods = getattr(cls, '%s_methods' % api_cls, [])
416 funcs = getattr(cls, '%s_funcs' % api_cls, [])
418 # wrap validators around readable class attributes
419 for attr_name in ro_attrs + rw_attrs + cls.Base_attr_ro:
420 doit('%s.get_%s' % (api_cls, attr_name), True,
421 async_support = False)
423 # wrap validators around writable class attrributes
424 for attr_name in rw_attrs + cls.Base_attr_rw:
425 doit('%s.set_%s' % (api_cls, attr_name), True,
426 async_support = False)
428 # wrap validators around methods
429 for method_name, return_type in methods + cls.Base_methods:
430 doit('%s.%s' % (api_cls, method_name), True,
431 async_support = True)
433 # wrap validators around class functions
434 for func_name, return_type in funcs + cls.Base_funcs:
435 doit('%s.%s' % (api_cls, func_name), False, async_support = True,
436 return_type = return_type)
438 _decorate = classmethod(_decorate)
440 def __init__(self, auth):
441 self.auth = auth
443 Base_attr_ro = ['uuid']
444 Base_attr_rw = []
445 Base_methods = [('destroy', None), ('get_record', 'Struct')]
446 Base_funcs = [('get_all', 'Set'), ('get_by_uuid', None)]
448 # Xen API: Class Session
449 # ----------------------------------------------------------------
450 # NOTE: Left unwrapped by __init__
452 session_attr_ro = ['this_host', 'this_user']
453 session_methods = [('logout', None)]
455 def session_login_with_password(self, *args):
456 if len(args) != 2:
457 return xen_api_error(
458 ['MESSAGE_PARAMETER_COUNT_MISMATCH',
459 'session.login_with_password', 2, len(args)])
460 username = args[0]
461 password = args[1]
462 try:
463 session = (self.auth == AUTH_NONE and
464 auth_manager().login_unconditionally(username) or
465 auth_manager().login_with_password(username, password))
466 return xen_api_success(session)
467 except XendError, e:
468 return xen_api_error(['SESSION_AUTHENTICATION_FAILED'])
469 session_login_with_password.api = 'session.login_with_password'
471 # object methods
472 def session_logout(self, session):
473 auth_manager().logout(session)
474 return xen_api_success_void()
475 def session_get_record(self, session):
476 record = {'this_host': XendNode.instance().uuid,
477 'this_user': auth_manager().get_user(session)}
478 return xen_api_success(record)
479 def session_get_all(self):
480 return xen_api_error(XEND_ERROR_UNSUPPORTED)
482 # attributes (ro)
483 def session_get_this_host(self, session):
484 return xen_api_success(XendNode.instance().uuid)
485 def session_get_this_user(self, session):
486 user = auth_manager().get_user(session)
487 if user:
488 return xen_api_success(user)
489 return xen_api_error(['SESSION_INVALID', session])
492 # Xen API: Class User
493 # ----------------------------------------------------------------
494 # TODO: NOT IMPLEMENTED YET
496 # Xen API: Class Tasks
497 # ----------------------------------------------------------------
499 task_attr_ro = ['name_label',
500 'name_description',
501 'status',
502 'progress',
503 'type',
504 'result',
505 'error_code',
506 'error_info',
507 'allowed_operations',
508 ]
510 task_attr_rw = []
512 task_funcs = [('get_by_name_label', 'Set(task)'),
513 ('cancel', None)]
515 def task_get_name_label(self, session, task_ref):
516 task = XendTaskManager.get_task(task_ref)
517 return xen_api_success(task.name_label)
519 def task_get_name_description(self, session, task_ref):
520 task = XendTaskManager.get_task(task_ref)
521 return xen_api_success(task.name_description)
523 def task_get_status(self, session, task_ref):
524 task = XendTaskManager.get_task(task_ref)
525 return xen_api_success(task.get_status())
527 def task_get_progress(self, session, task_ref):
528 task = XendTaskManager.get_task(task_ref)
529 return xen_api_success(task.progress)
531 def task_get_type(self, session, task_ref):
532 task = XendTaskManager.get_task(task_ref)
533 return xen_api_success(task.type)
535 def task_get_result(self, session, task_ref):
536 task = XendTaskManager.get_task(task_ref)
537 return xen_api_success(task.result)
539 def task_get_error_code(self, session, task_ref):
540 task = XendTaskManager.get_task(task_ref)
541 return xen_api_success(task.error_code)
543 def task_get_error_info(self, session, task_ref):
544 task = XendTaskManager.get_task(task_ref)
545 return xen_api_success(task.error_info)
547 def task_get_allowed_operations(self, session, task_ref):
548 return xen_api_success({})
550 def task_get_all(self, session):
551 tasks = XendTaskManager.get_all_tasks()
552 return xen_api_success(tasks)
554 def task_get_record(self, session, task_ref):
555 task = XendTaskManager.get_task(task_ref)
556 return xen_api_success(task.get_record())
558 def task_cancel(self, session, task_ref):
559 return xen_api_error('OPERATION_NOT_ALLOWED')
561 def task_get_by_name_label(self, session, name):
562 return xen_api_success(XendTaskManager.get_task_by_name(name))
564 # Xen API: Class Host
565 # ----------------------------------------------------------------
567 host_attr_ro = ['software_version',
568 'resident_VMs',
569 'host_CPUs']
571 host_attr_rw = ['name_label',
572 'name_description']
574 host_methods = [('disable', None),
575 ('enable', None),
576 ('reboot', None),
577 ('shutdown', None)]
579 host_funcs = [('get_by_name_label', 'Set(host)')]
581 # attributes
582 def host_get_name_label(self, session, host_ref):
583 return xen_api_success(XendNode.instance().name)
584 def host_set_name_label(self, session, host_ref, new_name):
585 XendNode.instance().set_name(new_name)
586 return xen_api_success_void()
587 def host_get_name_description(self, session, host_ref):
588 return xen_api_success(XendNode.instance().description)
589 def host_set_name_description(self, session, host_ref, new_desc):
590 XendNode.instance().set_description(new_desc)
591 return xen_api_success_void()
592 def host_get_software_version(self, session, host_ref):
593 return xen_api_success(XendNode.instance().xen_version())
594 def host_get_resident_VMs(self, session, host_ref):
595 return xen_api_success(XendDomain.instance().get_domain_refs())
596 def host_get_host_CPUs(self, session, host_ref):
597 return xen_api_success(XendNode.instance().get_host_cpu_refs())
599 # object methods
600 def host_destroy(self, session, host_ref):
601 return xen_api_error(XEND_ERROR_UNSUPPORTED)
602 def host_disable(self, session, host_ref):
603 XendDomain.instance().set_allow_new_domains(False)
604 return xen_api_success_void()
605 def host_enable(self, session, host_ref):
606 XendDomain.instance().set_allow_new_domains(True)
607 return xen_api_success_void()
608 def host_reboot(self, session, host_ref):
609 if not XendDomain.instance().allow_new_domains():
610 return xen_api_error(XEND_ERROR_HOST_RUNNING)
611 return xen_api_error(XEND_ERROR_UNSUPPORTED)
612 def host_shutdown(self, session, host_ref):
613 if not XendDomain.instance().allow_new_domains():
614 return xen_api_error(XEND_ERROR_HOST_RUNNING)
615 return xen_api_error(XEND_ERROR_UNSUPPORTED)
616 def host_get_record(self, session, host_ref):
617 node = XendNode.instance()
618 dom = XendDomain.instance()
619 record = {'uuid': node.uuid,
620 'name_label': node.name,
621 'name_description': '',
622 'software_version': node.xen_version(),
623 'resident_VMs': dom.get_domain_refs(),
624 'host_CPUs': node.get_host_cpu_refs()}
625 return xen_api_success(record)
627 # class methods
628 def host_get_all(self, session):
629 return xen_api_success((XendNode.instance().uuid,))
630 def host_create(self, session, struct):
631 return xen_api_error(XEND_ERROR_UNSUPPORTED)
632 def host_get_by_name_label(self, session, name):
633 if XendNode.instance().name == name:
634 return xen_api_success((XendNode.instance().uuid,))
635 return xen_api_success([])
638 # Xen API: Class Host_CPU
639 # ----------------------------------------------------------------
641 host_cpu_attr_ro = ['host',
642 'number',
643 'features',
644 'utilisation']
646 # attributes
647 def host_cpu_get_host(self, session, host_cpu_ref):
648 return xen_api_success(XendNode.instance().uuid)
649 def host_cpu_get_features(self, session, host_cpu_ref):
650 features = XendNode.instance().get_host_cpu_features(host_cpu_ref)
651 return xen_api_success(features)
652 def host_cpu_get_utilisation(self, session, host_cpu_ref):
653 util = XendNode.instance().get_host_cpu_load(host_cpu_ref)
654 return xen_api_success(util)
655 def host_cpu_get_number(self, session, host_cpu_ref):
656 num = XendNode.instance().get_host_cpu_number(host_cpu_ref)
657 return xen_api_success(num)
659 # object methods
660 def host_cpu_destroy(self, session, host_cpu_ref):
661 return xen_api_error(XEND_ERROR_UNSUPPORTED)
662 def host_cpu_get_record(self, session, host_cpu_ref):
663 node = XendNode.instance()
664 record = {'uuid': host_cpu_ref,
665 'host': node.uuid,
666 'number': node.get_host_cpu_number(host_cpu_ref),
667 'features': node.get_host_cpu_features(host_cpu_ref),
668 'utilisation': node.get_host_cpu_load(host_cpu_ref)}
669 return xen_api_success(record)
671 # class methods
672 def host_cpu_get_all(self, session):
673 return xen_api_success(XendNode.instance().get_host_cpu_refs())
676 # Xen API: Class network
677 # ----------------------------------------------------------------
679 network_attr_ro = ['VIFs', 'PIFs']
680 network_attr_rw = ['name_label',
681 'name_description',
682 'default_gateway',
683 'default_netmask']
685 network_funcs = [('create', 'network')]
687 def network_create(self, _, name_label, name_description,
688 default_gateway, default_netmask):
689 return xen_api_success(
690 XendNode.instance().network_create(name_label, name_description,
691 default_gateway,
692 default_netmask))
694 def network_destroy(self, _, ref):
695 return xen_api_success(XendNode.instance().network_destroy(ref))
697 def _get_network(self, ref):
698 return XendNode.instance().get_network(ref)
700 def network_get_all(self, _):
701 return xen_api_success(XendNode.instance().get_network_refs())
703 def network_get_record(self, _, ref):
704 return xen_api_success(
705 XendNode.instance().get_network(ref).get_record())
707 def network_get_name_label(self, _, ref):
708 return xen_api_success(self._get_network(ref).name_label)
710 def network_get_name_description(self, _, ref):
711 return xen_api_success(self._get_network(ref).name_description)
713 def network_get_default_gateway(self, _, ref):
714 return xen_api_success(self._get_network(ref).default_gateway)
716 def network_get_default_netmask(self, _, ref):
717 return xen_api_success(self._get_network(ref).default_netmask)
719 def network_get_VIFs(self, _, ref):
720 return xen_api_success(self._get_network(ref).get_VIF_UUIDs())
722 def network_get_PIFs(self, session, ref):
723 return xen_api_success(self._get_network(ref).get_PIF_UUIDs())
725 def network_set_name_label(self, _, ref, val):
726 return xen_api_success(self._get_network(ref).set_name_label(val))
728 def network_set_name_description(self, _, ref, val):
729 return xen_api_success(self._get_network(ref).set_name_description(val))
731 def network_set_default_gateway(self, _, ref, val):
732 return xen_api_success(self._get_network(ref).set_default_gateway(val))
734 def network_set_default_netmask(self, _, ref, val):
735 return xen_api_success(self._get_network(ref).set_default_netmask(val))
738 # Xen API: Class PIF
739 # ----------------------------------------------------------------
741 PIF_attr_ro = ['io_read_kbs',
742 'io_write_kbs']
743 PIF_attr_rw = ['device',
744 'network',
745 'host',
746 'MAC',
747 'MTU',
748 'VLAN']
750 PIF_attr_inst = PIF_attr_rw
752 PIF_methods = [('create_VLAN', 'int')]
754 def _get_PIF(self, ref):
755 return XendNode.instance().pifs[ref]
757 def PIF_destroy(self, _, ref):
758 try:
759 return xen_api_success(XendNode.instance().PIF_destroy(ref))
760 except PIFIsPhysical, exn:
761 return xen_api_error(['PIF_IS_PHYSICAL', ref])
763 # object methods
764 def PIF_get_record(self, _, ref):
765 return xen_api_success(self._get_PIF(ref).get_record())
767 def PIF_get_all(self, _):
768 return xen_api_success(XendNode.instance().pifs.keys())
770 def PIF_get_device(self, _, ref):
771 return xen_api_success(self._get_PIF(ref).device)
773 def PIF_get_network(self, _, ref):
774 return xen_api_success(self._get_PIF(ref).network.uuid)
776 def PIF_get_host(self, _, ref):
777 return xen_api_success(self._get_PIF(ref).host.uuid)
779 def PIF_get_MAC(self, _, ref):
780 return xen_api_success(self._get_PIF(ref).mac)
782 def PIF_get_MTU(self, _, ref):
783 return xen_api_success(self._get_PIF(ref).mtu)
785 def PIF_get_VLAN(self, _, ref):
786 return xen_api_success(self._get_PIF(ref).vlan)
788 def PIF_get_io_read_kbs(self, _, ref):
789 return xen_api_success(self._get_PIF(ref).get_io_read_kbs())
791 def PIF_get_io_write_kbs(self, _, ref):
792 return xen_api_success(self._get_PIF(ref).get_io_write_kbs())
794 def PIF_set_device(self, _, ref, device):
795 return xen_api_success(self._get_PIF(ref).set_device(device))
797 def PIF_set_MAC(self, _, ref, mac):
798 return xen_api_success(self._get_PIF(ref).set_mac(mac))
800 def PIF_set_MTU(self, _, ref, mtu):
801 return xen_api_success(self._get_PIF(ref).set_mtu(mtu))
803 def PIF_create_VLAN(self, _, ref, network, vlan):
804 try:
805 vlan = int(vlan)
806 except:
807 return xen_api_error(['VLAN_TAG_INVALID', vlan])
809 try:
810 node = XendNode.instance()
812 if _is_valid_ref(network, node.is_valid_network):
813 return xen_api_success(
814 node.PIF_create_VLAN(ref, network, vlan))
815 else:
816 return xen_api_error(['NETWORK_HANDLE_INVALID', network])
817 except NetworkAlreadyConnected, exn:
818 return xen_api_error(['NETWORK_ALREADY_CONNECTED',
819 network, exn.pif_uuid])
820 except VLANTagInvalid:
821 return xen_api_error(['VLAN_TAG_INVALID', vlan])
824 # Xen API: Class VM
825 # ----------------------------------------------------------------
827 VM_attr_ro = ['power_state',
828 'resident_on',
829 'memory_actual',
830 'memory_static_max',
831 'memory_static_min',
832 'VCPUs_number',
833 'VCPUs_utilisation',
834 'VCPUs_features_required',
835 'VCPUs_can_use',
836 'consoles',
837 'VIFs',
838 'VBDs',
839 'VTPMs',
840 'PCI_bus',
841 'tools_version',
842 ]
844 VM_attr_rw = ['name_label',
845 'name_description',
846 'user_version',
847 'is_a_template',
848 'auto_power_on',
849 'memory_dynamic_max',
850 'memory_dynamic_min',
851 'VCPUs_policy',
852 'VCPUs_params',
853 'VCPUs_features_force_on',
854 'VCPUs_features_force_off',
855 'actions_after_shutdown',
856 'actions_after_reboot',
857 'actions_after_suspend',
858 'actions_after_crash',
859 'PV_bootloader',
860 'PV_kernel',
861 'PV_ramdisk',
862 'PV_args',
863 'PV_bootloader_args',
864 'HVM_boot',
865 'platform_std_VGA',
866 'platform_serial',
867 'platform_localtime',
868 'platform_clock_offset',
869 'platform_enable_audio',
870 'platform_keymap',
871 'otherConfig']
873 VM_methods = [('clone', 'VM'),
874 ('start', None),
875 ('pause', None),
876 ('unpause', None),
877 ('clean_shutdown', None),
878 ('clean_reboot', None),
879 ('hard_shutdown', None),
880 ('hard_reboot', None),
881 ('suspend', None),
882 ('resume', None),
883 ('add_to_otherConfig', None),
884 ('remove_from_otherConfig', None)]
886 VM_funcs = [('create', 'VM'),
887 ('get_by_name_label', 'Set(VM)')]
889 # parameters required for _create()
890 VM_attr_inst = [
891 'name_label',
892 'name_description',
893 'user_version',
894 'is_a_template',
895 'memory_static_max',
896 'memory_dynamic_max',
897 'memory_dynamic_min',
898 'memory_static_min',
899 'VCPUs_policy',
900 'VCPUs_params',
901 'VCPUs_features_required',
902 'VCPUs_features_can_use',
903 'VCPUs_features_force_on',
904 'VCPUs_features_force_off',
905 'actions_after_shutdown',
906 'actions_after_reboot',
907 'actions_after_suspend',
908 'actions_after_crash',
909 'PV_bootloader',
910 'PV_kernel',
911 'PV_ramdisk',
912 'PV_args',
913 'PV_bootloader_args',
914 'HVM_boot',
915 'platform_std_VGA',
916 'platform_serial',
917 'platform_localtime',
918 'platform_clock_offset',
919 'platform_enable_audio',
920 'platform_keymap',
921 'grub_cmdline',
922 'PCI_bus',
923 'otherConfig']
925 def VM_get(self, name, session, vm_ref):
926 return xen_api_success(
927 XendDomain.instance().get_vm_by_uuid(vm_ref).info[name])
929 def VM_set(self, name, session, vm_ref, value):
930 xd = XendDomain.instance()
931 dominfo = xd.get_vm_by_uuid(vm_ref)
932 dominfo.info[name] = value
933 xd.managed_config_save(dominfo)
934 return xen_api_success_void()
936 # attributes (ro)
937 def VM_get_power_state(self, session, vm_ref):
938 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
939 return xen_api_success(dom.get_power_state())
941 def VM_get_resident_on(self, session, vm_ref):
942 return xen_api_success(XendNode.instance().uuid)
944 def VM_get_memory_actual(self, session, vm_ref):
945 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
946 return xen_api_todo() # unsupported by xc
948 def VM_get_memory_static_max(self, session, vm_ref):
949 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
950 return xen_api_success(dom.get_memory_static_max())
952 def VM_get_memory_static_min(self, session, vm_ref):
953 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
954 return xen_api_success(dom.get_memory_static_min())
956 def VM_get_VCPUs_number(self, session, vm_ref):
957 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
958 return xen_api_success(dom.getVCpuCount())
960 def VM_get_VCPUs_utilisation(self, session, vm_ref):
961 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
962 return xen_api_success(dom.get_vcpus_util())
964 def VM_get_VCPUs_features_required(self, session, vm_ref):
965 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
966 return xen_api_todo() # unsupported by xc
968 def VM_get_VCPUs_can_use(self, session, vm_ref):
969 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
970 return xen_api_todo() # unsupported by xc
972 def VM_get_VIFs(self, session, vm_ref):
973 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
974 return xen_api_success(dom.get_vifs())
976 def VM_get_VBDs(self, session, vm_ref):
977 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
978 return xen_api_success(dom.get_vbds())
980 def VM_get_VTPMs(self, session, vm_ref):
981 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
982 return xen_api_success(dom.get_vtpms())
984 def VM_get_consoles(self, session, vm_ref):
985 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
986 return xen_api_success(dom.get_consoles())
988 def VM_get_PCI_bus(self, session, vm_ref):
989 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
990 return dom.get_pci_bus()
992 def VM_get_tools_version(self, session, vm_ref):
993 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
994 return dom.get_tools_version()
996 # attributes (rw)
997 def VM_get_name_label(self, session, vm_ref):
998 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
999 return xen_api_success(dom.getName())
1001 def VM_get_name_description(self, session, vm_ref):
1002 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1003 return xen_api_todo()
1005 def VM_get_user_version(self, session, vm_ref):
1006 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1007 return xen_api_todo()
1009 def VM_get_is_a_template(self, session, vm_ref):
1010 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1011 return xen_api_todo()
1013 def VM_get_memory_dynamic_max(self, session, vm_ref):
1014 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1015 return xen_api_success(dom.get_memory_dynamic_max())
1017 def VM_get_memory_dynamic_min(self, session, vm_ref):
1018 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1019 return xen_api_success(dom.get_memory_dynamic_min())
1021 def VM_get_VCPUs_policy(self, session, vm_ref):
1022 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1023 return dom.get_vcpus_policy()
1025 def VM_get_VCPUs_params(self, session, vm_ref):
1026 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1027 return xen_api_todo() # need access to scheduler
1029 def VM_get_VCPUs_features_force_on(self, session, vm_ref):
1030 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1031 return xen_api_todo()
1033 def VM_get_VCPUs_features_force_off(self, session, vm_ref):
1034 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1035 return xen_api_todo()
1037 def VM_get_actions_after_shutdown(self, session, vm_ref):
1038 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1039 return xen_api_success(dom.get_on_shutdown())
1041 def VM_get_actions_after_reboot(self, session, vm_ref):
1042 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1043 return xen_api_success(dom.get_on_reboot())
1045 def VM_get_actions_after_suspend(self, session, vm_ref):
1046 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1047 return xen_api_success(dom.get_on_suspend())
1049 def VM_get_actions_after_crash(self, session, vm_ref):
1050 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1051 return xen_api_success(dom.get_on_crash())
1053 def VM_get_PV_bootloader(self, session, vm_ref):
1054 return self.VM_get('PV_bootloader', session, vm_ref)
1056 def VM_get_PV_kernel(self, session, vm_ref):
1057 return self.VM_get('PV_kernel', session, vm_ref)
1059 def VM_get_PV_ramdisk(self, session, vm_ref):
1060 return self.VM_get('PV_ramdisk', session, vm_ref)
1062 def VM_get_PV_args(self, session, vm_ref):
1063 return self.VM_get('PV_args', session, vm_ref)
1065 def VM_get_PV_bootloader_args(self, session, vm_ref):
1066 return self.VM_get('PV_bootloader_args', session, vm_ref)
1068 def VM_get_HVM_boot(self, session, vm_ref):
1069 return self.VM_get('HVM_boot', session, vm_ref)
1071 def VM_get_platform_std_VGA(self, session, vm_ref):
1072 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1073 return xen_api_success(dom.get_platform_std_vga())
1075 def VM_get_platform_serial(self, session, vm_ref):
1076 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1077 return xen_api_success(dom.get_platform_serial())
1079 def VM_get_platform_localtime(self, session, vm_ref):
1080 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1081 return xen_api_success(dom.get_platform_localtime())
1083 def VM_get_platform_clock_offset(self, session, vm_ref):
1084 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1085 return xen_api_success(dom.get_platform_clock_offset())
1087 def VM_get_platform_enable_audio(self, session, vm_ref):
1088 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1089 return xen_api_success(dom.get_platform_enable_audio())
1091 def VM_get_platform_keymap(self, session, vm_ref):
1092 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1093 return xen_api_success(dom.get_platform_keymap())
1095 def VM_get_otherConfig(self, session, vm_ref):
1096 return self.VM_get('otherConfig', session, vm_ref)
1098 def VM_set_name_label(self, session, vm_ref, label):
1099 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1100 dom.setName(label)
1101 return xen_api_success_void()
1103 def VM_set_name_description(self, session, vm_ref, desc):
1104 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1105 return xen_api_todo()
1107 def VM_set_user_version(self, session, vm_ref, ver):
1108 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1109 return xen_api_todo()
1111 def VM_set_is_a_template(self, session, vm_ref, is_template):
1112 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1113 return xen_api_todo()
1115 def VM_set_memory_dynamic_max(self, session, vm_ref, mem):
1116 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1117 return xen_api_todo()
1119 def VM_set_memory_dynamic_min(self, session, vm_ref, mem):
1120 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1121 return xen_api_todo()
1123 def VM_set_VCPUs_policy(self, session, vm_ref, policy):
1124 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1125 return xen_api_todo()
1127 def VM_set_VCPUs_params(self, session, vm_ref, params):
1128 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1129 return xen_api_todo()
1131 def VM_set_VCPUs_features_force_on(self, session, vm_ref, features):
1132 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1133 return xen_api_todo()
1135 def VM_set_VCPUs_features_force_off(self, session, vm_ref, features):
1136 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1137 return xen_api_todo()
1139 def VM_set_actions_after_shutdown(self, session, vm_ref, action):
1140 if action not in XEN_API_ON_NORMAL_EXIST:
1141 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1142 return self.VM_set('actions_after_shutdown', session, vm_ref, action)
1144 def VM_set_actions_after_reboot(self, session, vm_ref, action):
1145 if action not in XEN_API_ON_NORMAL_EXIST:
1146 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1147 return self.VM_set('actions_after_reboot', session, vm_ref, action)
1149 def VM_set_actions_after_suspend(self, session, vm_ref, action):
1150 if action not in XEN_API_ON_NORMAL_EXIT:
1151 return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
1152 return self.VM_set('actions_after_suspend', session, vm_ref, action)
1154 def VM_set_actions_after_crash(self, session, vm_ref, action):
1155 if action not in XEN_API_ON_CRASH_BEHAVIOUR:
1156 return xen_api_error(['VM_ON_CRASH_BEHAVIOUR_INVALID', vm_ref])
1157 return self.VM_set('actions_after_crash', session, vm_ref, action)
1159 def VM_set_HVM_boot(self, session, vm_ref, value):
1160 return self.VM_set('HVM_boot', session, vm_ref, value)
1162 def VM_set_PV_bootloader(self, session, vm_ref, value):
1163 return self.VM_set('PV_bootloader', session, vm_ref, value)
1165 def VM_set_PV_kernel(self, session, vm_ref, value):
1166 return self.VM_set('PV_kernel', session, vm_ref, value)
1168 def VM_set_PV_ramdisk(self, session, vm_ref, value):
1169 return self.VM_set('PV_ramdisk', session, vm_ref, value)
1171 def VM_set_PV_args(self, session, vm_ref, value):
1172 return self.VM_set('PV_args', session, vm_ref, value)
1174 def VM_set_PV_bootloader_args(self, session, vm_ref, value):
1175 return self.VM_set('PV_bootloader_args', session, vm_ref, value)
1177 def VM_set_platform_std_VGA(self, session, vm_ref, value):
1178 return self.VM_set('platform_std_vga', session, vm_ref, value)
1180 def VM_set_platform_serial(self, session, vm_ref, value):
1181 return self.VM_set('platform_serial', session, vm_ref, value)
1183 def VM_set_platform_keymap(self, session, vm_ref, value):
1184 return self.VM_set('platform_keymap', session, vm_ref, value)
1186 def VM_set_platform_localtime(self, session, vm_ref, value):
1187 return self.VM_set('platform_localtime', session, vm_ref, value)
1189 def VM_set_platform_clock_offset(self, session, vm_ref, value):
1190 return self.VM_set('platform_clock_offset', session, vm_ref, value)
1192 def VM_set_platform_enable_audio(self, session, vm_ref, value):
1193 return self.VM_set('platform_enable_audio', session, vm_ref, value)
1195 def VM_set_otherConfig(self, session, vm_ref, value):
1196 return self.VM_set('otherconfig', session, vm_ref, value)
1198 def VM_add_to_otherConfig(self, session, vm_ref, key, value):
1199 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1200 if dom and 'otherconfig' in dom.info:
1201 dom.info['otherconfig'][key] = value
1202 return xen_api_success_void()
1204 def VM_remove_from_otherConfig(self, session, vm_ref, key):
1205 dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
1206 if dom and 'otherconfig' in dom.info \
1207 and key in dom.info['otherconfig']:
1208 del dom.info['otherconfig'][key]
1209 return xen_api_success_void()
1211 # class methods
1212 def VM_get_all(self, session):
1213 refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
1214 return xen_api_success(refs)
1216 def VM_get_by_name_label(self, session, label):
1217 xendom = XendDomain.instance()
1218 dom = xendom.domain_lookup_nr(label)
1219 if dom:
1220 return xen_api_success([dom.get_uuid()])
1221 return xen_api_success([])
1223 def VM_create(self, session, vm_struct):
1224 xendom = XendDomain.instance()
1225 domuuid = XendTask.log_progress(0, 100,
1226 xendom.create_domain, vm_struct)
1227 return xen_api_success(domuuid)
1229 # object methods
1230 def VM_get_record(self, session, vm_ref):
1231 xendom = XendDomain.instance()
1232 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1233 if not xeninfo:
1234 return xen_api_error(['VM_HANDLE_INVALID', vm_ref])
1236 record = {
1237 'uuid': xeninfo.get_uuid(),
1238 'power_state': xeninfo.get_power_state(),
1239 'name_label': xeninfo.getName(),
1240 'name_description': xeninfo.getName(),
1241 'user_version': 1,
1242 'is_a_template': False,
1243 'auto_power_on': False,
1244 'resident_on': XendNode.instance().uuid,
1245 'memory_static_min': xeninfo.get_memory_static_min(),
1246 'memory_static_max': xeninfo.get_memory_static_max(),
1247 'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
1248 'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
1249 'memory_actual': xeninfo.get_memory_static_min(),
1250 'VCPUs_policy': xeninfo.get_vcpus_policy(),
1251 'VCPUs_params': xeninfo.get_vcpus_params(),
1252 'VCPUs_number': xeninfo.getVCpuCount(),
1253 'VCPUs_utilisation': xeninfo.get_vcpus_util(),
1254 'VCPUs_features_required': [],
1255 'VCPUs_features_can_use': [],
1256 'VCPUs_features_force_on': [],
1257 'VCPUs_features_force_off': [],
1258 'actions_after_shutdown': xeninfo.get_on_shutdown(),
1259 'actions_after_reboot': xeninfo.get_on_reboot(),
1260 'actions_after_suspend': xeninfo.get_on_suspend(),
1261 'actions_after_crash': xeninfo.get_on_crash(),
1262 'consoles': xeninfo.get_consoles(),
1263 'VIFs': xeninfo.get_vifs(),
1264 'VBDs': xeninfo.get_vbds(),
1265 'VTPMs': xeninfo.get_vtpms(),
1266 'PV_bootloader': xeninfo.info.get('PV_bootloader'),
1267 'PV_kernel': xeninfo.info.get('PV_kernel'),
1268 'PV_ramdisk': xeninfo.info.get('PV_ramdisk'),
1269 'PV_args': xeninfo.info.get('PV_args'),
1270 'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
1271 'HVM_boot': xeninfo.info.get('HVM_boot'),
1272 'platform_std_VGA': xeninfo.get_platform_std_vga(),
1273 'platform_serial': xeninfo.get_platform_serial(),
1274 'platform_localtime': xeninfo.get_platform_localtime(),
1275 'platform_clock_offset': xeninfo.get_platform_clock_offset(),
1276 'platform_enable_audio': xeninfo.get_platform_enable_audio(),
1277 'platform_keymap': xeninfo.get_platform_keymap(),
1278 'PCI_bus': xeninfo.get_pci_bus(),
1279 'tools_version': xeninfo.get_tools_version(),
1280 'otherConfig': xeninfo.info.get('otherconfig'),
1282 return xen_api_success(record)
1284 def VM_clean_reboot(self, session, vm_ref):
1285 xendom = XendDomain.instance()
1286 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1287 XendTask.log_progress(0, 100, xeninfo.shutdown, "reboot")
1288 return xen_api_success_void()
1290 def VM_clean_shutdown(self, session, vm_ref):
1291 xendom = XendDomain.instance()
1292 xeninfo = xendom.get_vm_by_uuid(vm_ref)
1293 XendTask.log_progress(0, 100, xeninfo.shutdown, "poweroff")
1294 return xen_api_success_void()
1296 def VM_clone(self, session, vm_ref):
1297 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1299 def VM_destroy(self, session, vm_ref):
1300 return XendTask.log_progress(0, 100, do_vm_func,
1301 "domain_delete", vm_ref)
1303 def VM_hard_reboot(self, session, vm_ref):
1304 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1306 def VM_hard_shutdown(self, session, vm_ref):
1307 return XendTask.log_progress(0, 100, do_vm_func,
1308 "domain_destroy", vm_ref)
1309 def VM_pause(self, session, vm_ref):
1310 return XendTask.log_progress(0, 100, do_vm_func,
1311 "domain_pause", vm_ref)
1313 def VM_resume(self, session, vm_ref, start_paused):
1314 return XendTask.log_progress(0, 100, do_vm_func,
1315 "domain_resume", vm_ref,
1316 start_paused = start_paused)
1318 def VM_start(self, session, vm_ref, start_paused):
1319 return XendTask.log_progress(0, 100, do_vm_func,
1320 "domain_start", vm_ref,
1321 start_paused = start_paused)
1323 def VM_suspend(self, session, vm_ref):
1324 return XendTask.log_progress(0, 100, do_vm_func,
1325 "domain_suspend", vm_ref)
1327 def VM_unpause(self, session, vm_ref):
1328 return XendTask.log_progress(0, 100, do_vm_func,
1329 "domain_unpause", vm_ref)
1331 # Xen API: Class VBD
1332 # ----------------------------------------------------------------
1334 VBD_attr_ro = ['io_read_kbs',
1335 'io_write_kbs']
1336 VBD_attr_rw = ['VM',
1337 'VDI',
1338 'device',
1339 'bootable',
1340 'mode',
1341 'type',
1342 'driver']
1344 VBD_attr_inst = VBD_attr_rw
1346 VBD_methods = [('media_change', None)]
1347 VBD_funcs = [('create', 'VBD')]
1349 # object methods
1350 def VBD_get_record(self, session, vbd_ref):
1351 xendom = XendDomain.instance()
1352 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1353 if not vm:
1354 return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref])
1355 cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
1356 if not cfg:
1357 return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref])
1359 valid_vbd_keys = self.VBD_attr_ro + self.VBD_attr_rw + \
1360 self.Base_attr_ro + self.Base_attr_rw
1362 return_cfg = {}
1363 for k in cfg.keys():
1364 if k in valid_vbd_keys:
1365 return_cfg[k] = cfg[k]
1367 return xen_api_success(return_cfg)
1369 def VBD_media_change(self, session, vbd_ref, vdi_ref):
1370 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1372 # class methods
1373 def VBD_create(self, session, vbd_struct):
1374 xendom = XendDomain.instance()
1375 if not xendom.is_valid_vm(vbd_struct['VM']):
1376 return xen_api_error(['VM_HANDLE_INVALID', vbd_struct['VM']])
1378 dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
1379 vbd_ref = ''
1380 try:
1381 # new VBD via VDI/SR
1382 vdi_ref = vbd_struct.get('VDI')
1383 vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
1384 if not vdi:
1385 return xen_api_error(['VDI_HANDLE_INVALID', vdi_ref])
1386 vdi_image = vdi.get_image_uri()
1387 vbd_ref = XendTask.log_progress(0, 100,
1388 dom.create_vbd,
1389 vbd_struct, vdi_image)
1390 except XendError:
1391 return xen_api_todo()
1393 xendom.managed_config_save(dom)
1394 return xen_api_success(vbd_ref)
1397 def VBD_destroy(self, session, vbd_ref):
1398 xendom = XendDomain.instance()
1399 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
1400 if not vm:
1401 return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref])
1403 XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref)
1404 return xen_api_success_void()
1406 # attributes (rw)
1407 def VBD_get_VM(self, session, vbd_ref):
1408 xendom = XendDomain.instance()
1409 return xen_api_success(xendom.get_dev_property_by_uuid('vbd',
1410 vbd_ref, 'VM'))
1412 def VBD_get_VDI(self, session, vbd_ref):
1413 xendom = XendDomain.instance()
1414 return xen_api_success(xendom.get_dev_property_by_uuid('vbd',
1415 vbd_ref, 'VDI'))
1417 def VBD_get_device(self, session, vbd_ref):
1418 xendom = XendDomain.instance()
1419 return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref,
1420 'device'))
1421 def VBD_get_bootable(self, session, vbd_ref):
1422 xendom = XendDomain.instance()
1423 return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref,
1424 'bootable'))
1425 def VBD_get_mode(self, session, vbd_ref):
1426 xendom = XendDomain.instance()
1427 return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref,
1428 'mode'))
1429 def VBD_get_driver(self, session, vbd_ref):
1430 xendom = XendDomain.instance()
1431 return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref,
1432 'driver'))
1434 def VBD_get_type(self, session, vbd_ref):
1435 xendom = XendDomain.instance()
1436 return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref,
1437 'type'))
1439 def VBD_get_io_read_kbs(self, session, vbd_ref):
1440 xendom = XendDomain.instance()
1441 return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref,
1442 'io_read_kbs'))
1445 def VBD_get_io_write_kbs(self, session, vbd_ref):
1446 xendom = XendDomain.instance()
1447 return xen_api_success(xendom.get_dev_property_by_uuid('vbd', vbd_ref,
1448 'io_read_kbs'))
1450 def VBD_set_bootable(self, session, vbd_ref, bootable):
1451 bootable = bool(bootable)
1452 xd = XendDomain.instance()
1453 vm = xd.get_vm_with_dev_uuid('vbd', vbd_ref)
1454 vm.set_dev_property('vbd', vbd_ref, 'bootable', bootable)
1455 xd.managed_config_save(vm)
1456 return xen_api_success_void()
1458 def VBD_get_all(self, session):
1459 xendom = XendDomain.instance()
1460 vbds = [d.get_vbds() for d in XendDomain.instance().list('all')]
1461 vbds = reduce(lambda x, y: x + y, vbds)
1462 return xen_api_success(vbds)
1464 # Xen API: Class VIF
1465 # ----------------------------------------------------------------
1467 VIF_attr_ro = ['io_read_kbs',
1468 'io_write_kbs']
1469 VIF_attr_rw = ['name',
1470 'type',
1471 'device',
1472 'network',
1473 'VM',
1474 'MAC',
1475 'MTU']
1477 VIF_attr_inst = VIF_attr_rw
1479 VIF_funcs = [('create', 'VIF')]
1482 # object methods
1483 def VIF_get_record(self, session, vif_ref):
1484 xendom = XendDomain.instance()
1485 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1486 if not vm:
1487 return xen_api_error(['VIF_HANDLE_INVALID', vif_ref])
1488 cfg = vm.get_dev_xenapi_config('vif', vif_ref)
1489 if not cfg:
1490 return xen_api_error(['VIF_HANDLE_INVALID', vif_ref])
1492 valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
1493 self.Base_attr_ro + self.Base_attr_rw
1495 return_cfg = {}
1496 for k in cfg.keys():
1497 if k in valid_vif_keys:
1498 return_cfg[k] = cfg[k]
1500 return xen_api_success(return_cfg)
1502 # class methods
1503 def VIF_create(self, session, vif_struct):
1504 xendom = XendDomain.instance()
1505 if xendom.is_valid_vm(vif_struct['VM']):
1506 dom = xendom.get_vm_by_uuid(vif_struct['VM'])
1507 try:
1508 vif_ref = dom.create_vif(vif_struct)
1509 xendom.managed_config_save(dom)
1510 return xen_api_success(vif_ref)
1511 except XendError:
1512 return xen_api_error(XEND_ERROR_TODO)
1513 else:
1514 return xen_api_error(['VM_HANDLE_INVALID', vif_struct['VM']])
1517 def VIF_destroy(self, session, vif_ref):
1518 xendom = XendDomain.instance()
1519 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1520 if not vm:
1521 return xen_api_error(['VIF_HANDLE_INVALID', vif_ref])
1523 vm.destroy_vif(vif_ref)
1524 return xen_api_success_void()
1526 # getters/setters
1527 def VIF_get_VM(self, session, vif_ref):
1528 xendom = XendDomain.instance()
1529 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
1530 return xen_api_success(vm.get_uuid())
1532 def VIF_get_name(self, session, vif_ref):
1533 xendom = XendDomain.instance()
1534 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1535 'name'))
1536 def VIF_get_MTU(self, session, vif_ref):
1537 xendom = XendDomain.instance()
1538 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1539 'MTU'))
1540 def VIF_get_MAC(self, session, vif_ref):
1541 xendom = XendDomain.instance()
1542 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1543 'MAC'))
1545 def VIF_get_type(self, session, vif_ref):
1546 xendom = XendDomain.instance()
1547 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1548 'type'))
1551 def VIF_get_device(self, session, vif_ref):
1552 xendom = XendDomain.instance()
1553 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1554 'device'))
1557 def VIF_get_io_read_kbs(self, session, vif_ref):
1558 xendom = XendDomain.instance()
1559 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1560 'io_read_kbs'))
1562 def VIF_get_io_write_kbs(self, session, vif_ref):
1563 xendom = XendDomain.instance()
1564 return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
1565 'io_write_kbs'))
1567 def VIF_get_all(self, session):
1568 xendom = XendDomain.instance()
1569 vifs = [d.get_vifs() for d in XendDomain.instance().list('all')]
1570 vifs = reduce(lambda x, y: x + y, vifs)
1571 return xen_api_success(vifs)
1574 # Xen API: Class VDI
1575 # ----------------------------------------------------------------
1576 VDI_attr_ro = ['VBDs',
1577 'physical_utilisation',
1578 'sector_size',
1579 'type',
1580 'parent',
1581 'children']
1582 VDI_attr_rw = ['name_label',
1583 'name_description',
1584 'SR',
1585 'virtual_size',
1586 'sharable',
1587 'read_only']
1588 VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
1590 VDI_methods = [('snapshot', 'VDI')]
1591 VDI_funcs = [('create', 'VDI'),
1592 ('get_by_name_label', 'Set(VDI)')]
1594 def _get_VDI(self, ref):
1595 return XendNode.instance().get_vdi_by_uuid(ref)
1597 def VDI_get_VBDs(self, session, vdi_ref):
1598 return xen_api_todo()
1600 def VDI_get_physical_utilisation(self, session, vdi_ref):
1601 return xen_api_success(self._get_VDI(vdi_ref).
1602 get_physical_utilisation())
1604 def VDI_get_sector_size(self, session, vdi_ref):
1605 return xen_api_success(self._get_VDI(vdi_ref).sector_size)
1607 def VDI_get_type(self, session, vdi_ref):
1608 return xen_api_success(self._get_VDI(vdi_ref).type)
1610 def VDI_get_parent(self, session, vdi_ref):
1611 return xen_api_success(self._get_VDI(vdi_ref).parent)
1613 def VDI_get_children(self, session, vdi_ref):
1614 return xen_api_success(self._get_VDI(vdi_ref).children)
1616 def VDI_get_name_label(self, session, vdi_ref):
1617 return xen_api_success(self._get_VDI(vdi_ref).name_label)
1619 def VDI_get_name_description(self, session, vdi_ref):
1620 return xen_api_success(self._get_VDI(vdi_ref).name_description)
1622 def VDI_get_SR(self, session, vdi_ref):
1623 return xen_api_success(self._get_VDI(vdi_ref).sr_uuid)
1625 def VDI_get_virtual_size(self, session, vdi_ref):
1626 return xen_api_success(self._get_VDI(vdi_ref).virtual_size)
1628 def VDI_get_sharable(self, session, vdi_ref):
1629 return xen_api_success(self._get_VDI(vdi_ref).sharable)
1631 def VDI_get_read_only(self, session, vdi_ref):
1632 return xen_api_success(self._get_VDI(vdi_ref).read_only)
1634 def VDI_set_name_label(self, session, vdi_ref, value):
1635 self._get_VDI(vdi_ref).name_label = value
1636 return xen_api_success_void()
1638 def VDI_set_name_description(self, session, vdi_ref, value):
1639 self._get_VDI(vdi_ref).name_description = value
1640 return xen_api_success_void()
1642 def VDI_set_SR(self, session, vdi_ref, value):
1643 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1645 def VDI_set_virtual_size(self, session, vdi_ref, value):
1646 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1648 def VDI_set_sharable(self, session, vdi_ref, value):
1649 self._get_VDI(vdi_ref).sharable = bool(value)
1650 return xen_api_success_void()
1652 def VDI_set_read_only(self, session, vdi_ref, value):
1653 self._get_VDI(vdi_ref).read_only = bool(value)
1654 return xen_api_success_void()
1656 # Object Methods
1657 def VDI_snapshot(self, session, vdi_ref):
1658 return xen_api_todo()
1660 def VDI_destroy(self, session, vdi_ref):
1661 sr = XendNode.instance().get_sr_containing_vdi(vdi_ref)
1662 sr.destroy_vdi(vdi_ref)
1663 return xen_api_success_void()
1665 def VDI_get_record(self, session, vdi_ref):
1666 image = XendNode.instance().get_vdi_by_uuid(vdi_ref)
1667 return xen_api_success({
1668 'uuid': vdi_ref,
1669 'name_label': image.name_label,
1670 'name_description': image.name_description,
1671 'SR': image.sr_uuid,
1672 'VBDs': [], # TODO
1673 'virtual_size': image.virtual_size,
1674 'physical_utilisation': image.physical_utilisation,
1675 'sector_size': image.sector_size,
1676 'type': image.type,
1677 'parent': image.parent,
1678 'children': image.children,
1679 'sharable': image.sharable,
1680 'read_only': image.read_only,
1681 })
1683 # Class Functions
1684 def VDI_create(self, session, vdi_struct):
1685 sr_ref = vdi_struct.get('SR')
1686 xennode = XendNode.instance()
1687 if not xennode.is_valid_sr(sr_ref):
1688 return xen_api_error(['SR_HANDLE_INVALID', sr_ref])
1690 vdi_uuid = xennode.srs[sr_ref].create_vdi(vdi_struct)
1691 return xen_api_success(vdi_uuid)
1693 def VDI_get_all(self, session):
1694 xennode = XendNode.instance()
1695 vdis = [sr.get_vdis() for sr in xennode.srs.values()]
1696 return xen_api_success(reduce(lambda x, y: x + y, vdis))
1698 def VDI_get_by_name_label(self, session, name):
1699 xennode = XendNode.instance()
1700 return xen_api_success(xennode.get_vdi_by_name_label(name))
1703 # Xen API: Class VTPM
1704 # ----------------------------------------------------------------
1706 VTPM_attr_rw = [ ]
1707 VTPM_attr_ro = ['VM',
1708 'backend',
1709 'instance',
1710 'driver']
1712 VTPM_attr_inst = VTPM_attr_rw
1714 VTPM_funcs = [('create', 'VTPM')]
1716 # object methods
1717 def VTPM_get_record(self, session, vtpm_ref):
1718 xendom = XendDomain.instance()
1719 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1720 if not vm:
1721 return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
1722 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1723 if not cfg:
1724 return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
1725 valid_vtpm_keys = self.VTPM_attr_ro + self.VTPM_attr_rw + \
1726 self.Base_attr_ro + self.Base_attr_rw
1727 for k in cfg.keys():
1728 if k not in valid_vtpm_keys:
1729 del cfg[k]
1731 return xen_api_success(cfg)
1733 # Class Functions
1734 def VTPM_get_instance(self, session, vtpm_ref):
1735 xendom = XendDomain.instance()
1736 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1737 if not vm:
1738 return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
1739 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1740 if not cfg:
1741 return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
1742 if cfg.has_key('instance'):
1743 instance = cfg['instance']
1744 else:
1745 instance = -1
1746 return xen_api_success(instance)
1748 def VTPM_get_driver(self, session, vtpm_ref):
1749 xendom = XendDomain.instance()
1750 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1751 if not vm:
1752 return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
1753 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1754 if not cfg:
1755 return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
1756 if cfg.has_key('type'):
1757 driver = cfg['type']
1758 else:
1759 driver = "Unknown"
1760 return xen_api_success(driver)
1762 def VTPM_get_backend(self, session, vtpm_ref):
1763 xendom = XendDomain.instance()
1764 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1765 if not vm:
1766 return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
1767 cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
1768 if not cfg:
1769 return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
1770 if cfg.has_key('backend'):
1771 backend = cfg['backend']
1772 else:
1773 backend = "Domain-0"
1774 return xen_api_success(backend)
1776 def VTPM_get_VM(self, session, vtpm_ref):
1777 xendom = XendDomain.instance()
1778 return xen_api_success(xendom.get_dev_property_by_uuid('vtpm',
1779 vtpm_ref, 'VM'))
1781 def VTPM_destroy(self, session, vtpm_ref):
1782 xendom = XendDomain.instance()
1783 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
1784 if not vm:
1785 return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
1787 vm.destroy_vtpm(vtpm_ref)
1788 return xen_api_success_void()
1790 # class methods
1791 def VTPM_create(self, session, vtpm_struct):
1792 xendom = XendDomain.instance()
1793 if xendom.is_valid_vm(vtpm_struct['VM']):
1794 dom = xendom.get_vm_by_uuid(vtpm_struct['VM'])
1795 try:
1796 vtpm_ref = dom.create_vtpm(vtpm_struct)
1797 xendom.managed_config_save(dom)
1798 return xen_api_success(vtpm_ref)
1799 except XendError:
1800 return xen_api_error(XEND_ERROR_TODO)
1801 else:
1802 return xen_api_error(['VM_HANDLE_INVALID', vtpm_struct['VM']])
1804 def VTPM_get_all(self, session):
1805 xendom = XendDomain.instance()
1806 vtpms = [d.get_vtpms() for d in XendDomain.instance().list('all')]
1807 vtpms = reduce(lambda x, y: x + y, vtpms)
1808 return xen_api_success(vtpms)
1810 # Xen API: Class console
1811 # ----------------------------------------------------------------
1814 console_attr_ro = ['uri', 'protocol', 'VM']
1815 console_attr_rw = []
1817 def console_get_all(self, session):
1818 xendom = XendDomain.instance()
1819 cons = [d.get_consoles() for d in XendDomain.instance().list('all')]
1820 cons = reduce(lambda x, y: x + y, cons)
1821 return xen_api_success(cons)
1823 def console_get_uri(self, session, console_ref):
1824 return xen_api_success(xendom.get_dev_property_by_uuid('console',
1825 console_ref,
1826 'uri'))
1828 def console_get_protocol(self, session, console_ref):
1829 return xen_api_success(xendom.get_dev_property_by_uuid('console',
1830 console_ref,
1831 'protocol'))
1833 def console_get_VM(self, session, console_ref):
1834 xendom = XendDomain.instance()
1835 vm = xendom.get_vm_with_dev_uuid('console', console_ref)
1836 return xen_api_success(vm.get_uuid())
1838 # object methods
1839 def console_get_record(self, session, console_ref):
1840 xendom = XendDomain.instance()
1841 vm = xendom.get_vm_with_dev_uuid('console', console_ref)
1842 if not vm:
1843 return xen_api_error(['CONSOLE_HANDLE_INVALID', console_ref])
1844 cfg = vm.get_dev_xenapi_config('console', console_ref)
1845 if not cfg:
1846 return xen_api_error(['CONSOLE_HANDLE_INVALID', console_ref])
1848 valid_console_keys = self.console_attr_ro + self.console_attr_rw + \
1849 self.Base_attr_ro + self.Base_attr_rw
1851 return_cfg = {}
1852 for k in cfg.keys():
1853 if k in valid_console_keys:
1854 return_cfg[k] = cfg[k]
1856 return xen_api_success(return_cfg)
1859 # Xen API: Class SR
1860 # ----------------------------------------------------------------
1861 SR_attr_ro = ['VDIs',
1862 'virtual_allocation',
1863 'physical_utilisation',
1864 'physical_size',
1865 'type',
1866 'location']
1868 SR_attr_rw = ['name_label',
1869 'name_description']
1871 SR_attr_inst = ['physical_size',
1872 'type',
1873 'location',
1874 'name_label',
1875 'name_description']
1877 SR_methods = [('clone', 'SR')]
1878 SR_funcs = [('get_by_name_label', 'Set(SR)'),
1879 ('get_by_uuid', 'SR')]
1881 # Class Functions
1882 def SR_get_all(self, session):
1883 return xen_api_success(XendNode.instance().get_all_sr_uuid())
1885 def SR_get_by_name_label(self, session, label):
1886 return xen_api_success(XendNode.instance().get_sr_by_name(label))
1888 def SR_create(self, session):
1889 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1891 # Class Methods
1892 def SR_clone(self, session, sr_ref):
1893 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1895 def SR_destroy(self, session, sr_ref):
1896 return xen_api_error(XEND_ERROR_UNSUPPORTED)
1898 def SR_get_record(self, session, sr_ref):
1899 sr = XendNode.instance().get_sr(sr_ref)
1900 if sr:
1901 return xen_api_success(sr.get_record())
1902 return xen_api_error(['SR_HANDLE_INVALID', sr_ref])
1904 # Attribute acceess
1906 def _get_SR_func(self, sr_ref, func):
1907 return xen_api_success(getattr(XendNode.instance().get_sr(sr_ref),
1908 func)())
1910 def _get_SR_attr(self, sr_ref, attr):
1911 return xen_api_success(getattr(XendNode.instance().get_sr(sr_ref),
1912 attr))
1914 def SR_get_VDIs(self, _, ref):
1915 return self._get_SR_func(ref, 'list_images')
1917 def SR_get_virtual_allocation(self, _, ref):
1918 return self._get_SR_func(ref, 'virtual_allocation')
1920 def SR_get_physical_utilisation(self, _, ref):
1921 return self._get_SR_func(ref, 'physical_utilisation')
1923 def SR_get_physical_size(self, _, ref):
1924 return self._get_SR_func(ref, 'physical_size')
1926 def SR_get_type(self, _, ref):
1927 return self._get_SR_attr(ref, 'type')
1929 def SR_get_location(self, _, ref):
1930 return self._get_SR_attr(ref, 'location')
1932 def SR_get_name_label(self, _, ref):
1933 return self._get_SR_attr(ref, 'name_label')
1935 def SR_get_name_description(self, _, ref):
1936 return self._get_SR_attr(ref, 'name_description')
1938 def SR_set_name_label(self, session, sr_ref, value):
1939 sr = XendNode.instance.get_sr(sr_ref)
1940 if sr:
1941 sr.name_label = value
1942 XendNode.instance().save()
1943 return xen_api_success_void()
1945 def SR_set_name_description(self, session, sr_ref, value):
1946 sr = XendNode.instance.get_sr(sr_ref)
1947 if sr:
1948 sr.name_description = value
1949 XendNode.instance().save()
1950 return xen_api_success_void()
1953 # Xen API: Class debug
1954 # ----------------------------------------------------------------
1956 debug_methods = [('destroy', None),
1957 ('get_record', 'debug')]
1958 debug_funcs = [('wait', None),
1959 ('return_failure', None)]
1961 def debug_wait(self, session, wait_secs):
1962 import time
1963 prog_units = 100/float(wait_secs)
1964 for i in range(int(wait_secs)):
1965 XendTask.log_progress(prog_units * i, prog_units * (i + 1),
1966 time.sleep, 1)
1967 return xen_api_success_void()
1970 def debug_return_failure(self, session):
1971 return xen_api_error(['DEBUG_FAIL', session])
1973 def debug_create(self, session):
1974 debug_uuid = uuid.createString()
1975 self._debug[debug_uuid] = None
1976 return xen_api_success(debug_uuid)
1978 def debug_destroy(self, session, debug_ref):
1979 del self._debug[debug_ref]
1980 return xen_api_success_void()
1982 def debug_get_record(self, session, debug_ref):
1983 return xen_api_success({'uuid': debug_ref})
1987 class XendAPIAsyncProxy:
1988 """ A redirector for Async.Class.function calls to XendAPI
1989 but wraps the call for use with the XendTaskManager.
1991 @ivar xenapi: Xen API instance
1992 @ivar method_map: Mapping from XMLRPC method name to callable objects.
1993 """
1995 method_prefix = 'Async.'
1997 def __init__(self, xenapi):
1998 """Initialises the Async Proxy by making a map of all
1999 implemented Xen API methods for use with XendTaskManager.
2001 @param xenapi: XendAPI instance
2002 """
2003 self.xenapi = xenapi
2004 self.method_map = {}
2005 for method_name in dir(self.xenapi):
2006 method = getattr(self.xenapi, method_name)
2007 if method_name[0] != '_' and hasattr(method, 'async') \
2008 and method.async == True:
2009 self.method_map[method.api] = method
2011 def _dispatch(self, method, args):
2012 """Overridden method so that SimpleXMLRPCServer will
2013 resolve methods through this method rather than through
2014 inspection.
2016 @param method: marshalled method name from XMLRPC.
2017 @param args: marshalled arguments from XMLRPC.
2018 """
2020 # Only deal with method names that start with "Async."
2021 if not method.startswith(self.method_prefix):
2022 return xen_api_error(['MESSAGE_METHOD_UNKNOWN', method])
2024 # Lookup synchronous version of the method
2025 synchronous_method_name = method[len(self.method_prefix):]
2026 if synchronous_method_name not in self.method_map:
2027 return xen_api_error(['MESSAGE_METHOD_UNKNOWN', method])
2029 method = self.method_map[synchronous_method_name]
2031 # Check that we've got enough arguments before issuing a task ID.
2032 needed = argcounts[method.api]
2033 if len(args) != needed:
2034 return xen_api_error(['MESSAGE_PARAMETER_COUNT_MISMATCH',
2035 self.method_prefix + method.api, needed,
2036 len(args)])
2038 # Validate the session before proceeding
2039 session = args[0]
2040 if not auth_manager().is_session_valid(session):
2041 return xen_api_error(['SESSION_INVALID', session])
2043 # create and execute the task, and return task_uuid
2044 return_type = getattr(method, 'return_type', None)
2045 task_uuid = XendTaskManager.create_task(method, args,
2046 synchronous_method_name,
2047 return_type,
2048 synchronous_method_name)
2049 return xen_api_success(task_uuid)
2052 # Auto generate some stubs based on XendAPI introspection
2054 if __name__ == "__main__":
2055 def output(line):
2056 print ' ' + line
2058 classes = ['VDI', 'SR']
2059 for cls in classes:
2060 ro_attrs = getattr(XendAPI, '%s_attr_ro' % cls, [])
2061 rw_attrs = getattr(XendAPI, '%s_attr_rw' % cls, [])
2062 methods = getattr(XendAPI, '%s_methods' % cls, [])
2063 funcs = getattr(XendAPI, '%s_funcs' % cls, [])
2065 ref = '%s_ref' % cls
2067 for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
2068 getter_name = '%s_get_%s' % (cls, attr_name)
2069 output('def %s(self, session, %s):' % (getter_name, ref))
2070 output(' return xen_api_todo()')
2072 for attr_name in rw_attrs + XendAPI.Base_attr_rw:
2073 setter_name = '%s_set_%s' % (cls, attr_name)
2074 output('def %s(self, session, %s, value):' % (setter_name, ref))
2075 output(' return xen_api_todo()')
2077 for method_name in methods + XendAPI.Base_methods:
2078 method_full_name = '%s_%s' % (cls,method_name)
2079 output('def %s(self, session, %s):' % (method_full_name, ref))
2080 output(' return xen_api_todo()')
2082 for func_name in funcs + XendAPI.Base_funcs:
2083 func_full_name = '%s_%s' % (cls, func_name)
2084 output('def %s(self, session):' % func_full_name)
2085 output(' return xen_api_todo()')