From ca8b371142ef078ea091fe272d5784f6d5c75f63 Mon Sep 17 00:00:00 2001 From: Achilleas Koutsou Date: Mon, 28 Feb 2022 21:08:36 +0100 Subject: [PATCH] osbuild2: deduplicate userStageOptions() Use single NewUsersStageOptions() from osbuild2 instead of implementing in each distro. --- internal/distro/rhel86/pipelines.go | 25 ++++------------ internal/distro/rhel86/stage_options.go | 34 --------------------- internal/distro/rhel90/pipelines.go | 24 ++++----------- internal/distro/rhel90/stage_options.go | 34 --------------------- internal/osbuild2/users_stage.go | 40 +++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 105 deletions(-) diff --git a/internal/distro/rhel86/pipelines.go b/internal/distro/rhel86/pipelines.go index b2c4b2593..2141569ec 100644 --- a/internal/distro/rhel86/pipelines.go +++ b/internal/distro/rhel86/pipelines.go @@ -415,29 +415,16 @@ func osPipeline(t *imageType, p.AddStage(osbuild.NewGroupsStage(groupStageOptions(groups))) } - if users := c.GetUsers(); len(users) > 0 { - userOptions, err := userStageOptions(users) - if err != nil { - return nil, err - } - + if userOptions, err := osbuild.NewUsersStageOptions(c.GetUsers(), false); err != nil { + return nil, err + } else if userOptions != nil { if t.rpmOstree { // for ostree, writing the key during user creation is redundant // and can cause issues so create users without keys and write them // on first boot - userOptionsSansKeys := new(osbuild.UsersStageOptions) - userOptionsSansKeys.Users = make(map[string]osbuild.UsersStageOptionsUser, len(userOptions.Users)) - for name, options := range userOptions.Users { - userOptionsSansKeys.Users[name] = osbuild.UsersStageOptionsUser{ - UID: options.UID, - GID: options.GID, - Groups: options.Groups, - Description: options.Description, - Home: options.Home, - Shell: options.Shell, - Password: options.Password, - Key: nil, - } + userOptionsSansKeys, err := osbuild.NewUsersStageOptions(c.GetUsers(), true) + if err != nil { + return nil, err } p.AddStage(osbuild.NewUsersStage(userOptionsSansKeys)) p.AddStage(osbuild.NewFirstBootStage(usersFirstBootOptions(userOptions))) diff --git a/internal/distro/rhel86/stage_options.go b/internal/distro/rhel86/stage_options.go index 6a52d18bb..26ef7b855 100644 --- a/internal/distro/rhel86/stage_options.go +++ b/internal/distro/rhel86/stage_options.go @@ -7,7 +7,6 @@ import ( "github.com/osbuild/osbuild-composer/internal/blueprint" "github.com/osbuild/osbuild-composer/internal/common" - "github.com/osbuild/osbuild-composer/internal/crypt" "github.com/osbuild/osbuild-composer/internal/distro" osbuild "github.com/osbuild/osbuild-composer/internal/osbuild2" "github.com/osbuild/osbuild-composer/internal/rpmmd" @@ -47,39 +46,6 @@ func selinuxStageOptions(labelcp bool) *osbuild.SELinuxStageOptions { return options } -func userStageOptions(users []blueprint.UserCustomization) (*osbuild.UsersStageOptions, error) { - options := osbuild.UsersStageOptions{ - Users: make(map[string]osbuild.UsersStageOptionsUser), - } - - for _, c := range users { - if c.Password != nil && !crypt.PasswordIsCrypted(*c.Password) { - cryptedPassword, err := crypt.CryptSHA512(*c.Password) - if err != nil { - return nil, err - } - - c.Password = &cryptedPassword - } - - user := osbuild.UsersStageOptionsUser{ - Groups: c.Groups, - Description: c.Description, - Home: c.Home, - Shell: c.Shell, - Password: c.Password, - Key: c.Key, - } - - user.UID = c.UID - user.GID = c.GID - - options.Users[c.Name] = user - } - - return &options, nil -} - func usersFirstBootOptions(usersStageOptions *osbuild.UsersStageOptions) *osbuild.FirstBootStageOptions { cmds := make([]string, 0, 3*len(usersStageOptions.Users)+2) // workaround for creating authorized_keys file for user diff --git a/internal/distro/rhel90/pipelines.go b/internal/distro/rhel90/pipelines.go index 948333a03..de11936a9 100644 --- a/internal/distro/rhel90/pipelines.go +++ b/internal/distro/rhel90/pipelines.go @@ -407,28 +407,16 @@ func osPipeline(t *imageType, p.AddStage(osbuild.NewGroupsStage(groupStageOptions(groups))) } - if users := c.GetUsers(); len(users) > 0 { - userOptions, err := userStageOptions(users) - if err != nil { - return nil, err - } + if userOptions, err := osbuild.NewUsersStageOptions(c.GetUsers(), false); err != nil { + return nil, err + } else if userOptions != nil { if t.rpmOstree { // for ostree, writing the key during user creation is redundant // and can cause issues so create users without keys and write them // on first boot - userOptionsSansKeys := new(osbuild.UsersStageOptions) - userOptionsSansKeys.Users = make(map[string]osbuild.UsersStageOptionsUser, len(userOptions.Users)) - for name, options := range userOptions.Users { - userOptionsSansKeys.Users[name] = osbuild.UsersStageOptionsUser{ - UID: options.UID, - GID: options.GID, - Groups: options.Groups, - Description: options.Description, - Home: options.Home, - Shell: options.Shell, - Password: options.Password, - Key: nil, - } + userOptionsSansKeys, err := osbuild.NewUsersStageOptions(c.GetUsers(), true) + if err != nil { + return nil, err } p.AddStage(osbuild.NewUsersStage(userOptionsSansKeys)) p.AddStage(osbuild.NewFirstBootStage(usersFirstBootOptions(userOptions))) diff --git a/internal/distro/rhel90/stage_options.go b/internal/distro/rhel90/stage_options.go index 4f2e31cef..06dd57030 100644 --- a/internal/distro/rhel90/stage_options.go +++ b/internal/distro/rhel90/stage_options.go @@ -7,7 +7,6 @@ import ( "github.com/osbuild/osbuild-composer/internal/blueprint" "github.com/osbuild/osbuild-composer/internal/common" - "github.com/osbuild/osbuild-composer/internal/crypt" "github.com/osbuild/osbuild-composer/internal/distro" osbuild "github.com/osbuild/osbuild-composer/internal/osbuild2" "github.com/osbuild/osbuild-composer/internal/rpmmd" @@ -47,39 +46,6 @@ func selinuxStageOptions(labelcp bool) *osbuild.SELinuxStageOptions { return options } -func userStageOptions(users []blueprint.UserCustomization) (*osbuild.UsersStageOptions, error) { - options := osbuild.UsersStageOptions{ - Users: make(map[string]osbuild.UsersStageOptionsUser), - } - - for _, c := range users { - if c.Password != nil && !crypt.PasswordIsCrypted(*c.Password) { - cryptedPassword, err := crypt.CryptSHA512(*c.Password) - if err != nil { - return nil, err - } - - c.Password = &cryptedPassword - } - - user := osbuild.UsersStageOptionsUser{ - Groups: c.Groups, - Description: c.Description, - Home: c.Home, - Shell: c.Shell, - Password: c.Password, - Key: c.Key, - } - - user.UID = c.UID - user.GID = c.GID - - options.Users[c.Name] = user - } - - return &options, nil -} - func usersFirstBootOptions(usersStageOptions *osbuild.UsersStageOptions) *osbuild.FirstBootStageOptions { cmds := make([]string, 0, 3*len(usersStageOptions.Users)+2) // workaround for creating authorized_keys file for user diff --git a/internal/osbuild2/users_stage.go b/internal/osbuild2/users_stage.go index 18ac35ff3..7d10d90f7 100644 --- a/internal/osbuild2/users_stage.go +++ b/internal/osbuild2/users_stage.go @@ -1,5 +1,10 @@ package osbuild2 +import ( + "github.com/osbuild/osbuild-composer/internal/blueprint" + "github.com/osbuild/osbuild-composer/internal/crypt" +) + type UsersStageOptions struct { Users map[string]UsersStageOptionsUser `json:"users"` } @@ -23,3 +28,38 @@ func NewUsersStage(options *UsersStageOptions) *Stage { Options: options, } } + +func NewUsersStageOptions(userCustomizations []blueprint.UserCustomization, omitKey bool) (*UsersStageOptions, error) { + if len(userCustomizations) == 0 { + return nil, nil + } + + users := make(map[string]UsersStageOptionsUser, len(userCustomizations)) + for _, uc := range userCustomizations { + if uc.Password != nil && !crypt.PasswordIsCrypted(*uc.Password) { + cryptedPassword, err := crypt.CryptSHA512(*uc.Password) + if err != nil { + return nil, err + } + + uc.Password = &cryptedPassword + } + + user := UsersStageOptionsUser{ + UID: uc.UID, + GID: uc.GID, + Groups: uc.Groups, + Description: uc.Description, + Home: uc.Home, + Shell: uc.Shell, + Password: uc.Password, + Key: nil, + } + if !omitKey { + user.Key = uc.Key + } + users[uc.Name] = user + } + + return &UsersStageOptions{Users: users}, nil +}