Skip to content

Commit 0c14644

Browse files
authored
modify api to allow expressing if previous entrypoints should be overridden (#103)
modify api to allow expressing if previous entrypoints should be overridden or not
1 parent feb3ef3 commit 0c14644

4 files changed

Lines changed: 173 additions & 127 deletions

File tree

docs/docs.md

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,6 @@
22

33
public API
44

5-
<a id="oci_image"></a>
6-
7-
## oci_image
8-
9-
<pre>
10-
load("@rules_oci//oci:defs.bzl", "oci_image")
11-
12-
oci_image(<a href="#oci_image-name">name</a>, <a href="#oci_image-annotations">annotations</a>, <a href="#oci_image-arch">arch</a>, <a href="#oci_image-base">base</a>, <a href="#oci_image-entrypoint">entrypoint</a>, <a href="#oci_image-env">env</a>, <a href="#oci_image-labels">labels</a>, <a href="#oci_image-layers">layers</a>, <a href="#oci_image-os">os</a>, <a href="#oci_image-stamp">stamp</a>, <a href="#oci_image-tars">tars</a>)
13-
</pre>
14-
15-
Creates a new image manifest and config by appending the `layers` to an existing image
16-
manifest and config defined by `base`. If `base` is an image index, then `os` and `arch` will
17-
be used to extract the image manifest.
18-
19-
**ATTRIBUTES**
20-
21-
22-
| Name | Description | Type | Mandatory | Default |
23-
| :------------- | :------------- | :------------- | :------------- | :------------- |
24-
| <a id="oci_image-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
25-
| <a id="oci_image-annotations"></a>annotations | [OCI Annotations](https://github.com/opencontainers/image-spec/blob/main/annotations.md) to add to the manifest. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | `{}` |
26-
| <a id="oci_image-arch"></a>arch | Used to extract a manifest from base if base is an index | String | optional | `""` |
27-
| <a id="oci_image-base"></a>base | A base image, as defined by oci_pull or oci_image | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
28-
| <a id="oci_image-entrypoint"></a>entrypoint | A list of entrypoints for the image; these will be inserted into the generated OCI image config | List of strings | optional | `[]` |
29-
| <a id="oci_image-env"></a>env | Entries are in the format of `VARNAME=VARVALUE`. These values act as defaults and are merged with any specified when creating a container. | List of strings | optional | `[]` |
30-
| <a id="oci_image-labels"></a>labels | labels that will be applied to the image configuration, as defined in [the OCI config](https://github.com/opencontainers/image-spec/blob/main/config.md#properties). These behave the same way as [docker LABEL](https://docs.docker.com/engine/reference/builder/#label); in particular, labels from the base image are inherited. An empty value for a label will cause that label to be deleted. For backwards compatibility, if this is not set, then the value of annotations will be used instead. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | `{}` |
31-
| <a id="oci_image-layers"></a>layers | A list of layers defined by oci_image_layer | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
32-
| <a id="oci_image-os"></a>os | Used to extract a manifest from base if base is an index | String | optional | `""` |
33-
| <a id="oci_image-stamp"></a>stamp | Whether to encode build information into the output. Possible values:<br><br>- `stamp = 1`: Always stamp the build information into the output, even in [--nostamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) builds. This setting should be avoided, since it is non-deterministic. It potentially causes remote cache misses for the target and any downstream actions that depend on the result. - `stamp = 0`: Never stamp, instead replace build information by constant values. This gives good build result caching. - `stamp = -1`: Embedding of build information is controlled by the [--[no]stamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) flag. Stamped targets are not rebuilt unless their dependencies change. | Integer | optional | `-1` |
34-
| <a id="oci_image-tars"></a>tars | A list of tars to add as layers | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
35-
36-
375
<a id="oci_image_config"></a>
386

397
## oci_image_config
@@ -167,6 +135,41 @@ not be an issue when using the `oci_image` rule).
167135
The config file named after the rule, os, and arch
168136

169137

138+
<a id="oci_image"></a>
139+
140+
## oci_image
141+
142+
<pre>
143+
load("@rules_oci//oci:defs.bzl", "oci_image")
144+
145+
oci_image(<a href="#oci_image-name">name</a>, <a href="#oci_image-base">base</a>, <a href="#oci_image-annotations">annotations</a>, <a href="#oci_image-arch">arch</a>, <a href="#oci_image-entrypoint">entrypoint</a>, <a href="#oci_image-env">env</a>, <a href="#oci_image-labels">labels</a>, <a href="#oci_image-layers">layers</a>, <a href="#oci_image-os">os</a>, <a href="#oci_image-tars">tars</a>, <a href="#oci_image-kwargs">kwargs</a>)
146+
</pre>
147+
148+
oci_image
149+
150+
Creates a new image manifest and config by appending the `layers` to an
151+
existing image manifest and config defined by `base`. If `base` is an image
152+
index, then `os` and `arch` will be used to extract the image manifest.
153+
154+
155+
**PARAMETERS**
156+
157+
158+
| Name | Description | Default Value |
159+
| :------------- | :------------- | :------------- |
160+
| <a id="oci_image-name"></a>name | The name of the rule. | none |
161+
| <a id="oci_image-base"></a>base | A base image, as defined by oci_pull or oci_image. | none |
162+
| <a id="oci_image-annotations"></a>annotations | OCI Annotations to add to the manifest. | `None` |
163+
| <a id="oci_image-arch"></a>arch | Used to extract a manifest from base if base is an index. | `None` |
164+
| <a id="oci_image-entrypoint"></a>entrypoint | A list of entrypoints for the image; these will be inserted into the generated container configuration. | `None` |
165+
| <a id="oci_image-env"></a>env | Entries are in the format of `VARNAME=VARVALUE`. These values act as defaults and are merged with any specified when creating a container. | `None` |
166+
| <a id="oci_image-labels"></a>labels | Labels that will be applied to the image configuration, as defined in the OCI config. These behave the same way as docker LABEL. In particular, labels from the base image are inherited. An empty value for a label will cause that label to be deleted. For backwards compatibility, if this is not set, then the value of annotations will be used instead. | `None` |
167+
| <a id="oci_image-layers"></a>layers | A list of layers defined by oci_image_layer. | `None` |
168+
| <a id="oci_image-os"></a>os | Used to extract a manifest from base if base is an index. | `None` |
169+
| <a id="oci_image-tars"></a>tars | A list of tars to add as layers. | `None` |
170+
| <a id="oci_image-kwargs"></a>kwargs | Additional keyword arguments, e.g. tags or visibility | none |
171+
172+
170173
<a id="oci_image_layer"></a>
171174

172175
## oci_image_layer

go/cmd/ocitool/appendlayer_cmd.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,18 +207,16 @@ func AppendLayersCmd(c *cli.Context) error {
207207
layerDescs = append(layerDescs, tarDesc)
208208
}
209209

210-
var entrypoint []string
211-
if entrypoint_file := c.String("entrypoint"); entrypoint_file != "" {
210+
var entrypoint *[]string
211+
if entrypointPath := c.String("entrypoint"); entrypointPath != "" {
212212
var entrypointStruct struct {
213213
Entrypoint []string `json:"entrypoint"`
214214
}
215-
216-
err := jsonutil.DecodeFromFile(entrypoint_file, &entrypointStruct)
215+
err := jsonutil.DecodeFromFile(entrypointPath, &entrypointStruct)
217216
if err != nil {
218217
return fmt.Errorf("failed to read entrypoint config file: %w", err)
219218
}
220-
221-
entrypoint = entrypointStruct.Entrypoint
219+
entrypoint = &entrypointStruct.Entrypoint
222220
}
223221

224222
outIngestor := layer.NewAppendIngester(c.String("out-manifest"), c.String("out-config"))

go/pkg/layer/append.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func AppendLayers(
2828
labels map[string]string,
2929
env []string,
3030
created time.Time,
31-
entrypoint []string,
31+
entrypoint *[]string,
3232
platform ocispec.Platform,
3333
) (ocispec.Descriptor, ocispec.Descriptor, error) {
3434
if annotations == nil {
@@ -136,7 +136,9 @@ func AppendLayers(
136136
imageConfig.History = append(imageConfig.History, history...)
137137

138138
imageConfig.Author = "rules_oci"
139-
imageConfig.Config.Entrypoint = entrypoint
139+
if entrypoint != nil {
140+
imageConfig.Config.Entrypoint = *entrypoint
141+
}
140142
imageConfig.Config.Env = append(imageConfig.Config.Env, env...)
141143

142144
newConfig, err := ociutil.IngestorJSONEncode(

oci/image.bzl

Lines changed: 130 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,65 @@
33
load("@aspect_bazel_lib//lib:stamping.bzl", "STAMP_ATTRS", "maybe_stamp")
44
load("@com_github_datadog_rules_oci//oci:providers.bzl", "OCIDescriptor", "OCILayout")
55

6+
def oci_image(
7+
name,
8+
base,
9+
annotations = None,
10+
arch = None,
11+
entrypoint = None,
12+
env = None,
13+
labels = None,
14+
layers = None,
15+
os = None,
16+
tars = None,
17+
**kwargs):
18+
""" oci_image
19+
20+
Creates a new image manifest and config by appending the `layers` to an
21+
existing image manifest and config defined by `base`. If `base` is an image
22+
index, then `os` and `arch` will be used to extract the image manifest.
23+
24+
Args:
25+
name: The name of the rule.
26+
base: A base image, as defined by oci_pull or oci_image.
27+
annotations: OCI Annotations to add to the manifest.
28+
arch: Used to extract a manifest from base if base is an index.
29+
entrypoint: A list of entrypoints for the image; these will be inserted
30+
into the generated container configuration.
31+
env: Entries are in the format of `VARNAME=VARVALUE`. These values act
32+
as defaults and are merged with any specified when creating a
33+
container.
34+
labels: Labels that will be applied to the image configuration, as
35+
defined in the OCI config. These behave the same way as docker
36+
LABEL. In particular, labels from the base image are inherited. An
37+
empty value for a label will cause that label to be deleted. For
38+
backwards compatibility, if this is not set, then the value of
39+
annotations will be used instead.
40+
layers: A list of layers defined by oci_image_layer.
41+
os: Used to extract a manifest from base if base is an index.
42+
tars: A list of tars to add as layers.
43+
**kwargs: Additional keyword arguments, e.g. tags or visibility
44+
"""
45+
if entrypoint == None:
46+
entrypoint_override = False
47+
else:
48+
entrypoint_override = True
49+
50+
_oci_image(
51+
name = name,
52+
base = base,
53+
annotations = annotations,
54+
arch = arch,
55+
entrypoint = entrypoint,
56+
entrypoint_override = entrypoint_override,
57+
env = env,
58+
labels = labels,
59+
layers = layers,
60+
os = os,
61+
tars = tars,
62+
**kwargs
63+
)
64+
665
# buildifier: disable=function-docstring
766
def get_descriptor_file(ctx, desc):
867
if hasattr(desc, "descriptor_file"):
@@ -98,16 +157,6 @@ def _oci_image_impl(ctx):
98157
config_file = ctx.actions.declare_file("{}.config.json".format(ctx.label.name))
99158
layout_file = ctx.actions.declare_file("{}.layout.json".format(ctx.label.name))
100159

101-
entrypoint_config_file = ctx.actions.declare_file("{}.entrypoint.config.json".format(ctx.label.name))
102-
entrypoint_config = struct(
103-
entrypoint = ctx.attr.entrypoint,
104-
)
105-
106-
ctx.actions.write(
107-
output = entrypoint_config_file,
108-
content = json.encode(entrypoint_config),
109-
)
110-
111160
annotations = ctx.attr.annotations
112161

113162
# Backwards compatibility: code that doesn't use the labels attr will expect annotations to be
@@ -132,44 +181,69 @@ def _oci_image_impl(ctx):
132181
if maybe_stamp(ctx):
133182
stamp_args.append("--bazel-version-file={}".format(ctx.version_file.path))
134183

184+
arguments = [
185+
"--layout={}".format(base_layout.blob_index.path),
186+
"append-layers",
187+
"--base={}".format(base_desc.path),
188+
"--os={}".format(ctx.attr.os),
189+
"--arch={}".format(ctx.attr.arch),
190+
"--out-manifest={}".format(manifest_file.path),
191+
"--out-config={}".format(config_file.path),
192+
"--out-layout={}".format(layout_file.path),
193+
"--outd={}".format(manifest_desc_file.path),
194+
] + [
195+
"--layer={}={}".format(layer, descriptor)
196+
for layer, descriptor in layer_and_descriptor_paths
197+
] + [
198+
"--tar={}".format(tar.path)
199+
for tar in tars
200+
] + [
201+
"--annotations={}={}".format(k, v)
202+
for k, v in annotations.items()
203+
] + [
204+
"--labels={}={}".format(k, v)
205+
for k, v in labels.items()
206+
] + [
207+
"--env={}".format(env)
208+
for env in ctx.attr.env
209+
] + stamp_args
210+
211+
default_info_files = [
212+
config_file,
213+
layout_file,
214+
manifest_desc_file,
215+
manifest_file,
216+
]
217+
218+
inputs = [
219+
ctx.version_file,
220+
base_desc,
221+
base_layout.blob_index,
222+
] + ctx.files.layers + layer_descriptor_files + base_layout.files.to_list() + tars
223+
224+
if ctx.attr.entrypoint_override:
225+
entrypoint_config_file = ctx.actions.declare_file("{}.entrypoint.config.json".format(ctx.label.name))
226+
entrypoint_config = struct(
227+
entrypoint = ctx.attr.entrypoint,
228+
)
229+
ctx.actions.write(
230+
output = entrypoint_config_file,
231+
content = json.encode(entrypoint_config),
232+
)
233+
arguments.append("--entrypoint={}".format(entrypoint_config_file.path))
234+
default_info_files.append(entrypoint_config_file)
235+
inputs.append(entrypoint_config_file)
236+
135237
ctx.actions.run(
136238
executable = toolchain.sdk.ocitool,
137-
arguments = [
138-
"--layout={}".format(base_layout.blob_index.path),
139-
"append-layers",
140-
"--base={}".format(base_desc.path),
141-
"--os={}".format(ctx.attr.os),
142-
"--arch={}".format(ctx.attr.arch),
143-
"--out-manifest={}".format(manifest_file.path),
144-
"--out-config={}".format(config_file.path),
145-
"--out-layout={}".format(layout_file.path),
146-
"--outd={}".format(manifest_desc_file.path),
147-
"--entrypoint={}".format(entrypoint_config_file.path),
148-
] +
149-
[
150-
"--layer={}={}".format(layer, descriptor)
151-
for layer, descriptor in layer_and_descriptor_paths
152-
] +
153-
["--tar={}".format(tar.path) for tar in tars] +
154-
["--annotations={}={}".format(k, v) for k, v in annotations.items()] +
155-
["--labels={}={}".format(k, v) for k, v in labels.items()] +
156-
["--env={}".format(env) for env in ctx.attr.env] +
157-
stamp_args,
158-
inputs = [
159-
ctx.version_file,
160-
base_desc,
161-
base_layout.blob_index,
162-
entrypoint_config_file,
163-
] + ctx.files.layers +
164-
layer_descriptor_files +
165-
base_layout.files.to_list() +
166-
tars,
239+
arguments = arguments,
240+
inputs = inputs,
167241
mnemonic = "OCIImageAppendLayers",
168242
outputs = [
169-
manifest_file,
170243
config_file,
171244
layout_file,
172245
manifest_desc_file,
246+
manifest_file,
173247
],
174248
)
175249

@@ -180,72 +254,41 @@ def _oci_image_impl(ctx):
180254
OCILayout(
181255
blob_index = layout_file,
182256
files = depset(
183-
ctx.files.layers + ctx.files.tars + [manifest_file, config_file, layout_file],
257+
ctx.files.layers + ctx.files.tars + [
258+
manifest_file,
259+
config_file,
260+
layout_file,
261+
],
184262
transitive = [base_layout.files],
185263
),
186264
),
187265
DefaultInfo(
188-
files = depset([
189-
entrypoint_config_file,
190-
manifest_file,
191-
config_file,
192-
layout_file,
193-
manifest_desc_file,
194-
]),
266+
files = depset(default_info_files),
195267
),
196268
]
197269

198-
oci_image = rule(
270+
_oci_image = rule(
199271
implementation = _oci_image_impl,
200-
doc = """Creates a new image manifest and config by appending the `layers` to an existing image
201-
manifest and config defined by `base`. If `base` is an image index, then `os` and `arch` will
202-
be used to extract the image manifest.""",
203272
attrs = dict({
273+
"annotations": attr.string_dict(),
274+
"arch": attr.string(),
204275
"base": attr.label(
205-
doc = """A base image, as defined by oci_pull or oci_image""",
206276
mandatory = True,
207-
providers = [
208-
OCIDescriptor,
209-
OCILayout,
210-
],
211-
),
212-
"entrypoint": attr.string_list(
213-
doc = """A list of entrypoints for the image; these will be inserted into the generated
214-
OCI image config""",
215-
),
216-
"os": attr.string(
217-
doc = "Used to extract a manifest from base if base is an index",
218-
),
219-
"arch": attr.string(
220-
doc = "Used to extract a manifest from base if base is an index",
221-
),
222-
"env": attr.string_list(
223-
doc = """Entries are in the format of `VARNAME=VARVALUE`. These values act as defaults and
224-
are merged with any specified when creating a container.""",
277+
providers = [OCIDescriptor, OCILayout],
225278
),
279+
"entrypoint": attr.string_list(),
280+
"entrypoint_override": attr.bool(),
281+
"env": attr.string_list(),
282+
"labels": attr.string_dict(),
226283
"layers": attr.label_list(
227-
doc = "A list of layers defined by oci_image_layer",
228284
providers = [
229285
OCIDescriptor,
230286
],
231287
),
288+
"os": attr.string(),
232289
"tars": attr.label_list(
233-
doc = "A list of tars to add as layers",
234290
allow_files = [".tar", ".tar.gz", ".tgz", ".tar.zst"],
235291
),
236-
"annotations": attr.string_dict(
237-
doc = """[OCI Annotations](https://github.com/opencontainers/image-spec/blob/main/annotations.md)
238-
to add to the manifest.""",
239-
),
240-
"labels": attr.string_dict(
241-
doc = """labels that will be applied to the image configuration, as defined in
242-
[the OCI config](https://github.com/opencontainers/image-spec/blob/main/config.md#properties).
243-
These behave the same way as
244-
[docker LABEL](https://docs.docker.com/engine/reference/builder/#label);
245-
in particular, labels from the base image are inherited. An empty value for a label
246-
will cause that label to be deleted. For backwards compatibility, if this is not set,
247-
then the value of annotations will be used instead.""",
248-
),
249292
}, **STAMP_ATTRS),
250293
toolchains = ["@com_github_datadog_rules_oci//oci:toolchain"],
251294
provides = [OCIDescriptor, OCILayout],

0 commit comments

Comments
 (0)