diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index fd4f791cc..9be9739d9 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -6,14 +6,14 @@ name: Docker on: push: branches: - - master + - master paths: - - 'Cargo.lock' - - 'Dockerfile' + - "Cargo.lock" + - "Dockerfile" pull_request: paths: - - 'Cargo.lock' - - 'Dockerfile' + - "Cargo.lock" + - "Dockerfile" env: DOCKER_UNOPTIMIZED: "1" @@ -22,43 +22,43 @@ jobs: docker: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v1 - # Create a build image on a Linkerd build host. - - name: Setup (Origin) - if: '!github.event.pull_request.head.repo.fork' - run: | - mkdir -p ~/.ssh - # Create an identity file and protect before writing contents to it. - touch ~/.ssh/id && chmod 600 ~/.ssh/id - echo "${{ secrets.DOCKER_PRIVATE_KEY }}" >~/.ssh/id - # Use well-known public keys for the host to prevent middlemen. - echo "${{ secrets.DOCKER_KNOWN_HOSTS }}" >~/.ssh/known_hosts - # Configure host with ServerAliveInterval to ensure that the client - # stays alive even when the server is busy emitting nothing. - # ServerAliveCountMax ensures that server responds to these pings - # within ~5 minutes. - ( - echo "Host linkerd-docker" - echo " User github" - echo " Hostname ${{ secrets.DOCKER_ADDRESS }}" - echo " IdentityFile ~/.ssh/id" - echo " BatchMode yes" - echo " ServerAliveInterval 60" - echo " ServerAliveCountMax 5" - ) >~/.ssh/config - # Confirm that the SSH configuration works. - ssh linkerd-docker docker version + # Create a build image on a Linkerd build host. + - name: Setup (Origin) + if: "!github.event.pull_request.head.repo.fork" + run: | + mkdir -p ~/.ssh + # Create an identity file and protect before writing contents to it. + touch ~/.ssh/id && chmod 600 ~/.ssh/id + echo "${{ secrets.DOCKER_PRIVATE_KEY }}" >~/.ssh/id + # Use well-known public keys for the host to prevent middlemen. + echo "${{ secrets.DOCKER_KNOWN_HOSTS }}" >~/.ssh/known_hosts + # Configure host with ServerAliveInterval to ensure that the client + # stays alive even when the server is busy emitting nothing. + # ServerAliveCountMax ensures that server responds to these pings + # within ~5 minutes. + ( + echo "Host linkerd-docker" + echo " User github" + echo " Hostname ${{ secrets.DOCKER_ADDRESS }}" + echo " IdentityFile ~/.ssh/id" + echo " BatchMode yes" + echo " ServerAliveInterval 60" + echo " ServerAliveCountMax 5" + ) >~/.ssh/config + # Confirm that the SSH configuration works. + ssh linkerd-docker docker version - - name: Docker (Origin) - if: '!github.event.pull_request.head.repo.fork' - env: - DOCKER_HOST: "ssh://linkerd-docker" - run: | - export DOCKER_TAG="proxy-ci:$(dd bs=64 count=1 if=/dev/urandom status=none | tr -dc 'a-zA-Z0-9')" - make docker - docker image rm -f "$DOCKER_TAG" + - name: Docker (Origin) + if: "!github.event.pull_request.head.repo.fork" + env: + DOCKER_HOST: "ssh://linkerd-docker" + run: | + export DOCKER_TAG="proxy-ci:$(dd bs=64 count=1 if=/dev/urandom status=none | tr -dc 'a-zA-Z0-9')" + make docker + docker image rm -f "$DOCKER_TAG" - - name: Docker (Fork) - if: github.event.pull_request.head.repo.fork - run: make docker + - name: Docker (Fork) + if: github.event.pull_request.head.repo.fork + run: make docker diff --git a/Dockerfile b/Dockerfile index 90fa535e3..d6486adff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,36 +1,56 @@ +# syntax=docker/dockerfile:experimental + # Proxy build and runtime # # This is intended **DEVELOPMENT ONLY**, i.e. so that proxy developers can # easily test the proxy in the context of the larger `linkerd2` project. # -# When PROXY_UNOPTIMIZED is set and not empty, unoptimized rust artifacts are produced. -# This reduces build time and produces binaries with debug symbols, at the expense of -# runtime performance. +# This Dockerfile requires expirmental features to be enabled in both the +# Docker client and daemon. You MUST use buildkit to build this image. The +# simplest way to do this is to set the `DOCKER_BUILDKIT` environment variable: +# +# :; DOCKER_BUILDKIT=1 docker build . +# +# Alternatively, you can use `buildx`, which supports more complicated build +# configurations: +# +# :; docker buildx build . --load -# rather than updating this manually, run update-rust-version.sh +# Please make changes via update-rust-version.sh ARG RUST_IMAGE=rust:1.41.0-buster -ARG RUNTIME_IMAGE=gcr.io/linkerd-io/proxy:edge-20.2.2 -ARG PROXY_UNOPTIMIZED -## Builds the proxy as incrementally as possible. +# Use an arbitrary ~recent edge release image to get the proxy +# identity-initializing wrapper. +ARG RUNTIME_IMAGE=gcr.io/linkerd-io/proxy:edge-20.4.1 + +# Build the proxy, leveraging (new, experimental) cache mounting. +# +# See: https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md#run---mounttypecache FROM $RUST_IMAGE as build +# When set, causes the proxy to be compiled in development mode. +ARG PROXY_UNOPTIMIZED + +# Controls what features are enabled in the proxy. This is typically empty but +# may be set to `mock-orig-dst` for profiling builds. +ARG PROXY_FEATURES + WORKDIR /usr/src/linkerd2-proxy - COPY . . -RUN cargo fetch --locked -RUN if [ -n "$PROXY_UNOPTIMIZED" ]; \ - then \ - cargo build -p linkerd2-proxy --bin linkerd2-proxy --frozen && \ - mv target/debug/linkerd2-proxy target/linkerd2-proxy ; \ +RUN --mount=type=cache,target=target \ + --mount=type=cache,from=rust:1.41.0-buster,source=/usr/local/cargo,target=/usr/local/cargo \ + mkdir -p /out && \ + if [ -n "$PROXY_UNOPTIMIZED" ]; then \ + (cd linkerd2-proxy && cargo build --locked --features="$PROXY_FEATURES") && \ + mv target/debug/linkerd2-proxy /out/linkerd2-proxy ; \ else \ - cargo build -p linkerd2-proxy --bin linkerd2-proxy --frozen --release && \ - mv target/release/linkerd2-proxy target/linkerd2-proxy ; \ + (cd linkerd2-proxy && cargo build --locked --release --features="$PROXY_FEATURES") && \ + mv target/release/linkerd2-proxy /out/linkerd2-proxy ; \ fi - ## Install the proxy binary into the base runtime image. FROM $RUNTIME_IMAGE as runtime WORKDIR /linkerd -COPY --from=build /usr/src/linkerd2-proxy/target/linkerd2-proxy /usr/lib/linkerd/linkerd2-proxy -ENV LINKERD2_PROXY_LOG=warn,linkerd2_proxy=info +COPY --from=build /out/linkerd2-proxy /usr/lib/linkerd/linkerd2-proxy +ENV LINKERD2_PROXY_LOG=warn,linkerd=info +# Inherits the ENTRYPOINT from the runtime image. diff --git a/Makefile b/Makefile index 0706dbbaa..b0606dc41 100644 --- a/Makefile +++ b/Makefile @@ -105,7 +105,7 @@ clean-profile: .PHONY: docker docker: Dockerfile Cargo.lock - $(DOCKER_BUILD) . + DOCKER_BUILDKIT=1 $(DOCKER_BUILD) . .PHONY: all all: build test diff --git a/update-rust-version.sh b/update-rust-version.sh index 3cfab1a1d..08013d6b6 100755 --- a/update-rust-version.sh +++ b/update-rust-version.sh @@ -7,10 +7,14 @@ if [ $# -ne 1 ]; then exit 64 fi -VERSION=$1 +VERSION="$1" +if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$' ; then + echo "Expected M.N.P; got '$VERSION'" >&2 + exit 64 +fi echo "$VERSION" > rust-toolchain -sed -i'' -e "s/RUST_IMAGE=.*/RUST_IMAGE=rust:$VERSION-buster/" Dockerfile +sed -i'' -Ee "s/rust:[0-9]+\.[0-9]+\.[0-9]+/rust:$VERSION/" Dockerfile find .github -name \*.yml \ - -exec sed -i'' -e "s|docker://rust:.*|docker://rust:$VERSION-buster|" '{}' \; + -exec sed -i'' -Ee "s|docker://rust:[0-9]+\.[0-9]+\.[0-9]+|docker://rust:$VERSION|" '{}' \;