Skip to content

Commit

Permalink
VMware: spawn refactor enlist image
Browse files Browse the repository at this point in the history
Refactor code to mark the cached image to be in active use into a
method in the image cache.

partial blueprint: vmware-spawn-refactor
Change-Id: Ib057f794f5a3a214811e55bb5f8c23d4767e4594
  • Loading branch information
vuil authored and mdbooth committed Sep 3, 2014
1 parent f0a8517 commit ce96e0b
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 14 deletions.
30 changes: 30 additions & 0 deletions nova/tests/virt/vmwareapi/test_imagecache.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,36 @@ def fake_get_sub_folders(session, ds_browser, ds_path):
'unexplained_images': []},
images)

@mock.patch.object(imagecache.ImageCacheManager, 'timestamp_folder_get')
@mock.patch.object(imagecache.ImageCacheManager, 'timestamp_cleanup')
@mock.patch.object(imagecache.ImageCacheManager, '_get_ds_browser')
def test_enlist_image(self,
mock_get_ds_browser,
mock_timestamp_cleanup,
mock_timestamp_folder_get):
image_id = "fake_image_id"
dc_ref = "fake_dc_ref"
fake_ds_ref = mock.Mock()
ds = ds_util.Datastore(
ref=fake_ds_ref, name='fake_ds',
capacity=1,
freespace=1)

ds_browser = mock.Mock()
mock_get_ds_browser.return_value = ds_browser
timestamp_folder_path = mock.Mock()
mock_timestamp_folder_get.return_value = timestamp_folder_path

self._imagecache.enlist_image(image_id, ds, dc_ref)

cache_root_folder = ds.build_path("fake-base-folder")
mock_get_ds_browser.assert_called_once_with(
ds.ref)
mock_timestamp_folder_get.assert_called_once_with(
cache_root_folder, "fake_image_id")
mock_timestamp_cleanup.assert_called_once_with(
dc_ref, ds_browser, timestamp_folder_path)

def test_age_cached_images(self):
def fake_get_ds_browser(ds_ref):
return 'fake-ds-browser'
Expand Down
7 changes: 6 additions & 1 deletion nova/tests/virt/vmwareapi/test_vmops.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,6 @@ def _verify_spawn_method_calls(self, mock_call_method):
# handling/manipulation. Till then, we continue to assert on the
# sequence of VIM operations invoked.
expected_methods = ['get_dynamic_property',
'SearchDatastore_Task',
'SearchDatastore_Task',
'CreateVirtualDisk_Task',
'DeleteDatastoreFile_Task',
Expand Down Expand Up @@ -750,6 +749,8 @@ def _verify_spawn_method_calls(self, mock_call_method):
return_value='fake_vm_ref')
@mock.patch('nova.virt.vmwareapi.ds_util.mkdir')
@mock.patch('nova.virt.vmwareapi.vmops.VMwareVMOps._set_machine_id')
@mock.patch(
'nova.virt.vmwareapi.imagecache.ImageCacheManager.enlist_image')
@mock.patch('nova.virt.vmwareapi.vm_util.get_vnc_port', return_value=5900)
@mock.patch('nova.virt.vmwareapi.vmops.VMwareVMOps._set_vnc_config')
@mock.patch('nova.virt.vmwareapi.vm_util.power_on_instance')
Expand All @@ -761,6 +762,7 @@ def _test_spawn(self,
mock_power_on_instance,
mock_set_vnc_config,
mock_get_vnc_port,
mock_enlist_image,
mock_set_machine_id,
mock_mkdir,
mock_create_vm,
Expand Down Expand Up @@ -860,6 +862,9 @@ def _test_spawn(self,
self.assertFalse(_fetch_image.called)
self.assertFalse(_call_method.called)
else:
mock_enlist_image.assert_called_once_with(
self._image_id, self._ds, self._dc_info.ref)

upload_file_name = 'vmware_temp/tmp-uuid/%s/%s-flat.vmdk' % (
self._image_id, self._image_id)
_fetch_image.assert_called_once_with(
Expand Down
15 changes: 15 additions & 0 deletions nova/virt/vmwareapi/imagecache.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,21 @@ def _folder_delete(self, ds_path, dc_ref):
except vexc.FileNotFoundException:
LOG.debug("File not found: %s", ds_path)

def enlist_image(self, image_id, datastore, dc_ref):
ds_browser = self._get_ds_browser(datastore.ref)
cache_root_folder = datastore.build_path(self._base_folder)

# Check if the timestamp file exists - if so then delete it. This
# will ensure that the aging will not delete a cache image if it
# is going to be used now.
path = self.timestamp_folder_get(cache_root_folder, image_id)

# Lock to ensure that the spawn will not try and access a image
# that is currently being deleted on the datastore.
with lockutils.lock(str(path), lock_file_prefix='nova-vmware-ts',
external=True):
self.timestamp_cleanup(dc_ref, ds_browser, path)

def timestamp_folder_get(self, ds_path, image_id):
"""Returns the timestamp folder."""
return ds_path.join(image_id)
Expand Down
15 changes: 2 additions & 13 deletions nova/virt/vmwareapi/vmops.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,20 +378,9 @@ def spawn(self, context, instance, image_meta, injected_files,
ds_browser = self._get_ds_browser(datastore.ref)
upload_file_name = upload_name + ".%s" % image_info.file_type

# Check if the timestamp file exists - if so then delete it. This
# will ensure that the aging will not delete a cache image if it
# is going to be used now.
if CONF.remove_unused_base_images:
ds_path = datastore.build_path(self._base_folder)
path = self._imagecache.timestamp_folder_get(ds_path,
upload_name)
# Lock to ensure that the spawn will not try and access a image
# that is currently being deleted on the datastore.
with lockutils.lock(str(path),
lock_file_prefix='nova-vmware-ts',
external=True):
self._imagecache.timestamp_cleanup(dc_info.ref, ds_browser,
path)
self._imagecache.enlist_image(
image_info.image_id, datastore, dc_info.ref)

# Check if the image exists in the datastore cache. If not the
# image will be uploaded and cached.
Expand Down

0 comments on commit ce96e0b

Please sign in to comment.