feat: provide a way to load Linux kernel modules
Fixes #4693 Machine configuration change plus very simple controllers which transform config into the module spec and finally load modules. There's no support for advanced features like module params and aliases, but we can add it later. Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
This commit is contained in:
parent
4d1514add6
commit
3623da136b
1
go.mod
1
go.mod
@ -73,6 +73,7 @@ require (
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
|
||||
github.com/packethost/packngo v0.20.0
|
||||
github.com/pin/tftp v2.1.0+incompatible
|
||||
github.com/pmorjan/kmod v1.0.0
|
||||
github.com/prometheus/procfs v0.7.3
|
||||
github.com/rivo/tview v0.0.0-20211202162923-2a6de950f73b
|
||||
github.com/rs/xid v1.3.0
|
||||
|
2
go.sum
2
go.sum
@ -976,6 +976,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmorjan/kmod v1.0.0 h1:vzC1NAs8Ot25gFWkrN2jAy9GzDrYkTXlucr378FhZ7k=
|
||||
github.com/pmorjan/kmod v1.0.0/go.mod h1:8aTvlzx0I6TjLFDiaRL0VbSrsQkjMjA9wH08gYAkvEU=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
|
@ -28,7 +28,7 @@ const (
|
||||
fsFileMax = "fs.file-max"
|
||||
)
|
||||
|
||||
type KernelParamSuite struct {
|
||||
type RuntimeSuite struct {
|
||||
suite.Suite
|
||||
|
||||
state state.State
|
||||
@ -40,7 +40,7 @@ type KernelParamSuite struct {
|
||||
ctxCancel context.CancelFunc
|
||||
}
|
||||
|
||||
func (suite *KernelParamSuite) SetupTest() {
|
||||
func (suite *RuntimeSuite) SetupTest() {
|
||||
suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), 3*time.Minute)
|
||||
|
||||
suite.state = state.WrapCore(namespaced.NewState(inmem.Build))
|
||||
@ -53,7 +53,7 @@ func (suite *KernelParamSuite) SetupTest() {
|
||||
suite.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (suite *KernelParamSuite) startRuntime() {
|
||||
func (suite *RuntimeSuite) startRuntime() {
|
||||
suite.wg.Add(1)
|
||||
|
||||
go func() {
|
||||
@ -63,7 +63,7 @@ func (suite *KernelParamSuite) startRuntime() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (suite *KernelParamSuite) assertResource(md resource.Metadata, compare func(res resource.Resource) bool) func() error {
|
||||
func (suite *RuntimeSuite) assertResource(md resource.Metadata, compare func(res resource.Resource) bool) func() error {
|
||||
return func() error {
|
||||
r, err := suite.state.Get(suite.ctx, md)
|
||||
if err != nil {
|
||||
@ -82,7 +82,7 @@ func (suite *KernelParamSuite) assertResource(md resource.Metadata, compare func
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KernelParamSuite) TearDownTest() {
|
||||
func (suite *RuntimeSuite) TearDownTest() {
|
||||
suite.T().Log("tear down")
|
||||
|
||||
suite.ctxCancel()
|
||||
|
@ -0,0 +1,104 @@
|
||||
// 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/AlekSi/pointer"
|
||||
"github.com/cosi-project/runtime/pkg/controller"
|
||||
"github.com/cosi-project/runtime/pkg/resource"
|
||||
"github.com/cosi-project/runtime/pkg/state"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/config"
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/runtime"
|
||||
)
|
||||
|
||||
// KernelModuleConfigController watches v1alpha1.Config, creates/updates/deletes kernel module specs.
|
||||
type KernelModuleConfigController struct{}
|
||||
|
||||
// Name implements controller.Controller interface.
|
||||
func (ctrl *KernelModuleConfigController) Name() string {
|
||||
return "runtime.KernelModuleConfigController"
|
||||
}
|
||||
|
||||
// Inputs implements controller.Controller interface.
|
||||
func (ctrl *KernelModuleConfigController) Inputs() []controller.Input {
|
||||
return []controller.Input{
|
||||
{
|
||||
Namespace: config.NamespaceName,
|
||||
Type: config.MachineConfigType,
|
||||
ID: pointer.ToString(config.V1Alpha1ID),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Outputs implements controller.Controller interface.
|
||||
func (ctrl *KernelModuleConfigController) Outputs() []controller.Output {
|
||||
return []controller.Output{
|
||||
{
|
||||
Type: runtime.KernelModuleSpecType,
|
||||
Kind: controller.OutputShared,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Run implements controller.Controller interface.
|
||||
//
|
||||
//nolint:gocyclo
|
||||
func (ctrl *KernelModuleConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case <-r.EventCh():
|
||||
cfg, err := r.Get(ctx, resource.NewMetadata(config.NamespaceName, config.MachineConfigType, config.V1Alpha1ID, resource.VersionUndefined))
|
||||
if err != nil {
|
||||
if !state.IsNotFoundError(err) {
|
||||
return fmt.Errorf("error getting config: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
touchedIDs := make(map[resource.ID]struct{})
|
||||
|
||||
if cfg != nil {
|
||||
c, _ := cfg.(*config.MachineConfig) //nolint:errcheck
|
||||
for _, module := range c.Config().Machine().Kernel().Modules() {
|
||||
touchedIDs[module.Name()] = struct{}{}
|
||||
|
||||
item := runtime.NewKernelModuleSpec(runtime.NamespaceName, module.Name())
|
||||
|
||||
if err = r.Modify(ctx, item, func(res resource.Resource) error {
|
||||
res.(*runtime.KernelModuleSpec).TypedSpec().Name = module.Name()
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// list keys for cleanup
|
||||
list, err := r.List(ctx, resource.NewMetadata(runtime.NamespaceName, runtime.KernelModuleSpecType, "", resource.VersionUndefined))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error listing resources: %w", err)
|
||||
}
|
||||
|
||||
for _, res := range list.Items {
|
||||
if res.Metadata().Owner() != ctrl.Name() {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := touchedIDs[res.Metadata().ID()]; !ok {
|
||||
if err = r.Destroy(ctx, res.Metadata()); err != nil {
|
||||
return fmt.Errorf("error cleaning up specs: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
// 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 (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cosi-project/runtime/pkg/resource"
|
||||
"github.com/cosi-project/runtime/pkg/state"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/talos-systems/go-retry/retry"
|
||||
|
||||
runtimecontrollers "github.com/talos-systems/talos/internal/app/machined/pkg/controllers/runtime"
|
||||
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1"
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/config"
|
||||
runtimeresource "github.com/talos-systems/talos/pkg/machinery/resources/runtime"
|
||||
)
|
||||
|
||||
type KernelModuleConfigSuite struct {
|
||||
RuntimeSuite
|
||||
}
|
||||
|
||||
func (suite *KernelModuleConfigSuite) TestReconcileConfig() {
|
||||
suite.Require().NoError(suite.runtime.RegisterController(&runtimecontrollers.KernelModuleConfigController{}))
|
||||
|
||||
suite.startRuntime()
|
||||
|
||||
cfg := config.NewMachineConfig(&v1alpha1.Config{
|
||||
ConfigVersion: "v1alpha1",
|
||||
MachineConfig: &v1alpha1.MachineConfig{
|
||||
MachineKernel: &v1alpha1.KernelConfig{
|
||||
KernelModules: []*v1alpha1.KernelModuleConfig{
|
||||
{
|
||||
ModuleName: "brtfs",
|
||||
},
|
||||
{
|
||||
ModuleName: "e1000",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ClusterConfig: &v1alpha1.ClusterConfig{},
|
||||
})
|
||||
|
||||
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
|
||||
|
||||
specMD := resource.NewMetadata(runtimeresource.NamespaceName, runtimeresource.KernelModuleSpecType, "e1000", resource.VersionUndefined)
|
||||
|
||||
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
|
||||
suite.assertResource(
|
||||
specMD,
|
||||
func(res resource.Resource) bool {
|
||||
return res.(*runtimeresource.KernelModuleSpec).TypedSpec().Name == "e1000"
|
||||
},
|
||||
),
|
||||
))
|
||||
|
||||
cfg = config.NewMachineConfig(&v1alpha1.Config{
|
||||
ConfigVersion: "v1alpha1",
|
||||
MachineConfig: &v1alpha1.MachineConfig{
|
||||
MachineKernel: nil,
|
||||
},
|
||||
ClusterConfig: &v1alpha1.ClusterConfig{},
|
||||
})
|
||||
|
||||
old := cfg.Metadata().Version()
|
||||
|
||||
cfg.Metadata().BumpVersion()
|
||||
|
||||
suite.Require().NoError(suite.state.Update(suite.ctx, old, cfg))
|
||||
|
||||
var err error
|
||||
|
||||
// wait for the resource to be removed
|
||||
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
|
||||
func() error {
|
||||
for _, md := range []resource.Metadata{specMD} {
|
||||
_, err = suite.state.Get(suite.ctx, md)
|
||||
if err != nil {
|
||||
if state.IsNotFoundError(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return retry.ExpectedError(fmt.Errorf("resource still exists"))
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
func TestKernelModuleConfigSuite(t *testing.T) {
|
||||
suite.Run(t, new(KernelModuleConfigSuite))
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
// 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/resource"
|
||||
"github.com/pmorjan/kmod"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/runtime"
|
||||
)
|
||||
|
||||
// KernelModuleSpecController watches KernelModuleSpecs, sets/resets kernel params.
|
||||
type KernelModuleSpecController struct{}
|
||||
|
||||
// Name implements controller.Controller interface.
|
||||
func (ctrl *KernelModuleSpecController) Name() string {
|
||||
return "runtime.KernelModuleSpecController"
|
||||
}
|
||||
|
||||
// Inputs implements controller.Controller interface.
|
||||
func (ctrl *KernelModuleSpecController) Inputs() []controller.Input {
|
||||
return []controller.Input{
|
||||
{
|
||||
Namespace: runtime.NamespaceName,
|
||||
Type: runtime.KernelModuleSpecType,
|
||||
Kind: controller.InputStrong,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Outputs implements controller.Controller interface.
|
||||
func (ctrl *KernelModuleSpecController) Outputs() []controller.Output {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run implements controller.Controller interface.
|
||||
func (ctrl *KernelModuleSpecController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
|
||||
manager, err := kmod.New()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error initializing kmod manager")
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case <-r.EventCh():
|
||||
modules, err := r.List(ctx, resource.NewMetadata(runtime.NamespaceName, runtime.KernelModuleSpecType, "", resource.VersionUndefined))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// note: this code doesn't support module unloading in any way for now
|
||||
for _, res := range modules.Items {
|
||||
module := res.(*runtime.KernelModuleSpec).TypedSpec()
|
||||
|
||||
if err = manager.Load(module.Name, "", 0); err != nil {
|
||||
return fmt.Errorf("error loading module %q: %w", module.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ import (
|
||||
)
|
||||
|
||||
type KernelParamConfigSuite struct {
|
||||
KernelParamSuite
|
||||
RuntimeSuite
|
||||
}
|
||||
|
||||
func (suite *KernelParamConfigSuite) TestReconcileConfig() {
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
type KernelParamDefaultsSuite struct {
|
||||
KernelParamSuite
|
||||
RuntimeSuite
|
||||
}
|
||||
|
||||
func getParams(mode runtime.Mode) []*kernel.Param {
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
)
|
||||
|
||||
type KernelParamSpecSuite struct {
|
||||
KernelParamSuite
|
||||
RuntimeSuite
|
||||
}
|
||||
|
||||
func (suite *KernelParamSpecSuite) TestParamsSynced() {
|
||||
|
@ -100,6 +100,7 @@ func (r *Runtime) CanApplyImmediate(cfg config.Provider) error {
|
||||
// * .machine.logging
|
||||
// * .machine.controlplane
|
||||
// * .machine.kubelet
|
||||
// * .machine.kernel
|
||||
newConfig.ConfigDebug = currentConfig.ConfigDebug
|
||||
newConfig.ClusterConfig = currentConfig.ClusterConfig
|
||||
|
||||
@ -111,6 +112,7 @@ func (r *Runtime) CanApplyImmediate(cfg config.Provider) error {
|
||||
newConfig.MachineConfig.MachineLogging = currentConfig.MachineConfig.MachineLogging
|
||||
newConfig.MachineConfig.MachineControlPlane = currentConfig.MachineConfig.MachineControlPlane
|
||||
newConfig.MachineConfig.MachineKubelet = currentConfig.MachineConfig.MachineKubelet
|
||||
newConfig.MachineConfig.MachineKernel = currentConfig.MachineConfig.MachineKernel
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(currentConfig, newConfig) {
|
||||
|
@ -184,6 +184,8 @@ func (ctrl *Controller) Run(ctx context.Context, drainer *runtime.Drainer) error
|
||||
Cmdline: procfs.ProcCmdline(),
|
||||
Drainer: drainer,
|
||||
},
|
||||
&runtimecontrollers.KernelModuleConfigController{},
|
||||
&runtimecontrollers.KernelModuleSpecController{},
|
||||
&runtimecontrollers.KernelParamConfigController{},
|
||||
&runtimecontrollers.KernelParamDefaultsController{
|
||||
V1Alpha1Mode: ctrl.v1alpha1Runtime.State().Platform().Mode(),
|
||||
|
@ -124,6 +124,7 @@ func NewState() (*State, error) {
|
||||
&network.TimeServerSpec{},
|
||||
&perf.CPU{},
|
||||
&perf.Memory{},
|
||||
&runtime.KernelModuleSpec{},
|
||||
&runtime.KernelParamSpec{},
|
||||
&runtime.KernelParamDefaultSpec{},
|
||||
&runtime.KernelParamStatus{},
|
||||
|
@ -52,6 +52,7 @@ type MachineConfig interface {
|
||||
Features() Features
|
||||
Udev() UdevConfig
|
||||
Logging() Logging
|
||||
Kernel() Kernel
|
||||
}
|
||||
|
||||
// Disk represents the options available for partitioning, formatting, and
|
||||
@ -517,3 +518,13 @@ type LoggingDestination interface {
|
||||
Endpoint() *url.URL
|
||||
Format() string
|
||||
}
|
||||
|
||||
// Kernel describes Talos Linux kernel configuration.
|
||||
type Kernel interface {
|
||||
Modules() []KernelModule
|
||||
}
|
||||
|
||||
// KernelModule describes Linux module to load.
|
||||
type KernelModule interface {
|
||||
Name() string
|
||||
}
|
||||
|
28
pkg/machinery/config/types/v1alpha1/v1alpha1_kernel.go
Normal file
28
pkg/machinery/config/types/v1alpha1/v1alpha1_kernel.go
Normal file
@ -0,0 +1,28 @@
|
||||
// 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 v1alpha1
|
||||
|
||||
import (
|
||||
"github.com/talos-systems/talos/pkg/machinery/config"
|
||||
)
|
||||
|
||||
// Modules implements config.Kernel interface.
|
||||
func (kc *KernelConfig) Modules() []config.KernelModule {
|
||||
if kc.KernelModules == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
res := make([]config.KernelModule, len(kc.KernelModules))
|
||||
for i, m := range kc.KernelModules {
|
||||
res[i] = config.KernelModule(m)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// Name implements config.KernelModule interface.
|
||||
func (kmc *KernelModuleConfig) Name() string {
|
||||
return kmc.ModuleName
|
||||
}
|
@ -333,6 +333,15 @@ func (m *MachineConfig) Logging() config.Logging {
|
||||
return m.MachineLogging
|
||||
}
|
||||
|
||||
// Kernel implements the config.MachineConfig interface.
|
||||
func (m *MachineConfig) Kernel() config.Kernel {
|
||||
if m.MachineKernel == nil {
|
||||
return &KernelConfig{}
|
||||
}
|
||||
|
||||
return m.MachineKernel
|
||||
}
|
||||
|
||||
// Image implements the config.Provider interface.
|
||||
func (k *KubeletConfig) Image() string {
|
||||
image := k.KubeletImage
|
||||
|
@ -496,6 +496,14 @@ metadata:
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
machineKernelExample = &KernelConfig{
|
||||
KernelModules: []*KernelModuleConfig{
|
||||
{
|
||||
ModuleName: "brtfs",
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Config defines the v1alpha1 configuration file.
|
||||
@ -694,6 +702,11 @@ type MachineConfig struct {
|
||||
// examples:
|
||||
// - value: machineLoggingExample
|
||||
MachineLogging *LoggingConfig `yaml:"logging,omitempty"`
|
||||
// description: |
|
||||
// Configures the kernel.
|
||||
// examples:
|
||||
// - value: machineKernelExample
|
||||
MachineKernel *KernelConfig `yaml:"kernel,omitempty"`
|
||||
}
|
||||
|
||||
// ClusterConfig represents the cluster-wide config values.
|
||||
@ -2105,3 +2118,17 @@ type LoggingDestination struct {
|
||||
// - json_lines
|
||||
LoggingFormat string `yaml:"format"`
|
||||
}
|
||||
|
||||
// KernelConfig struct configures Talos Linux kernel.
|
||||
type KernelConfig struct {
|
||||
// description: |
|
||||
// Kernel modules to load.
|
||||
KernelModules []*KernelModuleConfig `yaml:"modules,omitempty"`
|
||||
}
|
||||
|
||||
// KernelModuleConfig struct configures Linux kernel modules to load.
|
||||
type KernelModuleConfig struct {
|
||||
// description: |
|
||||
// Module name.
|
||||
ModuleName string `yaml:"name"`
|
||||
}
|
||||
|
@ -73,6 +73,8 @@ var (
|
||||
UdevConfigDoc encoder.Doc
|
||||
LoggingConfigDoc encoder.Doc
|
||||
LoggingDestinationDoc encoder.Doc
|
||||
KernelConfigDoc encoder.Doc
|
||||
KernelModuleConfigDoc encoder.Doc
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -134,7 +136,7 @@ func init() {
|
||||
FieldName: "machine",
|
||||
},
|
||||
}
|
||||
MachineConfigDoc.Fields = make([]encoder.Doc, 18)
|
||||
MachineConfigDoc.Fields = make([]encoder.Doc, 19)
|
||||
MachineConfigDoc.Fields[0].Name = "type"
|
||||
MachineConfigDoc.Fields[0].Type = "string"
|
||||
MachineConfigDoc.Fields[0].Note = ""
|
||||
@ -275,6 +277,13 @@ func init() {
|
||||
MachineConfigDoc.Fields[17].Comments[encoder.LineComment] = "Configures the logging system."
|
||||
|
||||
MachineConfigDoc.Fields[17].AddExample("", machineLoggingExample)
|
||||
MachineConfigDoc.Fields[18].Name = "kernel"
|
||||
MachineConfigDoc.Fields[18].Type = "KernelConfig"
|
||||
MachineConfigDoc.Fields[18].Note = ""
|
||||
MachineConfigDoc.Fields[18].Description = "Configures the kernel."
|
||||
MachineConfigDoc.Fields[18].Comments[encoder.LineComment] = "Configures the kernel."
|
||||
|
||||
MachineConfigDoc.Fields[18].AddExample("", machineKernelExample)
|
||||
|
||||
ClusterConfigDoc.Type = "ClusterConfig"
|
||||
ClusterConfigDoc.Comments[encoder.LineComment] = "ClusterConfig represents the cluster-wide config values."
|
||||
@ -2299,6 +2308,40 @@ func init() {
|
||||
LoggingDestinationDoc.Fields[1].Values = []string{
|
||||
"json_lines",
|
||||
}
|
||||
|
||||
KernelConfigDoc.Type = "KernelConfig"
|
||||
KernelConfigDoc.Comments[encoder.LineComment] = "KernelConfig struct configures Talos Linux kernel."
|
||||
KernelConfigDoc.Description = "KernelConfig struct configures Talos Linux kernel."
|
||||
|
||||
KernelConfigDoc.AddExample("", machineKernelExample)
|
||||
KernelConfigDoc.AppearsIn = []encoder.Appearance{
|
||||
{
|
||||
TypeName: "MachineConfig",
|
||||
FieldName: "kernel",
|
||||
},
|
||||
}
|
||||
KernelConfigDoc.Fields = make([]encoder.Doc, 1)
|
||||
KernelConfigDoc.Fields[0].Name = "modules"
|
||||
KernelConfigDoc.Fields[0].Type = "[]KernelModuleConfig"
|
||||
KernelConfigDoc.Fields[0].Note = ""
|
||||
KernelConfigDoc.Fields[0].Description = "Kernel modules to load."
|
||||
KernelConfigDoc.Fields[0].Comments[encoder.LineComment] = "Kernel modules to load."
|
||||
|
||||
KernelModuleConfigDoc.Type = "KernelModuleConfig"
|
||||
KernelModuleConfigDoc.Comments[encoder.LineComment] = "KernelModuleConfig struct configures Linux kernel modules to load."
|
||||
KernelModuleConfigDoc.Description = "KernelModuleConfig struct configures Linux kernel modules to load."
|
||||
KernelModuleConfigDoc.AppearsIn = []encoder.Appearance{
|
||||
{
|
||||
TypeName: "KernelConfig",
|
||||
FieldName: "modules",
|
||||
},
|
||||
}
|
||||
KernelModuleConfigDoc.Fields = make([]encoder.Doc, 1)
|
||||
KernelModuleConfigDoc.Fields[0].Name = "name"
|
||||
KernelModuleConfigDoc.Fields[0].Type = "string"
|
||||
KernelModuleConfigDoc.Fields[0].Note = ""
|
||||
KernelModuleConfigDoc.Fields[0].Description = "Module name."
|
||||
KernelModuleConfigDoc.Fields[0].Comments[encoder.LineComment] = "Module name."
|
||||
}
|
||||
|
||||
func (_ Config) Doc() *encoder.Doc {
|
||||
@ -2545,6 +2588,14 @@ func (_ LoggingDestination) Doc() *encoder.Doc {
|
||||
return &LoggingDestinationDoc
|
||||
}
|
||||
|
||||
func (_ KernelConfig) Doc() *encoder.Doc {
|
||||
return &KernelConfigDoc
|
||||
}
|
||||
|
||||
func (_ KernelModuleConfig) Doc() *encoder.Doc {
|
||||
return &KernelModuleConfigDoc
|
||||
}
|
||||
|
||||
// GetConfigurationDoc returns documentation for the file ./v1alpha1_types_doc.go.
|
||||
func GetConfigurationDoc() *encoder.FileDoc {
|
||||
return &encoder.FileDoc{
|
||||
@ -2612,6 +2663,8 @@ func GetConfigurationDoc() *encoder.FileDoc {
|
||||
&UdevConfigDoc,
|
||||
&LoggingConfigDoc,
|
||||
&LoggingDestinationDoc,
|
||||
&KernelConfigDoc,
|
||||
&KernelModuleConfigDoc,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -833,6 +833,49 @@ func (in *InstallDiskSizeMatcher) DeepCopy() *InstallDiskSizeMatcher {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KernelConfig) DeepCopyInto(out *KernelConfig) {
|
||||
*out = *in
|
||||
if in.KernelModules != nil {
|
||||
in, out := &in.KernelModules, &out.KernelModules
|
||||
*out = make([]*KernelModuleConfig, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(KernelModuleConfig)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KernelConfig.
|
||||
func (in *KernelConfig) DeepCopy() *KernelConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KernelConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KernelModuleConfig) DeepCopyInto(out *KernelModuleConfig) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KernelModuleConfig.
|
||||
func (in *KernelModuleConfig) DeepCopy() *KernelModuleConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KernelModuleConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletConfig) DeepCopyInto(out *KubeletConfig) {
|
||||
*out = *in
|
||||
@ -1027,6 +1070,11 @@ func (in *MachineConfig) DeepCopyInto(out *MachineConfig) {
|
||||
*out = new(LoggingConfig)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.MachineKernel != nil {
|
||||
in, out := &in.MachineKernel, &out.MachineKernel
|
||||
*out = new(KernelConfig)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
75
pkg/machinery/resources/runtime/kernel_module_spec.go
Normal file
75
pkg/machinery/resources/runtime/kernel_module_spec.go
Normal file
@ -0,0 +1,75 @@
|
||||
// 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 (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosi-project/runtime/pkg/resource"
|
||||
"github.com/cosi-project/runtime/pkg/resource/meta"
|
||||
)
|
||||
|
||||
// KernelModuleSpecType is type of KernelModuleSpec resource.
|
||||
const KernelModuleSpecType = resource.Type("KernelModuleSpecs.runtime.talos.dev")
|
||||
|
||||
// KernelModuleSpec resource holds information about Linux kernel module to load.
|
||||
type KernelModuleSpec struct {
|
||||
md resource.Metadata
|
||||
spec KernelModuleSpecSpec
|
||||
}
|
||||
|
||||
// KernelModuleSpecSpec describes Linux kernel module to load.
|
||||
type KernelModuleSpecSpec struct {
|
||||
Name string `yaml:"string"`
|
||||
// more options in the future: args, aliases, etc.
|
||||
}
|
||||
|
||||
// NewKernelModuleSpec initializes a KernelModuleSpec resource.
|
||||
func NewKernelModuleSpec(namespace resource.Namespace, id resource.ID) *KernelModuleSpec {
|
||||
r := &KernelModuleSpec{
|
||||
md: resource.NewMetadata(namespace, KernelModuleSpecType, id, resource.VersionUndefined),
|
||||
spec: KernelModuleSpecSpec{},
|
||||
}
|
||||
|
||||
r.md.BumpVersion()
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// Metadata implements resource.Resource.
|
||||
func (r *KernelModuleSpec) Metadata() *resource.Metadata {
|
||||
return &r.md
|
||||
}
|
||||
|
||||
// Spec implements resource.Resource.
|
||||
func (r *KernelModuleSpec) Spec() interface{} {
|
||||
return r.spec
|
||||
}
|
||||
|
||||
func (r *KernelModuleSpec) String() string {
|
||||
return fmt.Sprintf("runtime.KernelModuleSpec.(%q)", r.md.ID())
|
||||
}
|
||||
|
||||
// DeepCopy implements resource.Resource.
|
||||
func (r *KernelModuleSpec) DeepCopy() resource.Resource {
|
||||
return &KernelModuleSpec{
|
||||
md: r.md,
|
||||
spec: r.spec,
|
||||
}
|
||||
}
|
||||
|
||||
// ResourceDefinition implements meta.ResourceDefinitionProvider interface.
|
||||
func (r *KernelModuleSpec) ResourceDefinition() meta.ResourceDefinitionSpec {
|
||||
return meta.ResourceDefinitionSpec{
|
||||
Type: KernelModuleSpecType,
|
||||
Aliases: []resource.Type{"modules"},
|
||||
DefaultNamespace: NamespaceName,
|
||||
}
|
||||
}
|
||||
|
||||
// TypedSpec allows to access the KernelModuleSpecSpec with the proper type.
|
||||
func (r *KernelModuleSpec) TypedSpec() *KernelModuleSpecSpec {
|
||||
return &r.spec
|
||||
}
|
@ -25,6 +25,7 @@ func TestRegisterResource(t *testing.T) {
|
||||
resourceRegistry := registry.NewResourceRegistry(resources)
|
||||
|
||||
for _, resource := range []resource.Resource{
|
||||
&runtime.KernelModuleSpec{},
|
||||
&runtime.KernelParamSpec{},
|
||||
&runtime.KernelParamStatus{},
|
||||
&runtime.MountStatus{},
|
||||
|
@ -815,6 +815,31 @@ logging:
|
||||
```
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
<div class="dd">
|
||||
|
||||
<code>kernel</code> <i><a href="#kernelconfig">KernelConfig</a></i>
|
||||
|
||||
</div>
|
||||
<div class="dt">
|
||||
|
||||
Configures the kernel.
|
||||
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
|
||||
``` yaml
|
||||
kernel:
|
||||
# Kernel modules to load.
|
||||
modules:
|
||||
- name: brtfs # Module name.
|
||||
```
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
@ -5851,3 +5876,60 @@ Valid values:
|
||||
<hr />
|
||||
|
||||
|
||||
|
||||
## KernelConfig
|
||||
KernelConfig struct configures Talos Linux kernel.
|
||||
|
||||
Appears in:
|
||||
|
||||
- <code><a href="#machineconfig">MachineConfig</a>.kernel</code>
|
||||
|
||||
|
||||
``` yaml
|
||||
# Kernel modules to load.
|
||||
modules:
|
||||
- name: brtfs # Module name.
|
||||
```
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="dd">
|
||||
|
||||
<code>modules</code> <i>[]<a href="#kernelmoduleconfig">KernelModuleConfig</a></i>
|
||||
|
||||
</div>
|
||||
<div class="dt">
|
||||
|
||||
Kernel modules to load.
|
||||
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
|
||||
|
||||
## KernelModuleConfig
|
||||
KernelModuleConfig struct configures Linux kernel modules to load.
|
||||
|
||||
Appears in:
|
||||
|
||||
- <code><a href="#kernelconfig">KernelConfig</a>.modules</code>
|
||||
|
||||
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="dd">
|
||||
|
||||
<code>name</code> <i>string</i>
|
||||
|
||||
</div>
|
||||
<div class="dt">
|
||||
|
||||
Module name.
|
||||
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user