diff --git a/api/resource/definitions/runtime/runtime.proto b/api/resource/definitions/runtime/runtime.proto index 225c663aed..cee2954515 100755 --- a/api/resource/definitions/runtime/runtime.proto +++ b/api/resource/definitions/runtime/runtime.proto @@ -17,6 +17,22 @@ message EventSinkConfigSpec { string endpoint = 1; } +// ExtensionServicesConfigFile describes extensions service config files. +message ExtensionServicesConfigFile { + string content = 1; + string mount_path = 2; +} + +// ExtensionServicesConfigSpec describes status of rendered extensions service config files. +message ExtensionServicesConfigSpec { + repeated ExtensionServicesConfigFile files = 2; +} + +// ExtensionServicesConfigStatusSpec describes status of rendered extensions service config files. +message ExtensionServicesConfigStatusSpec { + string spec_version = 1; +} + // KernelModuleSpecSpec describes Linux kernel module to load. message KernelModuleSpecSpec { string name = 1; diff --git a/hack/release.toml b/hack/release.toml index 8a6c553448..a7bd283397 100644 --- a/hack/release.toml +++ b/hack/release.toml @@ -61,6 +61,24 @@ Talos Linux starting from this release uses RSA key for Kubernetes API Server Se title = "OpenNebula" description = """\ Talos Linux now supports OpenNebula platform. +""" + + [notes.extensions] + title = "Extension Services Config" + description = """\ +Talos now supports supplying configuration files for extension services that can be mounted into the extension service container. +The extension service configuration is a separate config document. An example is shown below: + +```yaml +--- +apiVersion: v1alpha1 +kind: ExtensionServicesConfig +config: + - name: nut-client + configFiles: + - content: MONITOR ${upsmonHost} 1 remote pass password + mountPath: /usr/local/etc/nut/upsmon.conf +``` """ [make_deps] diff --git a/internal/app/machined/pkg/controllers/cri/seccomp_profile.go b/internal/app/machined/pkg/controllers/cri/seccomp_profile.go index 7d42dc826c..d41213d3be 100644 --- a/internal/app/machined/pkg/controllers/cri/seccomp_profile.go +++ b/internal/app/machined/pkg/controllers/cri/seccomp_profile.go @@ -18,7 +18,7 @@ import ( "github.com/siderolabs/talos/pkg/machinery/resources/cri" ) -// SeccompProfileController manages v1alpha1.Stats which is the current snaphot of the machine CPU and Memory consumption. +// SeccompProfileController manages SeccompProfiles. type SeccompProfileController struct{} // Name implements controller.StatsController interface. diff --git a/internal/app/machined/pkg/controllers/cri/seccomp_profile_test.go b/internal/app/machined/pkg/controllers/cri/seccomp_profile_test.go index 2404a9d4e7..054fc49ddb 100644 --- a/internal/app/machined/pkg/controllers/cri/seccomp_profile_test.go +++ b/internal/app/machined/pkg/controllers/cri/seccomp_profile_test.go @@ -85,29 +85,6 @@ func (suite *CRISeccompProfileSuite) TestReconcileSeccompProfile() { }) } - suite.AssertWithin(1*time.Second, 100*time.Millisecond, func() error { - seccompProfile, err := ctest.Get[*criseccompresource.SeccompProfile]( - suite, - criseccompresource.NewSeccompProfile("audit.json").Metadata(), - ) - if err != nil { - if state.IsNotFoundError(err) { - return retry.ExpectedError(err) - } - - return err - } - - spec := seccompProfile.TypedSpec() - - suite.Assert().Equal("audit.json", spec.Name) - suite.Assert().Equal(map[string]interface{}{ - "defaultAction": "SCMP_ACT_LOG", - }, spec.Value) - - return nil - }) - // test deletion cfg = config.NewMachineConfig(container.NewV1Alpha1(&v1alpha1.Config{ MachineConfig: &v1alpha1.MachineConfig{ diff --git a/internal/app/machined/pkg/controllers/runtime/extension_service.go b/internal/app/machined/pkg/controllers/runtime/extension_service.go index b44fbc3954..4a5a298f98 100644 --- a/internal/app/machined/pkg/controllers/runtime/extension_service.go +++ b/internal/app/machined/pkg/controllers/runtime/extension_service.go @@ -11,17 +11,21 @@ import ( "path/filepath" "github.com/cosi-project/runtime/pkg/controller" + "github.com/cosi-project/runtime/pkg/safe" "go.uber.org/zap" "gopkg.in/yaml.v3" "github.com/siderolabs/talos/internal/app/machined/pkg/system" "github.com/siderolabs/talos/internal/app/machined/pkg/system/services" extservices "github.com/siderolabs/talos/pkg/machinery/extensions/services" + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" ) // ServiceManager is the interface to the v1alpha1 services subsystems. type ServiceManager interface { + IsRunning(id string) (system.Service, bool, error) Load(services ...system.Service) []string + Stop(ctx context.Context, serviceIDs ...string) (err error) Start(serviceIDs ...string) error } @@ -29,6 +33,8 @@ type ServiceManager interface { type ExtensionServiceController struct { V1Alpha1Services ServiceManager ConfigPath string + + configStatusCache map[string]string } // Name implements controller.Controller interface. @@ -38,7 +44,13 @@ func (ctrl *ExtensionServiceController) Name() string { // Inputs implements controller.Controller interface. func (ctrl *ExtensionServiceController) Inputs() []controller.Input { - return nil + return []controller.Input{ + { + Namespace: runtime.NamespaceName, + Type: runtime.ExtensionServicesConfigStatusType, + Kind: controller.InputStrong, + }, + } } // Outputs implements controller.Controller interface. @@ -48,15 +60,16 @@ func (ctrl *ExtensionServiceController) Outputs() []controller.Output { // Run implements controller.Controller interface. // -//nolint:gocyclo +//nolint:gocyclo,cyclop func (ctrl *ExtensionServiceController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { + // wait for controller runtime to be ready select { case <-ctx.Done(): return nil case <-r.EventCh(): } - // controller runs only once, as services are static + // extensions loading only needs to run once, as services are static serviceFiles, err := os.ReadDir(ctrl.ConfigPath) if err != nil { if os.IsNotExist(err) { @@ -69,6 +82,21 @@ func (ctrl *ExtensionServiceController) Run(ctx context.Context, r controller.Ru return err } + // load initial state of configStatuses + if ctrl.configStatusCache == nil { + configStatuses, err := safe.ReaderListAll[*runtime.ExtensionServicesConfigStatus](ctx, r) + if err != nil { + return fmt.Errorf("error listing extension services config: %w", err) + } + + ctrl.configStatusCache = make(map[string]string, configStatuses.Len()) + + for iter := configStatuses.Iterator(); iter.Next(); { + ctrl.configStatusCache[iter.Value().Metadata().ID()] = iter.Value().TypedSpec().SpecVersion + } + } + + // load services from definitions into the service runner framework extServices := map[string]struct{}{} for _, serviceFile := range serviceFiles { @@ -110,7 +138,46 @@ func (ctrl *ExtensionServiceController) Run(ctx context.Context, r controller.Ru } } - return nil + // watch for changes in the configStatuses + for { + select { + case <-ctx.Done(): + return nil + case <-r.EventCh(): + } + + configStatuses, err := safe.ReaderListAll[*runtime.ExtensionServicesConfigStatus](ctx, r) + if err != nil { + return fmt.Errorf("error listing extension services config: %w", err) + } + + configStatusesPresent := map[string]struct{}{} + + for iter := configStatuses.Iterator(); iter.Next(); { + configStatusesPresent[iter.Value().Metadata().ID()] = struct{}{} + + if ctrl.configStatusCache[iter.Value().Metadata().ID()] == iter.Value().TypedSpec().SpecVersion { + continue + } + + if err = ctrl.handleRestart(ctx, logger, "ext-"+iter.Value().Metadata().ID(), iter.Value().TypedSpec().SpecVersion); err != nil { + return err + } + + ctrl.configStatusCache[iter.Value().Metadata().ID()] = iter.Value().TypedSpec().SpecVersion + } + + // cleanup configStatusesCache + for id := range ctrl.configStatusCache { + if _, ok := configStatusesPresent[id]; !ok { + if err = ctrl.handleRestart(ctx, logger, "ext-"+id, "nan"); err != nil { + return err + } + + delete(ctrl.configStatusCache, id) + } + } + } } func (ctrl *ExtensionServiceController) loadSpec(path string) (extservices.Spec, error) { @@ -129,3 +196,30 @@ func (ctrl *ExtensionServiceController) loadSpec(path string) (extservices.Spec, return spec, nil } + +func (ctrl *ExtensionServiceController) handleRestart(ctx context.Context, logger *zap.Logger, svcName, specVersion string) error { + _, running, err := ctrl.V1Alpha1Services.IsRunning(svcName) + if err != nil { + return nil //nolint:nilerr // IsRunning returns an error only if the service is not found, so ignore it + } + + // this means it's a new config and the service runner is already waiting for the config to start the service + // we don't need restart it again since it will be started automatically + if running && specVersion == "1" { + return nil + } + + logger.Warn("extension service config changed, restarting", zap.String("service", svcName)) + + if running { + if err = ctrl.V1Alpha1Services.Stop(ctx, svcName); err != nil { + return fmt.Errorf("error stopping extension service %s: %w", svcName, err) + } + } + + if err = ctrl.V1Alpha1Services.Start(svcName); err != nil { + return fmt.Errorf("error starting extension service %s: %w", svcName, err) + } + + return nil +} diff --git a/internal/app/machined/pkg/controllers/runtime/extension_service_test.go b/internal/app/machined/pkg/controllers/runtime/extension_service_test.go index a33b5d5eff..5ee27c7936 100644 --- a/internal/app/machined/pkg/controllers/runtime/extension_service_test.go +++ b/internal/app/machined/pkg/controllers/runtime/extension_service_test.go @@ -4,6 +4,7 @@ package runtime_test import ( + "context" "fmt" "reflect" "sort" @@ -17,6 +18,7 @@ import ( runtimecontrollers "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/runtime" "github.com/siderolabs/talos/internal/app/machined/pkg/system" "github.com/siderolabs/talos/internal/app/machined/pkg/system/services" + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" ) type ExtensionServiceSuite struct { @@ -24,8 +26,11 @@ type ExtensionServiceSuite struct { } type serviceMock struct { - mu sync.Mutex - services map[string]system.Service + mu sync.Mutex + services map[string]system.Service + running map[string]bool + timesStarted map[string]int + timesStopped map[string]int } func (mock *serviceMock) Load(services ...system.Service) []string { @@ -43,6 +48,40 @@ func (mock *serviceMock) Load(services ...system.Service) []string { } func (mock *serviceMock) Start(serviceIDs ...string) error { + mock.mu.Lock() + defer mock.mu.Unlock() + + for _, id := range serviceIDs { + mock.running[id] = true + mock.timesStarted[id]++ + } + + return nil +} + +func (mock *serviceMock) IsRunning(id string) (system.Service, bool, error) { + mock.mu.Lock() + defer mock.mu.Unlock() + + svc, exists := mock.services[id] + if !exists { + return nil, false, fmt.Errorf("service %q not found", id) + } + + _, running := mock.running[id] + + return svc, running, nil +} + +func (mock *serviceMock) Stop(ctx context.Context, serviceIDs ...string) error { + mock.mu.Lock() + defer mock.mu.Unlock() + + for _, id := range serviceIDs { + mock.running[id] = false + mock.timesStopped[id]++ + } + return nil } @@ -61,6 +100,27 @@ func (mock *serviceMock) getIDs() []string { return ids } +type serviceStartStopInfo struct { + started int + stopped int +} + +func (mock *serviceMock) getTimesStartedStopped() map[string]serviceStartStopInfo { + mock.mu.Lock() + defer mock.mu.Unlock() + + result := map[string]serviceStartStopInfo{} + + for id := range mock.services { + result[id] = serviceStartStopInfo{ + started: mock.timesStarted[id], + stopped: mock.timesStopped[id], + } + } + + return result +} + func (mock *serviceMock) get(id string) system.Service { mock.mu.Lock() defer mock.mu.Unlock() @@ -70,7 +130,10 @@ func (mock *serviceMock) get(id string) system.Service { func (suite *ExtensionServiceSuite) TestReconcile() { svcMock := &serviceMock{ - services: map[string]system.Service{}, + services: map[string]system.Service{}, + running: map[string]bool{}, + timesStarted: map[string]int{}, + timesStopped: map[string]int{}, } suite.Require().NoError(suite.runtime.RegisterController(&runtimecontrollers.ExtensionServiceController{ @@ -84,8 +147,8 @@ func (suite *ExtensionServiceSuite) TestReconcile() { func() error { ids := svcMock.getIDs() - if !reflect.DeepEqual(ids, []string{"ext-hello-world"}) { - return retry.ExpectedError(fmt.Errorf("services registered: %q", ids)) + if !reflect.DeepEqual(ids, []string{"ext-frr", "ext-hello-world"}) { + return retry.ExpectedErrorf("services registered: %q", ids) } return nil @@ -96,6 +159,88 @@ func (suite *ExtensionServiceSuite) TestReconcile() { suite.Require().IsType(&services.Extension{}, helloSvc) suite.Assert().Equal("./hello-world", helloSvc.(*services.Extension).Spec.Container.Entrypoint) + + suite.Assert().Equal( + map[string]serviceStartStopInfo{ + "ext-hello-world": { + started: 1, + }, + "ext-frr": { + started: 1, + }, + }, + svcMock.getTimesStartedStopped(), + ) + + helloConfig := runtime.NewExtensionServicesConfigStatusSpec(runtime.NamespaceName, "hello-world") + helloConfig.TypedSpec().SpecVersion = "1" + suite.Require().NoError(suite.state.Create(suite.ctx, helloConfig)) + + assertTimesStartedStopped := func(expected map[string]serviceStartStopInfo) { + suite.Assert().NoError(retry.Constant(5*time.Second, retry.WithUnits(100*time.Millisecond)).Retry( + func() error { + actual := svcMock.getTimesStartedStopped() + + if !reflect.DeepEqual(actual, expected) { + return retry.ExpectedErrorf("services restart status expected %v, actual %v", expected, actual) + } + + return nil + }, + )) + } + + // specVersion is 1, and ext-hello-world is already started, so it should not be restarted + assertTimesStartedStopped(map[string]serviceStartStopInfo{ + "ext-hello-world": { + started: 1, + stopped: 0, + }, + "ext-frr": { + started: 1, + }, + }) + + unexpectedConfig := runtime.NewExtensionServicesConfigStatusSpec(runtime.NamespaceName, "unexpected") + unexpectedConfig.TypedSpec().SpecVersion = "1" + suite.Require().NoError(suite.state.Create(suite.ctx, unexpectedConfig)) + + assertTimesStartedStopped(map[string]serviceStartStopInfo{ + "ext-hello-world": { + started: 1, + stopped: 0, + }, + "ext-frr": { + started: 1, + }, + }) + + // update config for hello service + helloConfig.TypedSpec().SpecVersion = "2" + suite.Require().NoError(suite.state.Update(suite.ctx, helloConfig)) + + assertTimesStartedStopped(map[string]serviceStartStopInfo{ + "ext-hello-world": { + started: 2, + stopped: 1, + }, + "ext-frr": { + started: 1, + }, + }) + + // destroy config for hello service + suite.Require().NoError(suite.state.Destroy(suite.ctx, helloConfig.Metadata())) + + assertTimesStartedStopped(map[string]serviceStartStopInfo{ + "ext-hello-world": { + started: 3, + stopped: 2, + }, + "ext-frr": { + started: 1, + }, + }) } func TestExtensionServiceSuite(t *testing.T) { diff --git a/internal/app/machined/pkg/controllers/runtime/extension_services_config.go b/internal/app/machined/pkg/controllers/runtime/extension_services_config.go new file mode 100644 index 0000000000..cdfde84e45 --- /dev/null +++ b/internal/app/machined/pkg/controllers/runtime/extension_services_config.go @@ -0,0 +1,92 @@ +// 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 runtime + +import ( + "context" + "fmt" + + "github.com/cosi-project/runtime/pkg/controller" + "github.com/cosi-project/runtime/pkg/safe" + "github.com/cosi-project/runtime/pkg/state" + "github.com/siderolabs/gen/optional" + "github.com/siderolabs/gen/xslices" + "go.uber.org/zap" + + extconfig "github.com/siderolabs/talos/pkg/machinery/config/config" + "github.com/siderolabs/talos/pkg/machinery/resources/config" + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" +) + +// ExtensionServicesConfigController watches v1alpha1.Config, creates/updates/deletes extension services config. +type ExtensionServicesConfigController struct{} + +// Name implements controller.Controller interface. +func (ctrl *ExtensionServicesConfigController) Name() string { + return "runtime.ExtensionServicesConfigController" +} + +// Inputs implements controller.Controller interface. +func (ctrl *ExtensionServicesConfigController) Inputs() []controller.Input { + return []controller.Input{ + { + Namespace: config.NamespaceName, + Type: config.MachineConfigType, + ID: optional.Some(config.V1Alpha1ID), + Kind: controller.InputWeak, + }, + } +} + +// Outputs implements controller.Controller interface. +func (ctrl *ExtensionServicesConfigController) Outputs() []controller.Output { + return []controller.Output{ + { + Type: runtime.ExtensionServicesConfigType, + Kind: controller.OutputExclusive, + }, + } +} + +// Run implements controller.Controller interface. +// +//nolint:gocyclo +func (ctrl *ExtensionServicesConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { + for { + select { + case <-ctx.Done(): + return nil + case <-r.EventCh(): + } + + cfg, err := safe.ReaderGetByID[*config.MachineConfig](ctx, r, config.V1Alpha1ID) + if err != nil && !state.IsNotFoundError(err) { + return fmt.Errorf("error getting machine config: %w", err) + } + + r.StartTrackingOutputs() + + if cfg != nil && cfg.Config() != nil && cfg.Config().ExtensionServicesConfig() != nil { + for _, ext := range cfg.Config().ExtensionServicesConfig().ConfigData() { + if err = safe.WriterModify(ctx, r, runtime.NewExtensionServicesConfigSpec(runtime.NamespaceName, ext.Name()), func(spec *runtime.ExtensionServicesConfig) error { + spec.TypedSpec().Files = xslices.Map(ext.ConfigFiles(), func(c extconfig.ExtensionServicesConfigFile) runtime.ExtensionServicesConfigFile { + return runtime.ExtensionServicesConfigFile{ + Content: c.Content(), + MountPath: c.Path(), + } + }) + + return nil + }); err != nil { + return err + } + } + } + + if err = safe.CleanupOutputs[*runtime.ExtensionServicesConfig](ctx, r); err != nil { + return err + } + } +} diff --git a/internal/app/machined/pkg/controllers/runtime/extension_services_config_files.go b/internal/app/machined/pkg/controllers/runtime/extension_services_config_files.go new file mode 100644 index 0000000000..db81756eef --- /dev/null +++ b/internal/app/machined/pkg/controllers/runtime/extension_services_config_files.go @@ -0,0 +1,124 @@ +// 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 runtime + +import ( + "context" + "fmt" + "io/fs" + "os" + "path/filepath" + "strings" + + "github.com/cosi-project/runtime/pkg/controller" + "github.com/cosi-project/runtime/pkg/safe" + "go.uber.org/zap" + + v1alpha1runtime "github.com/siderolabs/talos/internal/app/machined/pkg/runtime" + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" +) + +// ExtensionServicesConfigFilesController writes down the config files for extension services. +type ExtensionServicesConfigFilesController struct { + V1Alpha1Mode v1alpha1runtime.Mode + ExtensionsConfigBaseDir string +} + +// Name implements controller.Controller interface. +func (ctrl *ExtensionServicesConfigFilesController) Name() string { + return "runtime.ExtensionServicesConfigFilesController" +} + +// Inputs implements controller.Controller interface. +func (ctrl *ExtensionServicesConfigFilesController) Inputs() []controller.Input { + return []controller.Input{ + { + Namespace: runtime.NamespaceName, + Type: runtime.ExtensionServicesConfigType, + Kind: controller.InputStrong, + }, + } +} + +// Outputs implements controller.Controller interface. +func (ctrl *ExtensionServicesConfigFilesController) Outputs() []controller.Output { + return []controller.Output{ + { + Type: runtime.ExtensionServicesConfigStatusType, + Kind: controller.OutputExclusive, + }, + } +} + +// Run implements controller.Controller interface. +// +//nolint:gocyclo +func (ctrl *ExtensionServicesConfigFilesController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { + if ctrl.V1Alpha1Mode == v1alpha1runtime.ModeContainer { + return nil + } + + for { + select { + case <-ctx.Done(): + return nil + case <-r.EventCh(): + } + + list, err := safe.ReaderListAll[*runtime.ExtensionServicesConfig](ctx, r) + if err != nil { + return fmt.Errorf("error listing extension services config: %w", err) + } + + r.StartTrackingOutputs() + + touchedFiles := map[string]struct{}{} + + for iter := list.Iterator(); iter.Next(); { + extensionConfigPath := filepath.Join(ctrl.ExtensionsConfigBaseDir, iter.Value().Metadata().ID()) + + if err = os.MkdirAll(extensionConfigPath, 0o755); err != nil { + return fmt.Errorf("error creating directory %q: %w", extensionConfigPath, err) + } + + touchedFiles[extensionConfigPath] = struct{}{} + + for _, file := range iter.Value().TypedSpec().Files { + fileName := filepath.Join(extensionConfigPath, strings.ReplaceAll(strings.TrimPrefix(file.MountPath, "/"), "/", "-")) + + if err = updateFile(fileName, []byte(file.Content), 0o644); err != nil { + return fmt.Errorf("error writing file %q: %w", fileName, err) + } + + touchedFiles[fileName] = struct{}{} + } + + if err = safe.WriterModify(ctx, r, runtime.NewExtensionServicesConfigStatusSpec(runtime.NamespaceName, iter.Value().Metadata().ID()), func(spec *runtime.ExtensionServicesConfigStatus) error { + spec.TypedSpec().SpecVersion = iter.Value().Metadata().Version().String() + + return nil + }); err != nil { + return err + } + } + + // remove all files not managed by us + if err = filepath.WalkDir(ctrl.ExtensionsConfigBaseDir, func(path string, d fs.DirEntry, walkErr error) error { + if _, ok := touchedFiles[path]; path != ctrl.ExtensionsConfigBaseDir && !ok { + if err = os.RemoveAll(path); err != nil { + return err + } + } + + return nil + }); err != nil { + return err + } + + if err = safe.CleanupOutputs[*runtime.ExtensionServicesConfigStatus](ctx, r); err != nil { + return err + } + } +} diff --git a/internal/app/machined/pkg/controllers/runtime/extension_services_config_files_test.go b/internal/app/machined/pkg/controllers/runtime/extension_services_config_files_test.go new file mode 100644 index 0000000000..1b752d66f7 --- /dev/null +++ b/internal/app/machined/pkg/controllers/runtime/extension_services_config_files_test.go @@ -0,0 +1,129 @@ +// 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 runtime_test + +import ( + "os" + "path/filepath" + "strings" + "testing" + + "github.com/siderolabs/gen/xslices" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + + "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/ctest" + "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/runtime" + runtimeres "github.com/siderolabs/talos/pkg/machinery/resources/runtime" +) + +type ExtensionServicesConfigFilesSuite struct { + ctest.DefaultSuite + extensionsConfigDir string +} + +func TestExtensionServicesConfigFilesSuite(t *testing.T) { + extensionsConfigDir := t.TempDir() + + suite.Run(t, &ExtensionServicesConfigFilesSuite{ + DefaultSuite: ctest.DefaultSuite{ + AfterSetup: func(suite *ctest.DefaultSuite) { + suite.Require().NoError(suite.Runtime().RegisterController(&runtime.ExtensionServicesConfigFilesController{ + ExtensionsConfigBaseDir: extensionsConfigDir, + })) + }, + }, + extensionsConfigDir: extensionsConfigDir, + }) +} + +func (suite *ExtensionServicesConfigFilesSuite) TestReconcileExtensionServicesConfigFiles() { + for _, tt := range []struct { + extensionName string + configFiles []struct { + content string + mountPath string + } + }{ + { + extensionName: "test-extension-a", + configFiles: []struct { + content string + mountPath string + }{ + { + content: "test-content-a", + mountPath: "/etc/test", + }, + }, + }, + { + extensionName: "test-extension-b", + configFiles: []struct { + content string + mountPath string + }{ + { + content: "test-content-b", + mountPath: "/etc/bar", + }, + { + content: "test-content-c", + mountPath: "/var/etc/foo", + }, + }, + }, + } { + extensionServicesConfigFiles := runtimeres.NewExtensionServicesConfigSpec(runtimeres.NamespaceName, tt.extensionName) + extensionServicesConfigFiles.TypedSpec().Files = xslices.Map(tt.configFiles, func(config struct { + content string + mountPath string + }, + ) runtimeres.ExtensionServicesConfigFile { + return runtimeres.ExtensionServicesConfigFile{ + Content: config.content, + MountPath: config.mountPath, + } + }) + + suite.Require().NoError(suite.State().Create(suite.Ctx(), extensionServicesConfigFiles)) + + ctest.AssertResource(suite, tt.extensionName, + func(status *runtimeres.ExtensionServicesConfigStatus, asrt *assert.Assertions) { + asrt.Equal(extensionServicesConfigFiles.Metadata().Version().String(), status.TypedSpec().SpecVersion) + }, + ) + + for _, file := range tt.configFiles { + content, err := os.ReadFile(filepath.Join(suite.extensionsConfigDir, tt.extensionName, strings.ReplaceAll(strings.TrimPrefix(file.mountPath, "/"), "/", "-"))) + suite.Require().NoError(err) + + suite.Assert().Equal(file.content, string(content)) + } + } + + // create a directory and file manually in the extensions config directory + // ensure that the controller deletes the manually created directory/file + // also ensure that an update doesn't update existing files timestamp + suite.Assert().NoError(os.Mkdir(filepath.Join(suite.extensionsConfigDir, "test"), 0o755)) + suite.Assert().NoError(os.WriteFile(filepath.Join(suite.extensionsConfigDir, "test", "testdata"), []byte("{}"), 0o644)) + + extensionAConfigFileInfo, err := os.Stat(filepath.Join(suite.extensionsConfigDir, "test-extension-a", "etc-test")) + suite.Assert().NoError(err) + + // delete test-extension-b resource + suite.Assert().NoError(suite.State().Destroy(suite.Ctx(), runtimeres.NewExtensionServicesConfigSpec(runtimeres.NamespaceName, "test-extension-b").Metadata())) + ctest.AssertNoResource[*runtimeres.ExtensionServicesConfigStatus](suite, "test-extension-b") + + suite.Assert().NoFileExists(filepath.Join(suite.extensionsConfigDir, "test", "testdata")) + suite.Assert().NoDirExists(filepath.Join(suite.extensionsConfigDir, "test")) + suite.Assert().NoFileExists(filepath.Join(suite.extensionsConfigDir, "test-extension-b", "etc-bar")) + suite.Assert().NoFileExists(filepath.Join(suite.extensionsConfigDir, "test-extension-b", "var-etc-foo")) + suite.Assert().NoDirExists(filepath.Join(suite.extensionsConfigDir, "test-extension-b")) + + extensionAConfigFileInfoAfterUpdate, err := os.Stat(filepath.Join(suite.extensionsConfigDir, "test-extension-a", "etc-test")) + suite.Require().NoError(err) + + suite.Assert().Equal(extensionAConfigFileInfo.ModTime(), extensionAConfigFileInfoAfterUpdate.ModTime()) +} diff --git a/internal/app/machined/pkg/controllers/runtime/extension_services_config_test.go b/internal/app/machined/pkg/controllers/runtime/extension_services_config_test.go new file mode 100644 index 0000000000..207415c676 --- /dev/null +++ b/internal/app/machined/pkg/controllers/runtime/extension_services_config_test.go @@ -0,0 +1,133 @@ +// 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 runtime_test + +import ( + "testing" + + "github.com/siderolabs/gen/xslices" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + + "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/ctest" + "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/runtime" + "github.com/siderolabs/talos/pkg/machinery/config/container" + "github.com/siderolabs/talos/pkg/machinery/config/types/extensionservicesconfig" + "github.com/siderolabs/talos/pkg/machinery/resources/config" + runtimeres "github.com/siderolabs/talos/pkg/machinery/resources/runtime" +) + +type ExtensionServicesConfigSuite struct { + ctest.DefaultSuite +} + +func TestExtensionServicesConfigSuite(t *testing.T) { + suite.Run(t, &ExtensionServicesConfigSuite{ + DefaultSuite: ctest.DefaultSuite{ + AfterSetup: func(suite *ctest.DefaultSuite) { + suite.Require().NoError(suite.Runtime().RegisterController(&runtime.ExtensionServicesConfigController{})) + }, + }, + }) +} + +func (suite *ExtensionServicesConfigSuite) TestReconcileExtensionServicesConfig() { + extensionsServiceConfigDoc := extensionservicesconfig.NewExtensionServicesConfigV1Alpha1() + extensionsServiceConfigDoc.Config = []extensionservicesconfig.ExtensionServiceConfig{ + { + ExtensionName: "test-extension-a", + ExtensionServiceConfigFiles: []extensionservicesconfig.ExtensionServiceConfigFile{ + { + ExtensionContent: "test-content-a", + ExtensionMountPath: "/etc/test", + }, + }, + }, + { + ExtensionName: "test-extension-b", + ExtensionServiceConfigFiles: []extensionservicesconfig.ExtensionServiceConfigFile{ + { + ExtensionContent: "test-content-b", + ExtensionMountPath: "/etc/bar", + }, + { + ExtensionContent: "test-content-c", + ExtensionMountPath: "/var/etc/foo", + }, + }, + }, + } + + cntr, err := container.New(extensionsServiceConfigDoc) + suite.Require().NoError(err) + + cfg := config.NewMachineConfig(cntr) + suite.Require().NoError(suite.State().Create(suite.Ctx(), cfg)) + + for _, tt := range []struct { + extensionName string + configFiles []struct { + content string + mountPath string + } + }{ + { + extensionName: "test-extension-a", + configFiles: []struct { + content string + mountPath string + }{ + { + content: "test-content-a", + mountPath: "/etc/test", + }, + }, + }, + { + extensionName: "test-extension-b", + configFiles: []struct { + content string + mountPath string + }{ + { + content: "test-content-b", + mountPath: "/etc/bar", + }, + { + content: "test-content-c", + mountPath: "/var/etc/foo", + }, + }, + }, + } { + ctest.AssertResource(suite, tt.extensionName, func(config *runtimeres.ExtensionServicesConfig, asrt *assert.Assertions) { + spec := config.TypedSpec() + + configFileData := xslices.Map(tt.configFiles, func(config struct { + content string + mountPath string + }, + ) runtimeres.ExtensionServicesConfigFile { + return runtimeres.ExtensionServicesConfigFile{ + Content: config.content, + MountPath: config.mountPath, + } + }) + + suite.Assert().Equal(configFileData, spec.Files) + }) + } + + // test deletion + extensionsServiceConfigDoc.Config = extensionsServiceConfigDoc.Config[1:] // remove first extension service config + cntr, err = container.New(extensionsServiceConfigDoc) + suite.Require().NoError(err) + + newCfg := config.NewMachineConfig(cntr) + newCfg.Metadata().SetVersion(cfg.Metadata().Version()) + suite.Require().NoError(suite.State().Update(suite.Ctx(), cfg)) + + ctest.AssertNoResource[*runtimeres.ExtensionServicesConfig](suite, "test-extension-a") +} diff --git a/internal/app/machined/pkg/controllers/runtime/testdata/extservices/frr.yaml b/internal/app/machined/pkg/controllers/runtime/testdata/extservices/frr.yaml new file mode 100644 index 0000000000..7cfd66a6c8 --- /dev/null +++ b/internal/app/machined/pkg/controllers/runtime/testdata/extservices/frr.yaml @@ -0,0 +1,10 @@ +name: frr +container: + entrypoint: ./frr + args: + - --msg + - BGP FRR +depends: + - network: + - addresses +restart: always diff --git a/internal/app/machined/pkg/controllers/runtime/utils.go b/internal/app/machined/pkg/controllers/runtime/utils.go index 06c0db47cb..579fc8a727 100644 --- a/internal/app/machined/pkg/controllers/runtime/utils.go +++ b/internal/app/machined/pkg/controllers/runtime/utils.go @@ -5,7 +5,9 @@ package runtime import ( + "bytes" "context" + "os" "github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/safe" @@ -63,3 +65,14 @@ func WaitForDevicesReady(ctx context.Context, r controller.Runtime, nextInputs [ return nil } + +// updateFile is like `os.WriteFile`, but it will only update the file if the +// contents have changed. +func updateFile(filename string, contents []byte, mode os.FileMode) error { + oldContents, err := os.ReadFile(filename) + if err == nil && bytes.Equal(oldContents, contents) { + return nil + } + + return os.WriteFile(filename, contents, mode) +} diff --git a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go index 06c9434dcd..8da0247564 100644 --- a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go +++ b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go @@ -253,6 +253,11 @@ func (ctrl *Controller) Run(ctx context.Context, drainer *runtime.Drainer) error &runtimecontrollers.DropUpgradeFallbackController{ MetaProvider: ctrl.v1alpha1Runtime.State().Machine(), }, + &runtimecontrollers.ExtensionServicesConfigController{}, + &runtimecontrollers.ExtensionServicesConfigFilesController{ + V1Alpha1Mode: ctrl.v1alpha1Runtime.State().Platform().Mode(), + ExtensionsConfigBaseDir: constants.ExtensionServicesUserConfigPath, + }, &runtimecontrollers.EventsSinkConfigController{ Cmdline: procfs.ProcCmdline(), V1Alpha1Mode: ctrl.v1alpha1Runtime.State().Platform().Mode(), diff --git a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go index 56b10eeb61..fa8531d0f2 100644 --- a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go +++ b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go @@ -172,6 +172,8 @@ func NewState() (*State, error) { &perf.Memory{}, &runtime.DevicesStatus{}, &runtime.EventSinkConfig{}, + &runtime.ExtensionServicesConfig{}, + &runtime.ExtensionServicesConfigStatus{}, &runtime.ExtensionStatus{}, &runtime.KernelModuleSpec{}, &runtime.KernelParamSpec{}, diff --git a/internal/app/machined/pkg/system/services/export_test.go b/internal/app/machined/pkg/system/services/export_test.go index c839b83ec9..bea149cba6 100644 --- a/internal/app/machined/pkg/system/services/export_test.go +++ b/internal/app/machined/pkg/system/services/export_test.go @@ -13,5 +13,5 @@ func (svc *Extension) GetOCIOptions() ([]oci.SpecOpts, error) { return nil, err } - return svc.getOCIOptions(envVars), nil + return svc.getOCIOptions(envVars, svc.Spec.Container.Mounts), nil } diff --git a/internal/app/machined/pkg/system/services/extension.go b/internal/app/machined/pkg/system/services/extension.go index 15fec230dd..2221531509 100644 --- a/internal/app/machined/pkg/system/services/extension.go +++ b/internal/app/machined/pkg/system/services/extension.go @@ -10,8 +10,11 @@ import ( "fmt" "os" "path/filepath" + "strings" "github.com/containerd/containerd/oci" + "github.com/cosi-project/runtime/pkg/safe" + "github.com/cosi-project/runtime/pkg/state" "github.com/hashicorp/go-envparse" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/siderolabs/gen/maps" @@ -28,6 +31,7 @@ import ( "github.com/siderolabs/talos/pkg/machinery/constants" extservices "github.com/siderolabs/talos/pkg/machinery/extensions/services" "github.com/siderolabs/talos/pkg/machinery/resources/network" + runtimeres "github.com/siderolabs/talos/pkg/machinery/resources/runtime" "github.com/siderolabs/talos/pkg/machinery/resources/time" ) @@ -80,6 +84,8 @@ func (svc *Extension) Condition(r runtime.Runtime) conditions.Condition { conds = append(conds, network.NewReadyCondition(r.State().V1Alpha2().Resources(), network.StatusChecksFromStatuses(dep.Network...)...)) case dep.Time: conds = append(conds, time.NewSyncCondition(r.State().V1Alpha2().Resources())) + case dep.Configuration: + conds = append(conds, runtimeres.NewExtensionServiceConfigStatusCondition(r.State().V1Alpha2().Resources(), svc.Spec.Name)) } } @@ -103,12 +109,12 @@ func (svc *Extension) DependsOn(r runtime.Runtime) []string { return deps } -func (svc *Extension) getOCIOptions(envVars []string) []oci.SpecOpts { +func (svc *Extension) getOCIOptions(envVars []string, mounts []specs.Mount) []oci.SpecOpts { ociOpts := []oci.SpecOpts{ oci.WithRootFSPath(filepath.Join(constants.ExtensionServicesRootfsPath, svc.Spec.Name)), containerd.WithRootfsPropagation(svc.Spec.Container.Security.RootfsPropagation), oci.WithCgroup(filepath.Join(constants.CgroupExtensions, svc.Spec.Name)), - oci.WithMounts(svc.Spec.Container.Mounts), + oci.WithMounts(mounts), oci.WithHostNamespace(specs.NetworkNamespace), oci.WithSelinuxLabel(""), oci.WithApparmorProfile(""), @@ -137,6 +143,8 @@ func (svc *Extension) getOCIOptions(envVars []string) []oci.SpecOpts { } // Runner implements the Service interface. +// +//nolint:gocyclo func (svc *Extension) Runner(r runtime.Runtime) (runner.Runner, error) { args := runner.Args{ ID: svc.ID(r), @@ -156,6 +164,24 @@ func (svc *Extension) Runner(r runtime.Runtime) (runner.Runner, error) { } } + mounts := append([]specs.Mount{}, svc.Spec.Container.Mounts...) + + configSpec, err := safe.StateGetByID[*runtimeres.ExtensionServicesConfig](context.Background(), r.State().V1Alpha2().Resources(), svc.Spec.Name) + if err == nil { + spec := configSpec.TypedSpec() + + for _, ext := range spec.Files { + mounts = append(mounts, specs.Mount{ + Source: filepath.Join(constants.ExtensionServicesUserConfigPath, svc.Spec.Name, strings.ReplaceAll(strings.TrimPrefix(ext.MountPath, "/"), "/", "-")), + Destination: ext.MountPath, + Type: "bind", + Options: []string{"ro", "bind"}, + }) + } + } else if !state.IsNotFoundError(err) { + return nil, err + } + var restartType restart.Type switch svc.Spec.Restart { @@ -172,7 +198,7 @@ func (svc *Extension) Runner(r runtime.Runtime) (runner.Runner, error) { return nil, err } - ociSpecOpts := svc.getOCIOptions(envVars) + ociSpecOpts := svc.getOCIOptions(envVars, mounts) debug := false diff --git a/pkg/machinery/api/resource/definitions/runtime/runtime.pb.go b/pkg/machinery/api/resource/definitions/runtime/runtime.pb.go index ee80fccd85..a185491f7a 100644 --- a/pkg/machinery/api/resource/definitions/runtime/runtime.pb.go +++ b/pkg/machinery/api/resource/definitions/runtime/runtime.pb.go @@ -120,6 +120,158 @@ func (x *EventSinkConfigSpec) GetEndpoint() string { return "" } +// ExtensionServicesConfigFile describes extensions service config files. +type ExtensionServicesConfigFile struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Content string `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` + MountPath string `protobuf:"bytes,2,opt,name=mount_path,json=mountPath,proto3" json:"mount_path,omitempty"` +} + +func (x *ExtensionServicesConfigFile) Reset() { + *x = ExtensionServicesConfigFile{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExtensionServicesConfigFile) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExtensionServicesConfigFile) ProtoMessage() {} + +func (x *ExtensionServicesConfigFile) ProtoReflect() protoreflect.Message { + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExtensionServicesConfigFile.ProtoReflect.Descriptor instead. +func (*ExtensionServicesConfigFile) Descriptor() ([]byte, []int) { + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{2} +} + +func (x *ExtensionServicesConfigFile) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *ExtensionServicesConfigFile) GetMountPath() string { + if x != nil { + return x.MountPath + } + return "" +} + +// ExtensionServicesConfigSpec describes status of rendered extensions service config files. +type ExtensionServicesConfigSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Files []*ExtensionServicesConfigFile `protobuf:"bytes,2,rep,name=files,proto3" json:"files,omitempty"` +} + +func (x *ExtensionServicesConfigSpec) Reset() { + *x = ExtensionServicesConfigSpec{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExtensionServicesConfigSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExtensionServicesConfigSpec) ProtoMessage() {} + +func (x *ExtensionServicesConfigSpec) ProtoReflect() protoreflect.Message { + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExtensionServicesConfigSpec.ProtoReflect.Descriptor instead. +func (*ExtensionServicesConfigSpec) Descriptor() ([]byte, []int) { + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{3} +} + +func (x *ExtensionServicesConfigSpec) GetFiles() []*ExtensionServicesConfigFile { + if x != nil { + return x.Files + } + return nil +} + +// ExtensionServicesConfigStatusSpec describes status of rendered extensions service config files. +type ExtensionServicesConfigStatusSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SpecVersion string `protobuf:"bytes,1,opt,name=spec_version,json=specVersion,proto3" json:"spec_version,omitempty"` +} + +func (x *ExtensionServicesConfigStatusSpec) Reset() { + *x = ExtensionServicesConfigStatusSpec{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExtensionServicesConfigStatusSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExtensionServicesConfigStatusSpec) ProtoMessage() {} + +func (x *ExtensionServicesConfigStatusSpec) ProtoReflect() protoreflect.Message { + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExtensionServicesConfigStatusSpec.ProtoReflect.Descriptor instead. +func (*ExtensionServicesConfigStatusSpec) Descriptor() ([]byte, []int) { + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{4} +} + +func (x *ExtensionServicesConfigStatusSpec) GetSpecVersion() string { + if x != nil { + return x.SpecVersion + } + return "" +} + // KernelModuleSpecSpec describes Linux kernel module to load. type KernelModuleSpecSpec struct { state protoimpl.MessageState @@ -133,7 +285,7 @@ type KernelModuleSpecSpec struct { func (x *KernelModuleSpecSpec) Reset() { *x = KernelModuleSpecSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[2] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -146,7 +298,7 @@ func (x *KernelModuleSpecSpec) String() string { func (*KernelModuleSpecSpec) ProtoMessage() {} func (x *KernelModuleSpecSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[2] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -159,7 +311,7 @@ func (x *KernelModuleSpecSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use KernelModuleSpecSpec.ProtoReflect.Descriptor instead. func (*KernelModuleSpecSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{2} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{5} } func (x *KernelModuleSpecSpec) GetName() string { @@ -189,7 +341,7 @@ type KernelParamSpecSpec struct { func (x *KernelParamSpecSpec) Reset() { *x = KernelParamSpecSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[3] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -202,7 +354,7 @@ func (x *KernelParamSpecSpec) String() string { func (*KernelParamSpecSpec) ProtoMessage() {} func (x *KernelParamSpecSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[3] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -215,7 +367,7 @@ func (x *KernelParamSpecSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use KernelParamSpecSpec.ProtoReflect.Descriptor instead. func (*KernelParamSpecSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{3} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{6} } func (x *KernelParamSpecSpec) GetValue() string { @@ -246,7 +398,7 @@ type KernelParamStatusSpec struct { func (x *KernelParamStatusSpec) Reset() { *x = KernelParamStatusSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[4] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -259,7 +411,7 @@ func (x *KernelParamStatusSpec) String() string { func (*KernelParamStatusSpec) ProtoMessage() {} func (x *KernelParamStatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[4] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -272,7 +424,7 @@ func (x *KernelParamStatusSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use KernelParamStatusSpec.ProtoReflect.Descriptor instead. func (*KernelParamStatusSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{4} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{7} } func (x *KernelParamStatusSpec) GetCurrent() string { @@ -308,7 +460,7 @@ type KmsgLogConfigSpec struct { func (x *KmsgLogConfigSpec) Reset() { *x = KmsgLogConfigSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[5] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -321,7 +473,7 @@ func (x *KmsgLogConfigSpec) String() string { func (*KmsgLogConfigSpec) ProtoMessage() {} func (x *KmsgLogConfigSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[5] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -334,7 +486,7 @@ func (x *KmsgLogConfigSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use KmsgLogConfigSpec.ProtoReflect.Descriptor instead. func (*KmsgLogConfigSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{5} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{8} } func (x *KmsgLogConfigSpec) GetDestinations() []*common.URL { @@ -357,7 +509,7 @@ type MachineStatusSpec struct { func (x *MachineStatusSpec) Reset() { *x = MachineStatusSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[6] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -370,7 +522,7 @@ func (x *MachineStatusSpec) String() string { func (*MachineStatusSpec) ProtoMessage() {} func (x *MachineStatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[6] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -383,7 +535,7 @@ func (x *MachineStatusSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use MachineStatusSpec.ProtoReflect.Descriptor instead. func (*MachineStatusSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{6} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{9} } func (x *MachineStatusSpec) GetStage() enums.RuntimeMachineStage { @@ -413,7 +565,7 @@ type MachineStatusStatus struct { func (x *MachineStatusStatus) Reset() { *x = MachineStatusStatus{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[7] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -426,7 +578,7 @@ func (x *MachineStatusStatus) String() string { func (*MachineStatusStatus) ProtoMessage() {} func (x *MachineStatusStatus) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[7] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -439,7 +591,7 @@ func (x *MachineStatusStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use MachineStatusStatus.ProtoReflect.Descriptor instead. func (*MachineStatusStatus) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{7} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{10} } func (x *MachineStatusStatus) GetReady() bool { @@ -469,7 +621,7 @@ type MaintenanceServiceConfigSpec struct { func (x *MaintenanceServiceConfigSpec) Reset() { *x = MaintenanceServiceConfigSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[8] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -482,7 +634,7 @@ func (x *MaintenanceServiceConfigSpec) String() string { func (*MaintenanceServiceConfigSpec) ProtoMessage() {} func (x *MaintenanceServiceConfigSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[8] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -495,7 +647,7 @@ func (x *MaintenanceServiceConfigSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use MaintenanceServiceConfigSpec.ProtoReflect.Descriptor instead. func (*MaintenanceServiceConfigSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{8} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{11} } func (x *MaintenanceServiceConfigSpec) GetListenAddress() string { @@ -524,7 +676,7 @@ type MetaKeySpec struct { func (x *MetaKeySpec) Reset() { *x = MetaKeySpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[9] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -537,7 +689,7 @@ func (x *MetaKeySpec) String() string { func (*MetaKeySpec) ProtoMessage() {} func (x *MetaKeySpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[9] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -550,7 +702,7 @@ func (x *MetaKeySpec) ProtoReflect() protoreflect.Message { // Deprecated: Use MetaKeySpec.ProtoReflect.Descriptor instead. func (*MetaKeySpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{9} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{12} } func (x *MetaKeySpec) GetValue() string { @@ -572,7 +724,7 @@ type MetaLoadedSpec struct { func (x *MetaLoadedSpec) Reset() { *x = MetaLoadedSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[10] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -585,7 +737,7 @@ func (x *MetaLoadedSpec) String() string { func (*MetaLoadedSpec) ProtoMessage() {} func (x *MetaLoadedSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[10] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -598,7 +750,7 @@ func (x *MetaLoadedSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use MetaLoadedSpec.ProtoReflect.Descriptor instead. func (*MetaLoadedSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{10} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{13} } func (x *MetaLoadedSpec) GetDone() bool { @@ -625,7 +777,7 @@ type MountStatusSpec struct { func (x *MountStatusSpec) Reset() { *x = MountStatusSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[11] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -638,7 +790,7 @@ func (x *MountStatusSpec) String() string { func (*MountStatusSpec) ProtoMessage() {} func (x *MountStatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[11] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -651,7 +803,7 @@ func (x *MountStatusSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use MountStatusSpec.ProtoReflect.Descriptor instead. func (*MountStatusSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{11} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{14} } func (x *MountStatusSpec) GetSource() string { @@ -715,7 +867,7 @@ type PlatformMetadataSpec struct { func (x *PlatformMetadataSpec) Reset() { *x = PlatformMetadataSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -728,7 +880,7 @@ func (x *PlatformMetadataSpec) String() string { func (*PlatformMetadataSpec) ProtoMessage() {} func (x *PlatformMetadataSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -741,7 +893,7 @@ func (x *PlatformMetadataSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use PlatformMetadataSpec.ProtoReflect.Descriptor instead. func (*PlatformMetadataSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{12} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{15} } func (x *PlatformMetadataSpec) GetPlatform() string { @@ -814,7 +966,7 @@ type SecurityStateSpec struct { func (x *SecurityStateSpec) Reset() { *x = SecurityStateSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[13] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -827,7 +979,7 @@ func (x *SecurityStateSpec) String() string { func (*SecurityStateSpec) ProtoMessage() {} func (x *SecurityStateSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[13] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -840,7 +992,7 @@ func (x *SecurityStateSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use SecurityStateSpec.ProtoReflect.Descriptor instead. func (*SecurityStateSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{13} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{16} } func (x *SecurityStateSpec) GetSecureBoot() bool { @@ -876,7 +1028,7 @@ type UniqueMachineTokenSpec struct { func (x *UniqueMachineTokenSpec) Reset() { *x = UniqueMachineTokenSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[14] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -889,7 +1041,7 @@ func (x *UniqueMachineTokenSpec) String() string { func (*UniqueMachineTokenSpec) ProtoMessage() {} func (x *UniqueMachineTokenSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[14] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -902,7 +1054,7 @@ func (x *UniqueMachineTokenSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use UniqueMachineTokenSpec.ProtoReflect.Descriptor instead. func (*UniqueMachineTokenSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{14} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{17} } func (x *UniqueMachineTokenSpec) GetToken() string { @@ -925,7 +1077,7 @@ type UnmetCondition struct { func (x *UnmetCondition) Reset() { *x = UnmetCondition{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[15] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -938,7 +1090,7 @@ func (x *UnmetCondition) String() string { func (*UnmetCondition) ProtoMessage() {} func (x *UnmetCondition) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[15] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -951,7 +1103,7 @@ func (x *UnmetCondition) ProtoReflect() protoreflect.Message { // Deprecated: Use UnmetCondition.ProtoReflect.Descriptor instead. func (*UnmetCondition) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{15} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{18} } func (x *UnmetCondition) GetName() string { @@ -985,114 +1137,132 @@ var file_resource_definitions_runtime_runtime_proto_rawDesc = []byte{ 0x08, 0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x22, 0x31, 0x0a, 0x13, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0x4a, 0x0a, 0x14, 0x4b, - 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x53, 0x70, 0x65, 0x63, 0x53, - 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x50, 0x0a, 0x13, 0x4b, 0x65, 0x72, 0x6e, 0x65, - 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x67, 0x6e, - 0x6f, 0x72, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x6d, 0x0a, 0x15, 0x4b, 0x65, 0x72, - 0x6e, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, - 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x22, 0x44, 0x0a, 0x11, 0x4b, 0x6d, 0x73, 0x67, - 0x4c, 0x6f, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x2f, 0x0a, - 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x55, 0x52, 0x4c, - 0x52, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb1, - 0x01, 0x0a, 0x11, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x53, 0x70, 0x65, 0x63, 0x12, 0x4b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4d, 0x61, - 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, - 0x65, 0x12, 0x4f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0x56, 0x0a, 0x1b, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, + 0x61, 0x74, 0x68, 0x22, 0x74, 0x0a, 0x1b, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, + 0x65, 0x63, 0x12, 0x55, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x3f, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x22, 0x8a, 0x01, 0x0a, 0x13, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, - 0x61, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, - 0x12, 0x5d, 0x0a, 0x10, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, - 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x55, 0x6e, 0x6d, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, - 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, - 0x85, 0x01, 0x0a, 0x1c, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, - 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3e, 0x0a, 0x13, 0x72, 0x65, 0x61, 0x63, 0x68, - 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, - 0x74, 0x49, 0x50, 0x52, 0x12, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x23, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x61, 0x4b, - 0x65, 0x79, 0x53, 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x24, 0x0a, 0x0e, - 0x4d, 0x65, 0x74, 0x61, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, - 0x0a, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x64, 0x6f, - 0x6e, 0x65, 0x22, 0xd5, 0x01, 0x0a, 0x0f, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63, - 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x12, 0x31, 0x0a, 0x14, 0x65, 0x6e, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, - 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0xf5, 0x01, 0x0a, 0x14, 0x50, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x53, - 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, - 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, - 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, - 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, - 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, - 0x0a, 0x04, 0x73, 0x70, 0x6f, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x73, 0x70, - 0x6f, 0x74, 0x22, 0xb2, 0x01, 0x0a, 0x11, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x75, - 0x72, 0x65, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, - 0x65, 0x63, 0x75, 0x72, 0x65, 0x42, 0x6f, 0x6f, 0x74, 0x12, 0x3d, 0x0a, 0x1b, 0x75, 0x6b, 0x69, - 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6e, - 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, - 0x75, 0x6b, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6e, - 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x1b, 0x70, 0x63, 0x72, 0x5f, - 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6e, 0x67, - 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x70, - 0x63, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6e, 0x67, - 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x22, 0x2e, 0x0a, 0x16, 0x55, 0x6e, 0x69, 0x71, 0x75, - 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x70, 0x65, - 0x63, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3c, 0x0a, 0x0e, 0x55, 0x6e, 0x6d, 0x65, 0x74, - 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, - 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, - 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, - 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, - 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x69, + 0x6c, 0x65, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x46, 0x0a, 0x21, 0x45, 0x78, 0x74, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x21, + 0x0a, 0x0c, 0x73, 0x70, 0x65, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x22, 0x4a, 0x0a, 0x14, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x50, 0x0a, + 0x13, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x70, 0x65, 0x63, + 0x53, 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x67, + 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, + 0x6d, 0x0a, 0x15, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x20, 0x0a, 0x0b, + 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0b, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x22, 0x44, + 0x0a, 0x11, 0x4b, 0x6d, 0x73, 0x67, 0x4c, 0x6f, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, + 0x70, 0x65, 0x63, 0x12, 0x2f, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x55, 0x52, 0x4c, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb1, 0x01, 0x0a, 0x11, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x4b, 0x0a, 0x05, 0x73, 0x74, + 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, + 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x52, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, + 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x4f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x8a, 0x01, 0x0a, 0x13, 0x4d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x12, 0x5d, 0x0a, 0x10, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x5f, + 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x55, 0x6e, 0x6d, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x85, 0x01, 0x0a, 0x1c, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3e, 0x0a, + 0x13, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x12, 0x72, 0x65, 0x61, 0x63, 0x68, + 0x61, 0x62, 0x6c, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x23, 0x0a, + 0x0b, 0x4d, 0x65, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x53, 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x22, 0x24, 0x0a, 0x0e, 0x4d, 0x65, 0x74, 0x61, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, + 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x22, 0xd5, 0x01, 0x0a, 0x0f, 0x4d, 0x6f, 0x75, + 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x0f, + 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x12, 0x31, 0x0a, + 0x14, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x65, 0x6e, 0x63, + 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, + 0x22, 0xf5, 0x01, 0x0a, 0x14, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x7a, 0x6f, 0x6e, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x23, 0x0a, + 0x0d, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70, 0x6f, 0x74, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x04, 0x73, 0x70, 0x6f, 0x74, 0x22, 0xb2, 0x01, 0x0a, 0x11, 0x53, 0x65, 0x63, + 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, + 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x42, 0x6f, 0x6f, 0x74, 0x12, + 0x3d, 0x0a, 0x1b, 0x75, 0x6b, 0x69, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x6b, + 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x75, 0x6b, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, + 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x3d, + 0x0a, 0x1b, 0x70, 0x63, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x6b, 0x65, + 0x79, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x18, 0x70, 0x63, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x4b, + 0x65, 0x79, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x22, 0x2e, 0x0a, + 0x16, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3c, 0x0a, + 0x0e, 0x55, 0x6e, 0x6d, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x42, 0x4c, 0x5a, 0x4a, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, + 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -1107,39 +1277,43 @@ func file_resource_definitions_runtime_runtime_proto_rawDescGZIP() []byte { return file_resource_definitions_runtime_runtime_proto_rawDescData } -var file_resource_definitions_runtime_runtime_proto_msgTypes = make([]protoimpl.MessageInfo, 16) +var file_resource_definitions_runtime_runtime_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_resource_definitions_runtime_runtime_proto_goTypes = []interface{}{ - (*DevicesStatusSpec)(nil), // 0: talos.resource.definitions.runtime.DevicesStatusSpec - (*EventSinkConfigSpec)(nil), // 1: talos.resource.definitions.runtime.EventSinkConfigSpec - (*KernelModuleSpecSpec)(nil), // 2: talos.resource.definitions.runtime.KernelModuleSpecSpec - (*KernelParamSpecSpec)(nil), // 3: talos.resource.definitions.runtime.KernelParamSpecSpec - (*KernelParamStatusSpec)(nil), // 4: talos.resource.definitions.runtime.KernelParamStatusSpec - (*KmsgLogConfigSpec)(nil), // 5: talos.resource.definitions.runtime.KmsgLogConfigSpec - (*MachineStatusSpec)(nil), // 6: talos.resource.definitions.runtime.MachineStatusSpec - (*MachineStatusStatus)(nil), // 7: talos.resource.definitions.runtime.MachineStatusStatus - (*MaintenanceServiceConfigSpec)(nil), // 8: talos.resource.definitions.runtime.MaintenanceServiceConfigSpec - (*MetaKeySpec)(nil), // 9: talos.resource.definitions.runtime.MetaKeySpec - (*MetaLoadedSpec)(nil), // 10: talos.resource.definitions.runtime.MetaLoadedSpec - (*MountStatusSpec)(nil), // 11: talos.resource.definitions.runtime.MountStatusSpec - (*PlatformMetadataSpec)(nil), // 12: talos.resource.definitions.runtime.PlatformMetadataSpec - (*SecurityStateSpec)(nil), // 13: talos.resource.definitions.runtime.SecurityStateSpec - (*UniqueMachineTokenSpec)(nil), // 14: talos.resource.definitions.runtime.UniqueMachineTokenSpec - (*UnmetCondition)(nil), // 15: talos.resource.definitions.runtime.UnmetCondition - (*common.URL)(nil), // 16: common.URL - (enums.RuntimeMachineStage)(0), // 17: talos.resource.definitions.enums.RuntimeMachineStage - (*common.NetIP)(nil), // 18: common.NetIP + (*DevicesStatusSpec)(nil), // 0: talos.resource.definitions.runtime.DevicesStatusSpec + (*EventSinkConfigSpec)(nil), // 1: talos.resource.definitions.runtime.EventSinkConfigSpec + (*ExtensionServicesConfigFile)(nil), // 2: talos.resource.definitions.runtime.ExtensionServicesConfigFile + (*ExtensionServicesConfigSpec)(nil), // 3: talos.resource.definitions.runtime.ExtensionServicesConfigSpec + (*ExtensionServicesConfigStatusSpec)(nil), // 4: talos.resource.definitions.runtime.ExtensionServicesConfigStatusSpec + (*KernelModuleSpecSpec)(nil), // 5: talos.resource.definitions.runtime.KernelModuleSpecSpec + (*KernelParamSpecSpec)(nil), // 6: talos.resource.definitions.runtime.KernelParamSpecSpec + (*KernelParamStatusSpec)(nil), // 7: talos.resource.definitions.runtime.KernelParamStatusSpec + (*KmsgLogConfigSpec)(nil), // 8: talos.resource.definitions.runtime.KmsgLogConfigSpec + (*MachineStatusSpec)(nil), // 9: talos.resource.definitions.runtime.MachineStatusSpec + (*MachineStatusStatus)(nil), // 10: talos.resource.definitions.runtime.MachineStatusStatus + (*MaintenanceServiceConfigSpec)(nil), // 11: talos.resource.definitions.runtime.MaintenanceServiceConfigSpec + (*MetaKeySpec)(nil), // 12: talos.resource.definitions.runtime.MetaKeySpec + (*MetaLoadedSpec)(nil), // 13: talos.resource.definitions.runtime.MetaLoadedSpec + (*MountStatusSpec)(nil), // 14: talos.resource.definitions.runtime.MountStatusSpec + (*PlatformMetadataSpec)(nil), // 15: talos.resource.definitions.runtime.PlatformMetadataSpec + (*SecurityStateSpec)(nil), // 16: talos.resource.definitions.runtime.SecurityStateSpec + (*UniqueMachineTokenSpec)(nil), // 17: talos.resource.definitions.runtime.UniqueMachineTokenSpec + (*UnmetCondition)(nil), // 18: talos.resource.definitions.runtime.UnmetCondition + (*common.URL)(nil), // 19: common.URL + (enums.RuntimeMachineStage)(0), // 20: talos.resource.definitions.enums.RuntimeMachineStage + (*common.NetIP)(nil), // 21: common.NetIP } var file_resource_definitions_runtime_runtime_proto_depIdxs = []int32{ - 16, // 0: talos.resource.definitions.runtime.KmsgLogConfigSpec.destinations:type_name -> common.URL - 17, // 1: talos.resource.definitions.runtime.MachineStatusSpec.stage:type_name -> talos.resource.definitions.enums.RuntimeMachineStage - 7, // 2: talos.resource.definitions.runtime.MachineStatusSpec.status:type_name -> talos.resource.definitions.runtime.MachineStatusStatus - 15, // 3: talos.resource.definitions.runtime.MachineStatusStatus.unmet_conditions:type_name -> talos.resource.definitions.runtime.UnmetCondition - 18, // 4: talos.resource.definitions.runtime.MaintenanceServiceConfigSpec.reachable_addresses:type_name -> common.NetIP - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 2, // 0: talos.resource.definitions.runtime.ExtensionServicesConfigSpec.files:type_name -> talos.resource.definitions.runtime.ExtensionServicesConfigFile + 19, // 1: talos.resource.definitions.runtime.KmsgLogConfigSpec.destinations:type_name -> common.URL + 20, // 2: talos.resource.definitions.runtime.MachineStatusSpec.stage:type_name -> talos.resource.definitions.enums.RuntimeMachineStage + 10, // 3: talos.resource.definitions.runtime.MachineStatusSpec.status:type_name -> talos.resource.definitions.runtime.MachineStatusStatus + 18, // 4: talos.resource.definitions.runtime.MachineStatusStatus.unmet_conditions:type_name -> talos.resource.definitions.runtime.UnmetCondition + 21, // 5: talos.resource.definitions.runtime.MaintenanceServiceConfigSpec.reachable_addresses:type_name -> common.NetIP + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_resource_definitions_runtime_runtime_proto_init() } @@ -1173,7 +1347,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KernelModuleSpecSpec); i { + switch v := v.(*ExtensionServicesConfigFile); i { case 0: return &v.state case 1: @@ -1185,7 +1359,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KernelParamSpecSpec); i { + switch v := v.(*ExtensionServicesConfigSpec); i { case 0: return &v.state case 1: @@ -1197,7 +1371,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KernelParamStatusSpec); i { + switch v := v.(*ExtensionServicesConfigStatusSpec); i { case 0: return &v.state case 1: @@ -1209,7 +1383,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KmsgLogConfigSpec); i { + switch v := v.(*KernelModuleSpecSpec); i { case 0: return &v.state case 1: @@ -1221,7 +1395,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MachineStatusSpec); i { + switch v := v.(*KernelParamSpecSpec); i { case 0: return &v.state case 1: @@ -1233,7 +1407,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MachineStatusStatus); i { + switch v := v.(*KernelParamStatusSpec); i { case 0: return &v.state case 1: @@ -1245,7 +1419,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MaintenanceServiceConfigSpec); i { + switch v := v.(*KmsgLogConfigSpec); i { case 0: return &v.state case 1: @@ -1257,7 +1431,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MetaKeySpec); i { + switch v := v.(*MachineStatusSpec); i { case 0: return &v.state case 1: @@ -1269,7 +1443,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MetaLoadedSpec); i { + switch v := v.(*MachineStatusStatus); i { case 0: return &v.state case 1: @@ -1281,7 +1455,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MountStatusSpec); i { + switch v := v.(*MaintenanceServiceConfigSpec); i { case 0: return &v.state case 1: @@ -1293,7 +1467,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlatformMetadataSpec); i { + switch v := v.(*MetaKeySpec); i { case 0: return &v.state case 1: @@ -1305,7 +1479,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SecurityStateSpec); i { + switch v := v.(*MetaLoadedSpec); i { case 0: return &v.state case 1: @@ -1317,7 +1491,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UniqueMachineTokenSpec); i { + switch v := v.(*MountStatusSpec); i { case 0: return &v.state case 1: @@ -1329,6 +1503,42 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlatformMetadataSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_definitions_runtime_runtime_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SecurityStateSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_definitions_runtime_runtime_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UniqueMachineTokenSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_definitions_runtime_runtime_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UnmetCondition); i { case 0: return &v.state @@ -1347,7 +1557,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_resource_definitions_runtime_runtime_proto_rawDesc, NumEnums: 0, - NumMessages: 16, + NumMessages: 19, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/machinery/api/resource/definitions/runtime/runtime_vtproto.pb.go b/pkg/machinery/api/resource/definitions/runtime/runtime_vtproto.pb.go index 40568654a6..e40edba879 100644 --- a/pkg/machinery/api/resource/definitions/runtime/runtime_vtproto.pb.go +++ b/pkg/machinery/api/resource/definitions/runtime/runtime_vtproto.pb.go @@ -106,6 +106,138 @@ func (m *EventSinkConfigSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ExtensionServicesConfigFile) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ExtensionServicesConfigFile) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ExtensionServicesConfigFile) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.MountPath) > 0 { + i -= len(m.MountPath) + copy(dAtA[i:], m.MountPath) + i = encodeVarint(dAtA, i, uint64(len(m.MountPath))) + i-- + dAtA[i] = 0x12 + } + if len(m.Content) > 0 { + i -= len(m.Content) + copy(dAtA[i:], m.Content) + i = encodeVarint(dAtA, i, uint64(len(m.Content))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ExtensionServicesConfigSpec) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ExtensionServicesConfigSpec) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ExtensionServicesConfigSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Files) > 0 { + for iNdEx := len(m.Files) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Files[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + } + } + return len(dAtA) - i, nil +} + +func (m *ExtensionServicesConfigStatusSpec) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ExtensionServicesConfigStatusSpec) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ExtensionServicesConfigStatusSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.SpecVersion) > 0 { + i -= len(m.SpecVersion) + copy(dAtA[i:], m.SpecVersion) + i = encodeVarint(dAtA, i, uint64(len(m.SpecVersion))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *KernelModuleSpecSpec) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -925,6 +1057,54 @@ func (m *EventSinkConfigSpec) SizeVT() (n int) { return n } +func (m *ExtensionServicesConfigFile) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Content) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + l = len(m.MountPath) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *ExtensionServicesConfigSpec) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Files) > 0 { + for _, e := range m.Files { + l = e.SizeVT() + n += 1 + l + sov(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *ExtensionServicesConfigStatusSpec) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SpecVersion) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + n += len(m.unknownFields) + return n +} + func (m *KernelModuleSpecSpec) SizeVT() (n int) { if m == nil { return 0 @@ -1385,6 +1565,289 @@ func (m *EventSinkConfigSpec) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *ExtensionServicesConfigFile) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ExtensionServicesConfigFile: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ExtensionServicesConfigFile: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Content", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Content = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MountPath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MountPath = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ExtensionServicesConfigSpec) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ExtensionServicesConfigSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ExtensionServicesConfigSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Files", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Files = append(m.Files, &ExtensionServicesConfigFile{}) + if err := m.Files[len(m.Files)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ExtensionServicesConfigStatusSpec) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ExtensionServicesConfigStatusSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ExtensionServicesConfigStatusSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpecVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpecVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *KernelModuleSpecSpec) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/pkg/machinery/config/config/config.go b/pkg/machinery/config/config/config.go index 2b8829a4c4..6d47d579ae 100644 --- a/pkg/machinery/config/config/config.go +++ b/pkg/machinery/config/config/config.go @@ -11,6 +11,7 @@ type Config interface { Machine() MachineConfig Cluster() ClusterConfig SideroLink() SideroLinkConfig + ExtensionServicesConfig() ExtensionServicesConfigConfig Runtime() RuntimeConfig NetworkRules() NetworkRuleConfig } diff --git a/pkg/machinery/config/config/extensions_service_config.go b/pkg/machinery/config/config/extensions_service_config.go new file mode 100644 index 0000000000..ac4ff983a4 --- /dev/null +++ b/pkg/machinery/config/config/extensions_service_config.go @@ -0,0 +1,22 @@ +// 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 + +// ExtensionServicesConfigConfig is a config for extension services. +type ExtensionServicesConfigConfig interface { + ConfigData() []ExtensionServicesConfig +} + +// ExtensionServicesConfig is a config for extension services. +type ExtensionServicesConfig interface { + Name() string + ConfigFiles() []ExtensionServicesConfigFile +} + +// ExtensionServicesConfigFile is a config file for extension services. +type ExtensionServicesConfigFile interface { + Content() string + Path() string +} diff --git a/pkg/machinery/config/container/container.go b/pkg/machinery/config/container/container.go index 8226a48096..ddb754dff9 100644 --- a/pkg/machinery/config/container/container.go +++ b/pkg/machinery/config/container/container.go @@ -150,6 +150,16 @@ func (container *Container) SideroLink() config.SideroLinkConfig { return matching[0] } +// ExtensionServicesConfig implements config.Config interface. +func (container *Container) ExtensionServicesConfig() config.ExtensionServicesConfigConfig { + matching := findMatchingDocs[config.ExtensionServicesConfigConfig](container.documents) + if len(matching) == 0 { + return nil + } + + return matching[0] +} + // Runtime implements config.Config interface. func (container *Container) Runtime() config.RuntimeConfig { return config.WrapRuntimeConfigList(findMatchingDocs[config.RuntimeConfig](container.documents)...) diff --git a/pkg/machinery/config/container/container_test.go b/pkg/machinery/config/container/container_test.go index f267ba3dea..2b625c15ed 100644 --- a/pkg/machinery/config/container/container_test.go +++ b/pkg/machinery/config/container/container_test.go @@ -16,6 +16,7 @@ import ( "github.com/siderolabs/talos/pkg/machinery/config/config" "github.com/siderolabs/talos/pkg/machinery/config/configloader" "github.com/siderolabs/talos/pkg/machinery/config/container" + "github.com/siderolabs/talos/pkg/machinery/config/types/extensionservicesconfig" "github.com/siderolabs/talos/pkg/machinery/config/types/siderolink" "github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1" ) @@ -37,7 +38,20 @@ func TestNew(t *testing.T) { sideroLinkCfg := siderolink.NewConfigV1Alpha1() sideroLinkCfg.APIUrlConfig.URL = must.Value(url.Parse("https://siderolink.api/join?jointoken=secret&user=alice"))(t) - cfg, err := container.New(v1alpha1Cfg, sideroLinkCfg) + extensionsCfg := extensionservicesconfig.NewExtensionServicesConfigV1Alpha1() + extensionsCfg.Config = []extensionservicesconfig.ExtensionServiceConfig{ + { + ExtensionName: "test-extension", + ExtensionServiceConfigFiles: []extensionservicesconfig.ExtensionServiceConfigFile{ + { + ExtensionContent: "test", + ExtensionMountPath: "/etc/test", + }, + }, + }, + } + + cfg, err := container.New(v1alpha1Cfg, sideroLinkCfg, extensionsCfg) require.NoError(t, err) assert.False(t, cfg.Readonly()) @@ -45,8 +59,9 @@ func TestNew(t *testing.T) { assert.True(t, cfg.Machine().Features().RBACEnabled()) assert.Equal(t, "topsecret", cfg.Cluster().Secret()) assert.Equal(t, "https://siderolink.api/join?jointoken=secret&user=alice", cfg.SideroLink().APIUrl().String()) + assert.Equal(t, "test-extension", cfg.ExtensionServicesConfig().ConfigData()[0].Name()) assert.Same(t, v1alpha1Cfg, cfg.RawV1Alpha1()) - assert.Equal(t, []config.Document{v1alpha1Cfg, sideroLinkCfg}, cfg.Documents()) + assert.Equal(t, []config.Document{v1alpha1Cfg, sideroLinkCfg, extensionsCfg}, cfg.Documents()) bytes, err := cfg.Bytes() require.NoError(t, err) diff --git a/pkg/machinery/config/types/extensionservicesconfig/deep_copy.generated.go b/pkg/machinery/config/types/extensionservicesconfig/deep_copy.generated.go new file mode 100644 index 0000000000..17b4ec4c8f --- /dev/null +++ b/pkg/machinery/config/types/extensionservicesconfig/deep_copy.generated.go @@ -0,0 +1,23 @@ +// 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/. + +// Code generated by "deep-copy -type V1Alpha1 -pointer-receiver -header-file ../../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT. + +package extensionservicesconfig + +// DeepCopy generates a deep copy of *V1Alpha1. +func (o *V1Alpha1) DeepCopy() *V1Alpha1 { + var cp V1Alpha1 = *o + if o.Config != nil { + cp.Config = make([]ExtensionServiceConfig, len(o.Config)) + copy(cp.Config, o.Config) + for i2 := range o.Config { + if o.Config[i2].ExtensionServiceConfigFiles != nil { + cp.Config[i2].ExtensionServiceConfigFiles = make([]ExtensionServiceConfigFile, len(o.Config[i2].ExtensionServiceConfigFiles)) + copy(cp.Config[i2].ExtensionServiceConfigFiles, o.Config[i2].ExtensionServiceConfigFiles) + } + } + } + return &cp +} diff --git a/pkg/machinery/config/types/extensionservicesconfig/extension_services_config.go b/pkg/machinery/config/types/extensionservicesconfig/extension_services_config.go new file mode 100644 index 0000000000..421d6a2837 --- /dev/null +++ b/pkg/machinery/config/types/extensionservicesconfig/extension_services_config.go @@ -0,0 +1,142 @@ +// 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 extensionservicesconfig provides extensions config documents. +package extensionservicesconfig + +import ( + "fmt" + + "github.com/siderolabs/gen/xslices" + + "github.com/siderolabs/talos/pkg/machinery/config/config" + "github.com/siderolabs/talos/pkg/machinery/config/internal/registry" + "github.com/siderolabs/talos/pkg/machinery/config/types/meta" + "github.com/siderolabs/talos/pkg/machinery/config/validation" +) + +//go:generate deep-copy -type V1Alpha1 -pointer-receiver -header-file ../../../../../hack/boilerplate.txt -o deep_copy.generated.go . + +// Kind is a Extension config document kind. +const Kind = "ExtensionServicesConfig" + +func init() { + registry.Register(Kind, func(version string) config.Document { + switch version { + case "v1alpha1": + return &V1Alpha1{} + default: + return nil + } + }) +} + +// Check interfaces. +var ( + _ config.ExtensionServicesConfigConfig = &V1Alpha1{} + _ config.Document = &V1Alpha1{} + _ config.Validator = &V1Alpha1{} +) + +// V1Alpha1 is a extensionservicesconfig document. +type V1Alpha1 struct { + meta.Meta `yaml:",inline"` + Config []ExtensionServiceConfig `yaml:"config"` +} + +// ExtensionServiceConfig is a config for extension services. +type ExtensionServiceConfig struct { + ExtensionName string `yaml:"name"` + ExtensionServiceConfigFiles []ExtensionServiceConfigFile `yaml:"configFiles"` +} + +// ExtensionServiceConfigFile is a config file for extension services. +type ExtensionServiceConfigFile struct { + ExtensionContent string `yaml:"content"` + ExtensionMountPath string `yaml:"mountPath"` +} + +// NewExtensionServicesConfigV1Alpha1 creates a new siderolink config document. +func NewExtensionServicesConfigV1Alpha1() *V1Alpha1 { + return &V1Alpha1{ + Meta: meta.Meta{ + MetaKind: Kind, + MetaAPIVersion: "v1alpha1", + }, + } +} + +// Clone implements config.Document interface. +func (e *V1Alpha1) Clone() config.Document { + return e.DeepCopy() +} + +// Validate implements config.Validatator interface. +func (e *V1Alpha1) Validate(validation.RuntimeMode, ...validation.Option) ([]string, error) { + if len(e.Config) == 0 { + return nil, fmt.Errorf("no extensions config found") + } + + for _, ext := range e.Config { + if ext.ExtensionName == "" { + return nil, fmt.Errorf("extension name is required") + } + + if len(ext.ExtensionServiceConfigFiles) == 0 { + return nil, fmt.Errorf("no config files found for extension %q", ext.ExtensionName) + } + + for _, file := range ext.ExtensionServiceConfigFiles { + if file.ExtensionContent == "" { + return nil, fmt.Errorf("extension content is required for extension %q", ext.ExtensionName) + } + + if file.ExtensionMountPath == "" { + return nil, fmt.Errorf("extension mount path is required for extension %q", ext.ExtensionName) + } + } + } + + return nil, nil +} + +// ExtensionsCfg implements config.ExtensionsConfig interface. +func (e *V1Alpha1) ExtensionsCfg() config.ExtensionServicesConfigConfig { + return e +} + +// ConfigData implements config.ExtensionConfig interface. +func (e *V1Alpha1) ConfigData() []config.ExtensionServicesConfig { + return xslices.Map(e.Config, func(c ExtensionServiceConfig) config.ExtensionServicesConfig { + return &ExtensionServiceConfig{ + ExtensionName: c.ExtensionName, + ExtensionServiceConfigFiles: c.ExtensionServiceConfigFiles, + } + }) +} + +// Name implements config.ExtensionConfig interface. +func (e *ExtensionServiceConfig) Name() string { + return e.ExtensionName +} + +// ConfigFiles implements config.ExtensionConfig interface. +func (e *ExtensionServiceConfig) ConfigFiles() []config.ExtensionServicesConfigFile { + return xslices.Map(e.ExtensionServiceConfigFiles, func(c ExtensionServiceConfigFile) config.ExtensionServicesConfigFile { + return &ExtensionServiceConfigFile{ + ExtensionContent: c.ExtensionContent, + ExtensionMountPath: c.ExtensionMountPath, + } + }) +} + +// Content implements config.ConfigFile interface. +func (e *ExtensionServiceConfigFile) Content() string { + return e.ExtensionContent +} + +// Path implements config.ConfigFile interface. +func (e *ExtensionServiceConfigFile) Path() string { + return e.ExtensionMountPath +} diff --git a/pkg/machinery/config/types/extensionservicesconfig/extension_services_config_test.go b/pkg/machinery/config/types/extensionservicesconfig/extension_services_config_test.go new file mode 100644 index 0000000000..391308bba8 --- /dev/null +++ b/pkg/machinery/config/types/extensionservicesconfig/extension_services_config_test.go @@ -0,0 +1,43 @@ +// 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 extensionservicesconfig_test + +import ( + _ "embed" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/siderolabs/talos/pkg/machinery/config/encoder" + "github.com/siderolabs/talos/pkg/machinery/config/types/extensionservicesconfig" +) + +//go:embed testdata/extension_service_config.yaml +var expectedExtensionServicesConfigDocument []byte + +func TestExtensionServicesConfigMarshalStability(t *testing.T) { + t.Parallel() + + cfg := extensionservicesconfig.NewExtensionServicesConfigV1Alpha1() + cfg.Config = []extensionservicesconfig.ExtensionServiceConfig{ + { + ExtensionName: "foo", + ExtensionServiceConfigFiles: []extensionservicesconfig.ExtensionServiceConfigFile{ + { + ExtensionContent: "hello", + ExtensionMountPath: "/etc/foo", + }, + }, + }, + } + + marshaled, err := encoder.NewEncoder(cfg, encoder.WithComments(encoder.CommentsDisabled)).Encode() + require.NoError(t, err) + + t.Log(string(marshaled)) + + assert.Equal(t, expectedExtensionServicesConfigDocument, marshaled) +} diff --git a/pkg/machinery/config/types/extensionservicesconfig/testdata/extension_service_config.yaml b/pkg/machinery/config/types/extensionservicesconfig/testdata/extension_service_config.yaml new file mode 100644 index 0000000000..588d94533a --- /dev/null +++ b/pkg/machinery/config/types/extensionservicesconfig/testdata/extension_service_config.yaml @@ -0,0 +1,7 @@ +apiVersion: v1alpha1 +kind: ExtensionServicesConfig +config: + - name: foo + configFiles: + - content: hello + mountPath: /etc/foo diff --git a/pkg/machinery/config/types/types.go b/pkg/machinery/config/types/types.go index fdcbfa75cf..42d0f9781c 100644 --- a/pkg/machinery/config/types/types.go +++ b/pkg/machinery/config/types/types.go @@ -6,8 +6,9 @@ package types import ( - _ "github.com/siderolabs/talos/pkg/machinery/config/types/network" // import config types to register them - _ "github.com/siderolabs/talos/pkg/machinery/config/types/runtime" // import config types to register them - _ "github.com/siderolabs/talos/pkg/machinery/config/types/siderolink" // import config types to register them - _ "github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1" // import config types to register them + _ "github.com/siderolabs/talos/pkg/machinery/config/types/extensionservicesconfig" // import config types to register them + _ "github.com/siderolabs/talos/pkg/machinery/config/types/network" // import config types to register them + _ "github.com/siderolabs/talos/pkg/machinery/config/types/runtime" // import config types to register them + _ "github.com/siderolabs/talos/pkg/machinery/config/types/siderolink" // import config types to register them + _ "github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1" // import config types to register them ) diff --git a/pkg/machinery/constants/constants.go b/pkg/machinery/constants/constants.go index b30c1590dc..15d2cc153b 100644 --- a/pkg/machinery/constants/constants.go +++ b/pkg/machinery/constants/constants.go @@ -858,6 +858,9 @@ const ( // ExtensionServicesRootfsPath is the path to the extracted rootfs files of extension services. ExtensionServicesRootfsPath = "/usr/local/lib/containers" + // ExtensionServicesUserConfigPath is the path to the user provider extension services config directory. + ExtensionServicesUserConfigPath = SystemOverlaysPath + "/extensions" + // DBusServiceSocketPath is the path to the D-Bus socket for the logind mock to connect to. DBusServiceSocketPath = SystemRunPath + "/dbus/service.socket" diff --git a/pkg/machinery/extensions/services/services.go b/pkg/machinery/extensions/services/services.go index e98312456d..ce2a8fd9ad 100644 --- a/pkg/machinery/extensions/services/services.go +++ b/pkg/machinery/extensions/services/services.go @@ -76,6 +76,8 @@ type Dependency struct { Network []nethelpers.Status `yaml:"network,omitempty"` // Time sync check. Time bool `yaml:"time,omitempty"` + // Depends on configuration files to be present. + Configuration bool `yaml:"configuration,omitempty"` } var nameRe = regexp.MustCompile(`^[-_a-z0-9]{1,}$`) @@ -113,6 +115,8 @@ func (ctr *Container) Validate() error { } // Validate the dependency spec. +// +//nolint:gocyclo func (dep *Dependency) Validate() error { var multiErr *multierror.Error @@ -144,6 +148,10 @@ func (dep *Dependency) Validate() error { nonZeroDeps++ } + if dep.Configuration { + nonZeroDeps++ + } + if nonZeroDeps == 0 { multiErr = multierror.Append(multiErr, fmt.Errorf("no dependency specified")) } diff --git a/pkg/machinery/resources/runtime/condition.go b/pkg/machinery/resources/runtime/condition.go index 6178f51c4e..e5131fa78c 100644 --- a/pkg/machinery/resources/runtime/condition.go +++ b/pkg/machinery/resources/runtime/condition.go @@ -57,3 +57,32 @@ func (condition *KernelParamsSetCondition) Wait(ctx context.Context) error { return nil } + +// ExtensionServiceConfigStatusCondition implements condition which waits for extension service config to be available. +type ExtensionServiceConfigStatusCondition struct { + state state.State + serviceName string +} + +// NewExtensionServiceConfigStatusCondition builds a coondition which waits for extension service config to be available. +func NewExtensionServiceConfigStatusCondition(state state.State, serviceName string) *ExtensionServiceConfigStatusCondition { + return &ExtensionServiceConfigStatusCondition{ + state: state, + serviceName: serviceName, + } +} + +func (condition *ExtensionServiceConfigStatusCondition) String() string { + return "extension service config" +} + +// Wait implements condition interface. +func (condition *ExtensionServiceConfigStatusCondition) Wait(ctx context.Context) error { + _, err := condition.state.WatchFor( + ctx, + resource.NewMetadata(NamespaceName, ExtensionServicesConfigStatusType, condition.serviceName, resource.VersionUndefined), + state.WithEventTypes(state.Created, state.Updated), + ) + + return err +} diff --git a/pkg/machinery/resources/runtime/deep_copy.generated.go b/pkg/machinery/resources/runtime/deep_copy.generated.go index 709abb1d65..24e90e753f 100644 --- a/pkg/machinery/resources/runtime/deep_copy.generated.go +++ b/pkg/machinery/resources/runtime/deep_copy.generated.go @@ -2,7 +2,7 @@ // 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/. -// Code generated by "deep-copy -type DevicesStatusSpec -type EventSinkConfigSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineResetSignalSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -type SecurityStateSpec -type MetaLoadedSpec -type UniqueMachineTokenSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT. +// Code generated by "deep-copy -type DevicesStatusSpec -type EventSinkConfigSpec -type ExtensionServicesConfigSpec -type ExtensionServicesConfigStatusSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineResetSignalSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -type SecurityStateSpec -type MetaLoadedSpec -type UniqueMachineTokenSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT. package runtime @@ -23,6 +23,22 @@ func (o EventSinkConfigSpec) DeepCopy() EventSinkConfigSpec { return cp } +// DeepCopy generates a deep copy of ExtensionServicesConfigSpec. +func (o ExtensionServicesConfigSpec) DeepCopy() ExtensionServicesConfigSpec { + var cp ExtensionServicesConfigSpec = o + if o.Files != nil { + cp.Files = make([]ExtensionServicesConfigFile, len(o.Files)) + copy(cp.Files, o.Files) + } + return cp +} + +// DeepCopy generates a deep copy of ExtensionServicesConfigStatusSpec. +func (o ExtensionServicesConfigStatusSpec) DeepCopy() ExtensionServicesConfigStatusSpec { + var cp ExtensionServicesConfigStatusSpec = o + return cp +} + // DeepCopy generates a deep copy of KernelModuleSpecSpec. func (o KernelModuleSpecSpec) DeepCopy() KernelModuleSpecSpec { var cp KernelModuleSpecSpec = o diff --git a/pkg/machinery/resources/runtime/extension_services_config.go b/pkg/machinery/resources/runtime/extension_services_config.go new file mode 100644 index 0000000000..75d73ea458 --- /dev/null +++ b/pkg/machinery/resources/runtime/extension_services_config.go @@ -0,0 +1,65 @@ +// 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 runtime + +import ( + "github.com/cosi-project/runtime/pkg/resource" + "github.com/cosi-project/runtime/pkg/resource/meta" + "github.com/cosi-project/runtime/pkg/resource/protobuf" + "github.com/cosi-project/runtime/pkg/resource/typed" + + "github.com/siderolabs/talos/pkg/machinery/proto" +) + +// ExtensionServicesConfigType is a type of ExtensionServicesConfig. +const ExtensionServicesConfigType = resource.Type("ExtensionServicesConfigs.runtime.talos.dev") + +// ExtensionServicesConfig represents a resource that describes status of rendered extensions service config files. +type ExtensionServicesConfig = typed.Resource[ExtensionServicesConfigSpec, ExtensionServicesConfigExtension] + +// ExtensionServicesConfigSpec describes status of rendered extensions service config files. +// +//gotagsrewrite:gen +type ExtensionServicesConfigSpec struct { + Files []ExtensionServicesConfigFile `yaml:"files" protobuf:"2"` +} + +// ExtensionServicesConfigFile describes extensions service config files. +// +//gotagsrewrite:gen +type ExtensionServicesConfigFile struct { + Content string `yaml:"content" protobuf:"1"` + MountPath string `yaml:"mountPath" protobuf:"2"` +} + +// NewExtensionServicesConfigSpec initializes a new ExtensionServiceConfigSpec. +func NewExtensionServicesConfigSpec(namespace resource.Namespace, id resource.ID) *ExtensionServicesConfig { + return typed.NewResource[ExtensionServicesConfigSpec, ExtensionServicesConfigExtension]( + resource.NewMetadata(namespace, ExtensionServicesConfigType, id, resource.VersionUndefined), + ExtensionServicesConfigSpec{}, + ) +} + +// ExtensionServicesConfigExtension provides auxiliary methods for ExtensionServiceConfig. +type ExtensionServicesConfigExtension struct{} + +// ResourceDefinition implements meta.ResourceDefinitionProvider interface. +func (ExtensionServicesConfigExtension) ResourceDefinition() meta.ResourceDefinitionSpec { + return meta.ResourceDefinitionSpec{ + Type: ExtensionServicesConfigType, + Aliases: []resource.Type{}, + DefaultNamespace: NamespaceName, + PrintColumns: []meta.PrintColumn{}, + } +} + +func init() { + proto.RegisterDefaultTypes() + + err := protobuf.RegisterDynamic[ExtensionServicesConfigSpec](ExtensionServicesConfigType, &ExtensionServicesConfig{}) + if err != nil { + panic(err) + } +} diff --git a/pkg/machinery/resources/runtime/extension_services_config_status.go b/pkg/machinery/resources/runtime/extension_services_config_status.go new file mode 100644 index 0000000000..a985be8e09 --- /dev/null +++ b/pkg/machinery/resources/runtime/extension_services_config_status.go @@ -0,0 +1,57 @@ +// 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 runtime + +import ( + "github.com/cosi-project/runtime/pkg/resource" + "github.com/cosi-project/runtime/pkg/resource/meta" + "github.com/cosi-project/runtime/pkg/resource/protobuf" + "github.com/cosi-project/runtime/pkg/resource/typed" + + "github.com/siderolabs/talos/pkg/machinery/proto" +) + +// ExtensionServicesConfigStatusType is a type of ExtensionServicesConfig. +const ExtensionServicesConfigStatusType = resource.Type("ExtensionServicesConfigStatuses.runtime.talos.dev") + +// ExtensionServicesConfigStatus represents a resource that describes status of rendered extensions service config files. +type ExtensionServicesConfigStatus = typed.Resource[ExtensionServicesConfigStatusSpec, ExtensionServicesConfigStatusExtension] + +// ExtensionServicesConfigStatusSpec describes status of rendered extensions service config files. +// +//gotagsrewrite:gen +type ExtensionServicesConfigStatusSpec struct { + SpecVersion string `yaml:"specVersion" protobuf:"1"` +} + +// NewExtensionServicesConfigStatusSpec initializes a new ExtensionServicesConfigStatusSpec. +func NewExtensionServicesConfigStatusSpec(namespace resource.Namespace, id resource.ID) *ExtensionServicesConfigStatus { + return typed.NewResource[ExtensionServicesConfigStatusSpec, ExtensionServicesConfigStatusExtension]( + resource.NewMetadata(namespace, ExtensionServicesConfigStatusType, id, resource.VersionUndefined), + ExtensionServicesConfigStatusSpec{}, + ) +} + +// ExtensionServicesConfigStatusExtension provides auxiliary methods for ExtensionServiceConfig. +type ExtensionServicesConfigStatusExtension struct{} + +// ResourceDefinition implements meta.ResourceDefinitionProvider interface. +func (ExtensionServicesConfigStatusExtension) ResourceDefinition() meta.ResourceDefinitionSpec { + return meta.ResourceDefinitionSpec{ + Type: ExtensionServicesConfigStatusType, + Aliases: []resource.Type{}, + DefaultNamespace: NamespaceName, + PrintColumns: []meta.PrintColumn{}, + } +} + +func init() { + proto.RegisterDefaultTypes() + + err := protobuf.RegisterDynamic[ExtensionServicesConfigStatusSpec](ExtensionServicesConfigStatusType, &ExtensionServicesConfigStatus{}) + if err != nil { + panic(err) + } +} diff --git a/pkg/machinery/resources/runtime/runtime.go b/pkg/machinery/resources/runtime/runtime.go index 49f92ba026..91e0ddd07f 100644 --- a/pkg/machinery/resources/runtime/runtime.go +++ b/pkg/machinery/resources/runtime/runtime.go @@ -4,4 +4,4 @@ package runtime -//go:generate deep-copy -type DevicesStatusSpec -type EventSinkConfigSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineResetSignalSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -type SecurityStateSpec -type MetaLoadedSpec -type UniqueMachineTokenSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go . +//go:generate deep-copy -type DevicesStatusSpec -type EventSinkConfigSpec -type ExtensionServicesConfigSpec -type ExtensionServicesConfigStatusSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineResetSignalSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -type SecurityStateSpec -type MetaLoadedSpec -type UniqueMachineTokenSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go . diff --git a/website/content/v1.7/advanced/extension-services.md b/website/content/v1.7/advanced/extension-services.md index 3f129323e7..02690d559c 100644 --- a/website/content/v1.7/advanced/extension-services.md +++ b/website/content/v1.7/advanced/extension-services.md @@ -36,6 +36,7 @@ container: mounts: - # OCI Mount Spec depends: + - configuration: true - service: cri - path: /run/machined/machined.sock - network: @@ -127,6 +128,8 @@ Available dependencies: * `path: `: wait for the `` to exist * `network: [addresses, connectivity, hostname, etcfiles]`: wait for the specified network readiness checks to succeed * `time: true`: wait for the NTP time sync +* `configuration: true`: wait for `ExtensionServicesConfig` resource with a name matching the extension name to be available. + The mounts specified in the `ExtensionServicesConfig` will be added as extra mounts to the extension service. ### `restart` diff --git a/website/content/v1.7/reference/api.md b/website/content/v1.7/reference/api.md index f3eb82c18b..db2171c014 100644 --- a/website/content/v1.7/reference/api.md +++ b/website/content/v1.7/reference/api.md @@ -209,6 +209,9 @@ description: Talos gRPC API reference. - [resource/definitions/runtime/runtime.proto](#resource/definitions/runtime/runtime.proto) - [DevicesStatusSpec](#talos.resource.definitions.runtime.DevicesStatusSpec) - [EventSinkConfigSpec](#talos.resource.definitions.runtime.EventSinkConfigSpec) + - [ExtensionServicesConfigFile](#talos.resource.definitions.runtime.ExtensionServicesConfigFile) + - [ExtensionServicesConfigSpec](#talos.resource.definitions.runtime.ExtensionServicesConfigSpec) + - [ExtensionServicesConfigStatusSpec](#talos.resource.definitions.runtime.ExtensionServicesConfigStatusSpec) - [KernelModuleSpecSpec](#talos.resource.definitions.runtime.KernelModuleSpecSpec) - [KernelParamSpecSpec](#talos.resource.definitions.runtime.KernelParamSpecSpec) - [KernelParamStatusSpec](#talos.resource.definitions.runtime.KernelParamStatusSpec) @@ -3831,6 +3834,52 @@ EventSinkConfigSpec describes configuration of Talos event log streaming. + + +### ExtensionServicesConfigFile +ExtensionServicesConfigFile describes extensions service config files. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| content | [string](#string) | | | +| mount_path | [string](#string) | | | + + + + + + + + +### ExtensionServicesConfigSpec +ExtensionServicesConfigSpec describes status of rendered extensions service config files. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| files | [ExtensionServicesConfigFile](#talos.resource.definitions.runtime.ExtensionServicesConfigFile) | repeated | | + + + + + + + + +### ExtensionServicesConfigStatusSpec +ExtensionServicesConfigStatusSpec describes status of rendered extensions service config files. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| spec_version | [string](#string) | | | + + + + + + ### KernelModuleSpecSpec