From 532c6390801aa43cf611047f4e75cf3072e67909 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 2 Dec 2024 11:26:18 +0000 Subject: [PATCH 1/7] fix: enable logging for setup script when not a tty (#402) (#422) Co-authored-by: Mathias Fredriksson --- envbuilder.go | 30 +++++++++++++++++++----------- integration/integration_test.go | 3 +++ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/envbuilder.go b/envbuilder.go index 028a7bb2..a78c7666 100644 --- a/envbuilder.go +++ b/envbuilder.go @@ -1,7 +1,6 @@ package envbuilder import ( - "bufio" "bytes" "context" "encoding/base64" @@ -885,16 +884,8 @@ func run(ctx context.Context, opts options.Options, execArgs *execArgsInfo) erro cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin } else { - var buf bytes.Buffer - go func() { - scanner := bufio.NewScanner(&buf) - for scanner.Scan() { - opts.Logger(log.LevelInfo, "%s", scanner.Text()) - } - }() - - cmd.Stdout = &buf - cmd.Stderr = &buf + cmd.Stdout = newWriteLogger(opts.Logger, log.LevelInfo) + cmd.Stderr = newWriteLogger(opts.Logger, log.LevelError) } err = cmd.Run() if err != nil { @@ -1814,6 +1805,23 @@ func onceErrFunc(f func() error) func() error { } } +type writeLogger struct { + logf log.Func + level log.Level +} + +func newWriteLogger(logf log.Func, level log.Level) io.Writer { + return writeLogger{logf: logf, level: level} +} + +func (l writeLogger) Write(p []byte) (n int, err error) { + lines := bytes.Split(p, []byte("\n")) + for _, line := range lines { + l.logf(l.level, "%s", line) + } + return len(p), nil +} + // Allows quick testing of layer caching using a local directory! func serveLocalRegistry(ctx context.Context, logf log.Func, layerCacheDir string) (string, func(), error) { noop := func() {} diff --git a/integration/integration_test.go b/integration/integration_test.go index 46e0e88c..a00525fc 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -127,6 +127,7 @@ func TestLogs(t *testing.T) { envbuilderEnv("GIT_URL", srv.URL), "CODER_AGENT_URL=" + logSrv.URL, "CODER_AGENT_TOKEN=" + token, + "ENVBUILDER_SETUP_SCRIPT=/bin/sh -c 'echo MY${NO_MATCH_ENV}_SETUP_SCRIPT_OUT; echo MY${NO_MATCH_ENV}_SETUP_SCRIPT_ERR' 1>&2", "ENVBUILDER_INIT_SCRIPT=env", }}) require.NoError(t, err) @@ -159,6 +160,8 @@ func TestLogs(t *testing.T) { require.NoError(t, err) logs := string(logBytes) require.Contains(t, logs, "CODER_AGENT_SUBSYSTEM=envbuilder") + require.Contains(t, logs, "MY_SETUP_SCRIPT_OUT") + require.Contains(t, logs, "MY_SETUP_SCRIPT_ERR") } func TestInitScriptInitCommand(t *testing.T) { From 4cba91f430f868f6307849b67e77fb2450adc368 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 2 Dec 2024 11:26:36 +0000 Subject: [PATCH 2/7] fix: do not error if failed to push image (#390) (#423) --- docs/env-variables.md | 1 + envbuilder.go | 7 +++-- integration/integration_test.go | 52 ++++++++++++++++++++++++++++++--- options/options.go | 12 ++++++++ options/testdata/options.golden | 5 ++++ 5 files changed, 71 insertions(+), 6 deletions(-) diff --git a/docs/env-variables.md b/docs/env-variables.md index cb7054f3..c198c705 100644 --- a/docs/env-variables.md +++ b/docs/env-variables.md @@ -18,6 +18,7 @@ | `--docker-config-base64` | `ENVBUILDER_DOCKER_CONFIG_BASE64` | | The base64 encoded Docker config file that will be used to pull images from private container registries. When this is set, Docker configuration set via the DOCKER_CONFIG environment variable is ignored. | | `--fallback-image` | `ENVBUILDER_FALLBACK_IMAGE` | | Specifies an alternative image to use when neither an image is declared in the devcontainer.json file nor a Dockerfile is present. If there's a build failure (from a faulty Dockerfile) or a misconfiguration, this image will be the substitute. Set ExitOnBuildFailure to true to halt the container if the build faces an issue. | | `--exit-on-build-failure` | `ENVBUILDER_EXIT_ON_BUILD_FAILURE` | | Terminates the container upon a build failure. This is handy when preferring the FALLBACK_IMAGE in cases where no devcontainer.json or image is provided. However, it ensures that the container stops if the build process encounters an error. | +| `--exit-on-push-failure` | `ENVBUILDER_EXIT_ON_PUSH_FAILURE` | | ExitOnPushFailure terminates the container upon a push failure. This is useful if failure to push the built image should abort execution and result in an error. | | `--force-safe` | `ENVBUILDER_FORCE_SAFE` | | Ignores any filesystem safety checks. This could cause serious harm to your system! This is used in cases where bypass is needed to unblock customers. | | `--insecure` | `ENVBUILDER_INSECURE` | | Bypass TLS verification when cloning and pulling from container registries. | | `--ignore-paths` | `ENVBUILDER_IGNORE_PATHS` | | The comma separated list of paths to ignore when building the workspace. | diff --git a/envbuilder.go b/envbuilder.go index a78c7666..276c7fc3 100644 --- a/envbuilder.go +++ b/envbuilder.go @@ -581,10 +581,13 @@ func run(ctx context.Context, opts options.Options, execArgs *execArgsInfo) erro endStage("🏗️ Built image!") if opts.PushImage { endStage = startStage("🏗️ Pushing image...") - if err := executor.DoPush(image, kOpts); err != nil { + if err := executor.DoPush(image, kOpts); err == nil { + endStage("🏗️ Pushed image!") + } else if !opts.ExitOnPushFailure { + endStage("⚠️️ Failed to push image!") + } else { return nil, xerrors.Errorf("do push: %w", err) } - endStage("🏗️ Pushed image!") } return image, err diff --git a/integration/integration_test.go b/integration/integration_test.go index a00525fc..225509eb 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -1882,9 +1882,10 @@ RUN date --utc > /root/date.txt`, testImageAlpine), _, err = remote.Image(ref, remoteAuthOpt) require.ErrorContains(t, err, "NAME_UNKNOWN", "expected image to not be present before build + push") - // When: we run envbuilder with PUSH_IMAGE set + // When: we run envbuilder with PUSH_IMAGE and EXIT_ON_PUSH_FAILURE set _, err = runEnvbuilder(t, runOpts{env: append(opts, envbuilderEnv("PUSH_IMAGE", "1"), + envbuilderEnv("EXIT_ON_PUSH_FAILURE", "1"), )}) // Then: it should fail with an Unauthorized error require.ErrorContains(t, err, "401 Unauthorized", "expected unauthorized error using no auth when cache repo requires it") @@ -2077,7 +2078,7 @@ RUN date --utc > /root/date.txt`, testImageAlpine), require.ErrorContains(t, err, "--cache-repo must be set when using --push-image") }) - t.Run("PushErr", func(t *testing.T) { + t.Run("PushErr/ExitOnPushFail", func(t *testing.T) { t.Parallel() srv := gittest.CreateGitServer(t, gittest.Options{ @@ -2107,12 +2108,50 @@ RUN date --utc > /root/date.txt`, testImageAlpine), envbuilderEnv("GIT_URL", srv.URL), envbuilderEnv("CACHE_REPO", notRegURL), envbuilderEnv("PUSH_IMAGE", "1"), + envbuilderEnv("EXIT_ON_PUSH_FAILURE", "1"), }}) // Then: envbuilder should fail with a descriptive error require.ErrorContains(t, err, "failed to push to destination") }) + t.Run("PushErr/NoExitOnPushFail", func(t *testing.T) { + t.Parallel() + + srv := gittest.CreateGitServer(t, gittest.Options{ + Files: map[string]string{ + ".devcontainer/Dockerfile": fmt.Sprintf(`FROM %s +USER root +ARG WORKDIR=/ +WORKDIR $WORKDIR +ENV FOO=bar +RUN echo $FOO > /root/foo.txt +RUN date --utc > /root/date.txt`, testImageAlpine), + ".devcontainer/devcontainer.json": `{ + "name": "Test", + "build": { + "dockerfile": "Dockerfile" + }, + }`, + }, + }) + + // Given: registry is not set up (in this case, not a registry) + notRegSrv := httptest.NewServer(http.NotFoundHandler()) + notRegURL := strings.TrimPrefix(notRegSrv.URL, "http://") + "/test" + + // When: we run envbuilder with PUSH_IMAGE set + _, err := runEnvbuilder(t, runOpts{env: []string{ + envbuilderEnv("GIT_URL", srv.URL), + envbuilderEnv("CACHE_REPO", notRegURL), + envbuilderEnv("PUSH_IMAGE", "1"), + envbuilderEnv("EXIT_ON_PUSH_FAILURE", "0"), + }}) + + // Then: envbuilder should not fail + require.NoError(t, err) + }) + t.Run("CacheAndPushDevcontainerFeatures", func(t *testing.T) { t.Parallel() @@ -2354,8 +2393,13 @@ func pushImage(t *testing.T, ref name.Reference, remoteOpt remote.Option, env .. if remoteOpt != nil { remoteOpts = append(remoteOpts, remoteOpt) } - - _, err := runEnvbuilder(t, runOpts{env: append(env, envbuilderEnv("PUSH_IMAGE", "1"))}) + opts := runOpts{ + env: append(env, + envbuilderEnv("PUSH_IMAGE", "1"), + envbuilderEnv("EXIT_ON_PUSH_FAILURE", "1"), + ), + } + _, err := runEnvbuilder(t, opts) require.NoError(t, err, "envbuilder push image failed") img, err := remote.Image(ref, remoteOpts...) diff --git a/options/options.go b/options/options.go index ebda2eeb..b2497d3c 100644 --- a/options/options.go +++ b/options/options.go @@ -78,6 +78,10 @@ type Options struct { // devcontainer.json or image is provided. However, it ensures that the // container stops if the build process encounters an error. ExitOnBuildFailure bool + // ExitOnPushFailure terminates the container upon a push failure. This is + // useful if failure to push the built image should abort execution + // and result in an error. + ExitOnPushFailure bool // ForceSafe ignores any filesystem safety checks. This could cause serious // harm to your system! This is used in cases where bypass is needed to // unblock customers. @@ -301,6 +305,14 @@ func (o *Options) CLI() serpent.OptionSet { "no devcontainer.json or image is provided. However, it ensures " + "that the container stops if the build process encounters an error.", }, + { + Flag: "exit-on-push-failure", + Env: WithEnvPrefix("EXIT_ON_PUSH_FAILURE"), + Value: serpent.BoolOf(&o.ExitOnPushFailure), + Description: "ExitOnPushFailure terminates the container upon a push failure. " + + "This is useful if failure to push the built image should abort execution " + + "and result in an error.", + }, { Flag: "force-safe", Env: WithEnvPrefix("FORCE_SAFE"), diff --git a/options/testdata/options.golden b/options/testdata/options.golden index 397d5e0b..f5c5729d 100644 --- a/options/testdata/options.golden +++ b/options/testdata/options.golden @@ -62,6 +62,11 @@ OPTIONS: image is provided. However, it ensures that the container stops if the build process encounters an error. + --exit-on-push-failure bool, $ENVBUILDER_EXIT_ON_PUSH_FAILURE + ExitOnPushFailure terminates the container upon a push failure. This + is useful if failure to push the built image should abort execution + and result in an error. + --export-env-file string, $ENVBUILDER_EXPORT_ENV_FILE Optional file path to a .env file where envbuilder will dump environment variables from devcontainer.json and the built container From 5b1acda0ce03b5974f29ace38ad40c7b08e69f2d Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 2 Dec 2024 11:27:02 +0000 Subject: [PATCH 3/7] feat: allow changing default workspaces folder (#406) (#424) (cherry picked from commit 24ef801) Co-authored-by: Mathias Fredriksson --- docs/env-variables.md | 3 +- integration/integration_test.go | 22 ++++++++++++++ options/defaults.go | 23 ++++++++------- options/defaults_test.go | 52 +++++++++++++++++++++++++-------- options/options.go | 19 ++++++++++-- options/testdata/options.golden | 6 ++++ 6 files changed, 99 insertions(+), 26 deletions(-) diff --git a/docs/env-variables.md b/docs/env-variables.md index c198c705..427a3f63 100644 --- a/docs/env-variables.md +++ b/docs/env-variables.md @@ -31,7 +31,8 @@ | `--git-ssh-private-key-path` | `ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH` | | Path to an SSH private key to be used for Git authentication. If this is set, then GIT_SSH_PRIVATE_KEY_BASE64 cannot be set. | | `--git-ssh-private-key-base64` | `ENVBUILDER_GIT_SSH_PRIVATE_KEY_BASE64` | | Base64 encoded SSH private key to be used for Git authentication. If this is set, then GIT_SSH_PRIVATE_KEY_PATH cannot be set. | | `--git-http-proxy-url` | `ENVBUILDER_GIT_HTTP_PROXY_URL` | | The URL for the HTTP proxy. This is optional. | -| `--workspace-folder` | `ENVBUILDER_WORKSPACE_FOLDER` | | The path to the workspace folder that will be built. This is optional. | +| `--workspace-base-dir` | `ENVBUILDER_WORKSPACE_BASE_DIR` | `/workspaces` | The path under which workspaces will be placed when workspace folder option is not given. | +| `--workspace-folder` | `ENVBUILDER_WORKSPACE_FOLDER` | | The path to the workspace folder that will be built. This is optional. Defaults to `[workspace base dir]/[name]` where name is the name of the repository or `empty`. | | `--ssl-cert-base64` | `ENVBUILDER_SSL_CERT_BASE64` | | The content of an SSL cert file. This is useful for self-signed certificates. | | `--export-env-file` | `ENVBUILDER_EXPORT_ENV_FILE` | | Optional file path to a .env file where envbuilder will dump environment variables from devcontainer.json and the built container image. | | `--post-start-script-path` | `ENVBUILDER_POST_START_SCRIPT_PATH` | | The path to a script that will be created by envbuilder based on the postStartCommand in devcontainer.json, if any is specified (otherwise the script is not created). If this is set, the specified InitCommand should check for the presence of this script and execute it after successful startup. | diff --git a/integration/integration_test.go b/integration/integration_test.go index 225509eb..d10fac1c 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -821,6 +821,28 @@ func TestBuildFromDevcontainerInCustomPath(t *testing.T) { require.Equal(t, "hello", strings.TrimSpace(output)) } +func TestBuildFromCustomWorkspaceBaseDir(t *testing.T) { + t.Parallel() + + // Ensures that a Git repository with a devcontainer.json is cloned and built. + srv := gittest.CreateGitServer(t, gittest.Options{ + Files: map[string]string{ + "Dockerfile": "FROM " + testImageUbuntu, + }, + }) + ctr, err := runEnvbuilder(t, runOpts{ + env: []string{ + envbuilderEnv("DOCKERFILE_PATH", "Dockerfile"), + envbuilderEnv("WORKSPACE_BASE_DIR", "/foo"), + envbuilderEnv("GIT_URL", srv.URL), + }, + }) + require.NoError(t, err) + + output := execContainer(t, ctr, "readlink /proc/1/cwd") + require.Contains(t, output, "/foo/") +} + func TestBuildFromDevcontainerInSubfolder(t *testing.T) { t.Parallel() diff --git a/options/defaults.go b/options/defaults.go index b9e47a80..a6fd145b 100644 --- a/options/defaults.go +++ b/options/defaults.go @@ -12,29 +12,29 @@ import ( "github.com/coder/envbuilder/internal/workingdir" ) -// EmptyWorkspaceDir is the path to a workspace that has -// nothing going on... it's empty! -var EmptyWorkspaceDir = "/workspaces/empty" - // DefaultWorkspaceFolder returns the default workspace folder // for a given repository URL. -func DefaultWorkspaceFolder(repoURL string) string { +func DefaultWorkspaceFolder(workspacesFolder, repoURL string) string { + // emptyWorkspaceDir is the path to a workspace that has + // nothing going on... it's empty! + emptyWorkspaceDir := workspacesFolder + "/empty" + if repoURL == "" { - return EmptyWorkspaceDir + return emptyWorkspaceDir } parsed, err := giturls.Parse(repoURL) if err != nil { - return EmptyWorkspaceDir + return emptyWorkspaceDir } repo := path.Base(parsed.Path) // Giturls parsing never actually fails since ParseLocal never // errors and places the entire URL in the Path field. This check // ensures it's at least a Unix path containing forwardslash. if repo == repoURL || repo == "/" || repo == "." || repo == "" { - return EmptyWorkspaceDir + return emptyWorkspaceDir } repo = strings.TrimSuffix(repo, ".git") - return fmt.Sprintf("/workspaces/%s", repo) + return fmt.Sprintf("%s/%s", workspacesFolder, repo) } func (o *Options) SetDefaults() { @@ -59,8 +59,11 @@ func (o *Options) SetDefaults() { if o.Filesystem == nil { o.Filesystem = chmodfs.New(osfs.New("/")) } + if o.WorkspaceBaseDir == "" { + o.WorkspaceBaseDir = "/workspaces" + } if o.WorkspaceFolder == "" { - o.WorkspaceFolder = DefaultWorkspaceFolder(o.GitURL) + o.WorkspaceFolder = DefaultWorkspaceFolder(o.WorkspaceBaseDir, o.GitURL) } if o.BinaryPath == "" { o.BinaryPath = "/.envbuilder/bin/envbuilder" diff --git a/options/defaults_test.go b/options/defaults_test.go index de57365d..3efd8f25 100644 --- a/options/defaults_test.go +++ b/options/defaults_test.go @@ -17,83 +17,110 @@ func TestDefaultWorkspaceFolder(t *testing.T) { successTests := []struct { name string + baseDir string gitURL string expected string }{ { name: "HTTP", + baseDir: "/workspaces", gitURL: "https://github.com/coder/envbuilder.git", expected: "/workspaces/envbuilder", }, { name: "SSH", + baseDir: "/workspaces", gitURL: "git@github.com:coder/envbuilder.git", expected: "/workspaces/envbuilder", }, { name: "username and password", + baseDir: "/workspaces", gitURL: "https://username:password@github.com/coder/envbuilder.git", expected: "/workspaces/envbuilder", }, { name: "trailing", + baseDir: "/workspaces", gitURL: "https://github.com/coder/envbuilder.git/", expected: "/workspaces/envbuilder", }, { name: "trailing-x2", + baseDir: "/workspaces", gitURL: "https://github.com/coder/envbuilder.git//", expected: "/workspaces/envbuilder", }, { name: "no .git", + baseDir: "/workspaces", gitURL: "https://github.com/coder/envbuilder", expected: "/workspaces/envbuilder", }, { name: "trailing no .git", + baseDir: "/workspaces", gitURL: "https://github.com/coder/envbuilder/", expected: "/workspaces/envbuilder", }, { name: "fragment", + baseDir: "/workspaces", gitURL: "https://github.com/coder/envbuilder.git#feature-branch", expected: "/workspaces/envbuilder", }, { name: "fragment-trailing", + baseDir: "/workspaces", gitURL: "https://github.com/coder/envbuilder.git/#refs/heads/feature-branch", expected: "/workspaces/envbuilder", }, { name: "fragment-trailing no .git", + baseDir: "/workspaces", gitURL: "https://github.com/coder/envbuilder/#refs/heads/feature-branch", expected: "/workspaces/envbuilder", }, { name: "space", + baseDir: "/workspaces", gitURL: "https://github.com/coder/env%20builder.git", expected: "/workspaces/env builder", }, { name: "Unix path", + baseDir: "/workspaces", gitURL: "/repo", expected: "/workspaces/repo", }, { name: "Unix subpath", + baseDir: "/workspaces", gitURL: "/path/to/repo", expected: "/workspaces/repo", }, { name: "empty", + baseDir: "/workspaces", gitURL: "", - expected: options.EmptyWorkspaceDir, + expected: "/workspaces/empty", + }, + { + name: "non default workspaces folder", + baseDir: "/foo", + gitURL: "https://github.com/coder/envbuilder.git", + expected: "/foo/envbuilder", + }, + { + name: "non default workspaces folder empty git URL", + baseDir: "/foo", + gitURL: "", + expected: "/foo/empty", }, } for _, tt := range successTests { t.Run(tt.name, func(t *testing.T) { - dir := options.DefaultWorkspaceFolder(tt.gitURL) + dir := options.DefaultWorkspaceFolder(tt.baseDir, tt.gitURL) require.Equal(t, tt.expected, dir) }) } @@ -125,8 +152,8 @@ func TestDefaultWorkspaceFolder(t *testing.T) { } for _, tt := range invalidTests { t.Run(tt.name, func(t *testing.T) { - dir := options.DefaultWorkspaceFolder(tt.invalidURL) - require.Equal(t, options.EmptyWorkspaceDir, dir) + dir := options.DefaultWorkspaceFolder("/workspaces", tt.invalidURL) + require.Equal(t, "/workspaces/empty", dir) }) } } @@ -135,14 +162,15 @@ func TestOptions_SetDefaults(t *testing.T) { t.Parallel() expected := options.Options{ - InitScript: "sleep infinity", - InitCommand: "/bin/sh", - IgnorePaths: []string{"/var/run", "/product_uuid", "/product_name"}, - Filesystem: chmodfs.New(osfs.New("/")), - GitURL: "", - WorkspaceFolder: options.EmptyWorkspaceDir, - MagicDirBase: "/.envbuilder", - BinaryPath: "/.envbuilder/bin/envbuilder", + InitScript: "sleep infinity", + InitCommand: "/bin/sh", + IgnorePaths: []string{"/var/run", "/product_uuid", "/product_name"}, + Filesystem: chmodfs.New(osfs.New("/")), + GitURL: "", + WorkspaceBaseDir: "/workspaces", + WorkspaceFolder: "/workspaces/empty", + MagicDirBase: "/.envbuilder", + BinaryPath: "/.envbuilder/bin/envbuilder", } var actual options.Options diff --git a/options/options.go b/options/options.go index b2497d3c..9b9edda2 100644 --- a/options/options.go +++ b/options/options.go @@ -117,8 +117,12 @@ type Options struct { GitSSHPrivateKeyBase64 string // GitHTTPProxyURL is the URL for the HTTP proxy. This is optional. GitHTTPProxyURL string + // WorkspaceBaseDir is the path under which workspaces will be placed when + // workspace folder option is not given. + WorkspaceBaseDir string // WorkspaceFolder is the path to the workspace folder that will be built. - // This is optional. + // This is optional. Defaults to `[workspace base dir]/[name]` where name is + // the name of the repository or "empty". WorkspaceFolder string // SSLCertBase64 is the content of an SSL cert file. This is useful for // self-signed certificates. @@ -394,12 +398,21 @@ func (o *Options) CLI() serpent.OptionSet { Value: serpent.StringOf(&o.GitHTTPProxyURL), Description: "The URL for the HTTP proxy. This is optional.", }, + { + Flag: "workspace-base-dir", + Env: WithEnvPrefix("WORKSPACE_BASE_DIR"), + Value: serpent.StringOf(&o.WorkspaceBaseDir), + Default: "/workspaces", + Description: "The path under which workspaces will be placed when " + + "workspace folder option is not given.", + }, { Flag: "workspace-folder", Env: WithEnvPrefix("WORKSPACE_FOLDER"), Value: serpent.StringOf(&o.WorkspaceFolder), - Description: "The path to the workspace folder that will " + - "be built. This is optional.", + Description: "The path to the workspace folder that will be built. " + + "This is optional. Defaults to `[workspace base dir]/[name]` where " + + "name is the name of the repository or `empty`.", }, { Flag: "ssl-cert-base64", diff --git a/options/testdata/options.golden b/options/testdata/options.golden index f5c5729d..203c197b 100644 --- a/options/testdata/options.golden +++ b/options/testdata/options.golden @@ -177,6 +177,12 @@ OPTIONS: --verbose bool, $ENVBUILDER_VERBOSE Enable verbose logging. + --workspace-base-dir string, $ENVBUILDER_WORKSPACE_BASE_DIR (default: /workspaces) + The path under which workspaces will be placed when workspace folder + option is not given. + --workspace-folder string, $ENVBUILDER_WORKSPACE_FOLDER The path to the workspace folder that will be built. This is optional. + Defaults to `[workspace base dir]/[name]` where name is the name of + the repository or `empty`. From 84e1c40b1c51f79c675710273e308eec99a7f696 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 2 Dec 2024 11:29:08 +0000 Subject: [PATCH 4/7] fix: update kaniko fork to fix BLOB_UNKNOWN errors (#410) (#425) Co-authored-by: Mathias Fredriksson --- Makefile | 6 ++- devcontainer/devcontainer.go | 6 +-- envbuilder.go | 9 ++++ go.mod | 27 +++++----- go.sum | 52 ++++++++++---------- integration/integration_test.go | 41 +++++++++++++-- integration/testdata/blob-unknown/Dockerfile | 7 +++ 7 files changed, 101 insertions(+), 47 deletions(-) create mode 100644 integration/testdata/blob-unknown/Dockerfile diff --git a/Makefile b/Makefile index ce079015..14ed5182 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,7 @@ test-registry-container: .registry-cache # Pulls images referenced in integration tests and pushes them to the local cache. .PHONY: test-images-push -test-images-push: .registry-cache/docker/registry/v2/repositories/envbuilder-test-alpine .registry-cache/docker/registry/v2/repositories/envbuilder-test-ubuntu .registry-cache/docker/registry/v2/repositories/envbuilder-test-codercom-code-server +test-images-push: .registry-cache/docker/registry/v2/repositories/envbuilder-test-alpine .registry-cache/docker/registry/v2/repositories/envbuilder-test-ubuntu .registry-cache/docker/registry/v2/repositories/envbuilder-test-codercom-code-server .registry-cache/docker/registry/v2/repositories/envbuilder-test-blob-unknown .PHONY: test-images-pull test-images-pull: @@ -77,6 +77,7 @@ test-images-pull: docker tag ubuntu:latest localhost:5000/envbuilder-test-ubuntu:latest docker pull codercom/code-server:latest docker tag codercom/code-server:latest localhost:5000/envbuilder-test-codercom-code-server:latest + docker build -t localhost:5000/envbuilder-test-blob-unknown:latest -f integration/testdata/blob-unknown/Dockerfile integration/testdata/blob-unknown .registry-cache: mkdir -p .registry-cache && chmod -R ag+w .registry-cache @@ -89,3 +90,6 @@ test-images-pull: .registry-cache/docker/registry/v2/repositories/envbuilder-test-codercom-code-server: docker push localhost:5000/envbuilder-test-codercom-code-server:latest + +.registry-cache/docker/registry/v2/repositories/envbuilder-test-blob-unknown: + docker push localhost:5000/envbuilder-test-blob-unknown:latest diff --git a/devcontainer/devcontainer.go b/devcontainer/devcontainer.go index 6135c0ef..0bf7cc35 100644 --- a/devcontainer/devcontainer.go +++ b/devcontainer/devcontainer.go @@ -400,11 +400,11 @@ func ImageFromDockerfile(dockerfileContent string) (name.Reference, error) { arg = strings.TrimSpace(arg) if strings.Contains(arg, "=") { parts := strings.SplitN(arg, "=", 2) - key, err := lexer.ProcessWord(parts[0], args) + key, _, err := lexer.ProcessWord(parts[0], shell.EnvsFromSlice(args)) if err != nil { return nil, fmt.Errorf("processing %q: %w", line, err) } - val, err := lexer.ProcessWord(parts[1], args) + val, _, err := lexer.ProcessWord(parts[1], shell.EnvsFromSlice(args)) if err != nil { return nil, fmt.Errorf("processing %q: %w", line, err) } @@ -421,7 +421,7 @@ func ImageFromDockerfile(dockerfileContent string) (name.Reference, error) { if imageRef == "" { return nil, fmt.Errorf("no FROM directive found") } - imageRef, err := lexer.ProcessWord(imageRef, args) + imageRef, _, err := lexer.ProcessWord(imageRef, shell.EnvsFromSlice(args)) if err != nil { return nil, fmt.Errorf("processing %q: %w", imageRef, err) } diff --git a/envbuilder.go b/envbuilder.go index 276c7fc3..6f3231d1 100644 --- a/envbuilder.go +++ b/envbuilder.go @@ -581,6 +581,15 @@ func run(ctx context.Context, opts options.Options, execArgs *execArgsInfo) erro endStage("🏗️ Built image!") if opts.PushImage { endStage = startStage("🏗️ Pushing image...") + // To debug registry issues, enable logging: + // + // import ( + // stdlog "log" + // reglogs "github.com/google/go-containerregistry/pkg/logs" + // ) + // reglogs.Debug = stdlog.New(os.Stderr, "", 0) + // reglogs.Warn = stdlog.New(os.Stderr, "", 0) + // reglogs.Progress = stdlog.New(os.Stderr, "", 0) if err := executor.DoPush(image, kOpts); err == nil { endStage("🏗️ Pushed image!") } else if !opts.ExitOnPushFailure { diff --git a/go.mod b/go.mod index 9fa1d696..c51f4227 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.22.4 // There are a few options we need added to Kaniko! // See: https://github.com/GoogleContainerTools/kaniko/compare/main...coder:kaniko:main -replace github.com/GoogleContainerTools/kaniko => github.com/coder/kaniko v0.0.0-20240925122543-caa18967f374 +replace github.com/GoogleContainerTools/kaniko => github.com/coder/kaniko v0.0.0-20241120132148-131d6094d781 // Required to import codersdk due to gvisor dependency. replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa558fbe5374 @@ -19,8 +19,8 @@ require ( github.com/coder/serpent v0.7.0 github.com/containerd/platforms v0.2.1 github.com/distribution/distribution/v3 v3.0.0-alpha.1 - github.com/docker/cli v27.2.0+incompatible - github.com/docker/docker v26.1.5+incompatible + github.com/docker/cli v27.2.1+incompatible + github.com/docker/docker v27.3.1+incompatible github.com/fatih/color v1.17.0 github.com/gliderlabs/ssh v0.3.7 github.com/go-git/go-billy/v5 v5.5.0 @@ -31,7 +31,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/mattn/go-isatty v0.0.20 - github.com/moby/buildkit v0.13.1 + github.com/moby/buildkit v0.16.0 github.com/otiai10/copy v1.14.0 github.com/prometheus/procfs v0.15.1 github.com/sirupsen/logrus v1.9.3 @@ -100,14 +100,12 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/charmbracelet/lipgloss v0.8.0 // indirect github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect - github.com/cilium/ebpf v0.12.3 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 // indirect github.com/coder/quartz v0.1.0 // indirect github.com/coder/terraform-provider-coder v0.23.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect - github.com/containerd/cgroups/v3 v3.0.2 // indirect - github.com/containerd/containerd v1.7.19 // indirect + github.com/containerd/containerd v1.7.21 // indirect github.com/containerd/containerd/api v1.7.19 // indirect github.com/containerd/continuity v0.4.3 // indirect github.com/containerd/errdefs v0.1.0 // indirect @@ -115,10 +113,9 @@ require ( github.com/containerd/log v0.1.0 // indirect github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect github.com/containerd/ttrpc v1.2.5 // indirect - github.com/containerd/typeurl/v2 v2.1.1 // indirect + github.com/containerd/typeurl/v2 v2.2.0 // indirect github.com/coreos/go-iptables v0.6.0 // indirect github.com/coreos/go-oidc/v3 v3.10.0 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect @@ -151,7 +148,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/nftables v0.2.0 // indirect - github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect + github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect @@ -164,7 +161,7 @@ require ( github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl/v2 v2.21.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-plugin-go v0.12.0 // indirect @@ -202,11 +199,12 @@ require ( github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/swarmkit/v2 v2.0.0-20230315203717-e28e8ba9bc83 // indirect github.com/moby/sys/mount v0.3.3 // indirect - github.com/moby/sys/mountinfo v0.7.1 // indirect + github.com/moby/sys/mountinfo v0.7.2 // indirect github.com/moby/sys/sequential v0.5.0 // indirect - github.com/moby/sys/signal v0.7.0 // indirect + github.com/moby/sys/signal v0.7.1 // indirect github.com/moby/sys/symlink v0.2.0 // indirect - github.com/moby/sys/user v0.1.0 // indirect + github.com/moby/sys/user v0.3.0 // indirect + github.com/moby/sys/userns v0.1.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/muesli/reflow v0.3.0 // indirect @@ -245,6 +243,7 @@ require ( github.com/tailscale/wireguard-go v0.0.0-20231121184858-cc193a0b3272 // indirect github.com/tcnksm/go-httpstat v0.2.0 // indirect github.com/tinylib/msgp v1.1.8 // indirect + github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4 // indirect github.com/twpayne/go-vfs/v5 v5.0.4 // indirect github.com/u-root/uio v0.0.0-20240209044354-b3d14b93376a // indirect github.com/valyala/fasthttp v1.55.0 // indirect diff --git a/go.sum b/go.sum index 07dc01db..29fba2ef 100644 --- a/go.sum +++ b/go.sum @@ -171,8 +171,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/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/kaniko v0.0.0-20240925122543-caa18967f374 h1:/cyXf0vTSwFh7evQqeWHXXl14aRfC4CsNIYxOenJytQ= -github.com/coder/kaniko v0.0.0-20240925122543-caa18967f374/go.mod h1:XoTDIhNF0Ll4tLmRYdOn31udU9w5zFrY2PME/crSRCA= +github.com/coder/kaniko v0.0.0-20241120132148-131d6094d781 h1:/4SMdrjLQL1BseLSnMd9nYQSI+E63CXcyFGC7ZHHj8I= +github.com/coder/kaniko v0.0.0-20241120132148-131d6094d781/go.mod h1:3rM/KOQ4LgF8mE+O1P6pLDa/E57mzxIxNdUOMKi1qpg= github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs= github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0/go.mod h1:5UuS2Ts+nTToAMeOjNlnHFkPahrtDkmpydBen/3wgZc= github.com/coder/quartz v0.1.0 h1:cLL+0g5l7xTf6ordRnUMMiZtRE8Sq5LxpghS63vEXrQ= @@ -187,10 +187,8 @@ github.com/coder/terraform-provider-coder v0.23.0 h1:DuNLWxhnGlXyG0g+OCAZRI6xd8+ github.com/coder/terraform-provider-coder v0.23.0/go.mod h1:wMun9UZ9HT2CzF6qPPBup1odzBpVUc0/xSFoXgdI3tk= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= -github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0= -github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE= -github.com/containerd/containerd v1.7.19 h1:/xQ4XRJ0tamDkdzrrBAUy/LE5nCcxFKdBm4EcPrSMEE= -github.com/containerd/containerd v1.7.19/go.mod h1:h4FtNYUUMB4Phr6v+xG89RYKj9XccvbNSCKjdufCrkc= +github.com/containerd/containerd v1.7.21 h1:USGXRK1eOC/SX0L195YgxTHb0a00anxajOzgfN0qrCA= +github.com/containerd/containerd v1.7.21/go.mod h1:e3Jz1rYRUZ2Lt51YrH9Rz0zPyJBOlSvB3ghr2jbVD8g= github.com/containerd/containerd/api v1.7.19 h1:VWbJL+8Ap4Ju2mx9c9qS1uFSB1OVYr5JJrW2yT5vFoA= github.com/containerd/containerd/api v1.7.19/go.mod h1:fwGavl3LNwAV5ilJ0sbrABL44AQxmNjDRcwheXDb6Ig= github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= @@ -207,15 +205,13 @@ github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= github.com/containerd/ttrpc v1.2.5 h1:IFckT1EFQoFBMG4c3sMdT8EP3/aKfumK1msY+Ze4oLU= github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= -github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4= -github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0= +github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= +github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk= github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-oidc/v3 v3.10.0 h1:tDnXHnLyiTVyT/2zLDGj09pFPkhND8Gl8lnTRhoEaJU= github.com/coreos/go-oidc/v3 v3.10.0/go.mod h1:5j11xcw0D3+SGxn6Z/WFADsgcWVMyNAlSQupk0KK3ac= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= @@ -236,12 +232,12 @@ github.com/distribution/distribution/v3 v3.0.0-alpha.1 h1:jn7I1gvjOvmLztH1+1cLiU github.com/distribution/distribution/v3 v3.0.0-alpha.1/go.mod h1:LCp4JZp1ZalYg0W/TN05jarCQu+h4w7xc7ZfQF4Y/cY= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v27.2.0+incompatible h1:yHD1QEB1/0vr5eBNpu8tncu8gWxg8EydFPOSKHzXSMM= -github.com/docker/cli v27.2.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v27.2.1+incompatible h1:U5BPtiD0viUzjGAjV1p0MGB8eVA3L3cbIrnyWmSJI70= +github.com/docker/cli v27.2.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v26.1.5+incompatible h1:NEAxTwEjxV6VbBMBoGG3zPqbiJosIApZjxlbrG9q3/g= -github.com/docker/docker v26.1.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= +github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= @@ -394,8 +390,8 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/nftables v0.2.0 h1:PbJwaBmbVLzpeldoeUKGkE2RjstrjPKMl6oLrfEJ6/8= github.com/google/nftables v0.2.0/go.mod h1:Beg6V6zZ3oEn0JuiUQ4wqwuyqqzasOltcoXPtgLbFp4= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= -github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -439,8 +435,8 @@ github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iP github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw= github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU= -github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4= -github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hc-install v0.7.0 h1:Uu9edVqjKQxxuD28mR5TikkKDd/p55S8vzPC1659aBk= github.com/hashicorp/hc-install v0.7.0/go.mod h1:ELmmzZlGnEcqoUMKUuykHaPCIR1sYLYX+KSggWSKZuA= github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14= @@ -556,8 +552,8 @@ github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c h1:cqn374 github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/buildkit v0.13.1 h1:L8afOFhPq2RPJJSr/VyzbufwID7jquZVB7oFHbPRcPE= -github.com/moby/buildkit v0.13.1/go.mod h1:aNmNQKLBFYAOFuzQjR3VA27/FijlvtBD1pjNwTSN37k= +github.com/moby/buildkit v0.16.0 h1:wOVBj1o5YNVad/txPQNXUXdelm7Hs/i0PUFjzbK0VKE= +github.com/moby/buildkit v0.16.0/go.mod h1:Xqx/5GlrqE1yIRORk0NSCVDFpQAU1WjlT6KHYZdisIQ= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= @@ -569,16 +565,18 @@ github.com/moby/swarmkit/v2 v2.0.0-20230315203717-e28e8ba9bc83/go.mod h1:GvjR7mC github.com/moby/sys/mount v0.3.3 h1:fX1SVkXFJ47XWDoeFW4Sq7PdQJnV2QIDZAqjNqgEjUs= github.com/moby/sys/mount v0.3.3/go.mod h1:PBaEorSNTLG5t/+4EgukEQVlAvVEc6ZjTySwKdqp5K0= github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= -github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g= -github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= +github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= +github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= -github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI= -github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= +github.com/moby/sys/signal v0.7.1 h1:PrQxdvxcGijdo6UXXo/lU/TvHUWyPhj7UOpSo8tuvk0= +github.com/moby/sys/signal v0.7.1/go.mod h1:Se1VGehYokAkrSQwL4tDzHvETwUZlnY7S5XtQ50mQp8= github.com/moby/sys/symlink v0.2.0 h1:tk1rOM+Ljp0nFmfOIBtlV3rTDlWOwFRhjEeAhZB0nZc= github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= -github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg= -github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU= +github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= +github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= +github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= +github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -729,6 +727,8 @@ github.com/tcnksm/go-httpstat v0.2.0 h1:rP7T5e5U2HfmOBmZzGgGZjBQ5/GluWUylujl0tJ0 github.com/tcnksm/go-httpstat v0.2.0/go.mod h1:s3JVJFtQxtBEBC9dwcdTTXS9xFnM3SXAZwPG41aurT8= github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0= github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= +github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4 h1:7I5c2Ig/5FgqkYOh/N87NzoyI9U15qUPXhDD8uCupv8= +github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4/go.mod h1:278M4p8WsNh3n4a1eqiFcV2FGk7wE5fwUpUom9mK9lE= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/twpayne/go-vfs/v5 v5.0.4 h1:/ne3h+rW7f5YOyOFguz+3ztfUwzOLR0Vts3y0mMAitg= diff --git a/integration/integration_test.go b/integration/integration_test.go index d10fac1c..cb39988d 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -58,9 +58,10 @@ import ( ) const ( - testContainerLabel = "envbox-integration-test" - testImageAlpine = "localhost:5000/envbuilder-test-alpine:latest" - testImageUbuntu = "localhost:5000/envbuilder-test-ubuntu:latest" + testContainerLabel = "envbox-integration-test" + testImageAlpine = "localhost:5000/envbuilder-test-alpine:latest" + testImageUbuntu = "localhost:5000/envbuilder-test-ubuntu:latest" + testImageBlobUnknown = "localhost:5000/envbuilder-test-blob-unknown:latest" // nolint:gosec // Throw-away key for testing. DO NOT REUSE. testSSHKey = `-----BEGIN OPENSSH PRIVATE KEY----- @@ -2287,6 +2288,38 @@ USER devalot } require.Fail(t, "expected pid 1 to be running as devalot") }) + + t.Run("PushDuplicateLayersNoBlobUnknown", func(t *testing.T) { + t.Parallel() + + srv := gittest.CreateGitServer(t, gittest.Options{ + Files: map[string]string{ + ".devcontainer/Dockerfile": fmt.Sprintf(`FROM %s +USER root +RUN echo "hi i r empty" +RUN echo "who u" +`, testImageBlobUnknown), + ".devcontainer/devcontainer.json": `{ + "name": "Test", + "build": { + "dockerfile": "Dockerfile" + }, + }`, + }, + }) + + // NOTE(mafredri): The in-memory registry doesn't catch this error so we + // have to use registry:2. + ref, err := name.ParseReference(fmt.Sprintf("localhost:5000/test-blob-unknown-%s", uuid.NewString())) + require.NoError(t, err) + opts := []string{ + envbuilderEnv("GIT_URL", srv.URL), + envbuilderEnv("CACHE_REPO", ref.String()), + envbuilderEnv("VERBOSE", "1"), + } + + _ = pushImage(t, ref, nil, opts...) + }) } func TestChownHomedir(t *testing.T) { @@ -2465,6 +2498,8 @@ func getCachedImage(ctx context.Context, t *testing.T, cli *client.Client, env . } func startContainerFromRef(ctx context.Context, t *testing.T, cli *client.Client, ref name.Reference) container.CreateResponse { + t.Helper() + // Ensure that we can pull the image. rc, err := cli.ImagePull(ctx, ref.String(), image.PullOptions{}) require.NoError(t, err) diff --git a/integration/testdata/blob-unknown/Dockerfile b/integration/testdata/blob-unknown/Dockerfile new file mode 100644 index 00000000..fffcc574 --- /dev/null +++ b/integration/testdata/blob-unknown/Dockerfile @@ -0,0 +1,7 @@ +FROM alpine:latest + +# This will produce an empty layer via Docker. It will allow us to test for a +# conflicting empty layer produced by Kaniko. This is to check against the +# BLOB_UNKNOWN error when trying to upload the built image to a registry and +# Kaniko having overwritten this blob with its own. +WORKDIR /home From 0b4600f7f4c308cdc6379ea7e9f7efd07dc37f13 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 2 Dec 2024 11:30:49 +0000 Subject: [PATCH 5/7] chore: bump github.com/golang-jwt/jwt/v4 from 4.5.0 to 4.5.1 (#405) (#426) (cherry picked from commit b1dc272) Co-authored-by: Mathias Fredriksson Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- envbuilder.go | 1 + go.mod | 2 +- go.sum | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/envbuilder.go b/envbuilder.go index 6f3231d1..f19f5e4b 100644 --- a/envbuilder.go +++ b/envbuilder.go @@ -581,6 +581,7 @@ func run(ctx context.Context, opts options.Options, execArgs *execArgsInfo) erro endStage("🏗️ Built image!") if opts.PushImage { endStage = startStage("🏗️ Pushing image...") + // To debug registry issues, enable logging: // // import ( diff --git a/go.mod b/go.mod index c51f4227..09c0bab4 100644 --- a/go.mod +++ b/go.mod @@ -143,7 +143,7 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang-jwt/jwt/v4 v4.5.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.2 // indirect diff --git a/go.sum b/go.sum index 29fba2ef..429f4d8a 100644 --- a/go.sum +++ b/go.sum @@ -340,8 +340,9 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= +github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= From 15b5420c36e92f328dff676c4a2bf0746ea7bb32 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 2 Dec 2024 11:31:10 +0000 Subject: [PATCH 6/7] chore: improve logging around lifecycle scripts (#420) (#427) (cherry picked from commit fafad44) Co-authored-by: Mathias Fredriksson Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- envbuilder.go | 8 +++ integration/integration_test.go | 111 +++++++++++++++++++++++--------- 2 files changed, 89 insertions(+), 30 deletions(-) diff --git a/envbuilder.go b/envbuilder.go index f19f5e4b..ea7c4436 100644 --- a/envbuilder.go +++ b/envbuilder.go @@ -169,6 +169,7 @@ func run(ctx context.Context, opts options.Options, execArgs *execArgsInfo) erro RemoteEnv: make(map[string]string), } if fileExists(opts.Filesystem, workingDir.Image()) { + opts.Logger(log.LevelInfo, "Found magic image file at %s", workingDir.Image()) if err = parseMagicImageFile(opts.Filesystem, workingDir.Image(), &runtimeData); err != nil { return fmt.Errorf("parse magic image file: %w", err) } @@ -287,6 +288,7 @@ func run(ctx context.Context, opts options.Options, execArgs *execArgsInfo) erro var buildParams *devcontainer.Compiled if opts.DockerfilePath == "" { + opts.Logger(log.LevelInfo, "No Dockerfile specified, looking for a devcontainer.json...") // Only look for a devcontainer if a Dockerfile wasn't specified. // devcontainer is a standard, so it's reasonable to be the default. var devcontainerDir string @@ -296,6 +298,7 @@ func run(ctx context.Context, opts options.Options, execArgs *execArgsInfo) erro opts.Logger(log.LevelError, "Failed to locate devcontainer.json: %s", err.Error()) opts.Logger(log.LevelError, "Falling back to the default image...") } else { + opts.Logger(log.LevelInfo, "Building in Devcontainer mode using %s", strings.TrimPrefix(runtimeData.DevcontainerPath, buildTimeWorkspaceFolder)) // We know a devcontainer exists. // Let's parse it and use it! file, err := opts.Filesystem.Open(runtimeData.DevcontainerPath) @@ -334,6 +337,7 @@ func run(ctx context.Context, opts options.Options, execArgs *execArgsInfo) erro } else { // If a Dockerfile was specified, we use that. dockerfilePath := filepath.Join(buildTimeWorkspaceFolder, opts.DockerfilePath) + opts.Logger(log.LevelInfo, "Building in Dockerfile-only mode using %s", opts.DockerfilePath) // If the dockerfilePath is specified and deeper than the base of WorkspaceFolder AND the BuildContextPath is // not defined, show a warning @@ -1402,6 +1406,7 @@ func execOneLifecycleScript( userInfo userInfo, ) error { if s.IsEmpty() { + logf(log.LevelInfo, "=== No %s script specified", scriptName) return nil } logf(log.LevelInfo, "=== Running %s as the %q user...", scriptName, userInfo.user.Username) @@ -1420,6 +1425,7 @@ func execLifecycleScripts( userInfo userInfo, ) error { if options.PostStartScriptPath != "" { + options.Logger(log.LevelDebug, "Removing postStartScriptPath %s", options.PostStartScriptPath) _ = os.Remove(options.PostStartScriptPath) } @@ -1428,6 +1434,8 @@ func execLifecycleScripts( // skip remaining lifecycle commands return nil } + } else { + options.Logger(log.LevelDebug, "Skipping onCreateCommand for subsequent starts...") } if err := execOneLifecycleScript(ctx, options.Logger, scripts.UpdateContentCommand, "updateContentCommand", userInfo); err != nil { // skip remaining lifecycle commands diff --git a/integration/integration_test.go b/integration/integration_test.go index cb39988d..e7fbc959 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -1125,37 +1125,88 @@ func TestUnsetOptionsEnv(t *testing.T) { func TestLifecycleScripts(t *testing.T) { t.Parallel() - // Ensures that a Git repository with a devcontainer.json is cloned and built. - srv := gittest.CreateGitServer(t, gittest.Options{ - Files: map[string]string{ - ".devcontainer/devcontainer.json": `{ - "name": "Test", - "build": { - "dockerfile": "Dockerfile" - }, - "onCreateCommand": "echo create > /tmp/out", - "updateContentCommand": ["sh", "-c", "echo update >> /tmp/out"], - "postCreateCommand": "(echo -n postCreate. ; id -un) >> /tmp/out", - "postStartCommand": { - "parallel1": "echo parallel1 > /tmp/parallel1", - "parallel2": ["sh", "-c", "echo parallel2 > /tmp/parallel2"] - } - }`, - ".devcontainer/Dockerfile": "FROM " + testImageAlpine + "\nUSER nobody", + for _, tt := range []struct { + name string + files map[string]string + outputCmd string + expectOutput string + }{ + { + name: "build", + files: map[string]string{ + ".devcontainer/devcontainer.json": `{ + "name": "Test", + "build": { + "dockerfile": "Dockerfile" + }, + "onCreateCommand": "echo create > /tmp/out", + "updateContentCommand": ["sh", "-c", "echo update >> /tmp/out"], + "postCreateCommand": "(echo -n postCreate. ; id -un) >> /tmp/out", + "postStartCommand": { + "parallel1": "echo parallel1 > /tmp/parallel1", + "parallel2": ["sh", "-c", "echo parallel2 > /tmp/parallel2"] + } + }`, + ".devcontainer/Dockerfile": "FROM " + testImageAlpine + "\nUSER nobody", + }, + outputCmd: "cat /tmp/out /tmp/parallel1 /tmp/parallel2", + expectOutput: "create\nupdate\npostCreate.nobody\nparallel1\nparallel2", }, - }) - ctr, err := runEnvbuilder(t, runOpts{env: []string{ - envbuilderEnv("GIT_URL", srv.URL), - }}) - require.NoError(t, err) - - output := execContainer(t, ctr, "cat /tmp/out /tmp/parallel1 /tmp/parallel2") - require.Equal(t, - `create -update -postCreate.nobody -parallel1 -parallel2`, strings.TrimSpace(output)) + { + name: "image", + files: map[string]string{ + ".devcontainer/devcontainer.json": fmt.Sprintf(`{ + "name": "Test", + "image": %q, + "containerUser": "nobody", + "onCreateCommand": "echo create > /tmp/out", + "updateContentCommand": ["sh", "-c", "echo update >> /tmp/out"], + "postCreateCommand": "(echo -n postCreate. ; id -un) >> /tmp/out", + "postStartCommand": { + "parallel1": "echo parallel1 > /tmp/parallel1", + "parallel2": ["sh", "-c", "echo parallel2 > /tmp/parallel2"] + } + }`, testImageAlpine), + }, + outputCmd: "cat /tmp/out /tmp/parallel1 /tmp/parallel2", + expectOutput: "create\nupdate\npostCreate.nobody\nparallel1\nparallel2", + }, + { + name: "label", + files: map[string]string{ + ".devcontainer/Dockerfile": fmt.Sprintf(`FROM %s + LABEL devcontainer.metadata='[{ \ + "onCreateCommand": "echo create > /tmp/out", \ + "updateContentCommand": ["sh", "-c", "echo update >> /tmp/out"], \ + "postCreateCommand": "(echo -n postCreate. ; id -un) >> /tmp/out", \ + "postStartCommand": { \ + "parallel1": "echo parallel1 > /tmp/parallel1", \ + "parallel2": ["sh", "-c", "echo parallel2 > /tmp/parallel2"] \ + } \ + }]' + USER nobody`, testImageAlpine), + }, + outputCmd: "cat /tmp/out /tmp/parallel1 /tmp/parallel2", + expectOutput: "create\nupdate\npostCreate.nobody\nparallel1\nparallel2", + }, + } { + tt := tt + t.Run(tt.name, func(t *testing.T) { + srv := gittest.CreateGitServer(t, gittest.Options{ + Files: tt.files, + }) + env := []string{ + envbuilderEnv("GIT_URL", srv.URL), + } + if _, ok := tt.files[".devcontainer/devcontainer.json"]; !ok { + env = append(env, envbuilderEnv("DOCKERFILE_PATH", ".devcontainer/Dockerfile")) + } + ctr, err := runEnvbuilder(t, runOpts{env: env}) + require.NoError(t, err, "failed to run envbuilder") + output := execContainer(t, ctr, tt.outputCmd) + require.Equal(t, tt.expectOutput, strings.TrimSpace(output)) + }) + } } func TestPostStartScript(t *testing.T) { From a96ba9294b75828161a7718cfa408849950763e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:43:52 +0000 Subject: [PATCH 7/7] chore: bump golang.org/x/crypto from 0.26.0 to 0.29.0 (#417) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Cian Johnston (cherry picked from commit a3a6a837d369d2735445ab7c7c7d5f3193f4b44f) --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 09c0bab4..1283d599 100644 --- a/go.mod +++ b/go.mod @@ -39,9 +39,9 @@ require ( github.com/stretchr/testify v1.9.0 github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a go.uber.org/mock v0.4.0 - golang.org/x/crypto v0.26.0 + golang.org/x/crypto v0.29.0 golang.org/x/mod v0.21.0 - golang.org/x/sync v0.8.0 + golang.org/x/sync v0.9.0 golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 ) @@ -274,9 +274,9 @@ require ( golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/term v0.26.0 // indirect + golang.org/x/text v0.20.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.22.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect diff --git a/go.sum b/go.sum index 429f4d8a..96fa5e7c 100644 --- a/go.sum +++ b/go.sum @@ -836,8 +836,8 @@ golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= @@ -885,8 +885,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -925,15 +925,15 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.1-0.20230131160137-e7d7f63158de/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= +golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -943,8 +943,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=