Skip to content

Commit

Permalink
feat: support KB_POD_LIST env
Browse files Browse the repository at this point in the history
  • Loading branch information
free6om committed Apr 24, 2024
1 parent 8194d22 commit a7e02cd
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 38 deletions.
8 changes: 8 additions & 0 deletions apis/apps/v1alpha1/cluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1538,6 +1538,14 @@ func (r *ClusterComponentSpec) ToVolumeClaimTemplates() []corev1.PersistentVolum
return ts
}

func (t *InstanceTemplate) GetName() string {
return t.Name
}

func (t *InstanceTemplate) GetReplicas() *int32 {
return t.Replicas
}

// GetClusterUpRunningPhases returns Cluster running or partially running phases.
func GetClusterUpRunningPhases() []ClusterPhase {
return []ClusterPhase{
Expand Down
8 changes: 8 additions & 0 deletions apis/workloads/v1alpha1/instanceset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,14 @@ type MemberStatus struct {
ReadyWithoutPrimary bool `json:"readyWithoutPrimary"`
}

func (t *InstanceTemplate) GetName() string {
return t.Name
}

func (t *InstanceTemplate) GetReplicas() *int32 {
return t.Replicas
}

func init() {
SchemeBuilder.Register(&InstanceSet{}, &InstanceSetList{})
}
22 changes: 4 additions & 18 deletions controllers/apps/transformer_component_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import (
"github.com/apecloud/kubeblocks/pkg/controller/graph"
"github.com/apecloud/kubeblocks/pkg/controller/instanceset"
"github.com/apecloud/kubeblocks/pkg/controller/model"
intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
)

var (
Expand Down Expand Up @@ -210,23 +209,10 @@ func (t *componentServiceTransformer) skipDefaultHeadlessSvc(synthesizeComp *com
}

func generatePodNames(synthesizeComp *component.SynthesizedComponent) []string {

templateReplicasCnt := int32(0)
for _, template := range synthesizeComp.Instances {
if len(template.Name) > 0 {
templateReplicasCnt += intctrlutil.TemplateReplicas(template)
}
}

podNames := make([]string, 0)
workloadName := constant.GenerateWorkloadNamePattern(synthesizeComp.ClusterName, synthesizeComp.Name)
for _, template := range synthesizeComp.Instances {
templateNames := instanceset.GenerateInstanceNamesFromTemplate(workloadName, template.Name, intctrlutil.TemplateReplicas(template), synthesizeComp.OfflineInstances)
podNames = append(podNames, templateNames...)
}
if templateReplicasCnt < synthesizeComp.Replicas {
names := instanceset.GenerateInstanceNamesFromTemplate(workloadName, "", synthesizeComp.Replicas-templateReplicasCnt, synthesizeComp.OfflineInstances)
podNames = append(podNames, names...)
var templates []instanceset.InstanceTemplate
for i := range synthesizeComp.Instances {
templates = append(templates, &synthesizeComp.Instances[i])
}
return podNames
return instanceset.GenerateAllInstanceNames(workloadName, synthesizeComp.Replicas, templates, synthesizeComp.OfflineInstances)
}
33 changes: 32 additions & 1 deletion pkg/controller/instanceset/instance_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ import (
"github.com/apecloud/kubeblocks/pkg/controller/model"
)

type InstanceTemplate interface {
GetName() string
GetReplicas() *int32
}

type instanceTemplateExt struct {
Name string
Replicas int32
Expand Down Expand Up @@ -125,7 +130,7 @@ func baseSort(x any, getNameNOrdinalFunc func(i int) (string, int), getRolePrior
name1, ordinal1 := getNameNOrdinalFunc(i)
name2, ordinal2 := getNameNOrdinalFunc(j)
if name1 != name2 {
return name1 < name2
return name1 > name2
}
return ordinal1 > ordinal2
})
Expand Down Expand Up @@ -210,6 +215,32 @@ func buildInstanceName2TemplateMap(itsExt *instanceSetExt) (map[string]*instance
return allNameTemplateMap, nil
}

func GenerateAllInstanceNames(parentName string, replicas int32, templates []InstanceTemplate, offlineInstances []string) []string {
templateReplicas := func(template InstanceTemplate) int32 {
if template.GetReplicas() != nil {
return *template.GetReplicas()
}
return 1
}
totalReplicas := int32(0)
instanceNameList := make([]string, 0)
for _, template := range templates {
replicas := templateReplicas(template)
names := GenerateInstanceNamesFromTemplate(parentName, template.GetName(), replicas, offlineInstances)
instanceNameList = append(instanceNameList, names...)
totalReplicas += replicas
}
if totalReplicas < replicas {
names := GenerateInstanceNamesFromTemplate(parentName, "", replicas-totalReplicas, offlineInstances)
instanceNameList = append(instanceNameList, names...)
}
getNameNOrdinalFunc := func(i int) (string, int) {
return ParseParentNameAndOrdinal(instanceNameList[i])
}
baseSort(instanceNameList, getNameNOrdinalFunc, nil, true)
return instanceNameList
}

func GenerateInstanceNamesFromTemplate(parentName, templateName string, replicas int32, offlineInstances []string) []string {
instanceNames, _ := GenerateInstanceNames(parentName, templateName, replicas, 0, offlineInstances)
return instanceNames
Expand Down
26 changes: 24 additions & 2 deletions pkg/controller/instanceset/instance_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/utils/pointer"
"sigs.k8s.io/controller-runtime/pkg/client"

workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1"
Expand Down Expand Up @@ -61,7 +62,7 @@ var _ = Describe("instance util test", func() {
builder.NewPodBuilder(namespace, "pod-10").AddLabels(RoleLabelKey, "learner").GetObject(),
builder.NewPodBuilder(namespace, "foo-20").AddLabels(RoleLabelKey, "learner").GetObject(),
}
expectedOrder := []string{"pod-4", "pod-2", "foo-20", "pod-10", "pod-6", "pod-3", "pod-1", "pod-0", "pod-5"}
expectedOrder := []string{"pod-4", "pod-2", "pod-10", "pod-6", "pod-3", "foo-20", "pod-1", "pod-0", "pod-5"}

sortObjects(pods, priorityMap, false)
for i, pod := range pods {
Expand Down Expand Up @@ -413,7 +414,28 @@ var _ = Describe("instance util test", func() {
return ParseParentNameAndOrdinal(instanceNameList[i])
}
baseSort(instanceNameList, getNameNOrdinalFunc, nil, true)
podNamesExpected := []string{"foo-bar-0", "foo-bar-2", "foo-1", "foo-2"}
podNamesExpected := []string{"foo-1", "foo-2", "foo-bar-0", "foo-bar-2"}
Expect(instanceNameList).Should(Equal(podNamesExpected))
})
})

Context("GenerateAllInstanceNames", func() {
It("should work well", func() {
parentName := "foo"
templatesFoo := &workloads.InstanceTemplate{
Name: "foo",
Replicas: pointer.Int32(1),
}
templateBar := &workloads.InstanceTemplate{
Name: "bar",
Replicas: pointer.Int32(2),
}
var templates []InstanceTemplate
templates = append(templates, templatesFoo, templateBar)
offlineInstances := []string{"foo-bar-1", "foo-0"}
instanceNameList := GenerateAllInstanceNames(parentName, 5, templates, offlineInstances)

podNamesExpected := []string{"foo-1", "foo-2", "foo-bar-0", "foo-bar-2", "foo-foo-0"}
Expect(instanceNameList).Should(Equal(podNamesExpected))
})
})
Expand Down
11 changes: 11 additions & 0 deletions pkg/controller/instanceset/object_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,14 @@ func buildEnvConfigData(its workloads.InstanceSet) map[string]string {
envData[prefix+"FOLLOWERS"] = followers
}
}
// generate all pod names
generatePodNames := func() []string {
var instances []InstanceTemplate
for i := range its.Spec.Instances {
instances = append(instances, &its.Spec.Instances[i])
}
return GenerateAllInstanceNames(its.Name, *its.Spec.Replicas, instances, its.Spec.OfflineInstances)
}

prefix := constant.KBPrefix + "_ITS_"
envData[prefix+"N"] = strReplicas
Expand All @@ -546,6 +554,9 @@ func buildEnvConfigData(its workloads.InstanceSet) map[string]string {
envData[prefix+"REPLICA_COUNT"] = strReplicas
generateReplicaEnv(prefix)
generateMemberEnv(prefix)
// KB_POD_LIST
names := generatePodNames()
envData[prefix+"POD_LIST"] = strings.Join(names, ",")

// have backward compatible handling for CM key with 'compDefName' being part of the key name, prior 0.5.0
// and introduce env/cm key naming reference complexity
Expand Down
14 changes: 7 additions & 7 deletions pkg/controller/instanceset/reconciler_instance_alignment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ var _ = Describe("replicas alignment reconciler test", func() {
Expect(reconciler.PreCondition(tree)).Should(Equal(kubebuilderx.ResultSatisfied))

By("prepare current tree")
// desired: bar-hello-0, bar-foo-0, bar-foo-1, bar-0, bar-1, bar-2, bar-3
// current: bar-foo-0, bar-1
// desired: bar-0, bar-1, bar-2, bar-3, bar-foo-0, bar-foo-1, bar-hello-0
// current: bar-1, bar-foo-0
replicas := int32(7)
its.Spec.Replicas = &replicas
nameHello := "hello"
Expand Down Expand Up @@ -84,7 +84,7 @@ var _ = Describe("replicas alignment reconciler test", func() {
Expect(err).Should(BeNil())
newTree, err := reconciler.Reconcile(orderedReadyTree)
Expect(err).Should(BeNil())
// desired: bar-hello-0, bar-foo-0, bar-1
// desired: bar-0, bar-1, bar-foo-0
pods := newTree.List(&corev1.Pod{})
Expect(pods).Should(HaveLen(3))
currentPodSnapshot := make(model.ObjectSnapshot)
Expand All @@ -93,8 +93,8 @@ var _ = Describe("replicas alignment reconciler test", func() {
Expect(err).Should(BeNil())
currentPodSnapshot[*name] = object
}
podHelloBar0 := builder.NewPodBuilder(namespace, "bar-hello-0").GetObject()
for _, object := range []client.Object{podFoo0, podHelloBar0, podBar1} {
podBar0 := builder.NewPodBuilder(namespace, "bar-0").GetObject()
for _, object := range []client.Object{podFoo0, podBar0, podBar1} {
name, err := model.GetGVKName(object)
Expect(err).Should(BeNil())
_, ok := currentPodSnapshot[*name]
Expand All @@ -109,7 +109,7 @@ var _ = Describe("replicas alignment reconciler test", func() {
parallelITS.Spec.PodManagementPolicy = appsv1.ParallelPodManagement
newTree, err = reconciler.Reconcile(parallelTree)
Expect(err).Should(BeNil())
// desired: bar-hello-0, bar-foo-0, bar-foo-1, bar-0, bar-1, bar-2, bar-3
// desired: bar-0, bar-1, bar-2, bar-3, bar-foo-0, bar-foo-1, bar-hello-0
pods = newTree.List(&corev1.Pod{})
Expect(pods).Should(HaveLen(7))
currentPodSnapshot = make(model.ObjectSnapshot)
Expand All @@ -123,7 +123,7 @@ var _ = Describe("replicas alignment reconciler test", func() {
podFoo1 := builder.NewPodBuilder(namespace, its.Name+"-foo-1").GetObject()
podBar2 := builder.NewPodBuilder(namespace, "bar-2").GetObject()
podBar3 := builder.NewPodBuilder(namespace, "bar-3").GetObject()
for _, object := range []client.Object{podHello, podFoo0, podFoo1, podHelloBar0, podBar1, podBar2, podBar3} {
for _, object := range []client.Object{podHello, podFoo0, podFoo1, podBar0, podBar1, podBar2, podBar3} {
name, err := model.GetGVKName(object)
Expect(err).Should(BeNil())
_, ok := currentPodSnapshot[*name]
Expand Down
20 changes: 10 additions & 10 deletions pkg/controller/instanceset/reconciler_update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ var _ = Describe("update reconciler test", func() {
Expect(reconciler.PreCondition(tree)).Should(Equal(kubebuilderx.ResultSatisfied))

By("prepare current tree")
// desired: bar-3, bar-2, bar-1, bar-0, bar-foo-1, bar-foo-0, bar-hello-0
// desired: bar-hello-0, bar-foo-1, bar-foo-0, bar-3, bar-2, bar-1, bar-0
replicas := int32(7)
its.Spec.Replicas = &replicas
its.Spec.PodManagementPolicy = appsv1.ParallelPodManagement
Expand Down Expand Up @@ -137,13 +137,13 @@ var _ = Describe("update reconciler test", func() {
reconciler = NewUpdateReconciler()

By("reconcile with default UpdateStrategy(RollingUpdate, no partition, MaxUnavailable=1)")
// order: bar-3, bar-2, bar-1, bar-0, bar-foo-1, bar-foo-0, bar-hello-0
// expected: bar-3 being deleted
// order: bar-hello-0, bar-foo-1, bar-foo-0, bar-3, bar-2, bar-1, bar-0
// expected: bar-hello-0 being deleted
defaultTree, err := newTree.DeepCopy()
Expect(err).Should(BeNil())
_, err = reconciler.Reconcile(defaultTree)
Expect(err).Should(BeNil())
expectUpdatedPods(defaultTree, []string{"bar-3"})
expectUpdatedPods(defaultTree, []string{"bar-hello-0"})

By("reconcile with Partition=50% and MaxUnavailable=2")
partitionTree, err := newTree.DeepCopy()
Expand All @@ -158,13 +158,13 @@ var _ = Describe("update reconciler test", func() {
MaxUnavailable: &maxUnavailable,
},
}
// order: bar-3, bar-2, bar-1, bar-0, bar-foo-1, bar-foo-0, bar-hello-0
// expected: bar-0, bar-1 being deleted
// order: bar-hello-0, bar-foo-1, bar-foo-0, bar-3, bar-2, bar-1, bar-0
// expected: bar-hello-0, bar-foo-1 being deleted
_, err = reconciler.Reconcile(partitionTree)
Expect(err).Should(BeNil())
expectUpdatedPods(partitionTree, []string{"bar-3", "bar-2"})
expectUpdatedPods(partitionTree, []string{"bar-hello-0", "bar-foo-1"})

By("update 'bar-0' revision to the updated value")
By("update revisions to the updated value")
partitionTree, err = newTree.DeepCopy()
Expect(err).Should(BeNil())
root, ok = partitionTree.GetRoot().(*workloads.InstanceSet)
Expand All @@ -175,7 +175,7 @@ var _ = Describe("update reconciler test", func() {
MaxUnavailable: &maxUnavailable,
},
}
for _, name := range []string{"bar-3", "bar-2"} {
for _, name := range []string{"bar-hello-0", "bar-foo-1"} {
pod := builder.NewPodBuilder(namespace, name).GetObject()
object, err := partitionTree.Get(pod)
Expect(err).Should(BeNil())
Expand All @@ -185,7 +185,7 @@ var _ = Describe("update reconciler test", func() {
}
_, err = reconciler.Reconcile(partitionTree)
Expect(err).Should(BeNil())
expectUpdatedPods(partitionTree, []string{"bar-1"})
expectUpdatedPods(partitionTree, []string{"bar-foo-0"})

By("reconcile with UpdateStrategy='OnDelete'")
onDeleteTree, err := newTree.DeepCopy()
Expand Down

0 comments on commit a7e02cd

Please sign in to comment.