# HG changeset patch
# User Ewan Mellor <ewan@xxxxxxxxxxxxx>
# Date 1174391144 0
# Node ID e2f302488983548285f25f4e8927f1a456188c31
# Parent dace880e871a22883f61a3fdaeafae7fdd51ba58
Add VBD.runtime_properties dictionary, and use that to implement xm block-list
through the Xen-API. Implement xm block-attach and xm block-detach also.
Signed-off-by: Tom Wilkie <tom.wilkie@xxxxxxxxx>
---
tools/python/xen/xend/XendAPI.py | 61 ++++++++++++++++-----
tools/python/xen/xend/XendVDI.py | 10 +++
tools/python/xen/xm/main.py | 101 +++++++++++++++++++++++++++++------
tools/python/xen/xm/xenapi_create.py | 6 --
4 files changed, 145 insertions(+), 33 deletions(-)
diff -r dace880e871a -r e2f302488983 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py Tue Mar 20 11:44:13 2007 +0000
+++ b/tools/python/xen/xend/XendAPI.py Tue Mar 20 11:45:44 2007 +0000
@@ -35,6 +35,9 @@ from xen.xend.XendVMMetrics import XendV
from xen.xend.XendAPIConstants import *
from xen.util.xmlrpclib2 import stringify
+
+from xen.util.blkif import blkdev_name_to_number
+
AUTH_NONE = 'none'
AUTH_PAM = 'pam'
@@ -1555,7 +1558,8 @@ class XendAPI(object):
# Xen API: Class VBD
# ----------------------------------------------------------------
- VBD_attr_ro = ['metrics']
+ VBD_attr_ro = ['metrics',
+ 'runtime_properties']
VBD_attr_rw = ['VM',
'VDI',
'device',
@@ -1596,23 +1600,28 @@ class XendAPI(object):
# class methods
def VBD_create(self, session, vbd_struct):
xendom = XendDomain.instance()
+ xennode = XendNode.instance()
+
if not xendom.is_valid_vm(vbd_struct['VM']):
return xen_api_error(['HANDLE_INVALID', 'VM', vbd_struct['VM']])
dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
- vbd_ref = ''
+ vdi = xennode.get_vdi_by_uuid(vbd_struct['VDI'])
+ if not vdi:
+ return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
+
+ # new VBD via VDI/SR
+ vdi_image = vdi.get_location()
+
try:
- # new VBD via VDI/SR
- vdi_ref = vbd_struct.get('VDI')
- vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
- if not vdi:
- return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
- vdi_image = vdi.get_location()
vbd_ref = XendTask.log_progress(0, 100,
dom.create_vbd,
vbd_struct, vdi_image)
- except XendError:
- return xen_api_todo()
+ except XendError, e:
+ log.exception("Error in VBD_create")
+ return xen_api_error(['INTERNAL_ERROR', str(e)])
+
+ vdi.addVBD(vbd_ref)
xendom.managed_config_save(dom)
return xen_api_success(vbd_ref)
@@ -1624,7 +1633,14 @@ class XendAPI(object):
if not vm:
return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
+ vdi_ref = XendDomain.instance()\
+ .get_dev_property_by_uuid('vbd', vbd_ref, "VDI")
+ vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
+
XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref)
+
+ vdi.removeVBD(vbd_ref)
+
return xen_api_success_void()
def _VBD_get(self, vbd_ref, prop):
@@ -1635,6 +1651,26 @@ class XendAPI(object):
# attributes (ro)
def VBD_get_metrics(self, _, vbd_ref):
return xen_api_success(vbd_ref)
+
+ def VBD_get_runtime_properties(self, _, vbd_ref):
+ xendom = XendDomain.instance()
+ dominfo = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
+ device = dominfo.get_dev_config_by_uuid('vbd', vbd_ref)
+ devid = int(device['id'])
+ device_sxps = dominfo.getDeviceSxprs('vbd')
+
+ log.debug("VBD_get_runtime_properties devid: %i device_sxps: %s",
+ devid, device_sxps)
+
+ device_dicts = [dict(device_sxp[1][1:]) for device_sxp in device_sxps]
+
+ device_dict = [device_dict
+ for device_dict in device_dicts
+ if int(device_dict['virtual-device']) == devid][0]
+
+ log.debug("VBD_get_runtime_properties device_dict: %s", device_dict)
+
+ return xen_api_success(device_dict)
# attributes (rw)
def VBD_get_VM(self, session, vbd_ref):
@@ -1828,7 +1864,8 @@ class XendAPI(object):
return XendNode.instance().get_vdi_by_uuid(ref)
def VDI_get_VBDs(self, session, vdi_ref):
- return xen_api_todo()
+ vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
+ return xen_api_success(vdi.getVBDs())
def VDI_get_physical_utilisation(self, session, vdi_ref):
return xen_api_success(self._get_VDI(vdi_ref).
@@ -1898,7 +1935,7 @@ class XendAPI(object):
'name_label': image.name_label,
'name_description': image.name_description,
'SR': image.sr_uuid,
- 'VBDs': [], # TODO
+ 'VBDs': image.getVBDs(),
'virtual_size': image.virtual_size,
'physical_utilisation': image.physical_utilisation,
'type': image.type,
diff -r dace880e871a -r e2f302488983 tools/python/xen/xend/XendVDI.py
--- a/tools/python/xen/xend/XendVDI.py Tue Mar 20 11:44:13 2007 +0000
+++ b/tools/python/xen/xend/XendVDI.py Tue Mar 20 11:45:44 2007 +0000
@@ -72,6 +72,16 @@ class XendVDI(AutoSaveObject):
self.read_only = False
self.type = "system"
self.other_config = {}
+ self.vbds = []
+
+ def addVBD(self, vbd_ref):
+ self.vbds.append(vbd_ref)
+
+ def removeVBD(self, vbd_ref):
+ self.vbds.remove(vbd_ref)
+
+ def getVBDs(self):
+ return self.vbds
def load_config_dict(self, cfg):
"""Loads configuration into the object from a dict.
diff -r dace880e871a -r e2f302488983 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Tue Mar 20 11:44:13 2007 +0000
+++ b/tools/python/xen/xm/main.py Tue Mar 20 11:45:44 2007 +0000
@@ -33,7 +33,6 @@ import socket
import socket
import traceback
import xmlrpclib
-import traceback
import time
import datetime
from select import select
@@ -50,6 +49,7 @@ from xen.xm.opts import OptionError, Opt
from xen.xm.opts import OptionError, Opts, wrap, set_true
from xen.xm import console
from xen.util.xmlrpclib2 import ServerProxy
+
import XenAPI
@@ -492,6 +492,14 @@ def usage(cmd = None):
#
####################################################################
+def get_default_SR():
+ return [sr_ref
+ for sr_ref in server.xenapi.SR.get_all()
+ if server.xenapi.SR.get_type(sr_ref) == "local"][0]
+
+def map2sxp(m):
+ return [[k, m[k]] for k in m.keys()]
+
def arg_check(args, name, lo, hi = -1):
n = len([i for i in args if i != '--'])
@@ -675,9 +683,6 @@ def xm_restore(args):
def getDomains(domain_names, state, full = 0):
if serverType == SERVER_XEN_API:
- def map2sxp(m):
- return ["domain"] + [[k, m[k]] for k in m.keys()]
-
doms_sxp = []
doms_dict = []
dom_refs = server.xenapi.VM.get_all()
@@ -691,11 +696,11 @@ def getDomains(domain_names, state, full
'state': '-----',
'cpu_time': dom_metrics['vcpus_utilisation']})
- doms_sxp.append(map2sxp(dom_rec))
+ doms_sxp.append(['domain'] + map2sxp(dom_rec))
doms_dict.append(dom_rec)
if domain_names:
- doms = [map2sxp(dom) for dom in doms_dict
+ doms = [['domain'] + map2sxp(dom) for dom in doms_dict
if dom["name"] in domain_names]
if len(doms) > 0:
@@ -1689,12 +1694,20 @@ def xm_block_list(args):
(use_long, params) = arg_check_for_resource_list(args, "block-list")
dom = params[0]
+
+ if serverType == SERVER_XEN_API:
+ vbd_refs = server.xenapi.VM.get_VBDs(get_single_vm(dom))
+ vbd_properties = \
+ map(server.xenapi.VBD.get_runtime_properties, vbd_refs)
+ devs = map(lambda x: [x['virtual-device'], map2sxp(x)], vbd_properties)
+ else:
+ devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
+
if use_long:
- devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
map(PrettyPrint.prettyprint, devs)
else:
hdr = 0
- for x in server.xend.domain.getDeviceSxprs(dom, 'vbd'):
+ for x in devs:
if hdr == 0:
print 'Vdev BE handle state evt-ch ring-ref BE-path'
hdr = 1
@@ -1767,8 +1780,45 @@ def xm_block_attach(args):
def xm_block_attach(args):
arg_check(args, 'block-attach', 4, 5)
- (dom, vbd) = parse_block_configuration(args)
- server.xend.domain.device_create(dom, vbd)
+ if serverType == SERVER_XEN_API:
+ dom = args[0]
+ uname = args[1]
+ dev = args[2]
+ mode = args[3]
+
+ # First create new VDI
+ vdi_record = {
+ "name_label": "vdi" + str(uname.__hash__()),
+ "name_description": "",
+ "SR": get_default_SR(),
+ "virtual_size": 0,
+ "sector_size": 512,
+ "type": "system",
+ "sharable": False,
+ "read_only": mode!="w",
+ "other_config": {"location": uname}
+ }
+
+ vdi_ref = server.xenapi.VDI.create(vdi_record)
+
+ # Now create new VBD
+
+ vbd_record = {
+ "VM": get_single_vm(dom),
+ "VDI": vdi_ref,
+ "device": dev,
+ "bootable": True,
+ "mode": mode=="w" and "RW" or "RO",
+ "type": "Disk",
+ "qos_algorithm_type": "",
+ "qos_algorithm_params": {}
+ }
+
+ server.xenapi.VBD.create(vbd_record)
+
+ else:
+ (dom, vbd) = parse_block_configuration(args)
+ server.xend.domain.device_create(dom, vbd)
def xm_block_configure(args):
@@ -1814,13 +1864,30 @@ def detach(args, command, deviceClass):
def xm_block_detach(args):
- try:
- detach(args, 'block-detach', 'vbd')
- return
- except:
- pass
- detach(args, 'block-detach', 'tap')
-
+ if serverType == SERVER_XEN_API:
+ arg_check(args, "xm_block_detach", 2, 3)
+ dom = args[0]
+ dev = args[1]
+ vbd_refs = server.xenapi.VM.get_VBDs(get_single_vm(dom))
+ vbd_refs = [vbd_ref for vbd_ref in vbd_refs
+ if server.xenapi.VBD.get_device(vbd_ref) == dev]
+ if len(vbd_refs) > 0:
+ vbd_ref = vbd_refs[0]
+ vdi_ref = server.xenapi.VBD.get_VDI(vbd_ref)
+
+ server.xenapi.VBD.destroy(vbd_ref)
+
+ if len(server.xenapi.VDI.get_VBDs(vdi_ref)) <= 0:
+ server.xenapi.VDI.destroy(vdi_ref)
+ else:
+ print "Cannot find device '%s' in domain '%s'" % (dev,dom)
+ else:
+ try:
+ detach(args, 'block-detach', 'vbd')
+ return
+ except:
+ pass
+ detach(args, 'block-detach', 'tap')
def xm_network_detach(args):
detach(args, 'network-detach', 'vif')
diff -r dace880e871a -r e2f302488983 tools/python/xen/xm/xenapi_create.py
--- a/tools/python/xen/xm/xenapi_create.py Tue Mar 20 11:44:13 2007 +0000
+++ b/tools/python/xen/xm/xenapi_create.py Tue Mar 20 11:45:44 2007 +0000
@@ -18,7 +18,7 @@
"""Domain creation using new XenAPI
"""
-from xen.xm.main import server
+from xen.xm.main import server, get_default_SR
from xml.dom.minidom import parse, getDOMImplementation
from xml.dom.ext import PrettyPrint
from xml.parsers.xmlproc import xmlproc, xmlval, xmldtd
@@ -71,9 +71,7 @@ class xenapi_create:
class xenapi_create:
def __init__(self):
- self.DEFAULT_STORAGE_REPOSITORY = [sr_ref
- for sr_ref in server.xenapi.SR.get_all()
- if server.xenapi.SR.get_type(sr_ref) == "local"][0]
+ self.DEFAULT_STORAGE_REPOSITORY = get_default_SR()
self.dtd = "/usr/lib/python/xen/xm/create.dtd"
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|