Skip to content

Commit 5207c78

Browse files
authored
fix(snapshots): detect kURL minio add-on from any repository (#6037)
1 parent 72d05fa commit 5207c78

2 files changed

Lines changed: 112 additions & 3 deletions

File tree

pkg/image/minio.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package image
22

33
import (
44
"context"
5-
"strings"
5+
"regexp"
66

77
"github.com/pkg/errors"
88
"github.com/replicatedhq/kots/pkg/kurl"
@@ -11,6 +11,11 @@ import (
1111
"k8s.io/client-go/kubernetes"
1212
)
1313

14+
// minioReleaseImageRegexp matches any repository whose image name is "minio" with an
15+
// upstream RELEASE tag, e.g. "minio/minio:RELEASE.2025-10-15T17-29-55Z" and
16+
// "kurlsh/minio:RELEASE.2025-10-15T17-29-55Z".
17+
var minioReleaseImageRegexp = regexp.MustCompile(`(^|/)minio:RELEASE\.`)
18+
1419
// MinioImage looks through the nodes in the cluster and finds nodes that have already pulled Minio, and then finds the latest image tag listed
1520
func GetMinioImage(clientset kubernetes.Interface, kotsadmNamespace string) (string, error) {
1621
/*
@@ -30,7 +35,7 @@ func GetMinioImage(clientset kubernetes.Interface, kotsadmNamespace string) (str
3035
}
3136
if err == nil {
3237
for _, container := range deployment.Spec.Template.Spec.Containers {
33-
if strings.Contains(container.Image, "minio/minio:RELEASE.") {
38+
if isMinioReleaseImage(container.Image) {
3439
return container.Image, nil
3540
}
3641
}
@@ -44,11 +49,19 @@ func GetMinioImage(clientset kubernetes.Interface, kotsadmNamespace string) (str
4449
}
4550
if err == nil {
4651
for _, container := range statefulset.Spec.Template.Spec.Containers {
47-
if strings.Contains(container.Image, "minio/minio:RELEASE.") {
52+
if isMinioReleaseImage(container.Image) {
4853
return container.Image, nil
4954
}
5055
}
5156
}
5257

5358
return "", nil
5459
}
60+
61+
// isMinioReleaseImage returns true if the image is a minio image with an upstream
62+
// RELEASE tag, regardless of which repository it was published to. The add-on has
63+
// shipped from more than one repository (minio/minio, kurlsh/minio), so only the
64+
// image name and tag are matched, not the registry or organization.
65+
func isMinioReleaseImage(image string) bool {
66+
return minioReleaseImageRegexp.MatchString(image)
67+
}

pkg/image/minio_test.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,102 @@ func Test_GetMinioImage(t *testing.T) {
7171
wantImage: "minio/minio:RELEASE.2020-10-27T00-54-19Z",
7272
wantErr: false,
7373
},
74+
{
75+
name: "should return minio image from deployment when the add-on ships from the kurlsh repository",
76+
clientset: fake.NewSimpleClientset(
77+
&corev1.ConfigMap{
78+
ObjectMeta: metav1.ObjectMeta{
79+
Name: kurl.ConfigMapName,
80+
Namespace: kurl.ConfigMapNamespace,
81+
},
82+
},
83+
&appsv1.Deployment{
84+
ObjectMeta: metav1.ObjectMeta{
85+
Name: "minio",
86+
Namespace: "minio",
87+
},
88+
Spec: appsv1.DeploymentSpec{
89+
Template: corev1.PodTemplateSpec{
90+
Spec: corev1.PodSpec{
91+
Containers: []corev1.Container{
92+
{
93+
Name: "minio",
94+
Image: "kurlsh/minio:RELEASE.2025-10-15T17-29-55Z",
95+
},
96+
},
97+
},
98+
},
99+
},
100+
},
101+
),
102+
kotsadmNamespace: metav1.NamespaceDefault,
103+
wantImage: "kurlsh/minio:RELEASE.2025-10-15T17-29-55Z",
104+
wantErr: false,
105+
},
106+
{
107+
name: "should return minio image from deployment when the add-on is pulled from a private registry",
108+
clientset: fake.NewSimpleClientset(
109+
&corev1.ConfigMap{
110+
ObjectMeta: metav1.ObjectMeta{
111+
Name: kurl.ConfigMapName,
112+
Namespace: kurl.ConfigMapNamespace,
113+
},
114+
},
115+
&appsv1.Deployment{
116+
ObjectMeta: metav1.ObjectMeta{
117+
Name: "minio",
118+
Namespace: "minio",
119+
},
120+
Spec: appsv1.DeploymentSpec{
121+
Template: corev1.PodTemplateSpec{
122+
Spec: corev1.PodSpec{
123+
Containers: []corev1.Container{
124+
{
125+
Name: "minio",
126+
Image: "registry.example.com:5000/kurlsh/minio:RELEASE.2025-10-15T17-29-55Z",
127+
},
128+
},
129+
},
130+
},
131+
},
132+
},
133+
),
134+
kotsadmNamespace: metav1.NamespaceDefault,
135+
wantImage: "registry.example.com:5000/kurlsh/minio:RELEASE.2025-10-15T17-29-55Z",
136+
wantErr: false,
137+
},
138+
{
139+
name: "should return empty image when the minio container is not a RELEASE build",
140+
clientset: fake.NewSimpleClientset(
141+
&corev1.ConfigMap{
142+
ObjectMeta: metav1.ObjectMeta{
143+
Name: kurl.ConfigMapName,
144+
Namespace: kurl.ConfigMapNamespace,
145+
},
146+
},
147+
&appsv1.Deployment{
148+
ObjectMeta: metav1.ObjectMeta{
149+
Name: "minio",
150+
Namespace: "minio",
151+
},
152+
Spec: appsv1.DeploymentSpec{
153+
Template: corev1.PodTemplateSpec{
154+
Spec: corev1.PodSpec{
155+
Containers: []corev1.Container{
156+
{
157+
Name: "minio",
158+
Image: "kurlsh/minio:0.20250101.0",
159+
},
160+
},
161+
},
162+
},
163+
},
164+
},
165+
),
166+
kotsadmNamespace: metav1.NamespaceDefault,
167+
wantImage: "",
168+
wantErr: false,
169+
},
74170
{
75171
name: "should return minio image from statefulset for kurl instance with default namespace",
76172
clientset: fake.NewSimpleClientset(

0 commit comments

Comments
 (0)