From bfa6b992c35236bfea8a7c3b4fc38f65e1961351 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Fri, 17 Nov 2023 16:11:24 -0800 Subject: [PATCH] feat: implement home --- distroless/BUILD.bazel | 1 + distroless/defs.bzl | 2 ++ distroless/private/BUILD.bazel | 10 ++++++++++ distroless/private/home.bzl | 27 +++++++++++++++++++++++++++ distroless/private/passwd.bzl | 2 +- distroless/private/tar.bzl | 20 ++++++++++++++------ docs/rules.md | 20 ++++++++++++++++++++ examples/home/BUILD.bazel | 29 +++++++++++++++++++++++++++++ 8 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 distroless/private/home.bzl create mode 100644 examples/home/BUILD.bazel diff --git a/distroless/BUILD.bazel b/distroless/BUILD.bazel index 06ac0e8..f36f977 100644 --- a/distroless/BUILD.bazel +++ b/distroless/BUILD.bazel @@ -20,6 +20,7 @@ bzl_library( deps = [ "//distroless/private:cacerts", "//distroless/private:group", + "//distroless/private:home", "//distroless/private:locale", "//distroless/private:os_release", "//distroless/private:passwd", diff --git a/distroless/defs.bzl b/distroless/defs.bzl index c534e1a..253a7b9 100644 --- a/distroless/defs.bzl +++ b/distroless/defs.bzl @@ -2,6 +2,7 @@ load("//distroless/private:cacerts.bzl", _cacerts = "cacerts") load("//distroless/private:group.bzl", _group = "group") +load("//distroless/private:home.bzl", _home = "home") load("//distroless/private:locale.bzl", _locale = "locale") load("//distroless/private:os_release.bzl", _os_release = "os_release") load("//distroless/private:passwd.bzl", _passwd = "passwd") @@ -11,3 +12,4 @@ locale = _locale os_release = _os_release group = _group passwd = _passwd +home = _home diff --git a/distroless/private/BUILD.bazel b/distroless/private/BUILD.bazel index d254cbf..3493dde 100644 --- a/distroless/private/BUILD.bazel +++ b/distroless/private/BUILD.bazel @@ -52,6 +52,16 @@ bzl_library( ], ) +bzl_library( + name = "home", + srcs = ["home.bzl"], + visibility = ["//distroless:__subpackages__"], + deps = [ + ":tar", + "@aspect_bazel_lib//lib:tar", + ], +) + bzl_library( name = "tar", srcs = ["tar.bzl"], diff --git a/distroless/private/home.bzl b/distroless/private/home.bzl new file mode 100644 index 0000000..4687328 --- /dev/null +++ b/distroless/private/home.bzl @@ -0,0 +1,27 @@ +"home" + +load("@aspect_bazel_lib//lib:tar.bzl", "tar") +load(":tar.bzl", "tar_lib") + +def home(name, dirs, **kwargs): + """ + Create home directories with specific uid and gids. + + Args: + name: name of the target + dirs: an array of dicts + **kwargs: other named arguments to that is passed to tar. see [common rule attributes](https://bazel.build/reference/be/common-definitions#common-attributes). + """ + mtree = [] + + for home in dirs: + mtree.extend( + tar_lib.add_directory_with_parents(home["path"], uid = str(home["uid"]), gid = str(home["gid"])), + ) + + tar( + name = name, + srcs = [], + mtree = mtree, + **kwargs + ) diff --git a/distroless/private/passwd.bzl b/distroless/private/passwd.bzl index 62c6615..229ab56 100644 --- a/distroless/private/passwd.bzl +++ b/distroless/private/passwd.bzl @@ -50,7 +50,7 @@ def passwd(name, passwds, **kwargs): stamp = 0, template = [ "#mtree", - "etc/passwd uid=0 gid=0 mode=0700 time=0 type=file content={content}", + "./etc/passwd uid=0 gid=0 mode=0700 time=0 type=file content={content}", "", ], substitutions = { diff --git a/distroless/private/tar.bzl b/distroless/private/tar.bzl index 9160976..1fc3ce0 100644 --- a/distroless/private/tar.bzl +++ b/distroless/private/tar.bzl @@ -15,14 +15,17 @@ def _mtree_line(file, type, content = None, uid = "0", gid = "0", time = "167256 spec.append("content=" + content) return " ".join(spec) -def _add_parents(path): +def _add_parents(path, uid = "0", gid = "0", time = "1672560000", mode = "0755"): lines = [] segments = path.split("/") - for i in range(1, len(segments)): - parent = "/".join(segments[:i]) - if parent == "": + segments.pop() + for i in range(0, len(segments)): + parent = "/".join(segments[:i + 1]) + if not parent or parent == ".": continue - lines.append(_mtree_line(parent.lstrip("/"), "dir")) + lines.append( + _mtree_line(parent.lstrip("/"), "dir", uid = uid, gid = gid, time = time, mode = mode), + ) return lines def _add_file_with_parents(path, file): @@ -30,6 +33,11 @@ def _add_file_with_parents(path, file): lines.append(_mtree_line(path.lstrip("/"), "file", content = file.path)) return lines +def _add_directory_with_parents(path, **kwargs): + lines = _add_parents(path) + lines.append(_mtree_line(path.lstrip("/"), "dir", **kwargs)) + return lines + def _build_tar(ctx, mtree, output, inputs = [], compression = "gzip", mnemonic = "Tar"): bsdtar = ctx.toolchains[BSDTAR_TOOLCHAIN] @@ -71,7 +79,7 @@ def _create_mtree(ctx): tar_lib = struct( create_mtree = _create_mtree, line = _mtree_line, - add_directory_with_parents = _add_file_with_parents, + add_directory_with_parents = _add_directory_with_parents, add_file_with_parents = _add_file_with_parents, TOOLCHAIN_TYPE = BSDTAR_TOOLCHAIN, ) diff --git a/docs/rules.md b/docs/rules.md index d565189..0845701 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -116,6 +116,26 @@ https://www.ibm.com/docs/en/aix/7.2?topic=files-etcgroup-file#group_security__a2 | kwargs | other named arguments to expanded targets. see [common rule attributes](https://bazel.build/reference/be/common-definitions#common-attributes). | none | + + +## home + +
+home(name, dirs, kwargs)
+
+ + Create home directories with specific uid and gids. + +**PARAMETERS** + + +| Name | Description | Default Value | +| :------------- | :------------- | :------------- | +| name | name of the target | none | +| dirs | an array of dicts | none | +| kwargs | other named arguments to that is passed to tar. see [common rule attributes](https://bazel.build/reference/be/common-definitions#common-attributes). | none | + + ## os_release diff --git a/examples/home/BUILD.bazel b/examples/home/BUILD.bazel new file mode 100644 index 0000000..a12ca16 --- /dev/null +++ b/examples/home/BUILD.bazel @@ -0,0 +1,29 @@ +load("//distroless:defs.bzl", "home") +load("//distroless/tests:asserts.bzl", "assert_tar_listing") + +home( + name = "home", + dirs = [ + { + "path": "./root", + "uid": 0, + "gid": 0, + }, + { + "path": "./home/nonroot", + "uid": 666, + "gid": 666, + }, + ], +) + +assert_tar_listing( + name = "test_home", + actual = "home", + expected = """\ +#mtree +./home time=1672560000.0 mode=755 gid=0 uid=0 type=dir +./home/nonroot time=1672560000.0 mode=755 gid=666 uid=666 type=dir +./root time=1672560000.0 mode=755 gid=0 uid=0 type=dir +""", +)