Skip to content

Commit

Permalink
Merge pull request #1592 from aaron-prindle/remove-systemd-requirement
Browse files Browse the repository at this point in the history
Removed systemd dependency from minikube, updated none driver to refl…
  • Loading branch information
aaron-prindle committed Jun 20, 2017
2 parents ac8adc1 + 6639b2d commit 5c2b93c
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 59 deletions.
10 changes: 9 additions & 1 deletion cmd/minikube/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,10 @@ func runStart(cmd *cobra.Command, args []string) {
fmt.Println(`===================
WARNING: IT IS RECOMMENDED NOT TO RUN THE NONE DRIVER ON PERSONAL WORKSTATIONS
The 'none' driver will run an insecure kubernetes apiserver as root that may leave the host vulnerable to CSRF attacks
`)

When using the none driver, the kubectl config and credentials generated will be root owned and will appear in the root home directory.
if os.Getenv("CHANGE_MINIKUBE_NONE_USER") != "" {
fmt.Println(`When using the none driver, the kubectl config and credentials generated will be root owned and will appear in the root home directory.
You will need to move the files to the appropriate location and then set the correct permissions. An example of this is below:
sudo mv /root/.kube $HOME/.kube # this will overwrite any config you have. You may have to append the file contents manually
sudo chown -R $USER $HOME/.kube
Expand All @@ -252,6 +254,12 @@ You will need to move the files to the appropriate location and then set the cor
sudo chown -R $USER $HOME/.minikube
sudo chgrp -R $USER $HOME/.minikube
This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true`)
}
if err := cmdUtil.MaybeChownDirRecursiveToMinikubeUser(constants.GetMinipath()); err != nil {
glog.Errorf("Error recursively changing ownership of directory %s: %s",
constants.GetMinipath(), err)
cmdUtil.MaybeReportErrorAndExit(err)
}
}
}

Expand Down
32 changes: 32 additions & 0 deletions cmd/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"net/http"
"os"
"os/exec"
"os/user"
"path/filepath"
"runtime"
"strings"
Expand Down Expand Up @@ -246,3 +247,34 @@ func KillMountProcess() error {
}
return mountProc.Kill()
}

func MaybeChownDirRecursiveToMinikubeUser(dir string) error {
if os.Getenv("CHANGE_MINIKUBE_NONE_USER") != "" && os.Getenv("SUDO_USER") != "" {
username := os.Getenv("SUDO_USER")
usr, err := user.Lookup(username)
if err != nil {
return errors.Wrap(err, "Error looking up user")
}
uid, err := strconv.Atoi(usr.Uid)
if err != nil {
return errors.Wrapf(err, "Error parsing uid for user: %s", username)
}
gid, err := strconv.Atoi(usr.Gid)
if err != nil {
return errors.Wrapf(err, "Error parsing gid for user: %s", username)
}
if err := ChownR(dir, uid, gid); err != nil {
return errors.Wrapf(err, "Error changing ownership for: %s", dir)
}
}
return nil
}

func ChownR(path string, uid, gid int) error {
return filepath.Walk(path, func(name string, info os.FileInfo, err error) error {
if err == nil {
err = os.Chown(name, uid, gid)
}
return err
})
}
25 changes: 1 addition & 24 deletions pkg/minikube/assets/vm_assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"bytes"
"io"
"os"
"os/user"
"path/filepath"
"strconv"

Expand Down Expand Up @@ -157,29 +156,7 @@ func CopyFileLocal(f CopyableFile) error {

_, err = io.Copy(target, f)
if err != nil {
return errors.Wrap(err, "Error copying file to target location")
}

if os.Getenv("CHANGE_MINIKUBE_NONE_USER") != "" {
username := os.Getenv("SUDO_USER")
if username == "" {
return nil
}
usr, err := user.Lookup(username)
if err != nil {
return errors.Wrap(err, "Error looking up user")
}
uid, err := strconv.Atoi(usr.Uid)
if err != nil {
return errors.Wrapf(err, "Error parsing uid for user: %s", username)
}
gid, err := strconv.Atoi(usr.Gid)
if err != nil {
return errors.Wrapf(err, "Error parsing gid for user: %s", username)
}
if err := os.Chown(targetPath, uid, gid); err != nil {
return errors.Wrapf(err, "Error changing ownership for: %s", targetPath)
}
return errors.Wrap(err, "Error copying file to target location, do you have the correct permissions?")
}
return nil
}
22 changes: 12 additions & 10 deletions pkg/minikube/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,7 @@ func GetLocalkubeStatus(api libmachine.API) (string, error) {
if err != nil {
return "", err
}

statusCmd := localkubeStatusCommand

s, err := RunCommand(h, statusCmd, false)
s, err := RunCommand(h, localkubeStatusCommand, false)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -446,7 +443,7 @@ func GetHostLogs(api libmachine.API, follow bool) (string, error) {
s, err := RunCommand(h, logsCommand, false)

if err != nil {
return "", err
return s, err
}
return s, nil
}
Expand Down Expand Up @@ -577,15 +574,20 @@ func EnsureMinikubeRunningOrExit(api libmachine.API, exitStatus int) {
// RunCommand executes commands for both the local and driver implementations
func RunCommand(h *host.Host, command string, sudo bool) (string, error) {
if h.Driver.DriverName() == "none" {
cmd := exec.Command("/bin/sh", "-c", command)
cmd := exec.Command("/bin/bash", "-c", command)
if sudo {
cmd = exec.Command("sudo", "/bin/sh", "-c", command)
cmd = exec.Command("sudo", "/bin/bash", "-c", command)
}
out, err := cmd.CombinedOutput()
if err != nil {
return "", err
return "", errors.Wrap(err, string(out))
}
return string(out), nil
return string(out), err
}
return h.RunSSHCommand(command)
out, err := h.RunSSHCommand(command)
if err != nil {
return "", errors.Wrap(err, string(out))
}
return string(out), err

}
64 changes: 58 additions & 6 deletions pkg/minikube/cluster/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,20 @@ import (
"net"
"strings"

"k8s.io/minikube/pkg/minikube/constants"
"text/template"

"k8s.io/minikube/pkg/minikube/constants"
)

// Kill any running instances.

var localkubeStartCmdTemplate = "/usr/local/bin/localkube {{.Flags}} --generate-certs=false --logtostderr=true --enable-dns=false"

var startCommandNoSystemdTemplate = `
# Run with nohup so it stays up. Redirect logs to useful places.
sudo sh -c 'PATH=/usr/local/sbin:$PATH nohup {{.LocalkubeStartCmd}} > {{.Stdout}} 2> {{.Stderr}} < /dev/null & echo $! > {{.Pidfile}} &'
`

var localkubeSystemdTmpl = `[Unit]
Description=Localkube
Documentation=https://github.com/kubernetes/minikube/tree/master/pkg/localkube
Expand All @@ -47,28 +54,58 @@ ExecReload=/bin/kill -s HUP $MAINPID
WantedBy=multi-user.target
`

var startCommandTemplate = `
var startCommandTemplate = "if [[ `systemctl` =~ -\\.mount ]] &>/dev/null;" + `then
{{.StartCommandSystemd}}
sudo systemctl daemon-reload
sudo systemctl enable localkube.service
sudo systemctl restart localkube.service || true
else
sudo killall localkube || true
{{.StartCommandNoSystemd}}
fi
`

func GetStartCommand(kubernetesConfig KubernetesConfig) (string, error) {
localkubeStartCommand, err := GenLocalkubeStartCmd(kubernetesConfig)
if err != nil {
return "", err
}
startCommandNoSystemd, err := GetStartCommandNoSystemd(kubernetesConfig, localkubeStartCommand)
if err != nil {
return "", err
}
startCommandSystemd, err := GetStartCommandSystemd(kubernetesConfig, localkubeStartCommand)
if err != nil {
return "", err
}
t := template.Must(template.New("startCommand").Parse(startCommandTemplate))
buf := bytes.Buffer{}
data := struct {
StartCommandSystemd string
StartCommandNoSystemd string
StartCommandSystemd string
}{
StartCommandSystemd: startCommandSystemd,
StartCommandNoSystemd: startCommandNoSystemd,
StartCommandSystemd: startCommandSystemd,
}
if err := t.Execute(&buf, data); err != nil {
return "", err
}
return buf.String(), nil
}

func GetStartCommandNoSystemd(kubernetesConfig KubernetesConfig, localkubeStartCmd string) (string, error) {
t := template.Must(template.New("startCommand").Parse(startCommandNoSystemdTemplate))
buf := bytes.Buffer{}
data := struct {
LocalkubeStartCmd string
Stdout string
Stderr string
Pidfile string
}{
LocalkubeStartCmd: localkubeStartCmd,
Stdout: constants.RemoteLocalKubeOutPath,
Stderr: constants.RemoteLocalKubeErrPath,
Pidfile: constants.LocalkubePIDPath,
}
if err := t.Execute(&buf, data); err != nil {
return "", err
Expand Down Expand Up @@ -130,6 +167,7 @@ func GenLocalkubeStartCmd(kubernetesConfig KubernetesConfig) (string, error) {
flagVals = append(flagVals, fmt.Sprintf("--extra-config=%s", e.String()))
}
flags := strings.Join(flagVals, " ")

t := template.Must(template.New("localkubeStartCmd").Parse(localkubeStartCmdTemplate))
buf := bytes.Buffer{}
data := struct {
Expand All @@ -145,7 +183,12 @@ func GenLocalkubeStartCmd(kubernetesConfig KubernetesConfig) (string, error) {
return buf.String(), nil
}

const logsTemplate = "sudo journalctl {{.Flags}} -u localkube"
const logsTemplate = "if [[ `systemctl` =~ -\\.mount ]] &>/dev/null; " + `then
sudo journalctl {{.Flags}} -u localkube
else
tail -n +1 {{.Flags}} {{.RemoteLocalkubeErrPath}} {{.RemoteLocalkubeOutPath}}
fi
`

func GetLogsCommand(follow bool) (string, error) {
t, err := template.New("logsTemplate").Parse(logsTemplate)
Expand Down Expand Up @@ -173,7 +216,16 @@ func GetLogsCommand(follow bool) (string, error) {
return buf.String(), nil
}

var localkubeStatusCommand = `sudo systemctl is-active localkube 2>&1 1>/dev/null && echo "Running" || echo "Stopped"`
var localkubeStatusCommand = fmt.Sprintf("if [[ `systemctl` =~ -\\.mount ]] &>/dev/null; "+`then
sudo systemctl is-active localkube &>/dev/null && echo "Running" || echo "Stopped"
else
if ps $(cat %s) &>/dev/null; then
echo "Running"
else
echo "Stopped"
fi
fi
`, constants.LocalkubePIDPath)

func GetMountCleanupCommand(path string) string {
return fmt.Sprintf("sudo umount %s;", path)
Expand Down
5 changes: 5 additions & 0 deletions pkg/minikube/kubeconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/clientcmd/api"
"k8s.io/client-go/tools/clientcmd/api/latest"
cmdUtil "k8s.io/minikube/cmd/util"
cfg "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
)
Expand Down Expand Up @@ -166,6 +167,10 @@ func WriteConfig(config *api.Config, filename string) error {
if err := ioutil.WriteFile(filename, data, 0600); err != nil {
return errors.Wrapf(err, "Error writing file %s", filename)
}
if err := cmdUtil.MaybeChownDirRecursiveToMinikubeUser(dir); err != nil {
return errors.Wrapf(err, "Error recursively changing ownership for dir: %s", dir)
}

return nil
}

Expand Down
52 changes: 34 additions & 18 deletions pkg/minikube/machine/drivers/none/none.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,15 @@ limitations under the License.
package none

import (
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/mcnflag"
"github.com/docker/machine/libmachine/state"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/constants"
)

Expand All @@ -50,10 +48,6 @@ func NewDriver(hostName, storePath string) *Driver {

// PreCreateCheck checks that VBoxManage exists and works
func (d *Driver) PreCreateCheck() error {
// check that systemd is installed as it is a requirement
if _, err := exec.LookPath("systemctl"); err != nil {
return errors.New("systemd is a requirement in order to use the none driver")
}
return nil
}

Expand Down Expand Up @@ -96,17 +90,22 @@ func (d *Driver) GetURL() (string, error) {
}

func (d *Driver) GetState() (state.State, error) {
command := `sudo systemctl is-active localkube 2>&1 1>/dev/null && echo "Running" || echo "Stopped"`

path := filepath.Join(constants.GetMinipath(), "tmp-cmd")
ioutil.WriteFile(filepath.Join(constants.GetMinipath(), "tmp-cmd"), []byte(command), os.FileMode(0644))
defer os.Remove(path)
cmd := exec.Command("sudo", "/bin/sh", path)
out, err := cmd.CombinedOutput()
var statuscmd = fmt.Sprintf("if [[ `systemctl` =~ -\\.mount ]] &>/dev/null; "+`then
sudo systemctl is-active localkube &>/dev/null && echo "Running" || echo "Stopped"
else
if ps $(cat %s) &>/dev/null; then
echo "Running"
else
echo "Stopped"
fi
fi
`, constants.LocalkubePIDPath)

out, err := runCommand(statuscmd, true)
if err != nil {
return state.None, err
}
s := strings.TrimSpace(string(out))
s := strings.TrimSpace(out)
if state.Running.String() == s {
return state.Running, nil
} else if state.Stopped.String() == s {
Expand Down Expand Up @@ -162,11 +161,16 @@ func (d *Driver) Start() error {
}

func (d *Driver) Stop() error {
cmd := exec.Command("sudo", "systemctl", "stop", "localkube.service")
if err := cmd.Start(); err != nil {
var stopcmd = fmt.Sprintf("if [[ `systemctl` =~ -\\.mount ]] &>/dev/null; "+`then
sudo systemctl stop localkube.service
else
sudo kill $(cat %s)
fi
`, constants.LocalkubePIDPath)
_, err := runCommand(stopcmd, true)
if err != nil {
return err
}

for {
s, err := d.GetState()
if err != nil {
Expand All @@ -182,3 +186,15 @@ func (d *Driver) Stop() error {
func (d *Driver) RunSSHCommandFromDriver() error {
return fmt.Errorf("driver does not support ssh commands")
}

func runCommand(command string, sudo bool) (string, error) {
cmd := exec.Command("/bin/bash", "-c", command)
if sudo {
cmd = exec.Command("sudo", "/bin/bash", "-c", command)
}
out, err := cmd.CombinedOutput()
if err != nil {
return "", errors.Wrap(err, string(out))
}
return string(out), nil
}

0 comments on commit 5c2b93c

Please sign in to comment.