From 17da2be6cadc606316a1201651cb1a31848ee908 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Tue, 1 Apr 2025 16:00:08 -0400 Subject: [PATCH 01/11] chore: update runners to Ubuntu 22.04 (#135) - Support for 20.04 ends on 04/15/25. --- .github/workflows/ci.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c106dd0..b292e89 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -127,7 +127,7 @@ jobs: run: go test ./... integration-tests: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 timeout-minutes: 20 steps: - name: Install dependencies @@ -165,7 +165,7 @@ jobs: run: go test -tags=integration ./... build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 @@ -245,7 +245,7 @@ jobs: uses: github/codeql-action/analyze@v2 publish: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 if: github.ref == 'refs/heads/main' steps: - name: Docker Login From fde2c322ae31b6584e590cdcc190b2770793d3c7 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Tue, 1 Apr 2025 16:06:49 -0400 Subject: [PATCH 02/11] feat: pass through signals to inner container (#134) --- cli/docker.go | 199 ++++++++++++++++++-------- cmd/envbox/main.go | 1 - dockerutil/container.go | 1 + dockerutil/dockerfake/client.go | 4 +- dockerutil/exec.go | 43 +++++- integration/docker_test.go | 69 ++++++++- integration/integrationtest/docker.go | 25 ++++ 7 files changed, 277 insertions(+), 65 deletions(-) diff --git a/cli/docker.go b/cli/docker.go index 9ac872c..1573612 100644 --- a/cli/docker.go +++ b/cli/docker.go @@ -7,11 +7,15 @@ import ( "io" "net/url" "os" + "os/exec" + "os/signal" "path" "path/filepath" "sort" "strconv" "strings" + "syscall" + "time" "github.com/docker/docker/api/types/container" "github.com/google/go-containerregistry/pkg/name" @@ -157,11 +161,24 @@ func dockerCmd() *cobra.Command { Short: "Create a docker-based CVM", RunE: func(cmd *cobra.Command, args []string) (err error) { var ( - ctx = cmd.Context() - log = slog.Make(slogjson.Sink(cmd.ErrOrStderr()), slogkubeterminate.Make()).Leveled(slog.LevelDebug) - blog buildlog.Logger = buildlog.JSONLogger{Encoder: json.NewEncoder(os.Stderr)} + ctx, cancel = context.WithCancel(cmd.Context()) //nolint + log = slog.Make(slogjson.Sink(cmd.ErrOrStderr()), slogkubeterminate.Make()).Leveled(slog.LevelDebug) + blog buildlog.Logger = buildlog.JSONLogger{Encoder: json.NewEncoder(os.Stderr)} ) + // We technically leak a context here, but it's impact is negligible. + signalCtx, signalCancel := context.WithCancel(ctx) + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGTERM, syscall.SIGINT, syscall.SIGWINCH) + + // Spawn a goroutine to wait for a signal. + go func() { + defer signalCancel() + log.Info(ctx, "waiting for signal") + <-sigs + log.Info(ctx, "got signal, canceling context") + }() + if flags.noStartupLogs { log = slog.Make(slogjson.Sink(io.Discard)) blog = buildlog.NopLogger{} @@ -169,6 +186,7 @@ func dockerCmd() *cobra.Command { httpClient, err := xhttp.Client(log, flags.extraCertsPath) if err != nil { + //nolint return xerrors.Errorf("http client: %w", err) } @@ -208,13 +226,19 @@ func dockerCmd() *cobra.Command { // Start sysbox-mgr and sysbox-fs in order to run // sysbox containers. case err := <-background.New(ctx, log, "sysbox-mgr", sysboxArgs...).Run(): - blog.Info(sysboxErrMsg) - //nolint - log.Fatal(ctx, "sysbox-mgr exited", slog.Error(err)) + if ctx.Err() == nil { + blog.Info(sysboxErrMsg) + //nolint + log.Critical(ctx, "sysbox-mgr exited", slog.Error(err)) + panic(err) + } case err := <-background.New(ctx, log, "sysbox-fs").Run(): - blog.Info(sysboxErrMsg) - //nolint - log.Fatal(ctx, "sysbox-fs exited", slog.Error(err)) + if ctx.Err() == nil { + blog.Info(sysboxErrMsg) + //nolint + log.Critical(ctx, "sysbox-fs exited", slog.Error(err)) + panic(err) + } } }() @@ -316,7 +340,7 @@ func dockerCmd() *cobra.Command { ) } - err = runDockerCVM(ctx, log, client, blog, flags) + bootstrapExecID, err := runDockerCVM(ctx, log, client, blog, flags) if err != nil { // It's possible we failed because we ran out of disk while // pulling the image. We should restart the daemon and use @@ -345,7 +369,7 @@ func dockerCmd() *cobra.Command { }() log.Debug(ctx, "reattempting container creation") - err = runDockerCVM(ctx, log, client, blog, flags) + bootstrapExecID, err = runDockerCVM(ctx, log, client, blog, flags) } if err != nil { blog.Errorf("Failed to run envbox: %v", err) @@ -353,6 +377,44 @@ func dockerCmd() *cobra.Command { } } + go func() { + defer cancel() + + <-signalCtx.Done() + log.Debug(ctx, "ctx canceled, forwarding signal to inner container") + + if bootstrapExecID == "" { + log.Debug(ctx, "no bootstrap exec id, skipping") + return + } + + shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), time.Second*90) + defer shutdownCancel() + + bootstrapPID, err := dockerutil.GetExecPID(shutdownCtx, client, bootstrapExecID) + if err != nil { + log.Error(shutdownCtx, "get exec pid", slog.Error(err)) + } + + log.Debug(shutdownCtx, "killing container", slog.F("bootstrap_pid", bootstrapPID)) + + // The PID returned is the PID _outside_ the container... + out, err := exec.CommandContext(shutdownCtx, "kill", "-TERM", strconv.Itoa(bootstrapPID)).CombinedOutput() //nolint:gosec + if err != nil { + log.Error(shutdownCtx, "kill bootstrap process", slog.Error(err), slog.F("output", string(out))) + return + } + + log.Debug(shutdownCtx, "sent kill signal waiting for process to exit") + err = dockerutil.WaitForExit(shutdownCtx, client, bootstrapExecID) + if err != nil { + log.Error(shutdownCtx, "wait for exit", slog.Error(err)) + return + } + + log.Debug(shutdownCtx, "bootstrap process successfully exited") + }() + return nil }, } @@ -390,25 +452,22 @@ func dockerCmd() *cobra.Command { return cmd } -func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client, blog buildlog.Logger, flags flags) error { +func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client, blog buildlog.Logger, flags flags) (string, error) { fs := xunix.GetFS(ctx) - - // Set our OOM score to something really unfavorable to avoid getting killed - // in memory-scarce scenarios. err := xunix.SetOOMScore(ctx, "self", "-1000") if err != nil { - return xerrors.Errorf("set oom score: %w", err) + return "", xerrors.Errorf("set oom score: %w", err) } ref, err := name.ParseReference(flags.innerImage) if err != nil { - return xerrors.Errorf("parse ref: %w", err) + return "", xerrors.Errorf("parse ref: %w", err) } var dockerAuth dockerutil.AuthConfig if flags.imagePullSecret != "" { dockerAuth, err = dockerutil.AuthConfigFromString(flags.imagePullSecret, ref.Context().RegistryStr()) if err != nil { - return xerrors.Errorf("parse auth config: %w", err) + return "", xerrors.Errorf("parse auth config: %w", err) } } @@ -417,7 +476,7 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client log.Info(ctx, "detected file", slog.F("image", flags.innerImage)) dockerAuth, err = dockerutil.AuthConfigFromPath(flags.dockerConfig, ref.Context().RegistryStr()) if err != nil && !xerrors.Is(err, os.ErrNotExist) { - return xerrors.Errorf("auth config from file: %w", err) + return "", xerrors.Errorf("auth config from file: %w", err) } } @@ -430,7 +489,7 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client // Add any user-specified mounts to our mounts list. extraMounts, err := parseMounts(flags.containerMounts) if err != nil { - return xerrors.Errorf("read mounts: %w", err) + return "", xerrors.Errorf("read mounts: %w", err) } mounts = append(mounts, extraMounts...) @@ -442,7 +501,7 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client blog.Info("Creating TUN device") dev, err := xunix.CreateTUNDevice(ctx, OuterTUNPath) if err != nil { - return xerrors.Errorf("creat tun device: %w", err) + return "", xerrors.Errorf("creat tun device: %w", err) } devices = append(devices, container.DeviceMapping{ @@ -457,7 +516,7 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client blog.Info("Creating FUSE device") dev, err := xunix.CreateFuseDevice(ctx, OuterFUSEPath) if err != nil { - return xerrors.Errorf("create fuse device: %w", err) + return "", xerrors.Errorf("create fuse device: %w", err) } devices = append(devices, container.DeviceMapping{ @@ -479,7 +538,7 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client ) err = fs.Chown(device.PathOnHost, UserNamespaceOffset, UserNamespaceOffset) if err != nil { - return xerrors.Errorf("chown device %q: %w", device.PathOnHost, err) + return "", xerrors.Errorf("chown device %q: %w", device.PathOnHost, err) } } @@ -492,7 +551,7 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client ProgressFn: dockerutil.DefaultLogImagePullFn(blog), }) if err != nil { - return xerrors.Errorf("pull image: %w", err) + return "", xerrors.Errorf("pull image: %w", err) } log.Debug(ctx, "remounting /sys") @@ -500,19 +559,19 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client // After image pull we remount /sys so sysbox can have appropriate perms to create a container. err = xunix.MountFS(ctx, "/sys", "/sys", "", "remount", "rw") if err != nil { - return xerrors.Errorf("remount /sys: %w", err) + return "", xerrors.Errorf("remount /sys: %w", err) } if flags.addGPU { if flags.hostUsrLibDir == "" { - return xerrors.Errorf("when using GPUs, %q must be specified", EnvUsrLibDir) + return "", xerrors.Errorf("when using GPUs, %q must be specified", EnvUsrLibDir) } // Unmount GPU drivers in /proc as it causes issues when creating any // container in some cases (even the image metadata container). _, err = xunix.TryUnmountProcGPUDrivers(ctx, log) if err != nil { - return xerrors.Errorf("unmount /proc GPU drivers: %w", err) + return "", xerrors.Errorf("unmount /proc GPU drivers: %w", err) } } @@ -528,7 +587,7 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client // with /sbin/init or something simple like 'sleep infinity'. imgMeta, err := dockerutil.GetImageMetadata(ctx, log, client, flags.innerImage, flags.innerUsername) if err != nil { - return xerrors.Errorf("get image metadata: %w", err) + return "", xerrors.Errorf("get image metadata: %w", err) } blog.Infof("Detected entrypoint user '%s:%s' with home directory %q", imgMeta.UID, imgMeta.UID, imgMeta.HomeDir) @@ -543,11 +602,11 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client uid, err := strconv.ParseInt(imgMeta.UID, 10, 32) if err != nil { - return xerrors.Errorf("parse image uid: %w", err) + return "", xerrors.Errorf("parse image uid: %w", err) } gid, err := strconv.ParseInt(imgMeta.GID, 10, 32) if err != nil { - return xerrors.Errorf("parse image gid: %w", err) + return "", xerrors.Errorf("parse image gid: %w", err) } for _, m := range mounts { @@ -568,13 +627,13 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client mounter := xunix.Mounter(ctx) err := mounter.Mount("", m.Source, "", []string{"remount,rw"}) if err != nil { - return xerrors.Errorf("remount: %w", err) + return "", xerrors.Errorf("remount: %w", err) } } err := fs.Chmod(m.Source, 0o2755) if err != nil { - return xerrors.Errorf("chmod mountpoint %q: %w", m.Source, err) + return "", xerrors.Errorf("chmod mountpoint %q: %w", m.Source, err) } var ( @@ -601,14 +660,14 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client // user. err = fs.Chown(m.Source, shiftedUID, shiftedGID) if err != nil { - return xerrors.Errorf("chown mountpoint %q: %w", m.Source, err) + return "", xerrors.Errorf("chown mountpoint %q: %w", m.Source, err) } } if flags.addGPU { devs, binds, err := xunix.GPUs(ctx, log, flags.hostUsrLibDir) if err != nil { - return xerrors.Errorf("find gpus: %w", err) + return "", xerrors.Errorf("find gpus: %w", err) } for _, dev := range devs { @@ -679,14 +738,14 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client MemoryLimit: int64(flags.memory), }) if err != nil { - return xerrors.Errorf("create container: %w", err) + return "", xerrors.Errorf("create container: %w", err) } blog.Info("Pruning images to free up disk...") // Prune images to avoid taking up any unnecessary disk from the user. _, err = dockerutil.PruneImages(ctx, client) if err != nil { - return xerrors.Errorf("prune images: %w", err) + return "", xerrors.Errorf("prune images: %w", err) } // TODO fix iptables when istio detected. @@ -694,7 +753,7 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client blog.Info("Starting up workspace...") err = client.ContainerStart(ctx, containerID, container.StartOptions{}) if err != nil { - return xerrors.Errorf("start container: %w", err) + return "", xerrors.Errorf("start container: %w", err) } log.Debug(ctx, "creating bootstrap directory", slog.F("directory", imgMeta.HomeDir)) @@ -714,7 +773,7 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client Args: []string{"-p", bootDir}, }) if err != nil { - return xerrors.Errorf("make bootstrap dir: %w", err) + return "", xerrors.Errorf("make bootstrap dir: %w", err) } cpuQuota, err := xunix.ReadCPUQuota(ctx, log) @@ -736,34 +795,54 @@ func runDockerCVM(ctx context.Context, log slog.Logger, client dockerutil.Client } blog.Info("Envbox startup complete!") - - // The bootstrap script doesn't return since it execs the agent - // meaning that it can get pretty noisy if we were to log by default. - // In order to allow users to discern issues getting the bootstrap script - // to complete successfully we pipe the output to stdout if - // CODER_DEBUG=true. - debugWriter := io.Discard - if flags.debug { - debugWriter = os.Stdout + if flags.boostrapScript == "" { + return "", nil } - // Bootstrap the container if a script has been provided. blog.Infof("Bootstrapping workspace...") - err = dockerutil.BootstrapContainer(ctx, client, dockerutil.BootstrapConfig{ - ContainerID: containerID, - User: imgMeta.UID, - Script: flags.boostrapScript, - // We set this because the default behavior is to download the agent - // to /tmp/coder.XXXX. This causes a race to happen where we finish - // downloading the binary but before we can execute systemd remounts - // /tmp. - Env: []string{fmt.Sprintf("BINARY_DIR=%s", bootDir)}, - StdOutErr: debugWriter, + + bootstrapExec, err := client.ContainerExecCreate(ctx, containerID, container.ExecOptions{ + User: imgMeta.UID, + Cmd: []string{"/bin/sh", "-s"}, + Env: []string{fmt.Sprintf("BINARY_DIR=%s", bootDir)}, + AttachStdin: true, + AttachStdout: true, + AttachStderr: true, + Detach: true, }) if err != nil { - return xerrors.Errorf("boostrap container: %w", err) + return "", xerrors.Errorf("create exec: %w", err) + } + + resp, err := client.ContainerExecAttach(ctx, bootstrapExec.ID, container.ExecStartOptions{}) + if err != nil { + return "", xerrors.Errorf("attach exec: %w", err) + } + + _, err = io.Copy(resp.Conn, strings.NewReader(flags.boostrapScript)) + if err != nil { + return "", xerrors.Errorf("copy stdin: %w", err) } + err = resp.CloseWrite() + if err != nil { + return "", xerrors.Errorf("close write: %w", err) + } + + go func() { + defer resp.Close() + go func() { + // Also close the response reader when the context is canceled. + defer resp.Close() + <-ctx.Done() + }() + rd := io.LimitReader(resp.Reader, 1<<10) + _, err := io.Copy(blog, rd) + if err != nil { + log.Error(ctx, "copy bootstrap output", slog.Error(err)) + } + log.Debug(ctx, "bootstrap output copied") + }() - return nil + return bootstrapExec.ID, nil } //nolint:revive diff --git a/cmd/envbox/main.go b/cmd/envbox/main.go index 2dfdb94..d7bb87e 100644 --- a/cmd/envbox/main.go +++ b/cmd/envbox/main.go @@ -14,7 +14,6 @@ func main() { _, _ = fmt.Fprintln(os.Stderr, err.Error()) os.Exit(1) } - // We exit the main thread while keepin all the other procs goin strong. runtime.Goexit() } diff --git a/dockerutil/container.go b/dockerutil/container.go index 2731cbc..ca27375 100644 --- a/dockerutil/container.go +++ b/dockerutil/container.go @@ -115,6 +115,7 @@ func BootstrapContainer(ctx context.Context, client Client, conf BootstrapConfig Stdin: strings.NewReader(conf.Script), Env: conf.Env, StdOutErr: conf.StdOutErr, + Detach: conf.Detach, }) if err != nil { err = xerrors.Errorf("boostrap container (%s): %w", out, err) diff --git a/dockerutil/dockerfake/client.go b/dockerutil/dockerfake/client.go index 7c7d012..8e348dc 100644 --- a/dockerutil/dockerfake/client.go +++ b/dockerutil/dockerfake/client.go @@ -163,7 +163,9 @@ func (m MockClient) ContainerExecCreate(ctx context.Context, name string, config func (m MockClient) ContainerExecInspect(ctx context.Context, id string) (dockertypes.ContainerExecInspect, error) { if m.ContainerExecInspectFn == nil { - return dockertypes.ContainerExecInspect{}, nil + return dockertypes.ContainerExecInspect{ + Pid: 123, + }, nil } return m.ContainerExecInspectFn(ctx, id) diff --git a/dockerutil/exec.go b/dockerutil/exec.go index 8f27f47..c3821c6 100644 --- a/dockerutil/exec.go +++ b/dockerutil/exec.go @@ -4,11 +4,14 @@ import ( "bytes" "context" "io" + "time" dockertypes "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "golang.org/x/xerrors" "github.com/coder/envbox/xio" + "github.com/coder/retry" ) type ExecConfig struct { @@ -25,8 +28,8 @@ type ExecConfig struct { // ExecContainer runs a command in a container. It returns the output and any error. // If an error occurs during the execution of the command, the output is appended to the error. func ExecContainer(ctx context.Context, client Client, config ExecConfig) ([]byte, error) { - exec, err := client.ContainerExecCreate(ctx, config.ContainerID, dockertypes.ExecConfig{ - Detach: true, + exec, err := client.ContainerExecCreate(ctx, config.ContainerID, container.ExecOptions{ + Detach: config.Detach, Cmd: append([]string{config.Cmd}, config.Args...), User: config.User, AttachStderr: true, @@ -92,3 +95,39 @@ func ExecContainer(ctx context.Context, client Client, config ExecConfig) ([]byt return buf.Bytes(), nil } + +func GetExecPID(ctx context.Context, client Client, execID string) (int, error) { + for r := retry.New(time.Second, time.Second); r.Wait(ctx); { + inspect, err := client.ContainerExecInspect(ctx, execID) + if err != nil { + return 0, xerrors.Errorf("exec inspect: %w", err) + } + + if inspect.Pid == 0 { + continue + } + return inspect.Pid, nil + } + + return 0, ctx.Err() +} + +func WaitForExit(ctx context.Context, client Client, execID string) error { + for r := retry.New(time.Second, time.Second); r.Wait(ctx); { + inspect, err := client.ContainerExecInspect(ctx, execID) + if err != nil { + return xerrors.Errorf("exec inspect: %w", err) + } + + if inspect.Running { + continue + } + + if inspect.ExitCode > 0 { + return xerrors.Errorf("exit code %d", inspect.ExitCode) + } + + return nil + } + return ctx.Err() +} diff --git a/integration/docker_test.go b/integration/docker_test.go index 533d2ba..c7c1a6d 100644 --- a/integration/docker_test.go +++ b/integration/docker_test.go @@ -390,7 +390,7 @@ func TestDocker(t *testing.T) { // This indicates we've made it all the way to end // of the logs we attempt to push. - require.True(t, recorder.ContainsLog("Bootstrapping workspace...")) + require.True(t, recorder.ContainsLog("Envbox startup complete!")) }) // This tests the inverse of SelfSignedCerts. We assert that @@ -534,6 +534,59 @@ func TestDocker(t *testing.T) { require.NoError(t, err) require.Equal(t, "hello\n", string(output)) }) + t.Run("HandleSignals", func(t *testing.T) { + t.Parallel() + + pool, err := dockertest.NewPool("") + require.NoError(t, err) + + var ( + tmpdir = integrationtest.TmpDir(t) + binds = integrationtest.DefaultBinds(t, tmpdir) + ) + homeDir := filepath.Join(tmpdir, "home") + err = os.MkdirAll(homeDir, 0o777) + require.NoError(t, err) + + binds = append(binds, integrationtest.BindMount(homeDir, "/home/coder", false)) + + envs := []string{fmt.Sprintf("%s=%s:%s", cli.EnvMounts, "/home/coder", "/home/coder")} + // Run the envbox container. + resource := integrationtest.RunEnvbox(t, pool, &integrationtest.CreateDockerCVMConfig{ + Image: integrationtest.UbuntuImage, + Username: "root", + OuterMounts: binds, + Envs: envs, + BootstrapScript: sigtrapScript, + }) + + _, err = integrationtest.ExecInnerContainer(t, pool, integrationtest.ExecConfig{ + ContainerID: resource.Container.ID, + Cmd: []string{"/bin/sh", "-c", "stat /home/coder/foo"}, + }) + require.Error(t, err) + + // Simulate a shutdown. + integrationtest.StopContainer(t, pool, resource.Container.ID, 30*time.Second) + + err = resource.Close() + require.NoError(t, err) + + t.Logf("envbox %q started successfully, recreating...", resource.Container.ID) + // Run the envbox container. + resource = integrationtest.RunEnvbox(t, pool, &integrationtest.CreateDockerCVMConfig{ + Image: integrationtest.UbuntuImage, + Username: "root", + OuterMounts: binds, + Envs: envs, + BootstrapScript: sigtrapScript, + }) + _, err = integrationtest.ExecInnerContainer(t, pool, integrationtest.ExecConfig{ + ContainerID: resource.Container.ID, + Cmd: []string{"/bin/sh", "-c", "stat /home/coder/foo"}, + }) + require.NoError(t, err) + }) } func requireSliceNoContains(t *testing.T, ss []string, els ...string) { @@ -566,3 +619,17 @@ func tcpAddr(t testing.TB, l net.Listener) *net.TCPAddr { require.True(t, ok) return tcpAddr } + +const sigtrapScript = `#!/bin/bash +cleanup() { + echo "HANDLING A SIGNAL!" && touch /home/coder/foo && echo "touched file" + exit 0 +} + +trap 'cleanup' INT TERM + +while true; do + echo "Working..." + sleep 1 +done +` diff --git a/integration/integrationtest/docker.go b/integration/integrationtest/docker.go index 5b42bbe..0f820be 100644 --- a/integration/integrationtest/docker.go +++ b/integration/integrationtest/docker.go @@ -306,6 +306,31 @@ func ExecEnvbox(t *testing.T, pool *dockertest.Pool, conf ExecConfig) ([]byte, e return buf.Bytes(), nil } +func StopContainer(t *testing.T, pool *dockertest.Pool, id string, to time.Duration) { + t.Helper() + + err := pool.Client.KillContainer(docker.KillContainerOptions{ + ID: id, + Signal: docker.SIGTERM, + }) + require.NoError(t, err) + + ctx, cancel := context.WithTimeout(context.Background(), to) + defer cancel() + for r := retry.New(time.Second, time.Second); r.Wait(ctx); { + cnt, err := pool.Client.InspectContainer(id) + require.NoError(t, err) + + if cnt.State.Running { + continue + } + + return + } + + t.Fatalf("timed out waiting for container %s to stop", id) +} + // cmdLineEnvs returns args passed to the /envbox command // but using their env var alias. func cmdLineEnvs(c *CreateDockerCVMConfig) []string { From 909d05a2541924dc0542c4015541c2a31b7e00f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 01:47:00 -0400 Subject: [PATCH 03/11] chore(deps): bump github.com/go-jose/go-jose/v4 from 4.0.2 to 4.0.5 (#125) Bumps [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) from 4.0.2 to 4.0.5. - [Release notes](https://github.com/go-jose/go-jose/releases) - [Changelog](https://github.com/go-jose/go-jose/blob/main/CHANGELOG.md) - [Commits](https://github.com/go-jose/go-jose/compare/v4.0.2...v4.0.5) --- updated-dependencies: - dependency-name: github.com/go-jose/go-jose/v4 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Ayers --- go.mod | 11 +++++------ go.sum | 22 ++++++++++------------ 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 6e8dffc..ab9efd6 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,6 @@ module github.com/coder/envbox go 1.23.3 - // There are a few minor changes we make to Tailscale that we're slowly upstreaming. Compare here: // https://github.com/tailscale/tailscale/compare/main...coder:tailscale:main replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa558fbe5374 @@ -22,12 +21,12 @@ require ( github.com/spf13/afero v1.11.0 github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/vishvananda/netlink v1.2.1-beta.2 - golang.org/x/crypto v0.31.0 + golang.org/x/crypto v0.32.0 golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 golang.org/x/mod v0.19.0 - golang.org/x/sys v0.28.0 + golang.org/x/sys v0.29.0 golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 k8s.io/mount-utils v0.26.2 k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 @@ -93,7 +92,7 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect github.com/go-chi/chi/v5 v5.1.0 // indirect - github.com/go-jose/go-jose/v4 v4.0.2 // indirect + github.com/go-jose/go-jose/v4 v4.0.5 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect @@ -204,7 +203,7 @@ require ( golang.org/x/net v0.33.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.10.0 // indirect - golang.org/x/term v0.27.0 // indirect + golang.org/x/term v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.23.0 // indirect diff --git a/go.sum b/go.sum index d510e1c..8789e11 100644 --- a/go.sum +++ b/go.sum @@ -177,8 +177,8 @@ github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I= github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= -github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= +github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= +github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= @@ -483,8 +483,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/swaggest/assertjson v1.9.0 h1:dKu0BfJkIxv/xe//mkCrK5yZbs79jL7OVf9Ija7o2xQ= github.com/swaggest/assertjson v1.9.0/go.mod h1:b+ZKX2VRiUjxfUIal0HDN85W0nHPAYUbYH5WkkSsFsU= github.com/tailscale/certstore v0.1.1-0.20220316223106-78d6e1c49d8d h1:K3j02b5j2Iw1xoggN9B2DIEkhWGheqFOeDkdJdBrJI8= @@ -596,8 +596,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -618,8 +618,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= @@ -662,14 +660,14 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.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.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= 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= From 02b1861e9296712ec9cdab8d3b0c41211906f6cd Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 2 Apr 2025 03:27:46 -0400 Subject: [PATCH 04/11] chore: update go to 1.24.1 (#136) --- .github/workflows/ci.yaml | 14 +++++++------- .github/workflows/release.yaml | 2 +- .golangci.yaml | 2 +- go.mod | 3 ++- sysboxutil/manager.go | 3 ++- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b292e89..078d698 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -37,13 +37,13 @@ jobs: # Install Go! - uses: actions/setup-go@v3 with: - go-version: "~1.23" + go-version: "~1.24" # Check for Go linting errors! - name: Lint Go uses: golangci/golangci-lint-action@v6.1.1 with: - version: v1.62.2 + version: v1.64.8 args: "--out-${NO_FUTURE}format colored-line-number" - name: Lint shell scripts @@ -98,7 +98,7 @@ jobs: - uses: actions/setup-go@v3 with: - go-version: "~1.23" + go-version: "~1.24" # Sadly the new "set output" syntax (of writing env vars to # $GITHUB_OUTPUT) does not work on both powershell and bash so we use the @@ -136,7 +136,7 @@ jobs: - uses: actions/setup-go@v3 with: - go-version: "~1.23" + go-version: "~1.24" # Sadly the new "set output" syntax (of writing env vars to # $GITHUB_OUTPUT) does not work on both powershell and bash so we use the @@ -170,7 +170,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: "~1.23" + go-version: "~1.24" - name: Go Cache Paths id: go-cache-paths @@ -223,7 +223,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: "~1.23" + go-version: "~1.24" - name: Go Cache Paths id: go-cache-paths @@ -262,7 +262,7 @@ jobs: - uses: actions/setup-go@v3 with: - go-version: "~1.23" + go-version: "~1.24" - name: build image run: make -j build/image/envbox diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 2735b78..3c77ce1 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -57,7 +57,7 @@ jobs: - uses: actions/setup-go@v3 with: - go-version: "~1.23" + go-version: "~1.24" - name: Go Cache Paths id: go-cache-paths diff --git a/.golangci.yaml b/.golangci.yaml index e92087f..06f75af 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -202,6 +202,7 @@ run: concurrency: 4 skip-dirs: - node_modules + - cli/cliflag skip-files: - scripts/rules.go timeout: 5m @@ -218,7 +219,6 @@ linters: - errcheck - errname - errorlint - - exportloopref - forcetypeassert - gocritic - gocyclo diff --git a/go.mod b/go.mod index ab9efd6..4ce200b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,7 @@ module github.com/coder/envbox -go 1.23.3 +go 1.24.1 + // There are a few minor changes we make to Tailscale that we're slowly upstreaming. Compare here: // https://github.com/tailscale/tailscale/compare/main...coder:tailscale:main replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa558fbe5374 diff --git a/sysboxutil/manager.go b/sysboxutil/manager.go index 61ea658..d3f9bef 100644 --- a/sysboxutil/manager.go +++ b/sysboxutil/manager.go @@ -5,8 +5,9 @@ import ( "os" "time" - "github.com/coder/envbox/xunix" "golang.org/x/xerrors" + + "github.com/coder/envbox/xunix" ) const ManagerSocketPath = "/run/sysbox/sysmgr.sock" From a70d5a3214e5b88e1fe5dfdf96b48ab9ef3dc032 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 03:32:27 -0400 Subject: [PATCH 05/11] chore(deps): bump golang.org/x/net from 0.33.0 to 0.36.0 (#132) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.33.0 to 0.36.0. - [Commits](https://github.com/golang/net/compare/v0.33.0...v0.36.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 13 ++++++------- go.sum | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 4ce200b..7cff320 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,6 @@ module github.com/coder/envbox go 1.24.1 - // There are a few minor changes we make to Tailscale that we're slowly upstreaming. Compare here: // https://github.com/tailscale/tailscale/compare/main...coder:tailscale:main replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa558fbe5374 @@ -24,10 +23,10 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.10.0 github.com/vishvananda/netlink v1.2.1-beta.2 - golang.org/x/crypto v0.32.0 + golang.org/x/crypto v0.35.0 golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 golang.org/x/mod v0.19.0 - golang.org/x/sys v0.29.0 + golang.org/x/sys v0.30.0 golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 k8s.io/mount-utils v0.26.2 k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 @@ -201,11 +200,11 @@ require ( go.uber.org/atomic v1.11.0 // indirect go4.org/mem v0.0.0-20220726221520-4f986261bf13 // indirect go4.org/netipx v0.0.0-20230728180743-ad4cb58a6516 // indirect - golang.org/x/net v0.33.0 // indirect + golang.org/x/net v0.36.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/term v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/term v0.29.0 // indirect + golang.org/x/text v0.22.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.23.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect diff --git a/go.sum b/go.sum index 8789e11..0129eca 100644 --- a/go.sum +++ b/go.sum @@ -596,8 +596,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -618,8 +618,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= +golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -629,8 +629,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.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -660,14 +660,14 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.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.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= -golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= 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= @@ -675,8 +675,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 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.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= 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= From 81e3a3d28bd277a8fb29017e1bab57815e764e13 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 9 Apr 2025 17:09:34 -0400 Subject: [PATCH 06/11] fix: provide backwards compatibility for image secrets without a hostname (#137) --- dockerutil/client.go | 39 ++++++++++++---- integration/docker_test.go | 94 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 8 deletions(-) diff --git a/dockerutil/client.go b/dockerutil/client.go index 00dc4b9..c860fbc 100644 --- a/dockerutil/client.go +++ b/dockerutil/client.go @@ -82,16 +82,39 @@ func parseConfig(cfg dockercfg.Config, reg string) (AuthConfig, error) { } if secret != "" { - if username == "" { - return AuthConfig{ - IdentityToken: secret, - }, nil + return toAuthConfig(username, secret), nil + } + + // This to preserve backwards compatibility with older variants of envbox + // that didn't mandate a hostname key in the config file. We just take the + // first valid auth config we find and use that. + for _, auth := range cfg.AuthConfigs { + if auth.IdentityToken != "" { + return toAuthConfig("", auth.IdentityToken), nil } - return AuthConfig{ - Username: username, - Password: secret, - }, nil + + if auth.Username != "" && auth.Password != "" { + return toAuthConfig(auth.Username, auth.Password), nil + } + + username, secret, err = dockercfg.DecodeBase64Auth(auth) + if err == nil && secret != "" { + return toAuthConfig(username, secret), nil + } + // Invalid auth config, skip it. } return AuthConfig{}, xerrors.Errorf("no auth config found for registry %s: %w", reg, os.ErrNotExist) } + +func toAuthConfig(username, secret string) AuthConfig { + if username == "" { + return AuthConfig{ + IdentityToken: secret, + } + } + return AuthConfig{ + Username: username, + Password: secret, + } +} diff --git a/integration/docker_test.go b/integration/docker_test.go index c7c1a6d..61c961d 100644 --- a/integration/docker_test.go +++ b/integration/docker_test.go @@ -393,6 +393,100 @@ func TestDocker(t *testing.T) { require.True(t, recorder.ContainsLog("Envbox startup complete!")) }) + // This test provides backwards compatibility for older variants of envbox that may specify a + // Docker Auth config without a hostname key. + t.Run("NoHostnameAuthConfig", func(t *testing.T) { + t.Parallel() + + var ( + dir = integrationtest.TmpDir(t) + binds = integrationtest.DefaultBinds(t, dir) + ) + + pool, err := dockertest.NewPool("") + require.NoError(t, err) + + // Create some listeners for the Docker and Coder + // services we'll be running with self signed certs. + bridgeIP := integrationtest.DockerBridgeIP(t) + coderListener, err := net.Listen("tcp", fmt.Sprintf("%s:0", bridgeIP)) + require.NoError(t, err) + defer coderListener.Close() + coderAddr := tcpAddr(t, coderListener) + + registryListener, err := net.Listen("tcp", fmt.Sprintf("%s:0", bridgeIP)) + require.NoError(t, err) + err = registryListener.Close() + require.NoError(t, err) + registryAddr := tcpAddr(t, registryListener) + + coderCert := integrationtest.GenerateTLSCertificate(t, "host.docker.internal", coderAddr.IP.String()) + dockerCert := integrationtest.GenerateTLSCertificate(t, "host.docker.internal", registryAddr.IP.String()) + + // Startup our fake Coder "control-plane". + recorder := integrationtest.FakeBuildLogRecorder(t, coderListener, coderCert) + + certDir := integrationtest.MkdirAll(t, dir, "certs") + + // Write the Coder cert disk. + coderCertPath := filepath.Join(certDir, "coder_cert.pem") + coderKeyPath := filepath.Join(certDir, "coder_key.pem") + integrationtest.WriteCertificate(t, coderCert, coderCertPath, coderKeyPath) + coderCertMount := integrationtest.BindMount(certDir, "/tmp/certs", false) + + // Write the Registry cert to disk. + regCertPath := filepath.Join(certDir, "registry_cert.crt") + regKeyPath := filepath.Join(certDir, "registry_key.pem") + integrationtest.WriteCertificate(t, dockerCert, regCertPath, regKeyPath) + + username := "coder" + password := "helloworld" + + // Start up the docker registry and push an image + // to it that we can reference. + image := integrationtest.RunLocalDockerRegistry(t, pool, integrationtest.RegistryConfig{ + HostCertPath: regCertPath, + HostKeyPath: regKeyPath, + Image: integrationtest.UbuntuImage, + TLSPort: strconv.Itoa(registryAddr.Port), + PasswordDir: dir, + Username: username, + Password: password, + }) + + type authConfigs struct { + Auths map[string]dockerutil.AuthConfig `json:"auths"` + } + + auths := authConfigs{ + Auths: map[string]dockerutil.AuthConfig{ + "": {Username: username, Password: password}, + }, + } + + authStr, err := json.Marshal(auths) + require.NoError(t, err) + + envs := []string{ + integrationtest.EnvVar(cli.EnvAgentToken, "faketoken"), + integrationtest.EnvVar(cli.EnvAgentURL, fmt.Sprintf("https://%s:%d", "host.docker.internal", coderAddr.Port)), + integrationtest.EnvVar(cli.EnvExtraCertsPath, "/tmp/certs"), + integrationtest.EnvVar(cli.EnvBoxPullImageSecretEnvVar, string(authStr)), + } + + // Run the envbox container. + _ = integrationtest.RunEnvbox(t, pool, &integrationtest.CreateDockerCVMConfig{ + Image: image.String(), + Username: "coder", + Envs: envs, + OuterMounts: append(binds, coderCertMount), + }) + + // This indicates we've made it all the way to end + // of the logs we attempt to push. + require.True(t, recorder.ContainsLog("Envbox startup complete!")) + }) + // This tests the inverse of SelfSignedCerts. We assert that // the container fails to startup since we don't have a valid // cert for the registry. It mainly tests that we aren't From ffd993dada364cd1da2ad90f1edcefc224687f5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 May 2025 11:44:42 -0400 Subject: [PATCH 07/11] chore(deps): bump golang.org/x/net from 0.36.0 to 0.38.0 (#138) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.36.0 to 0.38.0. - [Commits](https://github.com/golang/net/compare/v0.36.0...v0.38.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-version: 0.38.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 13 +++++++------ go.sum | 24 ++++++++++++------------ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 7cff320..1babc85 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,7 @@ module github.com/coder/envbox go 1.24.1 + // There are a few minor changes we make to Tailscale that we're slowly upstreaming. Compare here: // https://github.com/tailscale/tailscale/compare/main...coder:tailscale:main replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa558fbe5374 @@ -23,10 +24,10 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.10.0 github.com/vishvananda/netlink v1.2.1-beta.2 - golang.org/x/crypto v0.35.0 + golang.org/x/crypto v0.36.0 golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 golang.org/x/mod v0.19.0 - golang.org/x/sys v0.30.0 + golang.org/x/sys v0.31.0 golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 k8s.io/mount-utils v0.26.2 k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 @@ -200,11 +201,11 @@ require ( go.uber.org/atomic v1.11.0 // indirect go4.org/mem v0.0.0-20220726221520-4f986261bf13 // indirect go4.org/netipx v0.0.0-20230728180743-ad4cb58a6516 // indirect - golang.org/x/net v0.36.0 // indirect + golang.org/x/net v0.38.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/term v0.29.0 // indirect - golang.org/x/text v0.22.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/term v0.30.0 // indirect + golang.org/x/text v0.23.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.23.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect diff --git a/go.sum b/go.sum index 0129eca..7bb650a 100644 --- a/go.sum +++ b/go.sum @@ -596,8 +596,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -618,8 +618,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= -golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -629,8 +629,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.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -660,14 +660,14 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= -golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= 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= @@ -675,8 +675,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 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.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= 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= From 3007894bd39d94db82184d301e510850fd4a8090 Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Wed, 11 Jun 2025 23:14:57 +1000 Subject: [PATCH 08/11] chore: move all images to new GCP project (#142) --- integration/integrationtest/docker.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/integration/integrationtest/docker.go b/integration/integrationtest/docker.go index 0f820be..b6f5ce4 100644 --- a/integration/integrationtest/docker.go +++ b/integration/integrationtest/docker.go @@ -33,13 +33,13 @@ import ( const ( // DockerdImage is a large image (~1GB) and should only be used to test // dockerd. - DockerdImage = "gcr.io/coder-dev-1/sreya/enterprise-base:ubuntu" + DockerdImage = "us-docker.pkg.dev/coder-v2-images-public/public/envbox/enterprise-base:ubuntu" // HelloWorldImage is useful for testing a CVM's dockerd is functioning // correctly - HelloWorldImage = "gcr.io/coder-dev-1/sreya/hello-world" + HelloWorldImage = "us-docker.pkg.dev/coder-v2-images-public/public/envbox/hello-world" // UbuntuImage is just vanilla ubuntu (80MB) but the user is set to a non-root // user . - UbuntuImage = "gcr.io/coder-dev-1/sreya/ubuntu-coder" + UbuntuImage = "us-docker.pkg.dev/coder-v2-images-public/public/envbox/ubuntu-coder" // Redhat UBI9 image as of 2025-03-05 RedhatImage = "registry.access.redhat.com/ubi9/ubi:9.5" // CUDASampleImage is a CUDA sample image from NVIDIA's container registry. @@ -49,7 +49,7 @@ const ( // RegistryImage is used to assert that we add certs // correctly to the docker daemon when pulling an image // from a registry with a self signed cert. - registryImage = "gcr.io/coder-dev-1/sreya/registry" + registryImage = "us-docker.pkg.dev/coder-v2-images-public/public/envbox/registry" registryTag = "2.8.3" ) From fd99816f30cfa214eff97dd0a19d38d610908a4a Mon Sep 17 00:00:00 2001 From: CVdV-au <69226052+CVdV-au@users.noreply.github.com> Date: Mon, 14 Jul 2025 13:46:05 +1000 Subject: [PATCH 09/11] Sysbox 0.6.7 (#145) --- .github/workflows/release.yaml | 4 ++-- Makefile | 2 +- deploy/Dockerfile | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3c77ce1..ccba56b 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -31,11 +31,11 @@ jobs: include: - os: ubuntu-22.04 arch: linux/amd64 - sha: 87cfa5cad97dc5dc1a243d6d88be1393be75b93a517dc1580ecd8a2801c2777a + sha: b7ac389e5a19592cadf16e0ca30e40919516128f6e1b7f99e1cb4ff64554172e arch-suffix: amd64 - os: depot-ubuntu-22.04-arm arch: linux/arm64 - sha: 640014411de589f4e09f8383dc53b3c7785575be13d5573d4addbd597f858d56 + sha: 16d80123ba53058cf90f5a68686e297621ea97942602682e34b3352783908f91 arch-suffix: arm64 runs-on: ${{ matrix.os }} steps: diff --git a/Makefile b/Makefile index b230ab7..8a22340 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ PROJECT_ROOT := $(shell git rev-parse --show-toplevel) GO_FILES := $(shell git ls-files '*.go' '*.sum') IMAGE_FILES := $(shell find deploy) ARCH ?= linux/amd64 -SYSBOX_SHA ?= 87cfa5cad97dc5dc1a243d6d88be1393be75b93a517dc1580ecd8a2801c2777a +SYSBOX_SHA ?= b7ac389e5a19592cadf16e0ca30e40919516128f6e1b7f99e1cb4ff64554172e .PHONY: clean clean: diff --git a/deploy/Dockerfile b/deploy/Dockerfile index c7c353d..1bf3ee3 100644 --- a/deploy/Dockerfile +++ b/deploy/Dockerfile @@ -6,7 +6,7 @@ ARG TARGETARCH # We don't hardcode it here because we have to be able to build both # amd and arm ARG SYSBOX_SHA -ARG SYSBOX_VERSION="0.6.6" +ARG SYSBOX_VERSION="0.6.7" ARG SYSBOX_DEB="sysbox-ce_$SYSBOX_VERSION-0.linux_$TARGETARCH.deb" # Copy configuration files to appropriate locations From 933e208c2a1b2fa476196ff0fe85c45e45bd2f86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Jul 2025 13:51:40 +1000 Subject: [PATCH 10/11] chore(deps): bump github.com/go-chi/chi/v5 from 5.1.0 to 5.2.2 (#143) Bumps [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) from 5.1.0 to 5.2.2. - [Release notes](https://github.com/go-chi/chi/releases) - [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md) - [Commits](https://github.com/go-chi/chi/compare/v5.1.0...v5.2.2) --- updated-dependencies: - dependency-name: github.com/go-chi/chi/v5 dependency-version: 5.2.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1babc85..94e81a9 100644 --- a/go.mod +++ b/go.mod @@ -92,7 +92,7 @@ require ( github.com/fatih/color v1.17.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect - github.com/go-chi/chi/v5 v5.1.0 // indirect + github.com/go-chi/chi/v5 v5.2.2 // indirect github.com/go-jose/go-jose/v4 v4.0.5 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect diff --git a/go.sum b/go.sum index 7bb650a..2422af4 100644 --- a/go.sum +++ b/go.sum @@ -175,8 +175,8 @@ github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I= github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo= -github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= -github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618= +github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= From 1c3d6e8073e99f19bd1e6ba1b4d19793993d27f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Jul 2025 13:51:47 +1000 Subject: [PATCH 11/11] chore(deps): bump github.com/go-viper/mapstructure/v2 (#144) Bumps [github.com/go-viper/mapstructure/v2](https://github.com/go-viper/mapstructure) from 2.2.1 to 2.3.0. - [Release notes](https://github.com/go-viper/mapstructure/releases) - [Changelog](https://github.com/go-viper/mapstructure/blob/main/CHANGELOG.md) - [Commits](https://github.com/go-viper/mapstructure/compare/v2.2.1...v2.3.0) --- updated-dependencies: - dependency-name: github.com/go-viper/mapstructure/v2 dependency-version: 2.3.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 94e81a9..de07e31 100644 --- a/go.mod +++ b/go.mod @@ -98,7 +98,7 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect - github.com/go-viper/mapstructure/v2 v2.2.1 // indirect + github.com/go-viper/mapstructure/v2 v2.3.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect diff --git a/go.sum b/go.sum index 2422af4..92b33e4 100644 --- a/go.sum +++ b/go.sum @@ -201,8 +201,8 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= -github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk= +github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=