Merge "Fix concurrency of XenAPI sessions"
This commit is contained in:
@@ -1072,8 +1072,11 @@ class FakeSession(object):
|
||||
'free-computed': 40}
|
||||
return json.dumps({'host_memory': vm})
|
||||
|
||||
def get_xenapi(self):
|
||||
return FakeXenApi()
|
||||
def call_xenapi(self, method, *args):
|
||||
f = FakeXenApi()
|
||||
for m in method.split('.'):
|
||||
f = getattr(f, m)
|
||||
return f(*args)
|
||||
|
||||
|
||||
class HostStateTestCase(test.TestCase):
|
||||
|
||||
@@ -38,7 +38,7 @@ def stubout_instance_snapshot(stubs):
|
||||
sr_ref = "fakesr"
|
||||
vdi_ref = create_vdi(name_label=name_label, read_only=False,
|
||||
sr_ref=sr_ref, sharable=False)
|
||||
vdi_rec = session.get_xenapi().VDI.get_record(vdi_ref)
|
||||
vdi_rec = session.call_xenapi("VDI.get_record", vdi_ref)
|
||||
vdi_uuid = vdi_rec['uuid']
|
||||
return [dict(vdi_type='os', vdi_uuid=vdi_uuid)]
|
||||
|
||||
@@ -307,7 +307,7 @@ def stub_out_migration_methods(stubs):
|
||||
def fake_get_vdi(cls, session, vm_ref):
|
||||
vdi_ref = fake.create_vdi(name_label='derp', read_only=False,
|
||||
sr_ref='herp', sharable=False)
|
||||
vdi_rec = session.get_xenapi().VDI.get_record(vdi_ref)
|
||||
vdi_rec = session.call_xenapi("VDI.get_record", vdi_ref)
|
||||
return vdi_ref, {'uuid': vdi_rec['uuid'], }
|
||||
|
||||
def fake_shutdown(self, inst, vm, hard=True):
|
||||
|
||||
@@ -205,8 +205,8 @@ class VMHelper(HelperBase):
|
||||
mem = long(instance_type['memory_mb']) * 1024 * 1024
|
||||
#get free memory from host
|
||||
host = session.get_xenapi_host()
|
||||
host_free_mem = long(session.get_xenapi().host.
|
||||
compute_free_memory(host))
|
||||
host_free_mem = long(session.call_xenapi("host.compute_free_memory",
|
||||
host))
|
||||
return host_free_mem >= mem
|
||||
|
||||
@classmethod
|
||||
@@ -260,11 +260,11 @@ class VMHelper(HelperBase):
|
||||
@classmethod
|
||||
def find_vbd_by_number(cls, session, vm_ref, number):
|
||||
"""Get the VBD reference from the device number"""
|
||||
vbd_refs = session.get_xenapi().VM.get_VBDs(vm_ref)
|
||||
vbd_refs = session.call_xenapi("VM.get_VBDs", vm_ref)
|
||||
if vbd_refs:
|
||||
for vbd_ref in vbd_refs:
|
||||
try:
|
||||
vbd_rec = session.get_xenapi().VBD.get_record(vbd_ref)
|
||||
vbd_rec = session.call_xenapi("VBD.get_record", vbd_ref)
|
||||
if vbd_rec['userdevice'] == str(number):
|
||||
return vbd_ref
|
||||
except cls.XenAPI.Failure, exc:
|
||||
@@ -303,7 +303,7 @@ class VMHelper(HelperBase):
|
||||
@classmethod
|
||||
def create_vdi(cls, session, sr_ref, name_label, virtual_size, read_only):
|
||||
"""Create a VDI record and returns its reference."""
|
||||
vdi_ref = session.get_xenapi().VDI.create(
|
||||
vdi_ref = session.call_xenapi("VDI.create",
|
||||
{'name_label': name_label,
|
||||
'name_description': '',
|
||||
'SR': sr_ref,
|
||||
@@ -322,18 +322,18 @@ class VMHelper(HelperBase):
|
||||
|
||||
@classmethod
|
||||
def set_vdi_name_label(cls, session, vdi_uuid, name_label):
|
||||
vdi_ref = session.get_xenapi().VDI.get_by_uuid(vdi_uuid)
|
||||
session.get_xenapi().VDI.set_name_label(vdi_ref, name_label)
|
||||
vdi_ref = session.call_xenapi("VDI.get_by_uuid", vdi_uuid)
|
||||
session.call_xenapi("VDI.set_name_label", vdi_ref, name_label)
|
||||
|
||||
@classmethod
|
||||
def get_vdi_for_vm_safely(cls, session, vm_ref):
|
||||
"""Retrieves the primary VDI for a VM"""
|
||||
vbd_refs = session.get_xenapi().VM.get_VBDs(vm_ref)
|
||||
vbd_refs = session.call_xenapi("VM.get_VBDs", vm_ref)
|
||||
for vbd in vbd_refs:
|
||||
vbd_rec = session.get_xenapi().VBD.get_record(vbd)
|
||||
vbd_rec = session.call_xenapi("VBD.get_record", vbd)
|
||||
# Convention dictates the primary VDI will be userdevice 0
|
||||
if vbd_rec['userdevice'] == '0':
|
||||
vdi_rec = session.get_xenapi().VDI.get_record(vbd_rec['VDI'])
|
||||
vdi_rec = session.call_xenapi("VDI.get_record", vbd_rec['VDI'])
|
||||
return vbd_rec['VDI'], vdi_rec
|
||||
raise exception.Error(_("No primary VDI found for"
|
||||
"%(vm_ref)s") % locals())
|
||||
@@ -377,7 +377,7 @@ class VMHelper(HelperBase):
|
||||
snapshots or by restoring an image in the DISK_VHD format.
|
||||
"""
|
||||
sr_ref = safe_find_sr(session)
|
||||
sr_rec = session.get_xenapi().SR.get_record(sr_ref)
|
||||
sr_rec = session.call_xenapi("SR.get_record", sr_ref)
|
||||
sr_uuid = sr_rec["uuid"]
|
||||
return os.path.join(FLAGS.xenapi_sr_base_path, sr_uuid)
|
||||
|
||||
@@ -602,9 +602,9 @@ w
|
||||
os_vdi_uuid = vdis[0]['vdi_uuid']
|
||||
|
||||
# Set the name-label to ease debugging
|
||||
vdi_ref = session.get_xenapi().VDI.get_by_uuid(os_vdi_uuid)
|
||||
vdi_ref = session.call_xenapi("VDI.get_by_uuid", os_vdi_uuid)
|
||||
primary_name_label = instance.name
|
||||
session.get_xenapi().VDI.set_name_label(vdi_ref, primary_name_label)
|
||||
session.call_xenapi("VDI.set_name_label", vdi_ref, primary_name_label)
|
||||
|
||||
cls._check_vdi_size(context, session, instance, os_vdi_uuid)
|
||||
return vdis
|
||||
@@ -696,7 +696,7 @@ w
|
||||
# If anything goes wrong, we need to remember its uuid.
|
||||
try:
|
||||
filename = None
|
||||
vdi_uuid = session.get_xenapi().VDI.get_uuid(vdi_ref)
|
||||
vdi_uuid = session.call_xenapi("VDI.get_uuid", vdi_ref)
|
||||
|
||||
with vdi_attached_here(session, vdi_ref, read_only=False) as dev:
|
||||
_stream_disk(dev, image_type, virtual_size, image_file)
|
||||
@@ -713,7 +713,7 @@ w
|
||||
task = session.async_call_plugin('glance', fn, args)
|
||||
filename = session.wait_for_task(task, instance_id)
|
||||
# Remove the VDI as it is not needed anymore.
|
||||
session.get_xenapi().VDI.destroy(vdi_ref)
|
||||
session.call_xenapi("VDI.destroy", vdi_ref)
|
||||
LOG.debug(_("Kernel/Ramdisk VDI %s destroyed"), vdi_ref)
|
||||
return [dict(vdi_type=ImageType.to_string(image_type),
|
||||
vdi_uuid=None,
|
||||
@@ -828,12 +828,12 @@ w
|
||||
|
||||
@classmethod
|
||||
def set_vm_name_label(cls, session, vm_ref, name_label):
|
||||
session.get_xenapi().VM.set_name_label(vm_ref, name_label)
|
||||
session.call_xenapi("VM.set_name_label", vm_ref, name_label)
|
||||
|
||||
@classmethod
|
||||
def lookup(cls, session, name_label):
|
||||
"""Look the instance up and return it if available"""
|
||||
vm_refs = session.get_xenapi().VM.get_by_name_label(name_label)
|
||||
vm_refs = session.call_xenapi("VM.get_by_name_label", name_label)
|
||||
n = len(vm_refs)
|
||||
if n == 0:
|
||||
return None
|
||||
@@ -847,14 +847,14 @@ w
|
||||
"""Look for the VDIs that are attached to the VM"""
|
||||
# Firstly we get the VBDs, then the VDIs.
|
||||
# TODO(Armando): do we leave the read-only devices?
|
||||
vbd_refs = session.get_xenapi().VM.get_VBDs(vm_ref)
|
||||
vbd_refs = session.call_xenapi("VM.get_VBDs", vm_ref)
|
||||
vdi_refs = []
|
||||
if vbd_refs:
|
||||
for vbd_ref in vbd_refs:
|
||||
try:
|
||||
vdi_ref = session.get_xenapi().VBD.get_VDI(vbd_ref)
|
||||
vdi_ref = session.call_xenapi("VBD.get_VDI", vbd_ref)
|
||||
# Test valid VDI
|
||||
record = session.get_xenapi().VDI.get_record(vdi_ref)
|
||||
record = session.call_xenapi("VDI.get_record", vdi_ref)
|
||||
LOG.debug(_('VDI %s is still available'), record['uuid'])
|
||||
except cls.XenAPI.Failure, exc:
|
||||
LOG.exception(exc)
|
||||
@@ -884,7 +884,7 @@ w
|
||||
|
||||
@classmethod
|
||||
def lookup_kernel_ramdisk(cls, session, vm):
|
||||
vm_rec = session.get_xenapi().VM.get_record(vm)
|
||||
vm_rec = session.call_xenapi("VM.get_record", vm)
|
||||
if 'PV_kernel' in vm_rec and 'PV_ramdisk' in vm_rec:
|
||||
return (vm_rec['PV_kernel'], vm_rec['PV_ramdisk'])
|
||||
else:
|
||||
@@ -908,7 +908,7 @@ w
|
||||
"""Compile VM diagnostics data"""
|
||||
try:
|
||||
host = session.get_xenapi_host()
|
||||
host_ip = session.get_xenapi().host.get_record(host)["address"]
|
||||
host_ip = session.call_xenapi("host.get_record", host)["address"]
|
||||
except (cls.XenAPI.Failure, KeyError) as e:
|
||||
return {"Unable to retrieve diagnostics": e}
|
||||
|
||||
@@ -936,7 +936,7 @@ w
|
||||
start_time = int(start_time)
|
||||
try:
|
||||
host = session.get_xenapi_host()
|
||||
host_ip = session.get_xenapi().host.get_record(host)["address"]
|
||||
host_ip = session.call_xenapi("host.get_record", host)["address"]
|
||||
except (cls.XenAPI.Failure, KeyError) as e:
|
||||
raise exception.CouldNotFetchMetrics()
|
||||
|
||||
@@ -1066,8 +1066,8 @@ def get_vhd_parent(session, vdi_rec):
|
||||
"""
|
||||
if 'vhd-parent' in vdi_rec['sm_config']:
|
||||
parent_uuid = vdi_rec['sm_config']['vhd-parent']
|
||||
parent_ref = session.get_xenapi().VDI.get_by_uuid(parent_uuid)
|
||||
parent_rec = session.get_xenapi().VDI.get_record(parent_ref)
|
||||
parent_ref = session.call_xenapi("VDI.get_by_uuid", parent_uuid)
|
||||
parent_rec = session.call_xenapi("VDI.get_record", parent_ref)
|
||||
vdi_uuid = vdi_rec['uuid']
|
||||
LOG.debug(_("VHD %(vdi_uuid)s has parent %(parent_ref)s") % locals())
|
||||
return parent_ref, parent_rec
|
||||
@@ -1076,7 +1076,7 @@ def get_vhd_parent(session, vdi_rec):
|
||||
|
||||
|
||||
def get_vhd_parent_uuid(session, vdi_ref):
|
||||
vdi_rec = session.get_xenapi().VDI.get_record(vdi_ref)
|
||||
vdi_rec = session.call_xenapi("VDI.get_record", vdi_ref)
|
||||
ret = get_vhd_parent(session, vdi_rec)
|
||||
if ret:
|
||||
parent_ref, parent_rec = ret
|
||||
@@ -1089,8 +1089,8 @@ def walk_vdi_chain(session, vdi_uuid):
|
||||
"""Yield vdi_recs for each element in a VDI chain"""
|
||||
# TODO(jk0): perhaps make get_vhd_parent use this
|
||||
while True:
|
||||
vdi_ref = session.get_xenapi().VDI.get_by_uuid(vdi_uuid)
|
||||
vdi_rec = session.get_xenapi().VDI.get_record(vdi_ref)
|
||||
vdi_ref = session.call_xenapi("VDI.get_by_uuid", vdi_uuid)
|
||||
vdi_rec = session.call_xenapi("VDI.get_record", vdi_ref)
|
||||
yield vdi_rec
|
||||
|
||||
parent_uuid = vdi_rec['sm_config'].get('vhd-parent')
|
||||
@@ -1153,14 +1153,14 @@ def safe_find_sr(session):
|
||||
def find_sr(session):
|
||||
"""Return the storage repository to hold VM images"""
|
||||
host = session.get_xenapi_host()
|
||||
sr_refs = session.get_xenapi().SR.get_all()
|
||||
sr_refs = session.call_xenapi("SR.get_all")
|
||||
for sr_ref in sr_refs:
|
||||
sr_rec = session.get_xenapi().SR.get_record(sr_ref)
|
||||
sr_rec = session.call_xenapi("SR.get_record", sr_ref)
|
||||
if not ('i18n-key' in sr_rec['other_config'] and
|
||||
sr_rec['other_config']['i18n-key'] == 'local-storage'):
|
||||
continue
|
||||
for pbd_ref in sr_rec['PBDs']:
|
||||
pbd_rec = session.get_xenapi().PBD.get_record(pbd_ref)
|
||||
pbd_rec = session.call_xenapi("PBD.get_record", pbd_ref)
|
||||
if pbd_rec['host'] == host:
|
||||
return sr_ref
|
||||
return None
|
||||
@@ -1179,9 +1179,9 @@ def safe_find_iso_sr(session):
|
||||
def find_iso_sr(session):
|
||||
"""Return the storage repository to hold ISO images"""
|
||||
host = session.get_xenapi_host()
|
||||
sr_refs = session.get_xenapi().SR.get_all()
|
||||
sr_refs = session.call_xenapi("SR.get_all")
|
||||
for sr_ref in sr_refs:
|
||||
sr_rec = session.get_xenapi().SR.get_record(sr_ref)
|
||||
sr_rec = session.call_xenapi("SR.get_record", sr_ref)
|
||||
|
||||
LOG.debug(_("ISO: looking at SR %(sr_rec)s") % locals())
|
||||
if not sr_rec['content_type'] == 'iso':
|
||||
@@ -1198,7 +1198,7 @@ def find_iso_sr(session):
|
||||
LOG.debug(_("ISO: SR MATCHing our criteria"))
|
||||
for pbd_ref in sr_rec['PBDs']:
|
||||
LOG.debug(_("ISO: ISO, looking to see if it is host local"))
|
||||
pbd_rec = session.get_xenapi().PBD.get_record(pbd_ref)
|
||||
pbd_rec = session.call_xenapi("PBD.get_record", pbd_ref)
|
||||
pbd_rec_host = pbd_rec['host']
|
||||
LOG.debug(_("ISO: PBD matching, want %(pbd_rec)s, have %(host)s") %
|
||||
locals())
|
||||
@@ -1257,14 +1257,14 @@ def vdi_attached_here(session, vdi_ref, read_only=False):
|
||||
vbd_rec['qos_algorithm_params'] = {}
|
||||
vbd_rec['qos_supported_algorithms'] = []
|
||||
LOG.debug(_('Creating VBD for VDI %s ... '), vdi_ref)
|
||||
vbd_ref = session.get_xenapi().VBD.create(vbd_rec)
|
||||
vbd_ref = session.call_xenapi("VBD.create", vbd_rec)
|
||||
LOG.debug(_('Creating VBD for VDI %s done.'), vdi_ref)
|
||||
try:
|
||||
LOG.debug(_('Plugging VBD %s ... '), vbd_ref)
|
||||
session.get_xenapi().VBD.plug(vbd_ref)
|
||||
session.call_xenapi("VBD.plug", vbd_ref)
|
||||
try:
|
||||
LOG.debug(_('Plugging VBD %s done.'), vbd_ref)
|
||||
orig_dev = session.get_xenapi().VBD.get_device(vbd_ref)
|
||||
orig_dev = session.call_xenapi("VBD.get_device", vbd_ref)
|
||||
LOG.debug(_('VBD %(vbd_ref)s plugged as %(orig_dev)s') % locals())
|
||||
dev = remap_vbd_dev(orig_dev)
|
||||
if dev != orig_dev:
|
||||
@@ -1280,7 +1280,7 @@ def vdi_attached_here(session, vdi_ref, read_only=False):
|
||||
LOG.debug(_('Destroying VBD for VDI %s ... '), vdi_ref)
|
||||
vbd_unplug_with_retry(session, vbd_ref)
|
||||
finally:
|
||||
ignore_failure(session.get_xenapi().VBD.destroy, vbd_ref)
|
||||
ignore_failure(session.call_xenapi, "VBD.destroy", vbd_ref)
|
||||
LOG.debug(_('Destroying VBD for VDI %s done.'), vdi_ref)
|
||||
|
||||
|
||||
@@ -1292,7 +1292,7 @@ def vbd_unplug_with_retry(session, vbd_ref):
|
||||
# FIXME(sirp): We can use LoopingCall here w/o blocking sleep()
|
||||
while True:
|
||||
try:
|
||||
session.get_xenapi().VBD.unplug(vbd_ref)
|
||||
session.call_xenapi("VBD.unplug", vbd_ref)
|
||||
LOG.debug(_('VBD.unplug successful first time.'))
|
||||
return
|
||||
except VMHelper.XenAPI.Failure, e:
|
||||
@@ -1325,7 +1325,7 @@ def get_this_vm_uuid():
|
||||
|
||||
|
||||
def get_this_vm_ref(session):
|
||||
return session.get_xenapi().VM.get_by_uuid(get_this_vm_uuid())
|
||||
return session.call_xenapi("VM.get_by_uuid", get_this_vm_uuid())
|
||||
|
||||
|
||||
def _is_vdi_pv(dev):
|
||||
|
||||
@@ -97,8 +97,8 @@ class VMOps(object):
|
||||
# TODO(justinsb): Should we just always use the details method?
|
||||
# Seems to be the same number of API calls..
|
||||
vm_refs = []
|
||||
for vm_ref in self._session.get_xenapi().VM.get_all():
|
||||
vm_rec = self._session.get_xenapi().VM.get_record(vm_ref)
|
||||
for vm_ref in self._session.call_xenapi("VM.get_all"):
|
||||
vm_rec = self._session.call_xenapi("VM.get_record", vm_ref)
|
||||
if not vm_rec["is_a_template"] and not vm_rec["is_control_domain"]:
|
||||
vm_refs.append(vm_rec["name_label"])
|
||||
return vm_refs
|
||||
@@ -106,8 +106,8 @@ class VMOps(object):
|
||||
def list_instances_detail(self):
|
||||
"""List VM instances, returning InstanceInfo objects."""
|
||||
instance_infos = []
|
||||
for vm_ref in self._session.get_xenapi().VM.get_all():
|
||||
vm_rec = self._session.get_xenapi().VM.get_record(vm_ref)
|
||||
for vm_ref in self._session.call_xenapi("VM.get_all"):
|
||||
vm_rec = self._session.call_xenapi("VM.get_record", vm_ref)
|
||||
if not vm_rec["is_a_template"] and not vm_rec["is_control_domain"]:
|
||||
name = vm_rec["name_label"]
|
||||
|
||||
@@ -519,7 +519,7 @@ class VMOps(object):
|
||||
obj = None
|
||||
try:
|
||||
# check for opaque ref
|
||||
obj = self._session.get_xenapi().VM.get_uuid(instance_or_vm)
|
||||
obj = self._session.call_xenapi("VM.get_uuid", instance_or_vm)
|
||||
return instance_or_vm
|
||||
except self.XenAPI.Failure:
|
||||
# wasn't an opaque ref, can be an instance name
|
||||
@@ -788,7 +788,7 @@ class VMOps(object):
|
||||
return resp['message'].replace('\\r\\n', '')
|
||||
|
||||
vm_ref = self._get_vm_opaque_ref(instance)
|
||||
vm_rec = self._session.get_xenapi().VM.get_record(vm_ref)
|
||||
vm_rec = self._session.call_xenapi("VM.get_record", vm_ref)
|
||||
|
||||
domid = vm_rec['domid']
|
||||
|
||||
@@ -798,7 +798,7 @@ class VMOps(object):
|
||||
if ret:
|
||||
return ret
|
||||
|
||||
vm_rec = self._session.get_xenapi().VM.get_record(vm_ref)
|
||||
vm_rec = self._session.call_xenapi("VM.get_record", vm_ref)
|
||||
if vm_rec['domid'] != domid:
|
||||
LOG.info(_('domid changed from %(olddomid)s to '
|
||||
'%(newdomid)s') % {
|
||||
@@ -913,8 +913,8 @@ class VMOps(object):
|
||||
|
||||
We use the second VBD here because swap is first with the root file
|
||||
system coming in second."""
|
||||
vbd_ref = self._session.get_xenapi().VM.get_VBDs(vm_ref)[1]
|
||||
vdi_ref = self._session.get_xenapi().VBD.get_record(vbd_ref)["VDI"]
|
||||
vbd_ref = self._session.call_xenapi("VM.get_VBDs", vm_ref)[1]
|
||||
vdi_ref = self._session.call_xenapi("VBD.get_record", vbd_ref)["VDI"]
|
||||
|
||||
return VMHelper.create_vbd(self._session, rescue_vm_ref, vdi_ref, 1,
|
||||
False)
|
||||
@@ -951,9 +951,9 @@ class VMOps(object):
|
||||
|
||||
def _destroy_rescue_vbds(self, rescue_vm_ref):
|
||||
"""Destroys all VBDs tied to a rescue VM."""
|
||||
vbd_refs = self._session.get_xenapi().VM.get_VBDs(rescue_vm_ref)
|
||||
vbd_refs = self._session.call_xenapi("VM.get_VBDs", rescue_vm_ref)
|
||||
for vbd_ref in vbd_refs:
|
||||
vbd_rec = self._session.get_xenapi().VBD.get_record(vbd_ref)
|
||||
vbd_rec = self._session.call_xenapi("VBD.get_record", vbd_ref)
|
||||
if vbd_rec.get("userdevice", None) == "1": # VBD is always 1
|
||||
VMHelper.unplug_vbd(self._session, vbd_ref)
|
||||
VMHelper.destroy_vbd(self._session, vbd_ref)
|
||||
@@ -1147,14 +1147,14 @@ class VMOps(object):
|
||||
|
||||
def _cancel_stale_tasks(self, timeout, task):
|
||||
"""Cancel the given tasks that are older than the given timeout."""
|
||||
task_refs = self._session.get_xenapi().task.get_by_name_label(task)
|
||||
task_refs = self._session.call_xenapi("task.get_by_name_label", task)
|
||||
for task_ref in task_refs:
|
||||
task_rec = self._session.get_xenapi().task.get_record(task_ref)
|
||||
task_rec = self._session.call_xenapi("task.get_record", task_ref)
|
||||
task_created = utils.parse_strtime(task_rec["created"].value,
|
||||
"%Y%m%dT%H:%M:%SZ")
|
||||
|
||||
if utils.is_older_than(task_created, timeout):
|
||||
self._session.get_xenapi().task.cancel(task_ref)
|
||||
self._session.call_xenapi("task.cancel", task_ref)
|
||||
|
||||
def poll_rebooting_instances(self, timeout):
|
||||
"""Look for expirable rebooting instances.
|
||||
@@ -1243,13 +1243,13 @@ class VMOps(object):
|
||||
def get_info(self, instance):
|
||||
"""Return data about VM instance."""
|
||||
vm_ref = self._get_vm_opaque_ref(instance)
|
||||
vm_rec = self._session.get_xenapi().VM.get_record(vm_ref)
|
||||
vm_rec = self._session.call_xenapi("VM.get_record", vm_ref)
|
||||
return VMHelper.compile_info(vm_rec)
|
||||
|
||||
def get_diagnostics(self, instance):
|
||||
"""Return data about VM diagnostics."""
|
||||
vm_ref = self._get_vm_opaque_ref(instance)
|
||||
vm_rec = self._session.get_xenapi().VM.get_record(vm_ref)
|
||||
vm_rec = self._session.call_xenapi("VM.get_record", vm_ref)
|
||||
return VMHelper.compile_diagnostics(self._session, vm_rec)
|
||||
|
||||
def get_all_bw_usage(self, start_time, stop_time=None):
|
||||
@@ -1264,10 +1264,10 @@ class VMOps(object):
|
||||
exc_info=sys.exc_info())
|
||||
bw = {}
|
||||
for uuid, data in metrics.iteritems():
|
||||
vm_ref = self._session.get_xenapi().VM.get_by_uuid(uuid)
|
||||
vm_rec = self._session.get_xenapi().VM.get_record(vm_ref)
|
||||
vm_ref = self._session.call_xenapi("VM.get_by_uuid", uuid)
|
||||
vm_rec = self._session.call_xenapi("VM.get_record", vm_ref)
|
||||
vif_map = {}
|
||||
for vif in [self._session.get_xenapi().VIF.get_record(vrec)
|
||||
for vif in [self._session.call_xenapi("VIF.get_record", vrec)
|
||||
for vrec in vm_rec['VIFs']]:
|
||||
vif_map[vif['device']] = vif['MAC']
|
||||
name = vm_rec['name_label']
|
||||
@@ -1340,7 +1340,7 @@ class VMOps(object):
|
||||
"""
|
||||
if vm_ref:
|
||||
# this function raises if vm_ref is not a vm_opaque_ref
|
||||
self._session.get_xenapi().VM.get_record(vm_ref)
|
||||
self._session.call_xenapi("VM.get_record", vm_ref)
|
||||
else:
|
||||
vm_ref = VMHelper.lookup(self._session, instance.name)
|
||||
logging.debug(_("injecting network info to xs for vm: |%s|"), vm_ref)
|
||||
@@ -1364,7 +1364,7 @@ class VMOps(object):
|
||||
logging.debug(_("creating vif(s) for vm: |%s|"), vm_ref)
|
||||
|
||||
# this function raises if vm_ref is not a vm_opaque_ref
|
||||
self._session.get_xenapi().VM.get_record(vm_ref)
|
||||
self._session.call_xenapi("VM.get_record", vm_ref)
|
||||
|
||||
for device, (network, info) in enumerate(network_info):
|
||||
vif_rec = self.vif_driver.plug(self._session,
|
||||
@@ -1473,7 +1473,7 @@ class VMOps(object):
|
||||
"""
|
||||
instance_id = vm.id
|
||||
vm_ref = vm_ref or self._get_vm_opaque_ref(vm)
|
||||
vm_rec = self._session.get_xenapi().VM.get_record(vm_ref)
|
||||
vm_rec = self._session.call_xenapi("VM.get_record", vm_ref)
|
||||
args = {'dom_id': vm_rec['domid'], 'path': path}
|
||||
args.update(addl_args or {})
|
||||
try:
|
||||
|
||||
@@ -52,7 +52,7 @@ class VolumeHelper(HelperBase):
|
||||
Create an iSCSI storage repository that will be used to mount
|
||||
the volume for the specified instance
|
||||
"""
|
||||
sr_ref = session.get_xenapi().SR.get_by_name_label(label)
|
||||
sr_ref = session.call_xenapi("SR.get_by_name_label", label)
|
||||
if len(sr_ref) == 0:
|
||||
LOG.debug(_('Introducing %s...'), label)
|
||||
record = {}
|
||||
@@ -67,7 +67,7 @@ class VolumeHelper(HelperBase):
|
||||
'port': info['targetPort'],
|
||||
'targetIQN': info['targetIQN']}
|
||||
try:
|
||||
sr_ref = session.get_xenapi().SR.create(
|
||||
sr_ref = session.call_xenapi("SR.create",
|
||||
session.get_xenapi_host(),
|
||||
record,
|
||||
'0', label, description, 'iscsi', '', False, {})
|
||||
@@ -83,8 +83,8 @@ class VolumeHelper(HelperBase):
|
||||
def find_sr_from_vbd(cls, session, vbd_ref):
|
||||
"""Find the SR reference from the VBD reference"""
|
||||
try:
|
||||
vdi_ref = session.get_xenapi().VBD.get_VDI(vbd_ref)
|
||||
sr_ref = session.get_xenapi().VDI.get_SR(vdi_ref)
|
||||
vdi_ref = session.call_xenapi("VBD.get_VDI", vbd_ref)
|
||||
sr_ref = session.call_xenapi("VDI.get_SR", vdi_ref)
|
||||
except cls.XenAPI.Failure, exc:
|
||||
LOG.exception(exc)
|
||||
raise StorageError(_('Unable to find SR from VBD %s') % vbd_ref)
|
||||
@@ -96,18 +96,18 @@ class VolumeHelper(HelperBase):
|
||||
LOG.debug(_("Forgetting SR %s ... "), sr_ref)
|
||||
pbds = []
|
||||
try:
|
||||
pbds = session.get_xenapi().SR.get_PBDs(sr_ref)
|
||||
pbds = session.call_xenapi("SR.get_PBDs", sr_ref)
|
||||
except cls.XenAPI.Failure, exc:
|
||||
LOG.warn(_('Ignoring exception %(exc)s when getting PBDs'
|
||||
' for %(sr_ref)s') % locals())
|
||||
for pbd in pbds:
|
||||
try:
|
||||
session.get_xenapi().PBD.unplug(pbd)
|
||||
session.call_xenapi("PBD.unplug", pbd)
|
||||
except cls.XenAPI.Failure, exc:
|
||||
LOG.warn(_('Ignoring exception %(exc)s when unplugging'
|
||||
' PBD %(pbd)s') % locals())
|
||||
try:
|
||||
session.get_xenapi().SR.forget(sr_ref)
|
||||
session.call_xenapi("SR.forget", sr_ref)
|
||||
LOG.debug(_("Forgetting SR %s done."), sr_ref)
|
||||
except cls.XenAPI.Failure, exc:
|
||||
LOG.warn(_('Ignoring exception %(exc)s when forgetting'
|
||||
@@ -117,19 +117,19 @@ class VolumeHelper(HelperBase):
|
||||
def introduce_vdi(cls, session, sr_ref):
|
||||
"""Introduce VDI in the host"""
|
||||
try:
|
||||
vdi_refs = session.get_xenapi().SR.get_VDIs(sr_ref)
|
||||
vdi_refs = session.call_xenapi("SR.get_VDIs", sr_ref)
|
||||
except cls.XenAPI.Failure, exc:
|
||||
LOG.exception(exc)
|
||||
raise StorageError(_('Unable to introduce VDI on SR %s') % sr_ref)
|
||||
try:
|
||||
vdi_rec = session.get_xenapi().VDI.get_record(vdi_refs[0])
|
||||
vdi_rec = session.call_xenapi("VDI.get_record", vdi_refs[0])
|
||||
except cls.XenAPI.Failure, exc:
|
||||
LOG.exception(exc)
|
||||
raise StorageError(_('Unable to get record'
|
||||
' of VDI %s on') % vdi_refs[0])
|
||||
else:
|
||||
try:
|
||||
return session.get_xenapi().VDI.introduce(
|
||||
return session.call_xenapi("VDI.introduce",
|
||||
vdi_rec['uuid'],
|
||||
vdi_rec['name_label'],
|
||||
vdi_rec['name_description'],
|
||||
|
||||
@@ -57,6 +57,7 @@ reactor thread if the VM.get_by_name_label or VM.get_record calls block.
|
||||
- suffix "_rec" for record objects
|
||||
"""
|
||||
|
||||
import contextlib
|
||||
import json
|
||||
import random
|
||||
import sys
|
||||
@@ -65,6 +66,7 @@ import urlparse
|
||||
import xmlrpclib
|
||||
|
||||
from eventlet import event
|
||||
from eventlet import queue
|
||||
from eventlet import tpool
|
||||
from eventlet import timeout
|
||||
|
||||
@@ -97,6 +99,10 @@ flags.DEFINE_string('xenapi_connection_password',
|
||||
None,
|
||||
'Password for connection to XenServer/Xen Cloud Platform.'
|
||||
' Used only if connection_type=xenapi.')
|
||||
flags.DEFINE_integer('xenapi_connection_concurrent',
|
||||
5,
|
||||
'Maximum number of concurrent XenAPI connections.'
|
||||
' Used only if connection_type=xenapi.')
|
||||
flags.DEFINE_float('xenapi_task_poll_interval',
|
||||
0.5,
|
||||
'The interval used for polling of remote tasks '
|
||||
@@ -401,44 +407,56 @@ class XenAPISession(object):
|
||||
|
||||
def __init__(self, url, user, pw):
|
||||
self.XenAPI = self.get_imported_xenapi()
|
||||
self._session = self._create_session(url)
|
||||
self._sessions = queue.Queue()
|
||||
exception = self.XenAPI.Failure(_("Unable to log in to XenAPI "
|
||||
"(is the Dom0 disk full?)"))
|
||||
with timeout.Timeout(FLAGS.xenapi_login_timeout, exception):
|
||||
self._session.login_with_password(user, pw)
|
||||
for i in xrange(FLAGS.xenapi_connection_concurrent):
|
||||
session = self._create_session(url)
|
||||
with timeout.Timeout(FLAGS.xenapi_login_timeout, exception):
|
||||
session.login_with_password(user, pw)
|
||||
self._sessions.put(session)
|
||||
|
||||
def get_imported_xenapi(self):
|
||||
"""Stubout point. This can be replaced with a mock xenapi module."""
|
||||
return __import__('XenAPI')
|
||||
|
||||
def get_xenapi(self):
|
||||
"""Return the xenapi object"""
|
||||
return self._session.xenapi
|
||||
@contextlib.contextmanager
|
||||
def _get_session(self):
|
||||
"""Return exclusive session for scope of with statement"""
|
||||
session = self._sessions.get()
|
||||
try:
|
||||
yield session
|
||||
finally:
|
||||
self._sessions.put(session)
|
||||
|
||||
def get_xenapi_host(self):
|
||||
"""Return the xenapi host"""
|
||||
return self._session.xenapi.session.get_this_host(self._session.handle)
|
||||
with self._get_session() as session:
|
||||
return session.xenapi.session.get_this_host(session.handle)
|
||||
|
||||
def call_xenapi(self, method, *args):
|
||||
"""Call the specified XenAPI method on a background thread."""
|
||||
f = self._session.xenapi
|
||||
for m in method.split('.'):
|
||||
f = f.__getattr__(m)
|
||||
return tpool.execute(f, *args)
|
||||
with self._get_session() as session:
|
||||
f = session.xenapi
|
||||
for m in method.split('.'):
|
||||
f = getattr(f, m)
|
||||
return tpool.execute(f, *args)
|
||||
|
||||
def call_xenapi_request(self, method, *args):
|
||||
"""Some interactions with dom0, such as interacting with xenstore's
|
||||
param record, require using the xenapi_request method of the session
|
||||
object. This wraps that call on a background thread.
|
||||
"""
|
||||
f = self._session.xenapi_request
|
||||
return tpool.execute(f, method, *args)
|
||||
with self._get_session() as session:
|
||||
f = session.xenapi_request
|
||||
return tpool.execute(f, method, *args)
|
||||
|
||||
def async_call_plugin(self, plugin, fn, args):
|
||||
"""Call Async.host.call_plugin on a background thread."""
|
||||
return tpool.execute(self._unwrap_plugin_exceptions,
|
||||
self._session.xenapi.Async.host.call_plugin,
|
||||
self.get_xenapi_host(), plugin, fn, args)
|
||||
with self._get_session() as session:
|
||||
return tpool.execute(self._unwrap_plugin_exceptions,
|
||||
session.xenapi.Async.host.call_plugin,
|
||||
self.get_xenapi_host(), plugin, fn, args)
|
||||
|
||||
def wait_for_task(self, task, id=None):
|
||||
"""Return the result of the given task. The task is polled
|
||||
@@ -452,8 +470,8 @@ class XenAPISession(object):
|
||||
"""
|
||||
try:
|
||||
ctxt = context.get_admin_context()
|
||||
name = self._session.xenapi.task.get_name_label(task)
|
||||
status = self._session.xenapi.task.get_status(task)
|
||||
name = self.call_xenapi("task.get_name_label", task)
|
||||
status = self.call_xenapi("task.get_status", task)
|
||||
|
||||
# Ensure action is never > 255
|
||||
action = dict(action=name[:255], error=None)
|
||||
@@ -464,7 +482,7 @@ class XenAPISession(object):
|
||||
if status == "pending":
|
||||
return
|
||||
elif status == "success":
|
||||
result = self._session.xenapi.task.get_result(task)
|
||||
result = self.call_xenapi("task.get_result", task)
|
||||
LOG.info(_("Task [%(name)s] %(task)s status:"
|
||||
" success %(result)s") % locals())
|
||||
|
||||
@@ -473,7 +491,7 @@ class XenAPISession(object):
|
||||
|
||||
done.send(_parse_xmlrpc_value(result))
|
||||
else:
|
||||
error_info = self._session.xenapi.task.get_error_info(task)
|
||||
error_info = self.call_xenapi("task.get_error_info", task)
|
||||
LOG.warn(_("Task [%(name)s] %(task)s status:"
|
||||
" %(status)s %(error_info)s") % locals())
|
||||
|
||||
@@ -559,7 +577,7 @@ class HostState(object):
|
||||
# No SR configured
|
||||
LOG.error(_("Unable to get SR for this host: %s") % e)
|
||||
return
|
||||
sr_rec = self._session.get_xenapi().SR.get_record(sr_ref)
|
||||
sr_rec = self._session.call_xenapi("SR.get_record", sr_ref)
|
||||
total = int(sr_rec["virtual_allocation"])
|
||||
used = int(sr_rec["physical_utilisation"])
|
||||
data["disk_total"] = total
|
||||
|
||||
Reference in New Issue
Block a user