mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat(coderd/templatebuilder): validation extraction, static file bundling, Windows OS (#26633)
Extract validation helpers to a dedicated file, add static file bundling for base templates, and add Windows OS support. **Commit 1: Extract validation to `validate.go`** Move `validateVariableValue`, `validateStringValue`, `validateNumberValue`, `validateBoolValue`, `toHCLLiteral`, `hclQuote`, and `isSimpleJSONValue` from `compose.go` into `validate.go`. Corresponding tests move to `validate_internal_test.go`. This keeps `compose.go` focused on the compose pipeline. **Commit 2: Static file bundling** Add `StaticFiles` field to `ComposeResult` and a `collectStaticFiles` helper that walks the base template FS to collect non-template files (e.g. cloud-init `.tftpl` inputs). `BundleTar` now writes these files into the output archive in sorted order for deterministic output. This fixes `aws-linux`, whose cloud-init files were embedded but never included in the tar. **Commit 3: Windows OS support** Add `BaseOSWindows` constant and register `"windows"` in `validBaseOS` so that base templates with `os="windows"` can be loaded and used for module compatibility filtering. > [!NOTE] > This PR was authored by Coder Agents on behalf of @jeremyruppel.
This commit is contained in:
@@ -66,6 +66,18 @@ func TestCompose(t *testing.T) {
|
||||
require.Contains(t, string(result.ModulesTF), `coder_agent.dev.id`)
|
||||
})
|
||||
|
||||
t.Run("AWSLinuxExtraFiles", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result, err := templatebuilder.Compose(templatebuilder.ComposeRequest{
|
||||
BaseTemplateID: "aws-linux",
|
||||
RegistryURL: "https://registry.coder.com",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, result.ExtraFiles, "aws-linux should have extra files")
|
||||
require.Contains(t, result.ExtraFiles, "cloud-init/cloud-config.yaml.tftpl")
|
||||
require.Contains(t, result.ExtraFiles, "cloud-init/userdata.sh.tftpl")
|
||||
})
|
||||
|
||||
t.Run("SensitiveVariable", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result, err := templatebuilder.Compose(templatebuilder.ComposeRequest{
|
||||
@@ -147,6 +159,16 @@ func TestCompose(t *testing.T) {
|
||||
require.Contains(t, err.Error(), "conflicts with")
|
||||
})
|
||||
|
||||
t.Run("DockerNoExtraFiles", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result, err := templatebuilder.Compose(templatebuilder.ComposeRequest{
|
||||
BaseTemplateID: "docker",
|
||||
RegistryURL: "https://registry.coder.com",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, result.ExtraFiles, "docker should have no extra files")
|
||||
})
|
||||
|
||||
t.Run("UnknownBase", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := templatebuilder.Compose(templatebuilder.ComposeRequest{
|
||||
@@ -320,6 +342,44 @@ func TestBundleTar(t *testing.T) {
|
||||
require.Equal(t, string(result.Readme), files["README.md"])
|
||||
})
|
||||
|
||||
t.Run("ExtraFilesInTar", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := &templatebuilder.ComposeResult{
|
||||
MainTF: []byte("resource {}"),
|
||||
ExtraFiles: map[string][]byte{
|
||||
"cloud-init/config.yaml.tftpl": []byte("cloud config"),
|
||||
"cloud-init/userdata.sh.tftpl": []byte("userdata"),
|
||||
},
|
||||
}
|
||||
data, err := templatebuilder.BundleTar(result)
|
||||
require.NoError(t, err)
|
||||
|
||||
files := extractTar(t, data)
|
||||
require.Contains(t, files, "main.tf")
|
||||
require.Contains(t, files, "cloud-init/config.yaml.tftpl")
|
||||
require.Contains(t, files, "cloud-init/userdata.sh.tftpl")
|
||||
require.Equal(t, "cloud config", files["cloud-init/config.yaml.tftpl"])
|
||||
require.Equal(t, "userdata", files["cloud-init/userdata.sh.tftpl"])
|
||||
})
|
||||
|
||||
t.Run("AWSLinuxRoundTrip", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result, err := templatebuilder.Compose(templatebuilder.ComposeRequest{
|
||||
BaseTemplateID: "aws-linux",
|
||||
RegistryURL: "https://registry.coder.com",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
data, err := templatebuilder.BundleTar(result)
|
||||
require.NoError(t, err)
|
||||
|
||||
files := extractTar(t, data)
|
||||
require.Contains(t, files, "main.tf")
|
||||
require.Contains(t, files, "README.md")
|
||||
require.Contains(t, files, "cloud-init/cloud-config.yaml.tftpl")
|
||||
require.Contains(t, files, "cloud-init/userdata.sh.tftpl")
|
||||
})
|
||||
|
||||
t.Run("ReproducibleArchive", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := &templatebuilder.ComposeResult{
|
||||
|
||||
Reference in New Issue
Block a user