Skip to content

Commit

Permalink
update workdir to be STRING_OR_LABEL
Browse files Browse the repository at this point in the history
It kinda doesn't exist in macro-land, so build a hacky string parsing heuristic
  • Loading branch information
lazcamus committed Sep 2, 2024
1 parent 348db1b commit f9f94de
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 12 deletions.
8 changes: 6 additions & 2 deletions docs/image.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions examples/assertion/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ oci_image(
volumes = ["/srv/data"],
# user & workdir
user = "root",
workdir = ["/root"],
workdir = "/root",
# labels & annotations
labels = {
"org.opencontainers.image.version": "0.0.0",
Expand Down Expand Up @@ -620,7 +620,7 @@ build_test(
],
)

# Case 21: accept workdir param as a target (list input tested in case8)
# Case 21: accept workdir param as a target label (string input is tested in case8)
genrule(
name = "case21_workdir_target",
outs = ["case21_workdir_target.txt"],
Expand All @@ -630,7 +630,7 @@ genrule(
oci_image(
name = "case21",
base = ":case8",
workdir = ":case21_workdir_target",
workdir = "case21_workdir_target",
)

assert_oci_config(
Expand Down
48 changes: 41 additions & 7 deletions oci/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,38 @@ def _write_nl_seperated_file(name, kind, elems, forwarded_kwargs):
)
return label


# There's no "is this a label or just a string?" check in macro land, so
# approximate it with some silly string heuristics. See
# https://bazel.build/concepts/labels for label name rules
def _is_a_workdir_label(input):
if input[0] in (":", "@") or input[:2] in ("@@", "//") or '/' not in input:
return True
return False


def test_is_a_workdir_label():
testdata = {
# Corner case: "foo" could be either a string or a target. This
# implementation chooses target. If you want a relative workdir "foo"
# use "./foo"
"foo": True,
"//foo": True,
"@@foo//bar": True,
":foo": True,
# These are all not labels
"/foo": False,
"./foo": False,
"foo/bar": False,
"../foo": False,
}

for input, expected in testdata.items():
value = _is_a_workdir_label(input)
if value != expected:
fail("_is_a_workdir_label(%s) returned %s, expected %s" % (input, value, expected))


def oci_image(name, labels = None, annotations = None, env = None, cmd = None, entrypoint = None, workdir = None, exposed_ports = None, volumes = None, **kwargs):
"""Macro wrapper around [oci_image_rule](#oci_image_rule).
Expand All @@ -50,18 +82,22 @@ def oci_image(name, labels = None, annotations = None, env = None, cmd = None, e
deterministic) information when running with `--stamp` flag. See the example in
[/examples/labels/BUILD.bazel](https://github.com/bazel-contrib/rules_oci/blob/main/examples/labels/BUILD.bazel).
**LIST_OR_LABEL**: `cmd`, `entrypoint`, `workdir`, `exposed_ports`, `volumes`
**LIST_OR_LABEL**: `cmd`, `entrypoint`, `exposed_ports`, `volumes`
Can be a list of strings, or a file with newlines separating entries.
**STRING_OR_LABEL**: `workdir`
A string, or a target text file whose output contains a single line
Args:
name: name of resulting oci_image_rule
labels: `DICT_OR_LABEL` Labels for the image config.
annotations: `DICT_OR_LABEL` Annotations for the image config.
env: `DICT_OR_LABEL` Environment variables provisioned by default to the running container.
cmd: `LIST_OR_LABEL` Command & argument configured by default in the running container.
entrypoint: `LIST_OR_LABEL` Entrypoint configured by default in the running container.
workdir: `LIST_OR_LABEL` Workdir configured by default in the running container. Only 1 list entry allowed.
workdir: `STRING_OR_LABEL` Workdir configured by default in the running container.
exposed_ports: `LIST_OR_LABEL` Exposed ports in the running container.
volumes: `LIST_OR_LABEL` Volumes for the container.
**kwargs: other named arguments to [oci_image_rule](#oci_image_rule) and
Expand Down Expand Up @@ -115,15 +151,13 @@ def oci_image(name, labels = None, annotations = None, env = None, cmd = None, e
forwarded_kwargs = forwarded_kwargs,
)

if types.is_list(workdir):
if len(workdir) > 1:
fail("workdir MUST only include 1 list element")

# Support a string for convenience. Create a label on the fly.
if workdir != None and not _is_a_workdir_label(workdir):
workdir_label = "_{}_write_workdir".format(name)
write_file(
name = workdir_label,
out = "_{}.workdir.txt".format(name),
content = workdir,
content = [workdir],
**forwarded_kwargs
)
workdir = workdir_label
Expand Down
3 changes: 3 additions & 0 deletions oci/tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ load("@aspect_bazel_lib//lib:diff_test.bzl", "diff_test")
load("@aspect_bazel_lib//lib:run_binary.bzl", "run_binary")
load("@bazel_skylib//rules:build_test.bzl", "build_test")
load(":pull_tests.bzl", "parse_image_test")
load("//oci:defs.bzl", "test_is_a_workdir_label")

IMAGES_TO_TEST = {
"linux/amd64": {
Expand Down Expand Up @@ -83,3 +84,5 @@ build_test(
)

parse_image_test(name = "parse_image_test")

test_is_a_workdir_label()

0 comments on commit f9f94de

Please sign in to comment.