diff --git a/.bcr/config.yml b/.bcr/config.yml index 6466426..654d1d5 100644 --- a/.bcr/config.yml +++ b/.bcr/config.yml @@ -1,6 +1,6 @@ # See https://github.com/bazel-contrib/publish-to-bcr#a-note-on-release-automation # for guidance about whether to uncomment this section: # -fixedReleaser: - login: loosebazooka - email: appu@google.com +# fixedReleaser: +# login: loosebazooka +# email: appu@google.com diff --git a/distroless/BUILD.bazel b/distroless/BUILD.bazel index 8aca409..06ac0e8 100644 --- a/distroless/BUILD.bazel +++ b/distroless/BUILD.bazel @@ -19,8 +19,10 @@ bzl_library( visibility = ["//visibility:public"], deps = [ "//distroless/private:cacerts", + "//distroless/private:group", "//distroless/private:locale", "//distroless/private:os_release", + "//distroless/private:passwd", ], ) diff --git a/distroless/defs.bzl b/distroless/defs.bzl index f360c31..c534e1a 100644 --- a/distroless/defs.bzl +++ b/distroless/defs.bzl @@ -1,9 +1,13 @@ "Public API re-exports" load("//distroless/private:cacerts.bzl", _cacerts = "cacerts") +load("//distroless/private:group.bzl", _group = "group") load("//distroless/private:locale.bzl", _locale = "locale") load("//distroless/private:os_release.bzl", _os_release = "os_release") +load("//distroless/private:passwd.bzl", _passwd = "passwd") cacerts = _cacerts locale = _locale os_release = _os_release +group = _group +passwd = _passwd diff --git a/distroless/private/BUILD.bazel b/distroless/private/BUILD.bazel index 22a137d..d254cbf 100644 --- a/distroless/private/BUILD.bazel +++ b/distroless/private/BUILD.bazel @@ -16,6 +16,18 @@ bzl_library( deps = [":tar"], ) +bzl_library( + name = "group", + srcs = ["group.bzl"], + visibility = ["//distroless:__subpackages__"], + deps = [ + "@aspect_bazel_lib//lib:expand_template", + "@aspect_bazel_lib//lib:tar", + "@aspect_bazel_lib//lib:utils", + "@bazel_skylib//rules:write_file", + ], +) + bzl_library( name = "os_release", srcs = ["os_release.bzl"], @@ -28,6 +40,18 @@ bzl_library( ], ) +bzl_library( + name = "passwd", + srcs = ["passwd.bzl"], + visibility = ["//distroless:__subpackages__"], + deps = [ + "@aspect_bazel_lib//lib:expand_template", + "@aspect_bazel_lib//lib:tar", + "@aspect_bazel_lib//lib:utils", + "@bazel_skylib//rules:write_file", + ], +) + bzl_library( name = "tar", srcs = ["tar.bzl"], diff --git a/distroless/private/group.bzl b/distroless/private/group.bzl new file mode 100644 index 0000000..e273612 --- /dev/null +++ b/distroless/private/group.bzl @@ -0,0 +1,57 @@ +"osrelease" + +load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template") +load("@aspect_bazel_lib//lib:tar.bzl", "tar") +load("@aspect_bazel_lib//lib:utils.bzl", "propagate_common_rule_attributes") +load("@bazel_skylib//rules:write_file.bzl", "write_file") + +def group(name, groups, **kwargs): + """ + Create a group file from array of dicts. + + https://www.ibm.com/docs/en/aix/7.2?topic=files-etcgroup-file#group_security__a21597b8__title__1 + + Args: + name: name of the target + groups: an array of dicts which will be serialized into single group file. + **kwargs: other named arguments to expanded targets. see [common rule attributes](https://bazel.build/reference/be/common-definitions#common-attributes). + """ + common_kwargs = propagate_common_rule_attributes(kwargs) + write_file( + name = "%s_content" % name, + content = [ + # See https://www.ibm.com/docs/en/aix/7.2?topic=files-etcgroup-file#group_security__a3179518__title__1 + ":".join([ + entry["name"], + "!", # not used. Group administrators are provided instead of group passwords. + str(entry["gid"]), + ",".join(entry["users"]), + ]) + for entry in groups + ], + out = "%s.content" % name, + **common_kwargs + ) + + # TODO: remove this expansion target once https://github.com/aspect-build/bazel-lib/issues/653 is fixed. + expand_template( + name = "%s_mtree" % name, + out = "%s.mtree" % name, + data = [":%s_content" % name], + stamp = 0, + template = [ + "#mtree", + "etc/group uid=0 gid=0 mode=0644 time=0 type=file content={content}", + "", + ], + substitutions = { + "{content}": "$(BINDIR)/$(rootpath :%s_content)" % name, + }, + **common_kwargs + ) + tar( + name = name, + srcs = [":%s_content" % name], + mtree = ":%s_mtree" % name, + **common_kwargs + ) diff --git a/distroless/private/passwd.bzl b/distroless/private/passwd.bzl new file mode 100644 index 0000000..62c6615 --- /dev/null +++ b/distroless/private/passwd.bzl @@ -0,0 +1,66 @@ +"osrelease" + +load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template") +load("@aspect_bazel_lib//lib:tar.bzl", "tar") +load("@aspect_bazel_lib//lib:utils.bzl", "propagate_common_rule_attributes") +load("@bazel_skylib//rules:write_file.bzl", "write_file") + +def passwd(name, passwds, **kwargs): + """ + Create a passwd file from array of dicts. + + https://www.ibm.com/docs/en/aix/7.3?topic=passwords-using-etcpasswd-file + + Args: + name: name of the target + passwds: an array of dicts which will be serialized into single passwd file. + + An example; + + ``` + dict(gid = 0, uid = 0, home = "/root", shell = "/bin/bash", username = "root") + ``` + **kwargs: other named arguments to expanded targets. see [common rule attributes](https://bazel.build/reference/be/common-definitions#common-attributes). + """ + common_kwargs = propagate_common_rule_attributes(kwargs) + write_file( + name = "%s_content" % name, + content = [ + # See: https://www.ibm.com/docs/kk/aix/7.2?topic=files-etcpasswd-file#passwd_security__a21597b8__title__1 + ":".join([ + entry["username"], + entry.pop("password", "!"), + str(entry["uid"]), + str(entry["gid"]), + ",".join(entry.pop("gecos", [])), + entry["home"], + entry["shell"], + ]) + for entry in passwds + ], + out = "%s.content" % name, + **common_kwargs + ) + + # TODO: remove this expansion target once https://github.com/aspect-build/bazel-lib/issues/653 is fixed. + expand_template( + name = "%s_mtree" % name, + out = "%s.mtree" % name, + data = [":%s_content" % name], + stamp = 0, + template = [ + "#mtree", + "etc/passwd uid=0 gid=0 mode=0700 time=0 type=file content={content}", + "", + ], + substitutions = { + "{content}": "$(BINDIR)/$(rootpath :%s_content)" % name, + }, + **common_kwargs + ) + tar( + name = name, + srcs = [":%s_content" % name], + mtree = ":%s_mtree" % name, + **common_kwargs + ) diff --git a/docs/rules.md b/docs/rules.md index 9d53f5f..d565189 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -93,6 +93,29 @@ locale( | package | - | Label | required | | + + +## group + +
+group(name, groups, kwargs)
+
+ + Create a group file from array of dicts. + +https://www.ibm.com/docs/en/aix/7.2?topic=files-etcgroup-file#group_security__a21597b8__title__1 + + +**PARAMETERS** + + +| Name | Description | Default Value | +| :------------- | :------------- | :------------- | +| name | name of the target | none | +| groups | an array of dicts which will be serialized into single group file. | none | +| kwargs | other named arguments to expanded targets. see [common rule attributes](https://bazel.build/reference/be/common-definitions#common-attributes). | none | + + ## os_release @@ -117,3 +140,26 @@ https://www.freedesktop.org/software/systemd/man/latest/os-release.html | kwargs | other named arguments to expanded targets. see [common rule attributes](https://bazel.build/reference/be/common-definitions#common-attributes). | none | + + +## passwd + +
+passwd(name, passwds, kwargs)
+
+ + Create a passwd file from array of dicts. + +https://www.ibm.com/docs/en/aix/7.3?topic=passwords-using-etcpasswd-file + + +**PARAMETERS** + + +| Name | Description | Default Value | +| :------------- | :------------- | :------------- | +| name | name of the target | none | +| passwds | an array of dicts which will be serialized into single passwd file.

An example;

 dict(gid = 0, uid = 0, home = "/root", shell = "/bin/bash", username = "root") 
| none | +| kwargs | other named arguments to expanded targets. see [common rule attributes](https://bazel.build/reference/be/common-definitions#common-attributes). | none | + + diff --git a/examples/group/BUILD.bazel b/examples/group/BUILD.bazel new file mode 100644 index 0000000..09bb4f1 --- /dev/null +++ b/examples/group/BUILD.bazel @@ -0,0 +1,33 @@ +load("@aspect_bazel_lib//lib:diff_test.bzl", "diff_test") +load("//distroless:defs.bzl", "group") +load("//distroless/tests:asserts.bzl", "assert_tar_listing") + +group( + name = "group", + groups = [ + # https://www.ibm.com/docs/kk/aix/7.2?topic=files-etcgroup-file#group_security__a3179518__title__1 + dict( + name = "root", + gid = 0, + users = [ + "shadow", + "cjf", + ], + ), + ], +) + +diff_test( + name = "test_group_content", + file1 = "group_content", + file2 = "group.expected.txt", +) + +assert_tar_listing( + name = "test_group", + actual = "group", + expected = """\ +#mtree +./etc/group nlink=0 time=0.0 mode=644 gid=0 uid=0 type=file size=19 cksum=290415485 sha1digest=20c70f96d7939eb77c7f07bb8c0f200d89ce33b0 +""", +) diff --git a/examples/group/group.expected.txt b/examples/group/group.expected.txt new file mode 100644 index 0000000..5757472 --- /dev/null +++ b/examples/group/group.expected.txt @@ -0,0 +1 @@ +root:!:0:shadow,cjf \ No newline at end of file diff --git a/examples/passwd/BUILD.bazel b/examples/passwd/BUILD.bazel new file mode 100644 index 0000000..231e021 --- /dev/null +++ b/examples/passwd/BUILD.bazel @@ -0,0 +1,32 @@ +load("@aspect_bazel_lib//lib:diff_test.bzl", "diff_test") +load("//distroless:defs.bzl", "passwd") +load("//distroless/tests:asserts.bzl", "assert_tar_listing") + +passwd( + name = "passwd", + passwds = [ + dict( + gecos = ["root"], + gid = 0, + home = "/root", + shell = "/usr/bin/bash", + uid = 0, + username = "root", + ), + ], +) + +diff_test( + name = "test_passwd_content", + file1 = "passwd_content", + file2 = "passwd.expected.txt", +) + +assert_tar_listing( + name = "test_passwd", + actual = "passwd", + expected = """\ +#mtree +./etc/passwd nlink=0 time=0.0 mode=700 gid=0 uid=0 type=file size=35 cksum=2298809208 sha1digest=31ad675c1210fd0413dd9b2441aaaf13c18d1547 +""", +) diff --git a/examples/passwd/passwd.expected.txt b/examples/passwd/passwd.expected.txt new file mode 100644 index 0000000..7b99591 --- /dev/null +++ b/examples/passwd/passwd.expected.txt @@ -0,0 +1 @@ +root:!:0:0:root:/root:/usr/bin/bash \ No newline at end of file