def _write_test_image(self, url, manifest): image, tag = image_uploader.BaseImageUploader._image_tag_from_url( url) blob_dir = os.path.join( image_export.IMAGE_EXPORT_DIR, 'v2', image[1:], 'blobs') image_export.make_dir(blob_dir) if manifest.get('schemaVersion', 2) == 1: config_str = None manifest_type = image_uploader.MEDIA_MANIFEST_V1 layers = list(reversed([x['blobSum'] for x in manifest['fsLayers']])) else: config_str = '{"config": {}}' manifest_type = image_uploader.MEDIA_MANIFEST_V2 layers = [x['digest'] for x in manifest['layers']] manifest_str = json.dumps(manifest) calc_digest = hashlib.sha256() calc_digest.update(manifest_str.encode('utf-8')) manifest_digest = 'sha256:%s' % calc_digest.hexdigest() image_export.export_manifest_config( url, manifest_str, manifest_type, config_str ) for digest in layers: blob_path = os.path.join(blob_dir, '%s.gz' % digest) with open(blob_path, 'w+') as f: f.write('The Blob') return manifest_digest
def test_migrate_to_type_map_file(self): manifest_dir_path = os.path.join( image_export.IMAGE_EXPORT_DIR, 'v2/foo/bar/manifests' ) map_file_path = os.path.join( image_export.IMAGE_EXPORT_DIR, manifest_dir_path, 'latest.type-map' ) symlink_path = os.path.join( image_export.IMAGE_EXPORT_DIR, manifest_dir_path, 'latest' ) manifest_path = os.path.join( image_export.IMAGE_EXPORT_DIR, manifest_dir_path, 'sha256:1234abcd' ) image_export.make_dir(manifest_dir_path) # create legacy symlink os.symlink(manifest_path, symlink_path) # run the migration image_export.migrate_to_type_map_file('foo/bar', symlink_path) expected_map_file = '''URI: latest Content-Type: application/vnd.docker.distribution.manifest.v2+json URI: sha256:1234abcd/index.json ''' # assert the migrated file contains the expected content with open(map_file_path, 'r') as f: self.assertEqual(expected_map_file, f.read())
def test_cross_repo_mount(self): target_url = urlparse('docker://localhost:8787/t/nova-api:latest') other_url = urlparse('docker://localhost:8787/t/nova-compute:latest') image_layers = { 'sha256:1234': other_url } source_layers = [ 'sha256:1234', 'sha256:6789' ] source_blob_dir = os.path.join(image_export.IMAGE_EXPORT_DIR, 'v2/t/nova-compute/blobs') source_blob_path = os.path.join(source_blob_dir, 'sha256:1234.gz') target_blob_dir = os.path.join(image_export.IMAGE_EXPORT_DIR, 'v2/t/nova-api/blobs') target_blob_path = os.path.join(target_blob_dir, 'sha256:1234.gz') # call with missing source, no change image_export.cross_repo_mount(target_url, image_layers, source_layers, uploaded_layers={}) self.assertFalse(os.path.exists(source_blob_path)) self.assertFalse(os.path.exists(target_blob_path)) image_export.make_dir(source_blob_dir) with open(source_blob_path, 'w') as f: f.write('blob') self.assertTrue(os.path.exists(source_blob_path)) # call with existing source image_export.cross_repo_mount(target_url, image_layers, source_layers, uploaded_layers={}) self.assertTrue(os.path.exists(target_blob_path)) with open(target_blob_path, 'r') as f: self.assertEqual('blob', f.read())
def _write_test_image(self, url, manifest): image, tag = image_uploader.BaseImageUploader._image_tag_from_url( url) blob_dir = os.path.join( image_export.IMAGE_EXPORT_DIR, 'v2', image[1:], 'blobs') image_export.make_dir(blob_dir) if manifest.get('schemaVersion', 2) == 1: config_str = None manifest_type = image_uploader.MEDIA_MANIFEST_V1 layers = list(reversed([l['blobSum'] for l in manifest['fsLayers']])) else: config_str = '{"config": {}}' manifest_type = image_uploader.MEDIA_MANIFEST_V2 layers = [l['digest'] for l in manifest['layers']] manifest_str = json.dumps(manifest) calc_digest = hashlib.sha256() calc_digest.update(manifest_str.encode('utf-8')) manifest_digest = 'sha256:%s' % calc_digest.hexdigest() image_export.export_manifest_config( url, manifest_str, manifest_type, config_str ) for digest in layers: blob_path = os.path.join(blob_dir, '%s.gz' % digest) with open(blob_path, 'w+') as f: f.write('The Blob') return manifest_digest
def test_cross_repo_mount(self): target_url = urlparse('docker://localhost:8787/t/nova-api:latest') other_url = urlparse('docker://localhost:8787/t/nova-compute:latest') image_layers = { 'sha256:1234': other_url } source_layers = [ 'sha256:1234', 'sha256:6789' ] source_blob_dir = os.path.join(image_export.IMAGE_EXPORT_DIR, 'v2/t/nova-compute/blobs') source_blob_path = os.path.join(source_blob_dir, 'sha256:1234.gz') target_blob_dir = os.path.join(image_export.IMAGE_EXPORT_DIR, 'v2/t/nova-api/blobs') target_blob_path = os.path.join(target_blob_dir, 'sha256:1234.gz') # call with missing source, no change image_export.cross_repo_mount(target_url, image_layers, source_layers) self.assertFalse(os.path.exists(source_blob_path)) self.assertFalse(os.path.exists(target_blob_path)) image_export.make_dir(source_blob_dir) with open(source_blob_path, 'w') as f: f.write('blob') self.assertTrue(os.path.exists(source_blob_path)) # call with existing source image_export.cross_repo_mount(target_url, image_layers, source_layers) self.assertTrue(os.path.exists(target_blob_path)) with open(target_blob_path, 'r') as f: self.assertEqual('blob', f.read())
def test_write_parse_type_map_file(self): manifest_dir_path = os.path.join( image_export.IMAGE_EXPORT_DIR, 'v2/foo/bar/manifests' ) map_file_path = os.path.join( image_export.IMAGE_EXPORT_DIR, manifest_dir_path, 'latest.type-map' ) image_export.make_dir(manifest_dir_path) image_export.write_type_map_file( 'foo/bar', 'latest', {image_export.MEDIA_MANIFEST_V2: 'sha256:1234abcd'} ) expected_map_file = '''URI: latest Content-Type: application/vnd.docker.distribution.manifest.v2+json URI: sha256:1234abcd/index.json ''' # assert the file contains the expected content with open(map_file_path, 'r') as f: self.assertEqual(expected_map_file, f.read()) # assert parse_type_map_file correctly reads that file self.assertEqual( { 'application/vnd.docker.distribution.manifest.v2+json': 'sha256:1234abcd/index.json' }, image_export.parse_type_map_file(map_file_path) ) # assert a multi-entry file is correctly parsed multi_map_file = '''URI: latest Content-Type: application/vnd.docker.distribution.manifest.v2+json URI: sha256:1234abcd/index.json Content-Type: application/vnd.docker.distribution.manifest.list.v2+json URI: sha256:eeeeeeee/index.json ''' with open(map_file_path, 'w+') as f: f.write(multi_map_file) self.assertEqual( { 'application/vnd.docker.distribution.manifest.v2+json': 'sha256:1234abcd/index.json', 'application/vnd.docker.distribution.manifest.list.v2+json': 'sha256:eeeeeeee/index.json' }, image_export.parse_type_map_file(map_file_path) )
def test_make_dir(self): path = os.path.join(image_export.IMAGE_EXPORT_DIR, 'foo/bar') self.assertFalse(os.path.exists(path)) self.addCleanup(os.rmdir, path) image_export.make_dir(path) self.assertTrue(os.path.isdir(path)) # Call again to assert no error is raised image_export.make_dir(path)
def setUp(self): super(TestImageExport, self).setUp() export_dir = image_export.IMAGE_EXPORT_DIR with tempfile.NamedTemporaryFile() as f: temp_export_dir = f.name image_export.make_dir(temp_export_dir) def restore_export_dir(): shutil.rmtree(temp_export_dir) image_export.IMAGE_EXPORT_DIR = export_dir image_export.IMAGE_EXPORT_DIR = temp_export_dir self.addCleanup(restore_export_dir)
def _write_test_image(self, url, manifest): image, tag = image_uploader.BaseImageUploader._image_tag_from_url(url) blob_dir = os.path.join(image_export.IMAGE_EXPORT_DIR, 'v2', image[1:], 'blobs') image_export.make_dir(blob_dir) config_str = '{"config": {}}' manifest_str = json.dumps(manifest) calc_digest = hashlib.sha256() calc_digest.update(manifest_str.encode('utf-8')) manifest_digest = 'sha256:%s' % calc_digest.hexdigest() image_export.export_manifest_config(url, manifest_str, image_uploader.MEDIA_MANIFEST_V2, config_str) for layer in manifest['layers']: blob_path = os.path.join(blob_dir, '%s.gz' % layer['digest']) with open(blob_path, 'w+') as f: f.write('The Blob') return manifest_digest