diff options
author | Adin Scannell <ascannell@google.com> | 2020-04-24 14:10:28 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-04-24 14:11:42 -0700 |
commit | c60613475c92185c9b15468d0de87b321ef2b4d7 (patch) | |
tree | 470683d83c53ee44c174a06b5f673e5e19e1a38f /images | |
parent | f13f26d17da56d585fd9857a81175bbd0be8ce60 (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
Diffstat (limited to 'images')
-rw-r--r-- | images/BUILD | 11 | ||||
-rw-r--r-- | images/Makefile | 93 | ||||
-rw-r--r-- | images/README.md | 61 | ||||
-rw-r--r-- | images/basic/alpine/Dockerfile | 1 | ||||
-rw-r--r-- | images/basic/busybox/Dockerfile | 1 | ||||
-rw-r--r-- | images/basic/httpd/Dockerfile | 1 | ||||
-rw-r--r-- | images/basic/mysql/Dockerfile | 1 | ||||
-rw-r--r-- | images/basic/nginx/Dockerfile | 1 | ||||
-rw-r--r-- | images/basic/python/Dockerfile | 2 | ||||
-rw-r--r-- | images/basic/resolv/Dockerfile | 1 | ||||
-rw-r--r-- | images/basic/ruby/Dockerfile | 1 | ||||
-rw-r--r-- | images/basic/tomcat/Dockerfile | 1 | ||||
-rw-r--r-- | images/basic/ubuntu/Dockerfile | 1 | ||||
-rw-r--r-- | images/default/Dockerfile | 11 | ||||
-rw-r--r-- | images/iptables/Dockerfile | 2 | ||||
-rw-r--r-- | images/packetdrill/Dockerfile | 8 | ||||
-rw-r--r-- | images/packetimpact/Dockerfile | 16 | ||||
-rw-r--r-- | images/runtimes/go1.12/Dockerfile | 4 | ||||
-rw-r--r-- | images/runtimes/java11/Dockerfile | 22 | ||||
-rw-r--r-- | images/runtimes/nodejs12.4.0/Dockerfile | 21 | ||||
-rw-r--r-- | images/runtimes/php7.3.6/Dockerfile | 19 | ||||
-rw-r--r-- | images/runtimes/python3.7.3/Dockerfile | 21 |
22 files changed, 300 insertions, 0 deletions
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/images/packetdrill/Dockerfile b/images/packetdrill/Dockerfile new file mode 100644 index 000000000..7a006c85f --- /dev/null +++ b/images/packetdrill/Dockerfile @@ -0,0 +1,8 @@ +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 +RUN git clone --branch packetdrill-v2.0 \ + https://github.com/google/packetdrill.git +RUN cd packetdrill/gtests/net/packetdrill && ./configure && make +CMD /bin/bash diff --git a/images/packetimpact/Dockerfile b/images/packetimpact/Dockerfile new file mode 100644 index 000000000..87aa99ef2 --- /dev/null +++ b/images/packetimpact/Dockerfile @@ -0,0 +1,16 @@ +FROM ubuntu:bionic +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + # iptables to disable OS native packet processing. + iptables \ + # nc to check that the posix_server is running. + netcat \ + # tcpdump to log brief packet sniffing. + tcpdump \ + # ip link show to display MAC addresses. + iproute2 \ + # tshark to log verbose packet sniffing. + tshark \ + # killall for cleanup. + psmisc +RUN hash -r +CMD /bin/bash 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/images/runtimes/java11/Dockerfile b/images/runtimes/java11/Dockerfile new file mode 100644 index 000000000..03bc8aaf1 --- /dev/null +++ b/images/runtimes/java11/Dockerfile @@ -0,0 +1,22 @@ +FROM ubuntu:bionic +RUN apt-get update && apt-get install -y \ + autoconf \ + build-essential \ + curl \ + make \ + openjdk-11-jdk \ + unzip \ + zip + +# Download the JDK test library. +WORKDIR /root +RUN set -ex \ + && curl -fsSL --retry 10 -o /tmp/jdktests.tar.gz http://hg.openjdk.java.net/jdk/jdk11/archive/76072a077ee1.tar.gz/test \ + && tar -xzf /tmp/jdktests.tar.gz \ + && mv jdk11-76072a077ee1/test test \ + && rm -f /tmp/jdktests.tar.gz + +# Install jtreg and add to PATH. +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" diff --git a/images/runtimes/nodejs12.4.0/Dockerfile b/images/runtimes/nodejs12.4.0/Dockerfile new file mode 100644 index 000000000..d17924b62 --- /dev/null +++ b/images/runtimes/nodejs12.4.0/Dockerfile @@ -0,0 +1,21 @@ +FROM ubuntu:bionic +RUN apt-get update && apt-get install -y \ + curl \ + dumb-init \ + g++ \ + make \ + python + +WORKDIR /root +ARG VERSION=v12.4.0 +RUN curl -o node-${VERSION}.tar.gz https://nodejs.org/dist/${VERSION}/node-${VERSION}.tar.gz +RUN tar -zxf node-${VERSION}.tar.gz + +WORKDIR /root/node-${VERSION} +RUN ./configure +RUN make +RUN make test-build + +# Including dumb-init emulates the Linux "init" process, preventing the failure +# of tests involving worker processes. +ENTRYPOINT ["/usr/bin/dumb-init"] diff --git a/images/runtimes/php7.3.6/Dockerfile b/images/runtimes/php7.3.6/Dockerfile new file mode 100644 index 000000000..e5f67f79c --- /dev/null +++ b/images/runtimes/php7.3.6/Dockerfile @@ -0,0 +1,19 @@ +FROM ubuntu:bionic +RUN apt-get update && apt-get install -y \ + autoconf \ + automake \ + bison \ + build-essential \ + curl \ + libtool \ + libxml2-dev \ + re2c + +WORKDIR /root +ARG VERSION=7.3.6 +RUN curl -o php-${VERSION}.tar.gz https://www.php.net/distributions/php-${VERSION}.tar.gz +RUN tar -zxf php-${VERSION}.tar.gz + +WORKDIR /root/php-${VERSION} +RUN ./configure +RUN make diff --git a/images/runtimes/python3.7.3/Dockerfile b/images/runtimes/python3.7.3/Dockerfile new file mode 100644 index 000000000..4d1e1e221 --- /dev/null +++ b/images/runtimes/python3.7.3/Dockerfile @@ -0,0 +1,21 @@ +FROM ubuntu:bionic +RUN apt-get update && apt-get install -y \ + curl \ + gcc \ + libbz2-dev \ + libffi-dev \ + liblzma-dev \ + libreadline-dev \ + libssl-dev \ + make \ + zlib1g-dev + +# Use flags -LJO to follow the html redirect and download .tar.gz. +WORKDIR /root +ARG VERSION=3.7.3 +RUN curl -LJO https://github.com/python/cpython/archive/v${VERSION}.tar.gz +RUN tar -zxf cpython-${VERSION}.tar.gz + +WORKDIR /root/cpython-${VERSION} +RUN ./configure --with-pydebug +RUN make -s -j2 |