Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions apis/apps/v1/componentdefinition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,12 @@ type ComponentFileTemplate struct {
// +optional
Namespace string `json:"namespace,omitempty"`

// Indicates whether the template requires rendering at the pod level to incorporate pod-specific variables.
//
// +kubebuilder:default=false
// +optional
RequiresPodRender bool `json:"requiresPodRender,omitempty"`

// Refers to the volume name of PodTemplate. The file produced through the template will be mounted to
// the corresponding volume. Must be a DNS_LABEL name.
// The volume name must be defined in podSpec.containers[*].volumeMounts.
Expand Down
10 changes: 10 additions & 0 deletions config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4329,6 +4329,11 @@ spec:
maxLength: 63
pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$
type: string
requiresPodRender:
default: false
description: Indicates whether the template requires rendering
at the pod level to incorporate pod-specific variables.
type: boolean
template:
description: Specifies the name of the referenced template ConfigMap
object.
Expand Down Expand Up @@ -16057,6 +16062,11 @@ spec:
maxLength: 63
pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$
type: string
requiresPodRender:
default: false
description: Indicates whether the template requires rendering
at the pod level to incorporate pod-specific variables.
type: boolean
template:
description: Specifies the name of the referenced template ConfigMap
object.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ func (t *componentReconfigureTransformer) reconfigureReplicaTemplate(transCtx *c
return nil // disabled by the external
}
}
// TODO: variables, dynamic render
if tpl.Reconfigure != nil {
actionName := component.UDFReconfigureActionName(tpl)
args := lifecycle.FileTemplateChanges(changes.Created, changes.Removed, changes.Updated)
Expand Down
15 changes: 13 additions & 2 deletions controllers/apps/component/transformer_component_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ var _ graph.Transformer = &componentFileTemplateTransformer{}

func (t *componentFileTemplateTransformer) Transform(ctx graph.TransformContext, dag *graph.DAG) error {
transCtx, _ := ctx.(*componentTransformContext)
synthesizedComp := transCtx.SynthesizeComponent
if model.IsObjectDeleting(transCtx.ComponentOrig) {
return nil
}
Expand All @@ -73,7 +74,14 @@ func (t *componentFileTemplateTransformer) Transform(ctx graph.TransformContext,

t.handleTemplateObjectChanges(transCtx, dag, runningObjs, protoObjs, toCreate, toDelete, toUpdate)

return t.buildPodVolumes(transCtx)
if err = t.buildPodVolumes(transCtx); err != nil {
return err
}

synthesizedComp.KBAgentTasks = append(synthesizedComp.KBAgentTasks,
*component.NewRenderTask(synthesizedComp.FullCompName, synthesizedComp.Generation, nil, synthesizedComp, nil))

return nil
}

func (t *componentFileTemplateTransformer) precheck(transCtx *componentTransformContext) error {
Expand Down Expand Up @@ -234,7 +242,10 @@ func renderFileTemplateData(transCtx *componentTransformContext,
variables[k] = v // override
}

tpl := template.New(fileTemplate.Name).Option("missingkey=error").Funcs(sprig.TxtFuncMap())
tpl := template.New(fileTemplate.Name).Funcs(sprig.TxtFuncMap())
if !fileTemplate.RequiresPodRender {
tpl = tpl.Option("missingkey=error")
}
for key, val := range data {
ptpl, err := tpl.Parse(val)
if err != nil {
Expand Down
88 changes: 48 additions & 40 deletions controllers/apps/component/transformer_component_workload.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import (
"github.com/apecloud/kubeblocks/pkg/controller/lifecycle"
"github.com/apecloud/kubeblocks/pkg/controller/model"
intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
"github.com/apecloud/kubeblocks/pkg/kbagent"
)

const (
Expand Down Expand Up @@ -236,6 +237,10 @@ func (t *componentWorkloadTransformer) handleUpdate(reqCtx intctrlutil.RequestCt
if err := t.handleWorkloadUpdate(reqCtx, dag, synthesizedComp, comp, runningITS, protoITS); err != nil {
return err
}

if err := updateEnvCM4KBAgentTask(reqCtx.Ctx, t.Client, dag, synthesizedComp, comp); err != nil {
return err
}
}

objCopy := copyAndMergeITS(runningITS, protoITS)
Expand All @@ -250,9 +255,6 @@ func (t *componentWorkloadTransformer) handleUpdate(reqCtx intctrlutil.RequestCt
})
}

// if start {
// return intctrlutil.NewDelayedRequeueError(time.Second, "workload is starting")
// }
return nil
}

Expand Down Expand Up @@ -411,6 +413,26 @@ func buildPodSpecVolumeMounts(synthesizeComp *component.SynthesizedComponent) {
synthesizeComp.PodSpec = podSpec
}

func updateEnvCM4KBAgentTask(ctx context.Context, cli client.Reader, dag *graph.DAG,
synthesizedComp *component.SynthesizedComponent, comp *appsv1.Component) error {
if len(synthesizedComp.KBAgentTasks) == 0 {
return nil
}
envVar, err := kbagent.BuildEnv4Worker(synthesizedComp.KBAgentTasks)
if err != nil {
return err
}
// apply the updated env to the env CM
transCtx := &componentTransformContext{
Context: ctx,
Client: model.NewGraphClient(cli),
SynthesizeComponent: synthesizedComp,
Component: comp,
}
parameters := map[string]string{envVar.Name: envVar.Value}
return createOrUpdateEnvConfigMap(transCtx, dag, nil, parameters)
}

// copyAndMergeITS merges two ITS objects for updating:
// 1. new an object targetObj by copying from oldObj
// 2. merge all fields can be updated from newObj into targetObj
Expand Down Expand Up @@ -529,32 +551,6 @@ func checkNRollbackProtoImages(itsObj, itsProto *workloads.InstanceSet) {
}
}

// expandVolume handles workload expand volume
func (r *componentWorkloadOps) expandVolume() error {
return r.expandVolumeClaimTemplates(r.runningITS.Spec.VolumeClaimTemplates, r.synthesizeComp.VolumeClaimTemplates)
}

func (r *componentWorkloadOps) expandVolumeClaimTemplates(runningVCTs []corev1.PersistentVolumeClaim, protoVCTs []corev1.PersistentVolumeClaimTemplate) error {
for _, vct := range runningVCTs {
var proto *corev1.PersistentVolumeClaimTemplate
for i, v := range protoVCTs {
if v.Name == vct.Name {
proto = &protoVCTs[i]
break
}
}
// REVIEW: seems we can remove a volume claim from templates at runtime, without any changes and warning messages?
if proto == nil {
continue
}

if err := r.expandVolumes(vct.Name, proto); err != nil {
return err
}
}
return nil
}

func (r *componentWorkloadOps) horizontalScale() error {
var (
in = r.runningItsPodNameSet.Difference(r.desiredCompPodNameSet)
Expand Down Expand Up @@ -731,20 +727,11 @@ func (r *componentWorkloadOps) scaleOut() error {
}

replicas := append(slices.Clone(newReplicas), provisioningReplicas...)
parameters, err := component.NewReplicaTask(r.synthesizeComp.FullCompName, r.synthesizeComp.Generation, source, replicas)
task, err := component.NewReplicaTask(r.synthesizeComp.FullCompName, r.synthesizeComp.Generation, source, replicas)
if err != nil {
return err
}
// apply the updated env to the env CM
transCtx := &componentTransformContext{
Context: r.reqCtx.Ctx,
Client: model.NewGraphClient(r.cli),
SynthesizeComponent: r.synthesizeComp,
Component: r.component,
}
if err = createOrUpdateEnvConfigMap(transCtx, r.dag, nil, parameters); err != nil {
return err
}
r.synthesizeComp.KBAgentTasks = append(r.synthesizeComp.KBAgentTasks, *task)
return nil
}(); err != nil {
return err
Expand Down Expand Up @@ -848,6 +835,27 @@ func (r *componentWorkloadOps) joinMemberForPod(pod *corev1.Pod, pods []*corev1.
return nil
}

func (r *componentWorkloadOps) expandVolume() error {
for _, vct := range r.runningITS.Spec.VolumeClaimTemplates {
var proto *corev1.PersistentVolumeClaimTemplate
for i, v := range r.synthesizeComp.VolumeClaimTemplates {
if v.Name == vct.Name {
proto = &r.synthesizeComp.VolumeClaimTemplates[i]
break
}
}
// REVIEW: seems we can remove a volume claim from templates at runtime, without any changes and warning messages?
if proto == nil {
continue
}

if err := r.expandVolumes(vct.Name, proto); err != nil {
return err
}
}
return nil
}

func (r *componentWorkloadOps) expandVolumes(vctName string, proto *corev1.PersistentVolumeClaimTemplate) error {
for _, pod := range r.runningItsPodNames {
pvc := &corev1.PersistentVolumeClaim{}
Expand Down
10 changes: 10 additions & 0 deletions deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4329,6 +4329,11 @@ spec:
maxLength: 63
pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$
type: string
requiresPodRender:
default: false
description: Indicates whether the template requires rendering
at the pod level to incorporate pod-specific variables.
type: boolean
template:
description: Specifies the name of the referenced template ConfigMap
object.
Expand Down Expand Up @@ -16057,6 +16062,11 @@ spec:
maxLength: 63
pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$
type: string
requiresPodRender:
default: false
description: Indicates whether the template requires rendering
at the pod level to incorporate pod-specific variables.
type: boolean
template:
description: Specifies the name of the referenced template ConfigMap
object.
Expand Down
12 changes: 12 additions & 0 deletions docs/developer_docs/api-reference/cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -5622,6 +5622,18 @@ string
</tr>
<tr>
<td>
<code>requiresPodRender</code><br/>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>Indicates whether the template requires rendering at the pod level to incorporate pod-specific variables.</p>
</td>
</tr>
<tr>
<td>
<code>volumeName</code><br/>
<em>
string
Expand Down
Loading
Loading