-
Notifications
You must be signed in to change notification settings - Fork 372
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Install cmd: add user setup + cobra cmd
Signed-off-by: Karen Almog <kalmog@mirantis.com>
- Loading branch information
Karen Almog
committed
Dec 1, 2020
1 parent
c981751
commit 17156a8
Showing
8 changed files
with
212 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ bindata | |
.*.stamp | ||
.tmp | ||
.terraform | ||
.idea | ||
*.tfstate* | ||
aws_private.pem | ||
out.json | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"reflect" | ||
"strings" | ||
|
||
"github.com/sirupsen/logrus" | ||
"github.com/spf13/cobra" | ||
|
||
"github.com/k0sproject/k0s/pkg/apis/v1beta1" | ||
"github.com/k0sproject/k0s/pkg/install" | ||
) | ||
|
||
func init() { | ||
installCmd.Flags().StringVar(&role, "role", "server", "node role (possible values: server or worker. In a single-node setup, a worker role should be used)") | ||
} | ||
|
||
var ( | ||
role string | ||
|
||
installCmd = &cobra.Command{ | ||
Use: "install", | ||
Short: "Helper command for setting up k0s on a brand-new system. Must be run as root (or with sudo)", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
switch role { | ||
case "server", "worker": | ||
return setup() | ||
default: | ||
logrus.Errorf("invalid value %s for install role", role) | ||
return cmd.Help() | ||
} | ||
}, | ||
} | ||
) | ||
|
||
// the setup functions: | ||
// * Ensures that the proper users are created | ||
// * sets up startup and logging for k0s | ||
func setup() error { | ||
if os.Geteuid() != 0 { | ||
logrus.Fatal("this command must be run as root!") | ||
} | ||
|
||
if role == "server" { | ||
if err := createServerUsers(); err != nil { | ||
logrus.Errorf("failed to create server users: %v", err) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func createServerUsers() error { | ||
clusterConfig, err := ConfigFromYaml(cfgFile) | ||
if err != nil { | ||
return err | ||
} | ||
users := getUserList(*clusterConfig.Install.SystemUsers) | ||
|
||
var messages []string | ||
for _, v := range users { | ||
if err := install.EnsureUser(v, k0sVars.DataDir); err != nil { | ||
messages = append(messages, err.Error()) | ||
} | ||
} | ||
|
||
if len(messages) > 0 { | ||
return fmt.Errorf(strings.Join(messages, "\n")) | ||
} | ||
return nil | ||
} | ||
|
||
func getUserList(sysUsers v1beta1.SystemUser) []string { | ||
v := reflect.ValueOf(sysUsers) | ||
values := make([]string, v.NumField()) | ||
|
||
for i := 0; i < v.NumField(); i++ { | ||
values[i] = v.Field(i).String() | ||
} | ||
return values | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package install | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
"os/user" | ||
"strings" | ||
|
||
"github.com/sirupsen/logrus" | ||
|
||
"github.com/k0sproject/k0s/internal/util" | ||
) | ||
|
||
// EnsureUser checks if a user exists, and creates it, if it doesn't | ||
// TODO: we should also consider modifying the user, if the user exists, but with wrong settings | ||
func EnsureUser(name string, homeDir string) error { | ||
shell, err := util.GetExecPath("nologin") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
exists, err := util.CheckIfUserExists(name) | ||
// User doesn't exist | ||
if !exists && err == nil { | ||
// Create the User | ||
if err := CreateUser(name, homeDir, *shell); err != nil { | ||
return err | ||
} | ||
// User perhaps exists, but cannot be fetched | ||
} else if err != nil { | ||
return err | ||
} | ||
// verify that user can be fetched, and exists | ||
_, err = user.Lookup(name) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
// CreateUser creates a system user with either `adduser` or `useradd` command | ||
func CreateUser(userName string, homeDir string, shell string) error { | ||
var userCmd string | ||
var userCmdArgs []string | ||
|
||
logrus.Infof("creating user: %s", userName) | ||
_, err := util.GetExecPath("useradd") | ||
if err == nil { | ||
userCmd = "useradd" | ||
userCmdArgs = []string{`--home`, homeDir, `--shell`, shell, `--system`, userName} | ||
} else { | ||
userCmd = "adduser" | ||
userCmdArgs = []string{`--disabled-password`, `--gecos`, `""`, `--home`, homeDir, `--shell`, shell, `--system`, userName} | ||
} | ||
|
||
cmd := exec.Command(userCmd, userCmdArgs...) | ||
if err := execCmd(cmd); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
// cmd wrapper | ||
func execCmd(cmd *exec.Cmd) error { | ||
logrus.Debugf("executing command: %v", quoteCmd(cmd)) | ||
cmd.Stdout = os.Stdout | ||
cmd.Stderr = os.Stderr | ||
|
||
if err := cmd.Run(); err != nil { | ||
return fmt.Errorf("failed to run command %s: %v", quoteCmd(cmd), err) | ||
} | ||
return nil | ||
} | ||
|
||
// parse a cmd struct to string | ||
func quoteCmd(cmd *exec.Cmd) string { | ||
if len(cmd.Args) == 0 { | ||
return fmt.Sprintf("%q", cmd.Path) | ||
} | ||
|
||
var q []string | ||
for _, s := range cmd.Args { | ||
q = append(q, fmt.Sprintf("%q", s)) | ||
} | ||
return strings.Join(q, ` `) | ||
} |