From 2a40ef473f906b6a165690480dc000b9e5560258 Mon Sep 17 00:00:00 2001 From: Oz N Tiram Date: Sat, 19 Jan 2019 05:54:28 +0100 Subject: [PATCH] Add initial support for OpenRC * Gentoo has init scripts for kubelet * Added a new method of the InitSystem Interface This helps issuing nicer messages when not on systemd. * OpenRCInitSystem.ServiceExists uses CombinedOutput because the behaviour of OpenRC is different from systemd. This is a partial fix for https://github.com/kubernetes/kubeadm/issues/1295 --- pkg/util/initsystem/initsystem.go | 66 +++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/pkg/util/initsystem/initsystem.go b/pkg/util/initsystem/initsystem.go index 6638bab5eb2..da24217ebc3 100644 --- a/pkg/util/initsystem/initsystem.go +++ b/pkg/util/initsystem/initsystem.go @@ -23,6 +23,9 @@ import ( ) type InitSystem interface { + // return a string describing how to enable a service + EnableCommand(service string) string + // ServiceStart tries to start a specific service ServiceStart(service string) error @@ -42,8 +45,63 @@ type InitSystem interface { ServiceIsActive(service string) bool } +type OpenRCInitSystem struct{} + +func (openrc OpenRCInitSystem) ServiceStart(service string) error { + args := []string{service, "start"} + return exec.Command("rc-service", args...).Run() +} + +func (openrc OpenRCInitSystem) ServiceStop(service string) error { + args := []string{service, "stop"} + return exec.Command("rc-service", args...).Run() +} + +func (openrc OpenRCInitSystem) ServiceRestart(service string) error { + args := []string{service, "restart"} + return exec.Command("rc-service", args...).Run() +} + +// openrc writes to stderr if a service is not found or not enabled +// this is in contrast to systemd which only writes to stdout. +// Hence, we use the Combinedoutput, and ignore the error. +func (openrc OpenRCInitSystem) ServiceExists(service string) bool { + args := []string{service, "status"} + outBytes, _ := exec.Command("rc-service", args...).CombinedOutput() + if strings.Contains(string(outBytes), "does not exist") { + return false + } + return true +} + +func (openrc OpenRCInitSystem) ServiceIsEnabled(service string) bool { + args := []string{"show", "default"} + outBytes, _ := exec.Command("rc-update", args...).Output() + if strings.Contains(string(outBytes), service) { + return true + } + return false +} + +func (openrc OpenRCInitSystem) ServiceIsActive(service string) bool { + args := []string{service, "status"} + outBytes, _ := exec.Command("rc-service", args...).Output() + if strings.Contains(string(outBytes), "stopped") { + return false + } + return true +} + +func (openrc OpenRCInitSystem) EnableCommand(service string) string { + return fmt.Sprintf("rc-update add %s default", service) +} + type SystemdInitSystem struct{} +func (sysd SystemdInitSystem) EnableCommand(service string) string { + return fmt.Sprintf("systemctl enable %s.service", service) +} + func (sysd SystemdInitSystem) reloadSystemd() error { if err := exec.Command("systemctl", "daemon-reload").Run(); err != nil { return fmt.Errorf("failed to reload systemd: %v", err) @@ -110,6 +168,10 @@ func (sysd SystemdInitSystem) ServiceIsActive(service string) bool { // WindowsInitSystem is the windows implementation of InitSystem type WindowsInitSystem struct{} +func (sysd WindowsInitSystem) EnableCommand(service string) string { + return fmt.Sprintf("Set-Service '%s' -StartupType Automatic", service) +} + func (sysd WindowsInitSystem) ServiceStart(service string) error { args := []string{"Start-Service", service} err := exec.Command("powershell", args...).Run() @@ -171,6 +233,10 @@ func GetInitSystem() (InitSystem, error) { if err == nil { return &SystemdInitSystem{}, nil } + _, err = exec.LookPath("openrc") + if err == nil { + return &OpenRCInitSystem{}, nil + } _, err = exec.LookPath("wininit.exe") if err == nil { return &WindowsInitSystem{}, nil