Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make none driver work as regular user (use sudo on demand) #9379

Merged
merged 3 commits into from
Dec 9, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions cmd/minikube/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,17 @@ func validateUser(drvName string) {
exit.Message(reason.DrvNeedsRoot, `The "{{.driver_name}}" driver requires root privileges. Please run minikube using 'sudo -E minikube start --driver={{.driver_name}}'.`, out.V{"driver_name": drvName})
}

// None driver works with root and without root on Linux
if runtime.GOOS == "linux" && drvName == driver.None {
Git-Jiro marked this conversation as resolved.
Show resolved Hide resolved
if !viper.GetBool(interactive) {
test := exec.Command("sudo", "-n", "echo", "-n")
if err := test.Run(); err != nil {
exit.Message(reason.DrvNeedsRoot, `sudo requires a password, and --interactive=false`)
}
}
return
}

// If root is required, or we are not root, exit early
if driver.NeedsRoot(drvName) || u.Uid != "0" {
return
Expand Down
47 changes: 42 additions & 5 deletions pkg/minikube/command/exec_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ import (
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
"strconv"
"time"

Expand Down Expand Up @@ -85,11 +87,11 @@ func (*execRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) {
}

// Copy copies a file and its permissions
func (*execRunner) Copy(f assets.CopyableFile) error {
func (e *execRunner) Copy(f assets.CopyableFile) error {
dst := path.Join(f.GetTargetDir(), f.GetTargetName())
if _, err := os.Stat(dst); err == nil {
klog.Infof("found %s, removing ...", dst)
if err := os.Remove(dst); err != nil {
if err := e.Remove(f); err != nil {
return errors.Wrapf(err, "error removing file %s", dst)
}
}
Expand All @@ -105,12 +107,47 @@ func (*execRunner) Copy(f assets.CopyableFile) error {
return errors.Wrapf(err, "error converting permissions %s to integer", f.GetPermissions())
}

return writeFile(dst, f, os.FileMode(perms))
switch runtime.GOOS {
case "linux":
Git-Jiro marked this conversation as resolved.
Show resolved Hide resolved
// write to temp location ...
tmpfile, err := ioutil.TempFile("", "minikube")
if err != nil {
return errors.Wrapf(err, "error creating tempfile")
}
defer os.Remove(tmpfile.Name())
err = writeFile(tmpfile.Name(), f, os.FileMode(perms))
if err != nil {
return errors.Wrapf(err, "error writing to tempfile %s", tmpfile.Name())
}

// ... then use sudo to move to target ...
_, err = e.RunCmd(exec.Command("sudo", "cp", "-a", tmpfile.Name(), dst))
if err != nil {
return errors.Wrapf(err, "error copying tempfile %s to dst %s", tmpfile.Name(), dst)
}

// ... then fix file permission that should have been fine because of "cp -a"
err = os.Chmod(dst, os.FileMode(perms))
return err

default:
return writeFile(dst, f, os.FileMode(perms))
}

}

// Remove removes a file
func (*execRunner) Remove(f assets.CopyableFile) error {
func (e *execRunner) Remove(f assets.CopyableFile) error {
dst := filepath.Join(f.GetTargetDir(), f.GetTargetName())
klog.Infof("rm: %s", dst)
return os.Remove(dst)
if err := os.Remove(dst); err != nil {
if !os.IsPermission(err) {
return err
}
_, err = e.RunCmd(exec.Command("sudo", "rm", "-f", dst))
if err != nil {
return err
}
}
return nil
}
2 changes: 1 addition & 1 deletion pkg/minikube/driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func BareMetal(name string) bool {

// NeedsRoot returns true if driver needs to run with root privileges
func NeedsRoot(name string) bool {
Git-Jiro marked this conversation as resolved.
Show resolved Hide resolved
return name == None
Git-Jiro marked this conversation as resolved.
Show resolved Hide resolved
return false
}

// NeedsPortForward returns true if driver is unable provide direct IP connectivity
Expand Down
6 changes: 4 additions & 2 deletions pkg/minikube/registry/drvs/none/none.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ func status() registry.State {
}

Git-Jiro marked this conversation as resolved.
Show resolved Hide resolved
if u.Uid != "0" {
return registry.State{Error: fmt.Errorf("the 'none' driver must be run as the root user"), Healthy: false, Fix: "For non-root usage, try the newer 'docker' driver", Installed: true}
test := exec.Command("sudo", "-n", "echo", "-n")
if err := test.Run(); err != nil {
return registry.State{Error: fmt.Errorf("running the 'none' driver as a regular user requires sudo permissions"), Healthy: false}
}
}

return registry.State{Installed: true, Healthy: true}
}