diff --git a/internal/controller/builder/builder_pod_test.go b/internal/controller/builder/builder_pod_test.go index be7ecf6dbdc..affee34c34c 100644 --- a/internal/controller/builder/builder_pod_test.go +++ b/internal/controller/builder/builder_pod_test.go @@ -59,6 +59,7 @@ var _ = Describe("pod builder", func() { ctx := corev1.PodSecurityContext{ RunAsUser: &user, } + serviceAccount := "foo-1" tolerations := []corev1.Toleration{ { Key: "node", @@ -73,6 +74,7 @@ var _ = Describe("pod builder", func() { SetRestartPolicy(restartPolicy). SetSecurityContext(ctx). AddTolerations(tolerations...). + SetServiceAccountName(serviceAccount). GetObject() Expect(pod.Name).Should(Equal(name)) @@ -83,6 +85,7 @@ var _ = Describe("pod builder", func() { Expect(pod.Spec.Volumes).Should(HaveLen(1)) Expect(pod.Spec.Volumes[0]).Should(Equal(volumes[0])) Expect(pod.Spec.RestartPolicy).Should(Equal(restartPolicy)) + Expect(pod.Spec.ServiceAccountName).Should(Equal(serviceAccount)) Expect(pod.Spec.SecurityContext).ShouldNot(BeNil()) Expect(*pod.Spec.SecurityContext).Should(Equal(ctx)) Expect(pod.Spec.Tolerations).Should(HaveLen(1)) diff --git a/internal/controller/builder/builder_replicated_state_machine.go b/internal/controller/builder/builder_replicated_state_machine.go index 646d39be295..b652ba46c91 100644 --- a/internal/controller/builder/builder_replicated_state_machine.go +++ b/internal/controller/builder/builder_replicated_state_machine.go @@ -172,7 +172,7 @@ func (builder *ReplicatedStateMachineBuilder) SetCredential(credential workloads return builder } -func (builder *ReplicatedStateMachineBuilder) SetDebugMode(debugmode *bool) *ReplicatedStateMachineBuilder { - builder.get().Spec.DebugMode = debugmode +func (builder *ReplicatedStateMachineBuilder) SetDebugMode(debugMode *bool) *ReplicatedStateMachineBuilder { + builder.get().Spec.DebugMode = debugMode return builder } diff --git a/internal/controller/builder/builder_replicated_state_machine_test.go b/internal/controller/builder/builder_replicated_state_machine_test.go index fcdb803d9ef..c66b22c95c8 100644 --- a/internal/controller/builder/builder_replicated_state_machine_test.go +++ b/internal/controller/builder/builder_replicated_state_machine_test.go @@ -158,6 +158,7 @@ var _ = Describe("replicated_state_machine builder", func() { Username: workloads.CredentialVar{Value: "foo"}, Password: workloads.CredentialVar{Value: "bar"}, } + debugModeOn := true rsm := NewReplicatedStateMachineBuilder(ns, name). SetReplicas(replicas). AddMatchLabel(selectorKey1, selectorValue1). @@ -179,6 +180,7 @@ var _ = Describe("replicated_state_machine builder", func() { SetService(service). SetAlternativeServices(alternativeServices). SetCredential(credential). + SetDebugMode(&debugModeOn). GetObject() Expect(rsm.Name).Should(Equal(name)) @@ -197,6 +199,7 @@ var _ = Describe("replicated_state_machine builder", func() { Expect(rsm.Spec.MembershipReconfiguration).ShouldNot(BeNil()) Expect(*rsm.Spec.MembershipReconfiguration).Should(Equal(reconfiguration)) Expect(rsm.Spec.Template).Should(Equal(template)) + Expect(rsm.Spec.DebugMode).Should(Equal(&debugModeOn)) Expect(rsm.Spec.VolumeClaimTemplates).Should(HaveLen(2)) Expect(rsm.Spec.VolumeClaimTemplates[0]).Should(Equal(vcs[0])) Expect(rsm.Spec.VolumeClaimTemplates[1]).Should(Equal(vc)) diff --git a/internal/controller/factory/builder.go b/internal/controller/factory/builder.go index 238cde3a411..82dc08b9a4e 100644 --- a/internal/controller/factory/builder.go +++ b/internal/controller/factory/builder.go @@ -332,6 +332,7 @@ func BuildRSM(reqCtx intctrlutil.RequestCtx, cluster *appsv1alpha1.Cluster, SetServiceName(rsmName + "-headless"). SetReplicas(component.Replicas). SetTemplate(template) + var vcts []corev1.PersistentVolumeClaim for _, vct := range component.VolumeClaimTemplates { vcts = append(vcts, vctToPVC(vct)) diff --git a/internal/controller/model/transform_utils.go b/internal/controller/model/transform_utils.go index 261fe10384e..917fe51e628 100644 --- a/internal/controller/model/transform_utils.go +++ b/internal/controller/model/transform_utils.go @@ -21,10 +21,10 @@ package model import ( "fmt" - corev1 "k8s.io/api/core/v1" //nolint:goimports "reflect" "time" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -193,8 +193,11 @@ func ReadCacheSnapshot(transCtx graph.TransformContext, root client.Object, ml c } func AddDebugPodSnapshot(snapshot ObjectSnapshot, ctx graph.TransformContext) ObjectSnapshot { + if len(snapshot) == 0 { + return snapshot + } var a corev1.Pod - err := ctx.GetClient().Get(ctx.GetContext(), client.ObjectKey{Name: "debug.pod", Namespace: "default"}, &a) //nolint:errcheck + err := ctx.GetClient().Get(ctx.GetContext(), client.ObjectKey{Name: "debug.pod", Namespace: "default"}, &a) if err != nil { return nil } diff --git a/internal/controller/rsm/transformer_object_generation.go b/internal/controller/rsm/transformer_object_generation.go index 5b59a70e983..3c5b6b07c9d 100644 --- a/internal/controller/rsm/transformer_object_generation.go +++ b/internal/controller/rsm/transformer_object_generation.go @@ -21,10 +21,14 @@ package rsm import ( "encoding/json" - "fmt" //nolint:goimports + "fmt" + "reflect" + "strconv" + "strings" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/internal/constant" - "github.com/apecloud/kubeblocks/internal/controller/builder" //nolint:typecheck + "github.com/apecloud/kubeblocks/internal/controller/builder" "github.com/apecloud/kubeblocks/internal/controller/graph" "github.com/apecloud/kubeblocks/internal/controller/model" viper "github.com/apecloud/kubeblocks/internal/viperx" @@ -34,10 +38,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/sets" - "reflect" //nolint:goimports "sigs.k8s.io/controller-runtime/pkg/client" - "strconv" //nolint:goimports - "strings" //nolint:goimports ) type ObjectGenerationTransformer struct{} @@ -53,6 +54,7 @@ func (t *ObjectGenerationTransformer) Transform(ctx graph.TransformContext, dag if model.IsObjectDeleting(rsmOrig) { return nil } + // generate objects by current spec svc := buildSvc(*rsm) altSvs := buildAlternativeSvs(*rsm) @@ -60,8 +62,9 @@ func (t *ObjectGenerationTransformer) Transform(ctx graph.TransformContext, dag envConfig := buildEnvConfigMap(*rsm) sts := buildSts(*rsm, headLessSvc.Name, *envConfig) objects := []client.Object{headLessSvc, envConfig, sts} - if *rsm.Spec.DebugMode { - debugPod := buildDebugPod(*rsm, *envConfig, sts) + + if rsm.Spec.DebugMode != nil && *rsm.Spec.DebugMode { + debugPod := buildDebugPod(*rsm, sts) objects = append(objects, debugPod) } if svc != nil { @@ -82,9 +85,6 @@ func (t *ObjectGenerationTransformer) Transform(ctx graph.TransformContext, dag if err != nil { return err } - if *rsm.Spec.DebugMode { - oldSnapshot = model.AddDebugPodSnapshot(oldSnapshot, ctx) - } // compute create/update/delete set newSnapshot := make(map[model.GVKNObjKey]client.Object) @@ -312,65 +312,59 @@ func buildEnvConfigMap(rsm workloads.ReplicatedStateMachine) *corev1.ConfigMap { GetObject() } -func buildDebugPod(rsm workloads.ReplicatedStateMachine, envConfig corev1.ConfigMap, sts *apps.StatefulSet) *corev1.Pod { - stsName, serviceAccountName := sts.Name, sts.Spec.Template.Spec.ServiceAccountName - spec := buildDebugPodTemplate(rsm, envConfig, stsName).Spec +func buildDebugPod(rsm workloads.ReplicatedStateMachine, sts *apps.StatefulSet) *corev1.Pod { + stsName := sts.Name + spec := buildDebugPodTemplate(rsm, stsName).Spec container := spec.Containers[0] labels := sts.Spec.Template.Labels - annotations := ParseAnnotationsOfScope(DebugPodScope, rsm.Annotations) for key, value := range rsm.Spec.Selector.MatchLabels { labels[key] = value } container.Command = []string{ - "sleep", - "infinity", + "/bin/sh", + "-c", + "tail -f /dev/null", } - return builder.NewPodBuilder(rsm.Namespace, "debug.pod"). + + return builder.NewPodBuilder(rsm.Namespace, debugPodName). AddContainer(container). - AddAnnotationsInMap(annotations). - AddVolumes(spec.Volumes[0]). - SetServiceAccountName(serviceAccountName). AddLabelsInMap(labels). GetObject() } -func buildDebugPodTemplate(rsm workloads.ReplicatedStateMachine, envConfig corev1.ConfigMap, stsName string) *corev1.PodTemplateSpec { - template := rsm.Spec.Template - // inject env ConfigMap into workload pods only - for i := range template.Spec.Containers { - if i == 0 { - zeroPodName := stsName + "-0" - svcName := getHeadlessSvcName(rsm) - svcPort := findSvcPort(rsm) - host := fmt.Sprintf("%s.%s", zeroPodName, svcName) - template.Spec.Containers[i].Env = []corev1.EnvVar{ - { - Name: leaderHostVarName, - Value: host, - }, - { - Name: servicePortVarName, - Value: strconv.Itoa(svcPort), - }, - { - Name: targetHostVarName, - Value: host, - }, - } - - template.Spec.Containers[i].EnvFrom = append(template.Spec.Containers[i].EnvFrom, - corev1.EnvFromSource{ - ConfigMapRef: &corev1.ConfigMapEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: envConfig.Name, - }, - Optional: func() *bool { optional := false; return &optional }(), - }}) - continue - } +func buildDebugPodTemplate(rsm workloads.ReplicatedStateMachine, stsName string) *corev1.PodTemplateSpec { + zeroPodName := stsName + "-0" + env := buildActionEnv(&rsm, zeroPodName, zeroPodName) + credential := rsm.Spec.Credential + credentialEnv := make([]corev1.EnvVar, 0) + if credential != nil { + credentialEnv = append(credentialEnv, + corev1.EnvVar{ + Name: usernameCredentialVarName, + Value: credential.Username.Value, + ValueFrom: credential.Username.ValueFrom, + }, + corev1.EnvVar{ + Name: passwordCredentialVarName, + Value: credential.Password.Value, + ValueFrom: credential.Password.ValueFrom, + }) } - - return &template + env = append(env, credentialEnv...) + image := rsm.Spec.Template.Spec.Containers[0].Image + container := corev1.Container{ + Name: rsm.Spec.Template.Spec.Containers[0].Name, + Image: image, + ImagePullPolicy: corev1.PullIfNotPresent, + Env: env, + } + template := &corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{container}, + RestartPolicy: corev1.RestartPolicyNever, + }, + } + return template } func buildStsPodTemplate(rsm workloads.ReplicatedStateMachine, envConfig corev1.ConfigMap) *corev1.PodTemplateSpec { diff --git a/internal/controller/rsm/transformer_objection_generation_test.go b/internal/controller/rsm/transformer_objection_generation_test.go index 0f65d6f9f4d..ebb3869e897 100644 --- a/internal/controller/rsm/transformer_objection_generation_test.go +++ b/internal/controller/rsm/transformer_objection_generation_test.go @@ -146,6 +146,15 @@ var _ = Describe("object generation transformer test.", func() { }) }) + Context("buildDebugPod function", func() { + It("should work well", func() { + sts := mockUnderlyingSts(*rsm, 90) + debugPod := buildDebugPod(*rsm, sts) + Expect(debugPod).ShouldNot(BeNil()) + Expect(debugPod.Spec.Containers[0].Name).Should(Equal(rsm.Spec.Template.Spec.Containers[0].Name)) + }) + }) + Context("well-known service labels", func() { It("should work well", func() { svc := buildSvc(*rsm) @@ -157,4 +166,5 @@ var _ = Describe("object generation transformer test.", func() { } }) }) + }) diff --git a/internal/controller/rsm/types.go b/internal/controller/rsm/types.go index a3024688132..e5af4f7ebc5 100644 --- a/internal/controller/rsm/types.go +++ b/internal/controller/rsm/types.go @@ -53,6 +53,7 @@ const ( rsmGenerationLabelKey = "rsm.workloads.kubeblocks.io/controller-generation" defaultPodName = "Unknown" + debugPodName = "debug.pod" rsmFinalizerName = "rsm.workloads.kubeblocks.io/finalizer"