Skip to content

Commit 10ee2ea

Browse files
committed
fix: env vars containing =
1 parent 333a982 commit 10ee2ea

File tree

5 files changed

+175
-6
lines changed

5 files changed

+175
-6
lines changed

examples/BUILD.bazel

+16
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,19 @@ platform(
1515
"@platforms//cpu:x86_64",
1616
],
1717
)
18+
19+
config_setting(
20+
name = "platform_darwin_arm64",
21+
constraint_values = [
22+
"@platforms//os:macos",
23+
"@platforms//cpu:arm64",
24+
],
25+
)
26+
27+
config_setting(
28+
name = "platform_linux_amd64",
29+
constraint_values = [
30+
"@platforms//os:linux",
31+
"@platforms//cpu:x86_64",
32+
],
33+
)

examples/assertion/BUILD.bazel

+36-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ load("@aspect_bazel_lib//lib:tar.bzl", "tar")
22
load("@aspect_bazel_lib//lib:transitions.bzl", "platform_transition_filegroup")
33
load("@bazel_skylib//rules:build_test.bzl", "build_test")
44
load("//oci:defs.bzl", "oci_image", "oci_tarball")
5+
load(":assert.bzl", "assert_oci_config")
56

67
# Case 1: image name containing a capital case.
78
oci_image(
@@ -72,9 +73,7 @@ filegroup(
7273
output_group = "tarball",
7374
)
7475

75-
# Case 5:
76-
77-
# Case 4: An oci_image directly fed into oci_tarball
76+
# Case 5: An oci_image directly fed into oci_tarball
7877
oci_image(
7978
name = "case5",
8079
architecture = "arm64",
@@ -93,6 +92,40 @@ filegroup(
9392
output_group = "tarball",
9493
)
9594

95+
# Case 6: test all cases that might break
96+
oci_image(
97+
name = "case6",
98+
architecture = "arm64",
99+
env = {
100+
"TEST": "VALUE=",
101+
"TEST2": "=VALUE=",
102+
"TEST3": "=VALUE",
103+
"TEST4": "=V=VALUE",
104+
# an env that includes previously set $TEST env with a leading `=`
105+
"LEAD_WITH_REF": "=$TEST",
106+
"JUST_EQUALS": "======$$$$",
107+
"1": "VAL",
108+
# referencing non-existent env vars is just empty string.
109+
"REFS": "$1:${1}:${NONEXISTENT}",
110+
},
111+
os = "linux",
112+
)
113+
114+
assert_oci_config(
115+
name = "test_case6",
116+
env_eq = {
117+
"TEST": "VALUE=",
118+
"TEST2": "=VALUE=",
119+
"TEST3": "=VALUE",
120+
"TEST4": "=V=VALUE",
121+
"LEAD_WITH_REF": "=VALUE=",
122+
"JUST_EQUALS": "======$$$$",
123+
"1": "VAL",
124+
"REFS": "VAL:VAL:",
125+
},
126+
image = ":case6",
127+
)
128+
96129
# build them as test.
97130
build_test(
98131
name = "test",

examples/assertion/assert.bzl

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
"assertion rules to test metadata"
2+
3+
load("@bazel_skylib//rules:native_binary.bzl", "native_test")
4+
load("@bazel_skylib//rules:write_file.bzl", "write_file")
5+
6+
DIGEST_CMD = """
7+
image_path="$(location {image})"
8+
manifest_digest=$$($(JQ_BIN) -r '.manifests[0].digest | sub(":"; "/")' $$image_path/index.json)
9+
config_digest=$$($(JQ_BIN) -r '.config.digest | sub(":"; "/")' $$image_path/blobs/$$manifest_digest)
10+
11+
$(JQ_BIN) 'def pick(p): . as $$v | reduce path(p) as $$p ({{}}; setpath($$p; $$v | getpath($$p))); pick({keys})' "$$image_path/blobs/$$config_digest" > $@
12+
"""
13+
14+
# buildifier: disable=function-docstring-args
15+
def assert_oci_config(
16+
name,
17+
image,
18+
entrypoint_eq = None,
19+
cmd_eq = None,
20+
env_eq = None,
21+
ports_eq = None,
22+
user_eq = None,
23+
workdir_eq = None,
24+
architecture_eq = None,
25+
os_eq = None,
26+
variant_eq = None,
27+
labels_eq = None):
28+
"assert that an oci_image has specified config metadata according to https://github.com/opencontainers/image-spec/blob/main/config.md"
29+
pick = []
30+
31+
config = {}
32+
33+
# .config
34+
if entrypoint_eq:
35+
config["Entrypoint"] = entrypoint_eq
36+
if cmd_eq:
37+
config["Cmd"] = cmd_eq
38+
if env_eq:
39+
config["Env"] = ["=".join(e) for e in env_eq.items()]
40+
if workdir_eq:
41+
config["Workdir"] = workdir_eq
42+
if ports_eq:
43+
config["Ports"] = ports_eq
44+
if user_eq:
45+
config["User"] = user_eq
46+
if labels_eq:
47+
config["Labels"] = labels_eq
48+
49+
pick = [".config." + k for k in config.keys()]
50+
51+
# .
52+
config_json = {}
53+
54+
if os_eq:
55+
config_json["os"] = os_eq
56+
if architecture_eq:
57+
config_json["architecture"] = architecture_eq
58+
if variant_eq:
59+
config_json["variant"] = variant_eq
60+
61+
pick += ["." + k for k in config_json.keys()]
62+
63+
if len(config.keys()):
64+
config_json["config"] = config
65+
66+
expected = name + "_json"
67+
write_file(
68+
name = expected,
69+
out = name + ".json",
70+
content = [
71+
json.encode_indent(config_json),
72+
],
73+
)
74+
75+
actual = name + "_config_json"
76+
native.genrule(
77+
name = actual,
78+
srcs = [image],
79+
outs = [name + ".config.json"],
80+
cmd = DIGEST_CMD.format(keys = ",".join(pick), image = image),
81+
toolchains = ["@jq_toolchains//:resolved_toolchain"],
82+
)
83+
84+
native_test(
85+
name = name,
86+
data = [
87+
expected,
88+
actual,
89+
],
90+
args = [
91+
"$(location %s)" % expected,
92+
"$(location %s)" % actual,
93+
],
94+
src = select({
95+
"//examples:platform_darwin_arm64": "@jd_darwin_arm64//file",
96+
"//examples:platform_linux_amd64": "@jd_linux_amd64//file",
97+
}),
98+
out = name,
99+
)

fetch.bzl

+19-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This file is similar to how bazel_gazelle can manage go_repository calls
44
by writing them to a generated macro in a .bzl file.
55
"""
66

7-
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
7+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file")
88
load("@rules_oci//oci:pull.bzl", "oci_pull")
99

1010
def fetch_images():
@@ -222,3 +222,21 @@ genrule(
222222
],
223223
sha256 = "d7c7af5d86f43a885069408a89788f67f248e8124c682bb73936f33874e0611b",
224224
)
225+
226+
http_file(
227+
name = "jd_darwin_arm64",
228+
urls = [
229+
"https://github.com/josephburnett/jd/releases/download/v1.8.1/jd-arm64-darwin",
230+
],
231+
sha256 = "8b0e51b902650287b7dedc2beee476b96c5d589309d3a7f556334c1baedbec61",
232+
executable = True,
233+
)
234+
235+
http_file(
236+
name = "jd_linux_amd64",
237+
urls = [
238+
"https://github.com/josephburnett/jd/releases/download/v1.8.1/jd-amd64-linux",
239+
],
240+
sha256 = "ab918f52130561abd4f88d9c2d3ae95d4d56f1a2dff9762665890349d61c763e",
241+
executable = True,
242+
)

oci/private/image.sh

+5-2
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,12 @@ for ARG in "$@"; do
131131
--env=*)
132132
# Get environment from existing config
133133
env=$(get_config | jq '(.config.Env // []) | map(. | split("=") | {"key": .[0], "value": .[1:] | join("=")})')
134-
134+
135135
while IFS= read -r expansion || [ -n "$expansion" ]; do
136-
IFS="=" read -r key value <<<"${expansion}"
136+
# collect all characters until a `=` is encountered
137+
key="${expansion%%=*}"
138+
# skip `length(k) + 1` to collect the rest.
139+
value="${expansion:${#key}+1}"
137140
value_from_base=$(jq -nr --arg raw "${value}" --argjson envs "${env}" "${ENV_EXPAND_FILTER}")
138141
env=$(
139142
# update the existing env if it exists, or append to the end of env array.

0 commit comments

Comments
 (0)