Skip to content

Commit

Permalink
feat: allow overriding KSPP kernel parameters
Browse files Browse the repository at this point in the history
Fixes: #4385

Now sysctls defined in the config can override kernel args defined by
defaults controller.
In that case controller shows the warning that tells which param was
overridden and the new value and tells that it is not recommended.

Signed-off-by: Artem Chernyshev <artem.chernyshev@talos-systems.com>
  • Loading branch information
Unix4ever committed Dec 3, 2021
1 parent 6377f3d commit 4f5d9da
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (ctrl *KernelParamDefaultsController) Inputs() []controller.Input {
func (ctrl *KernelParamDefaultsController) Outputs() []controller.Output {
return []controller.Output{
{
Type: runtime.KernelParamSpecType,
Type: runtime.KernelParamDefaultSpecType,
Kind: controller.OutputShared,
},
}
Expand All @@ -55,13 +55,13 @@ func (ctrl *KernelParamDefaultsController) Run(ctx context.Context, r controller

for _, prop := range kernelParams {
value := prop.Value
item := runtime.NewKernelParamSpec(runtime.NamespaceName, prop.Key)
item := runtime.NewKernelParamDefaultSpec(runtime.NamespaceName, prop.Key)

if err := r.Modify(ctx, item, func(res resource.Resource) error {
res.(*runtime.KernelParamSpec).TypedSpec().Value = value
res.(*runtime.KernelParamDefaultSpec).TypedSpec().Value = value

if item.Metadata().ID() == "net.ipv6.conf.default.forwarding" {
res.(*runtime.KernelParamSpec).TypedSpec().IgnoreErrors = true
res.(*runtime.KernelParamDefaultSpec).TypedSpec().IgnoreErrors = true
}

return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ func (suite *KernelParamDefaultsSuite) TestContainerMode() {

suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertResource(
resource.NewMetadata(runtimeresource.NamespaceName, runtimeresource.KernelParamSpecType, prop.Key, resource.VersionUndefined),
resource.NewMetadata(runtimeresource.NamespaceName, runtimeresource.KernelParamDefaultSpecType, prop.Key, resource.VersionUndefined),
func(res resource.Resource) bool {
return res.(*runtimeresource.KernelParamSpec).TypedSpec().Value == prop.Value
return res.(runtimeresource.KernelParam).TypedSpec().Value == prop.Value
},
),
))
Expand All @@ -93,9 +93,9 @@ func (suite *KernelParamDefaultsSuite) TestMetalMode() {

suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertResource(
resource.NewMetadata(runtimeresource.NamespaceName, runtimeresource.KernelParamSpecType, prop.Key, resource.VersionUndefined),
resource.NewMetadata(runtimeresource.NamespaceName, runtimeresource.KernelParamDefaultSpecType, prop.Key, resource.VersionUndefined),
func(res resource.Resource) bool {
return res.(*runtimeresource.KernelParamSpec).TypedSpec().Value == prop.Value
return res.(runtimeresource.KernelParam).TypedSpec().Value == prop.Value
},
),
))
Expand Down
32 changes: 27 additions & 5 deletions internal/app/machined/pkg/controllers/runtime/kernel_param_spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ func (ctrl *KernelParamSpecController) Name() string {
// Inputs implements controller.Controller interface.
func (ctrl *KernelParamSpecController) Inputs() []controller.Input {
return []controller.Input{
{
Namespace: runtime.NamespaceName,
Type: runtime.KernelParamDefaultSpecType,
Kind: controller.InputStrong,
},
{
Namespace: runtime.NamespaceName,
Type: runtime.KernelParamSpecType,
Expand Down Expand Up @@ -68,19 +73,36 @@ func (ctrl *KernelParamSpecController) Run(ctx context.Context, r controller.Run
case <-ctx.Done():
return nil
case <-r.EventCh():
list, err := r.List(ctx, resource.NewMetadata(runtime.NamespaceName, runtime.KernelParamSpecType, "", resource.VersionUndefined))
defaults, err := r.List(ctx, resource.NewMetadata(runtime.NamespaceName, runtime.KernelParamDefaultSpecType, "", resource.VersionUndefined))
if err != nil {
return err
}

configs, err := r.List(ctx, resource.NewMetadata(runtime.NamespaceName, runtime.KernelParamSpecType, "", resource.VersionUndefined))
if err != nil {
return err
}

touchedIDs := map[string]struct{}{}
configsCounts := len(configs.Items)

list := configs.Items

list = append(list, defaults.Items...)

touchedIDs := map[string]string{}

var errs *multierror.Error

for _, item := range list.Items {
spec := item.(*runtime.KernelParamSpec).TypedSpec()
for i, item := range list {
spec := item.(runtime.KernelParam).TypedSpec()
key := item.Metadata().ID()

if value, duplicate := touchedIDs[key]; i >= configsCounts && duplicate {
logger.Warn("overriding KSPP enforced parameter, this is not recommended", zap.String("key", key), zap.String("value", value))

continue
}

if err = ctrl.updateKernelParam(ctx, r, key, spec.Value); err != nil {
if errors.Is(err, os.ErrNotExist) && spec.IgnoreErrors {
status := runtime.NewKernelParamStatus(runtime.NamespaceName, key)
Expand All @@ -99,7 +121,7 @@ func (ctrl *KernelParamSpecController) Run(ctx context.Context, r controller.Run
continue
}

touchedIDs[item.Metadata().ID()] = struct{}{}
touchedIDs[item.Metadata().ID()] = spec.Value
}

for key := range ctrl.state {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func NewState() (*State, error) {
&perf.CPU{},
&perf.Memory{},
&runtime.KernelParamSpec{},
&runtime.KernelParamDefaultSpec{},
&runtime.KernelParamStatus{},
&runtime.MountStatus{},
&secrets.API{},
Expand Down
1 change: 0 additions & 1 deletion internal/integration/cli/support.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ func (suite *SupportSuite) TestSupport() {
"machined.state",
"kubelet.log",
"kubelet.state",
"talosResources/kernelparamspecs.runtime.talos.dev.yaml",
"talosResources/kernelparamstatuses.runtime.talos.dev.yaml",
"kube-system/kube-apiserver.log",
"mounts",
Expand Down
63 changes: 63 additions & 0 deletions pkg/machinery/resources/runtime/kernel_params_spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ const NamespaceName resource.Namespace = v1alpha1.NamespaceName
// KernelParamSpecType is type of KernelParam resource.
const KernelParamSpecType = resource.Type("KernelParamSpecs.runtime.talos.dev")

// KernelParamDefaultSpecType is type of KernelParam resource for default kernel params.
const KernelParamDefaultSpecType = resource.Type("KernelParamDefaultSpecs.runtime.talos.dev")

// KernelParam interface.
type KernelParam interface {
TypedSpec() *KernelParamSpecSpec
}

// KernelParamSpec resource holds sysctl flags to define.
type KernelParamSpec struct {
md resource.Metadata
Expand Down Expand Up @@ -79,3 +87,58 @@ func (r *KernelParamSpec) ResourceDefinition() meta.ResourceDefinitionSpec {
func (r *KernelParamSpec) TypedSpec() *KernelParamSpecSpec {
return &r.spec
}

// NewKernelParamDefaultSpec initializes a KernelParamSpec resource.
func NewKernelParamDefaultSpec(namespace resource.Namespace, id resource.ID) *KernelParamDefaultSpec {
r := &KernelParamDefaultSpec{
md: resource.NewMetadata(namespace, KernelParamDefaultSpecType, id, resource.VersionUndefined),
spec: KernelParamSpecSpec{},
}

r.md.BumpVersion()

return r
}

// KernelParamDefaultSpec implements meta.ResourceDefinitionProvider interface.
type KernelParamDefaultSpec struct {
md resource.Metadata
spec KernelParamSpecSpec
}

// Metadata implements resource.Resource.
func (r *KernelParamDefaultSpec) Metadata() *resource.Metadata {
return &r.md
}

// Spec implements resource.Resource.
func (r *KernelParamDefaultSpec) Spec() interface{} {
return r.spec
}

func (r *KernelParamDefaultSpec) String() string {
return fmt.Sprintf("runtime.KernelParamDefaultSpec.(%q)", r.md.ID())
}

// DeepCopy implements resource.Resource.
func (r *KernelParamDefaultSpec) DeepCopy() resource.Resource {
return &KernelParamDefaultSpec{
md: r.md,
spec: r.spec,
}
}

// ResourceDefinition implements meta.ResourceDefinitionProvider interface.
func (r *KernelParamDefaultSpec) ResourceDefinition() meta.ResourceDefinitionSpec {
return meta.ResourceDefinitionSpec{
Type: KernelParamDefaultSpecType,
Aliases: []resource.Type{},
DefaultNamespace: NamespaceName,
PrintColumns: []meta.PrintColumn{},
}
}

// TypedSpec allows to access the KernelParamSpecSpec with the proper type.
func (r *KernelParamDefaultSpec) TypedSpec() *KernelParamSpecSpec {
return &r.spec
}

0 comments on commit 4f5d9da

Please sign in to comment.