talos/pkg/resources/config/machine_config.go
Andrey Smirnov d930a26502 chore: implement DeepCopy for machine configuration
Resources code extensively uses DeepCopy to prevent in-memory copy of
the resource to be mutated outside of the resource model.

Previous implementation relied on YAML serialization to copy the
machine configuration which was slow, potentially might lead to panics
and it generates pressure on garbage collection.

This implementation uses k8s code generator to generate DeepCopy methods
with some manual helpers when code generator can't handle it.

Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
2021-07-08 07:21:24 -07:00

90 lines
2.3 KiB
Go

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package config
import (
"fmt"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/resource/meta"
"github.com/talos-systems/talos/pkg/machinery/config"
"github.com/talos-systems/talos/pkg/machinery/config/encoder"
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1"
)
// MachineConfigType is type of Service resource.
const MachineConfigType = resource.Type("MachineConfigs.config.talos.dev")
// V1Alpha1ID is the ID of V1Alpha1 resource (singleton).
const V1Alpha1ID = resource.ID("v1alpha1")
// MachineConfig resource holds v1alpha Talos configuration.
type MachineConfig struct {
md resource.Metadata
spec *v1alpha1Spec
}
type v1alpha1Spec struct {
cfg config.Provider
}
func (s *v1alpha1Spec) MarshalYAML() (interface{}, error) {
return encoder.NewEncoder(s.cfg).Marshal()
}
// NewMachineConfig initializes a V1Alpha1 resource.
func NewMachineConfig(spec config.Provider) *MachineConfig {
r := &MachineConfig{
md: resource.NewMetadata(NamespaceName, MachineConfigType, V1Alpha1ID, resource.VersionUndefined),
spec: &v1alpha1Spec{
cfg: spec,
},
}
r.md.BumpVersion()
return r
}
// Metadata implements resource.Resource.
func (r *MachineConfig) Metadata() *resource.Metadata {
return &r.md
}
// Spec implements resource.Resource.
func (r *MachineConfig) Spec() interface{} {
return r.spec
}
func (r *MachineConfig) String() string {
return fmt.Sprintf("config.MachineConfig(%q)", r.md.ID())
}
// DeepCopy implements resource.Resource.
func (r *MachineConfig) DeepCopy() resource.Resource {
return &MachineConfig{
md: r.md,
spec: &v1alpha1Spec{
cfg: r.spec.cfg.(*v1alpha1.Config).DeepCopy(),
},
}
}
// ResourceDefinition implements meta.ResourceDefinitionProvider interface.
func (r *MachineConfig) ResourceDefinition() meta.ResourceDefinitionSpec {
return meta.ResourceDefinitionSpec{
Type: MachineConfigType,
Aliases: []resource.Type{},
DefaultNamespace: NamespaceName,
Sensitivity: meta.Sensitive,
}
}
// Config returns config.Provider.
func (r *MachineConfig) Config() config.Provider {
return r.spec.cfg
}