From a303427d4226ff8baf11c0cbddaefe3b27d2c289 Mon Sep 17 00:00:00 2001 From: Brian Myers Date: Mon, 30 Dec 2024 19:41:35 -0600 Subject: [PATCH] break out oci_image_layer into separate file --- docs/defs.md | 45 ++++++++--------- oci/BUILD.bazel | 1 + oci/defs.bzl | 2 +- oci/private/image.bzl | 56 --------------------- oci/private/oci_image_layer.bzl | 86 +++++++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 79 deletions(-) create mode 100644 oci/private/oci_image_layer.bzl diff --git a/docs/defs.md b/docs/defs.md index 82aa6fa..899e83c 100644 --- a/docs/defs.md +++ b/docs/defs.md @@ -50,28 +50,6 @@ oci_image_index(name, manifests | - | List of labels | optional | `[]` | - - -## oci_image_layer - -
-oci_image_layer(name, directory, file_map, files, symlinks)
-
- -Create a tarball and an OCI descriptor for it - -**ATTRIBUTES** - - -| Name | Description | Type | Mandatory | Default | -| :------------- | :------------- | :------------- | :------------- | :------------- | -| name | A unique name for this target. | Name | required | | -| directory | Directory in the tarball to place the `files` | String | optional | `""` | -| file_map | Dictionary of file -> file location in tarball | Dictionary: Label -> String | optional | `{}` | -| files | List of files to include under `directory` | List of labels | optional | `[]` | -| symlinks | Dictionary of symlink -> target entries to place in the tarball | Dictionary: String -> String | optional | `{}` | - - ## oci_image_layout @@ -122,3 +100,26 @@ Pushes a manifest or a list of manifests to an OCI registry. | x_meta_headers | (optional) A list of key/values to to be sent to the registry as headers with an X-Meta- prefix. | Dictionary: String -> String | optional | `{}` | + + +## oci_image_layer + +
+oci_image_layer(name, directory, file_map, files, symlinks, kwargs)
+
+ +oci_image_layer + +**PARAMETERS** + + +| Name | Description | Default Value | +| :------------- | :------------- | :------------- | +| name | A unique name for this rule | none | +| directory | Directory in the tarball to place the `files` | `"/"` | +| file_map | Dictionary of file -> file location in tarball | `None` | +| files | List of files to include under `directory` | `None` | +| symlinks | Dictionary of symlink -> target entries to place in the tarball | `None` | +| kwargs | Additional arguments to pass to the rule, e.g. `tags` or `visibility` | none | + + diff --git a/oci/BUILD.bazel b/oci/BUILD.bazel index bfacc92..0efabf2 100644 --- a/oci/BUILD.bazel +++ b/oci/BUILD.bazel @@ -30,6 +30,7 @@ bzl_library( "//oci:providers.bzl", "//oci/private:debug_flag.bzl", "//oci/private:image.bzl", + "//oci/private:oci_image_layer.bzl", "//oci/private:oci_image_layout.bzl", "//oci/private:push.bzl", "@aspect_bazel_lib//lib:stamping", diff --git a/oci/defs.bzl b/oci/defs.bzl index f82b509..027a1f8 100644 --- a/oci/defs.bzl +++ b/oci/defs.bzl @@ -4,8 +4,8 @@ load( "//oci/private:image.bzl", _oci_image = "oci_image", _oci_image_index = "oci_image_index", - _oci_image_layer = "oci_image_layer", ) +load("//oci/private:oci_image_layer.bzl", _oci_image_layer = "oci_image_layer") load("//oci/private:oci_image_layout.bzl", _oci_image_layout = "oci_image_layout") load("//oci/private:push.bzl", _oci_push = "oci_push") diff --git a/oci/private/image.bzl b/oci/private/image.bzl index b1cb5f3..d935149 100644 --- a/oci/private/image.bzl +++ b/oci/private/image.bzl @@ -21,62 +21,6 @@ def get_descriptor_file(ctx, desc): return out -def _oci_image_layer_impl(ctx): - toolchain = ctx.toolchains["//oci:toolchain"] - - descriptor_file = ctx.actions.declare_file("{}.descriptor.json".format(ctx.label.name)) - - ctx.actions.run( - executable = toolchain.sdk.ocitool, - arguments = [ - "create-layer", - "--out={}".format(ctx.outputs.layer.path), - "--outd={}".format(descriptor_file.path), - "--dir={}".format(ctx.attr.directory), - "--bazel-label={}".format(ctx.label), - ] + - ["--file={}".format(f.path) for f in ctx.files.files] + - ["--symlink={}={}".format(k, v) for k, v in ctx.attr.symlinks.items()] + - ["--file-map={}={}".format(k.files.to_list()[0].path, v) for k, v in ctx.attr.file_map.items()], - inputs = ctx.files.files + ctx.files.file_map, - outputs = [ - descriptor_file, - ctx.outputs.layer, - ], - ) - - return [ - OCIDescriptor( - descriptor_file = descriptor_file, - file = ctx.outputs.layer, - ), - ] - -oci_image_layer = rule( - implementation = _oci_image_layer_impl, - doc = "Create a tarball and an OCI descriptor for it", - attrs = { - "files": attr.label_list( - doc = "List of files to include under `directory`", - allow_files = True, - ), - "directory": attr.string( - doc = "Directory in the tarball to place the `files`", - ), - "symlinks": attr.string_dict( - doc = "Dictionary of symlink -> target entries to place in the tarball", - ), - "file_map": attr.label_keyed_string_dict( - doc = "Dictionary of file -> file location in tarball", - allow_files = True, - ), - }, - toolchains = ["//oci:toolchain"], - outputs = { - "layer": "%{name}-layer.tar.gz", - }, -) - def _oci_image_index_impl(ctx): toolchain = ctx.toolchains["//oci:toolchain"] diff --git a/oci/private/oci_image_layer.bzl b/oci/private/oci_image_layer.bzl new file mode 100644 index 0000000..28cab58 --- /dev/null +++ b/oci/private/oci_image_layer.bzl @@ -0,0 +1,86 @@ +""" oci_image_layer """ + +load("//oci:providers.bzl", "OCIDescriptor") + +def oci_image_layer( + *, + name, + directory = "/", # str + file_map = None, # dict[label, str] + files = None, # list[label] + symlinks = None, # dict[str, str] + **kwargs): + # -> None + """ oci_image_layer + + Args: + name: A unique name for this rule + directory: Directory in the tarball to place the `files` + file_map: Dictionary of file -> file location in tarball + files: List of files to include under `directory` + symlinks: Dictionary of symlink -> target entries to place in the tarball + **kwargs: Additional arguments to pass to the rule, e.g. `tags` or `visibility` + """ + file_map = file_map or {} + files = files or [] + symlinks = symlinks or {} + + if len(files) == 0 and len(file_map) == 0: + fail("At least one of `files` or `file_map` must be provided") + + _oci_image_layer( + name = name, + directory = directory, + file_map = file_map, + files = files, + symlinks = symlinks, + **kwargs + ) + +def _impl(ctx): + toolchain = ctx.toolchains["//oci:toolchain"] + + descriptor_file = ctx.actions.declare_file("{}.descriptor.json".format(ctx.label.name)) + + ctx.actions.run( + executable = toolchain.sdk.ocitool, + arguments = [ + "create-layer", + "--out={}".format(ctx.outputs.layer.path), + "--outd={}".format(descriptor_file.path), + "--dir={}".format(ctx.attr.directory), + "--bazel-label={}".format(ctx.label), + ] + + ["--file={}".format(f.path) for f in ctx.files.files] + + ["--symlink={}={}".format(k, v) for k, v in ctx.attr.symlinks.items()] + + ["--file-map={}={}".format(k.files.to_list()[0].path, v) for k, v in ctx.attr.file_map.items()], + inputs = ctx.files.files + ctx.files.file_map, + outputs = [ + descriptor_file, + ctx.outputs.layer, + ], + ) + + return [ + DefaultInfo( + files = depset([ctx.outputs.layer, descriptor_file]), + ), + OCIDescriptor( + descriptor_file = descriptor_file, + file = ctx.outputs.layer, + ), + ] + +_oci_image_layer = rule( + implementation = _impl, + attrs = { + "files": attr.label_list(allow_files = True), + "directory": attr.string(), + "symlinks": attr.string_dict(), + "file_map": attr.label_keyed_string_dict(allow_files = True), + }, + toolchains = ["//oci:toolchain"], + outputs = { + "layer": "%{name}-layer.tar.gz", + }, +)