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>
This commit is contained in:
parent
fe4ed3c734
commit
d930a26502
@ -42,6 +42,7 @@ policies:
|
||||
- .pb.go
|
||||
- _string.go
|
||||
- _string_linux.go
|
||||
- zz_generated.deepcopy.go
|
||||
header: |
|
||||
// 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
|
||||
|
@ -101,6 +101,9 @@ RUN go install mvdan.cc/gofumpt/gofumports@${GOFUMPT_VERSION} \
|
||||
ARG STRINGER_VERSION
|
||||
RUN go install golang.org/x/tools/cmd/stringer@${STRINGER_VERSION} \
|
||||
&& mv /go/bin/stringer /toolchain/go/bin/stringer
|
||||
ARG DEEPCOPY_GEN_VERSION
|
||||
RUN go install k8s.io/code-generator/cmd/deepcopy-gen@${DEEPCOPY_GEN_VERSION} \
|
||||
&& mv /go/bin/deepcopy-gen /toolchain/go/bin/deepcopy-gen
|
||||
RUN curl -sfL https://github.com/uber/prototool/releases/download/v1.10.0/prototool-Linux-x86_64.tar.gz | tar -xz --strip-components=2 -C /toolchain/bin prototool/bin/prototool
|
||||
COPY ./hack/docgen /go/src/github.com/talos-systems/talos-hack-docgen
|
||||
RUN cd /go/src/github.com/talos-systems/talos-hack-docgen \
|
||||
@ -165,6 +168,7 @@ RUN gofumports -w -local github.com/talos-systems/talos /api/
|
||||
# run docgen for machinery config
|
||||
FROM build-go AS go-generate
|
||||
COPY ./pkg ./pkg
|
||||
COPY ./hack/boilerplate.txt ./hack/boilerplate.txt
|
||||
RUN --mount=type=cache,target=/.cache go generate ./pkg/...
|
||||
WORKDIR /src/pkg/machinery
|
||||
RUN --mount=type=cache,target=/.cache go generate ./...
|
||||
|
2
Makefile
2
Makefile
@ -16,6 +16,7 @@ EXTRAS ?= v0.4.0
|
||||
GO_VERSION ?= 1.16
|
||||
GOFUMPT_VERSION ?= v0.1.0
|
||||
STRINGER_VERSION ?= v0.1.3
|
||||
DEEPCOPY_GEN_VERSION ?= v0.21.2
|
||||
IMPORTVET ?= autonomy/importvet:f6b07d9
|
||||
OPERATING_SYSTEM := $(shell uname -s | tr "[:upper:]" "[:lower:]")
|
||||
TALOSCTL_DEFAULT_TARGET := talosctl-$(OPERATING_SYSTEM)
|
||||
@ -79,6 +80,7 @@ COMMON_ARGS += --build-arg=PKGS=$(PKGS)
|
||||
COMMON_ARGS += --build-arg=EXTRAS=$(EXTRAS)
|
||||
COMMON_ARGS += --build-arg=GOFUMPT_VERSION=$(GOFUMPT_VERSION)
|
||||
COMMON_ARGS += --build-arg=STRINGER_VERSION=$(STRINGER_VERSION)
|
||||
COMMON_ARGS += --build-arg=DEEPCOPY_GEN_VERSION=$(DEEPCOPY_GEN_VERSION)
|
||||
COMMON_ARGS += --build-arg=TAG=$(TAG)
|
||||
COMMON_ARGS += --build-arg=ARTIFACTS=$(ARTIFACTS)
|
||||
COMMON_ARGS += --build-arg=IMPORTVET=$(IMPORTVET)
|
||||
|
2
go.mod
2
go.mod
@ -71,7 +71,7 @@ require (
|
||||
github.com/smira/go-xz v0.0.0-20201019130106-9921ed7a9935
|
||||
github.com/spf13/cobra v1.2.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/talos-systems/crypto v0.3.1
|
||||
github.com/talos-systems/crypto v0.3.2-0.20210707205149-deec8d47700e
|
||||
github.com/talos-systems/go-blockdevice v0.2.1
|
||||
github.com/talos-systems/go-cmd v0.1.0
|
||||
github.com/talos-systems/go-debug v0.2.1
|
||||
|
4
go.sum
4
go.sum
@ -1138,8 +1138,8 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69
|
||||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/talos-systems/crypto v0.3.1 h1:TSUfwrN3+sAunR/e78pU8JMbBo9VDfS3fJtpMg7xQ6k=
|
||||
github.com/talos-systems/crypto v0.3.1/go.mod h1:xaNCB2/Bxaj+qrkdeodhRv5eKQVvKOGBBMj58MrIPY8=
|
||||
github.com/talos-systems/crypto v0.3.2-0.20210707205149-deec8d47700e h1:7mNVNvTTRA7mqflb/34iSJrimISfRErruMyptRAGWkg=
|
||||
github.com/talos-systems/crypto v0.3.2-0.20210707205149-deec8d47700e/go.mod h1:xaNCB2/Bxaj+qrkdeodhRv5eKQVvKOGBBMj58MrIPY8=
|
||||
github.com/talos-systems/go-blockdevice v0.2.1 h1:swoY5NcssuMgdCf/dlMngNDgEAasGp2jviPqAz9Epss=
|
||||
github.com/talos-systems/go-blockdevice v0.2.1/go.mod h1:qnn/zDc09I1DA2BUDDCOSA2D0P8pIDjN8pGiRoRaQig=
|
||||
github.com/talos-systems/go-cmd v0.0.0-20210216164758-68eb0067e0f0/go.mod h1:kf+rZzTEmlDiYQ6ulslvRONnKLQH8x83TowltGMhO+k=
|
||||
|
3
hack/boilerplate.txt
Normal file
3
hack/boilerplate.txt
Normal file
@ -0,0 +1,3 @@
|
||||
// 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/.
|
7
pkg/machinery/config/types/v1alpha1/doc.go
Normal file
7
pkg/machinery/config/types/v1alpha1/doc.go
Normal file
@ -0,0 +1,7 @@
|
||||
// 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/.
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
package v1alpha1
|
@ -22,6 +22,7 @@ import (
|
||||
|
||||
// ConfigBundle defines the group of v1alpha1 config files.
|
||||
// docgen: nodoc
|
||||
// +k8s:deepcopy-gen=false
|
||||
type ConfigBundle struct {
|
||||
InitCfg *Config
|
||||
ControlPlaneCfg *Config
|
||||
|
@ -304,7 +304,17 @@ func (k *KubeletConfig) ExtraArgs() map[string]string {
|
||||
|
||||
// ExtraMounts implements the config.Provider interface.
|
||||
func (k *KubeletConfig) ExtraMounts() []specs.Mount {
|
||||
return k.KubeletExtraMounts
|
||||
if k.KubeletExtraMounts == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := make([]specs.Mount, len(k.KubeletExtraMounts))
|
||||
|
||||
for i := range k.KubeletExtraMounts {
|
||||
out[i] = k.KubeletExtraMounts[i].Mount
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// RegisterWithFQDN implements the config.Provider interface.
|
||||
|
@ -6,9 +6,8 @@
|
||||
Package v1alpha1 configuration file contains all the options available for configuring a machine.
|
||||
|
||||
To generate a set of basic configuration files, run:
|
||||
```bash
|
||||
talosctl gen config --version v1alpha1 <cluster name> <cluster endpoint>
|
||||
````
|
||||
|
||||
talosctl gen config --version v1alpha1 <cluster name> <cluster endpoint>
|
||||
|
||||
This will generate a machine config for each node type, and a talosconfig for the CLI.
|
||||
*/
|
||||
@ -16,6 +15,8 @@ package v1alpha1
|
||||
|
||||
//go:generate docgen ./v1alpha1_types.go ./v1alpha1_types_doc.go Configuration
|
||||
|
||||
//go:generate deepcopy-gen --input-dirs ../v1alpha1/ --go-header-file ../../../../../hack/boilerplate.txt --bounding-dirs ../v1alpha1 -O zz_generated.deepcopy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
@ -752,6 +753,28 @@ type ClusterConfig struct {
|
||||
AllowSchedulingOnMasters bool `yaml:"allowSchedulingOnMasters,omitempty"`
|
||||
}
|
||||
|
||||
// ExtraMount wraps OCI Mount specification.
|
||||
type ExtraMount struct {
|
||||
specs.Mount
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtraMount) DeepCopyInto(out *ExtraMount) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtraMount.
|
||||
func (in *ExtraMount) DeepCopy() *ExtraMount {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := new(ExtraMount)
|
||||
in.DeepCopyInto(out)
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// KubeletConfig represents the kubelet config values.
|
||||
type KubeletConfig struct {
|
||||
// description: |
|
||||
@ -771,7 +794,7 @@ type KubeletConfig struct {
|
||||
// The `extraMounts` field is used to add additional mounts to the kubelet container.
|
||||
// examples:
|
||||
// - value: kubeletExtraMountsExample
|
||||
KubeletExtraMounts []specs.Mount `yaml:"extraMounts,omitempty"`
|
||||
KubeletExtraMounts []ExtraMount `yaml:"extraMounts,omitempty"`
|
||||
// description: |
|
||||
// The `registerWithFQDN` field is used to force kubelet to use the node FQDN for registration.
|
||||
// This is required in clouds like AWS.
|
||||
@ -865,6 +888,11 @@ type InstallDiskSizeMatcher struct {
|
||||
condition string
|
||||
}
|
||||
|
||||
// DeepCopyInto implements DeepCopy interface.
|
||||
func (m *InstallDiskSizeMatcher) DeepCopyInto(out *InstallDiskSizeMatcher) {
|
||||
*out = *m
|
||||
}
|
||||
|
||||
// MarshalYAML is a custom marshaller for `InstallDiskSizeMatcher`.
|
||||
func (m *InstallDiskSizeMatcher) MarshalYAML() (interface{}, error) {
|
||||
return m.condition, nil
|
||||
@ -1067,6 +1095,29 @@ func (e *Endpoint) MarshalYAML() (interface{}, error) {
|
||||
return e.URL.String(), nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (e *Endpoint) DeepCopyInto(out *Endpoint) {
|
||||
*out = *e
|
||||
|
||||
if e.URL != nil {
|
||||
in, out := &e.URL, &out.URL
|
||||
*out = new(url.URL)
|
||||
*out = *in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint.
|
||||
func (e *Endpoint) DeepCopy() *Endpoint {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := new(Endpoint)
|
||||
e.DeepCopyInto(out)
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// ControlPlaneConfig represents the control plane configuration options.
|
||||
type ControlPlaneConfig struct {
|
||||
// description: |
|
||||
|
@ -14,6 +14,7 @@ var (
|
||||
ConfigDoc encoder.Doc
|
||||
MachineConfigDoc encoder.Doc
|
||||
ClusterConfigDoc encoder.Doc
|
||||
ExtraMountDoc encoder.Doc
|
||||
KubeletConfigDoc encoder.Doc
|
||||
NetworkConfigDoc encoder.Doc
|
||||
InstallConfigDoc encoder.Doc
|
||||
@ -401,6 +402,19 @@ func init() {
|
||||
"no",
|
||||
}
|
||||
|
||||
ExtraMountDoc.Type = "ExtraMount"
|
||||
ExtraMountDoc.Comments[encoder.LineComment] = "ExtraMount wraps OCI Mount specification."
|
||||
ExtraMountDoc.Description = "ExtraMount wraps OCI Mount specification."
|
||||
|
||||
ExtraMountDoc.AddExample("", kubeletExtraMountsExample)
|
||||
ExtraMountDoc.AppearsIn = []encoder.Appearance{
|
||||
{
|
||||
TypeName: "KubeletConfig",
|
||||
FieldName: "extraMounts",
|
||||
},
|
||||
}
|
||||
ExtraMountDoc.Fields = make([]encoder.Doc, 0)
|
||||
|
||||
KubeletConfigDoc.Type = "KubeletConfig"
|
||||
KubeletConfigDoc.Comments[encoder.LineComment] = "KubeletConfig represents the kubelet config values."
|
||||
KubeletConfigDoc.Description = "KubeletConfig represents the kubelet config values."
|
||||
@ -430,7 +444,7 @@ func init() {
|
||||
"key": "value",
|
||||
})
|
||||
KubeletConfigDoc.Fields[2].Name = "extraMounts"
|
||||
KubeletConfigDoc.Fields[2].Type = "[]Mount"
|
||||
KubeletConfigDoc.Fields[2].Type = "[]ExtraMount"
|
||||
KubeletConfigDoc.Fields[2].Note = ""
|
||||
KubeletConfigDoc.Fields[2].Description = "The `extraMounts` field is used to add additional mounts to the kubelet container."
|
||||
KubeletConfigDoc.Fields[2].Comments[encoder.LineComment] = "The `extraMounts` field is used to add additional mounts to the kubelet container."
|
||||
@ -1882,6 +1896,10 @@ func (_ ClusterConfig) Doc() *encoder.Doc {
|
||||
return &ClusterConfigDoc
|
||||
}
|
||||
|
||||
func (_ ExtraMount) Doc() *encoder.Doc {
|
||||
return &ExtraMountDoc
|
||||
}
|
||||
|
||||
func (_ KubeletConfig) Doc() *encoder.Doc {
|
||||
return &KubeletConfigDoc
|
||||
}
|
||||
@ -2061,12 +2079,13 @@ func (_ ClusterInlineManifest) Doc() *encoder.Doc {
|
||||
// GetConfigurationDoc returns documentation for the file ./v1alpha1_types_doc.go.
|
||||
func GetConfigurationDoc() *encoder.FileDoc {
|
||||
return &encoder.FileDoc{
|
||||
Name: "Configuration",
|
||||
Description: "Package v1alpha1 configuration file contains all the options available for configuring a machine.\n\nTo generate a set of basic configuration files, run:\n```bash\ntalosctl gen config --version v1alpha1 <cluster name> <cluster endpoint>\n````\n\nThis will generate a machine config for each node type, and a talosconfig for the CLI.\n",
|
||||
Name: "Configuration",
|
||||
Description: "Package v1alpha1 configuration file contains all the options available for configuring a machine.\n\nTo generate a set of basic configuration files, run:\n\n talosctl gen config --version v1alpha1 <cluster name> <cluster endpoint>\n\nThis will generate a machine config for each node type, and a talosconfig for the CLI.\n",
|
||||
Structs: []*encoder.Doc{
|
||||
&ConfigDoc,
|
||||
&MachineConfigDoc,
|
||||
&ClusterConfigDoc,
|
||||
&ExtraMountDoc,
|
||||
&KubeletConfigDoc,
|
||||
&NetworkConfigDoc,
|
||||
&InstallConfigDoc,
|
||||
|
@ -2,7 +2,6 @@
|
||||
// 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 v1alpha1 provides user-facing v1alpha1 machine configs
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
|
1292
pkg/machinery/config/types/v1alpha1/zz_generated.deepcopy.go
Normal file
1292
pkg/machinery/config/types/v1alpha1/zz_generated.deepcopy.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@ require (
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d
|
||||
github.com/stretchr/objx v0.3.0 // indirect
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/talos-systems/crypto v0.3.1
|
||||
github.com/talos-systems/crypto v0.3.2-0.20210707205149-deec8d47700e
|
||||
github.com/talos-systems/go-blockdevice v0.2.1
|
||||
github.com/talos-systems/net v0.3.0
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c
|
||||
|
@ -154,8 +154,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/talos-systems/crypto v0.3.1 h1:TSUfwrN3+sAunR/e78pU8JMbBo9VDfS3fJtpMg7xQ6k=
|
||||
github.com/talos-systems/crypto v0.3.1/go.mod h1:xaNCB2/Bxaj+qrkdeodhRv5eKQVvKOGBBMj58MrIPY8=
|
||||
github.com/talos-systems/crypto v0.3.2-0.20210707205149-deec8d47700e h1:7mNVNvTTRA7mqflb/34iSJrimISfRErruMyptRAGWkg=
|
||||
github.com/talos-systems/crypto v0.3.2-0.20210707205149-deec8d47700e/go.mod h1:xaNCB2/Bxaj+qrkdeodhRv5eKQVvKOGBBMj58MrIPY8=
|
||||
github.com/talos-systems/go-blockdevice v0.2.1 h1:swoY5NcssuMgdCf/dlMngNDgEAasGp2jviPqAz9Epss=
|
||||
github.com/talos-systems/go-blockdevice v0.2.1/go.mod h1:qnn/zDc09I1DA2BUDDCOSA2D0P8pIDjN8pGiRoRaQig=
|
||||
github.com/talos-systems/go-cmd v0.0.0-20210216164758-68eb0067e0f0/go.mod h1:kf+rZzTEmlDiYQ6ulslvRONnKLQH8x83TowltGMhO+k=
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"github.com/cosi-project/runtime/pkg/resource/meta"
|
||||
|
||||
"github.com/talos-systems/talos/pkg/machinery/config"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/configloader"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/encoder"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1"
|
||||
)
|
||||
@ -66,20 +65,10 @@ func (r *MachineConfig) String() string {
|
||||
|
||||
// DeepCopy implements resource.Resource.
|
||||
func (r *MachineConfig) DeepCopy() resource.Resource {
|
||||
b, err := r.spec.cfg.Bytes()
|
||||
if err != nil {
|
||||
panic(err) // TODO: DeepCopy() should support returning errors? or config should implement DeeCopy without errors?
|
||||
}
|
||||
|
||||
c, err := configloader.NewFromBytes(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &MachineConfig{
|
||||
md: r.md,
|
||||
spec: &v1alpha1Spec{
|
||||
cfg: c.(*v1alpha1.Config),
|
||||
cfg: r.spec.cfg.(*v1alpha1.Config).DeepCopy(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -11,9 +11,8 @@ desription: Talos node configuration file reference.
|
||||
Package v1alpha1 configuration file contains all the options available for configuring a machine.
|
||||
|
||||
To generate a set of basic configuration files, run:
|
||||
```bash
|
||||
talosctl gen config --version v1alpha1 <cluster name> <cluster endpoint>
|
||||
````
|
||||
|
||||
talosctl gen config --version v1alpha1 <cluster name> <cluster endpoint>
|
||||
|
||||
This will generate a machine config for each node type, and a talosconfig for the CLI.
|
||||
|
||||
@ -1287,6 +1286,26 @@ Valid values:
|
||||
|
||||
|
||||
|
||||
## ExtraMount
|
||||
ExtraMount wraps OCI Mount specification.
|
||||
|
||||
Appears in:
|
||||
|
||||
|
||||
- <code><a href="#kubeletconfig">KubeletConfig</a>.extraMounts</code>
|
||||
|
||||
|
||||
``` yaml
|
||||
- destination: /var/lib/example
|
||||
type: bind
|
||||
source: /var/lib/example
|
||||
options:
|
||||
- rshared
|
||||
- rw
|
||||
```
|
||||
|
||||
|
||||
|
||||
## KubeletConfig
|
||||
KubeletConfig represents the kubelet config values.
|
||||
|
||||
@ -1363,7 +1382,7 @@ extraArgs:
|
||||
|
||||
<div class="dd">
|
||||
|
||||
<code>extraMounts</code> <i>[]Mount</i>
|
||||
<code>extraMounts</code> <i>[]<a href="#extramount">ExtraMount</a></i>
|
||||
|
||||
</div>
|
||||
<div class="dt">
|
||||
|
Loading…
Reference in New Issue
Block a user