mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-30 11:31:29 +02:00
[e2e] Build images from source by default instead of pulling rc.2
The agent-network code under test lives in this branch, so the e2e should exercise it rather than a frozen published release. Flip the harness default: combined/proxy/client are now built from their in-repo Dockerfiles (combined/Dockerfile.multistage, proxy/Dockerfile.multistage, e2e/harness/Dockerfile.client) under local tags. Pulling a published image stays available by setting NB_E2E_*_IMAGE to a registry reference. Builds now go through buildx --load so the Dockerfile cache mounts are honored and the result is loaded for testcontainers. The CI workflow adds a container-driver builder and a local layer cache (NB_E2E_BUILDX_CACHE) persisted via actions/cache, which caches the base/apt/dep-download layers across runs. The Go compile still re-runs each time, as BuildKit mount caches cannot be exported to the GitHub cache.
This commit is contained in:
19
.github/workflows/agent-network-e2e.yml
vendored
19
.github/workflows/agent-network-e2e.yml
vendored
@@ -27,8 +27,27 @@ jobs:
|
||||
with:
|
||||
go-version-file: "go.mod"
|
||||
|
||||
# Container-driver builder so the harness can build the combined/proxy/
|
||||
# client images from source with a local layer cache.
|
||||
- name: Set up Buildx
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
|
||||
|
||||
# Persist the Docker layer cache across runs. This caches the base, apt,
|
||||
# and go-mod-download layers; the Go compile still re-runs, as BuildKit
|
||||
# mount caches cannot be exported to the GitHub cache.
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-anet-e2e-buildx-${{ hashFiles('go.sum', 'combined/Dockerfile.multistage', 'proxy/Dockerfile.multistage', 'e2e/harness/Dockerfile.client') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-anet-e2e-buildx-
|
||||
|
||||
- name: Run agent-network e2e
|
||||
env:
|
||||
# Build the images from source (this branch's code) with the shared
|
||||
# local layer cache.
|
||||
NB_E2E_BUILDX_CACHE: /tmp/.buildx-cache
|
||||
# Provider credentials. Each provider scenario skips if its
|
||||
# token (and URL, for gateways) is unset, so partial coverage is fine.
|
||||
OPENAI_TOKEN: ${{ secrets.E2E_OPENAI_TOKEN }}
|
||||
|
||||
@@ -17,10 +17,10 @@ import (
|
||||
|
||||
const (
|
||||
clientDockerfile = "e2e/harness/Dockerfile.client"
|
||||
// defaultClientImage is the published NetBird client release used by
|
||||
// default. Override with NB_E2E_CLIENT_IMAGE; a value without a "/" is built
|
||||
// locally from clientDockerfile.
|
||||
defaultClientImage = "netbirdio/netbird:0.74.0-rc.2"
|
||||
// defaultClientImage is the local tag the client is built under from
|
||||
// clientDockerfile. Override with NB_E2E_CLIENT_IMAGE: a value with a "/" is
|
||||
// pulled as a published image; a bare tag is built under that name.
|
||||
defaultClientImage = "netbird-client:e2e"
|
||||
clientAlias = "client"
|
||||
curlImage = "curlimages/curl:latest"
|
||||
)
|
||||
|
||||
@@ -24,11 +24,11 @@ import (
|
||||
|
||||
const (
|
||||
combinedDockerfile = "combined/Dockerfile.multistage"
|
||||
// defaultCombinedImage is the published combined-server release used by
|
||||
// default (the artifact operators run manually). Override with
|
||||
// NB_E2E_COMBINED_IMAGE; a value without a "/" is built locally from
|
||||
// combinedDockerfile instead of pulled.
|
||||
defaultCombinedImage = "netbirdio/netbird-server:0.74.0-rc.2"
|
||||
// defaultCombinedImage is the local tag the combined server is built under
|
||||
// from combinedDockerfile, so the e2e exercises this branch's code. Override
|
||||
// with NB_E2E_COMBINED_IMAGE: a value containing a "/" is pulled as a
|
||||
// published image; a bare tag is built under that name instead.
|
||||
defaultCombinedImage = "netbird-combined:e2e"
|
||||
combinedHTTPPort = "8080/tcp"
|
||||
|
||||
// combinedAlias is the combined server's network alias AND the deployment
|
||||
@@ -149,33 +149,42 @@ func StartCombined(ctx context.Context) (*Combined, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// resolveImage returns the image to run for a component. The env override (or
|
||||
// the default) is used as-is when it looks like a registry reference (contains
|
||||
// "/") — testcontainers pulls it. A bare local tag is built from the repo
|
||||
// Dockerfile instead, so developers can still test source builds.
|
||||
func resolveImage(ctx context.Context, root, envKey, defaultImage, dockerfile string) (string, error) {
|
||||
img := defaultImage
|
||||
// resolveImage returns the image to run for a component. By default it builds
|
||||
// the image from the repo Dockerfile under localTag, so the e2e exercises the
|
||||
// branch's code. The env override changes this: a value containing a "/" is a
|
||||
// registry reference that testcontainers pulls (e.g. to test a published
|
||||
// release); a bare tag is built under that name instead.
|
||||
func resolveImage(ctx context.Context, root, envKey, localTag, dockerfile string) (string, error) {
|
||||
if v := os.Getenv(envKey); v != "" {
|
||||
img = v
|
||||
if strings.Contains(v, "/") {
|
||||
return v, nil
|
||||
}
|
||||
localTag = v
|
||||
}
|
||||
if strings.Contains(img, "/") {
|
||||
return img, nil
|
||||
}
|
||||
if err := buildImage(ctx, root, dockerfile, img); err != nil {
|
||||
if err := buildImage(ctx, root, dockerfile, localTag); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return img, nil
|
||||
return localTag, nil
|
||||
}
|
||||
|
||||
// buildImage builds an image from a repo Dockerfile via the docker CLI with
|
||||
// BuildKit enabled, so cache mounts work and unchanged sources reuse the layer
|
||||
// + go caches. Tags are stable so reruns are cheap.
|
||||
// buildImage builds an image from a repo Dockerfile via buildx with BuildKit, so
|
||||
// the Dockerfile cache mounts are honored and unchanged layers are reused. The
|
||||
// result is loaded into the docker image store so testcontainers runs it by tag.
|
||||
// When NB_E2E_BUILDX_CACHE names a directory (CI, with a container-driver
|
||||
// builder from docker/setup-buildx-action), layer cache is read from and written
|
||||
// to it as a local cache so actions/cache can persist it across runs; the Go
|
||||
// compile itself still re-runs, as BuildKit mount caches can't be exported.
|
||||
func buildImage(ctx context.Context, root, dockerfile, tag string) error {
|
||||
cmd := exec.CommandContext(ctx, "docker", "build",
|
||||
"-f", dockerfile,
|
||||
"-t", tag,
|
||||
".",
|
||||
)
|
||||
args := []string{"buildx", "build", "-f", dockerfile, "-t", tag, "--load"}
|
||||
if dir := os.Getenv("NB_E2E_BUILDX_CACHE"); dir != "" {
|
||||
args = append(args,
|
||||
"--cache-from", "type=local,src="+dir,
|
||||
"--cache-to", "type=local,dest="+dir+",mode=max",
|
||||
)
|
||||
}
|
||||
args = append(args, ".")
|
||||
|
||||
cmd := exec.CommandContext(ctx, "docker", args...)
|
||||
cmd.Dir = root
|
||||
cmd.Env = append(os.Environ(), "DOCKER_BUILDKIT=1")
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
|
||||
@@ -15,9 +15,10 @@ import (
|
||||
|
||||
const (
|
||||
proxyDockerfile = "proxy/Dockerfile.multistage"
|
||||
// defaultProxyImage is the published reverse-proxy release used by default.
|
||||
// Override with NB_E2E_PROXY_IMAGE; a value without a "/" is built locally.
|
||||
defaultProxyImage = "netbirdio/reverse-proxy:0.74.0-rc.2"
|
||||
// defaultProxyImage is the local tag the reverse proxy is built under from
|
||||
// proxyDockerfile. Override with NB_E2E_PROXY_IMAGE: a value with a "/" is
|
||||
// pulled as a published image; a bare tag is built under that name.
|
||||
defaultProxyImage = "netbird-reverse-proxy:e2e"
|
||||
proxyAlias = "proxy"
|
||||
|
||||
// AgentNetworkCluster is the proxy cluster the e2e provider bootstraps and
|
||||
|
||||
Reference in New Issue
Block a user