github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/internal/operator/nodeagent/dep/sysctl/dep.go (about) 1 package sysctl 2 3 import ( 4 "bytes" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "os/exec" 9 "strings" 10 11 "github.com/caos/orbos/internal/operator/common" 12 "github.com/caos/orbos/internal/operator/nodeagent" 13 "github.com/caos/orbos/internal/operator/nodeagent/dep/middleware" 14 "github.com/caos/orbos/mntr" 15 ) 16 17 type Installer interface { 18 isSysctl() 19 nodeagent.Installer 20 } 21 type sysctlDep struct { 22 monitor mntr.Monitor 23 } 24 25 func New(monitor mntr.Monitor) Installer { 26 return &sysctlDep{monitor: monitor} 27 } 28 29 func (sysctlDep) isSysctl() {} 30 31 func (sysctlDep) Is(other nodeagent.Installer) bool { 32 _, ok := middleware.Unwrap(other).(Installer) 33 return ok 34 } 35 36 func (sysctlDep) String() string { return "sysctl" } 37 38 func (*sysctlDep) Equals(other nodeagent.Installer) bool { 39 _, ok := other.(*sysctlDep) 40 return ok 41 } 42 43 func (*sysctlDep) InstalledFilter() []string { return nil } 44 45 var supportedModules = []common.KernelModule{common.IpForward, common.NonLocalBind, common.BridgeNfCallIptables, common.BridgeNfCallIp6tables} 46 47 func Contains(this common.Package, that common.Package) bool { 48 if that.Config == nil { 49 return true 50 } 51 52 for thatKey, thatValue := range that.Config { 53 if this.Config == nil { 54 return false 55 } 56 if thisValue, ok := this.Config[thatKey]; !ok || thatValue == "1" && thisValue != "1" { 57 return false 58 } 59 } 60 return true 61 } 62 63 func Enable(pkg *common.Package, property common.KernelModule) { 64 if pkg.Config == nil { 65 pkg.Config = make(map[string]string) 66 } 67 68 for idx := range supportedModules { 69 module := supportedModules[idx] 70 if _, ok := pkg.Config[string(module)]; !ok { 71 pkg.Config[string(module)] = "0" 72 } 73 } 74 pkg.Config[string(property)] = "1" 75 } 76 77 func (s *sysctlDep) Current() (pkg common.Package, err error) { 78 79 for idx := range supportedModules { 80 module := supportedModules[idx] 81 if err := currentSysctlConfig(s.monitor, module, &pkg); err != nil { 82 return pkg, err 83 } 84 } 85 86 return pkg, nil 87 } 88 89 func (s *sysctlDep) Ensure(_ common.Package, ensure common.Package, _ bool) error { 90 91 if err := ioutil.WriteFile("/etc/sysctl.d/90-orbiter.conf", []byte(fmt.Sprintf( 92 `%s = %s 93 %s = %s 94 %s = %s 95 %s = %s 96 `, 97 string(common.IpForward), oneOrZero(ensure.Config, common.IpForward), 98 string(common.NonLocalBind), oneOrZero(ensure.Config, common.NonLocalBind), 99 string(common.BridgeNfCallIptables), oneOrZero(ensure.Config, common.BridgeNfCallIptables), 100 string(common.BridgeNfCallIp6tables), oneOrZero(ensure.Config, common.BridgeNfCallIp6tables), 101 )), os.ModePerm); err != nil { 102 return err 103 } 104 105 cmd := exec.Command("sysctl", "--system") 106 if output, err := cmd.CombinedOutput(); err != nil { 107 return fmt.Errorf("running %s failed with stderr %s: %w", strings.Join(cmd.Args, " "), string(output), err) 108 } 109 return nil 110 } 111 112 func oneOrZero(cfg map[string]string, property common.KernelModule) string { 113 val := cfg[string(property)] 114 if val == "1" { 115 return val 116 } 117 return "0" 118 } 119 120 func currentSysctlConfig(monitor mntr.Monitor, property common.KernelModule, pkg *common.Package) error { 121 122 propertyStr := string(property) 123 124 outBuf := new(bytes.Buffer) 125 defer outBuf.Reset() 126 errBuf := new(bytes.Buffer) 127 defer errBuf.Reset() 128 129 cmd := exec.Command("sysctl", propertyStr) 130 cmd.Stderr = errBuf 131 cmd.Stdout = outBuf 132 133 fullCmd := strings.Join(cmd.Args, " ") 134 monitor.WithFields(map[string]interface{}{"cmd": fullCmd}).Debug("Executing") 135 136 if err := cmd.Run(); err != nil { 137 errStr := errBuf.String() 138 if !strings.Contains(errStr, "No such file or directory") { 139 return fmt.Errorf("running %s failed with stderr %s: %w", fullCmd, errStr, err) 140 } 141 } 142 143 if pkg.Config == nil { 144 pkg.Config = make(map[string]string) 145 } 146 pkg.Config[propertyStr] = "0" 147 enabled := outBuf.String() == fmt.Sprintf("%s = 1\n", property) 148 if enabled { 149 pkg.Config[propertyStr] = "1" 150 } 151 152 return nil 153 }