From 37ddd681c7ec4c2704d53c2acfb96e06d49407ee Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Fri, 9 Aug 2024 15:46:29 +0100 Subject: [PATCH 01/40] add note regarding platform compatibility --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 62589ff..0159b7d 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ The `terraform-provider-envbuilder` is a Terraform provider that acts as a helpe It is used to determine if a pre-built image of a dev container built from a given Git repository is present in a given Docker registry. If it is found that building a particular dev container would produce the same image that is already present in the remote registry, then that image can be used to start the container instead, skipping over the build phase. +> **Note:** currently, this provider can only be run on Linux platforms. We are [investigating support](https://github.com/coder/terraform-provider-envbuilder/issues/26) for other platforms. + ## Usage Take a look at the [`envbuilder_cached_image_resource.tf`](./examples/resources/envbuilder_cached_image/envbuilder_cached_image_resource.tf) example for a detailed usage example. From a4e82b3d8cb7cd3a7cc8e680d2ad4fca5eb397f2 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Fri, 9 Aug 2024 15:47:15 +0100 Subject: [PATCH 02/40] readme: remove duplicated usage note --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 0159b7d..611d9bd 100644 --- a/README.md +++ b/README.md @@ -32,10 +32,6 @@ For use with [Coder](https://github.com/coder/coder), see the [Dev Containers do go install ``` -## Using the provider - -Fill this in for each provider - ## Developing the Provider If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (see [Requirements](#requirements) above). From a2a5fcf79bf43c99f5a108d4692be36a6dfd8623 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Mon, 12 Aug 2024 12:54:30 +0300 Subject: [PATCH 03/40] fix: prevent test flake by waiting on copy (#27) --- internal/provider/git_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/provider/git_test.go b/internal/provider/git_test.go index a512a85..86131fe 100644 --- a/internal/provider/git_test.go +++ b/internal/provider/git_test.go @@ -135,17 +135,19 @@ func startSSHServer(ctx context.Context, t testing.TB) string { _, _ = io.Copy(in, s) _ = in.Close() }() + outCopyDone := make(chan struct{}) go func() { _, _ = io.Copy(s, out) _ = out.Close() - _ = s.CloseWrite() + close(outCopyDone) }() err = cmd.Wait() if err != nil { t.Logf("command failed: %s", err) } + <-outCopyDone - t.Logf("session ended: %s", s.RawCommand()) + t.Logf("session ended (cmd=%q, code=%d)", s.RawCommand(), cmd.ProcessState.ExitCode()) err = s.Exit(cmd.ProcessState.ExitCode()) if err != nil { From f8a49e84ffa51d007cc19e2e5bac6015b2e44c0a Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 12 Aug 2024 11:51:06 +0100 Subject: [PATCH 04/40] ci: push envbuilder image to local registry (#28) --- GNUmakefile | 7 ++++++- internal/provider/provider_test.go | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 800fcb9..0fc2494 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -41,15 +41,20 @@ 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/test-ubuntu +test-images-push: .registry-cache/docker/registry/v2/repositories/test-ubuntu .registry-cache/docker/registry/v2/repositories/envbuilder .PHONY: test-images-pull test-images-pull: docker pull ubuntu:latest docker tag ubuntu:latest localhost:5000/test-ubuntu:latest + docker pull ghcr.io/coder/envbuilder-preview:latest + docker tag ghcr.io/coder/envbuilder-preview:latest localhost:5000/envbuilder:latest .registry-cache: mkdir -p .registry-cache && chmod -R ag+w .registry-cache .registry-cache/docker/registry/v2/repositories/test-ubuntu: docker push localhost:5000/test-ubuntu:latest + +.registry-cache/docker/registry/v2/repositories/envbuilder: + docker push localhost:5000/envbuilder:latest \ No newline at end of file diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index 59f21ed..cfe32a9 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -74,7 +74,7 @@ func quote(s string) string { func setup(ctx context.Context, t testing.TB, files map[string]string) testDependencies { t.Helper() - envbuilderImage := getEnvOrDefault("ENVBUILDER_IMAGE", "ghcr.io/coder/envbuilder-preview") + envbuilderImage := getEnvOrDefault("ENVBUILDER_IMAGE", "localhost:5000/envbuilder") envbuilderVersion := getEnvOrDefault("ENVBUILDER_VERSION", "latest") envbuilderImageRef := envbuilderImage + ":" + envbuilderVersion From 9a4bf0993d93bbdeddf9138947ae5a6181bb3aca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:17:17 +0100 Subject: [PATCH 05/40] chore(deps): bump github.com/hashicorp/terraform-plugin-testing from 1.9.0 to 1.10.0 (#29) chore(deps): bump github.com/hashicorp/terraform-plugin-testing Bumps [github.com/hashicorp/terraform-plugin-testing](https://github.com/hashicorp/terraform-plugin-testing) from 1.9.0 to 1.10.0. - [Release notes](https://github.com/hashicorp/terraform-plugin-testing/releases) - [Changelog](https://github.com/hashicorp/terraform-plugin-testing/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/terraform-plugin-testing/compare/v1.9.0...v1.10.0) --- updated-dependencies: - dependency-name: github.com/hashicorp/terraform-plugin-testing dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 19 ++++++++++--------- go.sum | 38 ++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/go.mod b/go.mod index 1f68bb3..66e2fb6 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/hashicorp/terraform-plugin-framework v1.11.0 github.com/hashicorp/terraform-plugin-go v0.23.0 github.com/hashicorp/terraform-plugin-log v0.9.0 - github.com/hashicorp/terraform-plugin-testing v1.9.0 + github.com/hashicorp/terraform-plugin-testing v1.10.0 github.com/stretchr/testify v1.9.0 ) @@ -158,12 +158,13 @@ require ( github.com/hashicorp/go-memdb v1.3.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.6.0 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect 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/hc-install v0.7.0 // indirect + github.com/hashicorp/hc-install v0.8.0 // indirect github.com/hashicorp/hcl/v2 v2.21.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.21.0 // indirect @@ -272,7 +273,7 @@ require ( github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/yuin/goldmark v1.7.1 // indirect github.com/yuin/goldmark-meta v1.1.0 // indirect - github.com/zclconf/go-cty v1.14.4 // indirect + github.com/zclconf/go-cty v1.15.0 // indirect github.com/zeebo/errs v1.3.0 // indirect go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect go.etcd.io/etcd/raft/v3 v3.5.6 // indirect @@ -289,15 +290,15 @@ 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/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect - golang.org/x/mod v0.18.0 // indirect + golang.org/x/mod v0.19.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.8.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/time v0.5.0 // indirect golang.org/x/tools v0.22.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect diff --git a/go.sum b/go.sum index 995dc1e..4215a54 100644 --- a/go.sum +++ b/go.sum @@ -441,6 +441,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -454,8 +456,8 @@ github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGN 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/hc-install v0.7.0 h1:Uu9edVqjKQxxuD28mR5TikkKDd/p55S8vzPC1659aBk= -github.com/hashicorp/hc-install v0.7.0/go.mod h1:ELmmzZlGnEcqoUMKUuykHaPCIR1sYLYX+KSggWSKZuA= +github.com/hashicorp/hc-install v0.8.0 h1:LdpZeXkZYMQhoKPCecJHlKvUkQFixN/nvyR1CdfOLjI= +github.com/hashicorp/hc-install v0.8.0/go.mod h1:+MwJYjDfCruSD/udvBmRB22Nlkwwkwf5sAB6uTIhSaU= github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14= github.com/hashicorp/hcl/v2 v2.21.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= @@ -474,8 +476,8 @@ github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9T github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 h1:kJiWGx2kiQVo97Y5IOGR4EMcZ8DtMswHhUuFibsCQQE= github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0/go.mod h1:sl/UoabMc37HA6ICVMmGO+/0wofkVIRxf+BMb/dnoIg= -github.com/hashicorp/terraform-plugin-testing v1.9.0 h1:xOsQRqqlHKXpFq6etTxih3ubdK3HVDtfE1IY7Rpd37o= -github.com/hashicorp/terraform-plugin-testing v1.9.0/go.mod h1:fhhVx/8+XNJZTD5o3b4stfZ6+q7z9+lIWigIYdT6/44= +github.com/hashicorp/terraform-plugin-testing v1.10.0 h1:2+tmRNhvnfE4Bs8rB6v58S/VpqzGC6RCh9Y8ujdn+aw= +github.com/hashicorp/terraform-plugin-testing v1.10.0/go.mod h1:iWRW3+loP33WMch2P/TEyCxxct/ZEcCGMquSLSCVsrc= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= @@ -807,8 +809,8 @@ github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0= -github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= -github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= +github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= @@ -874,8 +876,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +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/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= @@ -887,8 +889,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -922,8 +924,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.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.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= @@ -962,16 +964,16 @@ 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.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/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.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= 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.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +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/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= @@ -981,8 +983,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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/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 b35004a70209dc64939e483fe1b1147def389114 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Tue, 13 Aug 2024 13:13:45 +0100 Subject: [PATCH 06/40] feat: add warning diags to aid troubleshooting (#30) Adds warning diagnostics to aid in troubleshooting issues with cached builds. --- internal/provider/cached_image_resource.go | 26 ++++++++++++++++--- .../provider/cached_image_resource_test.go | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/internal/provider/cached_image_resource.go b/internal/provider/cached_image_resource.go index 4cbdfce..e165453 100644 --- a/internal/provider/cached_image_resource.go +++ b/internal/provider/cached_image_resource.go @@ -292,7 +292,11 @@ func (r *CachedImageResource) Read(ctx context.Context, req resource.ReadRequest // If the previous state is that Image == BuilderImage, then we previously did // not find the image. We will need to run another cache probe. if data.Image.Equal(data.BuilderImage) { - tflog.Debug(ctx, "Image previously not found. Recreating.", map[string]any{"ref": data.Image.ValueString()}) + resp.Diagnostics.AddWarning( + "Re-running cache probe due to previous miss.", + fmt.Sprintf(`The previous state specifies image == builder_image %q, which indicates a previous cache miss.`, + data.Image.ValueString(), + )) resp.State.RemoveResource(ctx) return } @@ -301,12 +305,22 @@ func (r *CachedImageResource) Read(ctx context.Context, req resource.ReadRequest img, err := getRemoteImage(data.Image.ValueString()) if err != nil { if !strings.Contains(err.Error(), "MANIFEST_UNKNOWN") { - resp.Diagnostics.AddError("Error checking remote image", err.Error()) + // Explicitly not making this an error diag. + resp.Diagnostics.AddWarning("Unable to check remote image.", + fmt.Sprintf("The repository %q returned the following error while checking for a cached image %q: %q", + data.CacheRepo.ValueString(), + data.Image.ValueString(), + err.Error(), + )) return } // Image does not exist any longer! Remove the resource so we can re-create // it next time. - tflog.Debug(ctx, "Remote image does not exist any longer. Recreating.", map[string]any{"ref": data.Image.ValueString()}) + resp.Diagnostics.AddWarning("Previously built image not found, recreating.", + fmt.Sprintf("The repository %q does not contain the cached image %q. It will be rebuilt in the next apply.", + data.CacheRepo.ValueString(), + data.Image.ValueString(), + )) resp.State.RemoveResource(ctx) return } @@ -365,7 +379,11 @@ func (r *CachedImageResource) Create(ctx context.Context, req resource.CreateReq // FIXME: there are legit errors that can crop up here. // We should add a sentinel error in Kaniko for uncached layers, and check // it here. - tflog.Info(ctx, "cached image not found", map[string]any{"err": err.Error()}) + resp.Diagnostics.AddWarning("Cached image not found.", fmt.Sprintf( + "Failed to find cached image in repository %q. It will be rebuilt in the next apply. Error: %s", + data.CacheRepo.ValueString(), + err.Error(), + )) data.Image = data.BuilderImage } else if digest, err := cachedImg.Digest(); err != nil { // There's something seriously up with this image! diff --git a/internal/provider/cached_image_resource_test.go b/internal/provider/cached_image_resource_test.go index e57ce8a..30bfc0e 100644 --- a/internal/provider/cached_image_resource_test.go +++ b/internal/provider/cached_image_resource_test.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) -func TestAccCachedImageDataSource(t *testing.T) { +func TestAccCachedImageResource(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() files := map[string]string{ From 68cc59d705f407bcf0e54f98a76f7b8b3095b067 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Wed, 14 Aug 2024 14:55:22 +0100 Subject: [PATCH 07/40] fix(internal/provider): correct escaping of strings in envbuilder_cached_image.env (#32) Fixes #31 We had previously been doing the equivalent of value.String() when writing envbuilder_cached_image.env. This was incorrectly escaping newlines, potentially breaking ENVBUILDER_INIT_SCRIPT. This PR modifies the behaviour to correctly handle string values via ValueString() instead. --- .../envbuilder_cached_image_resource.tf | 8 ++-- internal/provider/cached_image_resource.go | 42 ++++++++++++------- .../provider/cached_image_resource_test.go | 11 ++--- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/examples/resources/envbuilder_cached_image/envbuilder_cached_image_resource.tf b/examples/resources/envbuilder_cached_image/envbuilder_cached_image_resource.tf index 304aea4..af90219 100644 --- a/examples/resources/envbuilder_cached_image/envbuilder_cached_image_resource.tf +++ b/examples/resources/envbuilder_cached_image/envbuilder_cached_image_resource.tf @@ -66,10 +66,11 @@ resource "envbuilder_cached_image" "example" { builder_image = var.builder_image git_url = var.repo_url cache_repo = local.cache_repo + insecure = true extra_env = { "ENVBUILDER_VERBOSE" : "true" "ENVBUILDER_INSECURE" : "true" # due to local registry - "ENVBUILDER_INIT_SCRIPT" : "sleep infinity" + "ENVBUILDER_INIT_SCRIPT" : "#!/usr/bin/env bash\necho Hello && sleep infinity" "ENVBUILDER_PUSH_IMAGE" : "true" } depends_on = [docker_container.registry] @@ -77,8 +78,8 @@ resource "envbuilder_cached_image" "example" { // Run the cached image. Depending on the contents of // the cache repo, this will either be var.builder_image -// or a previously built image pusehd to var.cache_repo. -// Running `terraform apply` once (assuming empty cache) +// or a previously built image pushed to var.cache_repo. +// Running `terraform apply` once (assuming empty cache) // will result in the builder image running, and the built // image being pushed to the cache repo. // Running `terraform apply` again will result in the @@ -105,4 +106,3 @@ output "id" { output "image" { value = envbuilder_cached_image.example.image } - diff --git a/internal/provider/cached_image_resource.go b/internal/provider/cached_image_resource.go index e165453..6505736 100644 --- a/internal/provider/cached_image_resource.go +++ b/internal/provider/cached_image_resource.go @@ -22,6 +22,7 @@ import ( "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" @@ -631,20 +632,35 @@ func extractEnvbuilderFromImage(ctx context.Context, imgRef, destPath string) er return fmt.Errorf("extract envbuilder binary from image %q: %w", imgRef, os.ErrNotExist) } -// NOTE: the String() method of Terraform values will evalue to `` if unknown. -// Check IsUnknown() first before calling String(). -type stringable interface { - IsUnknown() bool - IsNull() bool - String() string +// tfValueToString converts an attr.Value to its string representation +// based on its Terraform type. This is needed because the String() +// method on an attr.Value creates a 'human-readable' version of the type, which +// leads to quotes, escaped characters, and other assorted sadness. +func tfValueToString(val attr.Value) string { + if val.IsUnknown() || val.IsNull() { + return "" + } + if vs, ok := val.(interface{ ValueString() string }); ok { + return vs.ValueString() + } + if vb, ok := val.(interface{ ValueBool() bool }); ok { + return fmt.Sprintf("%t", vb.ValueBool()) + } + if vi, ok := val.(interface{ ValueInt64() int64 }); ok { + return fmt.Sprintf("%d", vi.ValueInt64()) + } + panic(fmt.Errorf("tfValueToString: value %T is not a supported type", val)) } -func appendKnownEnvToList(list types.List, key string, value stringable) types.List { +func appendKnownEnvToList(list types.List, key string, value attr.Value) types.List { if value.IsUnknown() || value.IsNull() { return list } - val := strings.Trim(value.String(), `"`) - elem := types.StringValue(fmt.Sprintf("%s=%s", key, val)) + var sb strings.Builder + _, _ = sb.WriteString(key) + _, _ = sb.WriteRune('=') + _, _ = sb.WriteString(tfValueToString(value)) + elem := types.StringValue(sb.String()) list, _ = types.ListValue(types.StringType, append(list.Elements(), elem)) return list } @@ -652,13 +668,7 @@ func appendKnownEnvToList(list types.List, key string, value stringable) types.L func tfListToStringSlice(l types.List) []string { var ss []string for _, el := range l.Elements() { - if sv, ok := el.(stringable); !ok { - panic(fmt.Sprintf("developer error: element %+v must be stringable", el)) - } else if sv.IsUnknown() { - ss = append(ss, "") - } else { - ss = append(ss, sv.String()) - } + ss = append(ss, tfValueToString(el)) } return ss } diff --git a/internal/provider/cached_image_resource_test.go b/internal/provider/cached_image_resource_test.go index 30bfc0e..4653f8b 100644 --- a/internal/provider/cached_image_resource_test.go +++ b/internal/provider/cached_image_resource_test.go @@ -20,7 +20,8 @@ func TestAccCachedImageResource(t *testing.T) { } deps := setup(ctx, t, files) - deps.ExtraEnv["FOO"] = "bar" + deps.ExtraEnv["FOO"] = `bar +baz` // THIS IS A LOAD-BEARING NEWLINE. DO NOT REMOVE. resource.Test(t, resource.TestCase{ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, Steps: []resource.TestStep{ @@ -42,7 +43,7 @@ func TestAccCachedImageResource(t *testing.T) { resource.TestCheckResourceAttr("envbuilder_cached_image.test", "image", deps.BuilderImage), // Inputs should still be present. resource.TestCheckResourceAttr("envbuilder_cached_image.test", "cache_repo", deps.CacheRepo), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar\nbaz"), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "git_url", deps.Repo.URL), // Should be empty resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), @@ -63,7 +64,7 @@ func TestAccCachedImageResource(t *testing.T) { resource.TestCheckResourceAttr("envbuilder_cached_image.test", "image", deps.BuilderImage), // Inputs should still be present. resource.TestCheckResourceAttr("envbuilder_cached_image.test", "cache_repo", deps.CacheRepo), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar\nbaz"), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "git_url", deps.Repo.URL), // Should be empty resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), @@ -81,7 +82,7 @@ func TestAccCachedImageResource(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( // Inputs should still be present. resource.TestCheckResourceAttr("envbuilder_cached_image.test", "cache_repo", deps.CacheRepo), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar\nbaz"), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "git_url", deps.Repo.URL), // Should be empty resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), @@ -92,7 +93,7 @@ func TestAccCachedImageResource(t *testing.T) { resource.TestCheckResourceAttr("envbuilder_cached_image.test", "exists", "true"), resource.TestCheckResourceAttrSet("envbuilder_cached_image.test", "image"), resource.TestCheckResourceAttrWith("envbuilder_cached_image.test", "image", quotedPrefix(deps.CacheRepo)), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.0", "FOO=bar"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.0", "FOO=bar\nbaz"), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.1", fmt.Sprintf("ENVBUILDER_CACHE_REPO=%s", deps.CacheRepo)), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.2", fmt.Sprintf("ENVBUILDER_GIT_URL=%s", deps.Repo.URL)), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.3", "ENVBUILDER_REMOTE_REPO_BUILD_MODE=true"), From 9f455838b8ae33314901725c96295057d4f1e11a Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 15 Aug 2024 12:58:06 +0100 Subject: [PATCH 08/40] fix(provider): correctly handle devcontainer-only in cache probe mode (#33) * chore(internal/provider): add test case for dockerfile-only operation * chore(deps): update envbuilder to include #315 --- go.mod | 4 +- go.sum | 8 +- .../provider/cached_image_resource_test.go | 215 ++++++++++-------- 3 files changed, 125 insertions(+), 102 deletions(-) diff --git a/go.mod b/go.mod index 66e2fb6..ddfc2ad 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa55 require ( github.com/GoogleContainerTools/kaniko v1.9.2 - github.com/coder/envbuilder v1.0.0-rc.0.0.20240807151028-6e5bfa5faa29 + github.com/coder/envbuilder v1.0.0-rc.5.0.20240815111948-e6283db826e8 github.com/docker/docker v26.1.4+incompatible github.com/gliderlabs/ssh v0.3.7 github.com/go-git/go-billy/v5 v5.5.0 @@ -248,7 +248,7 @@ require ( github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/skeema/knownhosts v1.2.2 // indirect + github.com/skeema/knownhosts v1.3.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect diff --git a/go.sum b/go.sum index 4215a54..76dc58f 100644 --- a/go.sum +++ b/go.sum @@ -186,8 +186,8 @@ github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoC github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/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/envbuilder v1.0.0-rc.0.0.20240807151028-6e5bfa5faa29 h1:PhJBofIrh6NGuTQ93nW7/KWcYX6Ju0PGoE/BbNvf87o= -github.com/coder/envbuilder v1.0.0-rc.0.0.20240807151028-6e5bfa5faa29/go.mod h1:lm33s3+chqnl7lB4avNFfDH5gXDYSunYD7/y4bJ/LMA= +github.com/coder/envbuilder v1.0.0-rc.5.0.20240815111948-e6283db826e8 h1:tfmaVV7qFpODoBliTcDQyrB09FIjCQRUtjefr7zFEXY= +github.com/coder/envbuilder v1.0.0-rc.5.0.20240815111948-e6283db826e8/go.mod h1:HFqLE6BNJhR/fLknKWon5Eqhsr5FmuEJO1OJ/RKF2BA= github.com/coder/kaniko v0.0.0-20240807142221-ffc5e60fca41 h1:1Ye7AcLnuT5IDv6il7Fxo+aqpzlWfedkpraCCwx8Lyo= github.com/coder/kaniko v0.0.0-20240807142221-ffc5e60fca41/go.mod h1:YMK7BlxerzLlMwihGxNWUaFoN9LXCij4P+w/8/fNlcM= github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs= @@ -718,8 +718,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= -github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= +github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= diff --git a/internal/provider/cached_image_resource_test.go b/internal/provider/cached_image_resource_test.go index 4653f8b..5eeddfa 100644 --- a/internal/provider/cached_image_resource_test.go +++ b/internal/provider/cached_image_resource_test.go @@ -10,106 +10,129 @@ import ( "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) +// testEnvValue is a multi-line environment variable value that we use in +// tests to ensure that we can handle multi-line values correctly. +var testEnvValue = `bar +baz` + func TestAccCachedImageResource(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) defer cancel() - files := map[string]string{ - ".devcontainer/devcontainer.json": `{"build": { "dockerfile": "Dockerfile" }}`, - ".devcontainer/Dockerfile": `FROM localhost:5000/test-ubuntu:latest - RUN date > /date.txt`, - } - deps := setup(ctx, t, files) - deps.ExtraEnv["FOO"] = `bar -baz` // THIS IS A LOAD-BEARING NEWLINE. DO NOT REMOVE. - resource.Test(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, - Steps: []resource.TestStep{ - // Initial state: cache has not been seeded. - { - Config: deps.Config(t), - PlanOnly: true, - ExpectNonEmptyPlan: true, - }, - // Should detect that no cached image is present and plan to create the resource. - { - Config: deps.Config(t), - Check: resource.ComposeAggregateTestCheckFunc( - // Computed values MUST be present. - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "id", uuid.Nil.String()), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "exists", "false"), - resource.TestCheckResourceAttrSet("envbuilder_cached_image.test", "env.0"), - // Cached image should be set to the builder image. - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "image", deps.BuilderImage), - // Inputs should still be present. - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "cache_repo", deps.CacheRepo), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar\nbaz"), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "git_url", deps.Repo.URL), - // Should be empty - resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), - resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_password"), - resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "cache_ttl_days"), - ), - ExpectNonEmptyPlan: true, // TODO: check the plan. - }, - // Re-running plan should have the same effect. - { - Config: deps.Config(t), - Check: resource.ComposeAggregateTestCheckFunc( - // Computed values MUST be present. - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "id", uuid.Nil.String()), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "exists", "false"), - resource.TestCheckResourceAttrSet("envbuilder_cached_image.test", "env.0"), - // Cached image should be set to the builder image. - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "image", deps.BuilderImage), - // Inputs should still be present. - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "cache_repo", deps.CacheRepo), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar\nbaz"), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "git_url", deps.Repo.URL), - // Should be empty - resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), - resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_password"), - resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "cache_ttl_days"), - ), - ExpectNonEmptyPlan: true, // TODO: check the plan. - }, - // Now, seed the cache and re-run. We should now successfully create the cached image resource. - { - PreConfig: func() { - seedCache(ctx, t, deps) - }, - Config: deps.Config(t), - Check: resource.ComposeAggregateTestCheckFunc( - // Inputs should still be present. - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "cache_repo", deps.CacheRepo), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar\nbaz"), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "git_url", deps.Repo.URL), - // Should be empty - resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), - resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_password"), - resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "cache_ttl_days"), - // Computed - resource.TestCheckResourceAttrWith("envbuilder_cached_image.test", "id", quotedPrefix("sha256:")), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "exists", "true"), - resource.TestCheckResourceAttrSet("envbuilder_cached_image.test", "image"), - resource.TestCheckResourceAttrWith("envbuilder_cached_image.test", "image", quotedPrefix(deps.CacheRepo)), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.0", "FOO=bar\nbaz"), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.1", fmt.Sprintf("ENVBUILDER_CACHE_REPO=%s", deps.CacheRepo)), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.2", fmt.Sprintf("ENVBUILDER_GIT_URL=%s", deps.Repo.URL)), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.3", "ENVBUILDER_REMOTE_REPO_BUILD_MODE=true"), - resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "env.4"), - ), + for _, tc := range []struct { + name string + files map[string]string + }{ + { + name: "devcontainer only", + files: map[string]string{ + ".devcontainer/devcontainer.json": `{"image": "localhost:5000/test-ubuntu:latest"}`, }, - // Should produce an empty plan after apply - { - Config: deps.Config(t), - PlanOnly: true, - }, - // Ensure idempotence in this state! - { - Config: deps.Config(t), - PlanOnly: true, + }, + { + name: "devcontainer and Dockerfile", + files: map[string]string{ + ".devcontainer/devcontainer.json": `{"build": { "dockerfile": "Dockerfile" }}`, + ".devcontainer/Dockerfile": `FROM localhost:5000/test-ubuntu:latest +RUN date > /date.txt`, }, }, - }) + } { + t.Run(tc.name, func(t *testing.T) { + //nolint: paralleltest + deps := setup(ctx, t, tc.files) + deps.ExtraEnv["FOO"] = testEnvValue + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Initial state: cache has not been seeded. + { + Config: deps.Config(t), + PlanOnly: true, + ExpectNonEmptyPlan: true, + }, + // Should detect that no cached image is present and plan to create the resource. + { + Config: deps.Config(t), + Check: resource.ComposeAggregateTestCheckFunc( + // Computed values MUST be present. + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "id", uuid.Nil.String()), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "exists", "false"), + resource.TestCheckResourceAttrSet("envbuilder_cached_image.test", "env.0"), + // Cached image should be set to the builder image. + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "image", deps.BuilderImage), + // Inputs should still be present. + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "cache_repo", deps.CacheRepo), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar\nbaz"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "git_url", deps.Repo.URL), + // Should be empty + resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), + resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_password"), + resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "cache_ttl_days"), + ), + ExpectNonEmptyPlan: true, // TODO: check the plan. + }, + // Re-running plan should have the same effect. + { + Config: deps.Config(t), + Check: resource.ComposeAggregateTestCheckFunc( + // Computed values MUST be present. + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "id", uuid.Nil.String()), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "exists", "false"), + resource.TestCheckResourceAttrSet("envbuilder_cached_image.test", "env.0"), + // Cached image should be set to the builder image. + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "image", deps.BuilderImage), + // Inputs should still be present. + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "cache_repo", deps.CacheRepo), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar\nbaz"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "git_url", deps.Repo.URL), + // Should be empty + resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), + resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_password"), + resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "cache_ttl_days"), + ), + ExpectNonEmptyPlan: true, // TODO: check the plan. + }, + // Now, seed the cache and re-run. We should now successfully create the cached image resource. + { + PreConfig: func() { + seedCache(ctx, t, deps) + }, + Config: deps.Config(t), + Check: resource.ComposeAggregateTestCheckFunc( + // Inputs should still be present. + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "cache_repo", deps.CacheRepo), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar\nbaz"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "git_url", deps.Repo.URL), + // Should be empty + resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), + resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_password"), + resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "cache_ttl_days"), + // Computed + resource.TestCheckResourceAttrWith("envbuilder_cached_image.test", "id", quotedPrefix("sha256:")), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "exists", "true"), + resource.TestCheckResourceAttrSet("envbuilder_cached_image.test", "image"), + resource.TestCheckResourceAttrWith("envbuilder_cached_image.test", "image", quotedPrefix(deps.CacheRepo)), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.0", "FOO=bar\nbaz"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.1", fmt.Sprintf("ENVBUILDER_CACHE_REPO=%s", deps.CacheRepo)), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.2", fmt.Sprintf("ENVBUILDER_GIT_URL=%s", deps.Repo.URL)), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.3", "ENVBUILDER_REMOTE_REPO_BUILD_MODE=true"), + resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "env.4"), + ), + }, + // Should produce an empty plan after apply + { + Config: deps.Config(t), + PlanOnly: true, + }, + // Ensure idempotence in this state! + { + Config: deps.Config(t), + PlanOnly: true, + }, + }, + }) + }) + } } From b55c3783a8b1dbf906c6656c8335e810340e6ffc Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 15 Aug 2024 15:49:57 +0100 Subject: [PATCH 09/40] chore(deps): update docker/docker to v26.1.5 (#36) * chore(deps): update docker/docker to v26.1.5 * also update envbuilder --- go.mod | 21 ++++++++++++--------- go.sum | 42 ++++++++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/go.mod b/go.mod index ddfc2ad..671c8f6 100644 --- a/go.mod +++ b/go.mod @@ -10,8 +10,8 @@ replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa55 require ( github.com/GoogleContainerTools/kaniko v1.9.2 - github.com/coder/envbuilder v1.0.0-rc.5.0.20240815111948-e6283db826e8 - github.com/docker/docker v26.1.4+incompatible + github.com/coder/envbuilder v1.0.0-rc.5.0.20240815142547-cd63d0b71a40 + github.com/docker/docker v26.1.5+incompatible github.com/gliderlabs/ssh v0.3.7 github.com/go-git/go-billy/v5 v5.5.0 github.com/go-git/go-git/v5 v5.12.0 @@ -55,8 +55,8 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/Microsoft/hcsshim v0.11.7 // indirect github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/akutz/memconn v0.1.0 // indirect @@ -100,12 +100,15 @@ require ( 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.15 // indirect + github.com/containerd/containerd v1.7.19 // 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 github.com/containerd/fifo v1.1.0 // indirect github.com/containerd/log v0.1.0 // indirect + github.com/containerd/platforms v0.2.1 // indirect github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect - github.com/containerd/ttrpc v1.2.3 // indirect + github.com/containerd/ttrpc v1.2.5 // indirect github.com/containerd/typeurl/v2 v2.1.1 // indirect github.com/coreos/go-iptables v0.6.0 // indirect github.com/coreos/go-oidc/v3 v3.10.0 // indirect @@ -118,7 +121,7 @@ require ( github.com/distribution/reference v0.6.0 // indirect github.com/docker/cli v27.1.1+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker-credential-helpers v0.8.1 // indirect + github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/docker/go-metrics v0.0.1 // indirect @@ -222,7 +225,7 @@ require ( github.com/oklog/run v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/opencontainers/runtime-spec v1.1.0 // indirect + github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opencontainers/selinux v1.11.0 // indirect github.com/otiai10/copy v1.14.0 // indirect github.com/outcaste-io/ristretto v0.2.3 // indirect @@ -237,7 +240,7 @@ require ( github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.0 // indirect github.com/prometheus/common v0.48.0 // indirect - github.com/prometheus/procfs v0.15.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 // indirect github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 // indirect github.com/redis/go-redis/v9 v9.1.0 // indirect diff --git a/go.sum b/go.sum index 76dc58f..a52cab3 100644 --- a/go.sum +++ b/go.sum @@ -77,10 +77,10 @@ github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= -github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/Microsoft/hcsshim v0.11.7 h1:vl/nj3Bar/CvJSYo7gIQPyRWc9f3c6IeSNavBTSZNZQ= +github.com/Microsoft/hcsshim v0.11.7/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU= github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= @@ -186,8 +186,8 @@ github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoC github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/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/envbuilder v1.0.0-rc.5.0.20240815111948-e6283db826e8 h1:tfmaVV7qFpODoBliTcDQyrB09FIjCQRUtjefr7zFEXY= -github.com/coder/envbuilder v1.0.0-rc.5.0.20240815111948-e6283db826e8/go.mod h1:HFqLE6BNJhR/fLknKWon5Eqhsr5FmuEJO1OJ/RKF2BA= +github.com/coder/envbuilder v1.0.0-rc.5.0.20240815142547-cd63d0b71a40 h1:XxZpRd+bjCAZJJHCFBVsbIrYZSYcnZBm0kp/FgfZg0o= +github.com/coder/envbuilder v1.0.0-rc.5.0.20240815142547-cd63d0b71a40/go.mod h1:m7kjZGXpP8jAZgKwfBaMbXe0bg29ERZP3g4PMpQLR4k= github.com/coder/kaniko v0.0.0-20240807142221-ffc5e60fca41 h1:1Ye7AcLnuT5IDv6il7Fxo+aqpzlWfedkpraCCwx8Lyo= github.com/coder/kaniko v0.0.0-20240807142221-ffc5e60fca41/go.mod h1:YMK7BlxerzLlMwihGxNWUaFoN9LXCij4P+w/8/fNlcM= github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs= @@ -206,18 +206,24 @@ github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaD 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.15 h1:afEHXdil9iAm03BmhjzKyXnnEBtjaLJefdU7DV0IFes= -github.com/containerd/containerd v1.7.15/go.mod h1:ISzRRTMF8EXNpJlTzyr2XMhN+j9K302C21/+cr3kUnY= +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/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= github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= +github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY= github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= +github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= -github.com/containerd/ttrpc v1.2.3 h1:4jlhbXIGvijRtNC8F/5CpuJZ7yKOBFGFOOXg1bkISz0= -github.com/containerd/ttrpc v1.2.3/go.mod h1:ieWsXucbb8Mj9PH0rXCw1i8IunRbbAiDkpXkbfflWBM= +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/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk= @@ -250,10 +256,10 @@ github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2 github.com/docker/cli v27.1.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.4+incompatible h1:vuTpXDuoga+Z38m1OZHzl7NKisKWaWlhjQk7IDPSLsU= -github.com/docker/docker v26.1.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo= -github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= +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-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= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= @@ -636,8 +642,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= -github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= +github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -688,8 +694,8 @@ github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5E github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= -github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 h1:EaDatTxkdHG+U3Bk4EUr+DZ7fOGwTfezUiUJMaIcaho= github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5/go.mod h1:fyalQWdtzDBECAQFBJuQe5bzQ02jGd5Qcbgb97Flm7U= github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 h1:EfpWLLCyXw8PSM2/XNJLjI3Pb27yVE+gIAfeqp8LUCc= From 6cf3d934447f9dfead0fcaa9188d5017ceb42588 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Fri, 16 Aug 2024 09:42:27 +0100 Subject: [PATCH 10/40] feat(internal/provider): add env_map to cached_image_resource (#37) This PR adds `env_map` to `cached_image_resource.` This consists of the computed env in map format, which can be useful for other providers that do not expect `KEY=VALUE` format. --- docs/resources/cached_image.md | 3 +- internal/provider/cached_image_resource.go | 96 ++++++++++++------- .../provider/cached_image_resource_test.go | 52 +++++++--- 3 files changed, 105 insertions(+), 46 deletions(-) diff --git a/docs/resources/cached_image.md b/docs/resources/cached_image.md index 8498720..a7f4a38 100644 --- a/docs/resources/cached_image.md +++ b/docs/resources/cached_image.md @@ -48,7 +48,8 @@ The cached image resource can be used to retrieve a cached image produced by env ### Read-Only -- `env` (List of String, Sensitive) Computed envbuilder configuration to be set for the container. May contain secrets. +- `env` (List of String, Sensitive) Computed envbuilder configuration to be set for the container in the form of a list of strings of `key=value`. May contain secrets. +- `env_map` (Map of String, Sensitive) Computed envbuilder configuration to be set for the container in the form of a key-value map. May contain secrets. - `exists` (Boolean) Whether the cached image was exists or not for the given config. - `id` (String) Cached image identifier. This will generally be the image's SHA256 digest. - `image` (String) Outputs the cached image repo@digest if it exists, and builder image otherwise. diff --git a/internal/provider/cached_image_resource.go b/internal/provider/cached_image_resource.go index 6505736..4ea28b8 100644 --- a/internal/provider/cached_image_resource.go +++ b/internal/provider/cached_image_resource.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "path/filepath" + "sort" "strings" kconfig "github.com/GoogleContainerTools/kaniko/pkg/config" @@ -23,6 +24,7 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" @@ -31,6 +33,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-log/tflog" ) @@ -77,6 +80,7 @@ type CachedImageResourceModel struct { WorkspaceFolder types.String `tfsdk:"workspace_folder"` // Computed "outputs". Env types.List `tfsdk:"env"` + EnvMap types.Map `tfsdk:"env_map"` Exists types.Bool `tfsdk:"exists"` ID types.String `tfsdk:"id"` Image types.String `tfsdk:"image"` @@ -226,9 +230,8 @@ func (r *CachedImageResource) Schema(ctx context.Context, req resource.SchemaReq }, // Computed "outputs". - // TODO(mafredri): Map vs List? Support both? "env": schema.ListAttribute{ - MarkdownDescription: "Computed envbuilder configuration to be set for the container. May contain secrets.", + MarkdownDescription: "Computed envbuilder configuration to be set for the container in the form of a list of strings of `key=value`. May contain secrets.", ElementType: types.StringType, Computed: true, Sensitive: true, @@ -236,6 +239,15 @@ func (r *CachedImageResource) Schema(ctx context.Context, req resource.SchemaReq listplanmodifier.RequiresReplace(), }, }, + "env_map": schema.MapAttribute{ + MarkdownDescription: "Computed envbuilder configuration to be set for the container in the form of a key-value map. May contain secrets.", + ElementType: types.StringType, + Computed: true, + Sensitive: true, + PlanModifiers: []planmodifier.Map{ + mapplanmodifier.RequiresReplace(), + }, + }, "exists": schema.BoolAttribute{ MarkdownDescription: "Whether the cached image was exists or not for the given config.", Computed: true, @@ -338,28 +350,36 @@ func (r *CachedImageResource) Read(ctx context.Context, req resource.ReadRequest data.Exists = types.BoolValue(true) // Set the expected environment variables. + env := make(map[string]string) for key, elem := range data.ExtraEnv.Elements() { - data.Env = appendKnownEnvToList(data.Env, key, elem) + env[key] = tfValueToString(elem) } - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_CACHE_REPO", data.CacheRepo) - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_GIT_URL", data.GitURL) + env["ENVBUILDER_CACHE_REPO"] = tfValueToString(data.CacheRepo) + env["ENVBUILDER_GIT_URL"] = tfValueToString(data.GitURL) + if !data.CacheTTLDays.IsNull() { - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_CACHE_TTL_DAYS", data.CacheTTLDays) + env["ENVBUILDER_CACHE_TTL_DAYS"] = tfValueToString(data.CacheTTLDays) } if !data.GitUsername.IsNull() { - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_GIT_USERNAME", data.GitUsername) + env["ENVBUILDER_GIT_USERNAME"] = tfValueToString(data.GitUsername) } if !data.GitPassword.IsNull() { - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_GIT_PASSWORD", data.GitPassword) + env["ENVBUILDER_GIT_PASSWORD"] = tfValueToString(data.GitPassword) } // Default to remote build mode. if data.RemoteRepoBuildMode.IsNull() { - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_REMOTE_REPO_BUILD_MODE", types.BoolValue(true)) + env["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = "true" } else { - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_REMOTE_REPO_BUILD_MODE", data.RemoteRepoBuildMode) + env["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = tfValueToString(data.RemoteRepoBuildMode) } + var diag diag.Diagnostics + data.EnvMap, diag = basetypes.NewMapValueFrom(ctx, types.StringType, env) + resp.Diagnostics.Append(diag...) + data.Env, diag = basetypes.NewListValueFrom(ctx, types.StringType, sortedKeyValues(env)) + resp.Diagnostics.Append(diag...) + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) } @@ -396,29 +416,36 @@ func (r *CachedImageResource) Create(ctx context.Context, req resource.CreateReq data.ID = types.StringValue(digest.String()) } // Compute the env attribute from the config map. - // TODO(mafredri): Convert any other relevant attributes given via schema. + env := make(map[string]string) for key, elem := range data.ExtraEnv.Elements() { - data.Env = appendKnownEnvToList(data.Env, key, elem) + env[key] = tfValueToString(elem) } - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_CACHE_REPO", data.CacheRepo) - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_GIT_URL", data.GitURL) + env["ENVBUILDER_CACHE_REPO"] = tfValueToString(data.CacheRepo) + env["ENVBUILDER_GIT_URL"] = tfValueToString(data.GitURL) + if !data.CacheTTLDays.IsNull() { - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_CACHE_TTL_DAYS", data.CacheTTLDays) + env["ENVBUILDER_CACHE_TTL_DAYS"] = tfValueToString(data.CacheTTLDays) } if !data.GitUsername.IsNull() { - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_GIT_USERNAME", data.GitUsername) + env["ENVBUILDER_GIT_USERNAME"] = tfValueToString(data.GitUsername) } if !data.GitPassword.IsNull() { - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_GIT_PASSWORD", data.GitPassword) + env["ENVBUILDER_GIT_PASSWORD"] = tfValueToString(data.GitPassword) } // Default to remote build mode. if data.RemoteRepoBuildMode.IsNull() { - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_REMOTE_REPO_BUILD_MODE", types.BoolValue(true)) + env["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = "true" } else { - data.Env = appendKnownEnvToList(data.Env, "ENVBUILDER_REMOTE_REPO_BUILD_MODE", data.RemoteRepoBuildMode) + env["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = tfValueToString(data.RemoteRepoBuildMode) } + var diag diag.Diagnostics + data.EnvMap, diag = basetypes.NewMapValueFrom(ctx, types.StringType, env) + resp.Diagnostics.Append(diag...) + data.Env, diag = basetypes.NewListValueFrom(ctx, types.StringType, sortedKeyValues(env)) + resp.Diagnostics.Append(diag...) + // Save data into Terraform state resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) } @@ -652,19 +679,8 @@ func tfValueToString(val attr.Value) string { panic(fmt.Errorf("tfValueToString: value %T is not a supported type", val)) } -func appendKnownEnvToList(list types.List, key string, value attr.Value) types.List { - if value.IsUnknown() || value.IsNull() { - return list - } - var sb strings.Builder - _, _ = sb.WriteString(key) - _, _ = sb.WriteRune('=') - _, _ = sb.WriteString(tfValueToString(value)) - elem := types.StringValue(sb.String()) - list, _ = types.ListValue(types.StringType, append(list.Elements(), elem)) - return list -} - +// tfListToStringSlice converts a types.List to a []string by calling +// tfValueToString on each element. func tfListToStringSlice(l types.List) []string { var ss []string for _, el := range l.Elements() { @@ -692,3 +708,19 @@ func tfLogFunc(ctx context.Context) eblog.Func { logFn(ctx, fmt.Sprintf(format, args...)) } } + +// sortedKeyValues returns the keys and values of the map in the form "key=value" +// sorted by key in lexicographical order. +func sortedKeyValues(m map[string]string) []string { + pairs := make([]string, 0, len(m)) + var sb strings.Builder + for k := range m { + _, _ = sb.WriteString(k) + _, _ = sb.WriteRune('=') + _, _ = sb.WriteString(m[k]) + pairs = append(pairs, sb.String()) + sb.Reset() + } + sort.Strings(pairs) + return pairs +} diff --git a/internal/provider/cached_image_resource_test.go b/internal/provider/cached_image_resource_test.go index 5eeddfa..929c7b0 100644 --- a/internal/provider/cached_image_resource_test.go +++ b/internal/provider/cached_image_resource_test.go @@ -24,12 +24,18 @@ func TestAccCachedImageResource(t *testing.T) { files map[string]string }{ { + // This test case is the simplest possible case: a devcontainer.json. + // However, it also makes sure we are able to generate a Dockerfile + // from the devcontainer.json. name: "devcontainer only", files: map[string]string{ ".devcontainer/devcontainer.json": `{"image": "localhost:5000/test-ubuntu:latest"}`, }, }, { + // This test case includes a Dockerfile in addition to the devcontainer.json. + // The Dockerfile writes the current date to a file. This is currently not checked but + // illustrates that a RUN instruction is cached. name: "devcontainer and Dockerfile", files: map[string]string{ ".devcontainer/devcontainer.json": `{"build": { "dockerfile": "Dockerfile" }}`, @@ -46,20 +52,19 @@ RUN date > /date.txt`, resource.Test(t, resource.TestCase{ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, Steps: []resource.TestStep{ - // Initial state: cache has not been seeded. + // 1) Initial state: cache has not been seeded. { Config: deps.Config(t), PlanOnly: true, ExpectNonEmptyPlan: true, }, - // Should detect that no cached image is present and plan to create the resource. + // 2) Should detect that no cached image is present and plan to create the resource. { Config: deps.Config(t), Check: resource.ComposeAggregateTestCheckFunc( // Computed values MUST be present. resource.TestCheckResourceAttr("envbuilder_cached_image.test", "id", uuid.Nil.String()), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "exists", "false"), - resource.TestCheckResourceAttrSet("envbuilder_cached_image.test", "env.0"), // Cached image should be set to the builder image. resource.TestCheckResourceAttr("envbuilder_cached_image.test", "image", deps.BuilderImage), // Inputs should still be present. @@ -70,17 +75,18 @@ RUN date > /date.txt`, resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_password"), resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "cache_ttl_days"), + // Environment variables + assertEnv(t, deps), ), ExpectNonEmptyPlan: true, // TODO: check the plan. }, - // Re-running plan should have the same effect. + // 3) Re-running plan should have the same effect. { Config: deps.Config(t), Check: resource.ComposeAggregateTestCheckFunc( // Computed values MUST be present. resource.TestCheckResourceAttr("envbuilder_cached_image.test", "id", uuid.Nil.String()), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "exists", "false"), - resource.TestCheckResourceAttrSet("envbuilder_cached_image.test", "env.0"), // Cached image should be set to the builder image. resource.TestCheckResourceAttr("envbuilder_cached_image.test", "image", deps.BuilderImage), // Inputs should still be present. @@ -91,10 +97,12 @@ RUN date > /date.txt`, resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_password"), resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "cache_ttl_days"), + // Environment variables + assertEnv(t, deps), ), ExpectNonEmptyPlan: true, // TODO: check the plan. }, - // Now, seed the cache and re-run. We should now successfully create the cached image resource. + // 4) Now, seed the cache and re-run. We should now successfully create the cached image resource. { PreConfig: func() { seedCache(ctx, t, deps) @@ -114,19 +122,16 @@ RUN date > /date.txt`, resource.TestCheckResourceAttr("envbuilder_cached_image.test", "exists", "true"), resource.TestCheckResourceAttrSet("envbuilder_cached_image.test", "image"), resource.TestCheckResourceAttrWith("envbuilder_cached_image.test", "image", quotedPrefix(deps.CacheRepo)), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.0", "FOO=bar\nbaz"), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.1", fmt.Sprintf("ENVBUILDER_CACHE_REPO=%s", deps.CacheRepo)), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.2", fmt.Sprintf("ENVBUILDER_GIT_URL=%s", deps.Repo.URL)), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.3", "ENVBUILDER_REMOTE_REPO_BUILD_MODE=true"), - resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "env.4"), + // Environment variables + assertEnv(t, deps), ), }, - // Should produce an empty plan after apply + // 5) Should produce an empty plan after apply { Config: deps.Config(t), PlanOnly: true, }, - // Ensure idempotence in this state! + // 6) Ensure idempotence in this state! { Config: deps.Config(t), PlanOnly: true, @@ -136,3 +141,24 @@ RUN date > /date.txt`, }) } } + +// assertEnv is a test helper that checks the environment variables set on the +// cached image resource based on the provided test dependencies. +func assertEnv(t *testing.T, deps testDependencies) resource.TestCheckFunc { + t.Helper() + return resource.ComposeAggregateTestCheckFunc( + // Check that the environment variables are set correctly. + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.0", fmt.Sprintf("ENVBUILDER_CACHE_REPO=%s", deps.CacheRepo)), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.1", fmt.Sprintf("ENVBUILDER_GIT_URL=%s", deps.Repo.URL)), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.2", "ENVBUILDER_REMOTE_REPO_BUILD_MODE=true"), + // Check that the extra environment variables are set correctly. + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.3", "FOO=bar\nbaz"), + // We should not have any other environment variables set. + resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "env.4"), + // Check that the same values are set in env_map. + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.FOO", "bar\nbaz"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.ENVBUILDER_CACHE_REPO", deps.CacheRepo), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.ENVBUILDER_GIT_URL", deps.Repo.URL), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true"), + ) +} From cd1599f79d0417d3dc09ac16616e7d727cdb6ffe Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Fri, 16 Aug 2024 14:55:46 +0100 Subject: [PATCH 11/40] fix(internal/provider): set all supported envbuilder options (#38) * fix(internal/provider): set all supported envbuilder options * do not allow overriding git_url and cache_repo --- internal/provider/cached_image_resource.go | 193 ++++++++++++------ .../provider/cached_image_resource_test.go | 17 +- 2 files changed, 146 insertions(+), 64 deletions(-) diff --git a/internal/provider/cached_image_resource.go b/internal/provider/cached_image_resource.go index 4ea28b8..dbd5500 100644 --- a/internal/provider/cached_image_resource.go +++ b/internal/provider/cached_image_resource.go @@ -25,6 +25,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" @@ -160,7 +161,6 @@ func (r *CachedImageResource) Schema(ctx context.Context, req resource.SchemaReq MarkdownDescription: "(Envbuilder option) Terminates 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.", Optional: true, }, - // TODO(mafredri): Map vs List? Support both? "extra_env": schema.MapAttribute{ MarkdownDescription: "Extra environment variables to set for the container. This may include envbuilder options.", ElementType: types.StringType, @@ -293,6 +293,135 @@ func (r *CachedImageResource) Configure(ctx context.Context, req resource.Config r.client = client } +// setComputedEnv sets data.Env and data.EnvMap based on the values of the +// other fields in the model. +func (data *CachedImageResourceModel) setComputedEnv(ctx context.Context) diag.Diagnostics { + env := make(map[string]string) + + env["ENVBUILDER_CACHE_REPO"] = tfValueToString(data.CacheRepo) + env["ENVBUILDER_GIT_URL"] = tfValueToString(data.GitURL) + + if !data.BaseImageCacheDir.IsNull() { + env["ENVBUILDER_BASE_IMAGE_CACHE_DIR"] = tfValueToString(data.BaseImageCacheDir) + } + + if !data.BuildContextPath.IsNull() { + env["ENVBUILDER_BUILD_CONTEXT_PATH"] = tfValueToString(data.BuildContextPath) + } + + if !data.CacheTTLDays.IsNull() { + env["ENVBUILDER_CACHE_TTL_DAYS"] = tfValueToString(data.CacheTTLDays) + } + + if !data.DevcontainerDir.IsNull() { + env["ENVBUILDER_DEVCONTAINER_DIR"] = tfValueToString(data.DevcontainerDir) + } + + if !data.DevcontainerJSONPath.IsNull() { + env["ENVBUILDER_DEVCONTAINER_JSON_PATH"] = tfValueToString(data.DevcontainerJSONPath) + } + + if !data.DockerfilePath.IsNull() { + env["ENVBUILDER_DOCKERFILE_PATH"] = tfValueToString(data.DockerfilePath) + } + + if !data.DockerConfigBase64.IsNull() { + env["ENVBUILDER_DOCKER_CONFIG_BASE64"] = tfValueToString(data.DockerConfigBase64) + } + + if !data.ExitOnBuildFailure.IsNull() { + env["ENVBUILDER_EXIT_ON_BUILD_FAILURE"] = tfValueToString(data.ExitOnBuildFailure) + } + + if !data.FallbackImage.IsNull() { + env["ENVBUILDER_FALLBACK_IMAGE"] = tfValueToString(data.FallbackImage) + } + + if !data.GitCloneDepth.IsNull() { + env["ENVBUILDER_GIT_CLONE_DEPTH"] = tfValueToString(data.GitCloneDepth) + } + + if !data.GitCloneSingleBranch.IsNull() { + env["ENVBUILDER_GIT_CLONE_SINGLE_BRANCH"] = tfValueToString(data.GitCloneSingleBranch) + } + + if !data.GitHTTPProxyURL.IsNull() { + env["ENVBUILDER_GIT_HTTP_PROXY_URL"] = tfValueToString(data.GitHTTPProxyURL) + } + + if !data.GitSSHPrivateKeyPath.IsNull() { + env["ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH"] = tfValueToString(data.GitSSHPrivateKeyPath) + } + + if !data.GitUsername.IsNull() { + env["ENVBUILDER_GIT_USERNAME"] = tfValueToString(data.GitUsername) + } + + if !data.GitPassword.IsNull() { + env["ENVBUILDER_GIT_PASSWORD"] = tfValueToString(data.GitPassword) + } + + if !data.IgnorePaths.IsNull() { + env["ENVBUILDER_IGNORE_PATHS"] = strings.Join(tfListToStringSlice(data.IgnorePaths), ",") + } + + if !data.Insecure.IsNull() { + env["ENVBUILDER_INSECURE"] = tfValueToString(data.Insecure) + } + + // Default to remote build mode. + if data.RemoteRepoBuildMode.IsNull() { + env["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = "true" + } else { + env["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = tfValueToString(data.RemoteRepoBuildMode) + } + + if !data.SSLCertBase64.IsNull() { + env["ENVBUILDER_SSL_CERT_BASE64"] = tfValueToString(data.SSLCertBase64) + } + + if !data.Verbose.IsNull() { + env["ENVBUILDER_VERBOSE"] = tfValueToString(data.Verbose) + } + + if !data.WorkspaceFolder.IsNull() { + env["ENVBUILDER_WORKSPACE_FOLDER"] = tfValueToString(data.WorkspaceFolder) + } + + // Do ExtraEnv last so that it can override any other values. + // With one exception: ENVBUILDER_CACHE_REPO and ENVBUILDER_GIT_URL are required and should not be overridden. + // Other values set by the provider may be overridden, but will generate a warning. + var diag, ds diag.Diagnostics + if !data.ExtraEnv.IsNull() { + for key, elem := range data.ExtraEnv.Elements() { + switch key { + // These are required and should not be overridden. + case "ENVBUILDER_CACHE_REPO", "ENVBUILDER_GIT_URL": + diag.AddAttributeWarning(path.Root("extra_env"), + "Cannot override required environment variable", + fmt.Sprintf("The key %q in extra_env cannot be overridden.", key), + ) + default: + if _, ok := env[key]; ok { + // This is a warning because it's possible that the user wants to override + // a value set by the provider. + diag.AddAttributeWarning(path.Root("extra_env"), + "Overriding provider environment variable", + fmt.Sprintf("The key %q in extra_env overrides an environment variable set by the provider.", key), + ) + } + env[key] = tfValueToString(elem) + } + } + } + + data.EnvMap, ds = basetypes.NewMapValueFrom(ctx, types.StringType, env) + diag = append(diag, ds...) + data.Env, ds = basetypes.NewListValueFrom(ctx, types.StringType, sortedKeyValues(env)) + diag = append(diag, ds...) + return diag +} + func (r *CachedImageResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { var data CachedImageResourceModel @@ -350,35 +479,7 @@ func (r *CachedImageResource) Read(ctx context.Context, req resource.ReadRequest data.Exists = types.BoolValue(true) // Set the expected environment variables. - env := make(map[string]string) - for key, elem := range data.ExtraEnv.Elements() { - env[key] = tfValueToString(elem) - } - - env["ENVBUILDER_CACHE_REPO"] = tfValueToString(data.CacheRepo) - env["ENVBUILDER_GIT_URL"] = tfValueToString(data.GitURL) - - if !data.CacheTTLDays.IsNull() { - env["ENVBUILDER_CACHE_TTL_DAYS"] = tfValueToString(data.CacheTTLDays) - } - if !data.GitUsername.IsNull() { - env["ENVBUILDER_GIT_USERNAME"] = tfValueToString(data.GitUsername) - } - if !data.GitPassword.IsNull() { - env["ENVBUILDER_GIT_PASSWORD"] = tfValueToString(data.GitPassword) - } - // Default to remote build mode. - if data.RemoteRepoBuildMode.IsNull() { - env["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = "true" - } else { - env["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = tfValueToString(data.RemoteRepoBuildMode) - } - - var diag diag.Diagnostics - data.EnvMap, diag = basetypes.NewMapValueFrom(ctx, types.StringType, env) - resp.Diagnostics.Append(diag...) - data.Env, diag = basetypes.NewListValueFrom(ctx, types.StringType, sortedKeyValues(env)) - resp.Diagnostics.Append(diag...) + resp.Diagnostics.Append(data.setComputedEnv(ctx)...) resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) } @@ -415,36 +516,9 @@ func (r *CachedImageResource) Create(ctx context.Context, req resource.CreateReq data.Image = types.StringValue(fmt.Sprintf("%s@%s", data.CacheRepo.ValueString(), digest)) data.ID = types.StringValue(digest.String()) } - // Compute the env attribute from the config map. - env := make(map[string]string) - for key, elem := range data.ExtraEnv.Elements() { - env[key] = tfValueToString(elem) - } - env["ENVBUILDER_CACHE_REPO"] = tfValueToString(data.CacheRepo) - env["ENVBUILDER_GIT_URL"] = tfValueToString(data.GitURL) - - if !data.CacheTTLDays.IsNull() { - env["ENVBUILDER_CACHE_TTL_DAYS"] = tfValueToString(data.CacheTTLDays) - } - if !data.GitUsername.IsNull() { - env["ENVBUILDER_GIT_USERNAME"] = tfValueToString(data.GitUsername) - } - if !data.GitPassword.IsNull() { - env["ENVBUILDER_GIT_PASSWORD"] = tfValueToString(data.GitPassword) - } - // Default to remote build mode. - if data.RemoteRepoBuildMode.IsNull() { - env["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = "true" - } else { - env["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = tfValueToString(data.RemoteRepoBuildMode) - } - - var diag diag.Diagnostics - data.EnvMap, diag = basetypes.NewMapValueFrom(ctx, types.StringType, env) - resp.Diagnostics.Append(diag...) - data.Env, diag = basetypes.NewListValueFrom(ctx, types.StringType, sortedKeyValues(env)) - resp.Diagnostics.Append(diag...) + // Set the expected environment variables. + resp.Diagnostics.Append(data.setComputedEnv(ctx)...) // Save data into Terraform state resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) @@ -556,6 +630,7 @@ func (r *CachedImageResource) runCacheProbe(ctx context.Context, data CachedImag Insecure: data.Insecure.ValueBool(), // might have internal CAs? IgnorePaths: tfListToStringSlice(data.IgnorePaths), // may need to be specified? // The below options are not relevant and are set to their zero value explicitly. + // They must be set by extra_env. CoderAgentSubsystem: nil, CoderAgentToken: "", CoderAgentURL: "", diff --git a/internal/provider/cached_image_resource_test.go b/internal/provider/cached_image_resource_test.go index 929c7b0..c4f3f9a 100644 --- a/internal/provider/cached_image_resource_test.go +++ b/internal/provider/cached_image_resource_test.go @@ -48,6 +48,8 @@ RUN date > /date.txt`, //nolint: paralleltest deps := setup(ctx, t, tc.files) deps.ExtraEnv["FOO"] = testEnvValue + deps.ExtraEnv["ENVBUILDER_GIT_URL"] = "https://not.the.real.git/url" + deps.ExtraEnv["ENVBUILDER_CACHE_REPO"] = "not-the-real-cache-repo" resource.Test(t, resource.TestCase{ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, @@ -149,16 +151,21 @@ func assertEnv(t *testing.T, deps testDependencies) resource.TestCheckFunc { return resource.ComposeAggregateTestCheckFunc( // Check that the environment variables are set correctly. resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.0", fmt.Sprintf("ENVBUILDER_CACHE_REPO=%s", deps.CacheRepo)), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.1", fmt.Sprintf("ENVBUILDER_GIT_URL=%s", deps.Repo.URL)), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.2", "ENVBUILDER_REMOTE_REPO_BUILD_MODE=true"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.1", fmt.Sprintf("ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH=%s", deps.Repo.Key)), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.2", fmt.Sprintf("ENVBUILDER_GIT_URL=%s", deps.Repo.URL)), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.3", "ENVBUILDER_REMOTE_REPO_BUILD_MODE=true"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.4", "ENVBUILDER_VERBOSE=true"), // Check that the extra environment variables are set correctly. - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.3", "FOO=bar\nbaz"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.5", "FOO=bar\nbaz"), // We should not have any other environment variables set. - resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "env.4"), + resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "env.6"), + // Check that the same values are set in env_map. - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.FOO", "bar\nbaz"), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.ENVBUILDER_CACHE_REPO", deps.CacheRepo), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.ENVBUILDER_GIT_URL", deps.Repo.URL), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.ENVBUILDER_VERBOSE", "true"), + resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.FOO", "bar\nbaz"), ) } From d6192fcd1153cacf39ba26c9a72cab1ea1fd6f27 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Wed, 21 Aug 2024 10:10:58 +0100 Subject: [PATCH 12/40] chore(docs): add provider schema (#39) --- docs/index.md | 6 ++++-- internal/provider/provider.go | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 8148773..8bedaaa 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,12 +3,14 @@ page_title: "envbuilder Provider" subcategory: "" description: |- - + The Envbuilder provider can be used to check for the presence of a container image previously built by Envbuilder https://github.com/coder/envbuilder. + This allows re-using a previously built image pushed to a container registry without having to rebuild it. --- # envbuilder Provider - +The Envbuilder provider can be used to check for the presence of a container image previously built by [Envbuilder](https://github.com/coder/envbuilder). +This allows re-using a previously built image pushed to a container registry without having to rebuild it. ## Example Usage diff --git a/internal/provider/provider.go b/internal/provider/provider.go index d444c23..cfc0c61 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -36,6 +36,9 @@ func (p *EnvbuilderProvider) Metadata(ctx context.Context, req provider.Metadata func (p *EnvbuilderProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) { resp.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{}, + MarkdownDescription: ` +The Envbuilder provider can be used to check for the presence of a container image previously built by [Envbuilder](https://github.com/coder/envbuilder). +This allows re-using a previously built image pushed to a container registry without having to rebuild it.`, } } From 11c4b3b088c55c29ef3b17fe2297077d37b08153 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 12:01:54 +0100 Subject: [PATCH 13/40] chore(deps): bump hashicorp/setup-terraform from 3.1.1 to 3.1.2 (#40) Bumps [hashicorp/setup-terraform](https://github.com/hashicorp/setup-terraform) from 3.1.1 to 3.1.2. - [Release notes](https://github.com/hashicorp/setup-terraform/releases) - [Changelog](https://github.com/hashicorp/setup-terraform/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/setup-terraform/compare/651471c36a6092792c552e8b1bef71e592b462d8...b9cd54a3c349d3f38e8881555d616ced269862dd) --- updated-dependencies: - dependency-name: hashicorp/setup-terraform dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 39c50f2..66b5a40 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -70,7 +70,7 @@ jobs: with: go-version-file: "go.mod" cache: true - - uses: hashicorp/setup-terraform@651471c36a6092792c552e8b1bef71e592b462d8 # v3.1.1 + - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 with: terraform_version: ${{ matrix.terraform }} terraform_wrapper: false From e35030b39f66396533035af0f543a6ca448d726b Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Fri, 30 Aug 2024 17:26:01 +0100 Subject: [PATCH 14/40] chore: update envbuilder to include multi-stage cache probe fix (#41) --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 671c8f6..923e81f 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa55 require ( github.com/GoogleContainerTools/kaniko v1.9.2 - github.com/coder/envbuilder v1.0.0-rc.5.0.20240815142547-cd63d0b71a40 + github.com/coder/envbuilder v1.0.0-rc.0.0.20240830145058-fb7e689f39ed github.com/docker/docker v26.1.5+incompatible github.com/gliderlabs/ssh v0.3.7 github.com/go-git/go-billy/v5 v5.5.0 @@ -119,7 +119,7 @@ require ( github.com/dimchansky/utfbom v1.1.1 // indirect github.com/distribution/distribution/v3 v3.0.0-alpha.1 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/cli v27.1.1+incompatible // indirect + github.com/docker/cli v27.2.0+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/docker/go-connections v0.5.0 // indirect diff --git a/go.sum b/go.sum index a52cab3..fd61f13 100644 --- a/go.sum +++ b/go.sum @@ -186,8 +186,8 @@ github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoC github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/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/envbuilder v1.0.0-rc.5.0.20240815142547-cd63d0b71a40 h1:XxZpRd+bjCAZJJHCFBVsbIrYZSYcnZBm0kp/FgfZg0o= -github.com/coder/envbuilder v1.0.0-rc.5.0.20240815142547-cd63d0b71a40/go.mod h1:m7kjZGXpP8jAZgKwfBaMbXe0bg29ERZP3g4PMpQLR4k= +github.com/coder/envbuilder v1.0.0-rc.0.0.20240830145058-fb7e689f39ed h1:sDEjs9qB2uJ7O85vGmzMja99IZuLvesxElOUFyy22UY= +github.com/coder/envbuilder v1.0.0-rc.0.0.20240830145058-fb7e689f39ed/go.mod h1:LWImvtIWaX3eiAI3zyU46WE/PrE099nCut1zJultSk0= github.com/coder/kaniko v0.0.0-20240807142221-ffc5e60fca41 h1:1Ye7AcLnuT5IDv6il7Fxo+aqpzlWfedkpraCCwx8Lyo= github.com/coder/kaniko v0.0.0-20240807142221-ffc5e60fca41/go.mod h1:YMK7BlxerzLlMwihGxNWUaFoN9LXCij4P+w/8/fNlcM= github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs= @@ -252,8 +252,8 @@ 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.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE= -github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +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/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= From 23f2cf5f48b4cc9ecc379bccacb197c0f6f0f8f5 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Wed, 4 Sep 2024 11:19:25 +0100 Subject: [PATCH 15/40] fix(internal/provider): correctly override from extra_env (#44) Relates to #43 Our previous logic did not pass options from extra_env to envbuilder.RunCacheProbe. This fixes the logic and adds more comprehensive tests around the overriding logic. Future commits will refactor this logic some more. --- internal/provider/cached_image_resource.go | 367 ++++++++++++------ .../provider/cached_image_resource_test.go | 134 +++++-- internal/provider/provider_internal_test.go | 359 +++++++++++++++++ internal/provider/provider_test.go | 48 ++- 4 files changed, 741 insertions(+), 167 deletions(-) create mode 100644 internal/provider/provider_internal_test.go diff --git a/internal/provider/cached_image_resource.go b/internal/provider/cached_image_resource.go index dbd5500..c3f9378 100644 --- a/internal/provider/cached_image_resource.go +++ b/internal/provider/cached_image_resource.go @@ -16,12 +16,14 @@ import ( "github.com/coder/envbuilder/constants" eblog "github.com/coder/envbuilder/log" eboptions "github.com/coder/envbuilder/options" + "github.com/coder/serpent" "github.com/go-git/go-billy/v5/osfs" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/uuid" + "github.com/spf13/pflag" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -293,128 +295,246 @@ func (r *CachedImageResource) Configure(ctx context.Context, req resource.Config r.client = client } -// setComputedEnv sets data.Env and data.EnvMap based on the values of the -// other fields in the model. -func (data *CachedImageResourceModel) setComputedEnv(ctx context.Context) diag.Diagnostics { - env := make(map[string]string) +func optionsFromDataModel(data CachedImageResourceModel) (eboptions.Options, diag.Diagnostics) { + var diags diag.Diagnostics + var opts eboptions.Options - env["ENVBUILDER_CACHE_REPO"] = tfValueToString(data.CacheRepo) - env["ENVBUILDER_GIT_URL"] = tfValueToString(data.GitURL) + // Required options. Cannot be overridden by extra_env. + opts.CacheRepo = data.CacheRepo.ValueString() + opts.GitURL = data.GitURL.ValueString() + + // Other options can be overridden by extra_env, with a warning. + // Keep track of which options are overridden. + overrides := make(map[string]struct{}) if !data.BaseImageCacheDir.IsNull() { - env["ENVBUILDER_BASE_IMAGE_CACHE_DIR"] = tfValueToString(data.BaseImageCacheDir) + overrides["ENVBUILDER_BASE_IMAGE_CACHE_DIR"] = struct{}{} + opts.BaseImageCacheDir = data.BaseImageCacheDir.ValueString() } if !data.BuildContextPath.IsNull() { - env["ENVBUILDER_BUILD_CONTEXT_PATH"] = tfValueToString(data.BuildContextPath) + overrides["ENVBUILDER_BUILD_CONTEXT_PATH"] = struct{}{} + opts.BuildContextPath = data.BuildContextPath.ValueString() } if !data.CacheTTLDays.IsNull() { - env["ENVBUILDER_CACHE_TTL_DAYS"] = tfValueToString(data.CacheTTLDays) + overrides["ENVBUILDER_CACHE_TTL_DAYS"] = struct{}{} + opts.CacheTTLDays = data.CacheTTLDays.ValueInt64() } if !data.DevcontainerDir.IsNull() { - env["ENVBUILDER_DEVCONTAINER_DIR"] = tfValueToString(data.DevcontainerDir) + overrides["ENVBUILDER_DEVCONTAINER_DIR"] = struct{}{} + opts.DevcontainerDir = data.DevcontainerDir.ValueString() } if !data.DevcontainerJSONPath.IsNull() { - env["ENVBUILDER_DEVCONTAINER_JSON_PATH"] = tfValueToString(data.DevcontainerJSONPath) + overrides["ENVBUILDER_DEVCONTAINER_JSON_PATH"] = struct{}{} + opts.DevcontainerJSONPath = data.DevcontainerJSONPath.ValueString() } if !data.DockerfilePath.IsNull() { - env["ENVBUILDER_DOCKERFILE_PATH"] = tfValueToString(data.DockerfilePath) + overrides["ENVBUILDER_DOCKERFILE_PATH"] = struct{}{} + opts.DockerfilePath = data.DockerfilePath.ValueString() } if !data.DockerConfigBase64.IsNull() { - env["ENVBUILDER_DOCKER_CONFIG_BASE64"] = tfValueToString(data.DockerConfigBase64) + overrides["ENVBUILDER_DOCKER_CONFIG_BASE64"] = struct{}{} + opts.DockerConfigBase64 = data.DockerConfigBase64.ValueString() } if !data.ExitOnBuildFailure.IsNull() { - env["ENVBUILDER_EXIT_ON_BUILD_FAILURE"] = tfValueToString(data.ExitOnBuildFailure) + overrides["ENVBUILDER_EXIT_ON_BUILD_FAILURE"] = struct{}{} + opts.ExitOnBuildFailure = data.ExitOnBuildFailure.ValueBool() } if !data.FallbackImage.IsNull() { - env["ENVBUILDER_FALLBACK_IMAGE"] = tfValueToString(data.FallbackImage) + overrides["ENVBUILDER_FALLBACK_IMAGE"] = struct{}{} + opts.FallbackImage = data.FallbackImage.ValueString() } if !data.GitCloneDepth.IsNull() { - env["ENVBUILDER_GIT_CLONE_DEPTH"] = tfValueToString(data.GitCloneDepth) + overrides["ENVBUILDER_GIT_CLONE_DEPTH"] = struct{}{} + opts.GitCloneDepth = data.GitCloneDepth.ValueInt64() } if !data.GitCloneSingleBranch.IsNull() { - env["ENVBUILDER_GIT_CLONE_SINGLE_BRANCH"] = tfValueToString(data.GitCloneSingleBranch) + overrides["ENVBUILDER_GIT_CLONE_SINGLE_BRANCH"] = struct{}{} + opts.GitCloneSingleBranch = data.GitCloneSingleBranch.ValueBool() } if !data.GitHTTPProxyURL.IsNull() { - env["ENVBUILDER_GIT_HTTP_PROXY_URL"] = tfValueToString(data.GitHTTPProxyURL) + overrides["ENVBUILDER_GIT_HTTP_PROXY_URL"] = struct{}{} + opts.GitHTTPProxyURL = data.GitHTTPProxyURL.ValueString() } if !data.GitSSHPrivateKeyPath.IsNull() { - env["ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH"] = tfValueToString(data.GitSSHPrivateKeyPath) + overrides["ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH"] = struct{}{} + opts.GitSSHPrivateKeyPath = data.GitSSHPrivateKeyPath.ValueString() } if !data.GitUsername.IsNull() { - env["ENVBUILDER_GIT_USERNAME"] = tfValueToString(data.GitUsername) + overrides["ENVBUILDER_GIT_USERNAME"] = struct{}{} + opts.GitUsername = data.GitUsername.ValueString() } if !data.GitPassword.IsNull() { - env["ENVBUILDER_GIT_PASSWORD"] = tfValueToString(data.GitPassword) + overrides["ENVBUILDER_GIT_PASSWORD"] = struct{}{} + opts.GitPassword = data.GitPassword.ValueString() } if !data.IgnorePaths.IsNull() { - env["ENVBUILDER_IGNORE_PATHS"] = strings.Join(tfListToStringSlice(data.IgnorePaths), ",") + overrides["ENVBUILDER_IGNORE_PATHS"] = struct{}{} + opts.IgnorePaths = tfListToStringSlice(data.IgnorePaths) } if !data.Insecure.IsNull() { - env["ENVBUILDER_INSECURE"] = tfValueToString(data.Insecure) + overrides["ENVBUILDER_INSECURE"] = struct{}{} + opts.Insecure = data.Insecure.ValueBool() } - // Default to remote build mode. if data.RemoteRepoBuildMode.IsNull() { - env["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = "true" + opts.RemoteRepoBuildMode = true } else { - env["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = tfValueToString(data.RemoteRepoBuildMode) + overrides["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = struct{}{} + opts.RemoteRepoBuildMode = data.RemoteRepoBuildMode.ValueBool() } if !data.SSLCertBase64.IsNull() { - env["ENVBUILDER_SSL_CERT_BASE64"] = tfValueToString(data.SSLCertBase64) + overrides["ENVBUILDER_SSL_CERT_BASE64"] = struct{}{} + opts.SSLCertBase64 = data.SSLCertBase64.ValueString() } if !data.Verbose.IsNull() { - env["ENVBUILDER_VERBOSE"] = tfValueToString(data.Verbose) + overrides["ENVBUILDER_VERBOSE"] = struct{}{} + opts.Verbose = data.Verbose.ValueBool() } if !data.WorkspaceFolder.IsNull() { - env["ENVBUILDER_WORKSPACE_FOLDER"] = tfValueToString(data.WorkspaceFolder) + overrides["ENVBUILDER_WORKSPACE_FOLDER"] = struct{}{} + opts.WorkspaceFolder = data.WorkspaceFolder.ValueString() } - // Do ExtraEnv last so that it can override any other values. - // With one exception: ENVBUILDER_CACHE_REPO and ENVBUILDER_GIT_URL are required and should not be overridden. - // Other values set by the provider may be overridden, but will generate a warning. - var diag, ds diag.Diagnostics - if !data.ExtraEnv.IsNull() { - for key, elem := range data.ExtraEnv.Elements() { - switch key { - // These are required and should not be overridden. - case "ENVBUILDER_CACHE_REPO", "ENVBUILDER_GIT_URL": - diag.AddAttributeWarning(path.Root("extra_env"), - "Cannot override required environment variable", - fmt.Sprintf("The key %q in extra_env cannot be overridden.", key), + // convert extraEnv to a map for ease of use. + extraEnv := make(map[string]string) + for k, v := range data.ExtraEnv.Elements() { + extraEnv[k] = tfValueToString(v) + } + diags = append(diags, overrideOptionsFromExtraEnv(&opts, extraEnv, overrides)...) + + return opts, diags +} + +func overrideOptionsFromExtraEnv(opts *eboptions.Options, extraEnv map[string]string, overrides map[string]struct{}) diag.Diagnostics { + var diags diag.Diagnostics + // Make a map of the options for easy lookup. + optsMap := make(map[string]pflag.Value) + for _, opt := range opts.CLI() { + optsMap[opt.Env] = opt.Value + } + for key, val := range extraEnv { + switch key { + + // These options may not be overridden. + case "ENVBUILDER_CACHE_REPO", "ENVBUILDER_GIT_URL": + diags.AddAttributeWarning(path.Root("extra_env"), + "Cannot override required environment variable", + fmt.Sprintf("The key %q in extra_env cannot be overridden.", key), + ) + continue + + default: + // Check if the option was set on the provider data model and generate a warning if so. + if _, overridden := overrides[key]; overridden { + diags.AddAttributeWarning(path.Root("extra_env"), + "Overriding provider environment variable", + fmt.Sprintf("The key %q in extra_env overrides an option set on the provider.", key), + ) + } + + // XXX: workaround for serpent behaviour where calling Set() on a + // string slice will append instead of replace: set to empty first. + if key == "ENVBUILDER_IGNORE_PATHS" { + _ = optsMap[key].Set("") + } + + opt, found := optsMap[key] + if !found { + // ignore unknown keys + continue + } + + if err := opt.Set(val); err != nil { + diags.AddAttributeError(path.Root("extra_env"), + "Invalid value for environment variable", + fmt.Sprintf("The key %q in extra_env has an invalid value: %s", key, err), ) - default: - if _, ok := env[key]; ok { - // This is a warning because it's possible that the user wants to override - // a value set by the provider. - diag.AddAttributeWarning(path.Root("extra_env"), - "Overriding provider environment variable", - fmt.Sprintf("The key %q in extra_env overrides an environment variable set by the provider.", key), - ) - } - env[key] = tfValueToString(elem) } } } + return diags +} + +func computeEnvFromOptions(opts eboptions.Options, extraEnv map[string]string) map[string]string { + allEnvKeys := make(map[string]struct{}) + for _, opt := range opts.CLI() { + if opt.Env == "" { + continue + } + allEnvKeys[opt.Env] = struct{}{} + } + + // Only set the environment variables from opts that are not legacy options. + // Legacy options are those that are not prefixed with ENVBUILDER_. + // While we can detect when a legacy option is set, overriding it becomes + // problematic. Erring on the side of caution, we will not override legacy options. + isEnvbuilderOption := func(key string) bool { + switch key { + case "CODER_AGENT_URL", "CODER_AGENT_TOKEN", "CODER_AGENT_SUBSYSTEM": + return true // kinda + default: + return strings.HasPrefix(key, "ENVBUILDER_") + } + } + + computed := make(map[string]string) + for _, opt := range opts.CLI() { + if opt.Env == "" { + continue + } + // TODO: remove this check once support for legacy options is removed. + if !isEnvbuilderOption(opt.Env) { + continue + } + var val string + if sa, ok := opt.Value.(*serpent.StringArray); ok { + val = strings.Join(sa.GetSlice(), ",") + } else { + val = opt.Value.String() + } + + switch val { + case "", "false", "0": + // Skip zero values. + continue + } + computed[opt.Env] = val + } + + // Merge in extraEnv, which may override values from opts. + // Skip any keys that are envbuilder options. + for key, val := range extraEnv { + if isEnvbuilderOption(key) { + continue + } + computed[key] = val + } + return computed +} +// setComputedEnv sets data.Env and data.EnvMap based on the values of the +// other fields in the model. +func (data *CachedImageResourceModel) setComputedEnv(ctx context.Context, env map[string]string) diag.Diagnostics { + var diag, ds diag.Diagnostics data.EnvMap, ds = basetypes.NewMapValueFrom(ctx, types.StringType, env) diag = append(diag, ds...) data.Env, ds = basetypes.NewListValueFrom(ctx, types.StringType, sortedKeyValues(env)) @@ -431,6 +551,16 @@ func (r *CachedImageResource) Read(ctx context.Context, req resource.ReadRequest return } + // Get the options from the data model. + opts, diags := optionsFromDataModel(data) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + // Set the expected environment variables. + computedEnv := computeEnvFromOptions(opts, tfMapToStringMap(data.ExtraEnv)) + resp.Diagnostics.Append(data.setComputedEnv(ctx, computedEnv)...) + // If the previous state is that Image == BuilderImage, then we previously did // not find the image. We will need to run another cache probe. if data.Image.Equal(data.BuilderImage) { @@ -478,9 +608,6 @@ func (r *CachedImageResource) Read(ctx context.Context, req resource.ReadRequest data.Image = types.StringValue(fmt.Sprintf("%s@%s", data.CacheRepo.ValueString(), digest)) data.Exists = types.BoolValue(true) - // Set the expected environment variables. - resp.Diagnostics.Append(data.setComputedEnv(ctx)...) - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) } @@ -494,7 +621,18 @@ func (r *CachedImageResource) Create(ctx context.Context, req resource.CreateReq return } - cachedImg, err := r.runCacheProbe(ctx, data) + // Get the options from the data model. + opts, diags := optionsFromDataModel(data) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + // Set the expected environment variables. + computedEnv := computeEnvFromOptions(opts, tfMapToStringMap(data.ExtraEnv)) + resp.Diagnostics.Append(data.setComputedEnv(ctx, computedEnv)...) + + cachedImg, err := runCacheProbe(ctx, data.BuilderImage.ValueString(), opts) data.ID = types.StringValue(uuid.Nil.String()) data.Exists = types.BoolValue(err == nil) if err != nil { @@ -517,9 +655,6 @@ func (r *CachedImageResource) Create(ctx context.Context, req resource.CreateReq data.ID = types.StringValue(digest.String()) } - // Set the expected environment variables. - resp.Diagnostics.Append(data.setComputedEnv(ctx)...) - // Save data into Terraform state resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) } @@ -553,7 +688,7 @@ func (r *CachedImageResource) Delete(ctx context.Context, req resource.DeleteReq // runCacheProbe performs a 'fake build' of the requested image and ensures that // all of the resulting layers of the image are present in the configured cache // repo. Otherwise, returns an error. -func (r *CachedImageResource) runCacheProbe(ctx context.Context, data CachedImageResourceModel) (v1.Image, error) { +func runCacheProbe(ctx context.Context, builderImage string, opts eboptions.Options) (v1.Image, error) { tmpDir, err := os.MkdirTemp(os.TempDir(), "envbuilder-provider-cached-image-data-source") if err != nil { return nil, fmt.Errorf("unable to create temp directory: %s", err.Error()) @@ -581,69 +716,53 @@ func (r *CachedImageResource) runCacheProbe(ctx context.Context, data CachedImag // In order to correctly reproduce the final layer of the cached image, we // need the envbuilder binary used to originally build the image! envbuilderPath := filepath.Join(tmpDir, "envbuilder") - if err := extractEnvbuilderFromImage(ctx, data.BuilderImage.ValueString(), envbuilderPath); err != nil { + if err := extractEnvbuilderFromImage(ctx, builderImage, envbuilderPath); err != nil { tflog.Error(ctx, "failed to fetch envbuilder binary from builder image", map[string]any{"err": err}) return nil, fmt.Errorf("failed to fetch the envbuilder binary from the builder image: %s", err.Error()) } - - workspaceFolder := data.WorkspaceFolder.ValueString() - if workspaceFolder == "" { - workspaceFolder = filepath.Join(tmpDir, "workspace") - tflog.Debug(ctx, "workspace_folder not specified, using temp dir", map[string]any{"workspace_folder": workspaceFolder}) - } - - opts := eboptions.Options{ - // These options are always required - CacheRepo: data.CacheRepo.ValueString(), - Filesystem: osfs.New("/"), - ForceSafe: false, // This should never be set to true, as this may be running outside of a container! - GetCachedImage: true, // always! - Logger: tfLogFunc(ctx), - Verbose: data.Verbose.ValueBool(), - WorkspaceFolder: workspaceFolder, - - // Options related to compiling the devcontainer - BuildContextPath: data.BuildContextPath.ValueString(), - DevcontainerDir: data.DevcontainerDir.ValueString(), - DevcontainerJSONPath: data.DevcontainerJSONPath.ValueString(), - DockerfilePath: data.DockerfilePath.ValueString(), - DockerConfigBase64: data.DockerConfigBase64.ValueString(), - FallbackImage: data.FallbackImage.ValueString(), - - // These options are required for cloning the Git repo - CacheTTLDays: data.CacheTTLDays.ValueInt64(), - GitURL: data.GitURL.ValueString(), - GitCloneDepth: data.GitCloneDepth.ValueInt64(), - GitCloneSingleBranch: data.GitCloneSingleBranch.ValueBool(), - GitUsername: data.GitUsername.ValueString(), - GitPassword: data.GitPassword.ValueString(), - GitSSHPrivateKeyPath: data.GitSSHPrivateKeyPath.ValueString(), - GitHTTPProxyURL: data.GitHTTPProxyURL.ValueString(), - RemoteRepoBuildMode: data.RemoteRepoBuildMode.ValueBool(), - RemoteRepoDir: filepath.Join(tmpDir, "repo"), - SSLCertBase64: data.SSLCertBase64.ValueString(), - - // Other options - BaseImageCacheDir: data.BaseImageCacheDir.ValueString(), - BinaryPath: envbuilderPath, // needed to reproduce the final layer. - ExitOnBuildFailure: data.ExitOnBuildFailure.ValueBool(), // may wish to do this instead of fallback image? - Insecure: data.Insecure.ValueBool(), // might have internal CAs? - IgnorePaths: tfListToStringSlice(data.IgnorePaths), // may need to be specified? - // The below options are not relevant and are set to their zero value explicitly. - // They must be set by extra_env. - CoderAgentSubsystem: nil, - CoderAgentToken: "", - CoderAgentURL: "", - ExportEnvFile: "", - InitArgs: "", - InitCommand: "", - InitScript: "", - LayerCacheDir: "", - PostStartScriptPath: "", - PushImage: false, // This is only relevant when building. - SetupScript: "", - SkipRebuild: false, - } + opts.BinaryPath = envbuilderPath + + // We need a filesystem to work with. + opts.Filesystem = osfs.New("/") + // This should never be set to true, as this may be running outside of a container! + opts.ForceSafe = false + // We always want to get the cached image. + opts.GetCachedImage = true + // Log to the Terraform logger. + opts.Logger = tfLogFunc(ctx) + + // We don't require users to set a workspace folder, but maybe there's a + // reason someone may need to. + if opts.WorkspaceFolder == "" { + opts.WorkspaceFolder = filepath.Join(tmpDir, "workspace") + if err := os.MkdirAll(opts.WorkspaceFolder, 0o755); err != nil { + return nil, fmt.Errorf("failed to create workspace folder: %w", err) + } + tflog.Debug(ctx, "workspace_folder not specified, using temp dir", map[string]any{"workspace_folder": opts.WorkspaceFolder}) + } + + // We need a place to clone the repo. + repoDir := filepath.Join(tmpDir, "repo") + if err := os.MkdirAll(repoDir, 0o755); err != nil { + return nil, fmt.Errorf("failed to create repo dir: %w", err) + } + opts.RemoteRepoDir = repoDir + + // The below options are not relevant and are set to their zero value + // explicitly. + // They must be set by extra_env to be used in the final builder image. + opts.CoderAgentSubsystem = nil + opts.CoderAgentToken = "" + opts.CoderAgentURL = "" + opts.ExportEnvFile = "" + opts.InitArgs = "" + opts.InitCommand = "" + opts.InitScript = "" + opts.LayerCacheDir = "" + opts.PostStartScriptPath = "" + opts.PushImage = false + opts.SetupScript = "" + opts.SkipRebuild = false return envbuilder.RunCacheProbe(ctx, opts) } @@ -764,6 +883,16 @@ func tfListToStringSlice(l types.List) []string { return ss } +// tfMapToStringMap converts a types.Map to a map[string]string by calling +// tfValueToString on each element. +func tfMapToStringMap(m types.Map) map[string]string { + res := make(map[string]string) + for k, v := range m.Elements() { + res[k] = tfValueToString(v) + } + return res +} + // tfLogFunc is an adapter to envbuilder/log.Func. func tfLogFunc(ctx context.Context) eblog.Func { return func(level eblog.Level, format string, args ...any) { diff --git a/internal/provider/cached_image_resource_test.go b/internal/provider/cached_image_resource_test.go index c4f3f9a..b5fcb1d 100644 --- a/internal/provider/cached_image_resource_test.go +++ b/internal/provider/cached_image_resource_test.go @@ -20,8 +20,10 @@ func TestAccCachedImageResource(t *testing.T) { defer cancel() for _, tc := range []struct { - name string - files map[string]string + name string + files map[string]string + extraEnv map[string]string + assertEnv func(t *testing.T, deps testDependencies) resource.TestCheckFunc }{ { // This test case is the simplest possible case: a devcontainer.json. @@ -31,6 +33,23 @@ func TestAccCachedImageResource(t *testing.T) { files: map[string]string{ ".devcontainer/devcontainer.json": `{"image": "localhost:5000/test-ubuntu:latest"}`, }, + extraEnv: map[string]string{ + "FOO": testEnvValue, + "ENVBUILDER_GIT_URL": "https://not.the.real.git/url", + "ENVBUILDER_CACHE_REPO": "not-the-real-cache-repo", + }, + assertEnv: func(t *testing.T, deps testDependencies) resource.TestCheckFunc { + return resource.ComposeAggregateTestCheckFunc( + assertEnv(t, + "ENVBUILDER_CACHE_REPO", deps.CacheRepo, + "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key, + "ENVBUILDER_GIT_URL", deps.Repo.URL, + "ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true", + "ENVBUILDER_VERBOSE", "true", + "FOO", "bar\nbaz", + ), + ) + }, }, { // This test case includes a Dockerfile in addition to the devcontainer.json. @@ -42,14 +61,61 @@ func TestAccCachedImageResource(t *testing.T) { ".devcontainer/Dockerfile": `FROM localhost:5000/test-ubuntu:latest RUN date > /date.txt`, }, + extraEnv: map[string]string{ + "FOO": testEnvValue, + "ENVBUILDER_GIT_URL": "https://not.the.real.git/url", + "ENVBUILDER_CACHE_REPO": "not-the-real-cache-repo", + }, + assertEnv: func(t *testing.T, deps testDependencies) resource.TestCheckFunc { + return resource.ComposeAggregateTestCheckFunc( + assertEnv(t, + "ENVBUILDER_CACHE_REPO", deps.CacheRepo, + "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key, + "ENVBUILDER_GIT_URL", deps.Repo.URL, + "ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true", + "ENVBUILDER_VERBOSE", "true", + "FOO", "bar\nbaz", + ), + ) + }, + }, + { + // This test case ensures that parameters passed via extra_env are + // handled correctly. + name: "extra_env", + files: map[string]string{ + "path/to/.devcontainer/devcontainer.json": `{"build": { "dockerfile": "Dockerfile" }}`, + "path/to/.devcontainer/Dockerfile": `FROM localhost:5000/test-ubuntu:latest + RUN date > /date.txt`, + }, + extraEnv: map[string]string{ + "FOO": testEnvValue, + "ENVBUILDER_GIT_URL": "https://not.the.real.git/url", + "ENVBUILDER_CACHE_REPO": "not-the-real-cache-repo", + "ENVBUILDER_DEVCONTAINER_DIR": "path/to/.devcontainer", + "ENVBUILDER_DEVCONTAINER_JSON_PATH": "path/to/.devcontainer/devcontainer.json", + "ENVBUILDER_DOCKERFILE_PATH": "path/to/.devcontainer/Dockerfile", + }, + assertEnv: func(t *testing.T, deps testDependencies) resource.TestCheckFunc { + return resource.ComposeAggregateTestCheckFunc( + assertEnv(t, + "ENVBUILDER_CACHE_REPO", deps.CacheRepo, + "ENVBUILDER_DEVCONTAINER_DIR", "path/to/.devcontainer", + "ENVBUILDER_DEVCONTAINER_JSON_PATH", "path/to/.devcontainer/devcontainer.json", + "ENVBUILDER_DOCKERFILE_PATH", "path/to/.devcontainer/Dockerfile", + "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key, + "ENVBUILDER_GIT_URL", deps.Repo.URL, + "ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true", + "ENVBUILDER_VERBOSE", "true", + "FOO", "bar\nbaz", + ), + ) + }, }, } { t.Run(tc.name, func(t *testing.T) { //nolint: paralleltest - deps := setup(ctx, t, tc.files) - deps.ExtraEnv["FOO"] = testEnvValue - deps.ExtraEnv["ENVBUILDER_GIT_URL"] = "https://not.the.real.git/url" - deps.ExtraEnv["ENVBUILDER_CACHE_REPO"] = "not-the-real-cache-repo" + deps := setup(ctx, t, tc.extraEnv, tc.files) resource.Test(t, resource.TestCase{ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, @@ -71,14 +137,13 @@ RUN date > /date.txt`, resource.TestCheckResourceAttr("envbuilder_cached_image.test", "image", deps.BuilderImage), // Inputs should still be present. resource.TestCheckResourceAttr("envbuilder_cached_image.test", "cache_repo", deps.CacheRepo), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar\nbaz"), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "git_url", deps.Repo.URL), // Should be empty resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_password"), resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "cache_ttl_days"), // Environment variables - assertEnv(t, deps), + tc.assertEnv(t, deps), ), ExpectNonEmptyPlan: true, // TODO: check the plan. }, @@ -93,14 +158,13 @@ RUN date > /date.txt`, resource.TestCheckResourceAttr("envbuilder_cached_image.test", "image", deps.BuilderImage), // Inputs should still be present. resource.TestCheckResourceAttr("envbuilder_cached_image.test", "cache_repo", deps.CacheRepo), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar\nbaz"), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "git_url", deps.Repo.URL), // Should be empty resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_password"), resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "cache_ttl_days"), // Environment variables - assertEnv(t, deps), + tc.assertEnv(t, deps), ), ExpectNonEmptyPlan: true, // TODO: check the plan. }, @@ -113,7 +177,6 @@ RUN date > /date.txt`, Check: resource.ComposeAggregateTestCheckFunc( // Inputs should still be present. resource.TestCheckResourceAttr("envbuilder_cached_image.test", "cache_repo", deps.CacheRepo), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "extra_env.FOO", "bar\nbaz"), resource.TestCheckResourceAttr("envbuilder_cached_image.test", "git_url", deps.Repo.URL), // Should be empty resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "git_username"), @@ -125,7 +188,7 @@ RUN date > /date.txt`, resource.TestCheckResourceAttrSet("envbuilder_cached_image.test", "image"), resource.TestCheckResourceAttrWith("envbuilder_cached_image.test", "image", quotedPrefix(deps.CacheRepo)), // Environment variables - assertEnv(t, deps), + tc.assertEnv(t, deps), ), }, // 5) Should produce an empty plan after apply @@ -144,28 +207,31 @@ RUN date > /date.txt`, } } -// assertEnv is a test helper that checks the environment variables set on the -// cached image resource based on the provided test dependencies. -func assertEnv(t *testing.T, deps testDependencies) resource.TestCheckFunc { +// assertEnv is a test helper that checks the environment variables, in order, +// on both the env and env_map attributes of the cached image resource. +func assertEnv(t *testing.T, kvs ...string) resource.TestCheckFunc { t.Helper() - return resource.ComposeAggregateTestCheckFunc( - // Check that the environment variables are set correctly. - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.0", fmt.Sprintf("ENVBUILDER_CACHE_REPO=%s", deps.CacheRepo)), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.1", fmt.Sprintf("ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH=%s", deps.Repo.Key)), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.2", fmt.Sprintf("ENVBUILDER_GIT_URL=%s", deps.Repo.URL)), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.3", "ENVBUILDER_REMOTE_REPO_BUILD_MODE=true"), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.4", "ENVBUILDER_VERBOSE=true"), - // Check that the extra environment variables are set correctly. - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env.5", "FOO=bar\nbaz"), - // We should not have any other environment variables set. - resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", "env.6"), + if len(kvs)%2 != 0 { + t.Fatalf("assertEnv: expected an even number of key-value pairs, got %d", len(kvs)) + } + + funcs := make([]resource.TestCheckFunc, 0) + for i := 0; i < len(kvs); i += 2 { + resKey := fmt.Sprintf("env.%d", len(funcs)) + resVal := fmt.Sprintf("%s=%s", kvs[i], kvs[i+1]) + fn := resource.TestCheckResourceAttr("envbuilder_cached_image.test", resKey, resVal) + funcs = append(funcs, fn) + } + + lastKey := fmt.Sprintf("env.%d", len(funcs)) + lastFn := resource.TestCheckNoResourceAttr("envbuilder_cached_image.test", lastKey) + funcs = append(funcs, lastFn) + + for i := 0; i < len(kvs); i += 2 { + resKey := fmt.Sprintf("env_map.%s", kvs[i]) + fn := resource.TestCheckResourceAttr("envbuilder_cached_image.test", resKey, kvs[i+1]) + funcs = append(funcs, fn) + } - // Check that the same values are set in env_map. - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.ENVBUILDER_CACHE_REPO", deps.CacheRepo), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.ENVBUILDER_GIT_URL", deps.Repo.URL), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true"), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.ENVBUILDER_VERBOSE", "true"), - resource.TestCheckResourceAttr("envbuilder_cached_image.test", "env_map.FOO", "bar\nbaz"), - ) + return resource.ComposeAggregateTestCheckFunc(funcs...) } diff --git a/internal/provider/provider_internal_test.go b/internal/provider/provider_internal_test.go new file mode 100644 index 0000000..5601832 --- /dev/null +++ b/internal/provider/provider_internal_test.go @@ -0,0 +1,359 @@ +package provider + +import ( + "testing" + + eboptions "github.com/coder/envbuilder/options" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/stretchr/testify/assert" +) + +func Test_optionsFromDataModel(t *testing.T) { + t.Parallel() + + for _, tc := range []struct { + name string + data CachedImageResourceModel + expectOpts eboptions.Options + expectNumErrorDiags int + expectNumWarningDiags int + }{ + { + name: "required only", + data: CachedImageResourceModel{ + BuilderImage: basetypes.NewStringValue("envbuilder:latest"), + CacheRepo: basetypes.NewStringValue("localhost:5000/cache"), + GitURL: basetypes.NewStringValue("git@git.local/devcontainer.git"), + }, + expectOpts: eboptions.Options{ + CacheRepo: "localhost:5000/cache", + GitURL: "git@git.local/devcontainer.git", + RemoteRepoBuildMode: true, + }, + }, + { + name: "all options without extra_env", + data: CachedImageResourceModel{ + BuilderImage: basetypes.NewStringValue("envbuilder:latest"), + CacheRepo: basetypes.NewStringValue("localhost:5000/cache"), + GitURL: basetypes.NewStringValue("git@git.local/devcontainer.git"), + BaseImageCacheDir: basetypes.NewStringValue("/tmp/cache"), + BuildContextPath: basetypes.NewStringValue("."), + CacheTTLDays: basetypes.NewInt64Value(7), + DevcontainerDir: basetypes.NewStringValue(".devcontainer"), + DevcontainerJSONPath: basetypes.NewStringValue(".devcontainer/devcontainer.json"), + DockerfilePath: basetypes.NewStringValue("Dockerfile"), + DockerConfigBase64: basetypes.NewStringValue("some base64"), + ExitOnBuildFailure: basetypes.NewBoolValue(true), + // ExtraEnv: map[string]basetypes.Value{}, + FallbackImage: basetypes.NewStringValue("fallback"), + GitCloneDepth: basetypes.NewInt64Value(1), + GitCloneSingleBranch: basetypes.NewBoolValue(true), + GitHTTPProxyURL: basetypes.NewStringValue("http://proxy"), + GitPassword: basetypes.NewStringValue("password"), + GitSSHPrivateKeyPath: basetypes.NewStringValue("/tmp/id_rsa"), + GitUsername: basetypes.NewStringValue("user"), + IgnorePaths: listValue("ignore", "paths"), + Insecure: basetypes.NewBoolValue(true), + RemoteRepoBuildMode: basetypes.NewBoolValue(false), + SSLCertBase64: basetypes.NewStringValue("cert"), + Verbose: basetypes.NewBoolValue(true), + WorkspaceFolder: basetypes.NewStringValue("workspace"), + }, + expectOpts: eboptions.Options{ + CacheRepo: "localhost:5000/cache", + GitURL: "git@git.local/devcontainer.git", + BaseImageCacheDir: "/tmp/cache", + BuildContextPath: ".", + CacheTTLDays: 7, + DevcontainerDir: ".devcontainer", + DevcontainerJSONPath: ".devcontainer/devcontainer.json", + DockerfilePath: "Dockerfile", + DockerConfigBase64: "some base64", + ExitOnBuildFailure: true, + FallbackImage: "fallback", + GitCloneDepth: 1, + GitCloneSingleBranch: true, + GitHTTPProxyURL: "http://proxy", + GitPassword: "password", + GitSSHPrivateKeyPath: "/tmp/id_rsa", + GitUsername: "user", + IgnorePaths: []string{"ignore", "paths"}, + Insecure: true, + RemoteRepoBuildMode: false, + SSLCertBase64: "cert", + Verbose: true, + WorkspaceFolder: "workspace", + }, + }, + { + name: "extra env override", + data: CachedImageResourceModel{ + BuilderImage: basetypes.NewStringValue("envbuilder:latest"), + CacheRepo: basetypes.NewStringValue("localhost:5000/cache"), + GitURL: basetypes.NewStringValue("git@git.local/devcontainer.git"), + ExtraEnv: extraEnvMap(t, + "CODER_AGENT_TOKEN", "token", + "CODER_AGENT_URL", "http://coder", + "FOO", "bar", + ), + }, + expectOpts: eboptions.Options{ + CacheRepo: "localhost:5000/cache", + GitURL: "git@git.local/devcontainer.git", + RemoteRepoBuildMode: true, + CoderAgentToken: "token", + CoderAgentURL: "http://coder", + }, + }, + { + name: "extra_env override warnings", + data: CachedImageResourceModel{ + BuilderImage: basetypes.NewStringValue("envbuilder:latest"), + CacheRepo: basetypes.NewStringValue("localhost:5000/cache"), + GitURL: basetypes.NewStringValue("git@git.local/devcontainer.git"), + BaseImageCacheDir: basetypes.NewStringValue("/tmp/cache"), + BuildContextPath: basetypes.NewStringValue("."), + CacheTTLDays: basetypes.NewInt64Value(7), + DevcontainerDir: basetypes.NewStringValue(".devcontainer"), + DevcontainerJSONPath: basetypes.NewStringValue(".devcontainer/devcontainer.json"), + DockerfilePath: basetypes.NewStringValue("Dockerfile"), + DockerConfigBase64: basetypes.NewStringValue("some base64"), + ExitOnBuildFailure: basetypes.NewBoolValue(true), + // ExtraEnv: map[string]basetypes.Value{}, + FallbackImage: basetypes.NewStringValue("fallback"), + GitCloneDepth: basetypes.NewInt64Value(1), + GitCloneSingleBranch: basetypes.NewBoolValue(true), + GitHTTPProxyURL: basetypes.NewStringValue("http://proxy"), + GitPassword: basetypes.NewStringValue("password"), + GitSSHPrivateKeyPath: basetypes.NewStringValue("/tmp/id_rsa"), + GitUsername: basetypes.NewStringValue("user"), + IgnorePaths: listValue("ignore", "paths"), + Insecure: basetypes.NewBoolValue(true), + RemoteRepoBuildMode: basetypes.NewBoolValue(false), + SSLCertBase64: basetypes.NewStringValue("cert"), + Verbose: basetypes.NewBoolValue(true), + WorkspaceFolder: basetypes.NewStringValue("workspace"), + ExtraEnv: extraEnvMap(t, + "ENVBUILDER_CACHE_REPO", "override", + "ENVBUILDER_GIT_URL", "override", + "ENVBUILDER_BASE_IMAGE_CACHE_DIR", "override", + "ENVBUILDER_BUILD_CONTEXT_PATH", "override", + "ENVBUILDER_CACHE_TTL_DAYS", "8", + "ENVBUILDER_DEVCONTAINER_DIR", "override", + "ENVBUILDER_DEVCONTAINER_JSON_PATH", "override", + "ENVBUILDER_DOCKERFILE_PATH", "override", + "ENVBUILDER_DOCKER_CONFIG_BASE64", "override", + "ENVBUILDER_EXIT_ON_BUILD_FAILURE", "false", + "ENVBUILDER_FALLBACK_IMAGE", "override", + "ENVBUILDER_GIT_CLONE_DEPTH", "2", + "ENVBUILDER_GIT_CLONE_SINGLE_BRANCH", "false", + "ENVBUILDER_GIT_HTTP_PROXY_URL", "override", + "ENVBUILDER_GIT_PASSWORD", "override", + "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", "override", + "ENVBUILDER_GIT_USERNAME", "override", + "ENVBUILDER_IGNORE_PATHS", "override", + "ENVBUILDER_INSECURE", "false", + "ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true", + "ENVBUILDER_SSL_CERT_BASE64", "override", + "ENVBUILDER_VERBOSE", "false", + "ENVBUILDER_WORKSPACE_FOLDER", "override", + "FOO", "bar", + ), + }, + expectOpts: eboptions.Options{ + // not overridden + CacheRepo: "localhost:5000/cache", + GitURL: "git@git.local/devcontainer.git", + // overridden + BaseImageCacheDir: "override", + BuildContextPath: "override", + CacheTTLDays: 8, + DevcontainerDir: "override", + DevcontainerJSONPath: "override", + DockerfilePath: "override", + DockerConfigBase64: "override", + ExitOnBuildFailure: false, + FallbackImage: "override", + GitCloneDepth: 2, + GitCloneSingleBranch: false, + GitHTTPProxyURL: "override", + GitPassword: "override", + GitSSHPrivateKeyPath: "override", + GitUsername: "override", + IgnorePaths: []string{"override"}, + Insecure: false, + RemoteRepoBuildMode: true, + SSLCertBase64: "override", + Verbose: false, + WorkspaceFolder: "override", + }, + expectNumWarningDiags: 23, + }, + { + name: "extra_env override errors", + data: CachedImageResourceModel{ + BuilderImage: basetypes.NewStringValue("envbuilder:latest"), + CacheRepo: basetypes.NewStringValue("localhost:5000/cache"), + GitURL: basetypes.NewStringValue("git@git.local/devcontainer.git"), + ExtraEnv: extraEnvMap(t, + "ENVBUILDER_CACHE_TTL_DAYS", "not a number", + "ENVBUILDER_VERBOSE", "not a bool", + "FOO", "bar", + ), + }, + expectOpts: eboptions.Options{ + // not overridden + CacheRepo: "localhost:5000/cache", + GitURL: "git@git.local/devcontainer.git", + RemoteRepoBuildMode: true, + }, + expectNumErrorDiags: 2, + }, + } { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + actual, diags := optionsFromDataModel(tc.data) + assert.Equal(t, tc.expectNumErrorDiags, diags.ErrorsCount()) + assert.Equal(t, tc.expectNumWarningDiags, diags.WarningsCount()) + assert.EqualValues(t, tc.expectOpts, actual) + }) + } +} + +func Test_computeEnvFromOptions(t *testing.T) { + t.Parallel() + + for _, tc := range []struct { + name string + opts eboptions.Options + extraEnv map[string]string + expectEnv map[string]string + }{ + { + name: "empty", + opts: eboptions.Options{}, + expectEnv: map[string]string{}, + }, + { + name: "all options", + opts: eboptions.Options{ + BaseImageCacheDir: "string", + BinaryPath: "string", + BuildContextPath: "string", + CacheRepo: "string", + CacheTTLDays: 1, + CoderAgentSubsystem: []string{"one", "two"}, + CoderAgentToken: "string", + CoderAgentURL: "string", + DevcontainerDir: "string", + DevcontainerJSONPath: "string", + DockerConfigBase64: "string", + DockerfilePath: "string", + ExitOnBuildFailure: true, + ExportEnvFile: "string", + FallbackImage: "string", + ForceSafe: true, + GetCachedImage: true, + GitCloneDepth: 1, + GitCloneSingleBranch: true, + GitHTTPProxyURL: "string", + GitPassword: "string", + GitSSHPrivateKeyPath: "string", + GitURL: "string", + GitUsername: "string", + IgnorePaths: []string{"one", "two"}, + InitArgs: "string", + InitCommand: "string", + InitScript: "string", + Insecure: true, + LayerCacheDir: "string", + PostStartScriptPath: "string", + PushImage: true, + RemoteRepoBuildMode: true, + RemoteRepoDir: "string", + SetupScript: "string", + SkipRebuild: true, + SSLCertBase64: "string", + Verbose: true, + WorkspaceFolder: "string", + }, + extraEnv: map[string]string{ + "ENVBUILDER_SOMETHING": "string", // should be ignored + "FOO": "bar", // should be included + }, + expectEnv: map[string]string{ + "CODER_AGENT_SUBSYSTEM": "one,two", + "CODER_AGENT_TOKEN": "string", + "CODER_AGENT_URL": "string", + "ENVBUILDER_BASE_IMAGE_CACHE_DIR": "string", + "ENVBUILDER_BINARY_PATH": "string", + "ENVBUILDER_BUILD_CONTEXT_PATH": "string", + "ENVBUILDER_CACHE_REPO": "string", + "ENVBUILDER_CACHE_TTL_DAYS": "1", + "ENVBUILDER_DEVCONTAINER_DIR": "string", + "ENVBUILDER_DEVCONTAINER_JSON_PATH": "string", + "ENVBUILDER_DOCKER_CONFIG_BASE64": "string", + "ENVBUILDER_DOCKERFILE_PATH": "string", + "ENVBUILDER_EXIT_ON_BUILD_FAILURE": "true", + "ENVBUILDER_EXPORT_ENV_FILE": "string", + "ENVBUILDER_FALLBACK_IMAGE": "string", + "ENVBUILDER_FORCE_SAFE": "true", + "ENVBUILDER_GET_CACHED_IMAGE": "true", + "ENVBUILDER_GIT_CLONE_DEPTH": "1", + "ENVBUILDER_GIT_CLONE_SINGLE_BRANCH": "true", + "ENVBUILDER_GIT_HTTP_PROXY_URL": "string", + "ENVBUILDER_GIT_PASSWORD": "string", + "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH": "string", + "ENVBUILDER_GIT_URL": "string", + "ENVBUILDER_GIT_USERNAME": "string", + "ENVBUILDER_IGNORE_PATHS": "one,two", + "ENVBUILDER_INIT_ARGS": "string", + "ENVBUILDER_INIT_COMMAND": "string", + "ENVBUILDER_INIT_SCRIPT": "string", + "ENVBUILDER_INSECURE": "true", + "ENVBUILDER_LAYER_CACHE_DIR": "string", + "ENVBUILDER_POST_START_SCRIPT_PATH": "string", + "ENVBUILDER_PUSH_IMAGE": "true", + "ENVBUILDER_REMOTE_REPO_BUILD_MODE": "true", + "ENVBUILDER_REMOTE_REPO_DIR": "string", + "ENVBUILDER_SETUP_SCRIPT": "string", + "ENVBUILDER_SKIP_REBUILD": "true", + "ENVBUILDER_SSL_CERT_BASE64": "string", + "ENVBUILDER_VERBOSE": "true", + "ENVBUILDER_WORKSPACE_FOLDER": "string", + "FOO": "bar", + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + if tc.extraEnv == nil { + tc.extraEnv = map[string]string{} + } + actual := computeEnvFromOptions(tc.opts, tc.extraEnv) + assert.EqualValues(t, tc.expectEnv, actual) + }) + } +} + +func listValue(vs ...string) basetypes.ListValue { + vals := make([]attr.Value, len(vs)) + for i, s := range vs { + vals[i] = basetypes.NewStringValue(s) + } + return basetypes.NewListValueMust(basetypes.StringType{}, vals) +} + +func extraEnvMap(t *testing.T, kvs ...string) basetypes.MapValue { + t.Helper() + if len(kvs)%2 != 0 { + t.Fatalf("extraEnvMap: expected even number of key-value pairs, got %d", len(kvs)) + } + vals := make(map[string]attr.Value) + for i := 0; i < len(kvs); i += 2 { + vals[kvs[i]] = basetypes.NewStringValue(kvs[i+1]) + } + return basetypes.NewMapValueMust(basetypes.StringType{}, vals) +} diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index cfe32a9..de9ad8c 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -49,14 +49,14 @@ func (d *testDependencies) Config(t testing.TB) string { resource "envbuilder_cached_image" "test" { builder_image = {{ quote .BuilderImage }} cache_repo = {{ quote .CacheRepo }} + git_url = {{ quote .Repo.URL }} extra_env = { + "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH": {{ quote .Repo.Key }} + "ENVBUILDER_VERBOSE": true {{ range $k, $v := .ExtraEnv }} {{ quote $k }}: {{ quote $v }} {{ end }} } - git_url = {{ quote .Repo.URL }} - git_ssh_private_key_path = {{ quote .Repo.Key }} - verbose = true }` fm := template.FuncMap{"quote": quote} @@ -71,7 +71,7 @@ func quote(s string) string { return fmt.Sprintf("%q", s) } -func setup(ctx context.Context, t testing.TB, files map[string]string) testDependencies { +func setup(ctx context.Context, t testing.TB, extraEnv, files map[string]string) testDependencies { t.Helper() envbuilderImage := getEnvOrDefault("ENVBUILDER_IMAGE", "localhost:5000/envbuilder") @@ -89,7 +89,7 @@ func setup(ctx context.Context, t testing.TB, files map[string]string) testDepen return testDependencies{ BuilderImage: envbuilderImageRef, CacheRepo: reg + "/test", - ExtraEnv: make(map[string]string), + ExtraEnv: extraEnv, Repo: gitRepo, } } @@ -106,18 +106,38 @@ func seedCache(ctx context.Context, t testing.TB, deps testDependencies) { ensureImage(ctx, t, cli, deps.BuilderImage) + // Set up env for envbuilder + seedEnv := map[string]string{ + "ENVBUILDER_CACHE_REPO": deps.CacheRepo, + "ENVBUILDER_EXIT_ON_BUILD_FAILURE": "true", + "ENVBUILDER_INIT_SCRIPT": "exit", + "ENVBUILDER_PUSH_IMAGE": "true", + "ENVBUILDER_VERBOSE": "true", + "ENVBUILDER_GIT_URL": deps.Repo.URL, + "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH": "/id_ed25519", + } + + for k, v := range deps.ExtraEnv { + if !strings.HasPrefix(k, "ENVBUILDER_") { + continue + } + if _, ok := seedEnv[k]; ok { + continue + } + seedEnv[k] = v + } + + seedDockerEnv := make([]string, 0) + for k, v := range seedEnv { + seedDockerEnv = append(seedDockerEnv, k+"="+v) + } + + t.Logf("running envbuilder to seed cache with args: %v", seedDockerEnv) + // Run envbuilder using this dir as a local layer cache ctr, err := cli.ContainerCreate(ctx, &container.Config{ Image: deps.BuilderImage, - Env: []string{ - "ENVBUILDER_CACHE_REPO=" + deps.CacheRepo, - "ENVBUILDER_EXIT_ON_BUILD_FAILURE=true", - "ENVBUILDER_INIT_SCRIPT=exit", - "ENVBUILDER_PUSH_IMAGE=true", - "ENVBUILDER_VERBOSE=true", - "ENVBUILDER_GIT_URL=" + deps.Repo.URL, - "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH=/id_ed25519", - }, + Env: seedDockerEnv, Labels: map[string]string{ testContainerLabel: "true", }, From 482a446eb376fe9861291b8a07dbf94e26c30625 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Wed, 4 Sep 2024 16:29:25 +0100 Subject: [PATCH 16/40] chore(internal/provider): refactor cached_image_resource (#46) Addresses some non-blocking comments from #44: - Extracts some of the functions in cached_image_resource.go to separate internal packages tfutil and imgutil. - Some other functions are extracted to helpers.go. - Extracts non-overridable flags to a package-level variable. - Pre-allocates some slices where possible. - Removes some unused code and renames some existing code for readability --- internal/imgutil/imgutil.go | 103 +++++ internal/provider/cached_image_resource.go | 423 +----------------- .../provider/cached_image_resource_test.go | 14 +- internal/provider/helpers.go | 255 +++++++++++ internal/provider/provider_internal_test.go | 3 - internal/provider/provider_test.go | 2 +- internal/tfutil/tfutil.go | 92 ++++ 7 files changed, 472 insertions(+), 420 deletions(-) create mode 100644 internal/imgutil/imgutil.go create mode 100644 internal/provider/helpers.go create mode 100644 internal/tfutil/tfutil.go diff --git a/internal/imgutil/imgutil.go b/internal/imgutil/imgutil.go new file mode 100644 index 0000000..5c2d96a --- /dev/null +++ b/internal/imgutil/imgutil.go @@ -0,0 +1,103 @@ +package imgutil + +import ( + "archive/tar" + "context" + "fmt" + "io" + "os" + "path/filepath" + + "github.com/coder/envbuilder/constants" + "github.com/google/go-containerregistry/pkg/authn" + "github.com/google/go-containerregistry/pkg/name" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/remote" + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +// GetRemoteImage fetches the image manifest of the image. +func GetRemoteImage(imgRef string) (v1.Image, error) { + ref, err := name.ParseReference(imgRef) + if err != nil { + return nil, fmt.Errorf("parse reference: %w", err) + } + + img, err := remote.Image(ref, remote.WithAuthFromKeychain(authn.DefaultKeychain)) + if err != nil { + return nil, fmt.Errorf("check remote image: %w", err) + } + + return img, nil +} + +// ExtractEnvbuilderFromImage reads the image located at imgRef and extracts +// MagicBinaryLocation to destPath. +func ExtractEnvbuilderFromImage(ctx context.Context, imgRef, destPath string) error { + needle := filepath.Clean(constants.MagicBinaryLocation)[1:] // skip leading '/' + img, err := GetRemoteImage(imgRef) + if err != nil { + return fmt.Errorf("check remote image: %w", err) + } + + layers, err := img.Layers() + if err != nil { + return fmt.Errorf("get image layers: %w", err) + } + + // Check the layers in reverse order. The last layers are more likely to + // include the binary. + for i := len(layers) - 1; i >= 0; i-- { + ul, err := layers[i].Uncompressed() + if err != nil { + return fmt.Errorf("get uncompressed layer: %w", err) + } + + tr := tar.NewReader(ul) + for { + th, err := tr.Next() + if err == io.EOF { + break + } + + if err != nil { + return fmt.Errorf("read tar header: %w", err) + } + + name := filepath.Clean(th.Name) + if th.Typeflag != tar.TypeReg { + tflog.Debug(ctx, "skip non-regular file", map[string]any{"name": name, "layer_idx": i + 1}) + continue + } + + if name != needle { + tflog.Debug(ctx, "skip file", map[string]any{"name": name, "layer_idx": i + 1}) + continue + } + + tflog.Debug(ctx, "found file", map[string]any{"name": name, "layer_idx": i + 1}) + if err := os.MkdirAll(filepath.Dir(destPath), 0o755); err != nil { + return fmt.Errorf("create parent directories: %w", err) + } + destF, err := os.Create(destPath) + if err != nil { + return fmt.Errorf("create dest file for writing: %w", err) + } + defer destF.Close() + _, err = io.Copy(destF, tr) + if err != nil { + return fmt.Errorf("copy dest file from image: %w", err) + } + if err := destF.Close(); err != nil { + return fmt.Errorf("close dest file: %w", err) + } + + if err := os.Chmod(destPath, 0o755); err != nil { + return fmt.Errorf("chmod file: %w", err) + } + return nil + } + } + + return fmt.Errorf("extract envbuilder binary from image %q: %w", imgRef, os.ErrNotExist) +} diff --git a/internal/provider/cached_image_resource.go b/internal/provider/cached_image_resource.go index c3f9378..27adc98 100644 --- a/internal/provider/cached_image_resource.go +++ b/internal/provider/cached_image_resource.go @@ -1,33 +1,24 @@ package provider import ( - "archive/tar" "context" "fmt" - "io" "net/http" "os" "path/filepath" - "sort" "strings" kconfig "github.com/GoogleContainerTools/kaniko/pkg/config" "github.com/coder/envbuilder" "github.com/coder/envbuilder/constants" - eblog "github.com/coder/envbuilder/log" eboptions "github.com/coder/envbuilder/options" - "github.com/coder/serpent" + "github.com/coder/terraform-provider-envbuilder/internal/imgutil" + "github.com/coder/terraform-provider-envbuilder/internal/tfutil" "github.com/go-git/go-billy/v5/osfs" - "github.com/google/go-containerregistry/pkg/authn" - "github.com/google/go-containerregistry/pkg/name" v1 "github.com/google/go-containerregistry/pkg/v1" - "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/uuid" - "github.com/spf13/pflag" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" @@ -295,249 +286,13 @@ func (r *CachedImageResource) Configure(ctx context.Context, req resource.Config r.client = client } -func optionsFromDataModel(data CachedImageResourceModel) (eboptions.Options, diag.Diagnostics) { - var diags diag.Diagnostics - var opts eboptions.Options - - // Required options. Cannot be overridden by extra_env. - opts.CacheRepo = data.CacheRepo.ValueString() - opts.GitURL = data.GitURL.ValueString() - - // Other options can be overridden by extra_env, with a warning. - // Keep track of which options are overridden. - overrides := make(map[string]struct{}) - - if !data.BaseImageCacheDir.IsNull() { - overrides["ENVBUILDER_BASE_IMAGE_CACHE_DIR"] = struct{}{} - opts.BaseImageCacheDir = data.BaseImageCacheDir.ValueString() - } - - if !data.BuildContextPath.IsNull() { - overrides["ENVBUILDER_BUILD_CONTEXT_PATH"] = struct{}{} - opts.BuildContextPath = data.BuildContextPath.ValueString() - } - - if !data.CacheTTLDays.IsNull() { - overrides["ENVBUILDER_CACHE_TTL_DAYS"] = struct{}{} - opts.CacheTTLDays = data.CacheTTLDays.ValueInt64() - } - - if !data.DevcontainerDir.IsNull() { - overrides["ENVBUILDER_DEVCONTAINER_DIR"] = struct{}{} - opts.DevcontainerDir = data.DevcontainerDir.ValueString() - } - - if !data.DevcontainerJSONPath.IsNull() { - overrides["ENVBUILDER_DEVCONTAINER_JSON_PATH"] = struct{}{} - opts.DevcontainerJSONPath = data.DevcontainerJSONPath.ValueString() - } - - if !data.DockerfilePath.IsNull() { - overrides["ENVBUILDER_DOCKERFILE_PATH"] = struct{}{} - opts.DockerfilePath = data.DockerfilePath.ValueString() - } - - if !data.DockerConfigBase64.IsNull() { - overrides["ENVBUILDER_DOCKER_CONFIG_BASE64"] = struct{}{} - opts.DockerConfigBase64 = data.DockerConfigBase64.ValueString() - } - - if !data.ExitOnBuildFailure.IsNull() { - overrides["ENVBUILDER_EXIT_ON_BUILD_FAILURE"] = struct{}{} - opts.ExitOnBuildFailure = data.ExitOnBuildFailure.ValueBool() - } - - if !data.FallbackImage.IsNull() { - overrides["ENVBUILDER_FALLBACK_IMAGE"] = struct{}{} - opts.FallbackImage = data.FallbackImage.ValueString() - } - - if !data.GitCloneDepth.IsNull() { - overrides["ENVBUILDER_GIT_CLONE_DEPTH"] = struct{}{} - opts.GitCloneDepth = data.GitCloneDepth.ValueInt64() - } - - if !data.GitCloneSingleBranch.IsNull() { - overrides["ENVBUILDER_GIT_CLONE_SINGLE_BRANCH"] = struct{}{} - opts.GitCloneSingleBranch = data.GitCloneSingleBranch.ValueBool() - } - - if !data.GitHTTPProxyURL.IsNull() { - overrides["ENVBUILDER_GIT_HTTP_PROXY_URL"] = struct{}{} - opts.GitHTTPProxyURL = data.GitHTTPProxyURL.ValueString() - } - - if !data.GitSSHPrivateKeyPath.IsNull() { - overrides["ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH"] = struct{}{} - opts.GitSSHPrivateKeyPath = data.GitSSHPrivateKeyPath.ValueString() - } - - if !data.GitUsername.IsNull() { - overrides["ENVBUILDER_GIT_USERNAME"] = struct{}{} - opts.GitUsername = data.GitUsername.ValueString() - } - - if !data.GitPassword.IsNull() { - overrides["ENVBUILDER_GIT_PASSWORD"] = struct{}{} - opts.GitPassword = data.GitPassword.ValueString() - } - - if !data.IgnorePaths.IsNull() { - overrides["ENVBUILDER_IGNORE_PATHS"] = struct{}{} - opts.IgnorePaths = tfListToStringSlice(data.IgnorePaths) - } - - if !data.Insecure.IsNull() { - overrides["ENVBUILDER_INSECURE"] = struct{}{} - opts.Insecure = data.Insecure.ValueBool() - } - - if data.RemoteRepoBuildMode.IsNull() { - opts.RemoteRepoBuildMode = true - } else { - overrides["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = struct{}{} - opts.RemoteRepoBuildMode = data.RemoteRepoBuildMode.ValueBool() - } - - if !data.SSLCertBase64.IsNull() { - overrides["ENVBUILDER_SSL_CERT_BASE64"] = struct{}{} - opts.SSLCertBase64 = data.SSLCertBase64.ValueString() - } - - if !data.Verbose.IsNull() { - overrides["ENVBUILDER_VERBOSE"] = struct{}{} - opts.Verbose = data.Verbose.ValueBool() - } - - if !data.WorkspaceFolder.IsNull() { - overrides["ENVBUILDER_WORKSPACE_FOLDER"] = struct{}{} - opts.WorkspaceFolder = data.WorkspaceFolder.ValueString() - } - - // convert extraEnv to a map for ease of use. - extraEnv := make(map[string]string) - for k, v := range data.ExtraEnv.Elements() { - extraEnv[k] = tfValueToString(v) - } - diags = append(diags, overrideOptionsFromExtraEnv(&opts, extraEnv, overrides)...) - - return opts, diags -} - -func overrideOptionsFromExtraEnv(opts *eboptions.Options, extraEnv map[string]string, overrides map[string]struct{}) diag.Diagnostics { - var diags diag.Diagnostics - // Make a map of the options for easy lookup. - optsMap := make(map[string]pflag.Value) - for _, opt := range opts.CLI() { - optsMap[opt.Env] = opt.Value - } - for key, val := range extraEnv { - switch key { - - // These options may not be overridden. - case "ENVBUILDER_CACHE_REPO", "ENVBUILDER_GIT_URL": - diags.AddAttributeWarning(path.Root("extra_env"), - "Cannot override required environment variable", - fmt.Sprintf("The key %q in extra_env cannot be overridden.", key), - ) - continue - - default: - // Check if the option was set on the provider data model and generate a warning if so. - if _, overridden := overrides[key]; overridden { - diags.AddAttributeWarning(path.Root("extra_env"), - "Overriding provider environment variable", - fmt.Sprintf("The key %q in extra_env overrides an option set on the provider.", key), - ) - } - - // XXX: workaround for serpent behaviour where calling Set() on a - // string slice will append instead of replace: set to empty first. - if key == "ENVBUILDER_IGNORE_PATHS" { - _ = optsMap[key].Set("") - } - - opt, found := optsMap[key] - if !found { - // ignore unknown keys - continue - } - - if err := opt.Set(val); err != nil { - diags.AddAttributeError(path.Root("extra_env"), - "Invalid value for environment variable", - fmt.Sprintf("The key %q in extra_env has an invalid value: %s", key, err), - ) - } - } - } - return diags -} - -func computeEnvFromOptions(opts eboptions.Options, extraEnv map[string]string) map[string]string { - allEnvKeys := make(map[string]struct{}) - for _, opt := range opts.CLI() { - if opt.Env == "" { - continue - } - allEnvKeys[opt.Env] = struct{}{} - } - - // Only set the environment variables from opts that are not legacy options. - // Legacy options are those that are not prefixed with ENVBUILDER_. - // While we can detect when a legacy option is set, overriding it becomes - // problematic. Erring on the side of caution, we will not override legacy options. - isEnvbuilderOption := func(key string) bool { - switch key { - case "CODER_AGENT_URL", "CODER_AGENT_TOKEN", "CODER_AGENT_SUBSYSTEM": - return true // kinda - default: - return strings.HasPrefix(key, "ENVBUILDER_") - } - } - - computed := make(map[string]string) - for _, opt := range opts.CLI() { - if opt.Env == "" { - continue - } - // TODO: remove this check once support for legacy options is removed. - if !isEnvbuilderOption(opt.Env) { - continue - } - var val string - if sa, ok := opt.Value.(*serpent.StringArray); ok { - val = strings.Join(sa.GetSlice(), ",") - } else { - val = opt.Value.String() - } - - switch val { - case "", "false", "0": - // Skip zero values. - continue - } - computed[opt.Env] = val - } - - // Merge in extraEnv, which may override values from opts. - // Skip any keys that are envbuilder options. - for key, val := range extraEnv { - if isEnvbuilderOption(key) { - continue - } - computed[key] = val - } - return computed -} - // setComputedEnv sets data.Env and data.EnvMap based on the values of the // other fields in the model. func (data *CachedImageResourceModel) setComputedEnv(ctx context.Context, env map[string]string) diag.Diagnostics { var diag, ds diag.Diagnostics data.EnvMap, ds = basetypes.NewMapValueFrom(ctx, types.StringType, env) diag = append(diag, ds...) - data.Env, ds = basetypes.NewListValueFrom(ctx, types.StringType, sortedKeyValues(env)) + data.Env, ds = basetypes.NewListValueFrom(ctx, types.StringType, tfutil.DockerEnv(env)) diag = append(diag, ds...) return diag } @@ -558,7 +313,7 @@ func (r *CachedImageResource) Read(ctx context.Context, req resource.ReadRequest return } // Set the expected environment variables. - computedEnv := computeEnvFromOptions(opts, tfMapToStringMap(data.ExtraEnv)) + computedEnv := computeEnvFromOptions(opts, tfutil.TFMapToStringMap(data.ExtraEnv)) resp.Diagnostics.Append(data.setComputedEnv(ctx, computedEnv)...) // If the previous state is that Image == BuilderImage, then we previously did @@ -574,7 +329,7 @@ func (r *CachedImageResource) Read(ctx context.Context, req resource.ReadRequest } // Check the remote registry for the image we previously found. - img, err := getRemoteImage(data.Image.ValueString()) + img, err := imgutil.GetRemoteImage(data.Image.ValueString()) if err != nil { if !strings.Contains(err.Error(), "MANIFEST_UNKNOWN") { // Explicitly not making this an error diag. @@ -629,7 +384,7 @@ func (r *CachedImageResource) Create(ctx context.Context, req resource.CreateReq } // Set the expected environment variables. - computedEnv := computeEnvFromOptions(opts, tfMapToStringMap(data.ExtraEnv)) + computedEnv := computeEnvFromOptions(opts, tfutil.TFMapToStringMap(data.ExtraEnv)) resp.Diagnostics.Append(data.setComputedEnv(ctx, computedEnv)...) cachedImg, err := runCacheProbe(ctx, data.BuilderImage.ValueString(), opts) @@ -716,7 +471,7 @@ func runCacheProbe(ctx context.Context, builderImage string, opts eboptions.Opti // In order to correctly reproduce the final layer of the cached image, we // need the envbuilder binary used to originally build the image! envbuilderPath := filepath.Join(tmpDir, "envbuilder") - if err := extractEnvbuilderFromImage(ctx, builderImage, envbuilderPath); err != nil { + if err := imgutil.ExtractEnvbuilderFromImage(ctx, builderImage, envbuilderPath); err != nil { tflog.Error(ctx, "failed to fetch envbuilder binary from builder image", map[string]any{"err": err}) return nil, fmt.Errorf("failed to fetch the envbuilder binary from the builder image: %s", err.Error()) } @@ -729,7 +484,7 @@ func runCacheProbe(ctx context.Context, builderImage string, opts eboptions.Opti // We always want to get the cached image. opts.GetCachedImage = true // Log to the Terraform logger. - opts.Logger = tfLogFunc(ctx) + opts.Logger = tfutil.TFLogFunc(ctx) // We don't require users to set a workspace folder, but maybe there's a // reason someone may need to. @@ -766,165 +521,3 @@ func runCacheProbe(ctx context.Context, builderImage string, opts eboptions.Opti return envbuilder.RunCacheProbe(ctx, opts) } - -// getRemoteImage fetches the image manifest of the image. -func getRemoteImage(imgRef string) (v1.Image, error) { - ref, err := name.ParseReference(imgRef) - if err != nil { - return nil, fmt.Errorf("parse reference: %w", err) - } - - img, err := remote.Image(ref, remote.WithAuthFromKeychain(authn.DefaultKeychain)) - if err != nil { - return nil, fmt.Errorf("check remote image: %w", err) - } - - return img, nil -} - -// extractEnvbuilderFromImage reads the image located at imgRef and extracts -// MagicBinaryLocation to destPath. -func extractEnvbuilderFromImage(ctx context.Context, imgRef, destPath string) error { - needle := filepath.Clean(constants.MagicBinaryLocation)[1:] // skip leading '/' - img, err := getRemoteImage(imgRef) - if err != nil { - return fmt.Errorf("check remote image: %w", err) - } - - layers, err := img.Layers() - if err != nil { - return fmt.Errorf("get image layers: %w", err) - } - - // Check the layers in reverse order. The last layers are more likely to - // include the binary. - for i := len(layers) - 1; i >= 0; i-- { - ul, err := layers[i].Uncompressed() - if err != nil { - return fmt.Errorf("get uncompressed layer: %w", err) - } - - tr := tar.NewReader(ul) - for { - th, err := tr.Next() - if err == io.EOF { - break - } - - if err != nil { - return fmt.Errorf("read tar header: %w", err) - } - - name := filepath.Clean(th.Name) - if th.Typeflag != tar.TypeReg { - tflog.Debug(ctx, "skip non-regular file", map[string]any{"name": name, "layer_idx": i + 1}) - continue - } - - if name != needle { - tflog.Debug(ctx, "skip file", map[string]any{"name": name, "layer_idx": i + 1}) - continue - } - - tflog.Debug(ctx, "found file", map[string]any{"name": name, "layer_idx": i + 1}) - if err := os.MkdirAll(filepath.Dir(destPath), 0o755); err != nil { - return fmt.Errorf("create parent directories: %w", err) - } - destF, err := os.Create(destPath) - if err != nil { - return fmt.Errorf("create dest file for writing: %w", err) - } - defer destF.Close() - _, err = io.Copy(destF, tr) - if err != nil { - return fmt.Errorf("copy dest file from image: %w", err) - } - if err := destF.Close(); err != nil { - return fmt.Errorf("close dest file: %w", err) - } - - if err := os.Chmod(destPath, 0o755); err != nil { - return fmt.Errorf("chmod file: %w", err) - } - return nil - } - } - - return fmt.Errorf("extract envbuilder binary from image %q: %w", imgRef, os.ErrNotExist) -} - -// tfValueToString converts an attr.Value to its string representation -// based on its Terraform type. This is needed because the String() -// method on an attr.Value creates a 'human-readable' version of the type, which -// leads to quotes, escaped characters, and other assorted sadness. -func tfValueToString(val attr.Value) string { - if val.IsUnknown() || val.IsNull() { - return "" - } - if vs, ok := val.(interface{ ValueString() string }); ok { - return vs.ValueString() - } - if vb, ok := val.(interface{ ValueBool() bool }); ok { - return fmt.Sprintf("%t", vb.ValueBool()) - } - if vi, ok := val.(interface{ ValueInt64() int64 }); ok { - return fmt.Sprintf("%d", vi.ValueInt64()) - } - panic(fmt.Errorf("tfValueToString: value %T is not a supported type", val)) -} - -// tfListToStringSlice converts a types.List to a []string by calling -// tfValueToString on each element. -func tfListToStringSlice(l types.List) []string { - var ss []string - for _, el := range l.Elements() { - ss = append(ss, tfValueToString(el)) - } - return ss -} - -// tfMapToStringMap converts a types.Map to a map[string]string by calling -// tfValueToString on each element. -func tfMapToStringMap(m types.Map) map[string]string { - res := make(map[string]string) - for k, v := range m.Elements() { - res[k] = tfValueToString(v) - } - return res -} - -// tfLogFunc is an adapter to envbuilder/log.Func. -func tfLogFunc(ctx context.Context) eblog.Func { - return func(level eblog.Level, format string, args ...any) { - var logFn func(context.Context, string, ...map[string]interface{}) - switch level { - case eblog.LevelTrace: - logFn = tflog.Trace - case eblog.LevelDebug: - logFn = tflog.Debug - case eblog.LevelWarn: - logFn = tflog.Warn - case eblog.LevelError: - logFn = tflog.Error - default: - logFn = tflog.Info - } - logFn(ctx, fmt.Sprintf(format, args...)) - } -} - -// sortedKeyValues returns the keys and values of the map in the form "key=value" -// sorted by key in lexicographical order. -func sortedKeyValues(m map[string]string) []string { - pairs := make([]string, 0, len(m)) - var sb strings.Builder - for k := range m { - _, _ = sb.WriteString(k) - _, _ = sb.WriteRune('=') - _, _ = sb.WriteString(m[k]) - pairs = append(pairs, sb.String()) - sb.Reset() - } - sort.Strings(pairs) - return pairs -} diff --git a/internal/provider/cached_image_resource_test.go b/internal/provider/cached_image_resource_test.go index b5fcb1d..29e043a 100644 --- a/internal/provider/cached_image_resource_test.go +++ b/internal/provider/cached_image_resource_test.go @@ -34,13 +34,17 @@ func TestAccCachedImageResource(t *testing.T) { ".devcontainer/devcontainer.json": `{"image": "localhost:5000/test-ubuntu:latest"}`, }, extraEnv: map[string]string{ - "FOO": testEnvValue, + "CODER_AGENT_TOKEN": "some-token", + "CODER_AGENT_URL": "https://coder.example.com", "ENVBUILDER_GIT_URL": "https://not.the.real.git/url", "ENVBUILDER_CACHE_REPO": "not-the-real-cache-repo", + "FOO": testEnvValue, }, assertEnv: func(t *testing.T, deps testDependencies) resource.TestCheckFunc { return resource.ComposeAggregateTestCheckFunc( assertEnv(t, + "CODER_AGENT_TOKEN", "some-token", + "CODER_AGENT_URL", "https://coder.example.com", "ENVBUILDER_CACHE_REPO", deps.CacheRepo, "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key, "ENVBUILDER_GIT_URL", deps.Repo.URL, @@ -62,6 +66,8 @@ func TestAccCachedImageResource(t *testing.T) { RUN date > /date.txt`, }, extraEnv: map[string]string{ + "CODER_AGENT_TOKEN": "some-token", + "CODER_AGENT_URL": "https://coder.example.com", "FOO": testEnvValue, "ENVBUILDER_GIT_URL": "https://not.the.real.git/url", "ENVBUILDER_CACHE_REPO": "not-the-real-cache-repo", @@ -69,6 +75,8 @@ RUN date > /date.txt`, assertEnv: func(t *testing.T, deps testDependencies) resource.TestCheckFunc { return resource.ComposeAggregateTestCheckFunc( assertEnv(t, + "CODER_AGENT_TOKEN", "some-token", + "CODER_AGENT_URL", "https://coder.example.com", "ENVBUILDER_CACHE_REPO", deps.CacheRepo, "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key, "ENVBUILDER_GIT_URL", deps.Repo.URL, @@ -89,6 +97,8 @@ RUN date > /date.txt`, RUN date > /date.txt`, }, extraEnv: map[string]string{ + "CODER_AGENT_TOKEN": "some-token", + "CODER_AGENT_URL": "https://coder.example.com", "FOO": testEnvValue, "ENVBUILDER_GIT_URL": "https://not.the.real.git/url", "ENVBUILDER_CACHE_REPO": "not-the-real-cache-repo", @@ -99,6 +109,8 @@ RUN date > /date.txt`, assertEnv: func(t *testing.T, deps testDependencies) resource.TestCheckFunc { return resource.ComposeAggregateTestCheckFunc( assertEnv(t, + "CODER_AGENT_TOKEN", "some-token", + "CODER_AGENT_URL", "https://coder.example.com", "ENVBUILDER_CACHE_REPO", deps.CacheRepo, "ENVBUILDER_DEVCONTAINER_DIR", "path/to/.devcontainer", "ENVBUILDER_DEVCONTAINER_JSON_PATH", "path/to/.devcontainer/devcontainer.json", diff --git a/internal/provider/helpers.go b/internal/provider/helpers.go new file mode 100644 index 0000000..21137f1 --- /dev/null +++ b/internal/provider/helpers.go @@ -0,0 +1,255 @@ +package provider + +import ( + "fmt" + "strings" + + eboptions "github.com/coder/envbuilder/options" + "github.com/coder/serpent" + "github.com/coder/terraform-provider-envbuilder/internal/tfutil" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/spf13/pflag" +) + +const ( + envbuilderOptionPrefix = "ENVBUILDER_" +) + +// nonOverrideOptions are options that cannot be overridden by extra_env. +var nonOverrideOptions = map[string]bool{ + "ENVBUILDER_CACHE_REPO": true, + "ENVBUILDER_GIT_URL": true, +} + +// optionsFromDataModel converts a CachedImageResourceModel into a corresponding set of +// Envbuilder options. It returns the options and any diagnostics encountered. +func optionsFromDataModel(data CachedImageResourceModel) (eboptions.Options, diag.Diagnostics) { + var diags diag.Diagnostics + var opts eboptions.Options + + // Required options. Cannot be overridden by extra_env. + opts.CacheRepo = data.CacheRepo.ValueString() + opts.GitURL = data.GitURL.ValueString() + + // Other options can be overridden by extra_env, with a warning. + // Keep track of which options are set from the data model so we + // can check if they are being overridden. + providerOpts := make(map[string]bool) + + if !data.BaseImageCacheDir.IsNull() { + providerOpts["ENVBUILDER_BASE_IMAGE_CACHE_DIR"] = true + opts.BaseImageCacheDir = data.BaseImageCacheDir.ValueString() + } + + if !data.BuildContextPath.IsNull() { + providerOpts["ENVBUILDER_BUILD_CONTEXT_PATH"] = true + opts.BuildContextPath = data.BuildContextPath.ValueString() + } + + if !data.CacheTTLDays.IsNull() { + providerOpts["ENVBUILDER_CACHE_TTL_DAYS"] = true + opts.CacheTTLDays = data.CacheTTLDays.ValueInt64() + } + + if !data.DevcontainerDir.IsNull() { + providerOpts["ENVBUILDER_DEVCONTAINER_DIR"] = true + opts.DevcontainerDir = data.DevcontainerDir.ValueString() + } + + if !data.DevcontainerJSONPath.IsNull() { + providerOpts["ENVBUILDER_DEVCONTAINER_JSON_PATH"] = true + opts.DevcontainerJSONPath = data.DevcontainerJSONPath.ValueString() + } + + if !data.DockerfilePath.IsNull() { + providerOpts["ENVBUILDER_DOCKERFILE_PATH"] = true + opts.DockerfilePath = data.DockerfilePath.ValueString() + } + + if !data.DockerConfigBase64.IsNull() { + providerOpts["ENVBUILDER_DOCKER_CONFIG_BASE64"] = true + opts.DockerConfigBase64 = data.DockerConfigBase64.ValueString() + } + + if !data.ExitOnBuildFailure.IsNull() { + providerOpts["ENVBUILDER_EXIT_ON_BUILD_FAILURE"] = true + opts.ExitOnBuildFailure = data.ExitOnBuildFailure.ValueBool() + } + + if !data.FallbackImage.IsNull() { + providerOpts["ENVBUILDER_FALLBACK_IMAGE"] = true + opts.FallbackImage = data.FallbackImage.ValueString() + } + + if !data.GitCloneDepth.IsNull() { + providerOpts["ENVBUILDER_GIT_CLONE_DEPTH"] = true + opts.GitCloneDepth = data.GitCloneDepth.ValueInt64() + } + + if !data.GitCloneSingleBranch.IsNull() { + providerOpts["ENVBUILDER_GIT_CLONE_SINGLE_BRANCH"] = true + opts.GitCloneSingleBranch = data.GitCloneSingleBranch.ValueBool() + } + + if !data.GitHTTPProxyURL.IsNull() { + providerOpts["ENVBUILDER_GIT_HTTP_PROXY_URL"] = true + opts.GitHTTPProxyURL = data.GitHTTPProxyURL.ValueString() + } + + if !data.GitSSHPrivateKeyPath.IsNull() { + providerOpts["ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH"] = true + opts.GitSSHPrivateKeyPath = data.GitSSHPrivateKeyPath.ValueString() + } + + if !data.GitUsername.IsNull() { + providerOpts["ENVBUILDER_GIT_USERNAME"] = true + opts.GitUsername = data.GitUsername.ValueString() + } + + if !data.GitPassword.IsNull() { + providerOpts["ENVBUILDER_GIT_PASSWORD"] = true + opts.GitPassword = data.GitPassword.ValueString() + } + + if !data.IgnorePaths.IsNull() { + providerOpts["ENVBUILDER_IGNORE_PATHS"] = true + opts.IgnorePaths = tfutil.TFListToStringSlice(data.IgnorePaths) + } + + if !data.Insecure.IsNull() { + providerOpts["ENVBUILDER_INSECURE"] = true + opts.Insecure = data.Insecure.ValueBool() + } + + if data.RemoteRepoBuildMode.IsNull() { + opts.RemoteRepoBuildMode = true + } else { + providerOpts["ENVBUILDER_REMOTE_REPO_BUILD_MODE"] = true + opts.RemoteRepoBuildMode = data.RemoteRepoBuildMode.ValueBool() + } + + if !data.SSLCertBase64.IsNull() { + providerOpts["ENVBUILDER_SSL_CERT_BASE64"] = true + opts.SSLCertBase64 = data.SSLCertBase64.ValueString() + } + + if !data.Verbose.IsNull() { + providerOpts["ENVBUILDER_VERBOSE"] = true + opts.Verbose = data.Verbose.ValueBool() + } + + if !data.WorkspaceFolder.IsNull() { + providerOpts["ENVBUILDER_WORKSPACE_FOLDER"] = true + opts.WorkspaceFolder = data.WorkspaceFolder.ValueString() + } + + // convert extraEnv to a map for ease of use. + extraEnv := make(map[string]string) + for k, v := range data.ExtraEnv.Elements() { + extraEnv[k] = tfutil.TFValueToString(v) + } + diags = append(diags, overrideOptionsFromExtraEnv(&opts, extraEnv, providerOpts)...) + + return opts, diags +} + +// overrideOptionsFromExtraEnv overrides the options in opts with values from extraEnv. +// It returns any diagnostics encountered. +// It will not override certain options, such as ENVBUILDER_CACHE_REPO and ENVBUILDER_GIT_URL. +func overrideOptionsFromExtraEnv(opts *eboptions.Options, extraEnv map[string]string, providerOpts map[string]bool) diag.Diagnostics { + var diags diag.Diagnostics + // Make a map of the options for easy lookup. + optsMap := make(map[string]pflag.Value) + for _, opt := range opts.CLI() { + optsMap[opt.Env] = opt.Value + } + for key, val := range extraEnv { + opt, found := optsMap[key] + if !found { + // ignore unknown keys + continue + } + + if nonOverrideOptions[key] { + diags.AddAttributeWarning(path.Root("extra_env"), + "Cannot override required environment variable", + fmt.Sprintf("The key %q in extra_env cannot be overridden.", key), + ) + continue + } + + // Check if the option was set on the provider data model and generate a warning if so. + if providerOpts[key] { + diags.AddAttributeWarning(path.Root("extra_env"), + "Overriding provider environment variable", + fmt.Sprintf("The key %q in extra_env overrides an option set on the provider.", key), + ) + } + + // XXX: workaround for serpent behaviour where calling Set() on a + // string slice will append instead of replace: set to empty first. + if key == "ENVBUILDER_IGNORE_PATHS" { + _ = optsMap[key].Set("") + } + + if err := opt.Set(val); err != nil { + diags.AddAttributeError(path.Root("extra_env"), + "Invalid value for environment variable", + fmt.Sprintf("The key %q in extra_env has an invalid value: %s", key, err), + ) + } + } + return diags +} + +// computeEnvFromOptions computes the environment variables to set based on the +// options in opts and the extra environment variables in extraEnv. +// It returns the computed environment variables as a map. +// It will not set certain options, such as ENVBUILDER_CACHE_REPO and ENVBUILDER_GIT_URL. +// It will also not handle legacy Envbuilder options (i.e. those not prefixed with ENVBUILDER_). +func computeEnvFromOptions(opts eboptions.Options, extraEnv map[string]string) map[string]string { + for _, opt := range opts.CLI() { + if opt.Env == "" { + continue + } + } + + computed := make(map[string]string) + for _, opt := range opts.CLI() { + if opt.Env == "" { + continue + } + // TODO: remove this check once support for legacy options is removed. + // Only set the environment variables from opts that are not legacy options. + // Legacy options are those that are not prefixed with ENVBUILDER_. + // While we can detect when a legacy option is set, overriding it becomes + // problematic. Erring on the side of caution, we will not override legacy options. + if !strings.HasPrefix(opt.Env, envbuilderOptionPrefix) { + continue + } + var val string + if sa, ok := opt.Value.(*serpent.StringArray); ok { + val = strings.Join(sa.GetSlice(), ",") + } else { + val = opt.Value.String() + } + + switch val { + case "", "false", "0": + // Skip zero values. + continue + } + computed[opt.Env] = val + } + + // Merge in extraEnv, which may override values from opts. + // Skip any keys that are envbuilder options. + for key, val := range extraEnv { + if strings.HasPrefix(key, envbuilderOptionPrefix) { + continue + } + computed[key] = val + } + return computed +} diff --git a/internal/provider/provider_internal_test.go b/internal/provider/provider_internal_test.go index 5601832..a9be0ae 100644 --- a/internal/provider/provider_internal_test.go +++ b/internal/provider/provider_internal_test.go @@ -284,9 +284,6 @@ func Test_computeEnvFromOptions(t *testing.T) { "FOO": "bar", // should be included }, expectEnv: map[string]string{ - "CODER_AGENT_SUBSYSTEM": "one,two", - "CODER_AGENT_TOKEN": "string", - "CODER_AGENT_URL": "string", "ENVBUILDER_BASE_IMAGE_CACHE_DIR": "string", "ENVBUILDER_BINARY_PATH": "string", "ENVBUILDER_BUILD_CONTEXT_PATH": "string", diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index de9ad8c..26dc7d4 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -118,7 +118,7 @@ func seedCache(ctx context.Context, t testing.TB, deps testDependencies) { } for k, v := range deps.ExtraEnv { - if !strings.HasPrefix(k, "ENVBUILDER_") { + if !strings.HasPrefix(k, envbuilderOptionPrefix) { continue } if _, ok := seedEnv[k]; ok { diff --git a/internal/tfutil/tfutil.go b/internal/tfutil/tfutil.go new file mode 100644 index 0000000..3366b6f --- /dev/null +++ b/internal/tfutil/tfutil.go @@ -0,0 +1,92 @@ +package tfutil + +import ( + "context" + "fmt" + "sort" + "strings" + + "github.com/coder/envbuilder/log" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +// TFValueToString converts an attr.Value to its string representation +// based on its Terraform type. This is needed because the String() +// method on an attr.Value creates a 'human-readable' version of the type, which +// leads to quotes, escaped characters, and other assorted sadness. +func TFValueToString(val attr.Value) string { + if val.IsUnknown() || val.IsNull() { + return "" + } + if vs, ok := val.(interface{ ValueString() string }); ok { + return vs.ValueString() + } + if vb, ok := val.(interface{ ValueBool() bool }); ok { + return fmt.Sprintf("%t", vb.ValueBool()) + } + if vi, ok := val.(interface{ ValueInt64() int64 }); ok { + return fmt.Sprintf("%d", vi.ValueInt64()) + } + panic(fmt.Errorf("tfValueToString: value %T is not a supported type", val)) +} + +// TFListToStringSlice converts a types.List to a []string by calling +// tfValueToString on each element. +func TFListToStringSlice(l types.List) []string { + els := l.Elements() + ss := make([]string, len(els)) + for idx, el := range els { + ss[idx] = TFValueToString(el) + } + return ss +} + +// TFMapToStringMap converts a types.Map to a map[string]string by calling +// tfValueToString on each element. +func TFMapToStringMap(m types.Map) map[string]string { + els := m.Elements() + res := make(map[string]string, len(els)) + for k, v := range els { + res[k] = TFValueToString(v) + } + return res +} + +// TFLogFunc is an adapter to envbuilder/log.Func. +func TFLogFunc(ctx context.Context) log.Func { + return func(level log.Level, format string, args ...any) { + var logFn func(context.Context, string, ...map[string]interface{}) + switch level { + case log.LevelTrace: + logFn = tflog.Trace + case log.LevelDebug: + logFn = tflog.Debug + case log.LevelWarn: + logFn = tflog.Warn + case log.LevelError: + logFn = tflog.Error + default: + logFn = tflog.Info + } + logFn(ctx, fmt.Sprintf(format, args...)) + } +} + +// DockerEnv returns the keys and values of the map in the form "key=value" +// sorted by key in lexicographical order. This is the format expected by +// Docker and some other tools that consume environment variables. +func DockerEnv(m map[string]string) []string { + pairs := make([]string, 0, len(m)) + var sb strings.Builder + for k := range m { + _, _ = sb.WriteString(k) + _, _ = sb.WriteRune('=') + _, _ = sb.WriteString(m[k]) + pairs = append(pairs, sb.String()) + sb.Reset() + } + sort.Strings(pairs) + return pairs +} From 6137223cea8c4ccc5c7b650c60423e848e515004 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 5 Sep 2024 17:41:42 +0100 Subject: [PATCH 17/40] update kaniko to latest main to keep in sync with envbuilder (#47) --- go.mod | 8 ++--- go.sum | 8 ++--- .../provider/cached_image_resource_test.go | 34 +++++++++++++++++++ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 923e81f..d05a28a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/coder/terraform-provider-envbuilder go 1.22.4 // We use our own Kaniko fork. -replace github.com/GoogleContainerTools/kaniko => github.com/coder/kaniko v0.0.0-20240807142221-ffc5e60fca41 +replace github.com/GoogleContainerTools/kaniko => github.com/coder/kaniko v0.0.0-20240830141327-f307586e3dca // Required to import codersdk due to gvisor dependency. replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa558fbe5374 @@ -11,6 +11,7 @@ replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa55 require ( github.com/GoogleContainerTools/kaniko v1.9.2 github.com/coder/envbuilder v1.0.0-rc.0.0.20240830145058-fb7e689f39ed + github.com/coder/serpent v0.7.0 github.com/docker/docker v26.1.5+incompatible github.com/gliderlabs/ssh v0.3.7 github.com/go-git/go-billy/v5 v5.5.0 @@ -22,6 +23,7 @@ require ( github.com/hashicorp/terraform-plugin-go v0.23.0 github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/hashicorp/terraform-plugin-testing v1.10.0 + github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 ) @@ -96,7 +98,6 @@ require ( github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 // indirect github.com/coder/quartz v0.1.0 // indirect github.com/coder/retry v1.5.1 // indirect - github.com/coder/serpent v0.7.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 @@ -185,7 +186,6 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 // indirect github.com/jsimonetti/rtnetlink v1.3.5 // indirect - github.com/karrick/godirwalk v1.16.1 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/klauspost/compress v1.17.9 // indirect @@ -255,7 +255,6 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect github.com/tailscale/certstore v0.1.1-0.20220316223106-78d6e1c49d8d // indirect github.com/tailscale/golang-x-crypto v0.0.0-20230713185742-f0b76a10a08e // indirect github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 // indirect @@ -264,6 +263,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/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 github.com/vbatts/tar-split v0.11.5 // indirect diff --git a/go.sum b/go.sum index fd61f13..3678f90 100644 --- a/go.sum +++ b/go.sum @@ -188,8 +188,8 @@ github.com/coder/coder/v2 v2.10.1-0.20240704130443-c2d44d16a352 h1:L/EjCuZxs5tOc github.com/coder/coder/v2 v2.10.1-0.20240704130443-c2d44d16a352/go.mod h1:P1KoQSgnKEAG6Mnd3YlGzAophty+yKA9VV48LpfNRvo= github.com/coder/envbuilder v1.0.0-rc.0.0.20240830145058-fb7e689f39ed h1:sDEjs9qB2uJ7O85vGmzMja99IZuLvesxElOUFyy22UY= github.com/coder/envbuilder v1.0.0-rc.0.0.20240830145058-fb7e689f39ed/go.mod h1:LWImvtIWaX3eiAI3zyU46WE/PrE099nCut1zJultSk0= -github.com/coder/kaniko v0.0.0-20240807142221-ffc5e60fca41 h1:1Ye7AcLnuT5IDv6il7Fxo+aqpzlWfedkpraCCwx8Lyo= -github.com/coder/kaniko v0.0.0-20240807142221-ffc5e60fca41/go.mod h1:YMK7BlxerzLlMwihGxNWUaFoN9LXCij4P+w/8/fNlcM= +github.com/coder/kaniko v0.0.0-20240830141327-f307586e3dca h1:PrcSWrllqipTrtet50a3VyAJEQmjziIZyhpy0bsC6o0= +github.com/coder/kaniko v0.0.0-20240830141327-f307586e3dca/go.mod h1:XoTDIhNF0Ll4tLmRYdOn31udU9w5zFrY2PME/crSRCA= github.com/coder/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= @@ -524,8 +524,6 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= -github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= @@ -774,6 +772,8 @@ 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/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= +github.com/twpayne/go-vfs/v5 v5.0.4/go.mod h1:zTPFJUbgsEMFNSWnWQlLq9wh4AN83edZzx3VXbxrS1w= github.com/u-root/uio v0.0.0-20240209044354-b3d14b93376a h1:BH1SOPEvehD2kVrndDnGJiUF0TrBpNs+iyYocu6h0og= github.com/u-root/uio v0.0.0-20240209044354-b3d14b93376a/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= diff --git a/internal/provider/cached_image_resource_test.go b/internal/provider/cached_image_resource_test.go index 29e043a..00b50ff 100644 --- a/internal/provider/cached_image_resource_test.go +++ b/internal/provider/cached_image_resource_test.go @@ -124,6 +124,40 @@ RUN date > /date.txt`, ) }, }, + { + // This tests that a multi-stage build works correctly. + name: "multistage_run_copy", + files: map[string]string{ + "Dockerfile": ` + FROM localhost:5000/test-ubuntu:latest AS a + RUN date > /date.txt + FROM localhost:5000/test-ubuntu:latest + COPY --from=a /date.txt /date.txt`, + }, + extraEnv: map[string]string{ + "CODER_AGENT_TOKEN": "some-token", + "CODER_AGENT_URL": "https://coder.example.com", + "FOO": testEnvValue, + "ENVBUILDER_GIT_URL": "https://not.the.real.git/url", + "ENVBUILDER_CACHE_REPO": "not-the-real-cache-repo", + "ENVBUILDER_DOCKERFILE_PATH": "Dockerfile", + }, + assertEnv: func(t *testing.T, deps testDependencies) resource.TestCheckFunc { + return resource.ComposeAggregateTestCheckFunc( + assertEnv(t, + "CODER_AGENT_TOKEN", "some-token", + "CODER_AGENT_URL", "https://coder.example.com", + "ENVBUILDER_CACHE_REPO", deps.CacheRepo, + "ENVBUILDER_DOCKERFILE_PATH", "Dockerfile", + "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key, + "ENVBUILDER_GIT_URL", deps.Repo.URL, + "ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true", + "ENVBUILDER_VERBOSE", "true", + "FOO", "bar\nbaz", + ), + ) + }, + }, } { t.Run(tc.name, func(t *testing.T) { //nolint: paralleltest From 4077a87dca6852f7cb6dbcb4fa7005b9f3f7f5fd Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Tue, 10 Sep 2024 09:47:39 +0100 Subject: [PATCH 18/40] fix: set MagicDir to tempdir when performing cache probe (#48) * fix: set MagicDir to tempdir when performing cache probe * chore: update envbuilder to b7781d8 * imgutil: get default envbuilder binary path from envbuilder options --- go.mod | 4 +- go.sum | 8 ++-- internal/imgutil/imgutil.go | 7 +++- internal/provider/cached_image_resource.go | 12 ++---- .../provider/cached_image_resource_test.go | 9 +++-- internal/provider/provider_internal_test.go | 2 - internal/provider/provider_test.go | 38 +++++++++++++------ testutil/registrytest/registrytest.go | 22 ++++++++++- 8 files changed, 67 insertions(+), 35 deletions(-) diff --git a/go.mod b/go.mod index d05a28a..6d869ee 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa55 require ( github.com/GoogleContainerTools/kaniko v1.9.2 - github.com/coder/envbuilder v1.0.0-rc.0.0.20240830145058-fb7e689f39ed + github.com/coder/envbuilder v1.0.0-rc.0.0.20240910082823-b7781d802f88 github.com/coder/serpent v0.7.0 github.com/docker/docker v26.1.5+incompatible github.com/gliderlabs/ssh v0.3.7 @@ -295,7 +295,7 @@ require ( go4.org/netipx v0.0.0-20230728180743-ad4cb58a6516 // indirect golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect - golang.org/x/mod v0.19.0 // indirect + golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect diff --git a/go.sum b/go.sum index 3678f90..744e4f0 100644 --- a/go.sum +++ b/go.sum @@ -186,8 +186,8 @@ github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoC github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/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/envbuilder v1.0.0-rc.0.0.20240830145058-fb7e689f39ed h1:sDEjs9qB2uJ7O85vGmzMja99IZuLvesxElOUFyy22UY= -github.com/coder/envbuilder v1.0.0-rc.0.0.20240830145058-fb7e689f39ed/go.mod h1:LWImvtIWaX3eiAI3zyU46WE/PrE099nCut1zJultSk0= +github.com/coder/envbuilder v1.0.0-rc.0.0.20240910082823-b7781d802f88 h1:eXOILD2tWepnV1r7XZalBX0yC4NJMnpf6OP1nF8O2Ak= +github.com/coder/envbuilder v1.0.0-rc.0.0.20240910082823-b7781d802f88/go.mod h1:krXpDmUsORgNNdvBe6tnwWCGGDLhabom1UUqAZq9+v0= github.com/coder/kaniko v0.0.0-20240830141327-f307586e3dca h1:PrcSWrllqipTrtet50a3VyAJEQmjziIZyhpy0bsC6o0= github.com/coder/kaniko v0.0.0-20240830141327-f307586e3dca/go.mod h1:XoTDIhNF0Ll4tLmRYdOn31udU9w5zFrY2PME/crSRCA= github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs= @@ -895,8 +895,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/internal/imgutil/imgutil.go b/internal/imgutil/imgutil.go index 5c2d96a..5c04441 100644 --- a/internal/imgutil/imgutil.go +++ b/internal/imgutil/imgutil.go @@ -7,8 +7,9 @@ import ( "io" "os" "path/filepath" + "strings" - "github.com/coder/envbuilder/constants" + eboptions "github.com/coder/envbuilder/options" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" v1 "github.com/google/go-containerregistry/pkg/v1" @@ -34,7 +35,9 @@ func GetRemoteImage(imgRef string) (v1.Image, error) { // ExtractEnvbuilderFromImage reads the image located at imgRef and extracts // MagicBinaryLocation to destPath. func ExtractEnvbuilderFromImage(ctx context.Context, imgRef, destPath string) error { - needle := filepath.Clean(constants.MagicBinaryLocation)[1:] // skip leading '/' + var o eboptions.Options + o.SetDefaults() + needle := strings.TrimPrefix(o.BinaryPath, "/") img, err := GetRemoteImage(imgRef) if err != nil { return fmt.Errorf("check remote image: %w", err) diff --git a/internal/provider/cached_image_resource.go b/internal/provider/cached_image_resource.go index 27adc98..9378094 100644 --- a/internal/provider/cached_image_resource.go +++ b/internal/provider/cached_image_resource.go @@ -10,7 +10,6 @@ import ( kconfig "github.com/GoogleContainerTools/kaniko/pkg/config" "github.com/coder/envbuilder" - "github.com/coder/envbuilder/constants" eboptions "github.com/coder/envbuilder/options" "github.com/coder/terraform-provider-envbuilder/internal/imgutil" "github.com/coder/terraform-provider-envbuilder/internal/tfutil" @@ -455,7 +454,7 @@ func runCacheProbe(ctx context.Context, builderImage string, opts eboptions.Opti }() oldKanikoDir := kconfig.KanikoDir - tmpKanikoDir := filepath.Join(tmpDir, constants.MagicDir) + tmpKanikoDir := filepath.Join(tmpDir, ".envbuilder") // Normally you would set the KANIKO_DIR environment variable, but we are importing kaniko directly. kconfig.KanikoDir = tmpKanikoDir tflog.Info(ctx, "set kaniko dir to "+tmpKanikoDir) @@ -467,6 +466,8 @@ func runCacheProbe(ctx context.Context, builderImage string, opts eboptions.Opti if err := os.MkdirAll(tmpKanikoDir, 0o755); err != nil { return nil, fmt.Errorf("failed to create kaniko dir: %w", err) } + // Use the temporary directory as our 'magic dir'. + opts.MagicDirBase = tmpKanikoDir // In order to correctly reproduce the final layer of the cached image, we // need the envbuilder binary used to originally build the image! @@ -496,13 +497,6 @@ func runCacheProbe(ctx context.Context, builderImage string, opts eboptions.Opti tflog.Debug(ctx, "workspace_folder not specified, using temp dir", map[string]any{"workspace_folder": opts.WorkspaceFolder}) } - // We need a place to clone the repo. - repoDir := filepath.Join(tmpDir, "repo") - if err := os.MkdirAll(repoDir, 0o755); err != nil { - return nil, fmt.Errorf("failed to create repo dir: %w", err) - } - opts.RemoteRepoDir = repoDir - // The below options are not relevant and are set to their zero value // explicitly. // They must be set by extra_env to be used in the final builder image. diff --git a/internal/provider/cached_image_resource_test.go b/internal/provider/cached_image_resource_test.go index 00b50ff..6b6c832 100644 --- a/internal/provider/cached_image_resource_test.go +++ b/internal/provider/cached_image_resource_test.go @@ -46,6 +46,7 @@ func TestAccCachedImageResource(t *testing.T) { "CODER_AGENT_TOKEN", "some-token", "CODER_AGENT_URL", "https://coder.example.com", "ENVBUILDER_CACHE_REPO", deps.CacheRepo, + "ENVBUILDER_DOCKER_CONFIG_BASE64", deps.DockerConfigBase64, "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key, "ENVBUILDER_GIT_URL", deps.Repo.URL, "ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true", @@ -78,6 +79,7 @@ RUN date > /date.txt`, "CODER_AGENT_TOKEN", "some-token", "CODER_AGENT_URL", "https://coder.example.com", "ENVBUILDER_CACHE_REPO", deps.CacheRepo, + "ENVBUILDER_DOCKER_CONFIG_BASE64", deps.DockerConfigBase64, "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key, "ENVBUILDER_GIT_URL", deps.Repo.URL, "ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true", @@ -88,9 +90,8 @@ RUN date > /date.txt`, }, }, { - // This test case ensures that parameters passed via extra_env are - // handled correctly. - name: "extra_env", + // This test case ensures that overriding the devcontainer directory works. + name: "different_dir", files: map[string]string{ "path/to/.devcontainer/devcontainer.json": `{"build": { "dockerfile": "Dockerfile" }}`, "path/to/.devcontainer/Dockerfile": `FROM localhost:5000/test-ubuntu:latest @@ -115,6 +116,7 @@ RUN date > /date.txt`, "ENVBUILDER_DEVCONTAINER_DIR", "path/to/.devcontainer", "ENVBUILDER_DEVCONTAINER_JSON_PATH", "path/to/.devcontainer/devcontainer.json", "ENVBUILDER_DOCKERFILE_PATH", "path/to/.devcontainer/Dockerfile", + "ENVBUILDER_DOCKER_CONFIG_BASE64", deps.DockerConfigBase64, "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key, "ENVBUILDER_GIT_URL", deps.Repo.URL, "ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true", @@ -149,6 +151,7 @@ RUN date > /date.txt`, "CODER_AGENT_URL", "https://coder.example.com", "ENVBUILDER_CACHE_REPO", deps.CacheRepo, "ENVBUILDER_DOCKERFILE_PATH", "Dockerfile", + "ENVBUILDER_DOCKER_CONFIG_BASE64", deps.DockerConfigBase64, "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key, "ENVBUILDER_GIT_URL", deps.Repo.URL, "ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true", diff --git a/internal/provider/provider_internal_test.go b/internal/provider/provider_internal_test.go index a9be0ae..aedfca2 100644 --- a/internal/provider/provider_internal_test.go +++ b/internal/provider/provider_internal_test.go @@ -272,7 +272,6 @@ func Test_computeEnvFromOptions(t *testing.T) { PostStartScriptPath: "string", PushImage: true, RemoteRepoBuildMode: true, - RemoteRepoDir: "string", SetupScript: "string", SkipRebuild: true, SSLCertBase64: "string", @@ -314,7 +313,6 @@ func Test_computeEnvFromOptions(t *testing.T) { "ENVBUILDER_POST_START_SCRIPT_PATH": "string", "ENVBUILDER_PUSH_IMAGE": "true", "ENVBUILDER_REMOTE_REPO_BUILD_MODE": "true", - "ENVBUILDER_REMOTE_REPO_DIR": "string", "ENVBUILDER_SETUP_SCRIPT": "string", "ENVBUILDER_SKIP_REBUILD": "true", "ENVBUILDER_SSL_CERT_BASE64": "string", diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index 26dc7d4..ef58b73 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -3,6 +3,7 @@ package provider import ( "bufio" "context" + "encoding/base64" "fmt" "io" "os" @@ -35,10 +36,11 @@ var testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServe // testDependencies contain information about stuff the test depends on. type testDependencies struct { - BuilderImage string - CacheRepo string - ExtraEnv map[string]string - Repo testGitRepoSSH + BuilderImage string + CacheRepo string + DockerConfigBase64 string + ExtraEnv map[string]string + Repo testGitRepoSSH } // Config generates a valid Terraform config file from the dependencies. @@ -47,8 +49,9 @@ func (d *testDependencies) Config(t testing.TB) string { tpl := `provider envbuilder {} resource "envbuilder_cached_image" "test" { - builder_image = {{ quote .BuilderImage }} + builder_image = {{ quote .BuilderImage }} cache_repo = {{ quote .CacheRepo }} + docker_config_base64 = {{ quote .DockerConfigBase64 }} git_url = {{ quote .Repo.URL }} extra_env = { "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH": {{ quote .Repo.Key }} @@ -78,19 +81,29 @@ func setup(ctx context.Context, t testing.TB, extraEnv, files map[string]string) envbuilderVersion := getEnvOrDefault("ENVBUILDER_VERSION", "latest") envbuilderImageRef := envbuilderImage + ":" + envbuilderVersion - // TODO: envbuilder creates /.envbuilder/bin/envbuilder owned by root:root which we are unable to clean up. - // This causes tests to fail. + testUsername := "testuser" + testPassword := "testpassword" + testAuthBase64 := base64.URLEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", testUsername, testPassword))) regDir := t.TempDir() - reg := registrytest.New(t, regDir) + reg := registrytest.New(t, regDir, registrytest.BasicAuthMW(t, testUsername, testPassword)) repoDir := setupGitRepo(t, files) gitRepo := serveGitRepoSSH(ctx, t, repoDir) + dockerConfigJSON := fmt.Sprintf(`{ + "auths": { + "%s": { + "auth": "%s", + } + } + }`, reg, testAuthBase64) + dockerConfigJSONBase64 := base64.StdEncoding.EncodeToString([]byte(dockerConfigJSON)) return testDependencies{ - BuilderImage: envbuilderImageRef, - CacheRepo: reg + "/test", - ExtraEnv: extraEnv, - Repo: gitRepo, + BuilderImage: envbuilderImageRef, + CacheRepo: reg + "/test", + ExtraEnv: extraEnv, + Repo: gitRepo, + DockerConfigBase64: dockerConfigJSONBase64, } } @@ -115,6 +128,7 @@ func seedCache(ctx context.Context, t testing.TB, deps testDependencies) { "ENVBUILDER_VERBOSE": "true", "ENVBUILDER_GIT_URL": deps.Repo.URL, "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH": "/id_ed25519", + "ENVBUILDER_DOCKER_CONFIG_BASE64": deps.DockerConfigBase64, } for k, v := range deps.ExtraEnv { diff --git a/testutil/registrytest/registrytest.go b/testutil/registrytest/registrytest.go index e18043a..be8d40d 100644 --- a/testutil/registrytest/registrytest.go +++ b/testutil/registrytest/registrytest.go @@ -2,6 +2,7 @@ package registrytest import ( "fmt" + "net/http" "net/http/httptest" "net/url" "testing" @@ -13,12 +14,31 @@ import ( // New starts a new Docker registry listening on localhost. // It will automatically shut down when the test finishes. // It will store data in dir. -func New(t testing.TB, dir string) string { +func New(t testing.TB, dir string, mws ...func(http.Handler) http.Handler) string { t.Helper() regHandler := registry.New(registry.WithBlobHandler(registry.NewDiskBlobHandler(dir))) + for _, mw := range mws { + regHandler = mw(regHandler) + } regSrv := httptest.NewServer(regHandler) t.Cleanup(func() { regSrv.Close() }) regSrvURL, err := url.Parse(regSrv.URL) require.NoError(t, err) return fmt.Sprintf("localhost:%s", regSrvURL.Port()) } + +func BasicAuthMW(t testing.TB, username, password string) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if username != "" || password != "" { + authUser, authPass, ok := r.BasicAuth() + if !ok || username != authUser || password != authPass { + t.Logf("basic auth failed: got user %q, pass %q", authUser, authPass) + w.WriteHeader(http.StatusUnauthorized) + return + } + } + next.ServeHTTP(w, r) + }) + } +} From 6c66d06af714bb9861094826b8112f44babff840 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 11:49:22 +0100 Subject: [PATCH 19/40] chore(deps): bump github.com/coder/serpent from 0.7.0 to 0.8.0 (#49) Bumps [github.com/coder/serpent](https://github.com/coder/serpent) from 0.7.0 to 0.8.0. - [Commits](https://github.com/coder/serpent/compare/v0.7.0...v0.8.0) --- updated-dependencies: - dependency-name: github.com/coder/serpent dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6d869ee..24c3ee5 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa55 require ( github.com/GoogleContainerTools/kaniko v1.9.2 github.com/coder/envbuilder v1.0.0-rc.0.0.20240910082823-b7781d802f88 - github.com/coder/serpent v0.7.0 + github.com/coder/serpent v0.8.0 github.com/docker/docker v26.1.5+incompatible github.com/gliderlabs/ssh v0.3.7 github.com/go-git/go-billy/v5 v5.5.0 diff --git a/go.sum b/go.sum index 744e4f0..a58cf0c 100644 --- a/go.sum +++ b/go.sum @@ -196,8 +196,8 @@ github.com/coder/quartz v0.1.0 h1:cLL+0g5l7xTf6ordRnUMMiZtRE8Sq5LxpghS63vEXrQ= github.com/coder/quartz v0.1.0/go.mod h1:vsiCc+AHViMKH2CQpGIpFgdHIEQsxwm8yCscqKmzbRA= github.com/coder/retry v1.5.1 h1:iWu8YnD8YqHs3XwqrqsjoBTAVqT9ml6z9ViJ2wlMiqc= github.com/coder/retry v1.5.1/go.mod h1:blHMk9vs6LkoRT9ZHyuZo360cufXEhrxqvEzeMtRGoY= -github.com/coder/serpent v0.7.0 h1:zGpD2GlF3lKIVkMjNGKbkip88qzd5r/TRcc30X/SrT0= -github.com/coder/serpent v0.7.0/go.mod h1:REkJ5ZFHQUWFTPLExhXYZ1CaHFjxvGNRlLXLdsI08YA= +github.com/coder/serpent v0.8.0 h1:6OR+k6fekhSeEDmwwzBgnSjaa7FfGGrMlc3GoAEH9dg= +github.com/coder/serpent v0.8.0/go.mod h1:cZFW6/fP+kE9nd/oRkEHJpG6sXCtQ+AX7WMMEHv0Y3Q= github.com/coder/tailscale v1.1.1-0.20240702054557-aa558fbe5374 h1:a5Eg7D5e2oAc0tN56ee4yxtiTo76ztpRlk6geljaZp8= github.com/coder/tailscale v1.1.1-0.20240702054557-aa558fbe5374/go.mod h1:rp6BIJxCp127/hvvDWNkHC9MxAlKvQfoOtBr8s5sCqo= github.com/coder/terraform-provider-coder v0.23.0 h1:DuNLWxhnGlXyG0g+OCAZRI6xd8+bJjIEnE4F3hYgA4E= @@ -632,6 +632,8 @@ github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKt github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A= +github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= From e565d7d145fcbed8bb83470522cefa351cd2d1b9 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Wed, 25 Sep 2024 13:48:48 +0100 Subject: [PATCH 20/40] fix: update envbuilder to include kaniko cache fix (#50) * chore: add test for copy perms * update kaniko and envbuilder to include fix * add multi-stage version of copy perms test * remove unnecessary chowns, collapse to single test * update envbuilder and kaniko --- go.mod | 4 +- go.sum | 12 ++++-- .../provider/cached_image_resource_test.go | 38 +++++++++++++++++++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 24c3ee5..e6bc076 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,14 @@ module github.com/coder/terraform-provider-envbuilder go 1.22.4 // We use our own Kaniko fork. -replace github.com/GoogleContainerTools/kaniko => github.com/coder/kaniko v0.0.0-20240830141327-f307586e3dca +replace github.com/GoogleContainerTools/kaniko => github.com/coder/kaniko v0.0.0-20240925122543-caa18967f374 // Required to import codersdk due to gvisor dependency. replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa558fbe5374 require ( github.com/GoogleContainerTools/kaniko v1.9.2 - github.com/coder/envbuilder v1.0.0-rc.0.0.20240910082823-b7781d802f88 + github.com/coder/envbuilder v1.0.0-rc.0.0.20240925123650-9c315aabfaef github.com/coder/serpent v0.8.0 github.com/docker/docker v26.1.5+incompatible github.com/gliderlabs/ssh v0.3.7 diff --git a/go.sum b/go.sum index a58cf0c..32f07ed 100644 --- a/go.sum +++ b/go.sum @@ -186,10 +186,14 @@ 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/envbuilder v1.0.0-rc.0.0.20240910082823-b7781d802f88 h1:eXOILD2tWepnV1r7XZalBX0yC4NJMnpf6OP1nF8O2Ak= -github.com/coder/envbuilder v1.0.0-rc.0.0.20240910082823-b7781d802f88/go.mod h1:krXpDmUsORgNNdvBe6tnwWCGGDLhabom1UUqAZq9+v0= -github.com/coder/kaniko v0.0.0-20240830141327-f307586e3dca h1:PrcSWrllqipTrtet50a3VyAJEQmjziIZyhpy0bsC6o0= -github.com/coder/kaniko v0.0.0-20240830141327-f307586e3dca/go.mod h1:XoTDIhNF0Ll4tLmRYdOn31udU9w5zFrY2PME/crSRCA= +github.com/coder/envbuilder v1.0.0-rc.0.0.20240924170424-29636303d05f h1:1KdB2Jbo+zLuG+R08/By1BIeHBcKXiOqv95wZ5+Ewks= +github.com/coder/envbuilder v1.0.0-rc.0.0.20240924170424-29636303d05f/go.mod h1:ju1iDjfVSUQS3tlaIItlRo8UwYbGN5KvOdnbOzlD/6I= +github.com/coder/envbuilder v1.0.0-rc.0.0.20240925123650-9c315aabfaef h1:l9mQMoHNl7P2tiahwM2zkUCdWsjSoLsUDn30Ndgsx0Y= +github.com/coder/envbuilder v1.0.0-rc.0.0.20240925123650-9c315aabfaef/go.mod h1:1Qn60Fx3oGZlwmRfTNkrGxrQJsEZ7XIUUPgzil2lte8= +github.com/coder/kaniko v0.0.0-20240924160037-1e6bd4e19fc6 h1:vLlV6P0abwoOeaBwkqQxB31ZzMv483UQLhQuPvXbvRM= +github.com/coder/kaniko v0.0.0-20240924160037-1e6bd4e19fc6/go.mod h1:XoTDIhNF0Ll4tLmRYdOn31udU9w5zFrY2PME/crSRCA= +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/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= diff --git a/internal/provider/cached_image_resource_test.go b/internal/provider/cached_image_resource_test.go index 6b6c832..86dd581 100644 --- a/internal/provider/cached_image_resource_test.go +++ b/internal/provider/cached_image_resource_test.go @@ -161,6 +161,44 @@ RUN date > /date.txt`, ) }, }, + { + // This tests correct handling of the difference in permissions between + // the provider and the image when running a COPY instruction. + // Added to verify fix for coder/terraform-provider-envbuilder#43 + name: "copy_perms", + files: map[string]string{ + "Dockerfile": ` + FROM localhost:5000/test-ubuntu:latest AS a + COPY date.txt /date.txt + FROM localhost:5000/test-ubuntu:latest + COPY --from=a /date.txt /date.txt`, + "date.txt": fmt.Sprintf("%d", time.Now().Unix()), + }, + extraEnv: map[string]string{ + "CODER_AGENT_TOKEN": "some-token", + "CODER_AGENT_URL": "https://coder.example.com", + "FOO": testEnvValue, + "ENVBUILDER_GIT_URL": "https://not.the.real.git/url", + "ENVBUILDER_CACHE_REPO": "not-the-real-cache-repo", + "ENVBUILDER_DOCKERFILE_PATH": "Dockerfile", + }, + assertEnv: func(t *testing.T, deps testDependencies) resource.TestCheckFunc { + return resource.ComposeAggregateTestCheckFunc( + assertEnv(t, + "CODER_AGENT_TOKEN", "some-token", + "CODER_AGENT_URL", "https://coder.example.com", + "ENVBUILDER_CACHE_REPO", deps.CacheRepo, + "ENVBUILDER_DOCKERFILE_PATH", "Dockerfile", + "ENVBUILDER_DOCKER_CONFIG_BASE64", deps.DockerConfigBase64, + "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", deps.Repo.Key, + "ENVBUILDER_GIT_URL", deps.Repo.URL, + "ENVBUILDER_REMOTE_REPO_BUILD_MODE", "true", + "ENVBUILDER_VERBOSE", "true", + "FOO", "bar\nbaz", + ), + ) + }, + }, } { t.Run(tc.name, func(t *testing.T) { //nolint: paralleltest From 437dde9144dd9c1fc218d23bc86657db2e86ad60 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Fri, 27 Sep 2024 21:21:46 +0100 Subject: [PATCH 21/40] update envbuilder to 5c150b3c1e35 (#54) --- go.mod | 2 +- go.sum | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index e6bc076..16b47b4 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa55 require ( github.com/GoogleContainerTools/kaniko v1.9.2 - github.com/coder/envbuilder v1.0.0-rc.0.0.20240925123650-9c315aabfaef + github.com/coder/envbuilder v1.0.0-rc.0.0.20240927195324-5c150b3c1e35 github.com/coder/serpent v0.8.0 github.com/docker/docker v26.1.5+incompatible github.com/gliderlabs/ssh v0.3.7 diff --git a/go.sum b/go.sum index 32f07ed..71badbc 100644 --- a/go.sum +++ b/go.sum @@ -186,12 +186,8 @@ github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoC github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/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/envbuilder v1.0.0-rc.0.0.20240924170424-29636303d05f h1:1KdB2Jbo+zLuG+R08/By1BIeHBcKXiOqv95wZ5+Ewks= -github.com/coder/envbuilder v1.0.0-rc.0.0.20240924170424-29636303d05f/go.mod h1:ju1iDjfVSUQS3tlaIItlRo8UwYbGN5KvOdnbOzlD/6I= -github.com/coder/envbuilder v1.0.0-rc.0.0.20240925123650-9c315aabfaef h1:l9mQMoHNl7P2tiahwM2zkUCdWsjSoLsUDn30Ndgsx0Y= -github.com/coder/envbuilder v1.0.0-rc.0.0.20240925123650-9c315aabfaef/go.mod h1:1Qn60Fx3oGZlwmRfTNkrGxrQJsEZ7XIUUPgzil2lte8= -github.com/coder/kaniko v0.0.0-20240924160037-1e6bd4e19fc6 h1:vLlV6P0abwoOeaBwkqQxB31ZzMv483UQLhQuPvXbvRM= -github.com/coder/kaniko v0.0.0-20240924160037-1e6bd4e19fc6/go.mod h1:XoTDIhNF0Ll4tLmRYdOn31udU9w5zFrY2PME/crSRCA= +github.com/coder/envbuilder v1.0.0-rc.0.0.20240927195324-5c150b3c1e35 h1:VtiMOd1q774fVZTSDuRlQcKbkQ1iNIDd2sqxcZ81cf0= +github.com/coder/envbuilder v1.0.0-rc.0.0.20240927195324-5c150b3c1e35/go.mod h1:1Qn60Fx3oGZlwmRfTNkrGxrQJsEZ7XIUUPgzil2lte8= 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/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs= From cdd57d3b36ff94b92a8f152e5ef6d152466aec6f Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Wed, 2 Oct 2024 14:45:15 +0300 Subject: [PATCH 22/40] chore(deps): update github.com/coder/envbuilder to v1.0.2 (#55) --- go.mod | 2 +- go.sum | 4 ++-- internal/provider/provider_test.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 16b47b4..0473867 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa55 require ( github.com/GoogleContainerTools/kaniko v1.9.2 - github.com/coder/envbuilder v1.0.0-rc.0.0.20240927195324-5c150b3c1e35 + github.com/coder/envbuilder v1.0.2 github.com/coder/serpent v0.8.0 github.com/docker/docker v26.1.5+incompatible github.com/gliderlabs/ssh v0.3.7 diff --git a/go.sum b/go.sum index 71badbc..ac631c7 100644 --- a/go.sum +++ b/go.sum @@ -186,8 +186,8 @@ github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoC github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/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/envbuilder v1.0.0-rc.0.0.20240927195324-5c150b3c1e35 h1:VtiMOd1q774fVZTSDuRlQcKbkQ1iNIDd2sqxcZ81cf0= -github.com/coder/envbuilder v1.0.0-rc.0.0.20240927195324-5c150b3c1e35/go.mod h1:1Qn60Fx3oGZlwmRfTNkrGxrQJsEZ7XIUUPgzil2lte8= +github.com/coder/envbuilder v1.0.2 h1:39YnrQKFoUW6++gdfV/TELOW8dZLE2VN3sxXbkYoaj4= +github.com/coder/envbuilder v1.0.2/go.mod h1:CkP/qKzWmK14I/aSPwEXoEHlss7OqYDmaM8Q7rDhwt8= 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/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs= diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index ef58b73..1df4490 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -194,7 +194,7 @@ SCANLOGS: } log := scanner.Text() t.Logf("envbuilder: %s", log) - if strings.Contains(log, "=== Running the init command") { + if strings.Contains(log, "=== Running init command") { break SCANLOGS } } From 875d1eb69ce94659abed2c6f695839d0ba93f7b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 18:48:07 -0500 Subject: [PATCH 23/40] chore(deps): bump github.com/coder/envbuilder from 1.0.2 to 1.0.3 (#57) Bumps [github.com/coder/envbuilder](https://github.com/coder/envbuilder) from 1.0.2 to 1.0.3. - [Release notes](https://github.com/coder/envbuilder/releases) - [Commits](https://github.com/coder/envbuilder/compare/v1.0.2...v1.0.3) --- updated-dependencies: - dependency-name: github.com/coder/envbuilder dependency-type: direct:production update-type: version-update:semver-patch ... 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 0473867..3518251 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa55 require ( github.com/GoogleContainerTools/kaniko v1.9.2 - github.com/coder/envbuilder v1.0.2 + github.com/coder/envbuilder v1.0.3 github.com/coder/serpent v0.8.0 github.com/docker/docker v26.1.5+incompatible github.com/gliderlabs/ssh v0.3.7 diff --git a/go.sum b/go.sum index ac631c7..a71417a 100644 --- a/go.sum +++ b/go.sum @@ -186,8 +186,8 @@ github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoC github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/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/envbuilder v1.0.2 h1:39YnrQKFoUW6++gdfV/TELOW8dZLE2VN3sxXbkYoaj4= -github.com/coder/envbuilder v1.0.2/go.mod h1:CkP/qKzWmK14I/aSPwEXoEHlss7OqYDmaM8Q7rDhwt8= +github.com/coder/envbuilder v1.0.3 h1:Ne2s+JBjGXwdO8PoNBEtgIos1a+VFB2iSuOBQHj+cFA= +github.com/coder/envbuilder v1.0.3/go.mod h1:CkP/qKzWmK14I/aSPwEXoEHlss7OqYDmaM8Q7rDhwt8= 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/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs= From 32d72a7b4e8730a1cfc671cedb8e3f23ada69572 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 18:48:36 -0500 Subject: [PATCH 24/40] chore(deps): bump golangci/golangci-lint-action from 6.1.0 to 6.1.1 (#56) Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 6.1.0 to 6.1.1. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/aaa42aa0628b4ae2578232a66b541047968fac86...971e284b6050e8a5849b72094c50ab08da042db8) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 66b5a40..fceccbc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,7 @@ jobs: - run: go mod download - run: go build -v . - name: Run linters - uses: golangci/golangci-lint-action@aaa42aa0628b4ae2578232a66b541047968fac86 # v6.1.0 + uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 with: version: latest From e7dc9a171ab549b9c8fc48923e7fa12c4083237a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:58:58 +0000 Subject: [PATCH 25/40] chore(deps): bump github.com/go-git/go-billy/v5 from 5.5.0 to 5.6.0 (#60) Bumps [github.com/go-git/go-billy/v5](https://github.com/go-git/go-billy) from 5.5.0 to 5.6.0. - [Release notes](https://github.com/go-git/go-billy/releases) - [Commits](https://github.com/go-git/go-billy/compare/v5.5.0...v5.6.0) --- updated-dependencies: - dependency-name: github.com/go-git/go-billy/v5 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 12 ++++++------ go.sum | 28 ++++++++++++++-------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/go.mod b/go.mod index 3518251..2435f51 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/coder/serpent v0.8.0 github.com/docker/docker v26.1.5+incompatible github.com/gliderlabs/ssh v0.3.7 - github.com/go-git/go-billy/v5 v5.5.0 + github.com/go-git/go-billy/v5 v5.6.0 github.com/go-git/go-git/v5 v5.12.0 github.com/google/go-containerregistry v0.20.2 github.com/google/uuid v1.6.0 @@ -114,7 +114,7 @@ require ( 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/cyphar/filepath-securejoin v0.2.5 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dimchansky/utfbom v1.1.1 // indirect @@ -294,16 +294,16 @@ require ( go4.org/mem v0.0.0-20220726221520-4f986261bf13 // indirect go4.org/netipx v0.0.0-20230728180743-ad4cb58a6516 // indirect golang.org/x/crypto v0.26.0 // indirect - golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.21.0 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.22.0 // indirect + golang.org/x/tools v0.23.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wireguard/windows v0.5.3 // indirect diff --git a/go.sum b/go.sum index a71417a..1e5903c 100644 --- a/go.sum +++ b/go.sum @@ -235,8 +235,8 @@ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo= +github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -309,8 +309,8 @@ github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= +github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= @@ -636,8 +636,8 @@ github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0 github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= @@ -887,8 +887,8 @@ 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/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= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -918,8 +918,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= @@ -972,8 +972,8 @@ 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.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.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= @@ -1008,8 +1008,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 311f01b14e252eb086cf67fc736d5079db7a08a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:11:31 +0000 Subject: [PATCH 26/40] chore(deps): bump crazy-max/ghaction-import-gpg from 6.1.0 to 6.2.0 (#59) Bumps [crazy-max/ghaction-import-gpg](https://github.com/crazy-max/ghaction-import-gpg) from 6.1.0 to 6.2.0. - [Release notes](https://github.com/crazy-max/ghaction-import-gpg/releases) - [Commits](https://github.com/crazy-max/ghaction-import-gpg/compare/v6.1.0...v6.2.0) --- updated-dependencies: - dependency-name: crazy-max/ghaction-import-gpg dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1966964..13013e9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,7 +22,7 @@ jobs: go-version: 1.22.4 - name: Import GPG Key id: import_gpg - uses: crazy-max/ghaction-import-gpg@v6.1.0 + uses: crazy-max/ghaction-import-gpg@v6.2.0 with: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.GPG_PASSPHRASE }} From 6795af2ba1f9b46af62d4f5b4d8bc8e6ccb32969 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 30 Oct 2024 14:15:44 +0000 Subject: [PATCH 27/40] feat: support ENVBUILDER_GIT_SSH_PRIVATE_KEY_BASE64 (#62) --- docs/resources/cached_image.md | 1 + go.mod | 2 +- go.sum | 4 +- internal/provider/cached_image_resource.go | 50 ++++++++++--------- internal/provider/helpers.go | 10 ++++ internal/provider/provider_internal_test.go | 53 +++++++++++++++++++++ 6 files changed, 95 insertions(+), 25 deletions(-) diff --git a/docs/resources/cached_image.md b/docs/resources/cached_image.md index a7f4a38..93923fe 100644 --- a/docs/resources/cached_image.md +++ b/docs/resources/cached_image.md @@ -37,6 +37,7 @@ The cached image resource can be used to retrieve a cached image produced by env - `git_clone_single_branch` (Boolean) (Envbuilder option) Clone only a single branch of the Git repository. - `git_http_proxy_url` (String) (Envbuilder option) The URL for the HTTP proxy. This is optional. - `git_password` (String, Sensitive) (Envbuilder option) The password to use for Git authentication. This is optional. +- `git_ssh_private_key_base64` (String, Sensitive) (Envbuilder option) Base64 encoded SSH private key to be used for Git authentication. - `git_ssh_private_key_path` (String) (Envbuilder option) Path to an SSH private key to be used for Git authentication. - `git_username` (String) (Envbuilder option) The username to use for Git authentication. This is optional. - `ignore_paths` (List of String) (Envbuilder option) The comma separated list of paths to ignore when building the workspace. diff --git a/go.mod b/go.mod index 2435f51..b961c18 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20240702054557-aa55 require ( github.com/GoogleContainerTools/kaniko v1.9.2 - github.com/coder/envbuilder v1.0.3 + github.com/coder/envbuilder v1.0.4 github.com/coder/serpent v0.8.0 github.com/docker/docker v26.1.5+incompatible github.com/gliderlabs/ssh v0.3.7 diff --git a/go.sum b/go.sum index 1e5903c..cf57857 100644 --- a/go.sum +++ b/go.sum @@ -186,8 +186,8 @@ github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoC github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/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/envbuilder v1.0.3 h1:Ne2s+JBjGXwdO8PoNBEtgIos1a+VFB2iSuOBQHj+cFA= -github.com/coder/envbuilder v1.0.3/go.mod h1:CkP/qKzWmK14I/aSPwEXoEHlss7OqYDmaM8Q7rDhwt8= +github.com/coder/envbuilder v1.0.4 h1:27DFtKhgsode5I0kBPTCHuzG88Zpny27OVvXOuA/zso= +github.com/coder/envbuilder v1.0.4/go.mod h1:CkP/qKzWmK14I/aSPwEXoEHlss7OqYDmaM8Q7rDhwt8= 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/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs= diff --git a/internal/provider/cached_image_resource.go b/internal/provider/cached_image_resource.go index 9378094..097b5fd 100644 --- a/internal/provider/cached_image_resource.go +++ b/internal/provider/cached_image_resource.go @@ -49,28 +49,29 @@ type CachedImageResourceModel struct { CacheRepo types.String `tfsdk:"cache_repo"` GitURL types.String `tfsdk:"git_url"` // Optional "inputs". - BaseImageCacheDir types.String `tfsdk:"base_image_cache_dir"` - BuildContextPath types.String `tfsdk:"build_context_path"` - CacheTTLDays types.Int64 `tfsdk:"cache_ttl_days"` - DevcontainerDir types.String `tfsdk:"devcontainer_dir"` - DevcontainerJSONPath types.String `tfsdk:"devcontainer_json_path"` - DockerfilePath types.String `tfsdk:"dockerfile_path"` - DockerConfigBase64 types.String `tfsdk:"docker_config_base64"` - ExitOnBuildFailure types.Bool `tfsdk:"exit_on_build_failure"` - ExtraEnv types.Map `tfsdk:"extra_env"` - FallbackImage types.String `tfsdk:"fallback_image"` - GitCloneDepth types.Int64 `tfsdk:"git_clone_depth"` - GitCloneSingleBranch types.Bool `tfsdk:"git_clone_single_branch"` - GitHTTPProxyURL types.String `tfsdk:"git_http_proxy_url"` - GitPassword types.String `tfsdk:"git_password"` - GitSSHPrivateKeyPath types.String `tfsdk:"git_ssh_private_key_path"` - GitUsername types.String `tfsdk:"git_username"` - IgnorePaths types.List `tfsdk:"ignore_paths"` - Insecure types.Bool `tfsdk:"insecure"` - RemoteRepoBuildMode types.Bool `tfsdk:"remote_repo_build_mode"` - SSLCertBase64 types.String `tfsdk:"ssl_cert_base64"` - Verbose types.Bool `tfsdk:"verbose"` - WorkspaceFolder types.String `tfsdk:"workspace_folder"` + BaseImageCacheDir types.String `tfsdk:"base_image_cache_dir"` + BuildContextPath types.String `tfsdk:"build_context_path"` + CacheTTLDays types.Int64 `tfsdk:"cache_ttl_days"` + DevcontainerDir types.String `tfsdk:"devcontainer_dir"` + DevcontainerJSONPath types.String `tfsdk:"devcontainer_json_path"` + DockerfilePath types.String `tfsdk:"dockerfile_path"` + DockerConfigBase64 types.String `tfsdk:"docker_config_base64"` + ExitOnBuildFailure types.Bool `tfsdk:"exit_on_build_failure"` + ExtraEnv types.Map `tfsdk:"extra_env"` + FallbackImage types.String `tfsdk:"fallback_image"` + GitCloneDepth types.Int64 `tfsdk:"git_clone_depth"` + GitCloneSingleBranch types.Bool `tfsdk:"git_clone_single_branch"` + GitHTTPProxyURL types.String `tfsdk:"git_http_proxy_url"` + GitPassword types.String `tfsdk:"git_password"` + GitSSHPrivateKeyPath types.String `tfsdk:"git_ssh_private_key_path"` + GitSSHPrivateKeyBase64 types.String `tfsdk:"git_ssh_private_key_base64"` + GitUsername types.String `tfsdk:"git_username"` + IgnorePaths types.List `tfsdk:"ignore_paths"` + Insecure types.Bool `tfsdk:"insecure"` + RemoteRepoBuildMode types.Bool `tfsdk:"remote_repo_build_mode"` + SSLCertBase64 types.String `tfsdk:"ssl_cert_base64"` + Verbose types.Bool `tfsdk:"verbose"` + WorkspaceFolder types.String `tfsdk:"workspace_folder"` // Computed "outputs". Env types.List `tfsdk:"env"` EnvMap types.Map `tfsdk:"env_map"` @@ -186,6 +187,11 @@ func (r *CachedImageResource) Schema(ctx context.Context, req resource.SchemaReq MarkdownDescription: "(Envbuilder option) Path to an SSH private key to be used for Git authentication.", Optional: true, }, + "git_ssh_private_key_base64": schema.StringAttribute{ + MarkdownDescription: "(Envbuilder option) Base64 encoded SSH private key to be used for Git authentication.", + Optional: true, + Sensitive: true, + }, "git_username": schema.StringAttribute{ MarkdownDescription: "(Envbuilder option) The username to use for Git authentication. This is optional.", Optional: true, diff --git a/internal/provider/helpers.go b/internal/provider/helpers.go index 21137f1..af4d237 100644 --- a/internal/provider/helpers.go +++ b/internal/provider/helpers.go @@ -102,6 +102,11 @@ func optionsFromDataModel(data CachedImageResourceModel) (eboptions.Options, dia opts.GitSSHPrivateKeyPath = data.GitSSHPrivateKeyPath.ValueString() } + if !data.GitSSHPrivateKeyBase64.IsNull() { + providerOpts["ENVBUILDER_GIT_SSH_PRIVATE_KEY_BASE64"] = true + opts.GitSSHPrivateKeyBase64 = data.GitSSHPrivateKeyBase64.ValueString() + } + if !data.GitUsername.IsNull() { providerOpts["ENVBUILDER_GIT_USERNAME"] = true opts.GitUsername = data.GitUsername.ValueString() @@ -151,6 +156,11 @@ func optionsFromDataModel(data CachedImageResourceModel) (eboptions.Options, dia } diags = append(diags, overrideOptionsFromExtraEnv(&opts, extraEnv, providerOpts)...) + if opts.GitSSHPrivateKeyPath != "" && opts.GitSSHPrivateKeyBase64 != "" { + diags.AddError("Cannot set more than one git ssh private key option", + "Both ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH and ENVBUILDER_GIT_SSH_PRIVATE_KEY_BASE64 have been set.") + } + return opts, diags } diff --git a/internal/provider/provider_internal_test.go b/internal/provider/provider_internal_test.go index aedfca2..c273a8c 100644 --- a/internal/provider/provider_internal_test.go +++ b/internal/provider/provider_internal_test.go @@ -211,6 +211,59 @@ func Test_optionsFromDataModel(t *testing.T) { }, expectNumErrorDiags: 2, }, + { + name: "errors when git ssh private key path and base64 are set", + data: CachedImageResourceModel{ + BuilderImage: basetypes.NewStringValue("envbuilder:latest"), + CacheRepo: basetypes.NewStringValue("localhost:5000/cache"), + GitURL: basetypes.NewStringValue("git@git.local/devcontainer.git"), + GitSSHPrivateKeyPath: basetypes.NewStringValue("/tmp/id_rsa"), + GitSSHPrivateKeyBase64: basetypes.NewStringValue("cHJpdmF0ZUtleQo="), + }, + expectOpts: eboptions.Options{ + CacheRepo: "localhost:5000/cache", + GitURL: "git@git.local/devcontainer.git", + RemoteRepoBuildMode: true, + GitSSHPrivateKeyPath: "/tmp/id_rsa", + GitSSHPrivateKeyBase64: "cHJpdmF0ZUtleQo=", + }, + expectNumErrorDiags: 1, + }, + { + name: "extra_env override errors when git ssh private key path and base64 are set", + data: CachedImageResourceModel{ + BuilderImage: basetypes.NewStringValue("envbuilder:latest"), + CacheRepo: basetypes.NewStringValue("localhost:5000/cache"), + GitURL: basetypes.NewStringValue("git@git.local/devcontainer.git"), + GitSSHPrivateKeyBase64: basetypes.NewStringValue("cHJpdmF0ZUtleQo="), + ExtraEnv: extraEnvMap(t, + "ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH", "/tmp/id_rsa", + ), + }, + expectOpts: eboptions.Options{ + CacheRepo: "localhost:5000/cache", + GitURL: "git@git.local/devcontainer.git", + RemoteRepoBuildMode: true, + GitSSHPrivateKeyPath: "/tmp/id_rsa", + GitSSHPrivateKeyBase64: "cHJpdmF0ZUtleQo=", + }, + expectNumErrorDiags: 1, + }, + { + name: "required only with base64 ssh key", + data: CachedImageResourceModel{ + BuilderImage: basetypes.NewStringValue("envbuilder:latest"), + CacheRepo: basetypes.NewStringValue("localhost:5000/cache"), + GitURL: basetypes.NewStringValue("git@git.local/devcontainer.git"), + GitSSHPrivateKeyBase64: basetypes.NewStringValue("cHJpdmF0ZUtleQo="), + }, + expectOpts: eboptions.Options{ + CacheRepo: "localhost:5000/cache", + GitURL: "git@git.local/devcontainer.git", + RemoteRepoBuildMode: true, + GitSSHPrivateKeyBase64: "cHJpdmF0ZUtleQo=", + }, + }, } { t.Run(tc.name, func(t *testing.T) { t.Parallel() From 1a997fdd608b858ba5a75dcd2818b8179343873c Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Tue, 7 Jan 2025 12:26:25 +0000 Subject: [PATCH 28/40] chore: update go-git to v5.13.1 (#72) --- .github/workflows/test.yml | 4 +++ go.mod | 24 +++++++++--------- go.sum | 52 +++++++++++++++++++------------------- 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fceccbc..4835018 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,6 +38,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 + with: + terraform_version: "1.9.*" + terraform_wrapper: false - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 with: go-version-file: "go.mod" diff --git a/go.mod b/go.mod index b961c18..b9fdc31 100644 --- a/go.mod +++ b/go.mod @@ -13,9 +13,9 @@ require ( github.com/coder/envbuilder v1.0.4 github.com/coder/serpent v0.8.0 github.com/docker/docker v26.1.5+incompatible - github.com/gliderlabs/ssh v0.3.7 - github.com/go-git/go-billy/v5 v5.6.0 - github.com/go-git/go-git/v5 v5.12.0 + github.com/gliderlabs/ssh v0.3.8 + github.com/go-git/go-billy/v5 v5.6.1 + github.com/go-git/go-git/v5 v5.13.1 github.com/google/go-containerregistry v0.20.2 github.com/google/uuid v1.6.0 github.com/hashicorp/terraform-plugin-docs v0.19.4 @@ -24,7 +24,7 @@ require ( github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/hashicorp/terraform-plugin-testing v1.10.0 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 ) require ( @@ -59,7 +59,7 @@ require ( github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Microsoft/hcsshim v0.11.7 // indirect - github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect + github.com/ProtonMail/go-crypto v1.1.3 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/akutz/memconn v0.1.0 // indirect github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 // indirect @@ -114,7 +114,7 @@ require ( 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.5 // indirect + github.com/cyphar/filepath-securejoin v0.3.6 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dimchansky/utfbom v1.1.1 // indirect @@ -293,15 +293,15 @@ 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/crypto v0.26.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.21.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.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 golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect diff --git a/go.sum b/go.sum index cf57857..49ed488 100644 --- a/go.sum +++ b/go.sum @@ -81,8 +81,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Microsoft/hcsshim v0.11.7 h1:vl/nj3Bar/CvJSYo7gIQPyRWc9f3c6IeSNavBTSZNZQ= github.com/Microsoft/hcsshim v0.11.7/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU= -github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= -github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk= +github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A= @@ -235,8 +235,8 @@ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo= -github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= +github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -275,8 +275,8 @@ github.com/ePirat/docker-credential-gitlabci v1.0.0 h1:YRkUSvkON6rT88vtscClAmPEY github.com/ePirat/docker-credential-gitlabci v1.0.0/go.mod h1:Ptmh+D0lzBQtgb6+QHjXl9HqOn3T1P8fKUHldiSQQGA= github.com/ebitengine/purego v0.6.0-alpha.5 h1:EYID3JOAdmQ4SNZYJHu9V6IqOeRQDBYxqKAg9PyoHFY= github.com/ebitengine/purego v0.6.0-alpha.5/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy v1.2.3 h1:xwIyKHbaP5yfT6O9KIeYJR5549MXRQkoQMRXGztz8YQ= +github.com/elazarl/goproxy v1.2.3/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -303,18 +303,18 @@ 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/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= -github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= +github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= +github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= -github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= +github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA= +github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= -github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M= +github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc= github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U= github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -752,8 +752,8 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F 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.8.2/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= @@ -884,8 +884,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= 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.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= @@ -918,8 +918,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= @@ -932,8 +932,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.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.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= @@ -972,16 +972,16 @@ 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.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/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.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= 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.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= 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= @@ -991,8 +991,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.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= 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 bceddea8cc844ce80635eb86d8f1bf8c8913a824 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 14:16:08 +0000 Subject: [PATCH 29/40] chore(deps): bump github.com/golang-jwt/jwt/v4 from 4.5.0 to 4.5.1 (#73) Bumps [github.com/golang-jwt/jwt/v4](https://github.com/golang-jwt/jwt) from 4.5.0 to 4.5.1. - [Release notes](https://github.com/golang-jwt/jwt/releases) - [Changelog](https://github.com/golang-jwt/jwt/blob/main/VERSION_HISTORY.md) - [Commits](https://github.com/golang-jwt/jwt/compare/v4.5.0...v4.5.1) --- updated-dependencies: - dependency-name: github.com/golang-jwt/jwt/v4 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 | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index b9fdc31..474b724 100644 --- a/go.mod +++ b/go.mod @@ -142,7 +142,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 49ed488..33d7600 100644 --- a/go.sum +++ b/go.sum @@ -360,8 +360,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 dabb7f31aa9d22c1445ea923325d56c9fac940c7 Mon Sep 17 00:00:00 2001 From: Sas Swart Date: Tue, 14 Jan 2025 17:16:24 +0200 Subject: [PATCH 30/40] chore(deps): upgrade the envbuilder and kaniko dependencies (#74) * chore(deps): upgrade the envbuilder and kaniko dependencies * make it build --- go.mod | 29 ++++++----- go.sum | 56 +++++++++++----------- internal/provider/cached_image_resource.go | 2 +- 3 files changed, 43 insertions(+), 44 deletions(-) diff --git a/go.mod b/go.mod index 474b724..6e85936 100644 --- a/go.mod +++ b/go.mod @@ -3,16 +3,16 @@ module github.com/coder/terraform-provider-envbuilder go 1.22.4 // We use our own Kaniko fork. -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 require ( github.com/GoogleContainerTools/kaniko v1.9.2 - github.com/coder/envbuilder v1.0.4 + github.com/coder/envbuilder v1.1.0 github.com/coder/serpent v0.8.0 - github.com/docker/docker v26.1.5+incompatible + github.com/docker/docker v27.3.1+incompatible github.com/gliderlabs/ssh v0.3.8 github.com/go-git/go-billy/v5 v5.6.1 github.com/go-git/go-git/v5 v5.13.1 @@ -92,7 +92,6 @@ require ( github.com/chainguard-dev/git-urls v1.0.2 // 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/coder/v2 v2.10.1-0.20240704130443-c2d44d16a352 // indirect github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 // indirect @@ -100,8 +99,7 @@ require ( github.com/coder/retry v1.5.1 // 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 @@ -110,17 +108,16 @@ require ( github.com/containerd/platforms v0.2.1 // 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.3.6 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dimchansky/utfbom v1.1.1 // indirect github.com/distribution/distribution/v3 v3.0.0-alpha.1 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/cli v27.2.0+incompatible // indirect + github.com/docker/cli v27.2.1+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/docker/go-connections v0.5.0 // indirect @@ -148,7 +145,7 @@ require ( github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // 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 @@ -167,7 +164,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/hc-install v0.8.0 // indirect github.com/hashicorp/hcl/v2 v2.21.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect @@ -207,17 +204,18 @@ require ( github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/moby/buildkit v0.13.1 // indirect + github.com/moby/buildkit v0.16.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/locker v1.0.1 // indirect 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 @@ -263,6 +261,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 33d7600..746f89e 100644 --- a/go.sum +++ b/go.sum @@ -186,10 +186,10 @@ 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/envbuilder v1.0.4 h1:27DFtKhgsode5I0kBPTCHuzG88Zpny27OVvXOuA/zso= -github.com/coder/envbuilder v1.0.4/go.mod h1:CkP/qKzWmK14I/aSPwEXoEHlss7OqYDmaM8Q7rDhwt8= -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/envbuilder v1.1.0 h1:OcICg3FzwFHzBDw+60tW7dgCxfkTxt/C6faz/cAfwDE= +github.com/coder/envbuilder v1.1.0/go.mod h1:WgqCgSz6XzXSoTGMMIuBf+0D38iofTqAwQCIlEmohX0= +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= @@ -204,10 +204,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= @@ -224,15 +222,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.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= @@ -252,12 +248,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= @@ -409,8 +405,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.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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= @@ -461,8 +457,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.8.0 h1:LdpZeXkZYMQhoKPCecJHlKvUkQFixN/nvyR1CdfOLjI= github.com/hashicorp/hc-install v0.8.0/go.mod h1:+MwJYjDfCruSD/udvBmRB22Nlkwwkwf5sAB6uTIhSaU= github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14= @@ -594,8 +590,8 @@ github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= 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= @@ -607,16 +603,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= @@ -773,6 +771,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/internal/provider/cached_image_resource.go b/internal/provider/cached_image_resource.go index 097b5fd..3085e0c 100644 --- a/internal/provider/cached_image_resource.go +++ b/internal/provider/cached_image_resource.go @@ -473,7 +473,7 @@ func runCacheProbe(ctx context.Context, builderImage string, opts eboptions.Opti return nil, fmt.Errorf("failed to create kaniko dir: %w", err) } // Use the temporary directory as our 'magic dir'. - opts.MagicDirBase = tmpKanikoDir + opts.WorkingDirBase = tmpKanikoDir // In order to correctly reproduce the final layer of the cached image, we // need the envbuilder binary used to originally build the image! From 82c856094e739449d449b69326ff22b09b242d17 Mon Sep 17 00:00:00 2001 From: Sas Swart Date: Thu, 16 Jan 2025 11:39:38 +0200 Subject: [PATCH 31/40] feat: add build secrets option (#75) * feat: add build secrets option * make gen and fix tests --- docs/resources/cached_image.md | 1 + internal/provider/cached_image_resource.go | 6 ++++ internal/provider/helpers.go | 19 ++++++++++- internal/provider/provider_internal_test.go | 36 ++++++++++++++------- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/docs/resources/cached_image.md b/docs/resources/cached_image.md index 93923fe..842d806 100644 --- a/docs/resources/cached_image.md +++ b/docs/resources/cached_image.md @@ -25,6 +25,7 @@ The cached image resource can be used to retrieve a cached image produced by env - `base_image_cache_dir` (String) (Envbuilder option) The path to a directory where the base image can be found. This should be a read-only directory solely mounted for the purpose of caching the base image. - `build_context_path` (String) (Envbuilder option) Can be specified when a DockerfilePath is specified outside the base WorkspaceFolder. This path MUST be relative to the WorkspaceFolder path into which the repo is cloned. +- `build_secrets` (Map of String) The secrets to use for the build. This is a map of key-value pairs. - `cache_ttl_days` (Number) (Envbuilder option) The number of days to use cached layers before expiring them. Defaults to 7 days. - `devcontainer_dir` (String) (Envbuilder option) The path to the folder containing the devcontainer.json file that will be used to build the workspace and can either be an absolute path or a path relative to the workspace folder. If not provided, defaults to `.devcontainer`. - `devcontainer_json_path` (String) (Envbuilder option) The path to a devcontainer.json file that is either an absolute path or a path relative to DevcontainerDir. This can be used in cases where one wants to substitute an edited devcontainer.json file for the one that exists in the repo. diff --git a/internal/provider/cached_image_resource.go b/internal/provider/cached_image_resource.go index 3085e0c..986d628 100644 --- a/internal/provider/cached_image_resource.go +++ b/internal/provider/cached_image_resource.go @@ -51,6 +51,7 @@ type CachedImageResourceModel struct { // Optional "inputs". BaseImageCacheDir types.String `tfsdk:"base_image_cache_dir"` BuildContextPath types.String `tfsdk:"build_context_path"` + BuildSecrets types.Map `tfsdk:"build_secrets"` CacheTTLDays types.Int64 `tfsdk:"cache_ttl_days"` DevcontainerDir types.String `tfsdk:"devcontainer_dir"` DevcontainerJSONPath types.String `tfsdk:"devcontainer_json_path"` @@ -121,6 +122,11 @@ func (r *CachedImageResource) Schema(ctx context.Context, req resource.SchemaReq MarkdownDescription: "(Envbuilder option) Can be specified when a DockerfilePath is specified outside the base WorkspaceFolder. This path MUST be relative to the WorkspaceFolder path into which the repo is cloned.", Optional: true, }, + "build_secrets": schema.MapAttribute{ + MarkdownDescription: "The secrets to use for the build. This is a map of key-value pairs.", + ElementType: types.StringType, + Optional: true, + }, "cache_ttl_days": schema.Int64Attribute{ MarkdownDescription: "(Envbuilder option) The number of days to use cached layers before expiring them. Defaults to 7 days.", Optional: true, diff --git a/internal/provider/helpers.go b/internal/provider/helpers.go index af4d237..acc69f2 100644 --- a/internal/provider/helpers.go +++ b/internal/provider/helpers.go @@ -2,6 +2,7 @@ package provider import ( "fmt" + "slices" "strings" eboptions "github.com/coder/envbuilder/options" @@ -47,6 +48,22 @@ func optionsFromDataModel(data CachedImageResourceModel) (eboptions.Options, dia opts.BuildContextPath = data.BuildContextPath.ValueString() } + if !data.BuildSecrets.IsNull() { + providerOpts["ENVBUILDER_BUILD_SECRETS"] = true + + // Depending on use case, users might want to provide build secrets as a map or a list of strings. + // The string list option is supported by extra_env, so we support the map option here. Envbuilder + // expects a list of strings, so we convert the map to a list of strings here. + buildSecretMap := tfutil.TFMapToStringMap(data.BuildSecrets) + buildSecretSlice := make([]string, 0, len(buildSecretMap)) + for k, v := range buildSecretMap { + buildSecretSlice = append(buildSecretSlice, fmt.Sprintf("%s=%s", k, v)) + } + slices.Sort(buildSecretSlice) + + opts.BuildSecrets = buildSecretSlice + } + if !data.CacheTTLDays.IsNull() { providerOpts["ENVBUILDER_CACHE_TTL_DAYS"] = true opts.CacheTTLDays = data.CacheTTLDays.ValueInt64() @@ -199,7 +216,7 @@ func overrideOptionsFromExtraEnv(opts *eboptions.Options, extraEnv map[string]st // XXX: workaround for serpent behaviour where calling Set() on a // string slice will append instead of replace: set to empty first. - if key == "ENVBUILDER_IGNORE_PATHS" { + if _, ok := optsMap[key].(*serpent.StringArray); ok { _ = optsMap[key].Set("") } diff --git a/internal/provider/provider_internal_test.go b/internal/provider/provider_internal_test.go index c273a8c..c1ae983 100644 --- a/internal/provider/provider_internal_test.go +++ b/internal/provider/provider_internal_test.go @@ -35,11 +35,15 @@ func Test_optionsFromDataModel(t *testing.T) { { name: "all options without extra_env", data: CachedImageResourceModel{ - BuilderImage: basetypes.NewStringValue("envbuilder:latest"), - CacheRepo: basetypes.NewStringValue("localhost:5000/cache"), - GitURL: basetypes.NewStringValue("git@git.local/devcontainer.git"), - BaseImageCacheDir: basetypes.NewStringValue("/tmp/cache"), - BuildContextPath: basetypes.NewStringValue("."), + BuilderImage: basetypes.NewStringValue("envbuilder:latest"), + CacheRepo: basetypes.NewStringValue("localhost:5000/cache"), + GitURL: basetypes.NewStringValue("git@git.local/devcontainer.git"), + BaseImageCacheDir: basetypes.NewStringValue("/tmp/cache"), + BuildContextPath: basetypes.NewStringValue("."), + BuildSecrets: basetypes.NewMapValueMust(basetypes.StringType{}, map[string]attr.Value{ + "FOO": basetypes.NewStringValue("bar"), + "BAZ": basetypes.NewStringValue("qux"), + }), CacheTTLDays: basetypes.NewInt64Value(7), DevcontainerDir: basetypes.NewStringValue(".devcontainer"), DevcontainerJSONPath: basetypes.NewStringValue(".devcontainer/devcontainer.json"), @@ -66,6 +70,7 @@ func Test_optionsFromDataModel(t *testing.T) { GitURL: "git@git.local/devcontainer.git", BaseImageCacheDir: "/tmp/cache", BuildContextPath: ".", + BuildSecrets: []string{"BAZ=qux", "FOO=bar"}, // Sorted CacheTTLDays: 7, DevcontainerDir: ".devcontainer", DevcontainerJSONPath: ".devcontainer/devcontainer.json", @@ -97,9 +102,11 @@ func Test_optionsFromDataModel(t *testing.T) { "CODER_AGENT_TOKEN", "token", "CODER_AGENT_URL", "http://coder", "FOO", "bar", + "ENVBUILDER_BUILD_SECRETS", "FOO=bar,BAZ=qux", ), }, expectOpts: eboptions.Options{ + BuildSecrets: []string{"FOO=bar", "BAZ=qux"}, CacheRepo: "localhost:5000/cache", GitURL: "git@git.local/devcontainer.git", RemoteRepoBuildMode: true, @@ -110,11 +117,14 @@ func Test_optionsFromDataModel(t *testing.T) { { name: "extra_env override warnings", data: CachedImageResourceModel{ - BuilderImage: basetypes.NewStringValue("envbuilder:latest"), - CacheRepo: basetypes.NewStringValue("localhost:5000/cache"), - GitURL: basetypes.NewStringValue("git@git.local/devcontainer.git"), - BaseImageCacheDir: basetypes.NewStringValue("/tmp/cache"), - BuildContextPath: basetypes.NewStringValue("."), + BuilderImage: basetypes.NewStringValue("envbuilder:latest"), + CacheRepo: basetypes.NewStringValue("localhost:5000/cache"), + GitURL: basetypes.NewStringValue("git@git.local/devcontainer.git"), + BaseImageCacheDir: basetypes.NewStringValue("/tmp/cache"), + BuildContextPath: basetypes.NewStringValue("."), + BuildSecrets: basetypes.NewMapValueMust(basetypes.StringType{}, map[string]attr.Value{ + "FOO": basetypes.NewStringValue("bar"), + }), CacheTTLDays: basetypes.NewInt64Value(7), DevcontainerDir: basetypes.NewStringValue(".devcontainer"), DevcontainerJSONPath: basetypes.NewStringValue(".devcontainer/devcontainer.json"), @@ -136,6 +146,7 @@ func Test_optionsFromDataModel(t *testing.T) { Verbose: basetypes.NewBoolValue(true), WorkspaceFolder: basetypes.NewStringValue("workspace"), ExtraEnv: extraEnvMap(t, + "ENVBUILDER_BUILD_SECRETS", "FOO=bar,BAZ=qux", "ENVBUILDER_CACHE_REPO", "override", "ENVBUILDER_GIT_URL", "override", "ENVBUILDER_BASE_IMAGE_CACHE_DIR", "override", @@ -169,6 +180,7 @@ func Test_optionsFromDataModel(t *testing.T) { // overridden BaseImageCacheDir: "override", BuildContextPath: "override", + BuildSecrets: []string{"FOO=bar", "BAZ=qux"}, CacheTTLDays: 8, DevcontainerDir: "override", DevcontainerJSONPath: "override", @@ -189,7 +201,7 @@ func Test_optionsFromDataModel(t *testing.T) { Verbose: false, WorkspaceFolder: "override", }, - expectNumWarningDiags: 23, + expectNumWarningDiags: 24, }, { name: "extra_env override errors", @@ -295,6 +307,7 @@ func Test_computeEnvFromOptions(t *testing.T) { BaseImageCacheDir: "string", BinaryPath: "string", BuildContextPath: "string", + BuildSecrets: []string{"FOO=bar", "BAZ=qux"}, CacheRepo: "string", CacheTTLDays: 1, CoderAgentSubsystem: []string{"one", "two"}, @@ -339,6 +352,7 @@ func Test_computeEnvFromOptions(t *testing.T) { "ENVBUILDER_BASE_IMAGE_CACHE_DIR": "string", "ENVBUILDER_BINARY_PATH": "string", "ENVBUILDER_BUILD_CONTEXT_PATH": "string", + "ENVBUILDER_BUILD_SECRETS": "FOO=bar,BAZ=qux", "ENVBUILDER_CACHE_REPO": "string", "ENVBUILDER_CACHE_TTL_DAYS": "1", "ENVBUILDER_DEVCONTAINER_DIR": "string", From 3adb53af1ac9211fb23b12b5c590941af3eac0bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 16:58:39 +0000 Subject: [PATCH 32/40] chore(deps): bump golangci/golangci-lint-action from 6.1.1 to 6.2.0 (#76) Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 6.1.1 to 6.2.0. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/971e284b6050e8a5849b72094c50ab08da042db8...ec5d18412c0aeab7936cb16880d708ba2a64e1ae) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4835018..335a826 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,7 @@ jobs: - run: go mod download - run: go build -v . - name: Run linters - uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 + uses: golangci/golangci-lint-action@ec5d18412c0aeab7936cb16880d708ba2a64e1ae # v6.2.0 with: version: latest From f98d104f23dfd2171ceed6f4506192ebd7e33dbd Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 20 Jan 2025 17:25:38 +0000 Subject: [PATCH 33/40] chore(README.md): update broken links (#78) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 611d9bd..92434e5 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ If it is found that building a particular dev container would produce the same i Take a look at the [`envbuilder_cached_image_resource.tf`](./examples/resources/envbuilder_cached_image/envbuilder_cached_image_resource.tf) example for a detailed usage example. For use with [Coder](https://github.com/coder/coder), see the [Dev Containers documentation](https://coder.com/docs/templates/dev-containers) and check out the example templates: -- [Docker](https://github.com/coder/coder/tree/main/examples/templates/devcontainer-docker) -- [Kubernetes](https://github.com/coder/coder/tree/main/examples/templates/devcontainer-kuberntes) -- [AWS VM](https://github.com/coder/coder/tree/main/examples/templates/devcontainer-aws-vm) -- [GCP VM](https://github.com/coder/coder/tree/main/examples/templates/devcontainer-gcp-vm) +- [Docker](https://github.com/coder/coder/tree/main/examples/templates/docker-devcontainer) +- [Kubernetes](https://github.com/coder/coder/tree/main/examples/templates/kubernetes-devcontainer) +- [AWS VM](https://github.com/coder/coder/tree/main/examples/templates/aws-devcontainer) +- [GCP VM](https://github.com/coder/coder/tree/main/examples/templates/gcp-devcontainer) ## Requirements From b86f527238674c758be8d04864eda094e4492478 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 11:04:49 +0000 Subject: [PATCH 34/40] chore(deps): bump golangci/golangci-lint-action from 6.2.0 to 6.3.1 (#80) Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 6.2.0 to 6.3.1. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/ec5d18412c0aeab7936cb16880d708ba2a64e1ae...2e788936b09dd82dc280e845628a40d2ba6b204c) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 335a826..28189fb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,7 @@ jobs: - run: go mod download - run: go build -v . - name: Run linters - uses: golangci/golangci-lint-action@ec5d18412c0aeab7936cb16880d708ba2a64e1ae # v6.2.0 + uses: golangci/golangci-lint-action@2e788936b09dd82dc280e845628a40d2ba6b204c # v6.3.1 with: version: latest From 99b0d0257b76859837e4355c604c7f712dba808e Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 13 Mar 2025 11:15:58 +0000 Subject: [PATCH 35/40] ci: update linters settings (#88) --- .golangci.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 223cf95..29ddfe8 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -9,19 +9,18 @@ linters: enable: - durationcheck - errcheck - - exportloopref - forcetypeassert - godot - gofmt - gosimple + - govet - ineffassign - makezero - misspell - nilerr - predeclared - staticcheck - - tenv - unconvert - unparam - unused - - vet \ No newline at end of file + - usetesting From e298d87ca36fb83c2780e31d8262e33cf370eaf4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Mar 2025 14:30:30 +0000 Subject: [PATCH 36/40] chore(deps): bump golang.org/x/net from 0.33.0 to 0.36.0 (#87) * chore(deps): bump golang.org/x/net from 0.33.0 to 0.36.0 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] * go mod tidy --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Cian Johnston --- go.mod | 16 +++++++++------- go.sum | 24 ++++++++++++------------ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 6e85936..1b28ab2 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/coder/terraform-provider-envbuilder -go 1.22.4 +go 1.23.0 + +toolchain go1.23.7 // We use our own Kaniko fork. replace github.com/GoogleContainerTools/kaniko => github.com/coder/kaniko v0.0.0-20241120132148-131d6094d781 @@ -292,15 +294,15 @@ 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/crypto v0.31.0 // indirect + golang.org/x/crypto v0.35.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.21.0 // indirect - golang.org/x/net v0.33.0 // indirect + golang.org/x/net v0.36.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/term v0.27.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.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.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect diff --git a/go.sum b/go.sum index 746f89e..a402afd 100644 --- a/go.sum +++ b/go.sum @@ -885,8 +885,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -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.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-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= @@ -919,8 +919,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -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.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= @@ -933,8 +933,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-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= @@ -973,16 +973,16 @@ 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.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.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.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= 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.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +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= @@ -992,8 +992,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.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 7b6e7d5fbadc33005f19ac5a29260e354cbe72e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Mar 2025 15:05:55 +0000 Subject: [PATCH 37/40] chore(deps): bump github.com/hashicorp/terraform-plugin-docs from 0.19.4 to 0.21.0 (#86) chore(deps): bump github.com/hashicorp/terraform-plugin-docs Bumps [github.com/hashicorp/terraform-plugin-docs](https://github.com/hashicorp/terraform-plugin-docs) from 0.19.4 to 0.21.0. - [Release notes](https://github.com/hashicorp/terraform-plugin-docs/releases) - [Changelog](https://github.com/hashicorp/terraform-plugin-docs/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/terraform-plugin-docs/compare/v0.19.4...v0.21.0) --- updated-dependencies: - dependency-name: github.com/hashicorp/terraform-plugin-docs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 20 ++++++++++---------- go.sum | 46 ++++++++++++++++++++++------------------------ 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/go.mod b/go.mod index 1b28ab2..b835db0 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/go-git/go-git/v5 v5.13.1 github.com/google/go-containerregistry v0.20.2 github.com/google/uuid v1.6.0 - github.com/hashicorp/terraform-plugin-docs v0.19.4 + github.com/hashicorp/terraform-plugin-docs v0.21.0 github.com/hashicorp/terraform-plugin-framework v1.11.0 github.com/hashicorp/terraform-plugin-go v0.23.0 github.com/hashicorp/terraform-plugin-log v0.9.0 @@ -88,7 +88,7 @@ require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect - github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect + github.com/bmatcuk/doublestar/v4 v4.8.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chainguard-dev/git-urls v1.0.2 // indirect @@ -151,7 +151,7 @@ require ( 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 - github.com/hashicorp/cli v1.1.6 // indirect + github.com/hashicorp/cli v1.1.7 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -167,11 +167,11 @@ require ( 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.7 // indirect - github.com/hashicorp/hc-install v0.8.0 // indirect + github.com/hashicorp/hc-install v0.9.1 // indirect github.com/hashicorp/hcl/v2 v2.21.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect - github.com/hashicorp/terraform-exec v0.21.0 // indirect - github.com/hashicorp/terraform-json v0.22.1 // indirect + github.com/hashicorp/terraform-exec v0.22.0 // indirect + github.com/hashicorp/terraform-json v0.24.0 // indirect github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect @@ -190,7 +190,7 @@ require ( github.com/klauspost/compress v1.17.9 // indirect github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mdlayher/genetlink v1.3.2 // indirect @@ -275,9 +275,9 @@ require ( github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect - github.com/yuin/goldmark v1.7.1 // indirect + github.com/yuin/goldmark v1.7.7 // indirect github.com/yuin/goldmark-meta v1.1.0 // indirect - github.com/zclconf/go-cty v1.15.0 // indirect + github.com/zclconf/go-cty v1.16.2 // indirect github.com/zeebo/errs v1.3.0 // indirect go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect go.etcd.io/etcd/raft/v3 v3.5.6 // indirect @@ -296,7 +296,7 @@ require ( go4.org/netipx v0.0.0-20230728180743-ad4cb58a6516 // indirect golang.org/x/crypto v0.35.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/mod v0.21.0 // indirect + golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.36.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sync v0.11.0 // indirect diff --git a/go.sum b/go.sum index a402afd..c482f28 100644 --- a/go.sum +++ b/go.sum @@ -144,8 +144,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= -github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38= +github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bool64/shared v0.1.5 h1:fp3eUhBsrSjNCQPcSdQqZxxh9bBwrYiZ+zOKFkM0/2E= github.com/bool64/shared v0.1.5/go.mod h1:081yz68YC9jeFB3+Bbmno2RFWvGKv1lPKkMP6MHJlPs= github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= @@ -420,8 +420,8 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk= -github.com/hashicorp/cli v1.1.6 h1:CMOV+/LJfL1tXCOKrgAX0uRKnzjj/mpmqNXloRSy2K8= -github.com/hashicorp/cli v1.1.6/go.mod h1:MPon5QYlgjjo0BSoAiN0ESeT5fRzDjVRp+uioJ0piz4= +github.com/hashicorp/cli v1.1.7 h1:/fZJ+hNdwfTSfsxMBa9WWMlfjUZbX8/LnUxgAd7lCVU= +github.com/hashicorp/cli v1.1.7/go.mod h1:e6Mfpga9OCT1vqzFuoGZiiF/KaG9CbUfO5s3ghU3YgU= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -459,18 +459,18 @@ github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGN github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU= 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.8.0 h1:LdpZeXkZYMQhoKPCecJHlKvUkQFixN/nvyR1CdfOLjI= -github.com/hashicorp/hc-install v0.8.0/go.mod h1:+MwJYjDfCruSD/udvBmRB22Nlkwwkwf5sAB6uTIhSaU= +github.com/hashicorp/hc-install v0.9.1 h1:gkqTfE3vVbafGQo6VZXcy2v5yoz2bE0+nhZXruCuODQ= +github.com/hashicorp/hc-install v0.9.1/go.mod h1:pWWvN/IrfeBK4XPeXXYkL6EjMufHkCK5DvwxeLKuBf0= github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14= github.com/hashicorp/hcl/v2 v2.21.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= -github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= -github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec= -github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= -github.com/hashicorp/terraform-plugin-docs v0.19.4 h1:G3Bgo7J22OMtegIgn8Cd/CaSeyEljqjH3G39w28JK4c= -github.com/hashicorp/terraform-plugin-docs v0.19.4/go.mod h1:4pLASsatTmRynVzsjEhbXZ6s7xBlUw/2Kt0zfrq8HxA= +github.com/hashicorp/terraform-exec v0.22.0 h1:G5+4Sz6jYZfRYUCg6eQgDsqTzkNXV+fP8l+uRmZHj64= +github.com/hashicorp/terraform-exec v0.22.0/go.mod h1:bjVbsncaeh8jVdhttWYZuBGj21FcYw6Ia/XfHcNO7lQ= +github.com/hashicorp/terraform-json v0.24.0 h1:rUiyF+x1kYawXeRth6fKFm/MdfBS6+lW4NbeATsYz8Q= +github.com/hashicorp/terraform-json v0.24.0/go.mod h1:Nfj5ubo9xbu9uiAoZVBsNOjvNKB66Oyrvtit74kC7ow= +github.com/hashicorp/terraform-plugin-docs v0.21.0 h1:yoyA/Y719z9WdFJAhpUkI1jRbKP/nteVNBaI3hW7iQ8= +github.com/hashicorp/terraform-plugin-docs v0.21.0/go.mod h1:J4Wott1J2XBKZPp/NkQv7LMShJYOcrqhQ2myXBcu64s= github.com/hashicorp/terraform-plugin-framework v1.11.0 h1:M7+9zBArexHFXDx/pKTxjE6n/2UCXY6b8FIq9ZYhwfE= github.com/hashicorp/terraform-plugin-framework v1.11.0/go.mod h1:qBXLDn69kM97NNVi/MQ9qgd1uWWsVftGSnygYG1tImM= github.com/hashicorp/terraform-plugin-go v0.23.0 h1:AALVuU1gD1kPb48aPQUjug9Ir/125t+AAurhqphJ2Co= @@ -551,11 +551,10 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69 github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= @@ -710,8 +709,8 @@ github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/secure-systems-lab/go-securesystemslib v0.7.0 h1:OwvJ5jQf9LnIAS83waAjPbcMsODrTQUpJ02eNLUoxBg= github.com/secure-systems-lab/go-securesystemslib v0.7.0/go.mod h1:/2gYnlnHVQ6xeGtfIqFy7Do03K4cdCY0A/GlJLDKLHI= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= @@ -814,12 +813,12 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= -github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +github.com/yuin/goldmark v1.7.7 h1:5m9rrB1sW3JUMToKFQfb+FGt1U7r57IHu5GrYrG2nqU= +github.com/yuin/goldmark v1.7.7/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0= -github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= -github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty v1.16.2 h1:LAJSwc3v81IRBZyUVQDUdZ7hs3SYs9jv0eZJDWHD/70= +github.com/zclconf/go-cty v1.16.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= @@ -898,8 +897,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -966,7 +965,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= From cd9c03270815bc9b045a2391ac72a5c666338343 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Mar 2025 15:21:34 +0000 Subject: [PATCH 38/40] chore(deps): bump github.com/go-jose/go-jose/v4 from 4.0.1 to 4.0.5 (#85) Bumps [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) from 4.0.1 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.1...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> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b835db0..56ad9aa 100644 --- a/go.mod +++ b/go.mod @@ -135,7 +135,7 @@ require ( github.com/fxamacker/cbor/v2 v2.4.0 // indirect github.com/go-chi/chi/v5 v5.0.10 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-jose/go-jose/v4 v4.0.1 // indirect + github.com/go-jose/go-jose/v4 v4.0.5 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect diff --git a/go.sum b/go.sum index c482f28..8bc6d05 100644 --- a/go.sum +++ b/go.sum @@ -311,8 +311,8 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMj github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M= github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc= -github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U= -github.com/go-jose/go-jose/v4 v4.0.1/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-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= From 251def25244b5cd15fe106a1028227fc0aa9d48d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 09:18:59 +0000 Subject: [PATCH 39/40] chore(deps): bump github.com/golang-jwt/jwt/v4 from 4.5.1 to 4.5.2 (#93) Bumps [github.com/golang-jwt/jwt/v4](https://github.com/golang-jwt/jwt) from 4.5.1 to 4.5.2. - [Release notes](https://github.com/golang-jwt/jwt/releases) - [Changelog](https://github.com/golang-jwt/jwt/blob/main/VERSION_HISTORY.md) - [Commits](https://github.com/golang-jwt/jwt/compare/v4.5.1...v4.5.2) --- updated-dependencies: - dependency-name: github.com/golang-jwt/jwt/v4 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 56ad9aa..01aed65 100644 --- a/go.mod +++ b/go.mod @@ -141,7 +141,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.1 // indirect + github.com/golang-jwt/jwt/v4 v4.5.2 // 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 8bc6d05..8eba68a 100644 --- a/go.sum +++ b/go.sum @@ -357,8 +357,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 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/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-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/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 52535609d07f7ec1aa1c98a6f166077abb55bee2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jun 2025 14:22:09 +0100 Subject: [PATCH 40/40] chore(deps): bump github.com/cloudflare/circl from 1.3.7 to 1.6.1 (#105) Bumps [github.com/cloudflare/circl](https://github.com/cloudflare/circl) from 1.3.7 to 1.6.1. - [Release notes](https://github.com/cloudflare/circl/releases) - [Commits](https://github.com/cloudflare/circl/compare/v1.3.7...v1.6.1) --- updated-dependencies: - dependency-name: github.com/cloudflare/circl dependency-version: 1.6.1 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 01aed65..fdd5454 100644 --- a/go.mod +++ b/go.mod @@ -94,7 +94,7 @@ require ( github.com/chainguard-dev/git-urls v1.0.2 // indirect github.com/charmbracelet/lipgloss v0.8.0 // indirect github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect - github.com/cloudflare/circl v1.3.7 // indirect + github.com/cloudflare/circl v1.6.1 // indirect github.com/coder/coder/v2 v2.10.1-0.20240704130443-c2d44d16a352 // indirect github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 // indirect github.com/coder/quartz v0.1.0 // indirect diff --git a/go.sum b/go.sum index 8eba68a..fe3c583 100644 --- a/go.sum +++ b/go.sum @@ -178,8 +178,8 @@ github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb2 github.com/cilium/ebpf v0.12.3 h1:8ht6F9MquybnY97at+VDZb3eQQr8ev79RueWeVaEcG4= github.com/cilium/ebpf v0.12.3/go.mod h1:TctK1ivibvI3znr66ljgi4hqOT8EYQjz1KWBfb1UVgM= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= +github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=