chore: support zip filetypes in the file cache (#18750)

This commit is contained in:
Steven Masley
2025-07-08 15:46:39 -06:00
committed by GitHub
parent 79d1465e23
commit 1319ae293f
4 changed files with 46 additions and 9 deletions
+22 -5
View File
@@ -1,6 +1,7 @@
package coderdtest
import (
"archive/tar"
"bytes"
"context"
"crypto"
@@ -52,6 +53,7 @@ import (
"cdr.dev/slog"
"cdr.dev/slog/sloggers/sloghuman"
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/archive"
"github.com/coder/coder/v2/coderd/files"
"github.com/coder/quartz"
@@ -886,14 +888,22 @@ func createAnotherUserRetry(t testing.TB, client *codersdk.Client, organizationI
return other, user
}
// CreateTemplateVersion creates a template import provisioner job
// with the responses provided. It uses the "echo" provisioner for compatibility
// with testing.
func CreateTemplateVersion(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, res *echo.Responses, mutators ...func(*codersdk.CreateTemplateVersionRequest)) codersdk.TemplateVersion {
func CreateTemplateVersionMimeType(t testing.TB, client *codersdk.Client, mimeType string, organizationID uuid.UUID, res *echo.Responses, mutators ...func(*codersdk.CreateTemplateVersionRequest)) codersdk.TemplateVersion {
t.Helper()
data, err := echo.TarWithOptions(context.Background(), client.Logger(), res)
require.NoError(t, err)
file, err := client.Upload(context.Background(), codersdk.ContentTypeTar, bytes.NewReader(data))
switch mimeType {
case codersdk.ContentTypeTar:
// do nothing
case codersdk.ContentTypeZip:
data, err = archive.CreateZipFromTar(tar.NewReader(bytes.NewBuffer(data)), int64(len(data)))
require.NoError(t, err, "creating zip")
default:
t.Fatal("unexpected mime type", mimeType)
}
file, err := client.Upload(context.Background(), mimeType, bytes.NewReader(data))
require.NoError(t, err)
req := codersdk.CreateTemplateVersionRequest{
@@ -910,6 +920,13 @@ func CreateTemplateVersion(t testing.TB, client *codersdk.Client, organizationID
return templateVersion
}
// CreateTemplateVersion creates a template import provisioner job
// with the responses provided. It uses the "echo" provisioner for compatibility
// with testing.
func CreateTemplateVersion(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, res *echo.Responses, mutators ...func(*codersdk.CreateTemplateVersionRequest)) codersdk.TemplateVersion {
return CreateTemplateVersionMimeType(t, client, codersdk.ContentTypeTar, organizationID, res, mutators...)
}
// CreateWorkspaceBuild creates a workspace build for the given workspace and transition.
func CreateWorkspaceBuild(
t *testing.T,
+8 -1
View File
@@ -20,6 +20,9 @@ type DynamicParameterTemplateParams struct {
Plan json.RawMessage
ModulesArchive []byte
// Uses a zip archive instead of a tar
Zip bool
// StaticParams is used if the provisioner daemon version does not support dynamic parameters.
StaticParams []*proto.RichParameter
@@ -45,7 +48,11 @@ func DynamicParameterTemplate(t *testing.T, client *codersdk.Client, org uuid.UU
},
}}
version := CreateTemplateVersion(t, client, org, files, func(request *codersdk.CreateTemplateVersionRequest) {
mime := codersdk.ContentTypeTar
if args.Zip {
mime = codersdk.ContentTypeZip
}
version := CreateTemplateVersionMimeType(t, client, mime, org, files, func(request *codersdk.CreateTemplateVersionRequest) {
if args.TemplateID != uuid.Nil {
request.TemplateID = args.TemplateID
}
+13 -2
View File
@@ -303,10 +303,21 @@ func fetch(store database.Store, fileID uuid.UUID) (CacheEntryValue, error) {
return CacheEntryValue{}, xerrors.Errorf("failed to read file from database: %w", err)
}
content := bytes.NewBuffer(file.Data)
var files fs.FS
switch file.Mimetype {
case "application/zip", "application/x-zip-compressed":
files, err = archivefs.FromZipReader(bytes.NewReader(file.Data), int64(len(file.Data)))
if err != nil {
return CacheEntryValue{}, xerrors.Errorf("failed to read zip file: %w", err)
}
default:
// Assume '"application/x-tar"' as the default mimetype.
files = archivefs.FromTarReader(bytes.NewBuffer(file.Data))
}
return CacheEntryValue{
Object: file.RBACObject(),
FS: archivefs.FromTarReader(content),
FS: files,
Size: int64(len(file.Data)),
}, nil
}
+3 -1
View File
@@ -294,7 +294,9 @@ func TestCreateUserWorkspace(t *testing.T) {
OrganizationID: first.OrganizationID,
})
template, _ := coderdtest.DynamicParameterTemplate(t, admin, first.OrganizationID, coderdtest.DynamicParameterTemplateParams{})
template, _ := coderdtest.DynamicParameterTemplate(t, admin, first.OrganizationID, coderdtest.DynamicParameterTemplateParams{
Zip: true,
})
ctx = testutil.Context(t, testutil.WaitLong)