consul/testing/deployer/sprawl/internal/build/docker.go

171 lines
4.7 KiB
Go
Raw Normal View History

[COMPLIANCE] License changes (#18443) * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Updating the license from MPL to Business Source License Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at <Blog URL>, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl. * add missing license headers * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
2023-08-11 13:12:13 +00:00
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package build
import (
"context"
"strings"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/consul/testing/deployer/sprawl/internal/runner"
"github.com/hashicorp/consul/testing/deployer/topology"
)
const dockerfileEnvoy = `
ARG CONSUL_IMAGE
ARG ENVOY_IMAGE
FROM ${CONSUL_IMAGE}
FROM ${ENVOY_IMAGE}
COPY --from=0 /bin/consul /bin/consul
`
// FROM hashicorp/consul-dataplane:latest
// COPY --from=busybox:uclibc /bin/sh /bin/sh
// TODO: busybox:latest doesn't work, see https://hashicorp.slack.com/archives/C03EUN3QF1C/p1691784078972959
const dockerfileDataplane = `
ARG DATAPLANE_IMAGE
FROM busybox:1.34
FROM ${DATAPLANE_IMAGE}
COPY --from=0 /bin/busybox /bin/busybox
USER 0:0
RUN ["busybox", "--install", "/bin", "-s"]
USER 100:0
ENTRYPOINT []
`
const dockerfileDataplaneForTProxy = `
ARG DATAPLANE_IMAGE
ARG CONSUL_IMAGE
FROM ${CONSUL_IMAGE} AS consul
FROM ${DATAPLANE_IMAGE} AS distroless
FROM debian:bullseye-slim
# undo the distroless aspect
COPY --from=distroless /usr/local/bin/discover /usr/local/bin/
COPY --from=distroless /usr/local/bin/envoy /usr/local/bin/
COPY --from=distroless /usr/local/bin/consul-dataplane /usr/local/bin/
COPY --from=distroless /licenses/copyright.txt /licenses/
COPY --from=consul /bin/consul /bin/
# Install iptables and sudo, needed for tproxy.
RUN apt update -y \
&& apt install -y iptables sudo curl dnsutils
RUN sed '/_apt/d' /etc/passwd > /etc/passwd.new \
&& mv -f /etc/passwd.new /etc/passwd \
&& adduser --uid=100 consul --no-create-home --disabled-password --system \
&& adduser consul sudo \
&& echo 'consul ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
COPY <<'EOF' /bin/tproxy-startup.sh
#!/bin/sh
set -ex
# HACK: UID of consul in the consul-client container
# This is conveniently also the UID of apt in the envoy container
CONSUL_UID=100
ENVOY_UID=$(id -u)
# - We allow 19000 so that the test can directly visit the envoy admin page.
# - We allow 20000 so that envoy can receive mTLS traffic from other nodes.
# - We (reluctantly) allow 8080 so that we can bypass envoy and talk to fortio
# to do test assertions.
sudo consul connect redirect-traffic \
-proxy-uid $ENVOY_UID \
-exclude-uid $CONSUL_UID \
-proxy-inbound-port=15001 \
-exclude-inbound-port=19000 \
-exclude-inbound-port=20000 \
-exclude-inbound-port=8080
exec "$@"
EOF
RUN chmod +x /bin/tproxy-startup.sh \
&& chown 100:0 /bin/tproxy-startup.sh
RUN echo 'consul ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER 100:0
ENTRYPOINT []
`
func DockerImages(
logger hclog.Logger,
run *runner.Runner,
t *topology.Topology,
) error {
built := make(map[string]struct{})
for _, c := range t.Clusters {
for _, n := range c.Nodes {
joint := n.Images.EnvoyConsulImage()
if _, ok := built[joint]; joint != "" && !ok {
logger.Info("building envoy+consul image", "image", joint)
logw := logger.Named("docker_envoy_consul").StandardWriter(&hclog.StandardLoggerOptions{ForceLevel: hclog.Debug})
err := run.DockerExecWithStderr(context.TODO(), []string{
"build",
// provenance causes non-idempotent builds, which leads to spurious terraform replacements
"--provenance=false",
"--build-arg",
"CONSUL_IMAGE=" + n.Images.Consul,
"--build-arg",
"ENVOY_IMAGE=" + n.Images.Envoy,
"-t", joint,
"-",
}, logw, logw, strings.NewReader(dockerfileEnvoy))
if err != nil {
return err
}
built[joint] = struct{}{}
}
cdp := n.Images.LocalDataplaneImage()
if _, ok := built[cdp]; cdp != "" && !ok {
logger.Info("building dataplane image", "image", cdp)
logw := logger.Named("docker_dataplane").StandardWriter(&hclog.StandardLoggerOptions{ForceLevel: hclog.Debug})
err := run.DockerExecWithStderr(context.TODO(), []string{
"build",
"--provenance=false",
"--build-arg",
"DATAPLANE_IMAGE=" + n.Images.Dataplane,
"-t", cdp,
"-",
}, logw, logw, strings.NewReader(dockerfileDataplane))
if err != nil {
return err
}
built[cdp] = struct{}{}
}
cdpTproxy := n.Images.LocalDataplaneTProxyImage()
if _, ok := built[cdpTproxy]; cdpTproxy != "" && !ok {
logger.Info("building image", "image", cdpTproxy)
logw := logger.Named("docker_dataplane_tproxy").StandardWriter(&hclog.StandardLoggerOptions{ForceLevel: hclog.Debug})
err := run.DockerExecWithStderr(context.TODO(), []string{
"build",
"--build-arg",
"DATAPLANE_IMAGE=" + n.Images.Dataplane,
"--build-arg",
"CONSUL_IMAGE=" + n.Images.Consul,
"-t", cdpTproxy,
"-",
}, logw, logw, strings.NewReader(dockerfileDataplaneForTProxy))
if err != nil {
return err
}
built[cdpTproxy] = struct{}{}
}
}
}
return nil
}