#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2006-2007 XenSource Ltd.
#============================================================================
import inspect
import os
import Queue
import sets
import string
import sys
import traceback
import threading
import time
import xmlrpclib
import XendDomain, XendDomainInfo, XendNode, XendDmesg
import XendLogging, XendTaskManager, XendAPIStore
from XendAPIVersion import *
from XendAuthSessions import instance as auth_manager
from XendError import *
from XendClient import ERROR_INVALID_DOMAIN
from XendLogging import log
from XendNetwork import XendNetwork
from XendTask import XendTask
from XendPIFMetrics import XendPIFMetrics
from XendVMMetrics import XendVMMetrics
from XendPIF import XendPIF
from XendPBD import XendPBD
from XendPPCI import XendPPCI
from XendDPCI import XendDPCI
from XendPSCSI import XendPSCSI
from XendDSCSI import XendDSCSI
from XendXSPolicy import XendXSPolicy, XendACMPolicy
from XendAPIConstants import *
from xen.util.xmlrpclib2 import stringify
from xen.util.blkif import blkdev_name_to_number
from xen.util import xsconstants
AUTH_NONE = 'none'
AUTH_PAM = 'pam'
argcounts = {}
# ------------------------------------------
# Utility Methods for Xen API Implementation
# ------------------------------------------
def xen_api_success(value):
"""Wraps a return value in XenAPI format."""
if value is None:
s = ''
else:
s = stringify(value)
return {"Status": "Success", "Value": s}
def xen_api_success_void():
"""Return success, but caller expects no return value."""
return xen_api_success("")
def xen_api_error(error):
"""Wraps an error value in XenAPI format."""
if type(error) == tuple:
error = list(error)
if type(error) != list:
error = [error]
if len(error) == 0:
error = ['INTERNAL_ERROR', 'Empty list given to xen_api_error']
return { "Status": "Failure",
"ErrorDescription": [str(x) for x in error] }
def xen_api_todo():
"""Temporary method to make sure we track down all the TODOs"""
return {"Status": "Error", "ErrorDescription": XEND_ERROR_TODO}
def now():
return datetime()
def datetime(when = None):
"""Marshall the given time as a Xen-API DateTime.
@param when The time in question, given as seconds since the epoch, UTC.
May be None, in which case the current time is used.
"""
if when is None:
return xmlrpclib.DateTime(time.gmtime())
else:
return xmlrpclib.DateTime(time.gmtime(when))
# ---------------------------------------------------
# Event dispatch
# ---------------------------------------------------
EVENT_QUEUE_LENGTH = 50
event_registrations = {}
def event_register(session, reg_classes):
if session not in event_registrations:
event_registrations[session] = {
'classes' : sets.Set(),
'queue' : Queue.Queue(EVENT_QUEUE_LENGTH),
'next-id' : 1
}
if not reg_classes:
reg_classes = classes
event_registrations[session]['classes'].union_update(reg_classes)
def event_unregister(session, unreg_classes):
if session not in event_registrations:
return
if unreg_classes:
event_registrations[session]['classes'].intersection_update(
unreg_classes)
if len(event_registrations[session]['classes']) == 0:
del event_registrations[session]
else:
del event_registrations[session]
def event_next(session):
if session not in event_registrations:
return xen_api_error(['SESSION_NOT_REGISTERED', session])
queue = event_registrations[session]['queue']
events = [queue.get()]
try:
while True:
events.append(queue.get(False))
except Queue.Empty:
pass
return xen_api_success(events)
def _ctor_event_dispatch(xenapi, ctor, api_cls, session, args):
result = ctor(xenapi, session, *args)
if result['Status'] == 'Success':
ref = result['Value']
event_dispatch('add', api_cls, ref, '')
return result
def _dtor_event_dispatch(xenapi, dtor, api_cls, session, ref, args):
result = dtor(xenapi, session, ref, *args)
if result['Status'] == 'Success':
event_dispatch('del', api_cls, ref, '')
return result
def _setter_event_dispatch(xenapi, setter, api_cls, attr_name, session, ref,