def _delete_master_path_if_stale(master_path, href, ctx): """Delete image from cache if it is not up to date with href contents. :param master_path: path to an image in master cache :param href: image href :param ctx: context to use :returns: True if master_path is up to date with href contents, False if master_path was stale and was deleted or it didn't exist """ if service_utils.is_glance_image(href): # Glance image contents cannot be updated without changing image's UUID return os.path.exists(master_path) if os.path.exists(master_path): img_service = image_service.get_image_service(href, context=ctx) img_mtime = img_service.show(href).get('updated_at') if not img_mtime: # This means that href is not a glance image and doesn't have an # updated_at attribute LOG.warn(_LW("Image service couldn't determine last " "modification time of %(href)s, considering " "cached image up to date."), {'href': href}) return True master_mtime = utils.unix_file_modification_datetime(master_path) if img_mtime <= master_mtime: return True # Delete image from cache as it is outdated LOG.info(_LI('Image %(href)s was last modified at %(remote_time)s. ' 'Deleting the cached copy "%(cached_file)s since it was ' 'last modified at %(local_time)s and may be outdated.'), {'href': href, 'remote_time': img_mtime, 'local_time': master_mtime, 'cached_file': master_path}) os.unlink(master_path) return False
def _delete_master_path_if_stale(master_path, href, ctx): """Delete image from cache if it is not up to date with href contents. :param master_path: path to an image in master cache :param href: image href :param ctx: context to use :returns: True if master_path is up to date with href contents, False if master_path was stale and was deleted or it didn't exist """ if service_utils.is_glance_image(href): # Glance image contents cannot be updated without changing image's UUID return os.path.exists(master_path) if os.path.exists(master_path): img_service = image_service.get_image_service(href, context=ctx) img_mtime = img_service.show(href).get('updated_at') if not img_mtime: # This means that href is not a glance image and doesn't have an # updated_at attribute LOG.warning("Image service couldn't determine last " "modification time of %(href)s, considering " "cached image up to date.", {'href': href}) return True master_mtime = utils.unix_file_modification_datetime(master_path) if img_mtime <= master_mtime: return True # Delete image from cache as it is outdated LOG.info('Image %(href)s was last modified at %(remote_time)s. ' 'Deleting the cached copy "%(cached_file)s since it was ' 'last modified at %(local_time)s and may be outdated.', {'href': href, 'remote_time': img_mtime, 'local_time': master_mtime, 'cached_file': master_path}) os.unlink(master_path) return False
def test__delete_master_path_if_stale_master_same_time( self, mock_gis, mock_unlink): # When times identical should not delete cached file touch(self.master_path) mtime = utils.unix_file_modification_datetime(self.master_path) href = 'http://awesomefreeimages.al/img999' mock_gis.return_value.show.return_value = {'updated_at': mtime} res = image_cache._delete_master_path_if_stale(self.master_path, href, None) mock_gis.assert_called_once_with(href, context=None) self.assertFalse(mock_unlink.called) self.assertTrue(res)
def test__delete_master_path_if_stale_master_same_time(self, mock_gis, mock_unlink): # When times identical should not delete cached file touch(self.master_path) mtime = utils.unix_file_modification_datetime(self.master_path) href = 'http://awesomefreeimages.al/img999' mock_gis.return_value.show.return_value = { 'updated_at': mtime } res = image_cache._delete_master_path_if_stale(self.master_path, href, None) mock_gis.assert_called_once_with(href, context=None) self.assertFalse(mock_unlink.called) self.assertTrue(res)
def show(self, image_href): """Get dictionary of image properties. :param image_href: Image reference. :raises: exception.ImageRefValidationFailed if image file specified doesn't exist. :returns: dictionary of image properties. It has three of them: 'size', 'updated_at' and 'properties'. 'updated_at' attribute is a naive UTC datetime object. """ source_image_path = self.validate_href(image_href) return { "size": os.path.getsize(source_image_path), "updated_at": utils.unix_file_modification_datetime(source_image_path), "properties": {}, }
def show(self, image_href): """Get dictionary of image properties. :param image_href: Image reference. :raises: exception.ImageRefValidationFailed if image file specified doesn't exist. :returns: dictionary of image properties. It has three of them: 'size', 'updated_at' and 'properties'. 'updated_at' attribute is a naive UTC datetime object. """ source_image_path = self.validate_href(image_href) return { 'size': os.path.getsize(source_image_path), 'updated_at': utils.unix_file_modification_datetime(source_image_path), 'properties': {} }
def test_unix_file_modification_datetime(self, mtime_mock): expected = datetime.datetime(2015, 8, 13, 11, 38, 9, 496475) self.assertEqual(expected, utils.unix_file_modification_datetime('foo')) mtime_mock.assert_called_once_with('foo')