mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
* perf: MakeDefaultConfig once
This shaves of another 2 seconds (62%) of the remaining execution
time for a kustomization tree with 4000 documents, reducing the execution
time from 4.79s to 1.82s
0 0% 1.38% 2.98s 37.25% sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig.MakeDefaultConfig
before:
(pprof) top30 -cum
Showing nodes accounting for 1.82s, 22.75% of 8s total
Dropped 408 nodes (cum <= 0.04s)
Showing top 30 nodes out of 308
flat flat% sum% cum cum%
0 0% 0% 4.79s 59.88% github.com/spf13/cobra.(*Command).Execute
0 0% 0% 4.79s 59.88% github.com/spf13/cobra.(*Command).ExecuteC
0 0% 0% 4.79s 59.88% github.com/spf13/cobra.(*Command).execute
0 0% 0% 4.79s 59.88% main.main
0 0% 0% 4.79s 59.88% runtime.main
0 0% 0% 4.79s 59.88% sigs.k8s.io/kustomize/kustomize/v5/commands/build.NewCmdBuild.func1
0 0% 0% 4.22s 52.75% sigs.k8s.io/kustomize/api/krusty.(*Kustomizer).Run
0 0% 0% 4.18s 52.25% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).MakeCustomizedResMap (inline)
0 0% 0% 4.18s 52.25% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).makeCustomizedResMap
0 0% 0% 4.06s 50.75% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).AccumulateTarget
0 0% 0% 4.06s 50.75% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).accumulateResources
0 0% 0% 4.06s 50.75% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).accumulateTarget
0 0% 0% 4.05s 50.62% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).accumulateDirectory
0 0% 0% 3.22s 40.25% runtime.systemstack
0 0% 0% 3.03s 37.88% runtime.gcBgMarkWorker
0 0% 0% 3.03s 37.88% runtime.gcBgMarkWorker.func2
0.11s 1.38% 1.38% 3.03s 37.88% runtime.gcDrain
0 0% 1.38% 2.98s 37.25% sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig.MakeDefaultConfig
0 0% 1.38% 2.98s 37.25% sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig.MakeTransformerConfig
0 0% 1.38% 2.98s 37.25% sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig.makeTransformerConfigFromBytes
0 0% 1.38% 2.97s 37.12% sigs.k8s.io/yaml.yamlUnmarshal
0 0% 1.38% 2.91s 36.38% sigs.k8s.io/yaml.Unmarshal (inline)
1.34s 16.75% 18.12% 2.87s 35.88% runtime.scanobject
0 0% 18.12% 2.53s 31.62% sigs.k8s.io/yaml.yamlToJSON
0 0% 18.12% 1.91s 23.88% gopkg.in/yaml%2ev2.unmarshal
0 0% 18.12% 1.86s 23.25% gopkg.in/yaml%2ev2.Unmarshal (partial-inline)
0 0% 18.12% 1.43s 17.88% gopkg.in/yaml%2ev2.(*parser).parse
0.01s 0.12% 18.25% 1.27s 15.88% gopkg.in/yaml%2ev2.(*parser).document
0.01s 0.12% 18.38% 1.25s 15.62% gopkg.in/yaml%2ev2.(*parser).mapping
0.35s 4.38% 22.75% 1.21s 15.12% runtime.mallocgc
after:
(pprof) top30 -cum
Showing nodes accounting for 0.84s, 24.42% of 3.44s total
Dropped 225 nodes (cum <= 0.02s)
Showing top 30 nodes out of 345
flat flat% sum% cum cum%
0 0% 0% 1.82s 52.91% github.com/spf13/cobra.(*Command).Execute
0 0% 0% 1.82s 52.91% github.com/spf13/cobra.(*Command).ExecuteC
0 0% 0% 1.82s 52.91% github.com/spf13/cobra.(*Command).execute
0 0% 0% 1.82s 52.91% main.main
0 0% 0% 1.82s 52.91% runtime.main
0 0% 0% 1.82s 52.91% sigs.k8s.io/kustomize/kustomize/v5/commands/build.NewCmdBuild.func1
0 0% 0% 1.57s 45.64% runtime.systemstack
0 0% 0% 1.49s 43.31% runtime.gcBgMarkWorker
0 0% 0% 1.49s 43.31% runtime.gcBgMarkWorker.func2
0.03s 0.87% 0.87% 1.49s 43.31% runtime.gcDrain
0.62s 18.02% 18.90% 1.45s 42.15% runtime.scanobject
0 0% 18.90% 1.25s 36.34% sigs.k8s.io/kustomize/api/krusty.(*Kustomizer).Run
0 0% 18.90% 1.21s 35.17% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).MakeCustomizedResMap (inline)
0 0% 18.90% 1.21s 35.17% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).makeCustomizedResMap
0 0% 18.90% 1.08s 31.40% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).AccumulateTarget
0 0% 18.90% 1.08s 31.40% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).accumulateResources
0 0% 18.90% 1.08s 31.40% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).accumulateTarget
0 0% 18.90% 1.07s 31.10% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).accumulateDirectory
0 0% 18.90% 0.57s 16.57% sigs.k8s.io/kustomize/api/resmap.(*resWrangler).AsYaml
0 0% 18.90% 0.57s 16.57% sigs.k8s.io/kustomize/api/resource.(*Resource).AsYAML
0.11s 3.20% 22.09% 0.48s 13.95% runtime.mallocgc
0 0% 22.09% 0.45s 13.08% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).accumulateFile
0 0% 22.09% 0.45s 13.08% sigs.k8s.io/kustomize/api/resmap.(*Factory).FromFile
0 0% 22.09% 0.33s 9.59% sigs.k8s.io/kustomize/kyaml/yaml.(*RNode).MarshalJSON
0.08s 2.33% 24.42% 0.32s 9.30% runtime.greyobject
0 0% 24.42% 0.30s 8.72% sigs.k8s.io/kustomize/api/resmap.(*Factory).NewResMapFromBytes
0 0% 24.42% 0.27s 7.85% sigs.k8s.io/yaml.JSONToYAML
0 0% 24.42% 0.25s 7.27% sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).runTransformers
0 0% 24.42% 0.25s 7.27% sigs.k8s.io/kustomize/api/resource.(*Factory).RNodesFromBytes
0 0% 24.42% 0.25s 7.27% sigs.k8s.io/kustomize/api/resource.(*Factory).SliceFromBytes
* Tests and comments for MakeDefaultConfig perf work
Document updated code in MakeDefaultConfig.
Add unit tests to ensure DeepCopy works.
Add hints to other code to ensure DeepCopy is kept up to date.
188 lines
6.6 KiB
Go
188 lines
6.6 KiB
Go
// Copyright 2019 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package builtinconfig
|
|
|
|
import (
|
|
"log"
|
|
"sort"
|
|
"sync"
|
|
|
|
"sigs.k8s.io/kustomize/api/ifc"
|
|
"sigs.k8s.io/kustomize/api/internal/konfig/builtinpluginconsts"
|
|
"sigs.k8s.io/kustomize/api/types"
|
|
"sigs.k8s.io/kustomize/kyaml/errors"
|
|
)
|
|
|
|
// TransformerConfig holds the data needed to perform transformations.
|
|
type TransformerConfig struct {
|
|
// if any fields are added, update the DeepCopy implementation
|
|
NamePrefix types.FsSlice `json:"namePrefix,omitempty" yaml:"namePrefix,omitempty"`
|
|
NameSuffix types.FsSlice `json:"nameSuffix,omitempty" yaml:"nameSuffix,omitempty"`
|
|
NameSpace types.FsSlice `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
|
CommonLabels types.FsSlice `json:"commonLabels,omitempty" yaml:"commonLabels,omitempty"`
|
|
TemplateLabels types.FsSlice `json:"templateLabels,omitempty" yaml:"templateLabels,omitempty"`
|
|
CommonAnnotations types.FsSlice `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"`
|
|
NameReference nbrSlice `json:"nameReference,omitempty" yaml:"nameReference,omitempty"`
|
|
VarReference types.FsSlice `json:"varReference,omitempty" yaml:"varReference,omitempty"`
|
|
Images types.FsSlice `json:"images,omitempty" yaml:"images,omitempty"`
|
|
Replicas types.FsSlice `json:"replicas,omitempty" yaml:"replicas,omitempty"`
|
|
}
|
|
|
|
// MakeEmptyConfig returns an empty TransformerConfig object
|
|
func MakeEmptyConfig() *TransformerConfig {
|
|
return &TransformerConfig{}
|
|
}
|
|
|
|
// DeepCopy returns a new copy of TransformerConfig
|
|
func (t *TransformerConfig) DeepCopy() *TransformerConfig {
|
|
return &TransformerConfig{
|
|
NamePrefix: t.NamePrefix.DeepCopy(),
|
|
NameSuffix: t.NameSuffix.DeepCopy(),
|
|
NameSpace: t.NameSpace.DeepCopy(),
|
|
CommonLabels: t.CommonLabels.DeepCopy(),
|
|
TemplateLabels: t.TemplateLabels.DeepCopy(),
|
|
CommonAnnotations: t.CommonAnnotations.DeepCopy(),
|
|
NameReference: t.NameReference.DeepCopy(),
|
|
VarReference: t.VarReference.DeepCopy(),
|
|
Images: t.Images.DeepCopy(),
|
|
Replicas: t.Replicas.DeepCopy(),
|
|
}
|
|
}
|
|
|
|
// the default transformer config is initialized by MakeDefaultConfig,
|
|
// and must only be accessed via that function.
|
|
var (
|
|
initDefaultConfig sync.Once //nolint:gochecknoglobals
|
|
defaultConfig *TransformerConfig //nolint:gochecknoglobals
|
|
)
|
|
|
|
// MakeDefaultConfig returns a default TransformerConfig.
|
|
func MakeDefaultConfig() *TransformerConfig {
|
|
// parsing is expensive when having a large tree with many kustomization modules, so only do it once
|
|
initDefaultConfig.Do(func() {
|
|
var err error
|
|
defaultConfig, err = makeTransformerConfigFromBytes(
|
|
builtinpluginconsts.GetDefaultFieldSpecs())
|
|
if err != nil {
|
|
log.Fatalf("Unable to make default transformconfig: %v", err)
|
|
}
|
|
})
|
|
|
|
// return a copy to avoid any mutations to protect the reference copy
|
|
return defaultConfig.DeepCopy()
|
|
}
|
|
|
|
// MakeTransformerConfig returns a merger of custom config,
|
|
// if any, with default config.
|
|
func MakeTransformerConfig(
|
|
ldr ifc.Loader, paths []string) (*TransformerConfig, error) {
|
|
t1 := MakeDefaultConfig()
|
|
if len(paths) == 0 {
|
|
return t1, nil
|
|
}
|
|
t2, err := loadDefaultConfig(ldr, paths)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return t1.Merge(t2)
|
|
}
|
|
|
|
// sortFields provides determinism in logging, tests, etc.
|
|
func (t *TransformerConfig) sortFields() {
|
|
sort.Sort(t.NamePrefix)
|
|
sort.Sort(t.NameSuffix)
|
|
sort.Sort(t.NameSpace)
|
|
sort.Sort(t.CommonLabels)
|
|
sort.Sort(t.TemplateLabels)
|
|
sort.Sort(t.CommonAnnotations)
|
|
sort.Sort(t.NameReference)
|
|
sort.Sort(t.VarReference)
|
|
sort.Sort(t.Images)
|
|
sort.Sort(t.Replicas)
|
|
}
|
|
|
|
// AddPrefixFieldSpec adds a FieldSpec to NamePrefix
|
|
func (t *TransformerConfig) AddPrefixFieldSpec(fs types.FieldSpec) (err error) {
|
|
t.NamePrefix, err = t.NamePrefix.MergeOne(fs)
|
|
return err
|
|
}
|
|
|
|
// AddSuffixFieldSpec adds a FieldSpec to NameSuffix
|
|
func (t *TransformerConfig) AddSuffixFieldSpec(fs types.FieldSpec) (err error) {
|
|
t.NameSuffix, err = t.NameSuffix.MergeOne(fs)
|
|
return err
|
|
}
|
|
|
|
// AddLabelFieldSpec adds a FieldSpec to CommonLabels
|
|
func (t *TransformerConfig) AddLabelFieldSpec(fs types.FieldSpec) (err error) {
|
|
t.CommonLabels, err = t.CommonLabels.MergeOne(fs)
|
|
return err
|
|
}
|
|
|
|
// AddAnnotationFieldSpec adds a FieldSpec to CommonAnnotations
|
|
func (t *TransformerConfig) AddAnnotationFieldSpec(fs types.FieldSpec) (err error) {
|
|
t.CommonAnnotations, err = t.CommonAnnotations.MergeOne(fs)
|
|
return err
|
|
}
|
|
|
|
// AddNamereferenceFieldSpec adds a NameBackReferences to NameReference
|
|
func (t *TransformerConfig) AddNamereferenceFieldSpec(
|
|
nbrs NameBackReferences) (err error) {
|
|
t.NameReference, err = t.NameReference.mergeOne(nbrs)
|
|
return err
|
|
}
|
|
|
|
// Merge merges two TransformerConfigs objects into
|
|
// a new TransformerConfig object
|
|
func (t *TransformerConfig) Merge(input *TransformerConfig) (
|
|
merged *TransformerConfig, err error) {
|
|
if input == nil {
|
|
return t, nil
|
|
}
|
|
merged = &TransformerConfig{}
|
|
merged.NamePrefix, err = t.NamePrefix.MergeAll(input.NamePrefix)
|
|
if err != nil {
|
|
return nil, errors.WrapPrefixf(err, "failed to merge NamePrefix fieldSpec")
|
|
}
|
|
merged.NameSuffix, err = t.NameSuffix.MergeAll(input.NameSuffix)
|
|
if err != nil {
|
|
return nil, errors.WrapPrefixf(err, "failed to merge NameSuffix fieldSpec")
|
|
}
|
|
merged.NameSpace, err = t.NameSpace.MergeAll(input.NameSpace)
|
|
if err != nil {
|
|
return nil, errors.WrapPrefixf(err, "failed to merge NameSpace fieldSpec")
|
|
}
|
|
merged.CommonAnnotations, err = t.CommonAnnotations.MergeAll(
|
|
input.CommonAnnotations)
|
|
if err != nil {
|
|
return nil, errors.WrapPrefixf(err, "failed to merge CommonAnnotations fieldSpec")
|
|
}
|
|
merged.CommonLabels, err = t.CommonLabels.MergeAll(input.CommonLabels)
|
|
if err != nil {
|
|
return nil, errors.WrapPrefixf(err, "failed to merge CommonLabels fieldSpec")
|
|
}
|
|
merged.TemplateLabels, err = t.TemplateLabels.MergeAll(input.TemplateLabels)
|
|
if err != nil {
|
|
return nil, errors.WrapPrefixf(err, "failed to merge TemplateLabels fieldSpec")
|
|
}
|
|
merged.VarReference, err = t.VarReference.MergeAll(input.VarReference)
|
|
if err != nil {
|
|
return nil, errors.WrapPrefixf(err, "failed to merge VarReference fieldSpec")
|
|
}
|
|
merged.NameReference, err = t.NameReference.mergeAll(input.NameReference)
|
|
if err != nil {
|
|
return nil, errors.WrapPrefixf(err, "failed to merge NameReference fieldSpec")
|
|
}
|
|
merged.Images, err = t.Images.MergeAll(input.Images)
|
|
if err != nil {
|
|
return nil, errors.WrapPrefixf(err, "failed to merge Images fieldSpec")
|
|
}
|
|
merged.Replicas, err = t.Replicas.MergeAll(input.Replicas)
|
|
if err != nil {
|
|
return nil, errors.WrapPrefixf(err, "failed to merge Replicas fieldSpec")
|
|
}
|
|
merged.sortFields()
|
|
return merged, nil
|
|
}
|