Skip to content

Commit

Permalink
Merge branch 'main' into fix-linux-arm-toolchains
Browse files Browse the repository at this point in the history
  • Loading branch information
archen authored Aug 14, 2023
2 parents 7700f62 + 0f7297c commit e060819
Show file tree
Hide file tree
Showing 26 changed files with 321 additions and 57 deletions.
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ jobs:
uses: bazel-contrib/.github/.github/workflows/release_ruleset.yaml@2ded56de883b35b1e18b37566fd406625153f1e2
with:
release_files: rules_oci-*.tar.gz
prerelease: false
29 changes: 28 additions & 1 deletion .github/workflows/release_prep.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,34 @@ git archive --format=tar --prefix=${PREFIX}/ ${TAG} | gzip > $ARCHIVE
SHA=$(shasum -a 256 $ARCHIVE | awk '{print $1}')

cat << EOF
WORKSPACE snippet:
## Using bzlmod with Bazel 6 or later:
1. Add \`common --enable_bzlmod\` to \`.bazelrc\`.
2. Add to your \`MODULE.bazel\` file:
\`\`\`starlark
bazel_dep(name = "rules_oci", version = "${TAG:1}")
# For testing, we also recommend https://registry.bazel.build/modules/container_structure_test
oci = use_extension("@rules_oci//oci:extensions.bzl", "oci")
# Declare external images you need to pull, for example:
oci.pull(
name = "distroless_base",
# 'latest' is not reproducible, but it's convenient.
# During the build we print a WARNING message that includes recommended 'digest' and 'platforms'
# values which you can use here in place of 'tag' to pin for reproducibility.
tag = "latest",
image = "gcr.io/distroless/base",
platforms = ["linux/amd64"],
)
# For each oci.pull call, repeat the "name" here to expose them as dependencies.
use_repo(oci, "distroless_base")
\`\`\`
## Using WORKSPACE:
\`\`\`starlark
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

This is a "barebones" alternative to [rules_docker](https://github.com/bazelbuild/rules_docker).

A lot of companies have already done a successful migration from `rules_docker`. Please let us know about yours on our adoption discussion!
<https://github.com/bazel-contrib/rules_oci/discussions/299>

We start from first principles and avoided some pitfalls we learned in maintaining that repo:

- Use a toolchain consisting of off-the-shelf, pre-built layer and container manipulation tools.
Expand All @@ -15,12 +18,11 @@ _Need help?_ This ruleset has support provided by https://aspect.dev.

## Installation

- Bazel >= 6.2.0 with `--enable_bzlmod`: start from <https://registry.bazel.build/modules/rules_oci>
- Others: Copy the WORKSPACE snippet into your `WORKSPACE` file from a release: <https://github.com/bazel-contrib/rules_oci/releases>
See the install instructions on the release notes: <https://github.com/bazel-contrib/rules_oci/releases>

To use a commit rather than a release, you can point at any SHA of the repo.

For example to use commit `abc123`:
With bzlmod, you can use `archive_override` or `git_override`. For `WORKSPACE`, you modify the `http_archive` call; for example to use commit `abc123` with a `WORKSPACE` file:

1. Replace `url = "https://github.com/bazel-contrib/rules_oci/releases/download/v0.1.0/rules_oci-v0.1.0.tar.gz"`
with a GitHub-provided source archive like `url = "https://github.com/bazel-contrib/rules_oci/archive/abc123.tar.gz"`
Expand Down
2 changes: 1 addition & 1 deletion docs/push.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ stamp_tags(
oci_push(
image = ":app_image",
repository = "ghcr.io/<OWNER>/image",
tags = ":stamped",
remote_tags = ":stamped",
)
```

Expand Down
4 changes: 1 addition & 3 deletions docs/static_content.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,7 @@ oci_image(
## Try running the container with docker

```bash
# File created by running bazel build //frontend:frontend_tarball
tarball_file=""
docker load --input "$tarball_file"
bazel run :frontend_tarball
docker run --rm -p 8080:80 "ourfrontend:latest"
```

Expand Down
5 changes: 2 additions & 3 deletions docs/tarball.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ oci_tarball(
and then run it in a container like so:

```
bazel build //path/to:tarball
docker load --input $(bazel cquery --output=files //path/to:tarball)
bazel run :tarball
docker run --rm my-repository:latest
```

Expand All @@ -41,6 +40,6 @@ Passing anything other than oci_image to the image attribute will lead to build
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="oci_tarball-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
| <a id="oci_tarball-image"></a>image | Label of a directory containing an OCI layout, typically <code>oci_image</code> | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |
| <a id="oci_tarball-repo_tags"></a>repo_tags | a file containing repo_tags, one per line. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="oci_tarball-repo_tags"></a>repo_tags | a file containing repo_tags, one per line. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |


3 changes: 1 addition & 2 deletions e2e/wasm/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ build_test(

# In order to run the image you need to follow instructions at https://docs.docker.com/desktop/wasm/ first.
# then run the following;
# `bazel build :tarball`
# `docker load -i bazel-bin/tarball/tarball.tar`
# `bazel run :tarball``
# `docker run --runtime=io.containerd.wasmedge.v1 --platform=wasi/wasm32 --pull=never gcr.io/wasm:latest`
oci_tarball(
name = "tarball",
Expand Down
31 changes: 25 additions & 6 deletions examples/deb/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
load("//oci:defs.bzl", "oci_image")
load("//oci:defs.bzl", "oci_image", "oci_tarball")

_ARCH = [
"amd64",
"arm64",
]

# crane doesn't do the right thing with compressed tarball inputs like .tar.gz or .tar.xz
[
genrule(
name = "decompress_" + architecture,
srcs = ["@bash_{}//:layer".format(architecture)],
outs = ["_{}.tar".format(architecture)],
cmd = "xz --decompress --stdout $< >$@",
)
for architecture in _ARCH
]

[
oci_image(
name = "image_" + architecture,
architecture = architecture,
os = "linux",
tars = ["@bash_{}//:layer".format(architecture)],
tars = ["_{}.tar".format(architecture)],
)
for architecture in [
"amd64",
"arm64",
]
for architecture in _ARCH
]

oci_tarball(
name = "tarball",
image = ":image_amd64",
repo_tags = ["test:test"],
)
30 changes: 29 additions & 1 deletion examples/empty_base/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
load("//oci:defs.bzl", "oci_image", "oci_tarball")
load("@aspect_bazel_lib//lib:testing.bzl", "assert_json_matches")
load("@bazel_skylib//rules:write_file.bzl", "write_file")
load("@container_structure_test//:defs.bzl", "container_structure_test")

oci_image(
Expand All @@ -24,8 +26,34 @@ container_structure_test(
image = ":image",
)

repo_tags = [
"gcr.io/empty_base:latest",
"two:is_a_company",
"three:is_a_crowd", # Used to test support for more than two repo_tags.
]

oci_tarball(
name = "tarball",
image = ":image",
repo_tags = ["gcr.io/empty_base:latest"],
repo_tags = repo_tags,
)

genrule(
name = "tar_manifest",
srcs = [":tarball"],
outs = ["manifest.json"],
cmd = "tar -xOf ./$(location :tarball) manifest.json > $@",
)

write_file(
name = "expected_RepoTags",
out = "expected_RepoTags.json",
content = [str(repo_tags)],
)

assert_json_matches(
name = "check_tags",
file1 = ":tar_manifest",
file2 = ":expected_RepoTags",
filter1 = ".[0].RepoTags",
)
44 changes: 44 additions & 0 deletions examples/repo_tags/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
load("//oci:defs.bzl", "oci_image", "oci_tarball")
load("@aspect_bazel_lib//lib:testing.bzl", "assert_json_matches")
load("@bazel_skylib//rules:write_file.bzl", "write_file")

oci_image(
name = "image",
architecture = select({
"@platforms//cpu:arm64": "arm64",
"@platforms//cpu:x86_64": "amd64",
}),
os = "linux",
)

repo_tags = [
"gcr.io/empty_base:latest",
"two:is_a_company",
"three:is_a_crowd", # Used to test support for more than two repo_tags.
]

oci_tarball(
name = "tarball",
image = ":image",
repo_tags = ":tags_file.txt", # In particular we check whether empty (last line) of the file gets ignored.
)

genrule(
name = "tar_manifest",
srcs = [":tarball"],
outs = ["manifest.json"],
cmd = "tar -xOf ./$(location :tarball) manifest.json > $@",
)

write_file(
name = "expected_RepoTags",
out = "expected_RepoTags.json",
content = [str(repo_tags)],
)

assert_json_matches(
name = "check_tags",
file1 = ":tar_manifest",
file2 = ":expected_RepoTags",
filter1 = ".[0].RepoTags",
)
6 changes: 6 additions & 0 deletions examples/repo_tags/tags_file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
gcr.io/empty_base:latest


two:is_a_company

three:is_a_crowd
8 changes: 8 additions & 0 deletions examples/repo_tags/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
schemaVersion: "2.0.0"

metadataTest:
envVars:
- key: "ENV"
value: "/test"
entrypoint: ["/custom_bin"]
cmd: ["--arg1", "--arg2"]
10 changes: 4 additions & 6 deletions oci/private/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@ exports_files(
visibility = ["//docs:__pkg__"],
)

exports_files([
"image.sh.tpl",
"image_index.sh.tpl",
"tarball.sh.tpl",
"push.sh.tpl",
])
exports_files(glob(["*.tpl"]) + ["empty.tar"])

bzl_library(
name = "tarball",
Expand All @@ -19,6 +14,7 @@ bzl_library(
"//docs:__pkg__",
"//oci:__subpackages__",
],
deps = [":util"],
)

bzl_library(
Expand All @@ -28,6 +24,7 @@ bzl_library(
"//docs:__pkg__",
"//oci:__subpackages__",
],
deps = [":util"],
)

bzl_library(
Expand Down Expand Up @@ -94,6 +91,7 @@ bzl_library(
name = "auth_config_locator",
srcs = ["auth_config_locator.bzl"],
visibility = ["//oci:__subpackages__"],
deps = ["@aspect_bazel_lib//lib:repo_utils"],
)

bzl_library(
Expand Down
8 changes: 6 additions & 2 deletions oci/private/auth_config_locator.bzl
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
"repository rule that locates the .docker/config.json or containers/auth.json file."

load("@aspect_bazel_lib//lib:repo_utils.bzl", "repo_utils")

def _file_exists(rctx, path):
result = rctx.execute(["stat", path])
return result.return_code == 0

# Path of the auth file is determined by the order described here;
# https://github.com/google/go-containerregistry/tree/main/pkg/authn#tldr-for-consumers-of-this-package
def _get_auth_file_path(rctx):
HOME = repo_utils.get_env_var(rctx, "HOME", "ERR_NO_HOME_SET")

# this is the standard path where registry credentials are stored
# https://docs.docker.com/engine/reference/commandline/cli/#configuration-files
DOCKER_CONFIG = "{}/.docker".format(rctx.os.environ["HOME"])
DOCKER_CONFIG = "{}/.docker".format(HOME)

# set DOCKER_CONFIG to $DOCKER_CONFIG env if present
if "DOCKER_CONFIG" in rctx.os.environ:
Expand All @@ -21,7 +25,7 @@ def _get_auth_file_path(rctx):
return config_path

# https://docs.podman.io/en/latest/markdown/podman-login.1.html#authfile-path
XDG_RUNTIME_DIR = "{}/.config".format(rctx.os.environ["HOME"])
XDG_RUNTIME_DIR = "{}/.config".format(HOME)

# set XDG_RUNTIME_DIR to $XDG_RUNTIME_DIR env if present
if "XDG_RUNTIME_DIR" in rctx.os.environ:
Expand Down
18 changes: 12 additions & 6 deletions oci/private/download.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ def _auth_to_header(url, auth):
if auth_url == url:
auth_val = auth[auth_url]

if "type" not in auth_val:
continue

if auth_val["type"] == "basic":
credentials = base64.encode("{}:{}".format(auth_val["login"], auth_val["password"]))
return [
Expand Down Expand Up @@ -72,7 +75,8 @@ def _download(
command = [
"curl",
url,
"--fail-with-body",
"--write-out",
"%{http_code}",
"--location",
"--no-progress-meter",
"--request",
Expand All @@ -92,12 +96,14 @@ def _download(

result = rctx.execute(command)

_debug("""\nSTDOUT\n{}\nSTDERR\n{}""".format(result.stdout, result.stderr))
status_code = int(result.stdout.strip())
_debug("""\nSTATUS\n{}\nSTDOUT\n{}\nSTDERR\n{}""".format(status_code, result.stdout, result.stderr))

if result.return_code != 0 and allow_fail:
return struct(success = False)
elif result.return_code != 0 and not allow_fail:
fail("Failed to fetch {} {}".format(url, result.stderr))
if result.return_code != 0 or status_code >= 400:
if allow_fail:
return struct(success = False)
else:
fail("Failed to fetch {} {}".format(url, result.stderr))

cache_it = rctx.download(
url = "file://{}".format(output_path),
Expand Down
Binary file added oci/private/empty.tar
Binary file not shown.
Loading

0 comments on commit e060819

Please sign in to comment.