def test_multiple_deps_docker_image(docker_client, cli, datafiles, tmp_path):
    test_element = "multiple-deps.bst"
    project = str(datafiles)
    checkout_dir = os.path.join(str(tmp_path), "checkout")

    build_and_checkout(test_element, checkout_dir, cli, project)
    tag = get_image_tag(load_image(docker_client, checkout_dir))

    image_attrs = docker_client.images.get(tag).attrs
    assert len(image_attrs["RootFS"]["Layers"]) == 3
    _test_no_file_duplication(
        _get_layer_files(untar(os.path.join(checkout_dir, "image.tar"))))
def test_diamond_deps_docker_image(docker_client, cli, datafiles, tmp_path):
    test_element = "diamond-deps.bst"
    project = str(datafiles)
    checkout_dir = os.path.join(str(tmp_path), "checkout")

    build_and_checkout(test_element, checkout_dir, cli, project)
    tag = get_image_tag(load_image(docker_client, checkout_dir))
    _check_meta_data(docker_client, tag)

    image_attrs = docker_client.images.get(tag).attrs
    assert len(image_attrs["RootFS"]["Layers"]) == 2

    # assert that there is no file duplication
    layer_files = _get_layer_files(
        untar(os.path.join(checkout_dir, "image.tar")))
    _test_no_file_duplication(layer_files)
def test_correct_checksum_docker_image(cli, datafiles, tmp_path):
    test_element = "multiple-deps.bst"
    project = str(datafiles)
    checkout_dir = os.path.join(str(tmp_path), "checkout")

    build_and_checkout(test_element, checkout_dir, cli, project)
    extract_path = untar(os.path.join(checkout_dir, "image.tar"))

    # check config file is correctly named
    config_json = [
        file for file in os.listdir(extract_path)
        if file.endswith(".json") and file != "manifest.json"
    ][0]
    assert config_json == "{}.json".format(
        hash_digest(os.path.join(extract_path, config_json)))

    # check each directory is correctly named
    for layer in os.listdir(extract_path):
        if os.path.isdir(layer):
            assert os.path.basename(layer) == hash_digest(
                os.path.join(layer, "layer.tar"))
def test_nested_overwrite_docker_image(docker_client, cli, datafiles,
                                       tmp_path):
    # pylint: disable=too-many-locals

    test_element = "nested-overwrite.bst"
    project = str(datafiles)
    checkout_dir = os.path.join(str(tmp_path), "checkout")
    container_fs_export_dir = os.path.join(str(tmp_path), "fs_extract")
    exported_tar = os.path.join(container_fs_export_dir, "image.tar")
    os.makedirs(container_fs_export_dir)

    build_and_checkout(test_element, checkout_dir, cli, project)
    tag = get_image_tag(load_image(docker_client, checkout_dir))

    image_attrs = docker_client.images.get(tag).attrs
    assert len(image_attrs["RootFS"]["Layers"]) == 2

    # assert that file is indeed overwritten
    extract_path = untar(os.path.join(checkout_dir, "image.tar"))
    assert (_get_number_of_file_duplications(
        _get_layer_files(extract_path)) == 2)

    # check overwritten file is content is as expected
    container = docker_client.containers.create(tag, command="/bin/sh")
    with open(exported_tar, "wb+") as tar_handle:
        for chunk in container.export():
            tar_handle.write(chunk)
    with tarfile.open(exported_tar) as tar_handle:
        tar_handle.extractall(path=container_fs_export_dir)

    try:
        with open(os.path.join(container_fs_export_dir, "layer1",
                               "hello.txt")) as produced_file:
            with open(
                    os.path.join(project, "files", "layers", "layer2",
                                 "hello.txt")) as actual_file:
                assert produced_file.read() == actual_file.read()
    except FileNotFoundError:
        assert False
Exemple #5
0
def test_image_equality(cli, datafiles, tmp_path):
    # pylint: disable=too-many-locals
    """
    Check that the filesystem of a rebuilt image built from an imported third-party image,
    results in the filesystem of the third-party image.
    """
    project = str(datafiles)
    yaml = YAML()
    yaml.default_flow_style = False

    # build and checkout hello-world image
    hello_world_source = "hello-world-image-source.bst"
    hello_world_source_element = {
        "kind":
        "import",
        "sources": [{
            "kind": "docker",
            "image": "library/hello-world",
            "track": "latest",
        }],
    }
    create_element(yaml, hello_world_source, hello_world_source_element,
                   project)

    hello_world_checkout_rel_dir = os.path.join("files", "hello-world")
    hello_world_checkout_dir = os.path.join(project,
                                            hello_world_checkout_rel_dir)
    result = cli.run(project=project,
                     args=["source", "track", hello_world_source])
    result.assert_success()
    build_and_checkout(hello_world_source, hello_world_checkout_dir, cli,
                       project)

    # build image from extracted fs
    # create elements
    import_hello_world = "import-hello-world.bst"
    import_hello_world_element = {
        "kind":
        "import",
        "sources": [{
            "kind": "local",
            "path": "./{}".format(hello_world_checkout_rel_dir),
        }],
    }
    create_element(yaml, import_hello_world, import_hello_world_element,
                   project)

    hello_world_rebuild = "hello-world-image-rebuild.bst"
    hello_world_rebuild_element = {
        "kind": "docker_image",
        "config": {
            "image-names":
            ["bst-plugins-container-tests/hello-world-rebuild:latest"]
        },
        "build-depends": [import_hello_world],
    }
    create_element(yaml, hello_world_rebuild, hello_world_rebuild_element,
                   project)

    # build image
    rebuilt_image_checkout_dir = os.path.join(str(tmp_path),
                                              "rebuilt_image_checkout_dir")
    build_and_checkout(hello_world_rebuild, rebuilt_image_checkout_dir, cli,
                       project)

    # get layer filesystem
    untar_dir = untar(os.path.join(rebuilt_image_checkout_dir, "image.tar"))
    layer_dir = [
        os.path.join(untar_dir, layer_dir)
        for layer_dir in os.listdir(untar_dir)
        if os.path.isdir(os.path.join(untar_dir, layer_dir))
    ][0]
    layer_untar_dir = untar(os.path.join(layer_dir, "layer.tar"))

    # assert file systems are equal and have the same contents
    _compare_directory_files(layer_untar_dir, hello_world_checkout_dir)