Skip to content

Commit

Permalink
Copy licenses into container image
Browse files Browse the repository at this point in the history
This adds bottlerocket-license-scanner's license scanning output and the
repository's LICENSEs in the built container image. The clarify.toml has
been added to clear up the unknown license in the sigs.k8s.io/yaml
dependency.

By using the scanner, the build process now relies on the bottlerocket
SDK container and is downloaded automatically for builds.
  • Loading branch information
jahkeup committed Feb 27, 2020
1 parent b07d30b commit 5574070
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 10 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ dev/
*.el
*.tar*
bin/
vendor/
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
/bin/
vendor/
*.tar.*
*.tar
20 changes: 16 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
# syntax=docker/dockerfile:experimental

# LICENSES_IMAGE_NAME is a container image that contains licenses to be included
# in the final container image.
ARG LICENSES_IMAGE_NAME=scratch
FROM $LICENSES_IMAGE_NAME as licenses
# This lets us drop in scratch as a substitute when LICENSES_IMAGE_NAME isn't
# specified (eg: when running `docker build -t tag:latest .`).
WORKDIR /licenses/

FROM golang:1.13 as build
ARG GO_LDFLAGS=
ARG GOARCH=
ARG SHORT_SHA=
ENV GOPROXY=direct
COPY go.mod go.sum /go/src/github.com/bottlerocket-os/bottlerocket-update-operator/
WORKDIR /go/src/github.com/bottlerocket-os/bottlerocket-update-operator
COPY go.mod go.sum /src/
WORKDIR /src/
RUN go mod download
COPY . /go/src/github.com/bottlerocket-os/bottlerocket-update-operator/
COPY ./ /src/
RUN make -e build GOBIN=/ CGO_ENABLED=0

# Build minimal container with a static build of the update operator executable.
FROM scratch as update-operator
COPY --from=build /bottlerocket-update-operator /etc/ssl /
COPY --from=build /bottlerocket-update-operator /
COPY --from=build /etc/ssl /etc/ssl
COPY --from=build /src/COPYRIGHT /src/LICENSE-* /usr/share/licenses/bottlerocket-update-operator/
COPY --from=licenses /licenses/ /usr/share/licenses/bottlerocket-update-operator/vendor/
ENTRYPOINT ["/bottlerocket-update-operator"]
CMD ["-help"]

Expand Down
51 changes: 45 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
# ecr_uri=$(aws ecr describe-repositories --repository bottlerocket-os/bottlerocket-update-operator --query 'repositories[].repositoryUri' --output text)
#
# make container IMAGE_REPO_NAME="$ecr_uri"
#

# SHELL is set as bash to use some bashisms.
SHELL = bash
# IMAGE_NAME is the full name of the container image being built. This may be
# specified to fully control the name of the container image's tag.
IMAGE_NAME = $(IMAGE_REPO_NAME)$(IMAGE_ARCH_SUFFIX):$(IMAGE_VERSION)$(addprefix -,$(SHORT_SHA))
Expand All @@ -19,6 +21,11 @@ SHORT_SHA = $(shell git describe --abbrev=8 --always --dirty='-dev' --exclude '*
# IMAGE_ARCH_SUFFIX is the runtime architecture designator for the container
# image, it is appended to the IMAGE_NAME unless the name is specified.
IMAGE_ARCH_SUFFIX = $(addprefix -,$(ARCH))
# BUILDSYS_SDK_IMAGE is the Bottlerocket SDK image used for license scanning.
BUILDSYS_SDK_IMAGE ?= bottlerocket/sdk-x86_64:v0.8
# LICENSES_IMAGE_NAME is the name of the container image that has LICENSE files
# for distribution.
LICENSES_IMAGE_NAME = $(IMAGE_NAME)-licenses
# DESTDIR is where the release artifacts will be written.
DESTDIR = .
# DISTFILE is the path to the dist target's output file - the container image
Expand All @@ -35,8 +42,6 @@ ARCH = $(lastword $(subst :, ,$(filter $(UNAME_ARCH):%,x86_64:amd64 aarch64:arm6
# DOCKER_ARCH is the docker specific architecture specifier used for building on
# multiarch container images.
DOCKER_ARCH = $(lastword $(subst :, ,$(filter $(ARCH):%,amd64:amd64 arm64:arm64v8)))
# Build container images using BuildKit strategy.
export DOCKER_BUILDKIT = 1

.PHONY: all build check

Expand Down Expand Up @@ -65,24 +70,26 @@ test:
go test -race -ldflags '$(GO_LDFLAGS)' $(GOPKGS)

# Build a container image for daemon and tools.
container:
container: licenses
docker build \
--network=host \
--build-arg GO_LDFLAGS \
--build-arg GOARCH \
--build-arg SHORT_SHA='$(SHORT_SHA)' \
--build-arg LICENSES_IMAGE_NAME=$(LICENSES_IMAGE_NAME) \
--target="update-operator" \
--tag $(IMAGE_NAME) \
.

# Build and test in a container.
container-test:
container-test: licenses
docker build \
--network=host \
--build-arg GO_LDFLAGS='$(GO_LDFLAGS)' \
--build-arg GOARCH='$(GOARCH)' \
--build-arg SHORT_SHA='$(SHORT_SHA)' \
--build-arg NOCACHE='$(shell date +"%s")' \
--build-arg LICENSES_IMAGE=$(IMAGE_NAME)-licenses \
--target="test" \
--tag $(IMAGE_NAME)-test \
.
Expand All @@ -98,14 +105,34 @@ dist: container check
docker save $(IMAGE_NAME) | gzip > '$(DISTFILE)'

# Run checks on the container image.
check: check-executable
check: check-executable check-licenses

# Check that the container's executable works.
check-executable:
@echo "Running check: $@"
@echo "Checking if the container image's ENTRYPOINT is executable..."
docker run --rm $(IMAGE_NAME) -help 2>&1 \
| grep -q '/bottlerocket-update-operator'

# Check that the container has LICENSE files included for its dependencies.
check-licenses: CONTAINER_HASH=$(shell echo "$(LICENSES_IMAGE_NAME)$$(pwd -P)" | sha256sum - | awk '{print $$1}' | head -c 16)
check-licenses: CHECK_CONTAINER_NAME=check-licenses-$(CONTAINER_HASH)
check-licenses:
@echo "Running check: $@"
@-if docker inspect $(CHECK_CONTAINER_NAME) &>/dev/null; then\
docker rm $(CHECK_CONTAINER_NAME) &>/dev/null; \
fi
@docker create --name $(CHECK_CONTAINER_NAME) $(IMAGE_NAME) >/dev/null
@echo "Checking if container image included dependencies' LICENSE files..."
@docker export $(CHECK_CONTAINER_NAME) | tar -tf - \
| grep usr/share/licenses/bottlerocket-update-operator/vendor \
| grep -q LICENSE || { \
echo "Container image is missing required LICENSE files (checked $(IMAGE_NAME))"; \
docker rm $(CHECK_CONTAINER_NAME) &>/dev/null; \
exit 1; \
}
@-docker rm $(CHECK_CONTAINER_NAME) &>/dev/null

# Clean the build artifacts on disk.
clean:
rm -f -- $(foreach binpkg,$(GOPKG) $(wildcard ./cmd/*),'$(GOBIN)/$(notdir $(binpkg))')
Expand Down Expand Up @@ -160,3 +187,15 @@ unsafe-dashboard:
# Print the Node operational management status.
get-nodes-status:
kubectl get nodes -o json | jq -C -S '.items | map(.metadata|{(.name): (.annotations*.labels|to_entries|map(select(.key|startswith("bottlerocket")))|from_entries)}) | add'

license-scanner-image: BUILDSYS_SDK_IMAGE_URL=https://cache.bottlerocket.aws/$(BUILDSYS_SDK_IMAGE).tar.gz
license-scanner-image:
docker inspect $(BUILDSYS_SDK_IMAGE) 2>&1 >/dev/null \
|| curl -# -qL $(BUILDSYS_SDK_IMAGE_URL) | docker load -i /dev/stdin

licenses: license-scanner-image go.mod go.sum
docker build \
--network=host \
--build-arg SDK_IMAGE=$(BUILDSYS_SDK_IMAGE) \
-t $(IMAGE_NAME)-licenses \
-f build/Dockerfile.licenses .
43 changes: 43 additions & 0 deletions build/Dockerfile.licenses
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# This Dockerfile produces an image that has only the licenses of dependencies
# used in the update operator. These are collected by bottlerocket-license-scan
# and organized into a project-wide conventional directory structure rooted at
# /licenses in the resulting image.

# SDK_IMAGE is the Bottlerocket SDK container image that provides
# `bottlerocket-license-scan`.
#
# Generally, this will track the value of BUILDSYS_SDK_IMAGE provided in
# Bottlerocket's Makefile.toml:
#
# https://github.com/bottlerocket-os/bottlerocket/blob/develop/Makefile.toml
#
# For example, see this line in Makefile.toml:
#
# https://github.com/bottlerocket-os/bottlerocket/blob/a1d098dcd9908e3db1dc290ed9dad53e6f8fe44c/Makefile.toml#L31
#
ARG SDK_IMAGE

# Fetch dependencies into a vendor/ directory.
FROM golang:1.13 as src
ENV GOPROXY=direct
WORKDIR /src
COPY go.mod go.sum /src/
RUN go mod download
COPY ./ /src/
RUN go mod vendor

# Run license scanner and dump result to be extracted.
FROM $SDK_IMAGE as license-scan
COPY --from=src /src/vendor /src/vendor
COPY --from=src /src/clarify.toml /src/clarify.toml
USER root
RUN bottlerocket-license-scan \
--spdx-data /usr/libexec/tools/spdx-data \
--out-dir /out/licenses \
--clarify /src/clarify.toml \
go-vendor /src/vendor

# Final container image has LICENSE files and accompanying attributions
# collected and produced by the license scanner.
FROM scratch as licenses
COPY --from=license-scan /out/licenses /licenses
7 changes: 7 additions & 0 deletions clarify.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[clarify."sigs.k8s.io/yaml"]
# The package's files are a mix of MIT with contributions attributed to "The Go
# Authors" licensed as BSD-3-Clause.
expression = "MIT AND BSD-3-Clause"
license-files = [
{ path = "LICENSE", hash = 0xcdf3ae00 },
]

0 comments on commit 5574070

Please sign in to comment.