diff --git a/docs/api/index.html b/docs/api/index.html
index dfeb3cff..92c2cd3c 100644
--- a/docs/api/index.html
+++ b/docs/api/index.html
@@ -7075,7 +7075,8 @@
VitessShardTabletPool
Name is the pool’s unique name within the (cell,type) pair.
This field is optional, and defaults to an empty.
Assigning different names to this field enables the existence of multiple pools with a specific tablet type in a given cell,
-which can be beneficial for unmanaged tablets.
+which can be beneficial for unmanaged tablets.
+Hence, you must specify ExternalDatastore when assigning a name to this field.
diff --git a/pkg/apis/planetscale/v2/labels.go b/pkg/apis/planetscale/v2/labels.go
index 80b8d28b..71c4421e 100644
--- a/pkg/apis/planetscale/v2/labels.go
+++ b/pkg/apis/planetscale/v2/labels.go
@@ -36,6 +36,7 @@ const (
// TabletTypeLabel is the key for identifying the Vitess target tablet type for a Pod.
TabletTypeLabel = LabelPrefix + "/" + "tablet-type"
// TabletPoolNameLabel is the key for identifying the Vitess target pool name within the (cell,type) pair.
+ // This label is applicable to Vitess-unmanaged keyspaces.
TabletPoolNameLabel = LabelPrefix + "/" + "pool-name"
// TabletIndexLabel is the key for identifying the index of a Vitess tablet within its pool.
TabletIndexLabel = LabelPrefix + "/" + "tablet-index"
diff --git a/pkg/apis/planetscale/v2/vitessshard_types.go b/pkg/apis/planetscale/v2/vitessshard_types.go
index 13af1d7b..e3f0dca8 100644
--- a/pkg/apis/planetscale/v2/vitessshard_types.go
+++ b/pkg/apis/planetscale/v2/vitessshard_types.go
@@ -175,6 +175,7 @@ type VitessShardTabletPool struct {
// This field is optional, and defaults to an empty.
// Assigning different names to this field enables the existence of multiple pools with a specific tablet type in a given cell,
// which can be beneficial for unmanaged tablets.
+ // Hence, you must specify ExternalDatastore when assigning a name to this field.
// +kubebuilder:default=""
Name string `json:"name,omitempty"`
diff --git a/pkg/controller/vitessshard/reconcile_tablets.go b/pkg/controller/vitessshard/reconcile_tablets.go
index e8623436..2722de2c 100644
--- a/pkg/controller/vitessshard/reconcile_tablets.go
+++ b/pkg/controller/vitessshard/reconcile_tablets.go
@@ -285,7 +285,7 @@ func vttabletSpecs(vts *planetscalev2.VitessShard, parentLabels map[string]strin
}
// If TabletPools has multiple pools within the same (cell,type) pair, we need to add a pool name to the UID generator.
- if 0 < len(pool.Name) {
+ if pool.ExternalDatastore != nil && 0 < len(pool.Name) {
tabletAlias.Uid = vttablet.UIDWithPoolName(pool.Cell, keyspaceName, vts.Spec.KeyRange, pool.Type, uint32(tabletIndex), pool.Name)
}
@@ -297,8 +297,10 @@ func vttabletSpecs(vts *planetscalev2.VitessShard, parentLabels map[string]strin
labels[planetscalev2.CellLabel] = tabletAlias.Cell
labels[planetscalev2.TabletUidLabel] = strconv.FormatUint(uint64(tabletAlias.Uid), 10)
labels[planetscalev2.TabletTypeLabel] = string(pool.Type)
- labels[planetscalev2.TabletPoolNameLabel] = pool.Name
labels[planetscalev2.TabletIndexLabel] = strconv.FormatUint(uint64(tabletIndex), 10)
+ if pool.ExternalDatastore != nil {
+ labels[planetscalev2.TabletPoolNameLabel] = pool.Name
+ }
// Merge ExtraVitessFlags into the tablet spec ExtraFlags field.
extraFlags := make(map[string]string)
diff --git a/test/integration/vitesscluster/vitesscluster_test.go b/test/integration/vitesscluster/vitesscluster_test.go
index f508352b..0483efb8 100644
--- a/test/integration/vitesscluster/vitesscluster_test.go
+++ b/test/integration/vitesscluster/vitesscluster_test.go
@@ -66,16 +66,6 @@ spec:
resources:
requests:
storage: 1Gi
- - cell: cell2
- type: rdonly
- name: unmanaged-replica-2
- replicas: 3
- mysqld: {}
- dataVolumeClaimTemplate:
- accessModes: [ReadWriteOnce]
- resources:
- requests:
- storage: 1Gi
- equal:
parts: 1
shardTemplate:
@@ -87,11 +77,28 @@ spec:
type: replica
replicas: 3
mysqld: {}
- dataVolumeClaimTemplate:
- accessModes: [ReadWriteOnce]
- resources:
- requests:
- storage: 1Gi
+ externalDatastore:
+ port: 3306
+ credentialsSecret:
+ name: cluster-config
+ key: db_credentials.json
+ - cell: cell3
+ type: rdonly
+ replicas: 3
+ externalDatastore:
+ port: 3307
+ credentialsSecret:
+ name: cluster-config
+ key: db_credentials.json
+ - cell: cell3
+ type: rdonly
+ replicas: 3
+ name: unmanaged-replica-2
+ externalDatastore:
+ port: 3308
+ credentialsSecret:
+ name: cluster-config
+ key: db_credentials.json
backup:
locations:
- name: vbs1
@@ -191,9 +198,9 @@ func verifyBasicVitessKeyspace(f *framework.Fixture, ns, cluster, keyspace strin
f.MustGet(ns, names.JoinWithConstraints(names.DefaultConstraints, cluster, keyspace), &planetscalev2.VitessKeyspace{})
// VitessKeyspaces create VitessShards.
- verifyBasicVitessShard(f, ns, cluster, keyspace, "x-80", []int{3, 3, 3, 0})
- verifyBasicVitessShard(f, ns, cluster, keyspace, "80-x", []int{3, 3, 3, 0})
- verifyBasicVitessShard(f, ns, cluster, keyspace, "x-x", []int{0, 0, 0, 3})
+ verifyBasicVitessShard(f, ns, cluster, keyspace, "x-80", []int{3, 3})
+ verifyBasicVitessShard(f, ns, cluster, keyspace, "80-x", []int{3, 3})
+ verifyBasicVitessShardExternal(f, ns, cluster, keyspace, "x-x", []int{3, 3, 3})
}
func verifyBasicVitessShard(f *framework.Fixture, ns, cluster, keyspace, shard string, expectedTabletCount []int) {
@@ -202,20 +209,12 @@ func verifyBasicVitessShard(f *framework.Fixture, ns, cluster, keyspace, shard s
// VitessShard creates vttablet Pods.
cell1Pods := f.ExpectPods(&client.ListOptions{
Namespace: ns,
- LabelSelector: tabletPodSelector(cluster, keyspace, shard, "cell1", "replica", ""),
+ LabelSelector: tabletPodSelector(cluster, keyspace, shard, "cell1", "replica"),
}, expectedTabletCount[0])
cell2Pods := f.ExpectPods(&client.ListOptions{
Namespace: ns,
- LabelSelector: tabletPodSelector(cluster, keyspace, shard, "cell2", "rdonly", ""),
+ LabelSelector: tabletPodSelector(cluster, keyspace, shard, "cell2", "rdonly"),
}, expectedTabletCount[1])
- cell2_1_Pods := f.ExpectPods(&client.ListOptions{
- Namespace: ns,
- LabelSelector: tabletPodSelector(cluster, keyspace, shard, "cell2", "rdonly", "unmanaged-replica-2"),
- }, expectedTabletCount[2])
- cell3Pods := f.ExpectPods(&client.ListOptions{
- Namespace: ns,
- LabelSelector: tabletPodSelector(cluster, keyspace, shard, "cell3", "replica", ""),
- }, expectedTabletCount[3])
// Each vttablet Pod should have a PVC.
for i := range cell1Pods.Items {
@@ -224,19 +223,43 @@ func verifyBasicVitessShard(f *framework.Fixture, ns, cluster, keyspace, shard s
for i := range cell2Pods.Items {
f.MustGet(ns, cell2Pods.Items[i].Name, &corev1.PersistentVolumeClaim{})
}
- for i := range cell2_1_Pods.Items {
- f.MustGet(ns, cell2_1_Pods.Items[i].Name, &corev1.PersistentVolumeClaim{})
- }
- for i := range cell3Pods.Items {
- f.MustGet(ns, cell3Pods.Items[i].Name, &corev1.PersistentVolumeClaim{})
- }
// VitessShard creates vtbackup-init Pod/PVC.
f.MustGet(ns, names.JoinWithConstraints(names.DefaultConstraints, cluster, keyspace, shard, "vtbackup", "init"), &corev1.Pod{})
f.MustGet(ns, names.JoinWithConstraints(names.DefaultConstraints, cluster, keyspace, shard, "vtbackup", "init"), &corev1.PersistentVolumeClaim{})
}
-func tabletPodSelector(cluster, keyspace, shard, cell, tabletType, poolName string) apilabels.Selector {
+func verifyBasicVitessShardExternal(f *framework.Fixture, ns, cluster, keyspace, shard string, expectedTabletCount []int) {
+ f.MustGet(ns, names.JoinWithConstraints(names.DefaultConstraints, cluster, keyspace, shard), &planetscalev2.VitessShard{})
+
+ // VitessShard creates vttablet Pods.
+ f.ExpectPods(&client.ListOptions{
+ Namespace: ns,
+ LabelSelector: tabletPodExternalSelector(cluster, keyspace, shard, "cell3", "replica", ""),
+ }, expectedTabletCount[0])
+ f.ExpectPods(&client.ListOptions{
+ Namespace: ns,
+ LabelSelector: tabletPodExternalSelector(cluster, keyspace, shard, "cell3", "rdonly", ""),
+ }, expectedTabletCount[1])
+ f.ExpectPods(&client.ListOptions{
+ Namespace: ns,
+ LabelSelector: tabletPodExternalSelector(cluster, keyspace, shard, "cell3", "rdonly", "unmanaged-replica-2"),
+ }, expectedTabletCount[2])
+}
+
+func tabletPodSelector(cluster, keyspace, shard, cell, tabletType string) apilabels.Selector {
+ // This intentionally does NOT use any shared constants because we want the
+ // test to fail if the labels change, since that's a breaking change.
+ return apilabels.Set{
+ "planetscale.com/cluster": cluster,
+ "planetscale.com/keyspace": keyspace,
+ "planetscale.com/shard": shard,
+ "planetscale.com/cell": cell,
+ "planetscale.com/tablet-type": tabletType,
+ }.AsSelector()
+}
+
+func tabletPodExternalSelector(cluster, keyspace, shard, cell, tabletType, poolName string) apilabels.Selector {
// This intentionally does NOT use any shared constants because we want the
// test to fail if the labels change, since that's a breaking change.
return apilabels.Set{