From c75a0703463cf5806996fa7aa4dacac944bfe3e6 Mon Sep 17 00:00:00 2001 From: Matteo Date: Thu, 15 Jan 2026 16:17:43 +0100 Subject: [PATCH 1/3] feat: support required extensions Signed-off-by: Matteo --- dagger/maintenance/main.go | 19 ++++++++--- dagger/maintenance/parse.go | 1 + dagger/maintenance/testingvalues.go | 49 +++++++++++++++++++++++++++++ pgaudit/metadata.hcl | 1 + pgvector/metadata.hcl | 1 + postgis/metadata.hcl | 1 + postgis/test/cluster.yaml | 8 +---- test/cluster.yaml | 8 +---- 8 files changed, 69 insertions(+), 19 deletions(-) create mode 100644 dagger/maintenance/testingvalues.go diff --git a/dagger/maintenance/main.go b/dagger/maintenance/main.go index 508c722..e77be42 100644 --- a/dagger/maintenance/main.go +++ b/dagger/maintenance/main.go @@ -136,6 +136,10 @@ func (m *Maintenance) GetTargets( // Generates Chainsaw's testing external values in YAML format func (m *Maintenance) GenerateTestingValues( ctx context.Context, + // The source directory containing the extension folders. Defaults to the current directory + // +ignore=["dagger", ".github"] + // +defaultPath="/" + source *dagger.Directory, // Path to the target extension directory target *dagger.Directory, // URL reference to the extension image to test [REPOSITORY[:TAG]] @@ -174,18 +178,23 @@ func (m *Maintenance) GenerateTestingValues( targetExtensionImage) } + extensions, generateExtErr := generateTestingValuesExtensions( + ctx, + source, + metadata, + targetExtensionImage, + ) + if generateExtErr != nil { + return nil, generateExtErr + } // Build values.yaml content values := map[string]any{ "name": metadata.Name, "sql_name": metadata.SQLName, - "image_name": metadata.ImageName, "shared_preload_libraries": metadata.SharedPreloadLibraries, - "extension_control_path": metadata.ExtensionControlPath, - "dynamic_library_path": metadata.DynamicLibraryPath, - "ld_library_path": metadata.LdLibraryPath, - "extension_image": targetExtensionImage, "pg_image": pgImage, "version": version, + "extensions": extensions, } valuesYaml, err := yaml.Marshal(values) if err != nil { diff --git a/dagger/maintenance/parse.go b/dagger/maintenance/parse.go index d82dd81..5853634 100644 --- a/dagger/maintenance/parse.go +++ b/dagger/maintenance/parse.go @@ -28,6 +28,7 @@ type extensionMetadata struct { DynamicLibraryPath []string `hcl:"dynamic_library_path" cty:"dynamic_library_path"` LdLibraryPath []string `hcl:"ld_library_path" cty:"ld_library_path"` AutoUpdateOsLibs bool `hcl:"auto_update_os_libs" cty:"auto_update_os_libs"` + RequiredExtensions []string `hcl:"required_extensions" cty:"required_extensions"` Versions versionMap `hcl:"versions" cty:"versions"` Remain hcl.Body `hcl:",remain"` } diff --git a/dagger/maintenance/testingvalues.go b/dagger/maintenance/testingvalues.go new file mode 100644 index 0000000..99e7b99 --- /dev/null +++ b/dagger/maintenance/testingvalues.go @@ -0,0 +1,49 @@ +package main + +import ( + "context" + + "dagger/maintenance/internal/dagger" +) + +func generateTestingValuesExtensions(ctx context.Context, source *dagger.Directory, metadata *extensionMetadata, extensionImage string) ([]map[string]any, error) { + var out []map[string]any + configuration, err := generateExtensionConfiguration(metadata, extensionImage) + if err != nil { + return nil, err + } + out = append(out, configuration) + for _, deps := range metadata.RequiredExtensions { + depsMetadata, parseErr := parseExtensionMetadata(ctx, source.Directory(deps)) + if parseErr != nil { + return nil, parseErr + } + depsConfiguration, extErr := generateExtensionConfiguration(depsMetadata, "") + if extErr != nil { + return nil, extErr + } + out = append(out, depsConfiguration) + + } + return out, nil +} + +func generateExtensionConfiguration(metadata *extensionMetadata, extensionImage string) (map[string]any, error) { + targetExtensionImage := extensionImage + if targetExtensionImage == "" { + var err error + targetExtensionImage, err = getDefaultExtensionImage(metadata) + if err != nil { + return nil, err + } + } + return map[string]any{ + "name": metadata.Name, + "image": map[string]string{ + "reference": targetExtensionImage, + }, + "extension_control_path": metadata.ExtensionControlPath, + "dynamic_library_path": metadata.DynamicLibraryPath, + "ld_library_path": metadata.LdLibraryPath, + }, nil +} diff --git a/pgaudit/metadata.hcl b/pgaudit/metadata.hcl index 7cdf53a..ba2a970 100644 --- a/pgaudit/metadata.hcl +++ b/pgaudit/metadata.hcl @@ -7,6 +7,7 @@ metadata = { dynamic_library_path = [] ld_library_path = [] auto_update_os_libs = false + required_extensions = [] versions = { bookworm = { diff --git a/pgvector/metadata.hcl b/pgvector/metadata.hcl index c8ca281..965b403 100644 --- a/pgvector/metadata.hcl +++ b/pgvector/metadata.hcl @@ -7,6 +7,7 @@ metadata = { dynamic_library_path = [] ld_library_path = [] auto_update_os_libs = false + required_extensions = [] versions = { bookworm = { diff --git a/postgis/metadata.hcl b/postgis/metadata.hcl index be8de2c..9f2156c 100644 --- a/postgis/metadata.hcl +++ b/postgis/metadata.hcl @@ -7,6 +7,7 @@ metadata = { dynamic_library_path = [] ld_library_path = ["/system"] auto_update_os_libs = true + required_extensions = [] versions = { bookworm = { diff --git a/postgis/test/cluster.yaml b/postgis/test/cluster.yaml index 779b4a1..1a06cd3 100644 --- a/postgis/test/cluster.yaml +++ b/postgis/test/cluster.yaml @@ -11,10 +11,4 @@ spec: postgresql: shared_preload_libraries: ($values.shared_preload_libraries) - extensions: - - name: ($values.name) - image: - reference: ($values.extension_image) - extension_control_path: ($values.extension_control_path) - dynamic_library_path: ($values.dynamic_library_path) - ld_library_path: ($values.ld_library_path) + extensions: ($values.extensions) diff --git a/test/cluster.yaml b/test/cluster.yaml index 779b4a1..1a06cd3 100644 --- a/test/cluster.yaml +++ b/test/cluster.yaml @@ -11,10 +11,4 @@ spec: postgresql: shared_preload_libraries: ($values.shared_preload_libraries) - extensions: - - name: ($values.name) - image: - reference: ($values.extension_image) - extension_control_path: ($values.extension_control_path) - dynamic_library_path: ($values.dynamic_library_path) - ld_library_path: ($values.ld_library_path) + extensions: ($values.extensions) From 48fd2a2ea12f6431dc3e884c3856bb517e15aa6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Fei?= Date: Wed, 28 Jan 2026 18:48:52 +0100 Subject: [PATCH 2/3] chore: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Niccolò Fei --- Taskfile.yml | 3 +++ dagger/maintenance/main.go | 12 ++++-------- dagger/maintenance/parse.go | 9 +++++++++ dagger/maintenance/testingvalues.go | 19 +++++++++++++++---- templates/metadata.hcl.tmpl | 1 + 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/Taskfile.yml b/Taskfile.yml index d22a197..ed85e48 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -328,6 +328,9 @@ tasks: # We need to replace localhost with the registry container name as it is how # the registry is reachable from within the Docker network. sh: sed -E 's/^localhost/{{ .REGISTRY_NAME }}/;t' <<< "{{ .EXTENSION_IMAGE }}" + requires: + vars: + - name: TARGET e2e:test: desc: Test target extension using Chainsaw diff --git a/dagger/maintenance/main.go b/dagger/maintenance/main.go index e77be42..618c407 100644 --- a/dagger/maintenance/main.go +++ b/dagger/maintenance/main.go @@ -178,15 +178,11 @@ func (m *Maintenance) GenerateTestingValues( targetExtensionImage) } - extensions, generateExtErr := generateTestingValuesExtensions( - ctx, - source, - metadata, - targetExtensionImage, - ) - if generateExtErr != nil { - return nil, generateExtErr + extensions, err := generateTestingValuesExtensions(ctx, source, metadata, targetExtensionImage) + if err != nil { + return nil, err } + // Build values.yaml content values := map[string]any{ "name": metadata.Name, diff --git a/dagger/maintenance/parse.go b/dagger/maintenance/parse.go index 5853634..344342a 100644 --- a/dagger/maintenance/parse.go +++ b/dagger/maintenance/parse.go @@ -3,6 +3,7 @@ package main import ( "context" "encoding/json" + "fmt" "path" "github.com/docker/buildx/bake" @@ -92,6 +93,14 @@ func parseExtensionMetadata(ctx context.Context, extensionDirectory *dagger.Dire Remain hcl.Body `hcl:",remain"` } + hasMetadataFile, err := extensionDirectory.Exists(ctx, metadataFile) + if err != nil { + return nil, err + } + if !hasMetadataFile { + return nil, fmt.Errorf("not a valid target, metadata.hcl file is missing") + } + data, err := extensionDirectory.File(metadataFile).Contents(ctx) if err != nil { return nil, err diff --git a/dagger/maintenance/testingvalues.go b/dagger/maintenance/testingvalues.go index 99e7b99..2bc21a8 100644 --- a/dagger/maintenance/testingvalues.go +++ b/dagger/maintenance/testingvalues.go @@ -2,6 +2,7 @@ package main import ( "context" + "fmt" "dagger/maintenance/internal/dagger" ) @@ -13,18 +14,27 @@ func generateTestingValuesExtensions(ctx context.Context, source *dagger.Directo return nil, err } out = append(out, configuration) - for _, deps := range metadata.RequiredExtensions { - depsMetadata, parseErr := parseExtensionMetadata(ctx, source.Directory(deps)) + + for _, dep := range metadata.RequiredExtensions { + depExists, err := source.Exists(ctx, dep) + if err != nil { + return nil, err + } + if !depExists { + return nil, fmt.Errorf("required dependency %q not found", dep) + } + + depMetadata, parseErr := parseExtensionMetadata(ctx, source.Directory(dep)) if parseErr != nil { return nil, parseErr } - depsConfiguration, extErr := generateExtensionConfiguration(depsMetadata, "") + depsConfiguration, extErr := generateExtensionConfiguration(depMetadata, "") if extErr != nil { return nil, extErr } out = append(out, depsConfiguration) - } + return out, nil } @@ -37,6 +47,7 @@ func generateExtensionConfiguration(metadata *extensionMetadata, extensionImage return nil, err } } + return map[string]any{ "name": metadata.Name, "image": map[string]string{ diff --git a/templates/metadata.hcl.tmpl b/templates/metadata.hcl.tmpl index d6f800f..cffc0ea 100644 --- a/templates/metadata.hcl.tmpl +++ b/templates/metadata.hcl.tmpl @@ -9,6 +9,7 @@ metadata = { dynamic_library_path = [] ld_library_path = [] auto_update_os_libs = false + required_extensions = [] versions = { {{- range $distro := .Distros}} From 61be6b05e8ef3257bb64433263cfb5d465b3ed92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Fei?= Date: Mon, 2 Feb 2026 14:52:29 +0100 Subject: [PATCH 3/3] Apply suggestions from Gabriele MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gabriele Fedi Signed-off-by: Niccolò Fei --- dagger/maintenance/parse.go | 2 +- dagger/maintenance/testingvalues.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dagger/maintenance/parse.go b/dagger/maintenance/parse.go index 344342a..82611b9 100644 --- a/dagger/maintenance/parse.go +++ b/dagger/maintenance/parse.go @@ -98,7 +98,7 @@ func parseExtensionMetadata(ctx context.Context, extensionDirectory *dagger.Dire return nil, err } if !hasMetadataFile { - return nil, fmt.Errorf("not a valid target, metadata.hcl file is missing") + return nil, fmt.Errorf("metadata.hcl file is missing") } data, err := extensionDirectory.File(metadataFile).Contents(ctx) diff --git a/dagger/maintenance/testingvalues.go b/dagger/maintenance/testingvalues.go index 2bc21a8..33ec68c 100644 --- a/dagger/maintenance/testingvalues.go +++ b/dagger/maintenance/testingvalues.go @@ -26,7 +26,7 @@ func generateTestingValuesExtensions(ctx context.Context, source *dagger.Directo depMetadata, parseErr := parseExtensionMetadata(ctx, source.Directory(dep)) if parseErr != nil { - return nil, parseErr + return nil, fmt.Errorf("failed to parse dependency metadata %q: %w", dep, parseErr) } depsConfiguration, extErr := generateExtensionConfiguration(depMetadata, "") if extErr != nil {