Пример #1
0
    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
Пример #2
0
    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())
Пример #3
0
    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())
Пример #4
0
    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
Пример #5
0
    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())
Пример #6
0
    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)
        )
Пример #7
0
    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)
Пример #8
0
    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)
Пример #9
0
    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)
Пример #10
0
    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)
Пример #11
0
    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