From c3cd3bc500a34e1c173c71bfbf48209c43c7890e Mon Sep 17 00:00:00 2001 From: Predrag Rogic Date: Thu, 4 Mar 2021 01:33:01 +0000 Subject: [PATCH 1/2] kvm: check if user belongs to libvirt group --- cmd/minikube/cmd/start.go | 5 +++ pkg/minikube/reason/known_issues.go | 12 ++++++ pkg/minikube/registry/drvs/kvm2/kvm2.go | 49 +++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 5bc2bf74b274..aadecb1c4de8 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -746,6 +746,11 @@ func validateDriver(ds registry.DriverState, existing *config.ClusterConfig) { return } + r := reason.MatchKnownIssue(reason.Kind{}, st.Error, runtime.GOOS) + if r.ID != "" { + exitIfNotForced(*r, st.Error.Error()) + } + if !st.Installed { exit.Message(reason.Kind{ ID: fmt.Sprintf("PROVIDER_%s_NOT_FOUND", strings.ToUpper(name)), diff --git a/pkg/minikube/reason/known_issues.go b/pkg/minikube/reason/known_issues.go index 17347661b401..cdb80017eedb 100644 --- a/pkg/minikube/reason/known_issues.go +++ b/pkg/minikube/reason/known_issues.go @@ -363,6 +363,18 @@ var providerIssues = []match{ }, // KVM hypervisor + { + Kind: Kind{ + ID: "PR_KVM_USER_PERMISSION", + ExitCode: ExProviderPermission, + Style: style.NotAllowed, + Advice: "Ensure that you are a member of the appropriate libvirt group (remember to relogin for group changes to take effect!)", + URL: "https://minikube.sigs.k8s.io/docs/reference/drivers/kvm2/", + Issues: []int{5617, 10070}, + }, + Regexp: re(`libvirt group membership check failed`), + GOOS: []string{"linux"}, + }, { Kind: Kind{ ID: "PR_KVM_CAPABILITIES", diff --git a/pkg/minikube/registry/drvs/kvm2/kvm2.go b/pkg/minikube/registry/drvs/kvm2/kvm2.go index 4ae331fff1cd..3d5e7058592d 100644 --- a/pkg/minikube/registry/drvs/kvm2/kvm2.go +++ b/pkg/minikube/registry/drvs/kvm2/kvm2.go @@ -23,6 +23,7 @@ import ( "fmt" "os" "os/exec" + "os/user" "path/filepath" "strings" "time" @@ -113,16 +114,55 @@ func status() registry.State { return registry.State{Error: err, Fix: "Install libvirt", Doc: docURL} } + // check if the current user is a member of "libvirt*" group + lvMember := false + var lvError error + var usr *user.User + usr, lvError = user.Current() + if lvError == nil { + var gids []string + gids, lvError = usr.GroupIds() + if lvError == nil { + for _, gid := range gids { + var grp *user.Group + grp, lvError = user.LookupGroupId(gid) + if lvError == nil && strings.HasPrefix(grp.Name, "libvirt") { + lvMember = true + break + } + } + } + } + if lvError != nil { + return registry.State{ + Installed: true, + Running: true, + Error: fmt.Errorf("libvirt group membership check failed:\n%v", lvError.Error()), // keep error messsage in sync with reason.providerIssues(Kind.ID: "PR_KVM_USER_PERMISSION") regexp + Reason: "PR_KVM_USER_PERMISSION", + Fix: "Check that libvirtd is properly installed and that you are a member of the appropriate libvirt group (remember to relogin for group changes to take effect!)", + Doc: docURL, + } + } + if !lvMember { + return registry.State{ + Installed: true, + Running: true, + Error: fmt.Errorf("libvirt group membership check failed:\nuser is not a member of the appropriate libvirt group"), // keep error messsage in sync with reason.providerIssues(Kind.ID: "PR_KVM_USER_PERMISSION") regexp + Reason: "PR_KVM_USER_PERMISSION", + Fix: "Check that libvirtd is properly installed and that you are a member of the appropriate libvirt group (remember to relogin for group changes to take effect!)", + Doc: docURL, + } + } + // On Ubuntu 19.10 (libvirt 5.4), this fails if LIBVIRT_DEFAULT_URI is unset cmd := exec.CommandContext(ctx, path, "domcapabilities", "--virttype", "kvm") cmd.Env = append(os.Environ(), fmt.Sprintf("LIBVIRT_DEFAULT_URI=%s", defaultURI())) - out, err := cmd.CombinedOutput() if err != nil { return registry.State{ Installed: true, Running: true, - Error: fmt.Errorf("%s failed:\n%s", strings.Join(cmd.Args, " "), strings.TrimSpace(string(out))), + Error: fmt.Errorf("%s failed:\n%s\n%v", strings.Join(cmd.Args, " "), strings.TrimSpace(string(out)), err), Fix: "Follow your Linux distribution instructions for configuring KVM", Doc: docURL, } @@ -136,9 +176,10 @@ func status() registry.State { Installed: true, Running: true, Error: fmt.Errorf("%s failed:\n%s", strings.Join(cmd.Args, " "), strings.TrimSpace(string(out))), - Fix: "Check that libvirtd is properly installed and that you are a member of the appropriate libvirt group", + Fix: "Check that libvirtd is properly installed and that you are a member of the appropriate libvirt group (remember to relogin for group changes to take effect!)", Doc: docURL, } } - return registry.State{Installed: true, Healthy: true} + + return registry.State{Installed: true, Healthy: true, Running: true} } From 5bd45cbb668e6601eb7abdd337c7993ff049c956 Mon Sep 17 00:00:00 2001 From: Predrag Rogic Date: Sat, 6 Mar 2021 01:04:23 +0000 Subject: [PATCH 2/2] kvm: check if user belongs to libvirt group --- pkg/minikube/registry/drvs/kvm2/kvm2.go | 64 ++++++++++++++----------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/pkg/minikube/registry/drvs/kvm2/kvm2.go b/pkg/minikube/registry/drvs/kvm2/kvm2.go index 3d5e7058592d..dc439d401fa0 100644 --- a/pkg/minikube/registry/drvs/kvm2/kvm2.go +++ b/pkg/minikube/registry/drvs/kvm2/kvm2.go @@ -114,43 +114,27 @@ func status() registry.State { return registry.State{Error: err, Fix: "Install libvirt", Doc: docURL} } - // check if the current user is a member of "libvirt*" group - lvMember := false - var lvError error - var usr *user.User - usr, lvError = user.Current() - if lvError == nil { - var gids []string - gids, lvError = usr.GroupIds() - if lvError == nil { - for _, gid := range gids { - var grp *user.Group - grp, lvError = user.LookupGroupId(gid) - if lvError == nil && strings.HasPrefix(grp.Name, "libvirt") { - lvMember = true - break - } - } - } - } - if lvError != nil { + member, err := isCurrentUserLibvirtGroupMember() + if err != nil { return registry.State{ Installed: true, Running: true, - Error: fmt.Errorf("libvirt group membership check failed:\n%v", lvError.Error()), // keep error messsage in sync with reason.providerIssues(Kind.ID: "PR_KVM_USER_PERMISSION") regexp - Reason: "PR_KVM_USER_PERMISSION", - Fix: "Check that libvirtd is properly installed and that you are a member of the appropriate libvirt group (remember to relogin for group changes to take effect!)", - Doc: docURL, + // keep the error messsage in sync with reason.providerIssues(Kind.ID: "PR_KVM_USER_PERMISSION") regexp + Error: fmt.Errorf("libvirt group membership check failed:\n%v", err.Error()), + Reason: "PR_KVM_USER_PERMISSION", + Fix: "Check that libvirtd is properly installed and that you are a member of the appropriate libvirt group (remember to relogin for group changes to take effect!)", + Doc: docURL, } } - if !lvMember { + if !member { return registry.State{ Installed: true, Running: true, - Error: fmt.Errorf("libvirt group membership check failed:\nuser is not a member of the appropriate libvirt group"), // keep error messsage in sync with reason.providerIssues(Kind.ID: "PR_KVM_USER_PERMISSION") regexp - Reason: "PR_KVM_USER_PERMISSION", - Fix: "Check that libvirtd is properly installed and that you are a member of the appropriate libvirt group (remember to relogin for group changes to take effect!)", - Doc: docURL, + // keep the error messsage in sync with reason.providerIssues(Kind.ID: "PR_KVM_USER_PERMISSION") regexp + Error: fmt.Errorf("libvirt group membership check failed:\nuser is not a member of the appropriate libvirt group"), + Reason: "PR_KVM_USER_PERMISSION", + Fix: "Check that libvirtd is properly installed and that you are a member of the appropriate libvirt group (remember to relogin for group changes to take effect!)", + Doc: docURL, } } @@ -183,3 +167,25 @@ func status() registry.State { return registry.State{Installed: true, Healthy: true, Running: true} } + +// isCurrentUserLibvirtGroupMember returns if the current user is a member of "libvirt*" group. +func isCurrentUserLibvirtGroupMember() (bool, error) { + usr, err := user.Current() + if err != nil { + return false, fmt.Errorf("error getting current user: %w", err) + } + gids, err := usr.GroupIds() + if err != nil { + return false, fmt.Errorf("error getting current user's GIDs: %w", err) + } + for _, gid := range gids { + grp, err := user.LookupGroupId(gid) + if err != nil { + return false, fmt.Errorf("error getting current user's group with GID %q: %w", gid, err) + } + if strings.HasPrefix(grp.Name, "libvirt") { + return true, nil + } + } + return false, nil +}