From 201b2bc41cbc95c5276e8ee4123a44f5bc6bc545 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 6 Feb 2024 17:31:46 +0100 Subject: [PATCH 1/5] feat(cli): pull templates in zip format --- cli/templatepull.go | 25 ++++++++++++++++++++++--- cli/templatepull_test.go | 17 ++++++++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/cli/templatepull.go b/cli/templatepull.go index e61d410268c1a..2509cc9df4281 100644 --- a/cli/templatepull.go +++ b/cli/templatepull.go @@ -17,6 +17,7 @@ import ( func (r *RootCmd) templatePull() *clibase.Cmd { var ( tarMode bool + zipMode bool versionName string ) @@ -39,6 +40,10 @@ func (r *RootCmd) templatePull() *clibase.Cmd { dest = inv.Args[1] } + if tarMode && zipMode { + return xerrors.Errorf("either tar or zip can be selected") + } + organization, err := CurrentOrganization(inv, client) if err != nil { return xerrors.Errorf("get current organization: %w", err) @@ -98,17 +103,25 @@ func (r *RootCmd) templatePull() *clibase.Cmd { cliui.Info(inv.Stderr, "Pulling template version "+cliui.Bold(templateVersion.Name)+"...") + var fileFormat string // empty = default, so .tar + if zipMode { + fileFormat = codersdk.FormatZip + } + // Download the tar archive. - raw, ctype, err := client.Download(ctx, templateVersion.Job.FileID) + raw, ctype, err := client.DownloadWithFormat(ctx, templateVersion.Job.FileID, fileFormat) if err != nil { return xerrors.Errorf("download template: %w", err) } - if ctype != codersdk.ContentTypeTar { + if fileFormat == "" && ctype != codersdk.ContentTypeTar { return xerrors.Errorf("unexpected Content-Type %q, expecting %q", ctype, codersdk.ContentTypeTar) } + if fileFormat == codersdk.FormatZip && ctype != codersdk.ContentTypeZip { + return xerrors.Errorf("unexpected Content-Type %q, expecting %q", ctype, codersdk.ContentTypeZip) + } - if tarMode { + if tarMode || zipMode { _, err = inv.Stdout.Write(raw) return err } @@ -152,6 +165,12 @@ func (r *RootCmd) templatePull() *clibase.Cmd { Value: clibase.BoolOf(&tarMode), }, + { + Description: "Output the template as a zip archive to stdout.", + Flag: "zip", + + Value: clibase.BoolOf(&zipMode), + }, { Description: "The name of the template version to pull. Use 'active' to pull the active version, 'latest' to pull the latest version, or the name of the template version to pull.", Flag: "version", diff --git a/cli/templatepull_test.go b/cli/templatepull_test.go index 782859c6a93ca..1bc287d8ebd3b 100644 --- a/cli/templatepull_test.go +++ b/cli/templatepull_test.go @@ -1,6 +1,7 @@ package cli_test import ( + "archive/tar" "bytes" "context" "crypto/sha256" @@ -15,6 +16,7 @@ import ( "github.com/stretchr/testify/require" "github.com/coder/coder/v2/cli/clitest" + "github.com/coder/coder/v2/coderd" "github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/provisioner/echo" @@ -81,6 +83,7 @@ func TestTemplatePull_Stdout(t *testing.T) { _ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, updatedVersion.ID) coderdtest.UpdateActiveTemplateVersion(t, client, template.ID, updatedVersion.ID) + // Verify .tar format inv, root := clitest.New(t, "templates", "pull", "--tar", template.Name) clitest.SetupConfig(t, templateAdmin, root) @@ -89,8 +92,20 @@ func TestTemplatePull_Stdout(t *testing.T) { err = inv.Run() require.NoError(t, err) - require.True(t, bytes.Equal(expected, buf.Bytes()), "tar files differ") + + // Verify .zip format + tarReader := tar.NewReader(bytes.NewReader(expected)) + expectedZip, err := coderd.CreateZipFromTar(tarReader) + + inv, root = clitest.New(t, "templates", "pull", "--zip", template.Name) + clitest.SetupConfig(t, templateAdmin, root) + buf.Reset() + inv.Stdout = &buf + + err = inv.Run() + require.NoError(t, err) + require.True(t, bytes.Equal(expectedZip, buf.Bytes()), "zip files differ") } // Stdout tests that 'templates pull' pulls down the non-latest active template From d936b2d8183937f02622003845317a325ece9c94 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 6 Feb 2024 17:39:11 +0100 Subject: [PATCH 2/5] zip --- cli/templatepull_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/templatepull_test.go b/cli/templatepull_test.go index 1bc287d8ebd3b..32dd18019dacb 100644 --- a/cli/templatepull_test.go +++ b/cli/templatepull_test.go @@ -97,6 +97,7 @@ func TestTemplatePull_Stdout(t *testing.T) { // Verify .zip format tarReader := tar.NewReader(bytes.NewReader(expected)) expectedZip, err := coderd.CreateZipFromTar(tarReader) + require.NoError(t, err) inv, root = clitest.New(t, "templates", "pull", "--zip", template.Name) clitest.SetupConfig(t, templateAdmin, root) From f070d08e7015f3246dd223143067210d5c863697 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 6 Feb 2024 17:47:09 +0100 Subject: [PATCH 3/5] make gen --- docs/cli/templates_pull.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/cli/templates_pull.md b/docs/cli/templates_pull.md index 9ad51ab64c912..b8a36ddcc1898 100644 --- a/docs/cli/templates_pull.md +++ b/docs/cli/templates_pull.md @@ -35,3 +35,11 @@ The name of the template version to pull. Use 'active' to pull the active versio | Type | bool | Bypass prompts. + +### --zip + +| | | +| ---- | ----------------- | +| Type | bool | + +Output the template as a zip archive to stdout. From 8c00cf2c4ad919920c65afccd956d9a95901ebe9 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 6 Feb 2024 17:54:48 +0100 Subject: [PATCH 4/5] fix --- cli/testdata/coder_templates_pull_--help.golden | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cli/testdata/coder_templates_pull_--help.golden b/cli/testdata/coder_templates_pull_--help.golden index 65cb302a65a8c..2598e35a303ef 100644 --- a/cli/testdata/coder_templates_pull_--help.golden +++ b/cli/testdata/coder_templates_pull_--help.golden @@ -17,5 +17,8 @@ OPTIONS: -y, --yes bool Bypass prompts. + --zip bool + Output the template as a zip archive to stdout. + ——— Run `coder --help` for a list of global options. From 752dbcd74f04eca0cea604e8b7c10472315b4195 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 6 Feb 2024 19:09:37 +0100 Subject: [PATCH 5/5] Empty commit