Merge "Add upload/download vhd2 interfaces"
This commit is contained in:
commit
2461ed3d38
@ -61,9 +61,7 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
|||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
return {'image_id': 'fake_image_uuid',
|
return {'image_id': 'fake_image_uuid',
|
||||||
'glance_host': '1.1.1.1',
|
'endpoint': 'http://1.1.1.1:123',
|
||||||
'glance_port': 123,
|
|
||||||
'glance_use_ssl': False,
|
|
||||||
'sr_path': '/fake/sr/path',
|
'sr_path': '/fake/sr/path',
|
||||||
'extra_headers': {'X-Auth-Token': 'foobar',
|
'extra_headers': {'X-Auth-Token': 'foobar',
|
||||||
'X-Roles': '',
|
'X-Roles': '',
|
||||||
@ -83,7 +81,8 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
|||||||
lambda *a, **kw: ['uuid1'])
|
lambda *a, **kw: ['uuid1'])
|
||||||
|
|
||||||
self.mox.StubOutWithMock(self.session, 'call_plugin_serialized')
|
self.mox.StubOutWithMock(self.session, 'call_plugin_serialized')
|
||||||
self.session.call_plugin_serialized('glance', 'download_vhd', **params)
|
self.session.call_plugin_serialized('glance', 'download_vhd2',
|
||||||
|
**params)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
self.store.download_image(self.context, self.session,
|
self.store.download_image(self.context, self.session,
|
||||||
@ -102,19 +101,20 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
|||||||
params = self._get_download_params()
|
params = self._get_download_params()
|
||||||
self.flags(num_retries=2, group='glance')
|
self.flags(num_retries=2, group='glance')
|
||||||
|
|
||||||
params.pop("glance_port")
|
params.pop("endpoint")
|
||||||
params.pop("glance_host")
|
calls = [mock.call('glance', 'download_vhd2',
|
||||||
calls = [mock.call('glance', 'download_vhd', glance_port=9292,
|
endpoint='http://10.0.1.1:9292',
|
||||||
glance_host='10.0.1.1', **params),
|
**params),
|
||||||
mock.call('glance', 'download_vhd', glance_port=9293,
|
mock.call('glance', 'download_vhd2',
|
||||||
glance_host='10.0.0.1', **params)]
|
endpoint='http://10.0.0.1:9293',
|
||||||
|
**params)]
|
||||||
log_calls = [mock.call(mock.ANY, {'callback_result': '10.0.1.1',
|
log_calls = [mock.call(mock.ANY, {'callback_result': '10.0.1.1',
|
||||||
'attempts': 3, 'attempt': 1,
|
'attempts': 3, 'attempt': 1,
|
||||||
'fn': 'download_vhd',
|
'fn': 'download_vhd2',
|
||||||
'plugin': 'glance'}),
|
'plugin': 'glance'}),
|
||||||
mock.call(mock.ANY, {'callback_result': '10.0.0.1',
|
mock.call(mock.ANY, {'callback_result': '10.0.0.1',
|
||||||
'attempts': 3, 'attempt': 2,
|
'attempts': 3, 'attempt': 2,
|
||||||
'fn': 'download_vhd',
|
'fn': 'download_vhd2',
|
||||||
'plugin': 'glance'})]
|
'plugin': 'glance'})]
|
||||||
|
|
||||||
glance_api_servers = ['10.0.1.1:9292',
|
glance_api_servers = ['10.0.1.1:9292',
|
||||||
@ -147,7 +147,7 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
|||||||
params = self._get_upload_params(auto_disk_config, expected_os_type)
|
params = self._get_upload_params(auto_disk_config, expected_os_type)
|
||||||
|
|
||||||
self.mox.StubOutWithMock(self.session, 'call_plugin_serialized')
|
self.mox.StubOutWithMock(self.session, 'call_plugin_serialized')
|
||||||
self.session.call_plugin_serialized('glance', 'upload_vhd', **params)
|
self.session.call_plugin_serialized('glance', 'upload_vhd2', **params)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
self.store.upload_image(self.context, self.session, self.instance,
|
self.store.upload_image(self.context, self.session, self.instance,
|
||||||
@ -174,7 +174,7 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
|||||||
params = self._get_upload_params()
|
params = self._get_upload_params()
|
||||||
|
|
||||||
self.mox.StubOutWithMock(self.session, 'call_plugin_serialized')
|
self.mox.StubOutWithMock(self.session, 'call_plugin_serialized')
|
||||||
self.session.call_plugin_serialized('glance', 'upload_vhd',
|
self.session.call_plugin_serialized('glance', 'upload_vhd2',
|
||||||
**params).AndRaise(RuntimeError)
|
**params).AndRaise(RuntimeError)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
@ -192,21 +192,21 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
|||||||
self.mox.StubOutWithMock(compute_utils, 'add_instance_fault_from_exc')
|
self.mox.StubOutWithMock(compute_utils, 'add_instance_fault_from_exc')
|
||||||
error_details = ["", "", "RetryableError", ""]
|
error_details = ["", "", "RetryableError", ""]
|
||||||
error = self.session.XenAPI.Failure(details=error_details)
|
error = self.session.XenAPI.Failure(details=error_details)
|
||||||
self.session.call_plugin_serialized('glance', 'upload_vhd',
|
self.session.call_plugin_serialized('glance', 'upload_vhd2',
|
||||||
**params).AndRaise(error)
|
**params).AndRaise(error)
|
||||||
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
||||||
error, (fake.Failure,
|
error, (fake.Failure,
|
||||||
error,
|
error,
|
||||||
mox.IgnoreArg()))
|
mox.IgnoreArg()))
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
self.session.call_plugin_serialized('glance', 'upload_vhd',
|
self.session.call_plugin_serialized('glance', 'upload_vhd2',
|
||||||
**params).AndRaise(error)
|
**params).AndRaise(error)
|
||||||
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
||||||
error, (fake.Failure,
|
error, (fake.Failure,
|
||||||
error,
|
error,
|
||||||
mox.IgnoreArg()))
|
mox.IgnoreArg()))
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
self.session.call_plugin_serialized('glance', 'upload_vhd',
|
self.session.call_plugin_serialized('glance', 'upload_vhd2',
|
||||||
**params).AndRaise(error)
|
**params).AndRaise(error)
|
||||||
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
||||||
error, (fake.Failure,
|
error, (fake.Failure,
|
||||||
@ -229,7 +229,7 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
|||||||
self.mox.StubOutWithMock(compute_utils, 'add_instance_fault_from_exc')
|
self.mox.StubOutWithMock(compute_utils, 'add_instance_fault_from_exc')
|
||||||
error_details = ["", "task signaled", "", ""]
|
error_details = ["", "task signaled", "", ""]
|
||||||
error = self.session.XenAPI.Failure(details=error_details)
|
error = self.session.XenAPI.Failure(details=error_details)
|
||||||
self.session.call_plugin_serialized('glance', 'upload_vhd',
|
self.session.call_plugin_serialized('glance', 'upload_vhd2',
|
||||||
**params).AndRaise(error)
|
**params).AndRaise(error)
|
||||||
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
||||||
error, (fake.Failure,
|
error, (fake.Failure,
|
||||||
@ -239,14 +239,14 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
|||||||
# Note(johngarbutt) XenServer 6.1 and later has this error
|
# Note(johngarbutt) XenServer 6.1 and later has this error
|
||||||
error_details = ["", "signal: SIGTERM", "", ""]
|
error_details = ["", "signal: SIGTERM", "", ""]
|
||||||
error = self.session.XenAPI.Failure(details=error_details)
|
error = self.session.XenAPI.Failure(details=error_details)
|
||||||
self.session.call_plugin_serialized('glance', 'upload_vhd',
|
self.session.call_plugin_serialized('glance', 'upload_vhd2',
|
||||||
**params).AndRaise(error)
|
**params).AndRaise(error)
|
||||||
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
||||||
error, (fake.Failure,
|
error, (fake.Failure,
|
||||||
error,
|
error,
|
||||||
mox.IgnoreArg()))
|
mox.IgnoreArg()))
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
self.session.call_plugin_serialized('glance', 'upload_vhd',
|
self.session.call_plugin_serialized('glance', 'upload_vhd2',
|
||||||
**params)
|
**params)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ class FakeSessionForVMTests(fake.SessionBase):
|
|||||||
"# Completed on Sun Nov 6 22:49:02 2011\n")
|
"# Completed on Sun Nov 6 22:49:02 2011\n")
|
||||||
|
|
||||||
def host_call_plugin(self, _1, _2, plugin, method, _5):
|
def host_call_plugin(self, _1, _2, plugin, method, _5):
|
||||||
if (plugin, method) == ('glance', 'download_vhd'):
|
if plugin == 'glance' and method in ('download_vhd', 'download_vhd2'):
|
||||||
root_uuid = _make_fake_vdi()
|
root_uuid = _make_fake_vdi()
|
||||||
return pickle.dumps(dict(root=dict(uuid=root_uuid)))
|
return pickle.dumps(dict(root=dict(uuid=root_uuid)))
|
||||||
elif (plugin, method) == ("xenhost", "iptables_config"):
|
elif (plugin, method) == ("xenhost", "iptables_config"):
|
||||||
|
@ -283,7 +283,7 @@ class FetchVhdImageTestCase(VMUtilsTestBase):
|
|||||||
self.mox.StubOutWithMock(
|
self.mox.StubOutWithMock(
|
||||||
self.session, 'call_plugin_serialized_with_retry')
|
self.session, 'call_plugin_serialized_with_retry')
|
||||||
func = self.session.call_plugin_serialized_with_retry(
|
func = self.session.call_plugin_serialized_with_retry(
|
||||||
'glance', 'download_vhd', 0, mox.IgnoreArg(), mox.IgnoreArg(),
|
'glance', 'download_vhd2', 0, mox.IgnoreArg(), mox.IgnoreArg(),
|
||||||
extra_headers={'X-Auth-Token': 'auth_token',
|
extra_headers={'X-Auth-Token': 'auth_token',
|
||||||
'X-Roles': '',
|
'X-Roles': '',
|
||||||
'X-Tenant-Id': None,
|
'X-Tenant-Id': None,
|
||||||
|
@ -81,7 +81,7 @@ class XenAPISession(object):
|
|||||||
# changed in development environments.
|
# changed in development environments.
|
||||||
# MAJOR VERSION: Incompatible changes with the plugins
|
# MAJOR VERSION: Incompatible changes with the plugins
|
||||||
# MINOR VERSION: Compatible changes, new plguins, etc
|
# MINOR VERSION: Compatible changes, new plguins, etc
|
||||||
PLUGIN_REQUIRED_VERSION = '1.2'
|
PLUGIN_REQUIRED_VERSION = '1.3'
|
||||||
|
|
||||||
def __init__(self, url, user, pw):
|
def __init__(self, url, user, pw):
|
||||||
version_string = version.version_string_with_package()
|
version_string = version.version_string_with_package()
|
||||||
|
@ -665,6 +665,7 @@ class SessionBase(object):
|
|||||||
return pickle.dumps(None)
|
return pickle.dumps(None)
|
||||||
|
|
||||||
_plugin_glance_upload_vhd = _plugin_pickle_noop
|
_plugin_glance_upload_vhd = _plugin_pickle_noop
|
||||||
|
_plugin_glance_upload_vhd2 = _plugin_pickle_noop
|
||||||
_plugin_kernel_copy_vdi = _plugin_noop
|
_plugin_kernel_copy_vdi = _plugin_noop
|
||||||
_plugin_kernel_create_kernel_ramdisk = _plugin_noop
|
_plugin_kernel_create_kernel_ramdisk = _plugin_noop
|
||||||
_plugin_kernel_remove_kernel_ramdisk = _plugin_noop
|
_plugin_kernel_remove_kernel_ramdisk = _plugin_noop
|
||||||
@ -761,7 +762,7 @@ class SessionBase(object):
|
|||||||
return base64.b64encode(zlib.compress("dom_id: %s" % dom_id))
|
return base64.b64encode(zlib.compress("dom_id: %s" % dom_id))
|
||||||
|
|
||||||
def _plugin_nova_plugin_version_get_version(self, method, args):
|
def _plugin_nova_plugin_version_get_version(self, method, args):
|
||||||
return pickle.dumps("1.2")
|
return pickle.dumps("1.3")
|
||||||
|
|
||||||
def _plugin_xenhost_query_gc(self, method, args):
|
def _plugin_xenhost_query_gc(self, method, args):
|
||||||
return pickle.dumps("False")
|
return pickle.dumps("False")
|
||||||
|
@ -36,11 +36,10 @@ class GlanceStore(object):
|
|||||||
glance_api_servers = glance.get_api_servers()
|
glance_api_servers = glance.get_api_servers()
|
||||||
|
|
||||||
def pick_glance(kwargs):
|
def pick_glance(kwargs):
|
||||||
g_host, g_port, g_use_ssl = next(glance_api_servers).as_tuple()
|
server = next(glance_api_servers)
|
||||||
kwargs['glance_host'] = g_host
|
kwargs['endpoint'] = server.url
|
||||||
kwargs['glance_port'] = g_port
|
# NOTE(sdague): is the return significant here at all?
|
||||||
kwargs['glance_use_ssl'] = g_use_ssl
|
return server.host
|
||||||
return g_host
|
|
||||||
|
|
||||||
def retry_cb(context, instance, exc=None):
|
def retry_cb(context, instance, exc=None):
|
||||||
if exc:
|
if exc:
|
||||||
@ -65,7 +64,7 @@ class GlanceStore(object):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
vdis = self._call_glance_plugin(context, instance, session,
|
vdis = self._call_glance_plugin(context, instance, session,
|
||||||
'download_vhd', params)
|
'download_vhd2', params)
|
||||||
except exception.PluginRetriesExceeded:
|
except exception.PluginRetriesExceeded:
|
||||||
raise exception.CouldNotFetchImage(image_id=image_id)
|
raise exception.CouldNotFetchImage(image_id=image_id)
|
||||||
|
|
||||||
@ -90,6 +89,6 @@ class GlanceStore(object):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
self._call_glance_plugin(context, instance, session,
|
self._call_glance_plugin(context, instance, session,
|
||||||
'upload_vhd', params)
|
'upload_vhd2', params)
|
||||||
except exception.PluginRetriesExceeded:
|
except exception.PluginRetriesExceeded:
|
||||||
raise exception.CouldNotUploadImage(image_id=image_id)
|
raise exception.CouldNotUploadImage(image_id=image_id)
|
||||||
|
@ -375,6 +375,24 @@ def validate_image_status_before_upload(conn, url, extra_headers):
|
|||||||
'image_status': image_status})
|
'image_status': image_status})
|
||||||
|
|
||||||
|
|
||||||
|
def download_vhd2(session, image_id, endpoint,
|
||||||
|
uuid_stack, sr_path, extra_headers):
|
||||||
|
"""Download an image from Glance, unbundle it, and then deposit the VHDs
|
||||||
|
into the storage repository
|
||||||
|
"""
|
||||||
|
staging_path = utils.make_staging_area(sr_path)
|
||||||
|
try:
|
||||||
|
# Download tarball into staging area and extract it
|
||||||
|
_download_tarball_by_url(
|
||||||
|
sr_path, staging_path, image_id,
|
||||||
|
endpoint, extra_headers)
|
||||||
|
|
||||||
|
# Move the VHDs from the staging area into the storage repository
|
||||||
|
return utils.import_vhds(sr_path, staging_path, uuid_stack)
|
||||||
|
finally:
|
||||||
|
utils.cleanup_staging_area(staging_path)
|
||||||
|
|
||||||
|
|
||||||
def download_vhd(session, image_id, glance_host, glance_port, glance_use_ssl,
|
def download_vhd(session, image_id, glance_host, glance_port, glance_use_ssl,
|
||||||
uuid_stack, sr_path, extra_headers):
|
uuid_stack, sr_path, extra_headers):
|
||||||
"""Download an image from Glance, unbundle it, and then deposit the VHDs
|
"""Download an image from Glance, unbundle it, and then deposit the VHDs
|
||||||
@ -393,6 +411,19 @@ def download_vhd(session, image_id, glance_host, glance_port, glance_use_ssl,
|
|||||||
utils.cleanup_staging_area(staging_path)
|
utils.cleanup_staging_area(staging_path)
|
||||||
|
|
||||||
|
|
||||||
|
def upload_vhd2(session, vdi_uuids, image_id,
|
||||||
|
endpoint, sr_path, extra_headers, properties):
|
||||||
|
"""Bundle the VHDs comprising an image and then stream them into Glance.
|
||||||
|
"""
|
||||||
|
staging_path = utils.make_staging_area(sr_path)
|
||||||
|
try:
|
||||||
|
utils.prepare_staging_area(sr_path, staging_path, vdi_uuids)
|
||||||
|
_upload_tarball_by_url(staging_path, image_id,
|
||||||
|
endpoint, extra_headers, properties)
|
||||||
|
finally:
|
||||||
|
utils.cleanup_staging_area(staging_path)
|
||||||
|
|
||||||
|
|
||||||
def upload_vhd(session, vdi_uuids, image_id, glance_host, glance_port,
|
def upload_vhd(session, vdi_uuids, image_id, glance_host, glance_port,
|
||||||
glance_use_ssl, sr_path, extra_headers, properties):
|
glance_use_ssl, sr_path, extra_headers, properties):
|
||||||
"""Bundle the VHDs comprising an image and then stream them into Glance.
|
"""Bundle the VHDs comprising an image and then stream them into Glance.
|
||||||
@ -407,4 +438,5 @@ def upload_vhd(session, vdi_uuids, image_id, glance_host, glance_port,
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
utils.register_plugin_calls(download_vhd, upload_vhd)
|
utils.register_plugin_calls(download_vhd, upload_vhd,
|
||||||
|
download_vhd2, upload_vhd2)
|
||||||
|
@ -28,7 +28,8 @@ import utils
|
|||||||
# 1.0 - Initial version.
|
# 1.0 - Initial version.
|
||||||
# 1.1 - New call to check GC status
|
# 1.1 - New call to check GC status
|
||||||
# 1.2 - Added support for pci passthrough devices
|
# 1.2 - Added support for pci passthrough devices
|
||||||
PLUGIN_VERSION = "1.2"
|
# 1.3 - Add vhd2 functions for doing glance operations by url
|
||||||
|
PLUGIN_VERSION = "1.3"
|
||||||
|
|
||||||
def get_version(session):
|
def get_version(session):
|
||||||
return PLUGIN_VERSION
|
return PLUGIN_VERSION
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
upgrade:
|
||||||
|
- The glance xenserver plugin has been bumped to version 1.3 which
|
||||||
|
includes new interfaces for referencing glance servers by url. All
|
||||||
|
dom0 will need to be upgraded with this plugin before upgrading
|
||||||
|
the nova code.
|
Loading…
Reference in New Issue
Block a user