Exemplo n.º 1
0
    def pull_config(self, image, arch="amd64"):
        """
        Nydusify converts oci to nydus format and push the nydus image manifest to registry,
        which belongs to a manifest index.
        """
        skopeo = utils.Skopeo()
        nydus_manifest, digest = skopeo.inspect(image,
                                                tls_verify=False,
                                                image_arch=arch)

        import requests

        # Currently, we can handle auth
        # OCI distribution spec: /v2/<name>/manifests/<digest>
        reader = requests.get(
            f"http://{self.registry_url}/v2/{self.original_repo}/manifests/{digest}",
            stream=True,
        )

        manifest = json.load(reader.raw)

        config_digest = manifest["config"]["digest"]
        reader = requests.get(
            f"http://{self.registry_url}/v2/{self.original_repo}/blobs/{config_digest}",
            stream=True,
        )

        config = json.load(reader.raw)
        return config
Exemplo n.º 2
0
    def find_nydus_image(self, image, arch):
        skopeo = utils.Skopeo()
        nydus_manifest, digest = skopeo.inspect(
            image,
            tls_verify=False,
            image_arch=arch,
            features="nydus.remoteimage.v1")

        assert nydus_manifest is not None
Exemplo n.º 3
0
    def get_build_cache_records(self, ref):
        skopeo = utils.Skopeo()
        build_cache_records, _ = skopeo.inspect(ref, tls_verify=False)

        c = json.dumps(build_cache_records, indent=4, sort_keys=False)

        logging.info("build cache: %s", c)

        records = build_cache_records["layers"]
        return records
Exemplo n.º 4
0
 def extract_converted_layers_names(self, arch="amd64"):
     skopeo = utils.Skopeo()
     manifest, _ = skopeo.inspect(
         self.target_ref,
         tls_verify=False,
         features="nydus.remoteimage.v1",
         image_arch=arch,
     )
     layers = [l["digest"] for l in manifest["layers"]]
     layers.reverse()
     return layers
Exemplo n.º 5
0
    def extract_source_layers_names_and_download(self, arch="amd64"):
        skopeo = utils.Skopeo()
        manifest, digest = skopeo.inspect(self.__source, image_arch=arch)
        layers = [l["digest"] for l in manifest["layers"]]

        # trimmed_layers = [os.path.join(self.work_dir, self.__source, l) for l in layers]
        # trimmed_layers.reverse()
        layers.reverse()
        skopeo.copy_to_local(
            self.__source,
            layers,
            os.path.join(self.work_dir, self.__source),
            resource_digest=digest,
        )
        return layers, os.path.join(self.work_dir, self.__source)
Exemplo n.º 6
0
    def pull_bootstrap(self, downloaded_dir, bootstrap_name, arch="amd64"):
        """
        Nydusify converts oci to nydus format and push the nydus image manifest to registry,
        which belongs to a manifest index.
        """
        skopeo = utils.Skopeo()
        nydus_manifest, _ = skopeo.inspect(
            self.target_ref,
            tls_verify=False,
            features="nydus.remoteimage.v1",
            image_arch=arch,
        )
        layers = nydus_manifest["layers"]

        for l in layers:
            if l["mediaType"] == "application/vnd.docker.image.rootfs.diff.tar.gzip":
                bootstrap_digest = l["digest"]

        import requests

        # Currently, we can not handle auth
        # OCI distribution spec: /v2/<name>/blobs/<digest>
        os.makedirs(downloaded_dir, exist_ok=True)

        reader = requests.get(
            f"http://{self.registry_url}/v2/{self.anchor.registry_namespace}/{self.original_repo}/blobs/{bootstrap_digest}",
            stream=True,
        )
        with utils.pushd(downloaded_dir):
            with open("image.gzip", "wb") as w:
                shutil.copyfileobj(reader.raw, w)
            with tarfile.open("image.gzip", "r:gz") as tar_gz:
                tar_gz.extractall()
                os.rename("image/image.boot", bootstrap_name)
            os.remove("image.gzip")

        return os.path.join(downloaded_dir, bootstrap_name)
Exemplo n.º 7
0
def test_cross_platform_multiplatform(
    nydus_anchor: NydusAnchor,
    rafs_conf: RafsConf,
    source,
    arch,
    enable_multiplatform,
    local_registry,
    nydusify_converter,
):
    """
    - copy the entire repo from source registry to target registry
    - One image coresponds to manifest list while the other one to single manifest
    - Use cloned source rather than the one from original registry
    - Push the converted images to the original source
    - Also test multiplatform here
    - ? Seems with flag --multiplatform to nydusify, it still just push single manifest
    - converted manifest index has one more image than origin.
    """

    # Copy the entire repo for multiplatform
    skopeo = utils.Skopeo()
    source_name_tagged = posixpath.basename(source)
    target_image = f"localhost:5000/{source_name_tagged}"
    cloned_source = f"localhost:5000/{source_name_tagged}"
    skopeo.copy_all_to_registry(source, target_image)

    origin_manifest_index = skopeo.manifest_list(cloned_source)
    utils.Skopeo.pretty_print(origin_manifest_index)

    converter = Nydusify(nydus_anchor)

    converter.docker_v2(
    ).build_cache_ref("localhost:5000/build_cache:000").platform(
        f"linux/{arch}").enable_multiplatfrom(enable_multiplatform).convert(
            cloned_source, target_ref=target_image)

    # TODO: configure registry backend from `local_registry` rather than anchor
    rafs_conf.set_rafs_backend(Backend.REGISTRY,
                               repo=posixpath.basename(source).split(":")[0])
    rafs_conf.enable_fs_prefetch()
    rafs_conf.enable_rafs_blobcache()

    pulled_bootstrap = converter.pull_bootstrap(
        tempfile.TemporaryDirectory(dir=nydus_anchor.workspace,
                                    suffix="bootstrap").name,
        "pulled_bootstrap",
        arch,
    )

    # Skopeo does not support media type: "application/vnd.oci.image.layer.nydus.blob.v1",
    # So can't download build cache like a oci image.
    layers, base = converter.extract_source_layers_names_and_download(
        arch=arch)
    nydus_anchor.mount_overlayfs(layers, base)

    converted_layers = converter.extract_converted_layers_names(arch=arch)
    converted_layers.sort()

    converted_manifest_index = skopeo.manifest_list(cloned_source)
    utils.Skopeo.pretty_print(converted_manifest_index)

    assert (len(converted_manifest_index["manifests"]) -
            len(origin_manifest_index["manifests"]) == 1)

    # `inspect` will succeed if image to arch can be found.
    skopeo.inspect(target_image, image_arch=arch)
    converter.find_nydus_image(target_image, arch)

    target_image_config = converter.pull_config(target_image, arch=arch)
    assert target_image_config["architecture"] == arch

    records = converter.get_build_cache_records(
        "localhost:5000/build_cache:000")
    assert len(records) != 0
    cached_layers = [c["digest"] for c in records]
    cached_layers.sort()
    # >       assert cached_layers == converted_layers
    # E       AssertionError: assert None == ['sha256:3f18...af3234b4c257']
    # E         +None
    # E         -['sha256:3f18b27a912188108c8590684206bd9da7d81bbfd0e8325f3ef0af3234b4c257']
    for r in converted_layers:
        assert r in cached_layers

    # Use `nydus-image inspect` to compare blob table in bootstrap and manifest
    workload_gen = WorkloadGen(nydus_anchor.mount_point,
                               nydus_anchor.overlayfs)
    # No need to locate where bootstrap is as we can directly pull it from registry
    rafs = RafsMount(nydus_anchor, None, rafs_conf)
    rafs.thread_num(6).bootstrap(pulled_bootstrap).prefetch_files("/").mount()

    assert workload_gen.verify_entire_fs()
    workload_gen.setup_workload_generator()
    workload_gen.torture_read(8, 12, verify=True)
    workload_gen.finish_torture_read()