mirror of
				https://github.com/siderolabs/talos.git
				synced 2025-11-04 10:21:13 +01:00 
			
		
		
		
	chore: handle documents diff in apply-config dry run
				
					
				
			Before this PR diff generator only diffed the v1alpha1 config and nothing else. With this PR it also takes
separate docs into the account.
```shell
~ > <editor> controlplane.yaml
~ > talosctl -n talos-default-controlplane-1  apply-config --file controlplane.yaml --dry-run
Dry run summary:
Applied configuration without a reboot (skipped in dry-run).
Config diff:
No changes.
Documents diff:
[]config.Document{
+	&runtime.KmsgLogV1Alpha1{
+		Meta:       meta.Meta{MetaAPIVersion: "v1alpha1", MetaKind: "KmsgLogConfig"},
+		MetaName:   "omni-kmsg",
+		KmsgLogURL: s"tcp://[fdae:41e4:649b:9303::1]:8092",
+	},
}
~ > talosctl -n talos-default-controlplane-1  apply-config --file controlplane.yaml
Applied configuration without a reboot
~ >
~ >
~ >
~ > <editor> controlplane.yaml
~ > talosctl -n talos-default-controlplane-1  apply-config --file controlplane.yaml --dry-run
Dry run summary:
Applied configuration without a reboot (skipped in dry-run).
Config diff:
No changes.
Documents diff:
[]config.Document{
	&runtime.KmsgLogV1Alpha1{Meta: {MetaAPIVersion: "v1alpha1", MetaKind: "KmsgLogConfig"}, MetaName: "omni-kmsg", KmsgLogURL: {URL: &{Scheme: "tcp", Host: "[fdae:41e4:649b:9303::1]:8092"}}},
+	&network.DefaultActionConfigV1Alpha1{
+		Meta:    meta.Meta{MetaAPIVersion: "v1alpha1", MetaKind: "NetworkDefaultActionConfig"},
+		Ingress: s"block",
+	},
}
```
Closes #8885
Signed-off-by: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com>
			
			
This commit is contained in:
		
							parent
							
								
									bd34f71f3e
								
							
						
					
					
						commit
						2d054ad355
					
				@ -43,7 +43,7 @@ var applyConfigCmd = &cobra.Command{
 | 
				
			|||||||
	RunE: func(cmd *cobra.Command, args []string) error {
 | 
						RunE: func(cmd *cobra.Command, args []string) error {
 | 
				
			||||||
		var (
 | 
							var (
 | 
				
			||||||
			cfgBytes []byte
 | 
								cfgBytes []byte
 | 
				
			||||||
			e        error
 | 
								err      error
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if len(args) > 0 {
 | 
							if len(args) > 0 {
 | 
				
			||||||
@ -59,9 +59,9 @@ var applyConfigCmd = &cobra.Command{
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if applyConfigCmdFlags.filename != "" {
 | 
							if applyConfigCmdFlags.filename != "" {
 | 
				
			||||||
			cfgBytes, e = os.ReadFile(applyConfigCmdFlags.filename)
 | 
								cfgBytes, err = os.ReadFile(applyConfigCmdFlags.filename)
 | 
				
			||||||
			if e != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return fmt.Errorf("failed to read configuration from %q: %w", applyConfigCmdFlags.filename, e)
 | 
									return fmt.Errorf("failed to read configuration from %q: %w", applyConfigCmdFlags.filename, err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if len(cfgBytes) < 1 {
 | 
								if len(cfgBytes) < 1 {
 | 
				
			||||||
@ -74,19 +74,19 @@ var applyConfigCmd = &cobra.Command{
 | 
				
			|||||||
					patches []configpatcher.Patch
 | 
										patches []configpatcher.Patch
 | 
				
			||||||
				)
 | 
									)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				patches, e = configpatcher.LoadPatches(applyConfigCmdFlags.patches)
 | 
									patches, err = configpatcher.LoadPatches(applyConfigCmdFlags.patches)
 | 
				
			||||||
				if e != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return e
 | 
										return err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				cfg, e = configpatcher.Apply(configpatcher.WithBytes(cfgBytes), patches)
 | 
									cfg, err = configpatcher.Apply(configpatcher.WithBytes(cfgBytes), patches)
 | 
				
			||||||
				if e != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return e
 | 
										return err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				cfgBytes, e = cfg.Bytes()
 | 
									cfgBytes, err = cfg.Bytes()
 | 
				
			||||||
				if e != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return e
 | 
										return err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else if applyConfigCmdFlags.Mode.Mode != helpers.InteractiveMode {
 | 
							} else if applyConfigCmdFlags.Mode.Mode != helpers.InteractiveMode {
 | 
				
			||||||
@ -108,8 +108,10 @@ var applyConfigCmd = &cobra.Command{
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				if len(GlobalArgs.Endpoints) > 0 {
 | 
									if len(GlobalArgs.Endpoints) > 0 {
 | 
				
			||||||
					return WithClientNoNodes(func(bootstrapCtx context.Context, bootstrapClient *client.Client) error {
 | 
										return WithClientNoNodes(func(bootstrapCtx context.Context, bootstrapClient *client.Client) error {
 | 
				
			||||||
						opts := []installer.Option{}
 | 
											opts := []installer.Option{
 | 
				
			||||||
						opts = append(opts, installer.WithBootstrapNode(bootstrapCtx, bootstrapClient, GlobalArgs.Endpoints[0]), installer.WithDryRun(applyConfigCmdFlags.dryRun))
 | 
												installer.WithBootstrapNode(bootstrapCtx, bootstrapClient, GlobalArgs.Endpoints[0]),
 | 
				
			||||||
 | 
												installer.WithDryRun(applyConfigCmdFlags.dryRun),
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						conn, err := installer.NewConnection(
 | 
											conn, err := installer.NewConnection(
 | 
				
			||||||
							ctx,
 | 
												ctx,
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,7 @@ import (
 | 
				
			|||||||
	"archive/tar"
 | 
						"archive/tar"
 | 
				
			||||||
	"bufio"
 | 
						"bufio"
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
 | 
						stdcmp "cmp"
 | 
				
			||||||
	"compress/gzip"
 | 
						"compress/gzip"
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
@ -76,6 +77,8 @@ import (
 | 
				
			|||||||
	"github.com/siderolabs/talos/pkg/machinery/api/storage"
 | 
						"github.com/siderolabs/talos/pkg/machinery/api/storage"
 | 
				
			||||||
	timeapi "github.com/siderolabs/talos/pkg/machinery/api/time"
 | 
						timeapi "github.com/siderolabs/talos/pkg/machinery/api/time"
 | 
				
			||||||
	clientconfig "github.com/siderolabs/talos/pkg/machinery/client/config"
 | 
						clientconfig "github.com/siderolabs/talos/pkg/machinery/client/config"
 | 
				
			||||||
 | 
						"github.com/siderolabs/talos/pkg/machinery/config"
 | 
				
			||||||
 | 
						docscfg "github.com/siderolabs/talos/pkg/machinery/config/config"
 | 
				
			||||||
	"github.com/siderolabs/talos/pkg/machinery/config/configloader"
 | 
						"github.com/siderolabs/talos/pkg/machinery/config/configloader"
 | 
				
			||||||
	"github.com/siderolabs/talos/pkg/machinery/config/generate/secrets"
 | 
						"github.com/siderolabs/talos/pkg/machinery/config/generate/secrets"
 | 
				
			||||||
	machinetype "github.com/siderolabs/talos/pkg/machinery/config/machine"
 | 
						machinetype "github.com/siderolabs/talos/pkg/machinery/config/machine"
 | 
				
			||||||
@ -218,15 +221,7 @@ func (s *Server) ApplyConfiguration(ctx context.Context, in *machine.ApplyConfig
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if in.DryRun {
 | 
						if in.DryRun {
 | 
				
			||||||
		var config interface{}
 | 
							details := generateDiff(s.Controller.Runtime(), cfgProvider)
 | 
				
			||||||
		if s.Controller.Runtime().Config() != nil {
 | 
					 | 
				
			||||||
			config = s.Controller.Runtime().ConfigContainer().RawV1Alpha1()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		diff := cmp.Diff(config, cfgProvider.RawV1Alpha1(), cmp.AllowUnexported(v1alpha1.InstallDiskSizeMatcher{}))
 | 
					 | 
				
			||||||
		if diff == "" {
 | 
					 | 
				
			||||||
			diff = "No changes."
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return &machine.ApplyConfigurationResponse{
 | 
							return &machine.ApplyConfigurationResponse{
 | 
				
			||||||
			Messages: []*machine.ApplyConfiguration{
 | 
								Messages: []*machine.ApplyConfiguration{
 | 
				
			||||||
@ -234,8 +229,7 @@ func (s *Server) ApplyConfiguration(ctx context.Context, in *machine.ApplyConfig
 | 
				
			|||||||
					Mode: in.Mode,
 | 
										Mode: in.Mode,
 | 
				
			||||||
					ModeDetails: fmt.Sprintf(`Dry run summary:
 | 
										ModeDetails: fmt.Sprintf(`Dry run summary:
 | 
				
			||||||
%s (skipped in dry-run).
 | 
					%s (skipped in dry-run).
 | 
				
			||||||
Config diff:
 | 
					%s`, modeDetails, details),
 | 
				
			||||||
%s`, modeDetails, diff),
 | 
					 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		}, nil
 | 
							}, nil
 | 
				
			||||||
@ -301,6 +295,35 @@ Config diff:
 | 
				
			|||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func generateDiff(r runtime.Runtime, provider config.Provider) string {
 | 
				
			||||||
 | 
						var cfg *v1alpha1.Config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if r.Config() != nil {
 | 
				
			||||||
 | 
							cfg = r.ConfigContainer().RawV1Alpha1()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						v1alpha1Diff := cmp.Diff(cfg, provider.RawV1Alpha1(), cmp.AllowUnexported(v1alpha1.InstallDiskSizeMatcher{}))
 | 
				
			||||||
 | 
						if v1alpha1Diff == "" {
 | 
				
			||||||
 | 
							v1alpha1Diff = "No changes."
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						origDocs := slices.DeleteFunc(r.ConfigContainer().Documents(), func(doc docscfg.Document) bool { return doc.Kind() == v1alpha1.Version })
 | 
				
			||||||
 | 
						newDocs := slices.DeleteFunc(provider.Documents(), func(doc docscfg.Document) bool { return doc.Kind() == v1alpha1.Version })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						slices.SortStableFunc(origDocs, func(a, b docscfg.Document) int { return stdcmp.Compare(a.Kind(), b.Kind()) })
 | 
				
			||||||
 | 
						slices.SortStableFunc(newDocs, func(a, b docscfg.Document) int { return stdcmp.Compare(a.Kind(), b.Kind()) })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						documentsDiff := cmp.Diff(origDocs, newDocs)
 | 
				
			||||||
 | 
						if documentsDiff == "" {
 | 
				
			||||||
 | 
							documentsDiff = "No changes."
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return fmt.Sprintf(`Config diff:
 | 
				
			||||||
 | 
					%s
 | 
				
			||||||
 | 
					Documents diff:
 | 
				
			||||||
 | 
					%s`, v1alpha1Diff, documentsDiff)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GenerateConfiguration implements the machine.MachineServer interface.
 | 
					// GenerateConfiguration implements the machine.MachineServer interface.
 | 
				
			||||||
func (s *Server) GenerateConfiguration(ctx context.Context, in *machine.GenerateConfigurationRequest) (reply *machine.GenerateConfigurationResponse, err error) {
 | 
					func (s *Server) GenerateConfiguration(ctx context.Context, in *machine.GenerateConfigurationRequest) (reply *machine.GenerateConfigurationResponse, err error) {
 | 
				
			||||||
	if s.Controller.Runtime().Config().Machine().Type() == machinetype.TypeWorker {
 | 
						if s.Controller.Runtime().Config().Machine().Type() == machinetype.TypeWorker {
 | 
				
			||||||
 | 
				
			|||||||
@ -8,12 +8,14 @@ package api
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"sort"
 | 
						"slices"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/cosi-project/runtime/pkg/safe"
 | 
						"github.com/cosi-project/runtime/pkg/safe"
 | 
				
			||||||
 | 
						"github.com/siderolabs/gen/ensure"
 | 
				
			||||||
	"github.com/siderolabs/go-pointer"
 | 
						"github.com/siderolabs/go-pointer"
 | 
				
			||||||
	"github.com/siderolabs/go-retry/retry"
 | 
						"github.com/siderolabs/go-retry/retry"
 | 
				
			||||||
	"google.golang.org/grpc/codes"
 | 
						"google.golang.org/grpc/codes"
 | 
				
			||||||
@ -23,7 +25,9 @@ import (
 | 
				
			|||||||
	machineapi "github.com/siderolabs/talos/pkg/machinery/api/machine"
 | 
						machineapi "github.com/siderolabs/talos/pkg/machinery/api/machine"
 | 
				
			||||||
	"github.com/siderolabs/talos/pkg/machinery/client"
 | 
						"github.com/siderolabs/talos/pkg/machinery/client"
 | 
				
			||||||
	"github.com/siderolabs/talos/pkg/machinery/config"
 | 
						"github.com/siderolabs/talos/pkg/machinery/config"
 | 
				
			||||||
 | 
						"github.com/siderolabs/talos/pkg/machinery/config/container"
 | 
				
			||||||
	"github.com/siderolabs/talos/pkg/machinery/config/machine"
 | 
						"github.com/siderolabs/talos/pkg/machinery/config/machine"
 | 
				
			||||||
 | 
						"github.com/siderolabs/talos/pkg/machinery/config/types/runtime"
 | 
				
			||||||
	"github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1"
 | 
						"github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1"
 | 
				
			||||||
	"github.com/siderolabs/talos/pkg/machinery/constants"
 | 
						"github.com/siderolabs/talos/pkg/machinery/constants"
 | 
				
			||||||
	mc "github.com/siderolabs/talos/pkg/machinery/resources/config"
 | 
						mc "github.com/siderolabs/talos/pkg/machinery/resources/config"
 | 
				
			||||||
@ -88,14 +92,13 @@ func (suite *ApplyConfigSuite) TestApply() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	suite.WaitForBootDone(suite.ctx)
 | 
						suite.WaitForBootDone(suite.ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sort.Strings(nodes)
 | 
						slices.Sort(nodes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	node := nodes[0]
 | 
						node := nodes[0]
 | 
				
			||||||
 | 
					 | 
				
			||||||
	nodeCtx := client.WithNode(suite.ctx, node)
 | 
						nodeCtx := client.WithNode(suite.ctx, node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	provider, err := suite.ReadConfigFromNode(nodeCtx)
 | 
						provider, err := suite.ReadConfigFromNode(nodeCtx)
 | 
				
			||||||
	suite.Assert().Nilf(err, "failed to read existing config from node %q: %w", node, err)
 | 
						suite.Assert().NoErrorf(err, "failed to read existing config from node %q: %w", node, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cfgDataOut := suite.PatchV1Alpha1Config(provider, func(cfg *v1alpha1.Config) {
 | 
						cfgDataOut := suite.PatchV1Alpha1Config(provider, func(cfg *v1alpha1.Config) {
 | 
				
			||||||
		if cfg.MachineConfig.MachineSysctls == nil {
 | 
							if cfg.MachineConfig.MachineSysctls == nil {
 | 
				
			||||||
@ -115,7 +118,7 @@ func (suite *ApplyConfigSuite) TestApply() {
 | 
				
			|||||||
			)
 | 
								)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				// It is expected that the connection will EOF here, so just log the error
 | 
									// It is expected that the connection will EOF here, so just log the error
 | 
				
			||||||
				suite.Assert().Nilf(err, "failed to apply configuration (node %q): %w", node, err)
 | 
									suite.Assert().NoErrorf(err, "failed to apply configuration (node %q): %w", node, err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return nil
 | 
								return nil
 | 
				
			||||||
@ -125,7 +128,7 @@ func (suite *ApplyConfigSuite) TestApply() {
 | 
				
			|||||||
	// Verify configuration change
 | 
						// Verify configuration change
 | 
				
			||||||
	var newProvider config.Provider
 | 
						var newProvider config.Provider
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	suite.Require().Nilf(
 | 
						suite.Require().NoErrorf(
 | 
				
			||||||
		retry.Constant(time.Minute, retry.WithUnits(time.Second)).Retry(
 | 
							retry.Constant(time.Minute, retry.WithUnits(time.Second)).Retry(
 | 
				
			||||||
			func() error {
 | 
								func() error {
 | 
				
			||||||
				newProvider, err = suite.ReadConfigFromNode(nodeCtx)
 | 
									newProvider, err = suite.ReadConfigFromNode(nodeCtx)
 | 
				
			||||||
@ -300,7 +303,7 @@ func (suite *ApplyConfigSuite) TestApplyConfigRotateEncryptionSecrets() {
 | 
				
			|||||||
				)
 | 
									)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					// It is expected that the connection will EOF here, so just log the error
 | 
										// It is expected that the connection will EOF here, so just log the error
 | 
				
			||||||
					suite.Assert().Nilf(err, "failed to apply configuration (node %q): %w", node, err)
 | 
										suite.Assert().Errorf(err, "failed to apply configuration (node %q): %w", node, err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				return nil
 | 
									return nil
 | 
				
			||||||
@ -312,7 +315,7 @@ func (suite *ApplyConfigSuite) TestApplyConfigRotateEncryptionSecrets() {
 | 
				
			|||||||
		// Verify configuration change
 | 
							// Verify configuration change
 | 
				
			||||||
		var newProvider config.Provider
 | 
							var newProvider config.Provider
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		suite.Require().Nilf(
 | 
							suite.Require().Errorf(
 | 
				
			||||||
			retry.Constant(time.Minute, retry.WithUnits(time.Second)).Retry(
 | 
								retry.Constant(time.Minute, retry.WithUnits(time.Second)).Retry(
 | 
				
			||||||
				func() error {
 | 
									func() error {
 | 
				
			||||||
					newProvider, err = suite.ReadConfigFromNode(nodeCtx)
 | 
										newProvider, err = suite.ReadConfigFromNode(nodeCtx)
 | 
				
			||||||
@ -355,14 +358,13 @@ func (suite *ApplyConfigSuite) TestApplyNoReboot() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	suite.WaitForBootDone(suite.ctx)
 | 
						suite.WaitForBootDone(suite.ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sort.Strings(nodes)
 | 
						slices.Sort(nodes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	node := nodes[0]
 | 
						node := nodes[0]
 | 
				
			||||||
 | 
					 | 
				
			||||||
	nodeCtx := client.WithNode(suite.ctx, node)
 | 
						nodeCtx := client.WithNode(suite.ctx, node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	provider, err := suite.ReadConfigFromNode(nodeCtx)
 | 
						provider, err := suite.ReadConfigFromNode(nodeCtx)
 | 
				
			||||||
	suite.Require().Nilf(err, "failed to read existing config from node %q: %s", node, err)
 | 
						suite.Require().NoErrorf(err, "failed to read existing config from node %q: %s", node, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cfgDataOut := suite.PatchV1Alpha1Config(provider, func(cfg *v1alpha1.Config) {
 | 
						cfgDataOut := suite.PatchV1Alpha1Config(provider, func(cfg *v1alpha1.Config) {
 | 
				
			||||||
		// this won't be possible without a reboot
 | 
							// this won't be possible without a reboot
 | 
				
			||||||
@ -387,14 +389,13 @@ func (suite *ApplyConfigSuite) TestApplyDryRun() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	suite.WaitForBootDone(suite.ctx)
 | 
						suite.WaitForBootDone(suite.ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sort.Strings(nodes)
 | 
						slices.Sort(nodes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	node := nodes[0]
 | 
						node := nodes[0]
 | 
				
			||||||
 | 
					 | 
				
			||||||
	nodeCtx := client.WithNode(suite.ctx, node)
 | 
						nodeCtx := client.WithNode(suite.ctx, node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	provider, err := suite.ReadConfigFromNode(nodeCtx)
 | 
						provider, err := suite.ReadConfigFromNode(nodeCtx)
 | 
				
			||||||
	suite.Require().Nilf(err, "failed to read existing config from node %q: %s", node, err)
 | 
						suite.Require().NoErrorf(err, "failed to read existing config from node %q: %s", node, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cfgDataOut := suite.PatchV1Alpha1Config(provider, func(cfg *v1alpha1.Config) {
 | 
						cfgDataOut := suite.PatchV1Alpha1Config(provider, func(cfg *v1alpha1.Config) {
 | 
				
			||||||
		// this won't be possible without a reboot
 | 
							// this won't be possible without a reboot
 | 
				
			||||||
@ -416,10 +417,49 @@ func (suite *ApplyConfigSuite) TestApplyDryRun() {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	suite.Require().Nilf(err, "failed to apply configuration (node %q): %s", node, err)
 | 
						suite.Require().NoErrorf(err, "failed to apply configuration (node %q): %s", node, err)
 | 
				
			||||||
	suite.Assert().Contains(reply.Messages[0].ModeDetails, "Dry run summary")
 | 
						suite.Assert().Contains(reply.Messages[0].ModeDetails, "Dry run summary")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TestApplyDryRunDocuments verifies the apply config API with multi doc and dry run enabled.
 | 
				
			||||||
 | 
					func (suite *ApplyConfigSuite) TestApplyDryRunDocuments() {
 | 
				
			||||||
 | 
						nodes := suite.DiscoverNodeInternalIPsByType(suite.ctx, machine.TypeWorker)
 | 
				
			||||||
 | 
						suite.Require().NotEmpty(nodes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						suite.WaitForBootDone(suite.ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						slices.Sort(nodes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						node := nodes[0]
 | 
				
			||||||
 | 
						nodeCtx := client.WithNode(suite.ctx, node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						provider, err := suite.ReadConfigFromNode(nodeCtx)
 | 
				
			||||||
 | 
						suite.Require().NoErrorf(err, "failed to read existing config from node %q: %s", node, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kmsg := runtime.NewKmsgLogV1Alpha1()
 | 
				
			||||||
 | 
						kmsg.MetaName = "omni-kmsg"
 | 
				
			||||||
 | 
						kmsg.KmsgLogURL.URL = ensure.Value(url.Parse("tcp://[fdae:41e4:649b:9303::1]:8092"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cont, err := container.New(provider.RawV1Alpha1(), kmsg)
 | 
				
			||||||
 | 
						suite.Require().NoErrorf(err, "failed to create container: %s", err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cfgDataOut, err := cont.Bytes()
 | 
				
			||||||
 | 
						suite.Require().NoErrorf(err, "failed to marshal container: %s", err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reply, err := suite.Client.ApplyConfiguration(
 | 
				
			||||||
 | 
							nodeCtx, &machineapi.ApplyConfigurationRequest{
 | 
				
			||||||
 | 
								Data:   cfgDataOut,
 | 
				
			||||||
 | 
								Mode:   machineapi.ApplyConfigurationRequest_AUTO,
 | 
				
			||||||
 | 
								DryRun: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						suite.Require().NoErrorf(err, "failed to apply configuration (node %q): %s", node, err)
 | 
				
			||||||
 | 
						suite.Assert().Contains(reply.Messages[0].ModeDetails, "Dry run summary")
 | 
				
			||||||
 | 
						suite.Assert().Contains(reply.Messages[0].ModeDetails, "omni-kmsg")
 | 
				
			||||||
 | 
						suite.Assert().Contains(reply.Messages[0].ModeDetails, "tcp://[fdae:41e4:649b:9303::1]:8092")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TestApplyTry applies the config in try mode with a short timeout.
 | 
					// TestApplyTry applies the config in try mode with a short timeout.
 | 
				
			||||||
func (suite *ApplyConfigSuite) TestApplyTry() {
 | 
					func (suite *ApplyConfigSuite) TestApplyTry() {
 | 
				
			||||||
	nodes := suite.DiscoverNodeInternalIPsByType(suite.ctx, machine.TypeWorker)
 | 
						nodes := suite.DiscoverNodeInternalIPsByType(suite.ctx, machine.TypeWorker)
 | 
				
			||||||
@ -427,10 +467,9 @@ func (suite *ApplyConfigSuite) TestApplyTry() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	suite.WaitForBootDone(suite.ctx)
 | 
						suite.WaitForBootDone(suite.ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sort.Strings(nodes)
 | 
						slices.Sort(nodes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	node := nodes[0]
 | 
						node := nodes[0]
 | 
				
			||||||
 | 
					 | 
				
			||||||
	nodeCtx := client.WithNode(suite.ctx, node)
 | 
						nodeCtx := client.WithNode(suite.ctx, node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	getMachineConfig := func(ctx context.Context) (*mc.MachineConfig, error) {
 | 
						getMachineConfig := func(ctx context.Context) (*mc.MachineConfig, error) {
 | 
				
			||||||
@ -443,7 +482,7 @@ func (suite *ApplyConfigSuite) TestApplyTry() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	provider, err := getMachineConfig(nodeCtx)
 | 
						provider, err := getMachineConfig(nodeCtx)
 | 
				
			||||||
	suite.Require().Nilf(err, "failed to read existing config from node %q: %s", node, err)
 | 
						suite.Require().NoErrorf(err, "failed to read existing config from node %q: %s", node, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cfgDataOut := suite.PatchV1Alpha1Config(provider.Provider(), func(cfg *v1alpha1.Config) {
 | 
						cfgDataOut := suite.PatchV1Alpha1Config(provider.Provider(), func(cfg *v1alpha1.Config) {
 | 
				
			||||||
		if cfg.MachineConfig.MachineNetwork == nil {
 | 
							if cfg.MachineConfig.MachineNetwork == nil {
 | 
				
			||||||
@ -465,10 +504,10 @@ func (suite *ApplyConfigSuite) TestApplyTry() {
 | 
				
			|||||||
			TryModeTimeout: durationpb.New(time.Second * 1),
 | 
								TryModeTimeout: durationpb.New(time.Second * 1),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	suite.Assert().Nilf(err, "failed to apply configuration (node %q): %s", node, err)
 | 
						suite.Assert().NoErrorf(err, "failed to apply configuration (node %q): %s", node, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	provider, err = getMachineConfig(nodeCtx)
 | 
						provider, err = getMachineConfig(nodeCtx)
 | 
				
			||||||
	suite.Require().Nilf(err, "failed to read existing config from node %q: %w", node, err)
 | 
						suite.Require().NoErrorf(err, "failed to read existing config from node %q: %w", node, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	suite.Assert().NotNil(provider.Config().Machine().Network())
 | 
						suite.Assert().NotNil(provider.Config().Machine().Network())
 | 
				
			||||||
	suite.Assert().NotNil(provider.Config().Machine().Network().Devices())
 | 
						suite.Assert().NotNil(provider.Config().Machine().Network().Devices())
 | 
				
			||||||
@ -487,7 +526,7 @@ func (suite *ApplyConfigSuite) TestApplyTry() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for range 100 {
 | 
						for range 100 {
 | 
				
			||||||
		provider, err = getMachineConfig(nodeCtx)
 | 
							provider, err = getMachineConfig(nodeCtx)
 | 
				
			||||||
		suite.Assert().Nilf(err, "failed to read existing config from node %q: %s", node, err)
 | 
							suite.Assert().NoErrorf(err, "failed to read existing config from node %q: %s", node, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if provider.Config().Machine().Network() == nil {
 | 
							if provider.Config().Machine().Network() == nil {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user