Skip to content

Commit 8a7db45

Browse files
authored
Merge pull request #4264 from twz123/renovate-install-users
Rework user installation functions
2 parents 3f37463 + 6bf01b6 commit 8a7db45

File tree

3 files changed

+50
-60
lines changed

3 files changed

+50
-60
lines changed

cmd/install/install.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ func (c *command) setup(role string, args []string, installFlags *installFlags)
6565
}
6666

6767
if role == "controller" {
68-
if err := install.CreateControllerUsers(nodeConfig, c.K0sVars); err != nil {
68+
systemUsers := nodeConfig.Spec.Install.SystemUsers
69+
homeDir := c.K0sVars.DataDir
70+
if err := install.EnsureControllerUsers(systemUsers, homeDir); err != nil {
6971
return fmt.Errorf("failed to create controller users: %w", err)
7072
}
7173
}

pkg/cleanup/users.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func (u *users) Run() error {
3636
if err != nil {
3737
logrus.Errorf("failed to get cluster setup: %v", err)
3838
}
39-
if err := install.DeleteControllerUsers(cfg); err != nil {
39+
if err := install.DeleteControllerUsers(cfg.Spec.Install.SystemUsers); err != nil {
4040
// don't fail, just notify on delete error
4141
logrus.Warnf("failed to delete controller users: %v", err)
4242
}

pkg/install/users.go

+46-58
Original file line numberDiff line numberDiff line change
@@ -18,68 +18,58 @@ package install
1818

1919
import (
2020
"errors"
21-
"fmt"
2221
"os/exec"
2322
"os/user"
24-
"reflect"
25-
"strings"
23+
"slices"
2624

2725
"github.com/sirupsen/logrus"
2826

29-
"github.com/k0sproject/k0s/internal/pkg/stringslice"
3027
"github.com/k0sproject/k0s/internal/pkg/users"
3128
"github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1"
32-
"github.com/k0sproject/k0s/pkg/config"
3329
)
3430

35-
func GetControllerUsers(clusterConfig *v1beta1.ClusterConfig) []string {
36-
return getUserList(*clusterConfig.Spec.Install.SystemUsers)
37-
}
31+
// Ensures that all controller users exist and creates any missing users with
32+
// the given home directory.
33+
func EnsureControllerUsers(systemUsers *v1beta1.SystemUser, homeDir string) error {
34+
var shell string
35+
var errs []error
36+
for _, userName := range getControllerUserNames(systemUsers) {
37+
_, err := users.GetUID(userName)
38+
if errors.Is(err, user.UnknownUserError(userName)) {
39+
if shell == "" {
40+
shell, err = nologinShell()
41+
if err != nil {
42+
// error out early, k0s won't be able to create any users anyways
43+
errs = append(errs, err)
44+
break
45+
}
46+
}
3847

39-
// CreateControllerUsers accepts a cluster config, and cfgVars and creates controller users accordingly
40-
func CreateControllerUsers(clusterConfig *v1beta1.ClusterConfig, k0sVars *config.CfgVars) error {
41-
users := getUserList(*clusterConfig.Spec.Install.SystemUsers)
42-
var messages []string
43-
for _, v := range users {
44-
if err := EnsureUser(v, k0sVars.DataDir); err != nil {
45-
messages = append(messages, err.Error())
48+
logrus.Infof("Creating user %q", userName)
49+
err = createUser(userName, homeDir, shell)
50+
}
51+
if err != nil {
52+
errs = append(errs, err)
4653
}
4754
}
48-
if len(messages) > 0 {
49-
return fmt.Errorf(strings.Join(messages, "\n"))
50-
}
51-
return nil
55+
56+
return errors.Join(errs...)
5257
}
5358

54-
// CreateControllerUsers accepts a cluster config, and cfgVars and creates controller users accordingly
55-
func DeleteControllerUsers(clusterConfig *v1beta1.ClusterConfig) error {
56-
cfgUsers := getUserList(*clusterConfig.Spec.Install.SystemUsers)
57-
var messages []string
58-
for _, v := range cfgUsers {
59-
if _, err := users.GetUID(v); err == nil {
60-
logrus.Debugf("deleting user: %s", v)
59+
// Deletes existing controller users.
60+
func DeleteControllerUsers(systemUsers *v1beta1.SystemUser) error {
61+
var errs []error
62+
for _, userName := range getControllerUserNames(systemUsers) {
63+
if _, err := users.GetUID(userName); err == nil {
64+
logrus.Debugf("Deleting user %q", userName)
6165

62-
if err := deleteUser(v); err != nil {
63-
messages = append(messages, err.Error())
66+
if err := deleteUser(userName); err != nil {
67+
errs = append(errs, err)
6468
}
6569
}
6670
}
67-
if len(messages) > 0 {
68-
// don't fail the command, just notify on errors
69-
return fmt.Errorf(strings.Join(messages, "\n"))
70-
}
71-
return nil
72-
}
7371

74-
// EnsureUser checks if a user exists, and creates it, if it doesn't
75-
// TODO: we should also consider modifying the user, if the user exists, but with wrong settings
76-
func EnsureUser(name string, homeDir string) error {
77-
_, err := users.GetUID(name)
78-
if errors.Is(err, user.UnknownUserError(name)) {
79-
logrus.Infof("creating user: %s", name)
80-
return createUser(name, homeDir)
81-
}
82-
return err
72+
return errors.Join(errs...)
8373
}
8474

8575
// nologinShell returns the path to /sbin/nologin, /bin/false or equivalent or an error if neither is available
@@ -93,13 +83,8 @@ func nologinShell() (string, error) {
9383
}
9484

9585
// CreateUser creates a system user with either `adduser` or `useradd` command
96-
func createUser(userName string, homeDir string) error {
97-
shell, err := nologinShell()
98-
if err != nil {
99-
return err
100-
}
101-
102-
_, err = exec.Command("useradd", `--home`, homeDir, `--shell`, shell, `--system`, `--no-create-home`, userName).Output()
86+
func createUser(userName, homeDir, shell string) error {
87+
_, err := exec.Command("useradd", `--home`, homeDir, `--shell`, shell, `--system`, `--no-create-home`, userName).Output()
10388
if errors.Is(err, exec.ErrNotFound) {
10489
_, err = exec.Command("adduser", `--disabled-password`, `--gecos`, `""`, `--home`, homeDir, `--shell`, shell, `--system`, `--no-create-home`, userName).Output()
10590
}
@@ -115,13 +100,16 @@ func deleteUser(userName string) error {
115100
return err
116101
}
117102

118-
// get user list
119-
func getUserList(sysUsers v1beta1.SystemUser) []string {
120-
v := reflect.ValueOf(sysUsers)
121-
values := make([]string, v.NumField())
122-
123-
for i := 0; i < v.NumField(); i++ {
124-
values[i] = v.Field(i).String()
103+
// Returns the controller user names.
104+
func getControllerUserNames(users *v1beta1.SystemUser) []string {
105+
userNames := []string{
106+
users.Etcd,
107+
users.Kine,
108+
users.Konnectivity,
109+
users.KubeAPIServer,
110+
users.KubeScheduler,
125111
}
126-
return stringslice.Unique(values)
112+
113+
slices.Sort(userNames)
114+
return slices.Compact(userNames)
127115
}

0 commit comments

Comments
 (0)