Skip to content

Commit d44af2b

Browse files
feat: enable ip_forward, disable arp_ignore arp_filter (#1484)
* feat: enable ip_forward, disable arp_ignore arp_filter we are now enabling ip_forward on the node, this is required for the embedded-cluster to work properly. we are also disabling arp_ignore and arp_filter to make sure the system is prepared for calico. * chore: do not fail if unable to config sysctl * feat: does not fail if unable to write sysctl config we only fail if the sysctl binary is not present on the system as we know that preflights depend on it. if we fail to configure sysctl we just move on as the preflights are expected to fail later on. * feat: config sysctl on 'run-prelights' command we need to configure sysctl before running the preflights. * chore: add unit tests for the new functions added unit tests around the sysctl configuation functions.
1 parent 3f4d8bd commit d44af2b

File tree

11 files changed

+158
-0
lines changed

11 files changed

+158
-0
lines changed

pkg/cmd/install.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,12 @@ func installCommand() *cli.Command {
781781
}
782782

783783
metrics.ReportApplyStarted(c)
784+
785+
logrus.Debugf("configuring sysctl")
786+
if err := configutils.ConfigureSysctl(provider); err != nil {
787+
return fmt.Errorf("unable to configure sysctl: %w", err)
788+
}
789+
784790
logrus.Debugf("configuring network manager")
785791
if err := configureNetworkManager(c, provider); err != nil {
786792
return fmt.Errorf("unable to configure network manager: %w", err)

pkg/cmd/join.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,11 @@ var joinCommand = &cli.Command{
249249
return err
250250
}
251251

252+
logrus.Debugf("configuring sysctl")
253+
if err := configutils.ConfigureSysctl(provider); err != nil {
254+
return fmt.Errorf("unable to configure sysctl: %w", err)
255+
}
256+
252257
// jcmd.InstallationSpec.MetricsBaseURL is the replicated.app endpoint url
253258
replicatedAPIURL := jcmd.InstallationSpec.MetricsBaseURL
254259
proxyRegistryURL := fmt.Sprintf("https://%s", defaults.ProxyRegistryAddress)

pkg/cmd/preflights.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"strings"
77

88
ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1"
9+
"github.com/replicatedhq/embedded-cluster/pkg/configutils"
910
"github.com/replicatedhq/embedded-cluster/pkg/defaults"
1011
"github.com/replicatedhq/embedded-cluster/pkg/versions"
1112
"github.com/sirupsen/logrus"
@@ -79,6 +80,10 @@ func installRunPreflightsCommand() *cli.Command {
7980
return err
8081
}
8182

83+
if err := configutils.ConfigureSysctl(provider); err != nil {
84+
return err
85+
}
86+
8287
applier, err := getAddonsApplier(c, runtimeConfig, "", proxy)
8388
if err != nil {
8489
return err
@@ -170,6 +175,10 @@ var joinRunPreflightsCommand = &cli.Command{
170175
return err
171176
}
172177

178+
if err := configutils.ConfigureSysctl(provider); err != nil {
179+
return err
180+
}
181+
173182
applier, err := getAddonsApplier(c, jcmd.InstallationSpec.RuntimeConfig, "", jcmd.InstallationSpec.Proxy)
174183
if err != nil {
175184
return err

pkg/cmd/reset.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,10 @@ func resetCommand() *cli.Command {
501501
return fmt.Errorf("failed to remove embedded cluster data config: %w", err)
502502
}
503503

504+
if err := helpers.RemoveAll("/etc/sysctl.d/99-embedded-cluster.conf"); err != nil {
505+
return fmt.Errorf("failed to remove embedded cluster sysctl config: %w", err)
506+
}
507+
504508
if _, err := helpers.RunCommand("reboot"); err != nil {
505509
return err
506510
}

pkg/cmd/restore.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,11 @@ func restoreCommand() *cli.Command {
969969
}
970970
}
971971

972+
logrus.Debugf("configuring sysctl")
973+
if err := configutils.ConfigureSysctl(provider); err != nil {
974+
return fmt.Errorf("unable to configure sysctl: %w", err)
975+
}
976+
972977
proxy, err := getProxySpecFromFlags(c)
973978
if err != nil {
974979
return fmt.Errorf("unable to get proxy spec from flags: %w", err)

pkg/configutils/runtime.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,22 @@ package configutils
33
import (
44
"fmt"
55
"os"
6+
"os/exec"
67
"path/filepath"
78

89
"github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1"
910
"github.com/replicatedhq/embedded-cluster/pkg/defaults"
11+
"github.com/replicatedhq/embedded-cluster/pkg/goods"
1012
"github.com/replicatedhq/embedded-cluster/pkg/helpers"
13+
"github.com/sirupsen/logrus"
1114
"sigs.k8s.io/yaml"
1215
)
1316

17+
// sysctlConfigPath is the path to the sysctl config file that is used to configure
18+
// the embedded cluster. This could have been a constant but we want to be able to
19+
// override it for testing purposes.
20+
var sysctlConfigPath = "/etc/sysctl.d/99-embedded-cluster.conf"
21+
1422
func WriteRuntimeConfig(spec *v1beta1.RuntimeConfigSpec) error {
1523
if spec == nil {
1624
return nil
@@ -57,3 +65,24 @@ func ReadRuntimeConfig() (*v1beta1.RuntimeConfigSpec, error) {
5765

5866
return &spec, nil
5967
}
68+
69+
// ConfigureSysctl writes the sysctl config file for the embedded cluster and
70+
// reloads the sysctl configuration. This function has a distinct behavior: if
71+
// the sysctl binary does not exist it returns an error but if it fails to lay
72+
// down the sysctl config on disk it simply returns nil.
73+
func ConfigureSysctl(provider *defaults.Provider) error {
74+
if _, err := exec.LookPath("sysctl"); err != nil {
75+
return fmt.Errorf("unable to find sysctl binary: %w", err)
76+
}
77+
78+
materializer := goods.NewMaterializer(provider)
79+
if err := materializer.SysctlConfig(sysctlConfigPath); err != nil {
80+
logrus.Debugf("unable to materialize sysctl config: %v", err)
81+
return nil
82+
}
83+
84+
if _, err := helpers.RunCommand("sysctl", "--system"); err != nil {
85+
logrus.Debugf("unable to configure sysctl: %v", err)
86+
}
87+
return nil
88+
}

pkg/configutils/runtime_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package configutils
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
8+
"github.com/replicatedhq/embedded-cluster/pkg/defaults"
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestConfigureSysctl(t *testing.T) {
13+
basedir, err := os.MkdirTemp("", "embedded-cluster-test-base-dir")
14+
assert.NoError(t, err)
15+
defer os.RemoveAll(basedir)
16+
17+
orig := sysctlConfigPath
18+
defer func() {
19+
sysctlConfigPath = orig
20+
}()
21+
22+
provider := defaults.NewProvider(basedir)
23+
24+
// happy path.
25+
dstdir, err := os.MkdirTemp("", "embedded-cluster-test")
26+
assert.NoError(t, err)
27+
defer os.RemoveAll(dstdir)
28+
29+
sysctlConfigPath = filepath.Join(dstdir, "sysctl.conf")
30+
err = ConfigureSysctl(provider)
31+
assert.NoError(t, err)
32+
33+
// check that the file exists.
34+
_, err = os.Stat(sysctlConfigPath)
35+
assert.NoError(t, err)
36+
37+
// now use a non-existing directory.
38+
sysctlConfigPath = filepath.Join(dstdir, "non-existing-dir", "sysctl.conf")
39+
// we do not expect an error here.
40+
assert.NoError(t, err)
41+
}

pkg/goods/goods.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ var (
2020
systemdfs embed.FS
2121
//go:embed internal/bins/*
2222
internalBinfs embed.FS
23+
//go:embed static/*
24+
staticfs embed.FS
2325
)
2426

2527
// K0sBinarySHA256 returns the SHA256 checksum of the embedded k0s binary.

pkg/goods/materializer.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,18 @@ func (m *Materializer) CalicoNetworkManagerConfig() error {
7676
return nil
7777
}
7878

79+
// SysctlConfig writes the embedded sysctl config to the /etc/sysctl.d directory.
80+
func (m *Materializer) SysctlConfig(dstpath string) error {
81+
content, err := staticfs.ReadFile("static/99-embedded-cluster.conf")
82+
if err != nil {
83+
return fmt.Errorf("unable to open embedded sysctl config file: %w", err)
84+
}
85+
if err := os.WriteFile(dstpath, content, 0644); err != nil {
86+
return fmt.Errorf("unable to write file: %w", err)
87+
}
88+
return nil
89+
}
90+
7991
// Materialize writes to disk all embedded assets.
8092
func (m *Materializer) Materialize() error {
8193
if err := m.Binaries(); err != nil {

pkg/goods/materializer_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package goods
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestMaterializer_SysctlConfig(t *testing.T) {
12+
m := NewMaterializer(nil)
13+
14+
// happy path.
15+
dstdir, err := os.MkdirTemp("", "embedded-cluster-test")
16+
assert.NoError(t, err)
17+
defer os.RemoveAll(dstdir)
18+
19+
dstpath := filepath.Join(dstdir, "sysctl.conf")
20+
err = m.SysctlConfig(dstpath)
21+
assert.NoError(t, err)
22+
23+
expected, err := os.ReadFile(dstpath)
24+
assert.NoError(t, err)
25+
26+
content, err := staticfs.ReadFile("static/99-embedded-cluster.conf")
27+
assert.NoError(t, err)
28+
assert.Equal(t, string(expected), string(content))
29+
30+
// write to a non-existent directory.
31+
dstpath = filepath.Join(dstdir, "dir-does-not-exist", "sysctl.conf")
32+
err = m.SysctlConfig(dstpath)
33+
assert.Contains(t, err.Error(), "no such file or directory")
34+
}

0 commit comments

Comments
 (0)