mirror of
https://github.com/siderolabs/talos.git
synced 2025-10-09 22:51:12 +02:00
feat: support version contract for Talos config generation
This allows to generating current version Talos configs (by default) or backwards compatible configuration (e.g. for Talos 0.8). `talosctl gen config` defaults to current version, but explicit version can be passed to the command via flags. `talosctl cluster create` defaults to install/container image version, but that can be overridden. This makes `talosctl cluster create` now compatible with 0.8.1 images out of the box. Upgrade tests use contract based on source version in the test. When used as a library, `VersionContract` can be omitted (defaults to current version) or passed explicitly. `VersionContract` can be convienietly parsed from Talos version string or specified as one of the constants. Fixes #3130 Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
This commit is contained in:
parent
f9896777fc
commit
daea9d3811
@ -86,6 +86,7 @@ var (
|
||||
crashdumpOnFailure bool
|
||||
skipKubeconfig bool
|
||||
skipInjectingConfig bool
|
||||
talosVersion string
|
||||
)
|
||||
|
||||
// createCmd represents the cluster up command.
|
||||
@ -280,6 +281,29 @@ func create(ctx context.Context) (err error) {
|
||||
genOptions = append(genOptions, generate.WithUserDisks(machineDisks))
|
||||
}
|
||||
|
||||
if talosVersion == "" {
|
||||
if provisionerName == "docker" {
|
||||
parts := strings.Split(nodeImage, ":")
|
||||
|
||||
talosVersion = parts[len(parts)-1]
|
||||
} else {
|
||||
parts := strings.Split(nodeInstallImage, ":")
|
||||
|
||||
talosVersion = parts[len(parts)-1]
|
||||
}
|
||||
}
|
||||
|
||||
if talosVersion != "latest" {
|
||||
var versionContract *config.VersionContract
|
||||
|
||||
versionContract, err = config.ParseContractFromVersion(talosVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing Talos version %q: %w", talosVersion, err)
|
||||
}
|
||||
|
||||
genOptions = append(genOptions, generate.WithVersionContract(versionContract))
|
||||
}
|
||||
|
||||
defaultInternalLB, defaultEndpoint := provisioner.GetLoadBalancers(request.Network)
|
||||
|
||||
if defaultInternalLB == "" {
|
||||
@ -677,5 +701,6 @@ func init() {
|
||||
createCmd.Flags().BoolVar(&crashdumpOnFailure, "crashdump", false, "print debug crashdump to stderr when cluster startup fails")
|
||||
createCmd.Flags().BoolVar(&skipKubeconfig, "skip-kubeconfig", false, "skip merging kubeconfig from the created cluster")
|
||||
createCmd.Flags().BoolVar(&skipInjectingConfig, "skip-injecting-config", false, "skip injecting config from embedded metadata server, write config files to current directory")
|
||||
createCmd.Flags().StringVar(&talosVersion, "talos-version", "", "the desired Talos version to generate config for (if not set, defaults to image version)")
|
||||
Cmd.AddCommand(createCmd)
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
|
||||
"github.com/talos-systems/talos/cmd/talosctl/pkg/mgmt/helpers"
|
||||
"github.com/talos-systems/talos/pkg/images"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/bundle"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/generate"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/machine"
|
||||
@ -29,6 +30,7 @@ var (
|
||||
configVersion string
|
||||
dnsDomain string
|
||||
kubernetesVersion string
|
||||
talosVersion string
|
||||
installDisk string
|
||||
installImage string
|
||||
outputDir string
|
||||
@ -127,6 +129,17 @@ func genV1Alpha1Config(args []string) error {
|
||||
genOptions = append(genOptions, generate.WithRegistryMirror(components[0], components[1]))
|
||||
}
|
||||
|
||||
if talosVersion != "" {
|
||||
var versionContract *config.VersionContract
|
||||
|
||||
versionContract, err = config.ParseContractFromVersion(talosVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid talos-version: %w", err)
|
||||
}
|
||||
|
||||
genOptions = append(genOptions, generate.WithVersionContract(versionContract))
|
||||
}
|
||||
|
||||
configBundle, err := bundle.NewConfigBundle(
|
||||
bundle.WithInputOptions(
|
||||
&bundle.InputOptions{
|
||||
@ -177,6 +190,7 @@ func init() {
|
||||
genConfigCmd.Flags().StringSliceVar(&additionalSANs, "additional-sans", []string{}, "additional Subject-Alt-Names for the APIServer certificate")
|
||||
genConfigCmd.Flags().StringVar(&dnsDomain, "dns-domain", "cluster.local", "the dns domain to use for cluster")
|
||||
genConfigCmd.Flags().StringVar(&configVersion, "version", "v1alpha1", "the desired machine config version to generate")
|
||||
genConfigCmd.Flags().StringVar(&talosVersion, "talos-version", "", "the desired Talos version to generate config for (backwards compatibility, e.g. v0.8)")
|
||||
genConfigCmd.Flags().StringVar(&kubernetesVersion, "kubernetes-version", "", "desired kubernetes version to run")
|
||||
genConfigCmd.Flags().StringVarP(&outputDir, "output-dir", "o", "", "destination to output generated files")
|
||||
genConfigCmd.Flags().StringSliceVar(®istryMirrors, "registry-mirror", []string{}, "list of registry mirrors to use in format: <registry host>=<mirror URL>")
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
machineapi "github.com/talos-systems/talos/pkg/machinery/api/machine"
|
||||
talosclient "github.com/talos-systems/talos/pkg/machinery/client"
|
||||
clientconfig "github.com/talos-systems/talos/pkg/machinery/client/config"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/bundle"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/generate"
|
||||
@ -62,7 +63,6 @@ type upgradeSpec struct {
|
||||
|
||||
UpgradePreserve bool
|
||||
UpgradeStage bool
|
||||
UseRSAKeys bool
|
||||
}
|
||||
|
||||
const (
|
||||
@ -106,7 +106,6 @@ func upgradeBetweenTwoLastReleases() upgradeSpec {
|
||||
|
||||
MasterNodes: DefaultSettings.MasterNodes,
|
||||
WorkerNodes: DefaultSettings.WorkerNodes,
|
||||
UseRSAKeys: true, // ECDSA is supported with Talos >= 0.9
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,7 +126,6 @@ func upgradeStableReleaseToCurrent() upgradeSpec {
|
||||
|
||||
MasterNodes: DefaultSettings.MasterNodes,
|
||||
WorkerNodes: DefaultSettings.WorkerNodes,
|
||||
UseRSAKeys: true, // ECDSA is supported with Talos >= 0.9
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,7 +147,6 @@ func upgradeSingeNodePreserve() upgradeSpec {
|
||||
MasterNodes: 1,
|
||||
WorkerNodes: 0,
|
||||
UpgradePreserve: true,
|
||||
UseRSAKeys: true, // ECDSA is supported with Talos >= 0.9
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,7 +169,6 @@ func upgradeSingeNodeStage() upgradeSpec {
|
||||
WorkerNodes: 0,
|
||||
UpgradePreserve: true,
|
||||
UpgradeStage: true,
|
||||
UseRSAKeys: true, // ECDSA is supported with Talos >= 0.9
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,17 +315,20 @@ func (suite *UpgradeSuite) setupCluster() {
|
||||
}))
|
||||
}
|
||||
|
||||
versionContract, err := config.ParseContractFromVersion(suite.spec.SourceVersion)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
suite.configBundle, err = bundle.NewConfigBundle(bundle.WithInputOptions(
|
||||
&bundle.InputOptions{
|
||||
ClusterName: clusterName,
|
||||
Endpoint: suite.controlPlaneEndpoint,
|
||||
KubeVersion: "", // keep empty so that default version is used per Talos version
|
||||
UseRSAKeys: suite.spec.UseRSAKeys,
|
||||
GenOptions: append(
|
||||
genOptions,
|
||||
generate.WithEndpointList(masterEndpoints),
|
||||
generate.WithInstallImage(suite.spec.SourceInstallerImage),
|
||||
generate.WithDNSDomain("cluster.local"),
|
||||
generate.WithVersionContract(versionContract),
|
||||
),
|
||||
}))
|
||||
suite.Require().NoError(err)
|
||||
|
@ -112,7 +112,7 @@ func Generate(ctx context.Context, in *machine.GenerateConfigurationRequest) (re
|
||||
|
||||
switch {
|
||||
case os.IsNotExist(err):
|
||||
secrets, err = generate.NewSecretsBundle(clock, false)
|
||||
secrets, err = generate.NewSecretsBundle(clock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
74
pkg/machinery/config/contract.go
Normal file
74
pkg/machinery/config/contract.go
Normal file
@ -0,0 +1,74 @@
|
||||
// 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"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// VersionContract describes Talos version to generate config for.
|
||||
//
|
||||
// Config generation only supports backwards compatibility (e.g. Talos 0.9 can generate configs for Talos 0.9 and 0.8).
|
||||
// Matching version of the machinery package is required to generate configs for the current version of Talos.
|
||||
//
|
||||
// Nil value of *VersionContract always describes current version of Talos.
|
||||
type VersionContract struct {
|
||||
Major int
|
||||
Minor int
|
||||
}
|
||||
|
||||
// Well-known Talos version contracts.
|
||||
var (
|
||||
TalosVersionCurrent = (*VersionContract)(nil)
|
||||
TalosVersion0_9 = &VersionContract{0, 9}
|
||||
TalosVersion0_8 = &VersionContract{0, 8}
|
||||
)
|
||||
|
||||
var versionRegexp = regexp.MustCompile(`^v(\d+)\.(\d+)($|\.)`)
|
||||
|
||||
// ParseContractFromVersion parses Talos version into VersionContract.
|
||||
func ParseContractFromVersion(version string) (*VersionContract, error) {
|
||||
matches := versionRegexp.FindStringSubmatch(version)
|
||||
if len(matches) < 3 {
|
||||
return nil, fmt.Errorf("error parsing version %q", version)
|
||||
}
|
||||
|
||||
var contract VersionContract
|
||||
|
||||
contract.Major, _ = strconv.Atoi(matches[1]) //nolint: errcheck
|
||||
contract.Minor, _ = strconv.Atoi(matches[2]) //nolint: errcheck
|
||||
|
||||
return &contract, nil
|
||||
}
|
||||
|
||||
// Greater compares contract to another contract.
|
||||
func (contract *VersionContract) Greater(other *VersionContract) bool {
|
||||
if contract == nil {
|
||||
return other != nil
|
||||
}
|
||||
|
||||
if other == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return contract.Major > other.Major || (contract.Major == other.Major && contract.Minor > other.Minor)
|
||||
}
|
||||
|
||||
// SupportsECDSAKeys returns true if version of Talos supports ECDSA keys (vs. RSA keys).
|
||||
func (contract *VersionContract) SupportsECDSAKeys() bool {
|
||||
return contract.Greater(TalosVersion0_8)
|
||||
}
|
||||
|
||||
// SupportsAggregatorCA returns true if version of Talos supports AggregatorCA in the config.
|
||||
func (contract *VersionContract) SupportsAggregatorCA() bool {
|
||||
return contract.Greater(TalosVersion0_8)
|
||||
}
|
||||
|
||||
// SupportsServiceAccount returns true if version of Talos supports ServiceAccount in the config.
|
||||
func (contract *VersionContract) SupportsServiceAccount() bool {
|
||||
return contract.Greater(TalosVersion0_8)
|
||||
}
|
59
pkg/machinery/config/contract_test.go
Normal file
59
pkg/machinery/config/contract_test.go
Normal file
@ -0,0 +1,59 @@
|
||||
// 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_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/talos-systems/talos/pkg/machinery/config"
|
||||
)
|
||||
|
||||
func TestContractGreater(t *testing.T) {
|
||||
assert.True(t, config.TalosVersion0_9.Greater(config.TalosVersion0_8))
|
||||
assert.True(t, config.TalosVersionCurrent.Greater(config.TalosVersion0_8))
|
||||
assert.True(t, config.TalosVersionCurrent.Greater(config.TalosVersion0_9))
|
||||
|
||||
assert.False(t, config.TalosVersion0_8.Greater(config.TalosVersion0_9))
|
||||
assert.False(t, config.TalosVersion0_8.Greater(config.TalosVersion0_8))
|
||||
assert.False(t, config.TalosVersionCurrent.Greater(config.TalosVersionCurrent))
|
||||
}
|
||||
|
||||
func TestContractParseVersion(t *testing.T) {
|
||||
contract, err := config.ParseContractFromVersion("v0.8")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, config.TalosVersion0_8, contract)
|
||||
|
||||
contract, err = config.ParseContractFromVersion("v0.8.1")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, config.TalosVersion0_8, contract)
|
||||
|
||||
contract, err = config.ParseContractFromVersion("v0.88")
|
||||
assert.NoError(t, err)
|
||||
assert.NotEqual(t, config.TalosVersion0_8, contract)
|
||||
|
||||
contract, err = config.ParseContractFromVersion("v0.8.3-alpha.4")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, config.TalosVersion0_8, contract)
|
||||
}
|
||||
|
||||
func TestContractCurrent(t *testing.T) {
|
||||
assert.True(t, config.TalosVersionCurrent.SupportsAggregatorCA())
|
||||
assert.True(t, config.TalosVersionCurrent.SupportsECDSAKeys())
|
||||
assert.True(t, config.TalosVersionCurrent.SupportsServiceAccount())
|
||||
}
|
||||
|
||||
func TestContract0_9(t *testing.T) {
|
||||
assert.True(t, config.TalosVersion0_9.SupportsAggregatorCA())
|
||||
assert.True(t, config.TalosVersion0_9.SupportsECDSAKeys())
|
||||
assert.True(t, config.TalosVersion0_9.SupportsServiceAccount())
|
||||
}
|
||||
|
||||
func TestContract0_8(t *testing.T) {
|
||||
assert.False(t, config.TalosVersion0_8.SupportsAggregatorCA())
|
||||
assert.False(t, config.TalosVersion0_8.SupportsECDSAKeys())
|
||||
assert.False(t, config.TalosVersion0_8.SupportsServiceAccount())
|
||||
}
|
@ -80,7 +80,7 @@ func NewConfigBundle(opts ...Option) (*v1alpha1.ConfigBundle, error) {
|
||||
fmt.Println("generating PKI and tokens")
|
||||
}
|
||||
|
||||
secrets, err := generate.NewSecretsBundle(generate.NewClock(), options.InputOptions.UseRSAKeys)
|
||||
secrets, err := generate.NewSecretsBundle(generate.NewClock(), options.InputOptions.GenOptions...)
|
||||
if err != nil {
|
||||
return bundle, err
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ type InputOptions struct {
|
||||
Endpoint string
|
||||
KubeVersion string
|
||||
GenOptions []generate.GenOption
|
||||
UseRSAKeys bool
|
||||
}
|
||||
|
||||
// Options describes generate parameters.
|
||||
|
@ -185,7 +185,15 @@ func (c *SystemClock) SetFixedTimestamp(t time.Time) {
|
||||
// NewSecretsBundle creates secrets bundle generating all secrets.
|
||||
//
|
||||
//nolint: gocyclo
|
||||
func NewSecretsBundle(clock Clock, useRSA bool) (*SecretsBundle, error) {
|
||||
func NewSecretsBundle(clock Clock, opts ...GenOption) (*SecretsBundle, error) {
|
||||
options := DefaultGenOptions()
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(&options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
etcd *x509.CertificateAuthority
|
||||
kubernetesCA *x509.CertificateAuthority
|
||||
@ -197,24 +205,28 @@ func NewSecretsBundle(clock Clock, useRSA bool) (*SecretsBundle, error) {
|
||||
err error
|
||||
)
|
||||
|
||||
etcd, err = NewEtcdCA(clock.Now(), useRSA)
|
||||
etcd, err = NewEtcdCA(clock.Now(), !options.VersionContract.SupportsECDSAKeys())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kubernetesCA, err = NewKubernetesCA(clock.Now(), useRSA)
|
||||
kubernetesCA, err = NewKubernetesCA(clock.Now(), !options.VersionContract.SupportsECDSAKeys())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aggregatorCA, err = NewAggregatorCA(clock.Now())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if options.VersionContract.SupportsAggregatorCA() {
|
||||
aggregatorCA, err = NewAggregatorCA(clock.Now())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
serviceAccount, err = x509.NewECDSAKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if options.VersionContract.SupportsServiceAccount() {
|
||||
serviceAccount, err = x509.NewECDSAKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
talosCA, err = NewTalosCA(clock.Now())
|
||||
@ -243,7 +255,7 @@ func NewSecretsBundle(clock Clock, useRSA bool) (*SecretsBundle, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &SecretsBundle{
|
||||
result := &SecretsBundle{
|
||||
Clock: clock,
|
||||
Secrets: kubeadmTokens,
|
||||
TrustdInfo: trustdInfo,
|
||||
@ -256,19 +268,27 @@ func NewSecretsBundle(clock Clock, useRSA bool) (*SecretsBundle, error) {
|
||||
Crt: kubernetesCA.CrtPEM,
|
||||
Key: kubernetesCA.KeyPEM,
|
||||
},
|
||||
K8sAggregator: &x509.PEMEncodedCertificateAndKey{
|
||||
Crt: aggregatorCA.CrtPEM,
|
||||
Key: aggregatorCA.KeyPEM,
|
||||
},
|
||||
K8sServiceAccount: &x509.PEMEncodedKey{
|
||||
Key: serviceAccount.KeyPEM,
|
||||
},
|
||||
OS: &x509.PEMEncodedCertificateAndKey{
|
||||
Crt: talosCA.CrtPEM,
|
||||
Key: talosCA.KeyPEM,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
if aggregatorCA != nil {
|
||||
result.Certs.K8sAggregator = &x509.PEMEncodedCertificateAndKey{
|
||||
Crt: aggregatorCA.CrtPEM,
|
||||
Key: aggregatorCA.KeyPEM,
|
||||
}
|
||||
}
|
||||
|
||||
if serviceAccount != nil {
|
||||
result.Certs.K8sServiceAccount = &x509.PEMEncodedKey{
|
||||
Key: serviceAccount.KeyPEM,
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// NewSecretsBundleFromConfig creates secrets bundle using existing config.
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/talos-systems/talos/pkg/machinery/config"
|
||||
genv1alpha1 "github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/generate"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/machine"
|
||||
"github.com/talos-systems/talos/pkg/machinery/constants"
|
||||
@ -17,18 +18,42 @@ import (
|
||||
type GenerateSuite struct {
|
||||
suite.Suite
|
||||
|
||||
input *genv1alpha1.Input
|
||||
input *genv1alpha1.Input
|
||||
genOptions []genv1alpha1.GenOption
|
||||
}
|
||||
|
||||
func TestGenerateSuite(t *testing.T) {
|
||||
suite.Run(t, new(GenerateSuite))
|
||||
for _, tt := range []struct {
|
||||
label string
|
||||
genOptions []genv1alpha1.GenOption
|
||||
}{
|
||||
{
|
||||
label: "current",
|
||||
},
|
||||
{
|
||||
label: "0.9",
|
||||
genOptions: []genv1alpha1.GenOption{genv1alpha1.WithVersionContract(config.TalosVersion0_9)},
|
||||
},
|
||||
{
|
||||
label: "0.8",
|
||||
genOptions: []genv1alpha1.GenOption{genv1alpha1.WithVersionContract(config.TalosVersion0_8)},
|
||||
},
|
||||
} {
|
||||
tt := tt
|
||||
|
||||
t.Run(tt.label, func(t *testing.T) {
|
||||
suite.Run(t, &GenerateSuite{
|
||||
genOptions: tt.genOptions,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *GenerateSuite) SetupSuite() {
|
||||
var err error
|
||||
secrets, err := genv1alpha1.NewSecretsBundle(genv1alpha1.NewClock(), false)
|
||||
secrets, err := genv1alpha1.NewSecretsBundle(genv1alpha1.NewClock(), suite.genOptions...)
|
||||
suite.Require().NoError(err)
|
||||
suite.input, err = genv1alpha1.NewInput("test", "10.0.1.5", constants.DefaultKubernetesVersion, secrets)
|
||||
suite.input, err = genv1alpha1.NewInput("test", "10.0.1.5", constants.DefaultKubernetesVersion, secrets, suite.genOptions...)
|
||||
suite.Require().NoError(err)
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"github.com/talos-systems/talos/pkg/machinery/config"
|
||||
v1alpha1 "github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1"
|
||||
)
|
||||
|
||||
@ -153,6 +154,15 @@ func WithAllowSchedulingOnMasters(enabled bool) GenOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithVersionContract specifies version contract to use when generating.
|
||||
func WithVersionContract(versionContract *config.VersionContract) GenOption {
|
||||
return func(o *GenOptions) error {
|
||||
o.VersionContract = versionContract
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// GenOptions describes generate parameters.
|
||||
type GenOptions struct {
|
||||
EndpointList []string
|
||||
@ -169,6 +179,7 @@ type GenOptions struct {
|
||||
Persist bool
|
||||
AllowSchedulingOnMasters bool
|
||||
MachineDisks []*v1alpha1.MachineDisk
|
||||
VersionContract *config.VersionContract
|
||||
}
|
||||
|
||||
// DefaultGenOptions returns default options.
|
||||
|
@ -108,6 +108,7 @@ talosctl cluster create [flags]
|
||||
--registry-mirror strings list of registry mirrors to use in format: <registry host>=<mirror URL>
|
||||
--skip-injecting-config skip injecting config from embedded metadata server, write config files to current directory
|
||||
--skip-kubeconfig skip merging kubeconfig from the created cluster
|
||||
--talos-version string the desired Talos version to generate config for (if not set, defaults to image version)
|
||||
--user-disk strings list of disks to create for each VM in format: <mount_point1>:<size1>:<mount_point2>:<size2>
|
||||
--vmlinuz-path string the compressed kernel image to use (default "_out/vmlinuz-${ARCH}")
|
||||
--wait wait for the cluster to be ready before returning (default true)
|
||||
@ -854,6 +855,7 @@ talosctl gen config <cluster name> <cluster endpoint> [flags]
|
||||
-o, --output-dir string destination to output generated files
|
||||
-p, --persist the desired persist value for configs (default true)
|
||||
--registry-mirror strings list of registry mirrors to use in format: <registry host>=<mirror URL>
|
||||
--talos-version string the desired Talos version to generate config for (backwards compatibility, e.g. v0.8)
|
||||
--version string the desired machine config version to generate (default "v1alpha1")
|
||||
```
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user