Skip to content

Commit

Permalink
feat: replace image registry dynamically (#8018)
Browse files Browse the repository at this point in the history
  • Loading branch information
cjc7373 authored Dec 5, 2024
1 parent db0a8d9 commit 3f6d0aa
Show file tree
Hide file tree
Showing 16 changed files with 514 additions and 19 deletions.
7 changes: 7 additions & 0 deletions cmd/dataprotection/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,16 @@ func main() {
if err := viper.ReadInConfig(); err != nil { // Handle errors reading the config file
setupLog.Info("unable to read in config, errors ignored")
}
if err := intctrlutil.LoadRegistryConfig(); err != nil {
setupLog.Error(err, "unable to reload registry config")
os.Exit(1)
}
setupLog.Info(fmt.Sprintf("config file: %s", viper.GetViper().ConfigFileUsed()))
viper.OnConfigChange(func(e fsnotify.Event) {
setupLog.Info(fmt.Sprintf("config file changed: %s", e.Name))
if err := intctrlutil.LoadRegistryConfig(); err != nil {
setupLog.Error(err, "unable to reload registry config")
}
})
viper.WatchConfig()

Expand Down
7 changes: 7 additions & 0 deletions cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,16 @@ func main() {
if err := viper.ReadInConfig(); err != nil { // Handle errors reading the config file
setupLog.Info("unable to read in config, errors ignored")
}
if err := intctrlutil.LoadRegistryConfig(); err != nil {
setupLog.Error(err, "unable to reload registry config")
os.Exit(1)
}
setupLog.Info(fmt.Sprintf("config file: %s", viper.GetViper().ConfigFileUsed()))
viper.OnConfigChange(func(e fsnotify.Event) {
setupLog.Info(fmt.Sprintf("config file changed: %s", e.Name))
if err := intctrlutil.LoadRegistryConfig(); err != nil {
setupLog.Error(err, "unable to reload registry config")
}
})
viper.WatchConfig()

Expand Down
88 changes: 88 additions & 0 deletions controllers/apps/component_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2105,4 +2105,92 @@ var _ = Describe("Component Controller", func() {
testImageUnchangedAfterNewReleasePublished(release)
})
})

Context("with registry replace enabled", func() {
registry := "foo.bar"
setRegistryConfig := func() {
viper.Set(constant.CfgRegistries, map[string]any{
"defaultRegistry": registry,
})
Expect(intctrlutil.LoadRegistryConfig()).Should(Succeed())
}

BeforeEach(func() {
createAllDefinitionObjects()
})

AfterEach(func() {
viper.Set(constant.CfgRegistries, nil)
Expect(intctrlutil.LoadRegistryConfig()).Should(Succeed())
})

It("replaces image registry", func() {
setRegistryConfig()

createClusterObj(defaultCompName, compDefName, nil)

itsKey := compKey
Eventually(testapps.CheckObj(&testCtx, itsKey, func(g Gomega, its *workloads.InstanceSet) {
// check the image
c := its.Spec.Template.Spec.Containers[0]
g.Expect(c.Image).To(HavePrefix(registry))
})).Should(Succeed())
})

It("handles running its and upgrade", func() {
createClusterObj(defaultCompName, compDefName, nil)
itsKey := compKey
Eventually(testapps.CheckObj(&testCtx, itsKey, func(g Gomega, its *workloads.InstanceSet) {
// check the image
c := its.Spec.Template.Spec.Containers[0]
g.Expect(c.Image).To(Equal(compVerObj.Spec.Releases[0].Images[c.Name]))
})).Should(Succeed())

setRegistryConfig()
By("trigger component reconcile")
now := time.Now().Format(time.RFC3339)
Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *kbappsv1.Component) {
comp.Annotations["now"] = now
})()).Should(Succeed())

Consistently(testapps.CheckObj(&testCtx, itsKey, func(g Gomega, its *workloads.InstanceSet) {
// check the image
c := its.Spec.Template.Spec.Containers[0]
g.Expect(c.Image).NotTo(HavePrefix(registry))
})).Should(Succeed())

By("replaces registry when upgrading")
release := kbappsv1.ComponentVersionRelease{
Name: "8.0.31",
ServiceVersion: "8.0.31",
Images: map[string]string{
testapps.DefaultMySQLContainerName: "docker.io/apecloud/mysql:8.0.31",
},
}

By("publish a new release")
compVerKey := client.ObjectKeyFromObject(compVerObj)
Expect(testapps.GetAndChangeObj(&testCtx, compVerKey, func(compVer *kbappsv1.ComponentVersion) {
compVer.Spec.Releases = append(compVer.Spec.Releases, release)
compVer.Spec.CompatibilityRules[0].Releases = append(compVer.Spec.CompatibilityRules[0].Releases, release.Name)
})()).Should(Succeed())

By("update serviceversion in cluster")
Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *kbappsv1.Cluster) {
cluster.Spec.ComponentSpecs[0].ServiceVersion = "8.0.31"
})()).Should(Succeed())

By("trigger component reconcile")
now = time.Now().Format(time.RFC3339)
Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *kbappsv1.Component) {
comp.Annotations["now"] = now
})()).Should(Succeed())

Eventually(testapps.CheckObj(&testCtx, itsKey, func(g Gomega, its *workloads.InstanceSet) {
// check the image
c := its.Spec.Template.Spec.Containers[0]
g.Expect(c.Image).To(HavePrefix(registry))
})).Should(Succeed())
})
})
})
2 changes: 1 addition & 1 deletion controllers/apps/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ var _ = BeforeSuite(func() {
Expect(err).ToNot(HaveOccurred())

viper.SetDefault("CERT_DIR", "/tmp/k8s-webhook-server/serving-certs")
viper.SetDefault(constant.KBToolsImage, "apecloud/kubeblocks-tools:latest")
viper.SetDefault(constant.KBToolsImage, "docker.io/apecloud/kubeblocks-tools:latest")
viper.SetDefault("PROBE_SERVICE_PORT", 3501)
viper.SetDefault("PROBE_SERVICE_LOG_LEVEL", "info")
viper.SetDefault("CM_NAMESPACE", "default")
Expand Down
10 changes: 10 additions & 0 deletions controllers/apps/transformer_component_workload.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,16 @@ func (t *componentWorkloadTransformer) runningInstanceSetObject(ctx graph.Transf

func (t *componentWorkloadTransformer) reconcileWorkload(ctx context.Context, cli client.Reader,
synthesizedComp *component.SynthesizedComponent, comp *appsv1.Component, runningITS, protoITS *workloads.InstanceSet) error {
// if runningITS already exists, the image changes in protoITS will be
// rollback to the original image in `checkNRollbackProtoImages`.
// So changing registry configs won't affect existing clusters.
for i, container := range protoITS.Spec.Template.Spec.Containers {
protoITS.Spec.Template.Spec.Containers[i].Image = intctrlutil.ReplaceImageRegistry(container.Image)
}
for i, container := range protoITS.Spec.Template.Spec.InitContainers {
protoITS.Spec.Template.Spec.InitContainers[i].Image = intctrlutil.ReplaceImageRegistry(container.Image)
}

buildInstanceSetPlacementAnnotation(comp, protoITS)

if err := t.reconcileReplicasStatus(ctx, cli, synthesizedComp, runningITS, protoITS); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion controllers/extensions/addon_controller_stages.go
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ func setInitContainer(addon *extensionsv1alpha1.Addon, helmJobPodSpec *corev1.Po
}
copyChartsContainer := corev1.Container{
Name: "copy-charts",
Image: addon.Spec.Helm.ChartsImage,
Image: intctrlutil.ReplaceImageRegistry(addon.Spec.Helm.ChartsImage),
Command: []string{"sh", "-c", fmt.Sprintf("cp %s/* /mnt/charts", fromPath)},
VolumeMounts: []corev1.VolumeMount{
{
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/aws/aws-sdk-go v1.50.8
github.com/bhmj/jsonslice v1.1.2
github.com/clbanning/mxj/v2 v2.5.7
github.com/distribution/reference v0.6.0
github.com/docker/docker v25.0.6+incompatible
github.com/evanphx/json-patch v5.6.0+incompatible
github.com/evanphx/json-patch/v5 v5.8.0
Expand Down Expand Up @@ -104,7 +105,6 @@ require (
github.com/containerd/log v0.1.0 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/docker/cli v25.0.1+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc=
github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI=
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v25.0.1+incompatible h1:mFpqnrS6Hsm3v1k7Wa/BO23oz0k121MTbTO1lpcGSkU=
github.com/docker/cli v25.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
Expand Down
1 change: 1 addition & 0 deletions pkg/constant/viper_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@ const (
CfgClientQPS = "CLIENT_QPS"
CfgClientBurst = "CLIENT_BURST"

CfgRegistries = "registries"
I18nResourcesName = "I18N_RESOURCES_NAME"
)
Loading

0 comments on commit 3f6d0aa

Please sign in to comment.