mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 02:30:03 +01:00
Remove docs and bindings for unimplemented SR.{create,destroy,clone}.
Implement PBD class, matching existing docs and bindings. Signed-off-by: Ewan Mellor <ewan@xensource.com>
This commit is contained in:
1 parent
6b5e36a305
commit
5adf114d68
10 files changed
+241
-226
No files matched your search
@@ -26,20 +26,22 @@ import threading
|
||||
import time
|
||||
import xmlrpclib
|
||||
|
||||
from xen.xend import XendDomain, XendDomainInfo, XendNode, XendDmesg
|
||||
from xen.xend import XendLogging, XendTaskManager
|
||||
import XendDomain, XendDomainInfo, XendNode, XendDmesg
|
||||
import XendLogging, XendTaskManager
|
||||
|
||||
from xen.xend.XendAPIVersion import *
|
||||
from xen.xend.XendAuthSessions import instance as auth_manager
|
||||
from xen.xend.XendError import *
|
||||
from xen.xend.XendClient import ERROR_INVALID_DOMAIN
|
||||
from xen.xend.XendLogging import log
|
||||
from xen.xend.XendNetwork import XendNetwork
|
||||
from xen.xend.XendTask import XendTask
|
||||
from xen.xend.XendPIFMetrics import XendPIFMetrics
|
||||
from xen.xend.XendVMMetrics import XendVMMetrics
|
||||
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 xen.xend.XendAPIConstants import *
|
||||
import XendPBD
|
||||
|
||||
from XendAPIConstants import *
|
||||
from xen.util.xmlrpclib2 import stringify
|
||||
|
||||
from xen.util.blkif import blkdev_name_to_number
|
||||
@@ -394,6 +396,17 @@ def valid_sr(func):
|
||||
_check_ref(lambda r: XendNode.instance().is_valid_sr,
|
||||
'SR', func, *args, **kwargs)
|
||||
|
||||
def valid_pbd(func):
|
||||
"""Decorator to verify if pbd_ref is valid before calling
|
||||
method.
|
||||
|
||||
@param func: function with params: (self, session, pbd_ref)
|
||||
@rtype: callable object
|
||||
"""
|
||||
return lambda *args, **kwargs: \
|
||||
_check_ref(lambda r: r in XendPBD.get_all_refs(),
|
||||
'PBD', func, *args, **kwargs)
|
||||
|
||||
def valid_pif(func):
|
||||
"""Decorator to verify if pif_ref is valid before calling
|
||||
method.
|
||||
@@ -479,6 +492,7 @@ classes = {
|
||||
'VTPM' : valid_vtpm,
|
||||
'console' : valid_console,
|
||||
'SR' : valid_sr,
|
||||
'PBD' : valid_pbd,
|
||||
'PIF' : valid_pif,
|
||||
'PIF_metrics' : valid_pif_metrics,
|
||||
'task' : valid_task,
|
||||
@@ -488,6 +502,7 @@ classes = {
|
||||
autoplug_classes = {
|
||||
'network' : XendNetwork,
|
||||
'VM_metrics' : XendVMMetrics,
|
||||
'PBD' : XendPBD.XendPBD,
|
||||
'PIF_metrics' : XendPIFMetrics,
|
||||
}
|
||||
|
||||
@@ -843,6 +858,7 @@ class XendAPI(object):
|
||||
|
||||
host_attr_ro = ['software_version',
|
||||
'resident_VMs',
|
||||
'PBDs',
|
||||
'PIFs',
|
||||
'host_CPUs',
|
||||
'cpu_configuration',
|
||||
@@ -913,6 +929,8 @@ class XendAPI(object):
|
||||
return xen_api_success(XendNode.instance().xen_version())
|
||||
def host_get_resident_VMs(self, session, host_ref):
|
||||
return xen_api_success(XendDomain.instance().get_domain_refs())
|
||||
def host_get_PBDs(self, _, ref):
|
||||
return xen_api_success(XendPBD.get_all_refs())
|
||||
def host_get_PIFs(self, session, ref):
|
||||
return xen_api_success(XendNode.instance().get_PIF_refs())
|
||||
def host_get_host_CPUs(self, session, host_ref):
|
||||
@@ -2434,18 +2452,17 @@ class XendAPI(object):
|
||||
'physical_utilisation',
|
||||
'physical_size',
|
||||
'type',
|
||||
'location']
|
||||
'content_type']
|
||||
|
||||
SR_attr_rw = ['name_label',
|
||||
'name_description']
|
||||
|
||||
SR_attr_inst = ['physical_size',
|
||||
'type',
|
||||
'location',
|
||||
'name_label',
|
||||
'name_description']
|
||||
|
||||
SR_methods = [('clone', 'SR'), ('destroy', None)]
|
||||
SR_methods = []
|
||||
SR_funcs = [('get_by_name_label', 'Set(SR)'),
|
||||
('get_by_uuid', 'SR')]
|
||||
|
||||
@@ -2456,15 +2473,10 @@ class XendAPI(object):
|
||||
def SR_get_by_name_label(self, session, label):
|
||||
return xen_api_success(XendNode.instance().get_sr_by_name(label))
|
||||
|
||||
def SR_create(self, session):
|
||||
return xen_api_error(XEND_ERROR_UNSUPPORTED)
|
||||
def SR_get_supported_types(self, _):
|
||||
return xen_api_success(['local', 'qcow_file'])
|
||||
|
||||
# Class Methods
|
||||
def SR_clone(self, session, sr_ref):
|
||||
return xen_api_error(XEND_ERROR_UNSUPPORTED)
|
||||
|
||||
def SR_destroy(self, session, sr_ref):
|
||||
return xen_api_error(XEND_ERROR_UNSUPPORTED)
|
||||
|
||||
def SR_get_record(self, session, sr_ref):
|
||||
sr = XendNode.instance().get_sr(sr_ref)
|
||||
@@ -2497,8 +2509,8 @@ class XendAPI(object):
|
||||
def SR_get_type(self, _, ref):
|
||||
return self._get_SR_attr(ref, 'type')
|
||||
|
||||
def SR_get_location(self, _, ref):
|
||||
return self._get_SR_attr(ref, 'location')
|
||||
def SR_get_content_type(self, _, ref):
|
||||
return self._get_SR_attr(ref, 'content_type')
|
||||
|
||||
def SR_get_name_label(self, _, ref):
|
||||
return self._get_SR_attr(ref, 'name_label')
|
||||
@@ -2521,6 +2533,33 @@ class XendAPI(object):
|
||||
return xen_api_success_void()
|
||||
|
||||
|
||||
# Xen API: Class PBD
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
PBD_attr_ro = ['host',
|
||||
'SR',
|
||||
'device_config',
|
||||
'currently_attached']
|
||||
PBD_attr_rw = []
|
||||
PBD_methods = [('destroy', None)]
|
||||
PBD_funcs = [('create', None)]
|
||||
|
||||
def PBD_get_all(self, _):
|
||||
return xen_api_success(XendPBD.get_all_refs())
|
||||
|
||||
def _PBD_get(self, _, ref):
|
||||
return XendPBD.get(ref)
|
||||
|
||||
def PBD_create(self, _, record):
|
||||
if 'uuid' in record:
|
||||
return xen_api_error(['VALUE_NOT_SUPPORTED',
|
||||
'uuid', record['uuid'],
|
||||
'You may not specify a UUID on creation'])
|
||||
new_uuid = XendPBD.XendPBD(record).get_uuid()
|
||||
XendNode.instance().save()
|
||||
return xen_api_success(new_uuid)
|
||||
|
||||
|
||||
# Xen API: Class event
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -30,13 +30,13 @@ import sys
|
||||
import struct
|
||||
|
||||
from xen.util import mkdir
|
||||
from xen.xend import uuid
|
||||
from xen.xend.XendError import XendError
|
||||
from xen.xend.XendVDI import *
|
||||
from xen.xend.XendTask import XendTask
|
||||
from xen.xend.XendStorageRepository import XendStorageRepository
|
||||
from xen.xend.XendStateStore import XendStateStore
|
||||
from xen.xend.XendOptions import instance as xendoptions
|
||||
import uuid
|
||||
from XendError import XendError
|
||||
from XendVDI import *
|
||||
from XendTask import XendTask
|
||||
from XendStorageRepository import XendStorageRepository
|
||||
from XendStateStore import XendStateStore
|
||||
from XendOptions import instance as xendoptions
|
||||
|
||||
MB = 1024 * 1024
|
||||
|
||||
@@ -58,8 +58,7 @@ class XendLocalStorageRepo(XendStorageRepository):
|
||||
"""
|
||||
|
||||
XendStorageRepository.__init__(self, sr_uuid, sr_type,
|
||||
name_label, name_description,
|
||||
'/')
|
||||
name_label, name_description)
|
||||
|
||||
self.state = XendStateStore(xendoptions().get_xend_state_path()
|
||||
+ '/local_sr')
|
||||
|
||||
@@ -22,17 +22,18 @@ import xen.lowlevel.xc
|
||||
|
||||
from xen.util import Brctl
|
||||
|
||||
from xen.xend import uuid, arch
|
||||
from xen.xend.XendError import *
|
||||
from xen.xend.XendOptions import instance as xendoptions
|
||||
from xen.xend.XendQCoWStorageRepo import XendQCoWStorageRepo
|
||||
from xen.xend.XendLocalStorageRepo import XendLocalStorageRepo
|
||||
from xen.xend.XendLogging import log
|
||||
from xen.xend.XendPIF import *
|
||||
from xen.xend.XendPIFMetrics import XendPIFMetrics
|
||||
from xen.xend.XendNetwork import *
|
||||
from xen.xend.XendStateStore import XendStateStore
|
||||
from xen.xend.XendMonitor import XendMonitor
|
||||
import uuid, arch
|
||||
import XendPBD
|
||||
from XendError import *
|
||||
from XendOptions import instance as xendoptions
|
||||
from XendQCoWStorageRepo import XendQCoWStorageRepo
|
||||
from XendLocalStorageRepo import XendLocalStorageRepo
|
||||
from XendLogging import log
|
||||
from XendPIF import *
|
||||
from XendPIFMetrics import XendPIFMetrics
|
||||
from XendNetwork import *
|
||||
from XendStateStore import XendStateStore
|
||||
from XendMonitor import XendMonitor
|
||||
|
||||
class XendNode:
|
||||
"""XendNode - Represents a Domain 0 Host."""
|
||||
@@ -193,13 +194,14 @@ class XendNode:
|
||||
saved_srs = self.state_store.load_state('sr')
|
||||
if saved_srs:
|
||||
for sr_uuid, sr_cfg in saved_srs.items():
|
||||
log.error("SAved SRS %s %s", sr_uuid, sr_cfg['type'])
|
||||
if sr_cfg['type'] == 'qcow_file':
|
||||
self.srs[sr_uuid] = XendQCoWStorageRepo(sr_uuid)
|
||||
elif sr_cfg['type'] == 'local_image':
|
||||
elif sr_cfg['type'] == 'local':
|
||||
self.srs[sr_uuid] = XendLocalStorageRepo(sr_uuid)
|
||||
|
||||
# Create missing SRs if they don't exist
|
||||
if not self.get_sr_by_type('local_image'):
|
||||
if not self.get_sr_by_type('local'):
|
||||
image_sr_uuid = uuid.createString()
|
||||
self.srs[image_sr_uuid] = XendLocalStorageRepo(image_sr_uuid)
|
||||
|
||||
@@ -207,6 +209,11 @@ class XendNode:
|
||||
qcow_sr_uuid = uuid.createString()
|
||||
self.srs[qcow_sr_uuid] = XendQCoWStorageRepo(qcow_sr_uuid)
|
||||
|
||||
saved_pbds = self.state_store.load_state('pbd')
|
||||
if saved_pbds:
|
||||
for pbd_uuid, pbd_cfg in saved_pbds.items():
|
||||
pbd_cfg['uuid'] = pbd_uuid
|
||||
XendPBD.XendPBD(pbd_cfg)
|
||||
|
||||
|
||||
def network_create(self, record, persist = True, net_uuid = None):
|
||||
@@ -280,6 +287,7 @@ class XendNode:
|
||||
self.state_store.save_state('cpu', self.cpus)
|
||||
self.save_PIFs()
|
||||
self.save_networks()
|
||||
self.save_PBDs()
|
||||
self.save_SRs()
|
||||
|
||||
def save_PIFs(self):
|
||||
@@ -292,6 +300,11 @@ class XendNode:
|
||||
for k, v in self.networks.items()])
|
||||
self.state_store.save_state('network', net_records)
|
||||
|
||||
def save_PBDs(self):
|
||||
pbd_records = dict([(v.get_uuid(), v.get_record())
|
||||
for v in XendPBD.get_all()])
|
||||
self.state_store.save_state('pbd', pbd_records)
|
||||
|
||||
def save_SRs(self):
|
||||
sr_records = dict([(k, v.get_record(transient = False))
|
||||
for k, v in self.srs.items()])
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#============================================================================
|
||||
# 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) 2007 Xensource Inc.
|
||||
#============================================================================
|
||||
|
||||
|
||||
import uuid
|
||||
from XendLogging import log
|
||||
|
||||
|
||||
attr_inst = ['uuid',
|
||||
'host',
|
||||
'SR',
|
||||
'device_config']
|
||||
attr_ro = attr_inst + ['currently_attached']
|
||||
|
||||
|
||||
_all = {}
|
||||
|
||||
|
||||
def get(ref):
|
||||
return _all[ref]
|
||||
|
||||
|
||||
def get_all():
|
||||
return _all.values()
|
||||
|
||||
|
||||
def get_all_refs():
|
||||
return _all.keys()
|
||||
|
||||
|
||||
def get_by_SR(sr_ref):
|
||||
return [k for (k, v) in _all.items() if v.get_SR() == sr_ref]
|
||||
|
||||
|
||||
class XendPBD:
|
||||
"""Physical block devices."""
|
||||
|
||||
def __init__(self, record):
|
||||
if 'uuid' not in record:
|
||||
record['uuid'] = uuid.createString()
|
||||
|
||||
import XendAPI
|
||||
for v in attr_inst:
|
||||
setattr(self, v, record[v])
|
||||
self.currently_attached = True
|
||||
_all[record['uuid']] = self
|
||||
|
||||
|
||||
def destroy(self):
|
||||
if self.uuid in _all:
|
||||
del _all[self.uuid]
|
||||
|
||||
|
||||
def get_record(self):
|
||||
import XendAPI
|
||||
result = {}
|
||||
for v in attr_ro:
|
||||
result[v] = getattr(self, v)
|
||||
return result
|
||||
|
||||
|
||||
for v in attr_ro:
|
||||
def f(v_):
|
||||
setattr(XendPBD, 'get_' + v_, lambda s: getattr(s, v_))
|
||||
f(v)
|
||||
@@ -29,12 +29,13 @@ import sys
|
||||
import struct
|
||||
|
||||
from xen.util import mkdir
|
||||
from xen.xend import uuid
|
||||
from xen.xend.XendError import XendError
|
||||
from xen.xend.XendVDI import *
|
||||
from xen.xend.XendTask import XendTask
|
||||
from xen.xend.XendStorageRepository import XendStorageRepository
|
||||
from xen.xend.XendOptions import instance as xendoptions
|
||||
import uuid
|
||||
import XendPBD
|
||||
from XendError import XendError
|
||||
from XendVDI import *
|
||||
from XendTask import XendTask
|
||||
from XendStorageRepository import XendStorageRepository
|
||||
from XendOptions import instance as xendoptions
|
||||
|
||||
XEND_STORAGE_NO_MAXIMUM = sys.maxint
|
||||
XEND_STORAGE_QCOW_FILENAME = "%s.qcow"
|
||||
@@ -72,7 +73,6 @@ class XendQCoWStorageRepo(XendStorageRepository):
|
||||
sr_type = "qcow_file",
|
||||
name_label = "QCoW",
|
||||
name_description = "Xend QCoW Storage Repository",
|
||||
location = xendoptions().get_xend_storage_path(),
|
||||
storage_max = XEND_STORAGE_NO_MAXIMUM):
|
||||
"""
|
||||
@keyword storage_max: Maximum disk space to use in bytes.
|
||||
@@ -85,9 +85,9 @@ class XendQCoWStorageRepo(XendStorageRepository):
|
||||
"""
|
||||
|
||||
XendStorageRepository.__init__(self, sr_uuid, sr_type, name_label,
|
||||
name_description, location,
|
||||
storage_max)
|
||||
name_description, storage_max)
|
||||
self.storage_free = 0
|
||||
self.location = xendoptions().get_xend_storage_path()
|
||||
self._refresh()
|
||||
|
||||
def get_record(self, transient = True):
|
||||
@@ -98,8 +98,9 @@ class XendQCoWStorageRepo(XendStorageRepository):
|
||||
'physical_utilisation': self.physical_utilisation,
|
||||
'physical_size': self.physical_size,
|
||||
'type': self.type,
|
||||
'location': self.location,
|
||||
'VDIs': self.images.keys()}
|
||||
'content_type': self.content_type,
|
||||
'VDIs': self.images.keys(),
|
||||
'PBDs': XendPBD.get_by_SR(self.uuid)}
|
||||
|
||||
if self.physical_size == XEND_STORAGE_NO_MAXIMUM:
|
||||
stfs = os.statvfs(self.location)
|
||||
|
||||
@@ -204,7 +204,7 @@ class XendStateStore:
|
||||
if type(val) == dict:
|
||||
for val_uuid in val.keys():
|
||||
val_node = doc.createElement(key)
|
||||
if key == 'other_config':
|
||||
if key in ['other_config', 'device_config']:
|
||||
val_node.setAttribute('key', str(val_uuid))
|
||||
val_node.setAttribute('value', str(val[val_uuid]))
|
||||
else:
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
import threading
|
||||
import sys
|
||||
|
||||
from xen.xend.XendError import XendError
|
||||
from xen.xend.XendVDI import *
|
||||
from XendError import XendError
|
||||
from XendVDI import *
|
||||
import XendPBD
|
||||
|
||||
XEND_STORAGE_NO_MAXIMUM = sys.maxint
|
||||
|
||||
@@ -34,7 +35,6 @@ class XendStorageRepository:
|
||||
sr_type = "unknown",
|
||||
name_label = 'Unknown',
|
||||
name_description = 'Not Implemented',
|
||||
location = '',
|
||||
storage_max = XEND_STORAGE_NO_MAXIMUM):
|
||||
"""
|
||||
@keyword storage_max: Maximum disk space to use in bytes.
|
||||
@@ -49,7 +49,6 @@ class XendStorageRepository:
|
||||
# XenAPI Parameters
|
||||
self.uuid = uuid
|
||||
self.type = sr_type
|
||||
self.location = location
|
||||
self.name_label = name_label
|
||||
self.name_description = name_description
|
||||
self.images = {}
|
||||
@@ -57,6 +56,7 @@ class XendStorageRepository:
|
||||
self.physical_size = storage_max
|
||||
self.physical_utilisation = 0
|
||||
self.virtual_allocation = 0
|
||||
self.content_type = ''
|
||||
|
||||
self.lock = threading.RLock()
|
||||
|
||||
@@ -68,9 +68,10 @@ class XendStorageRepository:
|
||||
'physical_utilisation': self.physical_utilisation,
|
||||
'physical_size': self.physical_size,
|
||||
'type': self.type,
|
||||
'location': self.location,
|
||||
'content_type': self.content_type,
|
||||
'VDIs': self.images.keys()}
|
||||
|
||||
if not transient:
|
||||
retval ['PBDs'] = XendPBD.get_by_SR(self.uuid)
|
||||
return retval
|
||||
|
||||
|
||||
|
||||