Skip to content

Commit

Permalink
fix: accept sysctl paths with dots
Browse files Browse the repository at this point in the history
Fixes #7878

Signed-off-by: Nico Berlee <nico.berlee@on2it.net>
Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
  • Loading branch information
nberlee authored and smira committed Oct 20, 2023
1 parent 4919f6e commit a009f5c
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 5 deletions.
18 changes: 18 additions & 0 deletions hack/release.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,24 @@ Previously, [network device selectors](https://www.talos.dev/v1.6/talos-guides/n
title = "KubePrism"
description = """\
[KubePrism](https://www.talos.dev/v1.6/kubernetes-guides/configuration/kubeprism/) is enabled by default on port 7445.
"""

[notes.sysctl]
title = "Sysctl"
description = """\
Talos now handles sysctl/sysfs key names in line with sysctl.conf(5):
* if the first separator is '/', no conversion is done
* if the first separator is '.', dots and slashes are remapped
Example (both sysctls are equivalent):
```yaml
machine:
sysctls:
net/ipv6/conf/eth0.100/disable_ipv6: "1"
net.ipv6.conf.eth0/100.disable_ipv6: "1"
```
"""

[make_deps]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package runtime
import (
"context"
"fmt"
"strings"

"github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource"
Expand Down Expand Up @@ -71,7 +70,7 @@ func (ctrl *KernelParamConfigController) Run(ctx context.Context, r controller.R
r.StartTrackingOutputs()

setKernelParam := func(kind, key, value string) error {
item := runtime.NewKernelParamSpec(runtime.NamespaceName, strings.Join([]string{kind, key}, "."))
item := runtime.NewKernelParamSpec(runtime.NamespaceName, kind+"."+key)

return r.Modify(ctx, item, func(res resource.Resource) error {
res.(*runtime.KernelParamSpec).TypedSpec().Value = value
Expand Down
5 changes: 3 additions & 2 deletions pkg/machinery/config/types/v1alpha1/v1alpha1_examples.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,9 @@ func machineTimeExample() *TimeConfig {

func machineSysctlsExample() map[string]string {
return map[string]string{
"kernel.domainname": "talos.dev",
"net.ipv4.ip_forward": "0",
"kernel.domainname": "talos.dev",
"net.ipv4.ip_forward": "0",
"net/ipv6/conf/eth0.100/disable_ipv6": "1",
}
}

Expand Down
51 changes: 50 additions & 1 deletion pkg/machinery/kernel/kernel.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
package kernel

import (
"path"
"path/filepath"
"strings"
)

Expand Down Expand Up @@ -44,5 +46,52 @@ type Param struct {

// Path returns the path to the systctl file under /proc/sys or /sys.
func (prop *Param) Path() string {
return "/" + strings.ReplaceAll(prop.Key, ".", "/")
// From: https://man7.org/linux/man-pages/man5/sysctl.d.5.html
//
// Note that either "/" or "." may be used as separators within
// sysctl variable names. If the first separator is a slash,
// remaining slashes and dots are left intact. If the first
// separator is a dot, dots and slashes are interchanged.
// "kernel.domainname=foo" and "kernel/domainname=foo" are
// equivalent and will cause "foo" to be written to
// /proc/sys/kernel/domainname. Either
// "net.ipv4.conf.enp3s0/200.forwarding" or
// "net/ipv4/conf/enp3s0.200/forwarding" may be used to refer to
// /proc/sys/net/ipv4/conf/enp3s0.200/forwarding
//
// detect the first separator, either '.' or '/'
// according to the sysctl man page, if the first separator is '/', we keep slashes intact,
// otherwise we convert dots to slashes
keyPath := prop.Key
prefix := ""

// trim standard prefix
for _, stdPrefix := range []string{Sysctl, Sysfs} {
if strings.HasPrefix(prop.Key, stdPrefix+".") {
keyPath = keyPath[len(stdPrefix)+1:]
prefix = stdPrefix

break
}
}

firstSepIndex := strings.IndexAny(keyPath, "./")
// if the first separator is a dot, remap '.' to '/', and '/' to '.'
if firstSepIndex != -1 && keyPath[firstSepIndex] == '.' {
keyPath = strings.Map(
func(r rune) rune {
switch r {
case '.':
return '/'
case '/':
return '.'
default:
return r
}
},
keyPath,
)
}

return path.Clean("/" + filepath.Join(strings.ReplaceAll(prefix, ".", "/"), keyPath))
}
63 changes: 63 additions & 0 deletions pkg/machinery/kernel/kernel_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// 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 kernel_test

import (
"testing"

"github.com/siderolabs/talos/pkg/machinery/kernel"
)

func TestParamPath(t *testing.T) {
tests := []struct {
name string
param *kernel.Param
want string
}{
{
name: "Test Sysfs Path",
param: &kernel.Param{
Key: kernel.Sysfs + ".block.sda.queue.scheduler",
},
want: "/sys/block/sda/queue/scheduler",
},
{
name: "Test Sysctl Path",
param: &kernel.Param{
Key: kernel.Sysctl + ".net.ipv6.conf.eth0.accept_ra",
},
want: "/proc/sys/net/ipv6/conf/eth0/accept_ra",
},
{
name: "Test Sysctl Path with vlan interface untouched",
param: &kernel.Param{
Key: kernel.Sysctl + ".net/ipv6/conf/eth0.103/disable_ipv6",
},
want: "/proc/sys/net/ipv6/conf/eth0.103/disable_ipv6",
},
{
name: "Test Sysctl Path with vlan interface inverted",
param: &kernel.Param{
Key: kernel.Sysctl + ".net.ipv6.conf.eth0/103.disable_ipv6",
},
want: "/proc/sys/net/ipv6/conf/eth0.103/disable_ipv6",
},
{
name: "Test Sysctl Path with invalid symbols which translate to '..'",
param: &kernel.Param{
Key: kernel.Sysctl + ".net.ipv6.conf.eth0/103.//.disable_ipv6",
},
want: "/proc/sys/net/ipv6/conf/disable_ipv6",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.param.Path(); got != tt.want {
t.Errorf("Param.Path() = %v, want %v", got, tt.want)
}
})
}
}
1 change: 1 addition & 0 deletions website/content/v1.6/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ time:
sysctls:
kernel.domainname: talos.dev
net.ipv4.ip_forward: "0"
net/ipv6/conf/eth0.100/disable_ipv6: "1"
{{< /highlight >}}</details> | |
|`sysfs` |map[string]string |Used to configure the machine's sysfs. <details><summary>Show example(s)</summary>{{< highlight yaml >}}
sysfs:
Expand Down

0 comments on commit a009f5c

Please sign in to comment.