Skip to content

Commit

Permalink
Add multi-arch image via Bazel
Browse files Browse the repository at this point in the history
  • Loading branch information
mattmoor committed Oct 8, 2020
1 parent 0ef3a6b commit c9cb67f
Show file tree
Hide file tree
Showing 13 changed files with 325 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
out/
bazel-*
*~
BUILD.bazel
.idea
*.iml
.vagrant
24 changes: 24 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
language: go
os: linux
dist: bionic

env:
global:
- IMAGE_REPO=localhost:5000 REGISTRY=localhost:5000
Expand Down Expand Up @@ -35,3 +36,26 @@ jobs:
- make travis-setup
script:
- make integration-test-misc

- arch: amd64
env: CPU=k8
before_install:
- export PATH=$PATH:$HOME/bin && mkdir -p $HOME/bin
- eval $(go env)
# install bazelisk as bazel to install the appropriate bazel version
- wget https://github.com/bazelbuild/bazelisk/releases/download/v1.6.1/bazelisk-linux-${GOARCH} && chmod +x bazelisk-linux-${GOARCH} && mv bazelisk-linux-${GOARCH} $HOME/bin/bazel
script:
# Generate BUILD.bazel files (we do not check them in)
- bazel run //:gazelle
- bazel build --cpu=${CPU} --curses=no //...
# Build all targets tagged with our architecture:
- bazel build --cpu=${CPU} --curses=no $(bazel query 'attr("tags", "'${GOARCH}'", "//...")')
# Run all tests not tagged as "manual":
- bazel test --cpu=${CPU} --curses=no --test_output=errors --test_timeout=900 //...
# Run all tests tagged with our architecture:
- bazel test --cpu=${CPU} --curses=no --test_output=errors --test_timeout=900 $(bazel query 'attr("tags", "'${GOARCH}'", "//...")')

# - arch: arm64
# env: CPU=aarch64
# before_install: *before_install_multiarch
# script: *script_multiarch
4 changes: 4 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
load("@bazel_gazelle//:def.bzl", "gazelle")

# gazelle:prefix github.com/GoogleContainerTools/kaniko
gazelle(name = "gazelle")
53 changes: 53 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
workspace(name = "kaniko")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "io_bazel_rules_go",
sha256 = "b725e6497741d7fc2d55fcc29a276627d10e43fa5d0bb692692890ae30d98d00",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.24.3/rules_go-v0.24.3.tar.gz",
"https://github.com/bazelbuild/rules_go/releases/download/v0.24.3/rules_go-v0.24.3.tar.gz",
],
)

http_archive(
name = "bazel_gazelle",
sha256 = "b85f48fa105c4403326e9525ad2b2cc437babaa6e15a3fc0b1dbab0ab064bc7c",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.22.2/bazel-gazelle-v0.22.2.tar.gz",
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.22.2/bazel-gazelle-v0.22.2.tar.gz",
],
)

load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")

go_rules_dependencies()

go_register_toolchains()

gazelle_dependencies()

# Docker rules.
http_archive(
name = "io_bazel_rules_docker",
sha256 = "cf53839c398e464b10ec2fbeb11aedb446f078c28e3b4ce372461bb105ef435c",
strip_prefix = "rules_docker-f8478e57ab7457e403fda474f06ac0bb120d92a7",
urls = ["https://github.com/bazelbuild/rules_docker/archive/f8478e57ab7457e403fda474f06ac0bb120d92a7.tar.gz"],
)

load(
"@io_bazel_rules_docker//repositories:repositories.bzl",
container_repositories = "repositories",
)

container_repositories()

load("@io_bazel_rules_docker//repositories:deps.bzl", container_deps = "deps")

container_deps()

load("@io_bazel_rules_docker//repositories:pip_repositories.bzl", "pip_deps")

pip_deps()
126 changes: 126 additions & 0 deletions cmd/executor/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
load("@io_bazel_rules_docker//container:container.bzl", "container_image")

go_library(
name = "executor_lib",
srcs = ["main.go"],
importpath = "github.com/GoogleContainerTools/kaniko/cmd/executor",
visibility = ["//visibility:private"],
deps = ["//cmd/executor/cmd"],
)

go_binary(
name = "executor",
embed = [":executor_lib"],
pure = "on",
visibility = ["//visibility:public"],
)

ARCHITECTURES = [
"amd64",
"arm64",
]

[
go_binary(
name = "executor_" + arch,
embed = [":executor_lib"],
goarch = arch,
goos = "linux",
pure = "on",
visibility = ["//visibility:public"],
)
for arch in ARCHITECTURES
]

[
container_image(
name = "image_" + arch,
architecture = arch,
base = "//files:image",
directory = "/kaniko",
entrypoint = ["/kaniko/executor_" + arch],
env = {
"HOME": "/root",
"USER": "root",
"PATH": "/usr/local/bin:/kaniko",
"SSL_CERT_DIR": "/kaniko/ssl/certs",
"DOCKER_CONFIG": "/kaniko/.docker/",
},
files = [
":executor_" + arch,
],
symlinks = {
"/kaniko/executor": "/kaniko/executor_" + arch,
},
workdir = "/workspace",
)
for arch in ARCHITECTURES
]

# Image with testdata
[
container_image(
name = "buildtest_image_" + arch,
architecture = arch,
base = ":image_" + arch,
directory = "/workspace",
files = [
":testdata/Dockerfile.trivial",
],
)
for arch in ARCHITECTURES
]

load("@io_bazel_rules_docker//contrib:test.bzl", "container_test")

# Non-executable tests can run on any architecture,
# so do not tag them.
[
container_test(
name = "image_files_" + arch + "_test",
configs = ["testdata/files.yaml"],
image = ":image_" + arch,
# tags = ["manual", arch],
)
for arch in ARCHITECTURES
]

[
container_test(
name = "buildtest_image_" + arch + "_test",
configs = [
"testdata/files.yaml",
"testdata/testfiles.yaml",
],
image = ":buildtest_image_" + arch,
# tags = ["manual", arch],
)
for arch in ARCHITECTURES
]

[
container_test(
name = "image_exec_" + arch + "_test",
configs = ["testdata/exec.yaml"],
image = ":image_" + arch,
tags = [
"manual",
arch,
],
)
for arch in ARCHITECTURES
]

[
container_test(
name = "image_build_" + arch + "_test",
configs = ["testdata/build.yaml"],
image = ":buildtest_image_" + arch,
tags = [
"manual",
arch,
],
)
for arch in ARCHITECTURES
]
6 changes: 4 additions & 2 deletions cmd/executor/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,10 @@ var RootCmd = &cobra.Command{
}
logrus.Warn("kaniko is being run outside of a container. This can have dangerous effects on your system")
}
if err := executor.CheckPushPermissions(opts); err != nil {
exit(errors.Wrap(err, "error checking push permissions -- make sure you entered the correct tag name, and that you are authenticated correctly, and try again"))
if !opts.NoPush {
if err := executor.CheckPushPermissions(opts); err != nil {
exit(errors.Wrap(err, "error checking push permissions -- make sure you entered the correct tag name, and that you are authenticated correctly, and try again"))
}
}
if err := resolveRelativePaths(); err != nil {
exit(errors.Wrap(err, "error resolving relative paths to absolute paths"))
Expand Down
2 changes: 2 additions & 0 deletions cmd/executor/testdata/Dockerfile.trivial
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FROM ubuntu
RUN echo Hello
5 changes: 5 additions & 0 deletions cmd/executor/testdata/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
schemaVersion: "1.0.0"
commandTests:
- name: Trivial build
command: ["/kaniko/executor", "--no-push", "--dockerfile", "./Dockerfile.trivial"]
exitCode: 0
10 changes: 10 additions & 0 deletions cmd/executor/testdata/exec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
schemaVersion: "1.0.0"
commandTests:
- name: check fixed name
command: ["/kaniko/executor"]
expectedError: ['Usage:']
exitCode: 1
- name: check PATH
command: ["executor"]
expectedError: ['Usage:']
exitCode: 1
12 changes: 12 additions & 0 deletions cmd/executor/testdata/files.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
schemaVersion: "1.0.0"
fileExistenceTests:
# Basic FS sanity checks.
- name: root
path: '/'
shouldExist: true
- name: certs
path: '/kaniko/ssl/certs/ca-certificates.crt'
shouldExist: true
- name: certs
path: '/etc/nsswitch.conf'
shouldExist: true
6 changes: 6 additions & 0 deletions cmd/executor/testdata/testfiles.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
schemaVersion: "1.0.0"
fileExistenceTests:
# Basic FS sanity checks.
- name: trivial testdata Dockerfile
path: '/workspace/Dockerfile.trivial'
shouldExist: true
60 changes: 60 additions & 0 deletions deploy/cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
steps:

# First, build kaniko
- name: "gcr.io/cloud-builders/docker"
args: ["build", "-f", "deploy/Dockerfile",
Expand All @@ -14,9 +15,68 @@ steps:
- name: "gcr.io/cloud-builders/docker"
args: ["build", "-f", "deploy/Dockerfile_warmer",
"-t", "gcr.io/$PROJECT_ID/${_WARMER_IMAGE_NAME}:${COMMIT_SHA}", "."]


# Build each of the multi-arch images with Bazel and load them into the Docker daemon.
- name: gcr.io/cloud-marketplace-containers/google/bazel:3.4.1
entrypoint: sh
args:
- -c
- |
#!/bin/sh
set -o errexit
set -o xtrace
bazel run //:gazelle
bazel run --host_force_python=PY2 //cmd/executor:image_amd64
bazel run --host_force_python=PY2 //cmd/executor:image_arm64
# Publish the individual container images
- name: docker
entrypoint: sh
args:
- -c
- |
#!/bin/sh
set -o errexit
set -o xtrace
docker tag bazel/cmd/executor:image_amd64 gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:amd64
docker tag bazel/cmd/executor:image_arm64 gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:arm64
docker push gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:amd64
docker push gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:arm64
# Enable "manifest list" support in docker, and publish one covering the per-architecture
# images published above.
- name: docker
entrypoint: sh
args:
- -c
- |
#!/bin/sh
set -o errexit
set -o xtrace
# Publish manifest lists second, after all of the binary material
# has been uploaded, so that it is fast. We want fast because enabling
# the experimental features in docker changes ~/.docker/config.json, which
# GCB periodically tramples.
#
# Enable support for 'docker manifest create'
# https://docs.docker.com/engine/reference/commandline/manifest_create/
sed -i 's/^{/{"experimental": "enabled",/g' ~/.docker/config.json
docker manifest create gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:multi-arch \
gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:amd64 \
gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:arm64
docker manifest push gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:multi-arch
images: ["gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:${COMMIT_SHA}",
"gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:debug-${COMMIT_SHA}",
"gcr.io/$PROJECT_ID/${_WARMER_IMAGE_NAME}:${COMMIT_SHA}"]

substitutions:
_EXECUTOR_IMAGE_NAME: executor
_WARMER_IMAGE_NAME: warmer
16 changes: 16 additions & 0 deletions files/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
load("@io_bazel_rules_docker//container:container.bzl", "container_image")

container_image(
name = "nsswitch",
directory = "etc",
files = [":nsswitch.conf"],
visibility = ["//visibility:private"],
)

container_image(
name = "image",
base = ":nsswitch",
directory = "kaniko/ssl/certs",
files = [":ca-certificates.crt"],
visibility = ["//visibility:public"],
)

0 comments on commit c9cb67f

Please sign in to comment.