mirror of
https://github.com/coder/terraform-provider-envbuilder.git
synced 2025-07-23 03:57:51 +00:00
fix: set MagicDir to tempdir when performing cache probe (#48)
* fix: set MagicDir to tempdir when performing cache probe * chore: update envbuilder to b7781d8 * imgutil: get default envbuilder binary path from envbuilder options
This commit is contained in:
parent
6137223cea
commit
4077a87dca
8 changed files with 67 additions and 35 deletions
4
go.mod
4
go.mod
|
@ -10,7 +10,7 @@ replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa55
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/GoogleContainerTools/kaniko v1.9.2
|
github.com/GoogleContainerTools/kaniko v1.9.2
|
||||||
github.com/coder/envbuilder v1.0.0-rc.0.0.20240830145058-fb7e689f39ed
|
github.com/coder/envbuilder v1.0.0-rc.0.0.20240910082823-b7781d802f88
|
||||||
github.com/coder/serpent v0.7.0
|
github.com/coder/serpent v0.7.0
|
||||||
github.com/docker/docker v26.1.5+incompatible
|
github.com/docker/docker v26.1.5+incompatible
|
||||||
github.com/gliderlabs/ssh v0.3.7
|
github.com/gliderlabs/ssh v0.3.7
|
||||||
|
@ -295,7 +295,7 @@ require (
|
||||||
go4.org/netipx v0.0.0-20230728180743-ad4cb58a6516 // indirect
|
go4.org/netipx v0.0.0-20230728180743-ad4cb58a6516 // indirect
|
||||||
golang.org/x/crypto v0.26.0 // indirect
|
golang.org/x/crypto v0.26.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
|
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
|
||||||
golang.org/x/mod v0.19.0 // indirect
|
golang.org/x/mod v0.21.0 // indirect
|
||||||
golang.org/x/net v0.26.0 // indirect
|
golang.org/x/net v0.26.0 // indirect
|
||||||
golang.org/x/oauth2 v0.20.0 // indirect
|
golang.org/x/oauth2 v0.20.0 // indirect
|
||||||
golang.org/x/sync v0.8.0 // indirect
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -186,8 +186,8 @@ github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoC
|
||||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
||||||
github.com/coder/coder/v2 v2.10.1-0.20240704130443-c2d44d16a352 h1:L/EjCuZxs5tOcqqCaASj/nu65TRYEFcTt8qRQfHZXX0=
|
github.com/coder/coder/v2 v2.10.1-0.20240704130443-c2d44d16a352 h1:L/EjCuZxs5tOcqqCaASj/nu65TRYEFcTt8qRQfHZXX0=
|
||||||
github.com/coder/coder/v2 v2.10.1-0.20240704130443-c2d44d16a352/go.mod h1:P1KoQSgnKEAG6Mnd3YlGzAophty+yKA9VV48LpfNRvo=
|
github.com/coder/coder/v2 v2.10.1-0.20240704130443-c2d44d16a352/go.mod h1:P1KoQSgnKEAG6Mnd3YlGzAophty+yKA9VV48LpfNRvo=
|
||||||
github.com/coder/envbuilder v1.0.0-rc.0.0.20240830145058-fb7e689f39ed h1:sDEjs9qB2uJ7O85vGmzMja99IZuLvesxElOUFyy22UY=
|
github.com/coder/envbuilder v1.0.0-rc.0.0.20240910082823-b7781d802f88 h1:eXOILD2tWepnV1r7XZalBX0yC4NJMnpf6OP1nF8O2Ak=
|
||||||
github.com/coder/envbuilder v1.0.0-rc.0.0.20240830145058-fb7e689f39ed/go.mod h1:LWImvtIWaX3eiAI3zyU46WE/PrE099nCut1zJultSk0=
|
github.com/coder/envbuilder v1.0.0-rc.0.0.20240910082823-b7781d802f88/go.mod h1:krXpDmUsORgNNdvBe6tnwWCGGDLhabom1UUqAZq9+v0=
|
||||||
github.com/coder/kaniko v0.0.0-20240830141327-f307586e3dca h1:PrcSWrllqipTrtet50a3VyAJEQmjziIZyhpy0bsC6o0=
|
github.com/coder/kaniko v0.0.0-20240830141327-f307586e3dca h1:PrcSWrllqipTrtet50a3VyAJEQmjziIZyhpy0bsC6o0=
|
||||||
github.com/coder/kaniko v0.0.0-20240830141327-f307586e3dca/go.mod h1:XoTDIhNF0Ll4tLmRYdOn31udU9w5zFrY2PME/crSRCA=
|
github.com/coder/kaniko v0.0.0-20240830141327-f307586e3dca/go.mod h1:XoTDIhNF0Ll4tLmRYdOn31udU9w5zFrY2PME/crSRCA=
|
||||||
github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs=
|
github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs=
|
||||||
|
@ -895,8 +895,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
|
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||||
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
|
|
@ -7,8 +7,9 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/coder/envbuilder/constants"
|
eboptions "github.com/coder/envbuilder/options"
|
||||||
"github.com/google/go-containerregistry/pkg/authn"
|
"github.com/google/go-containerregistry/pkg/authn"
|
||||||
"github.com/google/go-containerregistry/pkg/name"
|
"github.com/google/go-containerregistry/pkg/name"
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
|
@ -34,7 +35,9 @@ func GetRemoteImage(imgRef string) (v1.Image, error) {
|
||||||
// ExtractEnvbuilderFromImage reads the image located at imgRef and extracts
|
// ExtractEnvbuilderFromImage reads the image located at imgRef and extracts
|
||||||
// MagicBinaryLocation to destPath.
|
// MagicBinaryLocation to destPath.
|
||||||
func ExtractEnvbuilderFromImage(ctx context.Context, imgRef, destPath string) error {
|
func ExtractEnvbuilderFromImage(ctx context.Context, imgRef, destPath string) error {
|
||||||
needle := filepath.Clean(constants.MagicBinaryLocation)[1:] // skip leading '/'
|
var o eboptions.Options
|
||||||
|
o.SetDefaults()
|
||||||
|
needle := strings.TrimPrefix(o.BinaryPath, "/")
|
||||||
img, err := GetRemoteImage(imgRef)
|
img, err := GetRemoteImage(imgRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("check remote image: %w", err)
|
return fmt.Errorf("check remote image: %w", err)
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
|
|
||||||
kconfig "github.com/GoogleContainerTools/kaniko/pkg/config"
|
kconfig "github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||||
"github.com/coder/envbuilder"
|
"github.com/coder/envbuilder"
|
||||||
"github.com/coder/envbuilder/constants"
|
|
||||||
eboptions "github.com/coder/envbuilder/options"
|
eboptions "github.com/coder/envbuilder/options"
|
||||||
"github.com/coder/terraform-provider-envbuilder/internal/imgutil"
|
"github.com/coder/terraform-provider-envbuilder/internal/imgutil"
|
||||||
"github.com/coder/terraform-provider-envbuilder/internal/tfutil"
|
"github.com/coder/terraform-provider-envbuilder/internal/tfutil"
|
||||||
|
@ -455,7 +454,7 @@ func runCacheProbe(ctx context.Context, builderImage string, opts eboptions.Opti
|
||||||
}()
|
}()
|
||||||
|
|
||||||
oldKanikoDir := kconfig.KanikoDir
|
oldKanikoDir := kconfig.KanikoDir
|
||||||
tmpKanikoDir := filepath.Join(tmpDir, constants.MagicDir)
|
tmpKanikoDir := filepath.Join(tmpDir, ".envbuilder")
|
||||||
// Normally you would set the KANIKO_DIR environment variable, but we are importing kaniko directly.
|
// Normally you would set the KANIKO_DIR environment variable, but we are importing kaniko directly.
|
||||||
kconfig.KanikoDir = tmpKanikoDir
|
kconfig.KanikoDir = tmpKanikoDir
|
||||||
tflog.Info(ctx, "set kaniko dir to "+tmpKanikoDir)
|
tflog.Info(ctx, "set kaniko dir to "+tmpKanikoDir)
|
||||||
|
@ -467,6 +466,8 @@ func runCacheProbe(ctx context.Context, builderImage string, opts eboptions.Opti
|
||||||
if err := os.MkdirAll(tmpKanikoDir, 0o755); err != nil {
|
if err := os.MkdirAll(tmpKanikoDir, 0o755); err != nil {
|
||||||
return nil, fmt.Errorf("failed to create kaniko dir: %w", err)
|
return nil, fmt.Errorf("failed to create kaniko dir: %w", err)
|
||||||
}
|
}
|
||||||
|
// Use the temporary directory as our 'magic dir'.
|
||||||
|
opts.MagicDirBase = tmpKanikoDir
|
||||||
|
|
||||||
// In order to correctly reproduce the final layer of the cached image, we
|
// In order to correctly reproduce the final layer of the cached image, we
|
||||||
// need the envbuilder binary used to originally build the image!
|
// need the envbuilder binary used to originally build the image!
|
||||||
|
@ -496,13 +497,6 @@ func runCacheProbe(ctx context.Context, builderImage string, opts eboptions.Opti
|
||||||
tflog.Debug(ctx, "workspace_folder not specified, using temp dir", map[string]any{"workspace_folder": opts.WorkspaceFolder})
|
tflog.Debug(ctx, "workspace_folder not specified, using temp dir", map[string]any{"workspace_folder": opts.WorkspaceFolder})
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need a place to clone the repo.
|
|
||||||
repoDir := filepath.Join(tmpDir, "repo")
|
|
||||||
if err := os.MkdirAll(repoDir, 0o755); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to create repo dir: %w", err)
|
|
||||||
}
|
|
||||||
opts.RemoteRepoDir = repoDir
|
|
||||||
|
|
||||||
// The below options are not relevant and are set to their zero value
|
// The below options are not relevant and are set to their zero value
|
||||||
// explicitly.
|
// explicitly.
|
||||||
// They must be set by extra_env to be used in the final builder image.
|
// They must be set by extra_env to be used in the final builder image.
|
||||||
|
|
|
@ -46,6 +46,7 @@ func TestAccCachedImageResource(t *testing.T) {
|
||||||
"CODER_AGENT_TOKEN", "some-token",
|
"CODER_AGENT_TOKEN", "some-token",
|
||||||
"CODER_AGENT_URL", "https://coder.example.com",
|
"CODER_AGENT_URL", "https://coder.example.com",
|
||||||
"ENVBUILDER_CACHE_REPO", deps.CacheRepo,
|
"ENVBUILDER_CACHE_REPO", deps.CacheRepo,
|
||||||
|
"ENVBUILDER_DOCKER_CONFIG_BASE64", deps.DockerConfigBase64,
|
||||||
"ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key,
|
"ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key,
|
||||||
"ENVBUILDER_GIT_URL", deps.Repo.URL,
|
"ENVBUILDER_GIT_URL", deps.Repo.URL,
|
||||||
"ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true",
|
"ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true",
|
||||||
|
@ -78,6 +79,7 @@ RUN date > /date.txt`,
|
||||||
"CODER_AGENT_TOKEN", "some-token",
|
"CODER_AGENT_TOKEN", "some-token",
|
||||||
"CODER_AGENT_URL", "https://coder.example.com",
|
"CODER_AGENT_URL", "https://coder.example.com",
|
||||||
"ENVBUILDER_CACHE_REPO", deps.CacheRepo,
|
"ENVBUILDER_CACHE_REPO", deps.CacheRepo,
|
||||||
|
"ENVBUILDER_DOCKER_CONFIG_BASE64", deps.DockerConfigBase64,
|
||||||
"ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key,
|
"ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key,
|
||||||
"ENVBUILDER_GIT_URL", deps.Repo.URL,
|
"ENVBUILDER_GIT_URL", deps.Repo.URL,
|
||||||
"ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true",
|
"ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true",
|
||||||
|
@ -88,9 +90,8 @@ RUN date > /date.txt`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// This test case ensures that parameters passed via extra_env are
|
// This test case ensures that overriding the devcontainer directory works.
|
||||||
// handled correctly.
|
name: "different_dir",
|
||||||
name: "extra_env",
|
|
||||||
files: map[string]string{
|
files: map[string]string{
|
||||||
"path/to/.devcontainer/devcontainer.json": `{"build": { "dockerfile": "Dockerfile" }}`,
|
"path/to/.devcontainer/devcontainer.json": `{"build": { "dockerfile": "Dockerfile" }}`,
|
||||||
"path/to/.devcontainer/Dockerfile": `FROM localhost:5000/test-ubuntu:latest
|
"path/to/.devcontainer/Dockerfile": `FROM localhost:5000/test-ubuntu:latest
|
||||||
|
@ -115,6 +116,7 @@ RUN date > /date.txt`,
|
||||||
"ENVBUILDER_DEVCONTAINER_DIR", "path/to/.devcontainer",
|
"ENVBUILDER_DEVCONTAINER_DIR", "path/to/.devcontainer",
|
||||||
"ENVBUILDER_DEVCONTAINER_JSON_PATH", "path/to/.devcontainer/devcontainer.json",
|
"ENVBUILDER_DEVCONTAINER_JSON_PATH", "path/to/.devcontainer/devcontainer.json",
|
||||||
"ENVBUILDER_DOCKERFILE_PATH", "path/to/.devcontainer/Dockerfile",
|
"ENVBUILDER_DOCKERFILE_PATH", "path/to/.devcontainer/Dockerfile",
|
||||||
|
"ENVBUILDER_DOCKER_CONFIG_BASE64", deps.DockerConfigBase64,
|
||||||
"ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key,
|
"ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key,
|
||||||
"ENVBUILDER_GIT_URL", deps.Repo.URL,
|
"ENVBUILDER_GIT_URL", deps.Repo.URL,
|
||||||
"ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true",
|
"ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true",
|
||||||
|
@ -149,6 +151,7 @@ RUN date > /date.txt`,
|
||||||
"CODER_AGENT_URL", "https://coder.example.com",
|
"CODER_AGENT_URL", "https://coder.example.com",
|
||||||
"ENVBUILDER_CACHE_REPO", deps.CacheRepo,
|
"ENVBUILDER_CACHE_REPO", deps.CacheRepo,
|
||||||
"ENVBUILDER_DOCKERFILE_PATH", "Dockerfile",
|
"ENVBUILDER_DOCKERFILE_PATH", "Dockerfile",
|
||||||
|
"ENVBUILDER_DOCKER_CONFIG_BASE64", deps.DockerConfigBase64,
|
||||||
"ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key,
|
"ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key,
|
||||||
"ENVBUILDER_GIT_URL", deps.Repo.URL,
|
"ENVBUILDER_GIT_URL", deps.Repo.URL,
|
||||||
"ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true",
|
"ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true",
|
||||||
|
|
|
@ -272,7 +272,6 @@ func Test_computeEnvFromOptions(t *testing.T) {
|
||||||
PostStartScriptPath: "string",
|
PostStartScriptPath: "string",
|
||||||
PushImage: true,
|
PushImage: true,
|
||||||
RemoteRepoBuildMode: true,
|
RemoteRepoBuildMode: true,
|
||||||
RemoteRepoDir: "string",
|
|
||||||
SetupScript: "string",
|
SetupScript: "string",
|
||||||
SkipRebuild: true,
|
SkipRebuild: true,
|
||||||
SSLCertBase64: "string",
|
SSLCertBase64: "string",
|
||||||
|
@ -314,7 +313,6 @@ func Test_computeEnvFromOptions(t *testing.T) {
|
||||||
"ENVBUILDER_POST_START_SCRIPT_PATH": "string",
|
"ENVBUILDER_POST_START_SCRIPT_PATH": "string",
|
||||||
"ENVBUILDER_PUSH_IMAGE": "true",
|
"ENVBUILDER_PUSH_IMAGE": "true",
|
||||||
"ENVBUILDER_REMOTE_REPO_BUILD_MODE": "true",
|
"ENVBUILDER_REMOTE_REPO_BUILD_MODE": "true",
|
||||||
"ENVBUILDER_REMOTE_REPO_DIR": "string",
|
|
||||||
"ENVBUILDER_SETUP_SCRIPT": "string",
|
"ENVBUILDER_SETUP_SCRIPT": "string",
|
||||||
"ENVBUILDER_SKIP_REBUILD": "true",
|
"ENVBUILDER_SKIP_REBUILD": "true",
|
||||||
"ENVBUILDER_SSL_CERT_BASE64": "string",
|
"ENVBUILDER_SSL_CERT_BASE64": "string",
|
||||||
|
|
|
@ -3,6 +3,7 @@ package provider
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -35,10 +36,11 @@ var testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServe
|
||||||
|
|
||||||
// testDependencies contain information about stuff the test depends on.
|
// testDependencies contain information about stuff the test depends on.
|
||||||
type testDependencies struct {
|
type testDependencies struct {
|
||||||
BuilderImage string
|
BuilderImage string
|
||||||
CacheRepo string
|
CacheRepo string
|
||||||
ExtraEnv map[string]string
|
DockerConfigBase64 string
|
||||||
Repo testGitRepoSSH
|
ExtraEnv map[string]string
|
||||||
|
Repo testGitRepoSSH
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config generates a valid Terraform config file from the dependencies.
|
// Config generates a valid Terraform config file from the dependencies.
|
||||||
|
@ -47,8 +49,9 @@ func (d *testDependencies) Config(t testing.TB) string {
|
||||||
|
|
||||||
tpl := `provider envbuilder {}
|
tpl := `provider envbuilder {}
|
||||||
resource "envbuilder_cached_image" "test" {
|
resource "envbuilder_cached_image" "test" {
|
||||||
builder_image = {{ quote .BuilderImage }}
|
builder_image = {{ quote .BuilderImage }}
|
||||||
cache_repo = {{ quote .CacheRepo }}
|
cache_repo = {{ quote .CacheRepo }}
|
||||||
|
docker_config_base64 = {{ quote .DockerConfigBase64 }}
|
||||||
git_url = {{ quote .Repo.URL }}
|
git_url = {{ quote .Repo.URL }}
|
||||||
extra_env = {
|
extra_env = {
|
||||||
"ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH": {{ quote .Repo.Key }}
|
"ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH": {{ quote .Repo.Key }}
|
||||||
|
@ -78,19 +81,29 @@ func setup(ctx context.Context, t testing.TB, extraEnv, files map[string]string)
|
||||||
envbuilderVersion := getEnvOrDefault("ENVBUILDER_VERSION", "latest")
|
envbuilderVersion := getEnvOrDefault("ENVBUILDER_VERSION", "latest")
|
||||||
envbuilderImageRef := envbuilderImage + ":" + envbuilderVersion
|
envbuilderImageRef := envbuilderImage + ":" + envbuilderVersion
|
||||||
|
|
||||||
// TODO: envbuilder creates /.envbuilder/bin/envbuilder owned by root:root which we are unable to clean up.
|
testUsername := "testuser"
|
||||||
// This causes tests to fail.
|
testPassword := "testpassword"
|
||||||
|
testAuthBase64 := base64.URLEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", testUsername, testPassword)))
|
||||||
regDir := t.TempDir()
|
regDir := t.TempDir()
|
||||||
reg := registrytest.New(t, regDir)
|
reg := registrytest.New(t, regDir, registrytest.BasicAuthMW(t, testUsername, testPassword))
|
||||||
|
|
||||||
repoDir := setupGitRepo(t, files)
|
repoDir := setupGitRepo(t, files)
|
||||||
gitRepo := serveGitRepoSSH(ctx, t, repoDir)
|
gitRepo := serveGitRepoSSH(ctx, t, repoDir)
|
||||||
|
dockerConfigJSON := fmt.Sprintf(`{
|
||||||
|
"auths": {
|
||||||
|
"%s": {
|
||||||
|
"auth": "%s",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`, reg, testAuthBase64)
|
||||||
|
dockerConfigJSONBase64 := base64.StdEncoding.EncodeToString([]byte(dockerConfigJSON))
|
||||||
|
|
||||||
return testDependencies{
|
return testDependencies{
|
||||||
BuilderImage: envbuilderImageRef,
|
BuilderImage: envbuilderImageRef,
|
||||||
CacheRepo: reg + "/test",
|
CacheRepo: reg + "/test",
|
||||||
ExtraEnv: extraEnv,
|
ExtraEnv: extraEnv,
|
||||||
Repo: gitRepo,
|
Repo: gitRepo,
|
||||||
|
DockerConfigBase64: dockerConfigJSONBase64,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +128,7 @@ func seedCache(ctx context.Context, t testing.TB, deps testDependencies) {
|
||||||
"ENVBUILDER_VERBOSE": "true",
|
"ENVBUILDER_VERBOSE": "true",
|
||||||
"ENVBUILDER_GIT_URL": deps.Repo.URL,
|
"ENVBUILDER_GIT_URL": deps.Repo.URL,
|
||||||
"ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH": "/id_ed25519",
|
"ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH": "/id_ed25519",
|
||||||
|
"ENVBUILDER_DOCKER_CONFIG_BASE64": deps.DockerConfigBase64,
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range deps.ExtraEnv {
|
for k, v := range deps.ExtraEnv {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package registrytest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -13,12 +14,31 @@ import (
|
||||||
// New starts a new Docker registry listening on localhost.
|
// New starts a new Docker registry listening on localhost.
|
||||||
// It will automatically shut down when the test finishes.
|
// It will automatically shut down when the test finishes.
|
||||||
// It will store data in dir.
|
// It will store data in dir.
|
||||||
func New(t testing.TB, dir string) string {
|
func New(t testing.TB, dir string, mws ...func(http.Handler) http.Handler) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
regHandler := registry.New(registry.WithBlobHandler(registry.NewDiskBlobHandler(dir)))
|
regHandler := registry.New(registry.WithBlobHandler(registry.NewDiskBlobHandler(dir)))
|
||||||
|
for _, mw := range mws {
|
||||||
|
regHandler = mw(regHandler)
|
||||||
|
}
|
||||||
regSrv := httptest.NewServer(regHandler)
|
regSrv := httptest.NewServer(regHandler)
|
||||||
t.Cleanup(func() { regSrv.Close() })
|
t.Cleanup(func() { regSrv.Close() })
|
||||||
regSrvURL, err := url.Parse(regSrv.URL)
|
regSrvURL, err := url.Parse(regSrv.URL)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return fmt.Sprintf("localhost:%s", regSrvURL.Port())
|
return fmt.Sprintf("localhost:%s", regSrvURL.Port())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BasicAuthMW(t testing.TB, username, password string) func(http.Handler) http.Handler {
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if username != "" || password != "" {
|
||||||
|
authUser, authPass, ok := r.BasicAuth()
|
||||||
|
if !ok || username != authUser || password != authPass {
|
||||||
|
t.Logf("basic auth failed: got user %q, pass %q", authUser, authPass)
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue