Skip to content

Commit e73bc06

Browse files
committed
feat: automate generation of chainsaw testing values
Signed-off-by: Niccolò Fei <[email protected]>
1 parent 39c7567 commit e73bc06

File tree

6 files changed

+139
-28
lines changed

6 files changed

+139
-28
lines changed

.github/workflows/bake_targets.yml

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,6 @@ jobs:
130130
with:
131131
persist-credentials: false
132132

133-
- name: Install Go
134-
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6
135-
with:
136-
cache: false
137-
go-version: 'stable'
138-
139133
- name: Create kind cluster
140134
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0
141135
with:
@@ -155,24 +149,16 @@ jobs:
155149
curl -sSfL "$operator_manifest" | kubectl apply --server-side -f -
156150
kubectl wait --for=condition=Available --timeout=2m -n cnpg-system deployments cnpg-controller-manager
157151
158-
- name: Generate Chainsaw runtime values
152+
- name: Generate Chainsaw testing values
153+
uses: dagger/dagger-for-github@d913e70051faf3b907d4dd96ef1161083c88c644 # v8.2.0
159154
env:
160-
EXT_NAME: ${{ inputs.extension_name }}
161-
EXT_IMAGE: ${{ matrix.image }}
162-
run: |
163-
# Get the PG base image
164-
export PG_IMAGE=$(skopeo inspect "docker://$EXT_IMAGE" -f '{{ json .Labels }}' | jq -r '."io.cloudnativepg.image.base.name"')
165-
166-
go install github.com/tmccombs/[email protected]
167-
go install github.com/mikefarah/yq/v4@v4
168-
169-
# Convert metadata.hcl to YAML and merge it with runtime values to generate a valid Chainsaw values.yaml
170-
yq eval -P '
171-
.metadata.extension_image = strenv(EXT_IMAGE) |
172-
.metadata.pg_image = strenv(PG_IMAGE) |
173-
.metadata
174-
' <(hcl2json "$EXT_NAME/metadata.hcl") > "$EXT_NAME/values.yaml"
175-
cat "$EXT_NAME/values.yaml"
155+
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
156+
DAGGER_VERSION: 0.19.7
157+
with:
158+
version: ${{ env.DAGGER_VERSION }}
159+
verb: call
160+
module: ./dagger/maintenance/
161+
args: generate-testing-values --target ${{ inputs.extension_name }} --extension-image ${{ matrix.image }}
176162

177163
- name: Install Chainsaw
178164
uses: kyverno/action-install-chainsaw@06560d18422209e9c1e08e931d477d04bf2674c1 # v0.2.14

dagger/maintenance/go.mod

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ go 1.25.3
44

55
require (
66
github.com/docker/buildx v0.30.1
7+
github.com/google/go-containerregistry v0.20.6
78
github.com/hashicorp/hcl/v2 v2.24.0
89
github.com/vektah/gqlparser/v2 v2.5.30
910
go.opentelemetry.io/otel v1.38.0
@@ -42,10 +43,12 @@ require (
4243
github.com/containerd/errdefs/pkg v0.3.0 // indirect
4344
github.com/containerd/log v0.1.0 // indirect
4445
github.com/containerd/platforms v1.0.0-rc.2 // indirect
46+
github.com/containerd/stargz-snapshotter/estargz v0.17.0 // indirect
4547
github.com/containerd/ttrpc v1.2.7 // indirect
4648
github.com/containerd/typeurl/v2 v2.2.3 // indirect
4749
github.com/distribution/reference v0.6.0 // indirect
4850
github.com/docker/cli v28.5.1+incompatible // indirect
51+
github.com/docker/distribution v2.8.3+incompatible // indirect
4952
github.com/docker/docker v28.5.1+incompatible // indirect
5053
github.com/docker/docker-credential-helpers v0.9.3 // indirect
5154
github.com/docker/go v1.5.1-1 // indirect
@@ -71,6 +74,7 @@ require (
7174
github.com/klauspost/compress v1.18.1 // indirect
7275
github.com/mattn/go-runewidth v0.0.16 // indirect
7376
github.com/mattn/go-shellwords v1.0.12 // indirect
77+
github.com/mitchellh/go-homedir v1.1.0 // indirect
7478
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
7579
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
7680
github.com/moby/buildkit v0.26.1 // indirect
@@ -101,6 +105,7 @@ require (
101105
github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0 // indirect
102106
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
103107
github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab // indirect
108+
github.com/vbatts/tar-split v0.12.2 // indirect
104109
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
105110
github.com/zclconf/go-cty v1.17.0 // indirect
106111
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
@@ -119,7 +124,7 @@ require (
119124
go.opentelemetry.io/otel/sdk/log v0.14.0
120125
go.opentelemetry.io/otel/sdk/metric v1.38.0
121126
go.opentelemetry.io/proto/otlp v1.8.0
122-
go.yaml.in/yaml/v3 v3.0.4 // indirect
127+
go.yaml.in/yaml/v3 v3.0.4
123128
golang.org/x/crypto v0.42.0 // indirect
124129
golang.org/x/mod v0.29.0 // indirect
125130
golang.org/x/net v0.44.0 // indirect

dagger/maintenance/go.sum

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ github.com/containerd/platforms v1.0.0-rc.2 h1:0SPgaNZPVWGEi4grZdV8VRYQn78y+nm6a
8080
github.com/containerd/platforms v1.0.0-rc.2/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4=
8181
github.com/containerd/plugin v1.0.0 h1:c8Kf1TNl6+e2TtMHZt+39yAPDbouRH9WAToRjex483Y=
8282
github.com/containerd/plugin v1.0.0/go.mod h1:hQfJe5nmWfImiqT1q8Si3jLv3ynMUIBB47bQ+KexvO8=
83-
github.com/containerd/stargz-snapshotter v0.17.0 h1:djNS4KU8ztFhLdEDZ1bsfzOiYuVHT6TgSU5qwRk+cNc=
8483
github.com/containerd/stargz-snapshotter/estargz v0.17.0 h1:+TyQIsR/zSFI1Rm31EQBwpAA1ovYgIKHy7kctL3sLcE=
8584
github.com/containerd/stargz-snapshotter/estargz v0.17.0/go.mod h1:s06tWAiJcXQo9/8AReBCIo/QxcXFZ2n4qfsRnpl71SM=
8685
github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRqQ=
@@ -138,6 +137,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
138137
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
139138
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
140139
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
140+
github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU=
141+
github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y=
141142
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
142143
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
143144
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -170,6 +171,8 @@ github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebG
170171
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
171172
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
172173
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
174+
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
175+
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
173176
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
174177
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
175178
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=

dagger/maintenance/image.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
"strconv"
7+
8+
"github.com/google/go-containerregistry/pkg/name"
9+
"github.com/google/go-containerregistry/pkg/v1/remote"
10+
)
11+
12+
const (
13+
DefaultPgMajor = 18
14+
DefaultDistribution = "trixie"
15+
)
16+
17+
// getImageLabels returns the OCI labels given an image ref.
18+
func getImageLabels(imageRef string) (map[string]string, error) {
19+
ref, err := name.ParseReference(imageRef)
20+
if err != nil {
21+
return nil, err
22+
}
23+
24+
desc, err := remote.Get(ref)
25+
if err != nil {
26+
return nil, err
27+
}
28+
29+
img, err := desc.Image()
30+
if err != nil {
31+
return nil, err
32+
}
33+
34+
cfg, err := img.ConfigFile()
35+
if err != nil {
36+
return nil, err
37+
}
38+
39+
return cfg.Config.Labels, nil
40+
}
41+
42+
// getDefaultExtensionImage returns the default extension image for a given extension,
43+
// resolved from the metadata.
44+
func getDefaultExtensionImage(metadata *extensionMetadata) (string, error) {
45+
packageVersion := metadata.Versions[DefaultDistribution][strconv.Itoa(DefaultPgMajor)]
46+
re := regexp.MustCompile(`^(\d+(?:\.\d+)+)`)
47+
matches := re.FindStringSubmatch(packageVersion)
48+
if len(matches) < 2 {
49+
return "", fmt.Errorf("cannot extract extension version from %q", packageVersion)
50+
}
51+
version := matches[1]
52+
image := fmt.Sprintf("ghcr.io/cloudnative-pg/%s:%s-%d-%s",
53+
metadata.ImageName, version, DefaultPgMajor, DefaultDistribution)
54+
55+
return image, nil
56+
}

dagger/maintenance/main.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"path"
1111
"slices"
1212

13+
"go.yaml.in/yaml/v3"
14+
1315
"dagger/maintenance/internal/dagger"
1416
)
1517

@@ -92,3 +94,53 @@ func (m *Maintenance) GetOSLibsTargets(
9294

9395
return string(jsonTargets), nil
9496
}
97+
98+
// Generates Chainsaw's testing external values in YAML format
99+
func (m *Maintenance) GenerateTestingValues(
100+
ctx context.Context,
101+
// Path to the target extension directory
102+
target *dagger.Directory,
103+
// URL reference to the extension image to test [REPOSITORY[:TAG]]
104+
// +optional
105+
extensionImage string,
106+
) (*dagger.File, error) {
107+
metadata, err := parseExtensionMetadata(ctx, target)
108+
if err != nil {
109+
return nil, err
110+
}
111+
112+
targetExtensionImage := extensionImage
113+
if targetExtensionImage == "" {
114+
targetExtensionImage, err = getDefaultExtensionImage(metadata)
115+
if err != nil {
116+
return nil, err
117+
}
118+
}
119+
120+
labels, err := getImageLabels(targetExtensionImage)
121+
if err != nil {
122+
return nil, err
123+
}
124+
125+
// Build values.yaml content
126+
values := map[string]any{
127+
"name": metadata.Name,
128+
"sql_name": metadata.SQLName,
129+
"image_name": metadata.ImageName,
130+
"shared_preload_libraries": metadata.SharedPreloadLibraries,
131+
"extension_control_path": metadata.ExtensionControlPath,
132+
"dynamic_library_path": metadata.DynamicLibraryPath,
133+
"ld_library_path": metadata.LdLibraryPath,
134+
"extension_image": targetExtensionImage,
135+
"pg_image": labels["io.cloudnativepg.image.base.name"],
136+
"version": labels["org.opencontainers.image.version"],
137+
}
138+
valuesYaml, err := yaml.Marshal(values)
139+
if err != nil {
140+
return nil, err
141+
}
142+
143+
result := target.WithNewFile("values.yaml", string(valuesYaml))
144+
145+
return result.File("values.yaml"), nil
146+
}

dagger/maintenance/parse.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,19 @@ type buildMatrix struct {
1717
MajorVersions []string
1818
}
1919

20+
type versionMap map[string]map[string]string
21+
2022
type extensionMetadata struct {
21-
Name string `hcl:"name" cty:"name"`
22-
AutoUpdateOsLibs bool `hcl:"auto_update_os_libs" cty:"auto_update_os_libs"`
23-
Remain hcl.Body `hcl:",remain"`
23+
Name string `hcl:"name" cty:"name"`
24+
SQLName string `hcl:"sql_name" cty:"sql_name"`
25+
ImageName string `hcl:"image_name" cty:"image_name"`
26+
SharedPreloadLibraries []string `hcl:"shared_preload_libraries" cty:"shared_preload_libraries"`
27+
ExtensionControlPath []string `hcl:"extension_control_path" cty:"extension_control_path"`
28+
DynamicLibraryPath []string `hcl:"dynamic_library_path" cty:"dynamic_library_path"`
29+
LdLibraryPath []string `hcl:"ld_library_path" cty:"ld_library_path"`
30+
AutoUpdateOsLibs bool `hcl:"auto_update_os_libs" cty:"auto_update_os_libs"`
31+
Versions versionMap `hcl:"versions" cty:"versions"`
32+
Remain hcl.Body `hcl:",remain"`
2433
}
2534

2635
const (

0 commit comments

Comments
 (0)