Skip to content
Closed
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
3 changes: 2 additions & 1 deletion apis/apps/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ type TLSSecretRef struct {
// InstanceTemplate allows customization of individual replica configurations in a Component.
type InstanceTemplate struct {
// Name specifies the unique name of the instance Pod created using this InstanceTemplate.
// This name is constructed by concatenating the Component's name, the template's name, and the instance's ordinal
// This name is constructed by concatenating the Component's name, the template's name, and the instance's ordinal. The name can't be empty.
// using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0.
// The specified name overrides any default naming conventions or patterns.
//
Expand All @@ -768,6 +768,7 @@ type InstanceTemplate struct {

// Specifies the desired Ordinals of this InstanceTemplate.
// The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate.
// If Ordinals are defined, their number must match the corresponding replicas.
//
// For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]},
// then the instance names generated under this InstanceTemplate would be
Expand Down
10 changes: 10 additions & 0 deletions apis/workloads/v1/instanceset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ type InstanceSetSpec struct {

// Specifies the desired Ordinals of the default template.
// The Ordinals used to specify the ordinal of the instance (pod) names to be generated under the default template.
// If Ordinals are defined, their number must match the corresponding replicas.
//
// For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]},
// then the instance names generated under the default template would be
Expand Down Expand Up @@ -266,6 +267,9 @@ type InstanceSetStatus struct {
// [replicas-updatedReplicas,replicas)
UpdateRevision string `json:"updateRevision,omitempty"`

// FIXME: unify with InstanceStatus?
CurrentInstances CurrentInstances `json:"currentInstances,omitempty"`

// Represents the latest available observations of an instanceset's current state.
// Known .status.conditions.type are: "InstanceFailure", "InstanceReady"
//
Expand Down Expand Up @@ -433,6 +437,12 @@ type InstanceConfigStatus struct {
Generation int64 `json:"generation"`
}

// CurrentInstances maps templates to current pods
// key is template name (default template has empty name), value is a list of pod ordinals
// store ordinals only to save some space.
// the list is always sorted by ordinal
type CurrentInstances map[string][]int32

// InstanceTemplateStatus aggregates the status of replicas for each InstanceTemplate
type InstanceTemplateStatus struct {
// Name, the name of the InstanceTemplate.
Expand Down
21 changes: 10 additions & 11 deletions pkg/controller/instanceset/in_place_update_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (

workloads "github.com/apecloud/kubeblocks/apis/workloads/v1"
"github.com/apecloud/kubeblocks/pkg/constant"
"github.com/apecloud/kubeblocks/pkg/controller/instanceset/instancetemplate"
intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
viper "github.com/apecloud/kubeblocks/pkg/viperx"
)
Expand Down Expand Up @@ -294,23 +295,21 @@ func getPodUpdatePolicy(its *workloads.InstanceSet, pod *corev1.Pod) (PodUpdateP
return RecreatePolicy, nil
}

itsExt, err := buildInstanceSetExt(its, nil)
// FIXME: compressed templates
itsExt, err := instancetemplate.BuildInstanceSetExt(its, nil)
if err != nil {
return NoOpsPolicy, err
}
templateList := buildInstanceTemplateExts(itsExt)
parentName, _ := ParseParentNameAndOrdinal(pod.Name)
templateName, _ := strings.CutPrefix(parentName, its.Name)
if len(templateName) > 0 {
templateName, _ = strings.CutPrefix(templateName, "-")
instance2TemplateMap, err := instancetemplate.BuildInstanceName2TemplateMap(itsExt)
if err != nil {
return NoOpsPolicy, err
}
index := slices.IndexFunc(templateList, func(templateExt *instanceTemplateExt) bool {
return templateName == templateExt.Name
})
if index < 0 {
template, ok := instance2TemplateMap[pod.Name]
if !ok {
return NoOpsPolicy, fmt.Errorf("no corresponding template found for instance %s", pod.Name)
}
inst, err := buildInstanceByTemplate(pod.Name, templateList[index], its, getPodRevision(pod))

inst, err := buildInstanceByTemplate(pod.Name, template, its, getPodRevision(pod))
if err != nil {
return NoOpsPolicy, err
}
Expand Down
64 changes: 6 additions & 58 deletions pkg/controller/instanceset/instance_template_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,80 +20,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package instanceset

import (
corev1 "k8s.io/api/core/v1"

workloads "github.com/apecloud/kubeblocks/apis/workloads/v1"
"github.com/apecloud/kubeblocks/pkg/controller/instanceset/instancetemplate"
)

// TODO: remove these after extract the Schema of the API types from Kubeblocks into a separate Go package.

// InstanceSetExt serves as a Public Struct,
// used as the type for the input parameters of BuildInstanceTemplateExts.
type InstanceSetExt struct {
Its *workloads.InstanceSet
InstanceTemplates []*workloads.InstanceTemplate
}
type InstanceSetExt = instancetemplate.InstanceSetExt

// InstanceTemplateExt serves as a Public Struct,
// used as the type for the construction results returned by BuildInstanceTemplateExts.
type InstanceTemplateExt struct {
Name string
Replicas int32
corev1.PodTemplateSpec
VolumeClaimTemplates []corev1.PersistentVolumeClaim
}
type InstanceTemplateExt = instancetemplate.InstanceTemplateExt

// BuildInstanceName2TemplateMap serves as a Public API, through which users can obtain InstanceName2TemplateMap objects
// processed by the buildInstanceName2TemplateMap function.
func BuildInstanceName2TemplateMap(itsExt *InstanceSetExt) (map[string]*instanceTemplateExt, error) {
instanceTemplateList := buildInstanceTemplateExts(&instanceSetExt{
its: itsExt.Its,
instanceTemplates: itsExt.InstanceTemplates,
})
allNameTemplateMap := make(map[string]*instanceTemplateExt)
var instanceNameList []string
for _, template := range instanceTemplateList {
ordinalList, err := GetOrdinalListByTemplateName(itsExt.Its, template.Name)
if err != nil {
return nil, err
}
instanceNames, err := GenerateInstanceNamesFromTemplate(itsExt.Its.Name, template.Name, template.Replicas, itsExt.Its.Spec.OfflineInstances, ordinalList)
if err != nil {
return nil, err
}
instanceNameList = append(instanceNameList, instanceNames...)
for _, name := range instanceNames {
allNameTemplateMap[name] = template
}
}
// validate duplicate pod names
getNameFunc := func(n string) string {
return n
}
if err := ValidateDupInstanceNames(instanceNameList, getNameFunc); err != nil {
return nil, err
}

return allNameTemplateMap, nil
}
var BuildInstanceName2TemplateMap = instancetemplate.BuildInstanceName2TemplateMap

// BuildInstanceTemplateExts serves as a Public API, through which users can obtain InstanceTemplateExt objects
// processed by the buildInstanceTemplateExts function.
// Its main purpose is to acquire the PodTemplate rendered by InstanceTemplate.
func BuildInstanceTemplateExts(itsExt *InstanceSetExt) []*InstanceTemplateExt {
itsExts := buildInstanceTemplateExts(&instanceSetExt{
its: itsExt.Its,
instanceTemplates: itsExt.InstanceTemplates,
})
var instanceTemplateExts []*InstanceTemplateExt
for _, itsExt := range itsExts {
instanceTemplateExts = append(instanceTemplateExts, (*InstanceTemplateExt)(itsExt))
}
return instanceTemplateExts
}
var BuildInstanceTemplateExts = instancetemplate.BuildInstanceTemplateExts

// BuildInstanceTemplates serves as a Public API, allowing users to construct InstanceTemplates.
// The constructed InstanceTemplates can be used as part of the input for BuildInstanceTemplateExts.
func BuildInstanceTemplates(totalReplicas int32, instances []workloads.InstanceTemplate, instancesCompressed *corev1.ConfigMap) []*workloads.InstanceTemplate {
return buildInstanceTemplates(totalReplicas, instances, instancesCompressed)
}
var BuildInstanceTemplates = instancetemplate.BuildInstanceTemplates
Loading
Loading