Skip to content

Commit 637aca0

Browse files
authored
Merge pull request #53 from BaizeAI/add-append
add append snapeed suffix
2 parents 4ef6be3 + ef9dba7 commit 637aca0

File tree

10 files changed

+143
-145
lines changed

10 files changed

+143
-145
lines changed

api/v1alpha1/snapshotpod_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ type ImageSaveOptions struct {
5757
// tag - the tag of origin image, if not set, will be latest, if use sha format image like nginx@sha256:abcdef, tag will be the real sha value like abcdef
5858
ImageRefFormat string `json:"imageRefFormat,omitempty"`
5959
RegistrySecretRef string `json:"registrySecretRef,omitempty"`
60+
// AppendSnappedSuffix controls whether to append "-snapped" suffix to the image tag.
61+
// If true, the suffix will be added; if false, no suffix will be added.
62+
// +optional
63+
// +kubebuilder:default:=true
64+
AppendSnappedSuffix *bool `json:"appendSnappedSuffix,omitempty"`
6065
// MaxRetries defines the maximum number of retries when the task fails
6166
// +optional
6267
// +kubebuilder:default:=3

config/crd/bases/snapshot-pod.baizeai.io_snapshotpods.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ spec:
8282
imageSaveOptions:
8383
description: Image save options.
8484
properties:
85+
appendSnappedSuffix:
86+
default: true
87+
description: |-
88+
AppendSnappedSuffix controls whether to append "-snapped" suffix to the image tag.
89+
If true, the suffix will be added; if false, no suffix will be added.
90+
type: boolean
8591
imageRefFormat:
8692
description: |-
8793
ImageRefFormat is the format of new image.

config/samples/kustomization.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## Append samples of your project ##
22
resources:
33
- snapshot-pod_v1alpha1_snapshotpod.yaml
4+
- snapshot-pod_v1alpha1_snapshotpod_no_suffix.yaml
45
- snapshot-pod_v1alpha1_snapshotpodtask.yaml
56
# +kubebuilder:scaffold:manifestskustomizesamples

config/samples/snapshot-pod_v1alpha1_snapshotpod.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,9 @@ spec:
1515
message: auto save
1616
imageSaveOptions:
1717
imageRefFormat: aiharbor.daocloud.io/kebe-test/{last_repository}
18+
# appendSnappedSuffix controls whether to append the full suffix to the image tag
19+
# If true (default), the full suffix will be added: -snapped-{timestamp}-{uuid}
20+
# If false, no suffix will be added at all
21+
# +optional
22+
appendSnappedSuffix: true
1823
# registrySecretRef: aiharbor-secret
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
apiVersion: snapshot-pod.baizeai.io/v1alpha1
2+
kind: SnapshotPod
3+
metadata:
4+
labels:
5+
app.kubernetes.io/name: snapshot-pod
6+
app.kubernetes.io/managed-by: kustomize
7+
name: snapshotpod-sample-no-suffix
8+
spec:
9+
target:
10+
name: test
11+
triggerRound: 1
12+
commitOptions:
13+
pauseContainer: false
14+
timeout: 3m
15+
message: auto save without snapped suffix
16+
imageSaveOptions:
17+
imageRefFormat: aiharbor.daocloud.io/kebe-test/{last_repository}
18+
# Set appendSnappedSuffix to false to disable the full suffix
19+
# When false, the image tag will remain unchanged
20+
appendSnappedSuffix: false
21+
# registrySecretRef: aiharbor-secret

go.mod

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ require (
1818
k8s.io/apimachinery v0.33.3
1919
k8s.io/client-go v0.33.3
2020
k8s.io/klog/v2 v2.130.1
21-
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
2221
sigs.k8s.io/controller-runtime v0.21.0
2322
)
2423

@@ -123,7 +122,6 @@ require (
123122
github.com/spaolacci/murmur3 v1.1.0 // indirect
124123
github.com/spf13/pflag v1.0.6 // indirect
125124
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect
126-
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
127125
github.com/x448/float16 v0.8.4 // indirect
128126
go.opencensus.io v0.24.0 // indirect
129127
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
@@ -137,7 +135,6 @@ require (
137135
go.uber.org/zap v1.27.0 // indirect
138136
go.yaml.in/yaml/v2 v2.4.2 // indirect
139137
golang.org/x/crypto v0.40.0 // indirect
140-
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
141138
golang.org/x/net v0.41.0 // indirect
142139
golang.org/x/oauth2 v0.30.0 // indirect
143140
golang.org/x/sync v0.16.0 // indirect
@@ -154,6 +151,7 @@ require (
154151
gopkg.in/yaml.v3 v3.0.1 // indirect
155152
k8s.io/apiextensions-apiserver v0.33.2 // indirect
156153
k8s.io/kube-openapi v0.0.0-20250610211856-8b98d1ed966a // indirect
154+
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
157155
lukechampine.com/blake3 v1.4.1 // indirect
158156
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
159157
sigs.k8s.io/randfill v1.0.0 // indirect

go.sum

Lines changed: 6 additions & 131 deletions
Large diffs are not rendered by default.

internal/controller/snapshotpod_controller.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,14 @@ func (r *SnapshotPodReconciler) reconcileTasks(ctx context.Context, sp *snapshot
146146
if cs.ContainerID == "" {
147147
return fmt.Errorf("container %s not started", c)
148148
}
149-
newImage, err := renderNewImageName(cs.Image, sp.Spec.ImageSaveOptions.ImageRefFormat)
149+
150+
// Get appendSnappedSuffix value, default to true if not specified
151+
appendSnappedSuffix := true
152+
if sp.Spec.ImageSaveOptions.AppendSnappedSuffix != nil {
153+
appendSnappedSuffix = *sp.Spec.ImageSaveOptions.AppendSnappedSuffix
154+
}
155+
156+
newImage, err := renderNewImageName(cs.Image, sp.Spec.ImageSaveOptions.ImageRefFormat, appendSnappedSuffix)
150157
if err != nil {
151158
return err
152159
}
@@ -241,21 +248,25 @@ func (r *SnapshotPodReconciler) reconcileTasksStatus(ctx context.Context, sp *sn
241248
return nil
242249
}
243250

244-
func withRandomTag(tag string) string {
245-
fixed := "snapped-"
246-
if strings.Contains(tag, fixed) {
251+
func withRandomTag(tag string, appendSnappedSuffix bool) string {
252+
if !appendSnappedSuffix {
247253
return tag
248254
}
249-
gen := func() string {
250-
return fmt.Sprintf("%s%d-%s", fixed, time.Now().Unix(), strings.ReplaceAll(uuid.New().String(), "-", "")[:8])
255+
256+
if strings.Contains(tag, "snapped-") {
257+
return tag
251258
}
259+
260+
suffix := fmt.Sprintf("snapped-%d-%s", time.Now().Unix(), strings.ReplaceAll(uuid.New().String(), "-", "")[:8])
261+
252262
if tag == "" || tag == "latest" {
253-
return gen()
263+
return suffix
254264
}
255-
return fmt.Sprintf("%s-%s", tag, gen())
265+
266+
return fmt.Sprintf("%s-%s", tag, suffix)
256267
}
257268

258-
func renderNewImageName(originImage, format string) (string, error) {
269+
func renderNewImageName(originImage, format string, appendSnappedSuffix bool) (string, error) {
259270
ref, err := docker.ParseReference("//" + originImage)
260271
if err != nil {
261272
return "", err
@@ -286,9 +297,9 @@ func renderNewImageName(originImage, format string) (string, error) {
286297
}
287298
newTag := ""
288299
if v, ok := ref.DockerReference().(reference.NamedTagged); !ok {
289-
newTag = withRandomTag("")
300+
newTag = withRandomTag("", appendSnappedSuffix)
290301
} else {
291-
newTag = withRandomTag(v.Tag())
302+
newTag = withRandomTag(v.Tag(), appendSnappedSuffix)
292303
}
293304
v, err := reference.WithTag(ref.DockerReference(), newTag)
294305
if err != nil {

internal/controller/snapshotpod_controller_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,76 @@ import (
3131
)
3232

3333
var _ = Describe("SnapshotPod Controller", func() {
34+
Context("When testing withRandomTag function", func() {
35+
It("should return original tag when appendSnappedSuffix is false", func() {
36+
By("Testing with appendSnappedSuffix = false")
37+
38+
// Test case 1: empty tag
39+
result := withRandomTag("", false)
40+
Expect(result).To(Equal(""))
41+
42+
// Test case 2: latest tag
43+
result = withRandomTag("latest", false)
44+
Expect(result).To(Equal("latest"))
45+
46+
// Test case 3: custom tag
47+
result = withRandomTag("v1.0.0", false)
48+
Expect(result).To(Equal("v1.0.0"))
49+
50+
// Test case 4: tag with special characters
51+
result = withRandomTag("release-2024-01", false)
52+
Expect(result).To(Equal("release-2024-01"))
53+
})
54+
55+
It("should append snapped suffix when appendSnappedSuffix is true", func() {
56+
By("Testing with appendSnappedSuffix = true")
57+
58+
// Test case 1: empty tag
59+
result := withRandomTag("", true)
60+
Expect(result).To(ContainSubstring("snapped-"))
61+
Expect(result).To(MatchRegexp(`^snapped-\d+-[a-f0-9]{8}$`))
62+
63+
// Test case 2: latest tag
64+
result = withRandomTag("latest", true)
65+
Expect(result).To(ContainSubstring("snapped-"))
66+
Expect(result).To(MatchRegexp(`^snapped-\d+-[a-f0-9]{8}$`))
67+
68+
// Test case 3: custom tag
69+
result = withRandomTag("v1.0.0", true)
70+
Expect(result).To(ContainSubstring("v1.0.0-snapped-"))
71+
Expect(result).To(MatchRegexp(`^v1\.0\.0-snapped-\d+-[a-f0-9]{8}$`))
72+
73+
// Test case 4: tag with special characters
74+
result = withRandomTag("release-2024-01", true)
75+
Expect(result).To(ContainSubstring("release-2024-01-snapped-"))
76+
Expect(result).To(MatchRegexp(`^release-2024-01-snapped-\d+-[a-f0-9]{8}$`))
77+
})
78+
79+
It("should not append suffix to already snapped tags", func() {
80+
By("Testing with tags that already contain 'snapped-'")
81+
82+
// Test case 1: already snapped tag
83+
alreadySnapped := "v1.0.0-snapped-1704067200-abc12345"
84+
result := withRandomTag(alreadySnapped, true)
85+
Expect(result).To(Equal(alreadySnapped))
86+
87+
// Test case 2: already snapped tag with appendSnappedSuffix = false
88+
result = withRandomTag(alreadySnapped, false)
89+
Expect(result).To(Equal(alreadySnapped))
90+
})
91+
92+
It("should generate unique suffixes for different calls", func() {
93+
By("Testing that multiple calls generate different suffixes")
94+
95+
result1 := withRandomTag("test", true)
96+
result2 := withRandomTag("test", true)
97+
98+
Expect(result1).NotTo(Equal(result2))
99+
Expect(result1).To(ContainSubstring("test-snapped-"))
100+
Expect(result2).To(ContainSubstring("test-snapped-"))
101+
})
102+
})
103+
34104
Context("When reconciling a resource", func() {
35105
const resourceName = "test-resource"
36106

manifests/snapshot-pod/templates/snapshot-pod.baizeai.io_snapshotpods.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ spec:
8282
imageSaveOptions:
8383
description: Image save options.
8484
properties:
85+
appendSnappedSuffix:
86+
default: true
87+
description: |-
88+
AppendSnappedSuffix controls whether to append "-snapped" suffix to the image tag.
89+
If true, the suffix will be added; if false, no suffix will be added.
90+
type: boolean
8591
imageRefFormat:
8692
description: |-
8793
ImageRefFormat is the format of new image.

0 commit comments

Comments
 (0)