diff --git a/deploy/crds/planetscale.com_vitessclusters.yaml b/deploy/crds/planetscale.com_vitessclusters.yaml
index e1da903a..d58c87cd 100644
--- a/deploy/crds/planetscale.com_vitessclusters.yaml
+++ b/deploy/crds/planetscale.com_vitessclusters.yaml
@@ -1172,6 +1172,28 @@ spec:
type: string
durabilityPolicy:
type: string
+ images:
+ properties:
+ mysqld:
+ properties:
+ mariadb103Compatible:
+ type: string
+ mariadbCompatible:
+ type: string
+ mysql56Compatible:
+ type: string
+ mysql80Compatible:
+ type: string
+ type: object
+ mysqldExporter:
+ type: string
+ vtbackup:
+ type: string
+ vtorc:
+ type: string
+ vttablet:
+ type: string
+ type: object
name:
maxLength: 63
minLength: 1
diff --git a/docs/api/index.html b/docs/api/index.html
index 6cce83f3..075eed20 100644
--- a/docs/api/index.html
+++ b/docs/api/index.html
@@ -4738,10 +4738,11 @@
VitessKeyspace
- Images are not customizable by users at the keyspace level because version
-skew across the cluster is discouraged except during rolling updates,
-in which case this field is automatically managed by the VitessCluster
-controller that owns this VitessKeyspace.
+Images are inherited from the VitessCluster spec, unless the user has
+specified keyspace-level overrides. Version skew across the cluster is
+discouraged except during rolling updates, in which case this field is
+automatically managed by the VitessCluster controller that owns this
+VitessKeyspace.
|
@@ -5046,6 +5047,7 @@ VitessKeyspaceImages
(Appears on:
VitessKeyspaceSpec,
+VitessKeyspaceTemplate,
VitessShardSpec)
@@ -5525,10 +5527,11 @@
VitessKeyspaceSpec
- Images are not customizable by users at the keyspace level because version
-skew across the cluster is discouraged except during rolling updates,
-in which case this field is automatically managed by the VitessCluster
-controller that owns this VitessKeyspace.
+Images are inherited from the VitessCluster spec, unless the user has
+specified keyspace-level overrides. Version skew across the cluster is
+discouraged except during rolling updates, in which case this field is
+automatically managed by the VitessCluster controller that owns this
+VitessKeyspace.
|
@@ -5904,6 +5907,24 @@ VitessKeyspaceTemplate
Annotations can optionally be used to attach custom annotations to the VitessKeyspace object.
+
+
+images
+
+
+VitessKeyspaceImages
+
+
+ |
+
+ Users are encouraged to let the VitessCluster controller automatically
+propagate image changes from the VitessCluster to the VitessKeyspace
+via rolling updates.
+For special cases, users may specify per-VitessKeyspace images. An
+example: migrating from MySQL 5.7 to MySQL 8.0 via a MoveTables
+operation, after which the source keyspace is destroyed.
+ |
+
VitessKeyspaceTurndownPolicy
diff --git a/pkg/apis/planetscale/v2/vitesskeyspace_defaults.go b/pkg/apis/planetscale/v2/vitesskeyspace_defaults.go
index 81189b87..47cca2cf 100644
--- a/pkg/apis/planetscale/v2/vitesskeyspace_defaults.go
+++ b/pkg/apis/planetscale/v2/vitesskeyspace_defaults.go
@@ -69,3 +69,23 @@ func DefaultVitessKeyspaceImages(dst *VitessKeyspaceImages, clusterDefaults *Vit
dst.MysqldExporter = clusterDefaults.MysqldExporter
}
}
+
+// MergeVitessKeyspaceImages takes non-empty image values from a non-nil src
+// and sets them on dst.
+func MergeVitessKeyspaceImages(dst *VitessKeyspaceImages, src *VitessKeyspaceImages) {
+ if src.Vttablet != "" {
+ dst.Vttablet = src.Vttablet
+ }
+ if src.Vtorc != "" {
+ dst.Vtorc = src.Vtorc
+ }
+ if src.Vtbackup != "" {
+ dst.Vtbackup = src.Vtbackup
+ }
+ if src.Mysqld != nil {
+ dst.Mysqld = src.Mysqld
+ }
+ if dst.MysqldExporter != "" {
+ dst.MysqldExporter = src.MysqldExporter
+ }
+}
diff --git a/pkg/apis/planetscale/v2/vitesskeyspace_types.go b/pkg/apis/planetscale/v2/vitesskeyspace_types.go
index 6f4e0ff1..f631343f 100644
--- a/pkg/apis/planetscale/v2/vitesskeyspace_types.go
+++ b/pkg/apis/planetscale/v2/vitesskeyspace_types.go
@@ -51,10 +51,11 @@ type VitessKeyspaceSpec struct {
// GlobalLockserver are the params to connect to the global lockserver.
GlobalLockserver VitessLockserverParams `json:"globalLockserver"`
- // Images are not customizable by users at the keyspace level because version
- // skew across the cluster is discouraged except during rolling updates,
- // in which case this field is automatically managed by the VitessCluster
- // controller that owns this VitessKeyspace.
+ // Images are inherited from the VitessCluster spec, unless the user has
+ // specified keyspace-level overrides. Version skew across the cluster is
+ // discouraged except during rolling updates, in which case this field is
+ // automatically managed by the VitessCluster controller that owns this
+ // VitessKeyspace.
Images VitessKeyspaceImages `json:"images,omitempty"`
// ImagePullPolicies are inherited from the VitessCluster spec.
@@ -178,6 +179,15 @@ type VitessKeyspaceTemplate struct {
// Annotations can optionally be used to attach custom annotations to the VitessKeyspace object.
Annotations map[string]string `json:"annotations,omitempty"`
+
+ // Users are encouraged to let the VitessCluster controller automatically
+ // propagate image changes from the VitessCluster to the VitessKeyspace
+ // via rolling updates.
+ //
+ // For special cases, users may specify per-VitessKeyspace images. An
+ // example: migrating from MySQL 5.7 to MySQL 8.0 via a `MoveTables`
+ // operation, after which the source keyspace is destroyed.
+ Images VitessKeyspaceImages `json:"images,omitempty"`
}
// VitessOrchestratorSpec specifies deployment parameters for vtorc.
diff --git a/pkg/apis/planetscale/v2/zz_generated.deepcopy.go b/pkg/apis/planetscale/v2/zz_generated.deepcopy.go
index ff017d72..7fa5578b 100644
--- a/pkg/apis/planetscale/v2/zz_generated.deepcopy.go
+++ b/pkg/apis/planetscale/v2/zz_generated.deepcopy.go
@@ -1983,6 +1983,7 @@ func (in *VitessKeyspaceTemplate) DeepCopyInto(out *VitessKeyspaceTemplate) {
(*out)[key] = val
}
}
+ in.Images.DeepCopyInto(&out.Images)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VitessKeyspaceTemplate.
diff --git a/pkg/controller/vitesscluster/reconcile_keyspaces.go b/pkg/controller/vitesscluster/reconcile_keyspaces.go
index 54ef4784..826d4e8e 100644
--- a/pkg/controller/vitesscluster/reconcile_keyspaces.go
+++ b/pkg/controller/vitesscluster/reconcile_keyspaces.go
@@ -149,6 +149,9 @@ func newVitessKeyspace(key client.ObjectKey, vt *planetscalev2.VitessCluster, pa
images := planetscalev2.VitessKeyspaceImages{}
planetscalev2.DefaultVitessKeyspaceImages(&images, &vt.Spec.Images)
+ // Apply user-defined overrides for images.
+ planetscalev2.MergeVitessKeyspaceImages(&images, &keyspace.Images)
+
// Copy parent labels map and add keyspace-specific label.
labels := make(map[string]string, len(parentLabels)+1)
for k, v := range parentLabels {