Skip to content

Commit

Permalink
feat: demonstrate a replacement for go_image (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeagle authored Feb 24, 2023
1 parent 428b743 commit 27b6aef
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 23 deletions.
1 change: 1 addition & 0 deletions e2e/custom_registry/.bazelrc
6 changes: 3 additions & 3 deletions e2e/custom_registry/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ rules_pkg_dependencies()
load("@contrib_rules_oci//oci:pull.bzl", "oci_pull")

oci_pull(
name = "distroless_static",
digest = "sha256:c3c3d0230d487c0ad3a0d87ad03ee02ea2ff0b3dcce91ca06a1019e07de05f12",
image = "gcr.io/distroless/static",
name = "distroless_base",
digest = "sha256:ccaef5ee2f1850270d453fdf700a5392534f8d1a8ca2acda391fbb6a06b81c86",
image = "gcr.io/distroless/base",
platforms = [
"linux/amd64",
"linux/arm64",
Expand Down
57 changes: 57 additions & 0 deletions e2e/custom_registry/app/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
load("@aspect_bazel_lib//lib:transitions.bzl", "platform_transition_filegroup")
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
load("@contrib_rules_oci//oci:defs.bzl", "oci_image", "oci_tarball")
load("@rules_pkg//:pkg.bzl", "pkg_tar")

go_library(
name = "app_lib",
srcs = ["main.go"],
importpath = "example.com/custom_registry/app",
visibility = ["//visibility:private"],
deps = ["@com_github_google_go_cmp//cmp"],
)

go_binary(
name = "app",
embed = [":app_lib"],
visibility = ["//visibility:public"],
)

pkg_tar(
name = "tar",
srcs = [":app"],
)

platform_transition_filegroup(
name = "transition",
srcs = [":tar"],
target_platform = select({
"@platforms//cpu:arm64": "@io_bazel_rules_go//go/toolchain:linux_arm64",
"@platforms//cpu:x86_64": "@io_bazel_rules_go//go/toolchain:linux_amd64",
}),
)

oci_image(
name = "image",
architecture = select({
"@platforms//cpu:arm64": "arm64",
"@platforms//cpu:x86_64": "amd64",
}),
base = "@distroless_base",
entrypoint = ["/app"],
os = "linux",
tars = [":transition"],
)

# $ bazel build app:tarball
# $ docker load --input $(bazel cquery --output=files app:tarball)
# $ docker run --rm gcr.io/example:latest
# string(
# - "Hello World",
# + "Hello Go",
# )
oci_tarball(
name = "tarball",
image = ":image",
repotags = ["gcr.io/example:latest"],
)
10 changes: 10 additions & 0 deletions e2e/custom_registry/app/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package main

import (
"fmt"
"github.com/google/go-cmp/cmp"
)

func main() {
fmt.Println(cmp.Diff("Hello World", "Hello Go"))
}
19 changes: 0 additions & 19 deletions e2e/custom_registry/image/BUILD.bazel

This file was deleted.

2 changes: 1 addition & 1 deletion e2e/custom_registry/registry/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ go_library(
srcs = ["registry.go"],
importpath = "example.com/custom_registry/registry",
visibility = ["//visibility:private"],
deps = ["@com_github_google_go_containerregistry//pkg/registry:go_default_library"],
deps = ["@com_github_google_go_containerregistry//pkg/registry"],
)

go_binary(
Expand Down
1 change: 1 addition & 0 deletions e2e/custom_registry/registry/registry.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Workaround https://github.com/google/go-containerregistry/issues/1579
package main

import (
Expand Down
92 changes: 92 additions & 0 deletions examples/go/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Go example

This is an example of how to migrate from
[`go_image`](https://github.com/bazelbuild/rules_docker#go_image) in rules_docker.

## Base image

First, you'll need a base image.

It's wise to minimize changes by using the same one your current `go_image` uses.
The logic for choosing the default base in rules_docker is in
[https://github.com/bazelbuild/rules_docker/blob/fc729d85f284225cfc0b8c6d1d838f4b3e037749/go/image.bzl#L114](go_image.bzl)

Or, you can just use bazel query to find out:

```
$ bazel query --output=build hello_world:hello_world_go_image
Starting local Bazel server and connecting to it...
# /home/alexeagle/Projects/hello_world/BUILD.bazel:22:9
_app_layer(
name = "hello_world_go_image",
base = select({"@io_bazel_rules_docker//:debug": "@go_debug_image_base//image:image", "@io_bazel_rules_docker//:fastbuild": "@go_image_base//image:image", "@io_bazel_rules_docker//:optimized": "@go_image_base//image:image", "//conditions:default": "@go_image_base//image:image"}),
...
)
```

Since we don't use the "debug" config, this tells us that we use `@go_base_image`, we need one more lookup to see what that uses:

```
$ bazel query --output=build @go_image_base//image:image
# /shared/cache/bazel/user_base/bf7b6accf6f1187bd5511f3fbf7b21b9/external/go_image_base/image/BUILD:4:17
container_import(
name = "image",
base_image_registry = "gcr.io",
base_image_repository = "distroless/base",
...
)
```

Now that we know it's `gcr.io/distroless/base` we can pull the same base image by adding to WORKSPACE:

```
load("@contrib_rules_oci//oci:pull.bzl", "oci_pull")
oci_pull(
name = "distroless_base",
digest = "sha256:ccaef5ee2f1850270d453fdf700a5392534f8d1a8ca2acda391fbb6a06b81c86",
image = "gcr.io/distroless/base",
platforms = ["linux/amd64","linux/arm64"],
)
```

See more details in the [oci_pull docs](/docs/pull.md)

## The go_image

rules_docker makes you repeat the attributes of `go_binary` into `go_layer`.
This is a "layering violation" (get it?).

In rules_oci, you just start from a normal `go_binary` (typically by having Gazelle write it).
For this example let's say it's `go_binary(name = "app", ...)`.

Next, put that file into a layer, which is just a `.tar` file:

```
load("@rules_pkg//:pkg.bzl", "pkg_tar")
pkg_tar(
name = "tar",
srcs = [":app"],
)
```

Finally, add your layer to the base image:

```
load("@contrib_rules_oci//oci:defs.bzl", "oci_image")
oci_image(
name = "image",
architecture = select({
"@platforms//cpu:arm64": "arm64",
"@platforms//cpu:x86_64": "amd64",
}),
base = "@distroless_base",
tars = [":tar"],
entrypoint = ["/app"],
os = "linux",
)
```

See the complete example in /e2e/custom_registry.

0 comments on commit 27b6aef

Please sign in to comment.