summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdin Scannell <ascannell@google.com>2020-04-24 14:10:28 -0700
committergVisor bot <gvisor-bot@google.com>2020-04-24 14:11:42 -0700
commitc60613475c92185c9b15468d0de87b321ef2b4d7 (patch)
tree470683d83c53ee44c174a06b5f673e5e19e1a38f
parentf13f26d17da56d585fd9857a81175bbd0be8ce60 (diff)
Standardize all Docker images.
This change moves all Docker images to a standard location, and abstracts the build process so that they can be maintained in an automated fashion. This also allows the images to be architecture-independent. All images will now be referred to by the test framework via the canonical `gvisor.dev/images/<name>`, where `<name>` is a function of the path within the source tree. In a subsequent change, continuous integration will be added so that the images will always be correct and available locally. In the end, using `bazel` for Docker containers is simply not possible. Given that we already have the need to use `make` with the base container (for Docker), we extend this approach to get more flexibility. This change also adds a self-documenting and powerful Makefile that is intended to replace the collection of scripts in scripts. Canonical (self-documenting) targets can be added here for targets that understand which images need to be loaded and/or built. PiperOrigin-RevId: 308322438
-rw-r--r--.travis.yml11
-rw-r--r--CONTRIBUTING.md31
-rw-r--r--Dockerfile9
-rw-r--r--Makefile199
-rw-r--r--images/BUILD11
-rw-r--r--images/Makefile93
-rw-r--r--images/README.md61
-rw-r--r--images/basic/alpine/Dockerfile1
-rw-r--r--images/basic/busybox/Dockerfile1
-rw-r--r--images/basic/httpd/Dockerfile1
-rw-r--r--images/basic/mysql/Dockerfile1
-rw-r--r--images/basic/nginx/Dockerfile1
-rw-r--r--images/basic/python/Dockerfile2
-rw-r--r--images/basic/resolv/Dockerfile1
-rw-r--r--images/basic/ruby/Dockerfile1
-rw-r--r--images/basic/tomcat/Dockerfile1
-rw-r--r--images/basic/ubuntu/Dockerfile1
-rw-r--r--images/default/Dockerfile11
-rw-r--r--images/iptables/Dockerfile2
-rw-r--r--images/packetdrill/Dockerfile (renamed from test/packetdrill/Dockerfile)1
-rw-r--r--images/packetimpact/Dockerfile (renamed from test/packetimpact/tests/Dockerfile)1
-rw-r--r--images/runtimes/go1.12/Dockerfile4
-rw-r--r--images/runtimes/java11/Dockerfile (renamed from test/runtimes/images/Dockerfile_java11)8
-rw-r--r--images/runtimes/nodejs12.4.0/Dockerfile (renamed from test/runtimes/images/Dockerfile_nodejs12.4.0)9
-rw-r--r--images/runtimes/php7.3.6/Dockerfile (renamed from test/runtimes/images/Dockerfile_php7.3.6)8
-rw-r--r--images/runtimes/python3.7.3/Dockerfile (renamed from test/runtimes/images/Dockerfile_python3.7.3)9
-rw-r--r--pkg/test/testutil/testutil.go38
-rwxr-xr-xscripts/build.sh4
-rwxr-xr-xscripts/common.sh22
-rwxr-xr-xscripts/docker_tests.sh2
-rwxr-xr-xscripts/hostnet_tests.sh2
-rwxr-xr-xscripts/iptables_tests.sh6
-rwxr-xr-xscripts/kvm_tests.sh2
-rwxr-xr-xscripts/make_tests.sh5
-rwxr-xr-xscripts/overlay_tests.sh2
-rwxr-xr-xscripts/packetdrill_tests.sh2
-rwxr-xr-xscripts/packetimpact_tests.sh2
-rwxr-xr-xscripts/root_tests.sh3
-rwxr-xr-xscripts/swgso_tests.sh2
-rw-r--r--test/iptables/runner/Dockerfile4
-rw-r--r--test/root/BUILD1
-rw-r--r--test/runtimes/images/Dockerfile_go1.1210
-rw-r--r--tools/bazel.mk106
-rw-r--r--tools/installers/BUILD8
-rwxr-xr-xtools/installers/images.sh24
-rwxr-xr-xtools/make_repository.sh31
-rw-r--r--tools/vm/defs.bzl5
47 files changed, 559 insertions, 201 deletions
diff --git a/.travis.yml b/.travis.yml
index acbd3d61b..40c8773fa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,22 +1,19 @@
-language: minimal
-sudo: required
+language: shell
dist: xenial
cache:
directories:
- /home/travis/.cache/bazel/
+os: linux
services:
- docker
-matrix:
+jobs:
include:
- os: linux
arch: amd64
- env: RUNSC_PATH=./bazel-bin/runsc/linux_amd64_pure_stripped/runsc
- os: linux
arch: arm64
- env: RUNSC_PATH=./bazel-bin/runsc/linux_arm64_pure_stripped/runsc
script:
- - uname -a
- - make DOCKER_RUN_OPTIONS="" BAZEL_OPTIONS="build runsc:runsc" bazel && $RUNSC_PATH --alsologtostderr --network none --debug --TESTONLY-unsafe-nonroot=true --rootless do ls
+ - uname -a && make smoke-test
branches:
except:
# Skip copybara branches.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ad8e710da..423cf7a34 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -108,32 +108,15 @@ ignored.
### Build and test with Docker
-`scripts/dev.sh` is a convenient script that builds and installs `runsc` as a
-new Docker runtime for you. The scripts tries to extract the runtime name from
-your local environment and will print it at the end. You can also customize it.
-The script creates one regular runtime and another with debug flags enabled.
-Here are a few examples:
+Running `make dev` is a convenient way to build and install `runsc` as a Docker
+runtime. The output of this command will show the runtimes installed.
+
+You may use `make refresh` to refresh the binary after any changes. For example:
```bash
-# Default case (inside branch my-branch)
-$ scripts/dev.sh
-...
-Runtimes my-branch and my-branch-d (debug enabled) setup.
-Use --runtime=my-branch with your Docker command.
- docker run --rm --runtime=my-branch --rm hello-world
-
-If you rebuild, use scripts/dev.sh --refresh.
-Logs are in: /tmp/my-branch/logs
-
-# --refresh just updates the runtime binary and doesn't restart docker.
-$ git/my_branch> scripts/dev.sh --refresh
-
-# Using a custom runtime name
-$ git/my_branch> scripts/dev.sh my-runtime
-...
-Runtimes my-runtime and my-runtime-d (debug enabled) setup.
-Use --runtime=my-runtime with your Docker command.
- docker run --rm --runtime=my-runtime --rm hello-world
+make dev
+docker run --rm --runtime=my-branch --rm hello-world
+make refresh
```
### The small print
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 0fac71710..000000000
--- a/Dockerfile
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM fedora:31
-
-RUN dnf install -y dnf-plugins-core && dnf copr enable -y vbatts/bazel
-
-RUN dnf install -y bazel2 git gcc make golang gcc-c++ glibc-devel python3 which python3-pip python3-devel libffi-devel openssl-devel pkg-config glibc-static libstdc++-static patch
-
-RUN pip install pycparser
-
-WORKDIR /gvisor
diff --git a/Makefile b/Makefile
index d9531fbd5..c56c6ed48 100644
--- a/Makefile
+++ b/Makefile
@@ -1,50 +1,173 @@
-UID := $(shell id -u ${USER})
-GID := $(shell id -g ${USER})
-GVISOR_BAZEL_CACHE := $(shell readlink -f ~/.cache/bazel/)
+#!/usr/bin/make -f
-# The --privileged is required to run tests.
-DOCKER_RUN_OPTIONS ?= --privileged
+# Copyright 2019 The gVisor Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
-all: runsc
+# Described below.
+OPTIONS :=
+TARGETS := //runsc
+ARGS :=
-docker-build:
- docker build -t gvisor-bazel .
+default: runsc
+.PHONY: default
-bazel-shutdown:
- docker exec -i gvisor-bazel bazel shutdown && \
- docker kill gvisor-bazel
+## usage: make <target>
+## or
+## make <build|test|copy|run|sudo> OPTIONS="..." TARGETS="..." ARGS="..."
+##
+## Basic targets.
+##
+## This Makefile wraps basic build and test targets for ease-of-use. Bazel
+## is run inside a canonical Docker container in order to simplify up-front
+## requirements.
+##
+## There are common arguments that may be passed to targets. These are:
+## OPTIONS - Build or test options.
+## TARGETS - The bazel targets.
+## ARGS - Arguments for run or sudo.
+##
+## Additionally, the copy target expects a DESTINATION to be provided.
+##
+## For example, to build runsc using this Makefile, you can run:
+## make build OPTIONS="" TARGETS="//runsc"'
+##
+help: ## Shows all targets and help from the Makefile (this message).
+ @grep --no-filename -E '^([a-z.A-Z_-]+:.*?|)##' $(MAKEFILE_LIST) | \
+ awk 'BEGIN {FS = "(:.*?|)## ?"}; { \
+ if (length($$1) > 0) { \
+ printf " \033[36m%-20s\033[0m %s\n", $$1, $$2; \
+ } else { \
+ printf "%s\n", $$2; \
+ } \
+ }'
+build: ## Builds the given $(TARGETS) with the given $(OPTIONS). E.g. make build TARGETS=runsc
+test: ## Tests the given $(TARGETS) with the given $(OPTIONS). E.g. make test TARGETS=pkg/buffer:buffer_test
+copy: ## Copies the given $(TARGETS) to the given $(DESTINATION). E.g. make copy TARGETS=runsc DESTINATION=/tmp
+run: ## Runs the given $(TARGETS), built with $(OPTIONS), using $(ARGS). E.g. make run TARGETS=runsc ARGS=-version
+sudo: ## Runs the given $(TARGETS) as per run, but using "sudo -E". E.g. make sudo TARGETS=test/root:root_test ARGS=-test.v
+.PHONY: help build test copy run sudo
-bazel-server-start: docker-build
- mkdir -p "$(GVISOR_BAZEL_CACHE)" && \
- docker run -d --rm --name gvisor-bazel \
- --user 0:0 \
- -v "$(GVISOR_BAZEL_CACHE):$(HOME)/.cache/bazel/" \
- -v "$(CURDIR):$(CURDIR)" \
- --workdir "$(CURDIR)" \
- --tmpfs /tmp:rw,exec \
- $(DOCKER_RUN_OPTIONS) \
- gvisor-bazel \
- sh -c "while :; do sleep 100; done" && \
- docker exec --user 0:0 -i gvisor-bazel sh -c "groupadd --gid $(GID) --non-unique gvisor && useradd --uid $(UID) --non-unique --gid $(GID) -d $(HOME) gvisor"
+# Load all bazel wrappers.
+#
+# This file should define the basic "build", "test", "run" and "sudo" rules, in
+# addition to the $(BRANCH_NAME) variable.
+ifneq (,$(wildcard tools/google.mk))
+include tools/google.mk
+else
+include tools/bazel.mk
+endif
-bazel-server:
- docker exec gvisor-bazel true || \
- $(MAKE) bazel-server-start
+##
+## Docker image targets.
+##
+## Images used by the tests must also be built and available locally.
+## The canonical test targets defined below will automatically load
+## relevant images. These can be loaded or built manually via these
+## targets.
+##
+## (*) Note that you may provide an ARCH parameter in order to build
+## and load images from an alternate archiecture (using qemu). When
+## bazel is run as a server, this has the effect of running an full
+## cross-architecture chain, and can produce cross-compiled binaries.
+##
+define images
+$(1)-%: ## Image tool: $(1) a given image (also may use 'all-images').
+ @$(MAKE) -C images $$@
+endef
+rebuild-...: ## Rebuild the given image. Also may use 'rebuild-all-images'.
+$(eval $(call images,rebuild))
+push-...: ## Push the given image. Also may use 'push-all-images'.
+$(eval $(call images,pull))
+pull-...: ## Pull the given image. Also may use 'pull-all-images'.
+$(eval $(call images,push))
+load-...: ## Load (pull or rebuild) the given image. Also may use 'load-all-images'.
+$(eval $(call images,load))
+list-images: ## List all available images.
+ @$(MAKE) -C images $$@
-BAZEL_OPTIONS := build runsc
-bazel: bazel-server
- docker exec -u $(UID):$(GID) -i gvisor-bazel bazel $(BAZEL_OPTIONS)
+##
+## Canonical build and test targets.
+##
+## These targets are used by continuous integration and provide
+## convenient entrypoints for testing changes. If you're adding a
+## new subsystem or workflow, consider adding a new target here.
+##
+runsc: ## Builds the runsc binary.
+ @$(MAKE) build TARGETS="//runsc"
+.PHONY: runsc
-bazel-alias:
- @echo "alias bazel='docker exec -u $(UID):$(GID) -i gvisor-bazel bazel'"
+smoke-test: ## Runs a simple smoke test after build runsc.
+ @$(MAKE) run DOCKER_RUN_OPTIONS="" ARGS="--alsologtostderr --network none --debug --TESTONLY-unsafe-nonroot=true --rootless do true"
+.PHONY: smoke-tests
-runsc:
- $(MAKE) BAZEL_OPTIONS="build runsc" bazel
+unit-tests: ## Runs all unit tests in pkg runsc and tools.
+ @$(MAKE) test OPTIONS="pkg/... runsc/... tools/..."
+.PHONY: unit-tests
-tests:
- $(MAKE) BAZEL_OPTIONS="test --test_tag_filters runsc_ptrace //test/syscalls/..." bazel
+tests: ## Runs all local ptrace system call tests.
+ @$(MAKE) test OPTIONS="--test_tag_filter runsc_ptrace test/syscalls/..."
+.PHONY: tests
-unit-tests:
- $(MAKE) BAZEL_OPTIONS="test //pkg/... //runsc/... //tools/..." bazel
+##
+## Development helpers and tooling.
+##
+## These targets faciliate local development by automatically
+## installing and configuring a runtime. Several variables may
+## be used here to tweak the installation:
+## RUNTIME - The name of the installed runtime (default: branch).
+## RUNTIME_DIR - Where the runtime will be installed (default: temporary directory with the $RUNTIME).
+## RUNTIME_BIN - The runtime binary (default: $RUNTIME_DIR/runsc).
+## RUNTIME_LOG_DIR - The logs directory (default: $RUNTIME_DIR/logs).
+## RUNTIME_LOGS - The log pattern (default: $RUNTIME_LOG_DIR/runsc.log.%TEST%.%TIMESTAMP%.%COMMAND%).
+##
+ifeq (,$(BRANCH_NAME))
+RUNTIME := runsc
+RUNTIME_DIR := $(shell dirname $(shell mktemp -u))/runsc
+else
+RUNTIME := $(BRANCH_NAME)
+RUNTIME_DIR := $(shell dirname $(shell mktemp -u))/$(BRANCH_NAME)
+endif
+RUNTIME_BIN := $(RUNTIME_DIR)/runsc
+RUNTIME_LOG_DIR := $(RUNTIME_DIR)/logs
+RUNTIME_LOGS := $(RUNTIME_LOG_DIR)/runsc.log.%TEST%.%TIMESTAMP%.%COMMAND%
-.PHONY: docker-build bazel-shutdown bazel-server-start bazel-server bazel runsc tests
+dev: ## Installs a set of local runtimes. Requires sudo.
+ @$(MAKE) refresh ARGS="--net-raw"
+ @$(MAKE) configure RUNTIME="$(RUNTIME)" ARGS="--net-raw"
+ @$(MAKE) configure RUNTIME="$(RUNTIME)-d" ARGS="--net-raw --debug --strace --log-packets"
+ @$(MAKE) configure RUNTIME="$(RUNTIME)-p" ARGS="--net-raw --profile"
+ @sudo systemctl restart docker
+.PHONY: dev
+
+refresh: ## Refreshes the runtime binary (for development only). Must have called 'dev' or 'test-install' first.
+ @mkdir -p "$(RUNTIME_DIR)"
+ @$(MAKE) copy TARGETS=runsc DESTINATION="$(RUNTIME_BIN)" && chmod 0755 "$(RUNTIME_BIN)"
+.PHONY: install
+
+test-install: ## Installs the runtime for testing. Requires sudo.
+ @$(MAKE) refresh ARGS="--net-raw --TESTONLY-test-name-env=RUNSC_TEST_NAME --debug --strace --log-packets $(ARGS)"
+ @$(MAKE) configure
+ @sudo systemctl restart docker
+.PHONY: install-test
+
+configure: ## Configures a single runtime. Requires sudo. Typically called from dev or test-install.
+ @sudo sudo "$(RUNTIME_BIN)" install --experimental=true --runtime="$(RUNTIME)" -- --debug-log "$(RUNTIME_LOGS)" $(ARGS)
+ @echo "Installed runtime \"$(RUNTIME)\" @ $(RUNTIME_BIN)"
+ @echo "Logs are in: $(RUNTIME_LOG_DIR)"
+ @sudo rm -rf "$(RUNTIME_LOG_DIR)" && mkdir -p "$(RUNTIME_LOG_DIR)"
+.PHONY: configure
+
+test-runtime: ## A convenient wrapper around test that provides the runtime argument. Target must still be provided.
+ @$(MAKE) test OPTIONS="$(OPTIONS) --test_arg=--runtime=$(RUNTIME)"
+.PHONY: runtime-test
diff --git a/images/BUILD b/images/BUILD
new file mode 100644
index 000000000..a50f388e9
--- /dev/null
+++ b/images/BUILD
@@ -0,0 +1,11 @@
+package(licenses = ["notice"])
+
+# The images filegroup is definitely not a hermetic target, and requires Make
+# to do anything meaningful with. However, this will be slurped up and used by
+# the tools/installer/images.sh installer, which will ensure that all required
+# images are available locally when running vm_tests.
+filegroup(
+ name = "images",
+ srcs = glob(["**"]),
+ visibility = ["//tools/installers:__pkg__"],
+)
diff --git a/images/Makefile b/images/Makefile
new file mode 100644
index 000000000..1485607bd
--- /dev/null
+++ b/images/Makefile
@@ -0,0 +1,93 @@
+#!/usr/bin/make -f
+
+# Copyright 2018 The gVisor Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# ARCH is the architecture used for the build. This may be overriden at the
+# command line in order to perform a cross-build (in a limited capacity).
+ARCH := $(shell uname -m)
+
+# Note that the image prefixes used here must match the image mangling in
+# runsc/testutil.MangleImage. Names are mangled in this way to ensure that all
+# tests are using locally-defined images (that are consistent and idempotent).
+REMOTE_IMAGE_PREFIX ?= gcr.io/gvisor-presubmit
+LOCAL_IMAGE_PREFIX ?= gvisor.dev/images
+ALL_IMAGES := $(subst /,_,$(subst ./,,$(shell find . -name Dockerfile -exec dirname {} \;)))
+ifneq ($(ARCH),$(shell uname -m))
+DOCKER_PLATFORM_ARGS := --platform=$(ARCH)
+else
+DOCKER_PLATFORM_ARGS :=
+endif
+
+list-all-images:
+ @for image in $(ALL_IMAGES); do echo $${image}; done
+.PHONY: list-build-images
+
+%-all-images:
+ @$(MAKE) $(patsubst %,$*-%,$(ALL_IMAGES))
+
+# tag is a function that returns the tag name, given an image.
+#
+# The tag constructed is used to memoize the image generated (see README.md).
+# This scheme is used to enable aggressive caching in a central repository, but
+# ensuring that images will always be sourced using the local files if there
+# are changes.
+path = $(subst _,/,$(1))
+tag = $(shell find $(call path,$(1)) -type f -print | sort | xargs -n 1 sha256sum | sha256sum - | cut -c 1-16)
+remote_image = $(REMOTE_IMAGE_PREFIX)/$(subst _,/,$(1))_$(ARCH):$(call tag,$(1))
+local_image = $(LOCAL_IMAGE_PREFIX)/$(subst _,/,$(1))
+
+# rebuild builds the image locally. Only the "remote" tag will be applied. Note
+# we need to explicitly repull the base layer in order to ensure that the
+# architecture is correct. Note that we use the term "rebuild" here to avoid
+# conflicting with the bazel "build" terminology, which is used elsewhere.
+rebuild-%: register-cross
+ FROM=$(shell grep FROM $(call path,$*)/Dockerfile | cut -d' ' -f2-) && \
+ docker pull $(DOCKER_PLATFORM_ARGS) $$FROM
+ T=$$(mktemp -d) && cp -a $(call path,$*)/* $$T && \
+ docker build $(DOCKER_PLATFORM_ARGS) -t $(call remote_image,$*) $$T && \
+ rm -rf $$T
+
+# pull will check the "remote" image and pull if necessary. If the remote image
+# must be pulled, then it will tag with the latest local target. Note that pull
+# may fail if the remote image is not available.
+pull-%:
+ docker pull $(DOCKER_PLATFORM_ARGS) $(call remote_image,$*)
+
+# load will either pull the "remote" or build it locally. This is the preferred
+# entrypoint, as it should never file. The local tag should always be set after
+# this returns (either by the pull or the build).
+load-%:
+ docker inspect $(call remote_image,$*) >/dev/null 2>&1 || $(MAKE) pull-$* || $(MAKE) rebuild-$*
+ docker tag $(call remote_image,$*) $(call local_image,$*)
+
+# push pushes the remote image, after either pulling (to validate that the tag
+# already exists) or building manually.
+push-%: load-%
+ docker push $(call remote_image,$*)
+
+# register-cross registers the necessary qemu binaries for cross-compilation.
+# This may be used by any target that may execute containers that are not the
+# native format.
+register-cross:
+ifneq ($(ARCH),$(shell uname -m))
+ifeq (,$(wildcard /proc/sys/fs/binfmt_misc/qemu-*))
+ docker run --rm --privileged multiarch/qemu-user-static --reset --persistent yes
+else
+ @true # Already registered.
+endif
+else
+ @true # No cross required.
+endif
+.PHONY: register-cross
diff --git a/images/README.md b/images/README.md
new file mode 100644
index 000000000..d2efb5db4
--- /dev/null
+++ b/images/README.md
@@ -0,0 +1,61 @@
+# Container Images
+
+This directory contains all images used by tests.
+
+Note that all these images must be pushed to the testing project hosted on
+[Google Container Registry][gcr]. This will happen automatically as part of
+continuous integration. This will speed up loading as images will not need to be
+built from scratch for each test run.
+
+Image tooling is accessible via `make`, specifically via `tools/images.mk`.
+
+## Why make?
+
+Make is used because it can bootstrap the `default` image, which contains
+`bazel` and all other parts of the toolchain.
+
+## Listing images
+
+To list all images, use `make list-all-images` from the top-level directory.
+
+## Loading and referencing images
+
+To build a specific image, use `make load-<image>` from the top-level directory.
+This will ensure that an image `gvisor.dev/images/<image>:latest` is available.
+
+Images should always be referred to via the `gvisor.dev/images` canonical path.
+This tag exists only locally, but serves to decouple tests from the underlying
+image infrastructure.
+
+The continuous integration system can either take fine-grained dependencies on
+single images via individual `load` targets, or pull all images via a single
+`load-all-images` invocation.
+
+## Adding new images
+
+To add a new image, create a new directory under `images` containing a
+Dockerfile and any other files that the image requires. You may choose to add to
+an existing subdirectory if applicable, or create a new one.
+
+All images will be tagged and memoized using a hash of the directory contents.
+As a result, every image should be made completely reproducible if possible.
+This means using fixed tags and fixed versions whenever feasible.
+
+Notes that images should also be made architecture-independent if possible. The
+build scripts will handling loading the appropriate architecture onto the
+machine and tagging it with the single canonical tag.
+
+Add a `load-<image>` dependency in the Makefile if the image is required for a
+particular set of tests. This target will pull the tag from the image repository
+if available.
+
+## Building and pushing images
+
+All images can be built manually by running `build-<image>` and pushed using
+`push-<image>`. Note that you can also use `build-all-images` and
+`push-all-images`. Note that pushing will require appropriate permissions in the
+project.
+
+The continuous integration system can either take fine-grained dependencies on
+individual `push` targets, or ensure all images are up-to-date with a single
+`push-all-images` invocation.
diff --git a/images/basic/alpine/Dockerfile b/images/basic/alpine/Dockerfile
new file mode 100644
index 000000000..12b26040a
--- /dev/null
+++ b/images/basic/alpine/Dockerfile
@@ -0,0 +1 @@
+FROM alpine:3.11.5
diff --git a/images/basic/busybox/Dockerfile b/images/basic/busybox/Dockerfile
new file mode 100644
index 000000000..79b3f683a
--- /dev/null
+++ b/images/basic/busybox/Dockerfile
@@ -0,0 +1 @@
+FROM busybox:1.31.1
diff --git a/images/basic/httpd/Dockerfile b/images/basic/httpd/Dockerfile
new file mode 100644
index 000000000..83bc0ed88
--- /dev/null
+++ b/images/basic/httpd/Dockerfile
@@ -0,0 +1 @@
+FROM httpd:2.4.43
diff --git a/images/basic/mysql/Dockerfile b/images/basic/mysql/Dockerfile
new file mode 100644
index 000000000..95da9c48d
--- /dev/null
+++ b/images/basic/mysql/Dockerfile
@@ -0,0 +1 @@
+FROM mysql:8.0.19
diff --git a/images/basic/nginx/Dockerfile b/images/basic/nginx/Dockerfile
new file mode 100644
index 000000000..af2e62526
--- /dev/null
+++ b/images/basic/nginx/Dockerfile
@@ -0,0 +1 @@
+FROM nginx:1.17.9
diff --git a/images/basic/python/Dockerfile b/images/basic/python/Dockerfile
new file mode 100644
index 000000000..acf07cca9
--- /dev/null
+++ b/images/basic/python/Dockerfile
@@ -0,0 +1,2 @@
+FROM python:3
+ENTRYPOINT ["python", "-m", "http.server", "8080"]
diff --git a/images/basic/resolv/Dockerfile b/images/basic/resolv/Dockerfile
new file mode 100644
index 000000000..13665bdaf
--- /dev/null
+++ b/images/basic/resolv/Dockerfile
@@ -0,0 +1 @@
+FROM k8s.gcr.io/busybox:latest
diff --git a/images/basic/ruby/Dockerfile b/images/basic/ruby/Dockerfile
new file mode 100644
index 000000000..d290418fb
--- /dev/null
+++ b/images/basic/ruby/Dockerfile
@@ -0,0 +1 @@
+FROM ruby:2.7.1
diff --git a/images/basic/tomcat/Dockerfile b/images/basic/tomcat/Dockerfile
new file mode 100644
index 000000000..c7db39a36
--- /dev/null
+++ b/images/basic/tomcat/Dockerfile
@@ -0,0 +1 @@
+FROM tomcat:8.0
diff --git a/images/basic/ubuntu/Dockerfile b/images/basic/ubuntu/Dockerfile
new file mode 100644
index 000000000..331b71343
--- /dev/null
+++ b/images/basic/ubuntu/Dockerfile
@@ -0,0 +1 @@
+FROM ubuntu:trusty
diff --git a/images/default/Dockerfile b/images/default/Dockerfile
new file mode 100644
index 000000000..2d0bb5ba5
--- /dev/null
+++ b/images/default/Dockerfile
@@ -0,0 +1,11 @@
+FROM fedora:31
+RUN dnf install -y dnf-plugins-core && dnf copr enable -y vbatts/bazel
+RUN dnf install -y git gcc make golang gcc-c++ glibc-devel python3 which python3-pip python3-devel libffi-devel openssl-devel pkg-config glibc-static libstdc++-static patch
+RUN pip install pycparser
+RUN dnf install -y bazel3
+RUN curl https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-289.0.0-linux-x86_64.tar.gz | \
+ tar zxvf - google-cloud-sdk && \
+ google-cloud-sdk/install.sh && \
+ ln -s /google-cloud-sdk/bin/gcloud /usr/bin/gcloud
+WORKDIR /workspace
+ENTRYPOINT ["/usr/bin/bazel"]
diff --git a/images/iptables/Dockerfile b/images/iptables/Dockerfile
new file mode 100644
index 000000000..efd91cb80
--- /dev/null
+++ b/images/iptables/Dockerfile
@@ -0,0 +1,2 @@
+FROM ubuntu
+RUN apt update && apt install -y iptables
diff --git a/test/packetdrill/Dockerfile b/images/packetdrill/Dockerfile
index 4b75e9527..7a006c85f 100644
--- a/test/packetdrill/Dockerfile
+++ b/images/packetdrill/Dockerfile
@@ -1,5 +1,4 @@
FROM ubuntu:bionic
-
RUN apt-get update && apt-get install -y net-tools git iptables iputils-ping \
netcat tcpdump jq tar bison flex make
RUN hash -r
diff --git a/test/packetimpact/tests/Dockerfile b/images/packetimpact/Dockerfile
index 9075bc555..87aa99ef2 100644
--- a/test/packetimpact/tests/Dockerfile
+++ b/images/packetimpact/Dockerfile
@@ -1,5 +1,4 @@
FROM ubuntu:bionic
-
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
# iptables to disable OS native packet processing.
iptables \
diff --git a/images/runtimes/go1.12/Dockerfile b/images/runtimes/go1.12/Dockerfile
new file mode 100644
index 000000000..cb2944062
--- /dev/null
+++ b/images/runtimes/go1.12/Dockerfile
@@ -0,0 +1,4 @@
+# Go is easy, since we already have everything we need to compile the proctor
+# binary and run the tests in the golang Docker image.
+FROM golang:1.12
+RUN ["go", "tool", "dist", "test", "-compile-only"]
diff --git a/test/runtimes/images/Dockerfile_java11 b/images/runtimes/java11/Dockerfile
index 9b7c3d5a3..03bc8aaf1 100644
--- a/test/runtimes/images/Dockerfile_java11
+++ b/images/runtimes/java11/Dockerfile
@@ -1,8 +1,3 @@
-# Compile the proctor binary.
-FROM golang:1.12 AS golang
-ADD ["proctor/", "/go/src/proctor/"]
-RUN ["go", "build", "-o", "/proctor", "/go/src/proctor"]
-
FROM ubuntu:bionic
RUN apt-get update && apt-get install -y \
autoconf \
@@ -25,6 +20,3 @@ RUN set -ex \
RUN curl -o jtreg.tar.gz https://ci.adoptopenjdk.net/view/Dependencies/job/jtreg/lastSuccessfulBuild/artifact/jtreg-4.2.0-tip.tar.gz
RUN tar -xzf jtreg.tar.gz
ENV PATH="/root/jtreg/bin:$PATH"
-
-COPY --from=golang /proctor /proctor
-ENTRYPOINT ["/proctor", "--runtime=java"]
diff --git a/test/runtimes/images/Dockerfile_nodejs12.4.0 b/images/runtimes/nodejs12.4.0/Dockerfile
index 26f68b487..d17924b62 100644
--- a/test/runtimes/images/Dockerfile_nodejs12.4.0
+++ b/images/runtimes/nodejs12.4.0/Dockerfile
@@ -1,8 +1,3 @@
-# Compile the proctor binary.
-FROM golang:1.12 AS golang
-ADD ["proctor/", "/go/src/proctor/"]
-RUN ["go", "build", "-o", "/proctor", "/go/src/proctor"]
-
FROM ubuntu:bionic
RUN apt-get update && apt-get install -y \
curl \
@@ -21,8 +16,6 @@ RUN ./configure
RUN make
RUN make test-build
-COPY --from=golang /proctor /proctor
-
# Including dumb-init emulates the Linux "init" process, preventing the failure
# of tests involving worker processes.
-ENTRYPOINT ["/usr/bin/dumb-init", "/proctor", "--runtime=nodejs"]
+ENTRYPOINT ["/usr/bin/dumb-init"]
diff --git a/test/runtimes/images/Dockerfile_php7.3.6 b/images/runtimes/php7.3.6/Dockerfile
index e6b4c6329..e5f67f79c 100644
--- a/test/runtimes/images/Dockerfile_php7.3.6
+++ b/images/runtimes/php7.3.6/Dockerfile
@@ -1,8 +1,3 @@
-# Compile the proctor binary.
-FROM golang:1.12 AS golang
-ADD ["proctor/", "/go/src/proctor/"]
-RUN ["go", "build", "-o", "/proctor", "/go/src/proctor"]
-
FROM ubuntu:bionic
RUN apt-get update && apt-get install -y \
autoconf \
@@ -22,6 +17,3 @@ RUN tar -zxf php-${VERSION}.tar.gz
WORKDIR /root/php-${VERSION}
RUN ./configure
RUN make
-
-COPY --from=golang /proctor /proctor
-ENTRYPOINT ["/proctor", "--runtime=php"]
diff --git a/test/runtimes/images/Dockerfile_python3.7.3 b/images/runtimes/python3.7.3/Dockerfile
index 905cd22d7..4d1e1e221 100644
--- a/test/runtimes/images/Dockerfile_python3.7.3
+++ b/images/runtimes/python3.7.3/Dockerfile
@@ -1,10 +1,4 @@
-# Compile the proctor binary.
-FROM golang:1.12 AS golang
-ADD ["proctor/", "/go/src/proctor/"]
-RUN ["go", "build", "-o", "/proctor", "/go/src/proctor"]
-
FROM ubuntu:bionic
-
RUN apt-get update && apt-get install -y \
curl \
gcc \
@@ -25,6 +19,3 @@ RUN tar -zxf cpython-${VERSION}.tar.gz
WORKDIR /root/cpython-${VERSION}
RUN ./configure --with-pydebug
RUN make -s -j2
-
-COPY --from=golang /proctor /proctor
-ENTRYPOINT ["/proctor", "--runtime=python"]
diff --git a/pkg/test/testutil/testutil.go b/pkg/test/testutil/testutil.go
index d75ceca3d..ee8c78014 100644
--- a/pkg/test/testutil/testutil.go
+++ b/pkg/test/testutil/testutil.go
@@ -57,42 +57,10 @@ func IsCheckpointSupported() bool {
return *checkpoint
}
-// nameToActual is used by ImageByName (for now).
-var nameToActual = map[string]string{
- "basic/alpine": "alpine",
- "basic/busybox": "busybox:1.31.1",
- "basic/httpd": "httpd",
- "basic/mysql": "mysql",
- "basic/nginx": "nginx",
- "basic/python": "gcr.io/gvisor-presubmit/python-hello",
- "basic/resolv": "k8s.gcr.io/busybox",
- "basic/ruby": "ruby",
- "basic/tomcat": "tomcat:8.0",
- "basic/ubuntu": "ubuntu:trusty",
- "iptables": "gcr.io/gvisor-presubmit/iptables-test",
- "packetdrill": "gcr.io/gvisor-presubmit/packetdrill",
- "packetimpact": "gcr.io/gvisor-presubmit/packetimpact",
- "runtimes/go1.12": "gcr.io/gvisor-presubmit/go1.12",
- "runtimes/java11": "gcr.io/gvisor-presubmit/java11",
- "runtimes/nodejs12.4.0": "gcr.io/gvisor-presubmit/nodejs12.4.0",
- "runtimes/php7.3.6": "gcr.io/gvisor-presubmit/php7.3.6",
- "runtimes/python3.7.3": "gcr.io/gvisor-presubmit/python3.7.3",
-}
-
-// ImageByName mangles the image name used locally.
-//
-// For now, this is implemented as a static lookup table. In a subsequent
-// change, this will be used to reference a locally-generated image.
+// ImageByName mangles the image name used locally. This depends on the image
+// build infrastructure in images/ and tools/vm.
func ImageByName(name string) string {
- actual, ok := nameToActual[name]
- if !ok {
- panic(fmt.Sprintf("unknown image: %v", name))
- }
- // A terrible hack, for now execute a manual pull.
- if out, err := exec.Command("docker", "pull", actual).CombinedOutput(); err != nil {
- panic(fmt.Sprintf("error pulling image %q -> %q: %v, out: %s", name, actual, err, string(out)))
- }
- return actual
+ return fmt.Sprintf("gvisor.dev/images/%s", name)
}
// ConfigureExePath configures the executable for runsc in the test environment.
diff --git a/scripts/build.sh b/scripts/build.sh
index 7c9c99800..e821e8624 100755
--- a/scripts/build.sh
+++ b/scripts/build.sh
@@ -16,9 +16,6 @@
source $(dirname $0)/common.sh
-# Install required packages for make_repository.sh et al.
-apt_install dpkg-sig coreutils apt-utils xz-utils
-
# Build runsc.
runsc=$(build -c opt //runsc)
@@ -45,7 +42,6 @@ if [[ -v KOKORO_REPO_KEY ]]; then
repo=$(tools/make_repository.sh \
"${KOKORO_KEYSTORE_DIR}/${KOKORO_REPO_KEY}" \
gvisor-bot@google.com \
- main \
"${KOKORO_ARTIFACTS_DIR}" \
${pkgs})
fi
diff --git a/scripts/common.sh b/scripts/common.sh
index bc6ba71e8..3ca699e4a 100755
--- a/scripts/common.sh
+++ b/scripts/common.sh
@@ -84,25 +84,3 @@ function install_runsc() {
# Restart docker to pick up the new runtime configuration.
sudo systemctl restart docker
}
-
-# Installs the given packages. Note that the package names should be verified to
-# be correct, otherwise this may result in a loop that spins until time out.
-function apt_install() {
- while true; do
- sudo apt-get update &&
- sudo apt-get install -y "$@" &&
- true
- result="${?}"
- case $result in
- 0)
- break
- ;;
- 100)
- # 100 is the error code that apt-get returns.
- ;;
- *)
- exit $result
- ;;
- esac
- done
-}
diff --git a/scripts/docker_tests.sh b/scripts/docker_tests.sh
index 72ba05260..931ce1aa4 100755
--- a/scripts/docker_tests.sh
+++ b/scripts/docker_tests.sh
@@ -16,5 +16,7 @@
source $(dirname $0)/common.sh
+make load-all-images
+
install_runsc_for_test docker
test_runsc //test/image:image_test //test/e2e:integration_test
diff --git a/scripts/hostnet_tests.sh b/scripts/hostnet_tests.sh
index 41298293d..992db50dd 100755
--- a/scripts/hostnet_tests.sh
+++ b/scripts/hostnet_tests.sh
@@ -16,6 +16,8 @@
source $(dirname $0)/common.sh
+make load-all-images
+
# Install the runtime and perform basic tests.
install_runsc_for_test hostnet --network=host
test_runsc --test_arg=-checkpoint=false //test/image:image_test //test/e2e:integration_test
diff --git a/scripts/iptables_tests.sh b/scripts/iptables_tests.sh
index c8da1f32d..2a8c24907 100755
--- a/scripts/iptables_tests.sh
+++ b/scripts/iptables_tests.sh
@@ -16,6 +16,8 @@
source $(dirname $0)/common.sh
+make load-iptables
+
install_runsc_for_test iptables --net-raw
-test //test/iptables:iptables_test --test_arg=--runtime=runc
-test //test/iptables:iptables_test --test_arg=--runtime=${RUNTIME}
+test //test/iptables:iptables_test "--test_arg=--runtime=runc"
+test //test/iptables:iptables_test "--test_arg=--runtime=${RUNTIME}"
diff --git a/scripts/kvm_tests.sh b/scripts/kvm_tests.sh
index 5662401df..619571c74 100755
--- a/scripts/kvm_tests.sh
+++ b/scripts/kvm_tests.sh
@@ -16,6 +16,8 @@
source $(dirname $0)/common.sh
+make load-all-images
+
# Ensure that KVM is loaded, and we can use it.
(lsmod | grep -E '^(kvm_intel|kvm_amd)') || sudo modprobe kvm
sudo chmod a+rw /dev/kvm
diff --git a/scripts/make_tests.sh b/scripts/make_tests.sh
index 79426756d..dbf1bba77 100755
--- a/scripts/make_tests.sh
+++ b/scripts/make_tests.sh
@@ -16,10 +16,5 @@
source $(dirname $0)/common.sh
-top_level=$(git rev-parse --show-toplevel 2>/dev/null)
-[[ $? -eq 0 ]] && cd "${top_level}" || exit 1
-
-make
make runsc
-make BAZEL_OPTIONS="build //..." bazel
make bazel-shutdown
diff --git a/scripts/overlay_tests.sh b/scripts/overlay_tests.sh
index 2a1f12c0b..448864953 100755
--- a/scripts/overlay_tests.sh
+++ b/scripts/overlay_tests.sh
@@ -16,6 +16,8 @@
source $(dirname $0)/common.sh
+make load-all-images
+
# Install the runtime and perform basic tests.
install_runsc_for_test overlay --overlay
test_runsc //test/image:image_test //test/e2e:integration_test
diff --git a/scripts/packetdrill_tests.sh b/scripts/packetdrill_tests.sh
index fc6bef79c..f0fc444c8 100755
--- a/scripts/packetdrill_tests.sh
+++ b/scripts/packetdrill_tests.sh
@@ -16,5 +16,7 @@
source $(dirname $0)/common.sh
+make load-packetdrill
+
install_runsc_for_test runsc-d
test_runsc $(bazel query "attr(tags, manual, tests(//test/packetdrill/...))")
diff --git a/scripts/packetimpact_tests.sh b/scripts/packetimpact_tests.sh
index 027d11e64..17fc43f27 100755
--- a/scripts/packetimpact_tests.sh
+++ b/scripts/packetimpact_tests.sh
@@ -16,5 +16,7 @@
source $(dirname $0)/common.sh
+make load-packetimpact
+
install_runsc_for_test runsc-d
test_runsc $(bazel query "attr(tags, packetimpact, tests(//test/packetimpact/...))")
diff --git a/scripts/root_tests.sh b/scripts/root_tests.sh
index 4e4fcc76b..d629bf2aa 100755
--- a/scripts/root_tests.sh
+++ b/scripts/root_tests.sh
@@ -16,6 +16,8 @@
source $(dirname $0)/common.sh
+make load-all-images
+
# Reinstall the latest containerd shim.
declare -r base="https://storage.googleapis.com/cri-containerd-staging/gvisor-containerd-shim"
declare -r latest=$(mktemp --tmpdir gvisor-containerd-shim-latest.XXXXXX)
@@ -28,4 +30,3 @@ sudo mv ${shim_path} /usr/local/bin/gvisor-containerd-shim
# Run the tests that require root.
install_runsc_for_test root
run_as_root //test/root:root_test --runtime=${RUNTIME}
-
diff --git a/scripts/swgso_tests.sh b/scripts/swgso_tests.sh
index 0de2df1d2..c67f2fe5c 100755
--- a/scripts/swgso_tests.sh
+++ b/scripts/swgso_tests.sh
@@ -16,6 +16,8 @@
source $(dirname $0)/common.sh
+make load-all-images
+
# Install the runtime and perform basic tests.
install_runsc_for_test swgso --software-gso=true --gso=false
test_runsc //test/image:image_test //test/e2e:integration_test
diff --git a/test/iptables/runner/Dockerfile b/test/iptables/runner/Dockerfile
deleted file mode 100644
index b77db44a1..000000000
--- a/test/iptables/runner/Dockerfile
+++ /dev/null
@@ -1,4 +0,0 @@
-# This Dockerfile builds the image hosted at
-# gcr.io/gvisor-presubmit/iptables-test.
-FROM ubuntu
-RUN apt update && apt install -y iptables
diff --git a/test/root/BUILD b/test/root/BUILD
index 17e51e66e..639e293e3 100644
--- a/test/root/BUILD
+++ b/test/root/BUILD
@@ -48,6 +48,7 @@ go_test(
vm_test(
name = "root_vm_test",
+ size = "large",
shard_count = 1,
targets = [
"//tools/installers:shim",
diff --git a/test/runtimes/images/Dockerfile_go1.12 b/test/runtimes/images/Dockerfile_go1.12
deleted file mode 100644
index ab9d6abf3..000000000
--- a/test/runtimes/images/Dockerfile_go1.12
+++ /dev/null
@@ -1,10 +0,0 @@
-# Go is easy, since we already have everything we need to compile the proctor
-# binary and run the tests in the golang Docker image.
-FROM golang:1.12
-ADD ["proctor/", "/go/src/proctor/"]
-RUN ["go", "build", "-o", "/proctor", "/go/src/proctor"]
-
-# Pre-compile the tests so we don't need to do so in each test run.
-RUN ["go", "tool", "dist", "test", "-compile-only"]
-
-ENTRYPOINT ["/proctor", "--runtime=go"]
diff --git a/tools/bazel.mk b/tools/bazel.mk
new file mode 100644
index 000000000..45fbbecca
--- /dev/null
+++ b/tools/bazel.mk
@@ -0,0 +1,106 @@
+#!/usr/bin/make -f
+
+# Copyright 2018 The gVisor Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# See base Makefile.
+BRANCH_NAME := $(shell (git branch --show-current 2>/dev/null || \
+ git rev-parse --abbrev-ref HEAD 2>/dev/null) | \
+ xargs -n 1 basename 2>/dev/null)
+
+# Bazel container configuration (see below).
+USER ?= gvisor
+DOCKER_NAME ?= gvisor-bazel
+DOCKER_RUN_OPTIONS ?= --privileged
+BAZEL_CACHE := $(shell readlink -m ~/.cache/bazel/)
+GCLOUD_CONFIG := $(shell readlink -m ~/.config/gcloud/)
+DOCKER_SOCKET := /var/run/docker.sock
+
+# Non-configurable.
+UID := $(shell id -u ${USER})
+GID := $(shell id -g ${USER})
+FULL_DOCKER_RUN_OPTIONS := $(DOCKER_RUN_OPTIONS)
+FULL_DOCKER_RUN_OPTIONS += -v "$(BAZEL_CACHE):$(BAZEL_CACHE)"
+FULL_DOCKER_RUN_OPTIONS += -v "$(GCLOUD_CONFIG):$(GCLOUD_CONFIG)"
+FULL_DOCKER_RUN_OPTIONS += -v "$(DOCKER_SOCKET):$(DOCKER_SOCKET)"
+
+##
+## Bazel helpers.
+##
+## This file supports targets that wrap bazel in a running Docker
+## container to simplify development. Some options are available to
+## control the behavior of this container:
+## USER - The in-container user.
+## DOCKER_RUN_OPTIONS - Options for the container (default: --privileged, required for tests).
+## DOCKER_NAME - The container name (default: gvisor-bazel-HASH).
+## BAZEL_CACHE - The bazel cache directory (default: detected).
+## GCLOUD_CONFIG - The gcloud config directory (detect: detected).
+## DOCKER_SOCKET - The Docker socket (default: detected).
+##
+bazel-server-start: load-default ## Starts the bazel server.
+ docker run -d --rm \
+ --name $(DOCKER_NAME) \
+ --user 0:0 \
+ -v "$(CURDIR):$(CURDIR)" \
+ --workdir "$(CURDIR)" \
+ --tmpfs /tmp:rw,exec \
+ --entrypoint "" \
+ $(FULL_DOCKER_RUN_OPTIONS) \
+ gvisor.dev/images/default \
+ sh -c "groupadd --gid $(GID) --non-unique $(USER) && \
+ useradd --uid $(UID) --non-unique --no-create-home --gid $(GID) -d $(HOME) $(USER) && \
+ bazel version && \
+ while :; do sleep 3600; done"
+ @while :; do if docker logs $(DOCKER_NAME) 2>/dev/null | grep "Build label:" >/dev/null; then break; fi; sleep 1; done
+.PHONY: bazel-server-start
+
+bazel-shutdown: ## Shuts down a running bazel server.
+ @docker exec --user $(UID):$(GID) $(DOCKER_NAME) bazel shutdown; rc=$$?; docker kill $(DOCKER_NAME) || [[ $$rc -ne 0 ]]
+.PHONY: bazel-shutdown
+
+bazel-alias: ## Emits an alias that can be used within the shell.
+ @echo "alias bazel='docker exec --user $(UID):$(GID) -i $(DOCKER_NAME) bazel'"
+.PHONY: bazel-alias
+
+bazel-server: ## Ensures that the server exists. Used as an internal target.
+ @docker exec $(DOCKER_NAME) true || $(MAKE) bazel-server-start
+.PHONY: bazel-server
+
+build_paths = docker exec --user $(UID):$(GID) -i $(DOCKER_NAME) sh -c 'bazel build $(OPTIONS) $(TARGETS) 2>&1 \
+ | tee /dev/fd/2 \
+ | grep -E "^ bazel-bin/" \
+ | awk "{print $$1;}"' \
+ | xargs -n 1 -I {} sh -c "$(1)"
+
+build: bazel-server
+ @$(call build_paths,echo {})
+.PHONY: build
+
+copy: bazel-server
+ifeq (,$(DESTINATION))
+ $(error Destination not provided.)
+endif
+ @$(call build_paths,cp -a {} $(DESTINATION))
+
+run: bazel-server
+ @$(call build_paths,{} $(ARGS))
+.PHONY: run
+
+sudo: bazel-server
+ @$(call build_paths,sudo -E {} $(ARGS))
+.PHONY: sudo
+
+test: bazel-server
+ @docker exec --user $(UID):$(GID) -i $(DOCKER_NAME) bazel test $(OPTIONS) $(TARGETS)
+.PHONY: test
diff --git a/tools/installers/BUILD b/tools/installers/BUILD
index d78a265ca..caa7b1983 100644
--- a/tools/installers/BUILD
+++ b/tools/installers/BUILD
@@ -17,6 +17,14 @@ sh_binary(
)
sh_binary(
+ name = "images",
+ srcs = ["images.sh"],
+ data = [
+ "//images",
+ ],
+)
+
+sh_binary(
name = "master",
srcs = ["master.sh"],
)
diff --git a/tools/installers/images.sh b/tools/installers/images.sh
new file mode 100755
index 000000000..52e750f57
--- /dev/null
+++ b/tools/installers/images.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# Copyright 2020 The gVisor Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -xeuo pipefail
+
+# Find the images directory.
+for images in $(find . -type d -name images); do
+ if [[ -f "${images}"/Makefile ]]; then
+ make -C "${images}" load-all-images
+ fi
+done
diff --git a/tools/make_repository.sh b/tools/make_repository.sh
index 27ffbc9f3..c91fd283c 100755
--- a/tools/make_repository.sh
+++ b/tools/make_repository.sh
@@ -17,14 +17,37 @@
# Parse arguments. We require more than two arguments, which are the private
# keyring, the e-mail associated with the signer, and the list of packages.
if [ "$#" -le 3 ]; then
- echo "usage: $0 <private-key> <signer-email> <component> <root> <packages...>"
+ echo "usage: $0 <private-key> <signer-email> <root> <packages...>"
exit 1
fi
declare -r private_key=$(readlink -e "$1"); shift
declare -r signer="$1"; shift
-declare -r component="$1"; shift
declare -r root="$1"; shift
+# Ensure that we have the correct packages installed.
+function apt_install() {
+ while true; do
+ sudo apt-get update &&
+ sudo apt-get install -y "$@" &&
+ true
+ result="${?}"
+ case $result in
+ 0)
+ break
+ ;;
+ 100)
+ # 100 is the error code that apt-get returns.
+ ;;
+ *)
+ exit $result
+ ;;
+ esac
+ done
+}
+dpkg-sig --help >/dev/null || apt_install dpkg-sig
+apt-ftparchive --help >/dev/null || apt_install apt-utils
+xz --help >/dev/null || apt_install xz-utils
+
# Verbose from this point.
set -xeo pipefail
@@ -78,7 +101,7 @@ for dir in "${root}"/pool/*/binary-*; do
name=$(basename "${dir}")
arch=${name##binary-}
arches+=("${arch}")
- repo_packages="${tmpdir}"/"${component}"/"${name}"
+ repo_packages="${tmpdir}"/main/"${name}"
mkdir -p "${repo_packages}"
(cd "${root}" && apt-ftparchive --arch "${arch}" packages pool > "${repo_packages}"/Packages)
(cd "${repo_packages}" && cat Packages | gzip > Packages.gz)
@@ -91,7 +114,7 @@ APT {
FTPArchive {
Release {
Architectures "${arches[@]}";
- Components "${component}";
+ Components "main";
};
};
};
diff --git a/tools/vm/defs.bzl b/tools/vm/defs.bzl
index 24bf0aabc..61feefcbc 100644
--- a/tools/vm/defs.bzl
+++ b/tools/vm/defs.bzl
@@ -183,7 +183,10 @@ def vm_test(
"""
targets = kwargs.pop("targets", [])
if installers == None:
- installers = ["//tools/installers:head"]
+ installers = [
+ "//tools/installers:head",
+ "//tools/installers:images",
+ ]
targets = installers + targets
if default_installer():
targets = [default_installer()] + targets