distro: deduplicate userStageOptions() in RHEL pipelines

Use single NewUsersStageOptions() from osbuild1 and osbuild2 instead of
implementing in each distro.
- Followup from ca8b371142, copied to the
  rest of the RHEL distro definitions.
- Added NewUsersStageOptions() to osbuild1 for rhel8 and rhel84.

NB: The change was not made in the Fedora distro definitions as they are
    currently being rewritten.
This commit is contained in:
Achilleas Koutsou 2022-03-30 17:32:31 +02:00 committed by Christian Kellner
parent 15243f1dc5
commit 333bec57ef
10 changed files with 88 additions and 218 deletions

View file

@ -12,7 +12,6 @@ import (
"github.com/google/uuid"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/crypt"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
)
@ -387,12 +386,10 @@ func (t *imageType) pipeline(c *blueprint.Customizations, options distro.ImageOp
p.AddStage(osbuild.NewGroupsStage(t.groupStageOptions(groups)))
}
if users := c.GetUsers(); len(users) > 0 {
options, err := t.userStageOptions(users)
if err != nil {
return nil, err
}
p.AddStage(osbuild.NewUsersStage(options))
if userOptions, err := osbuild.NewUsersStageOptions(c.GetUsers()); err != nil {
return nil, err
} else if userOptions != nil {
p.AddStage(osbuild.NewUsersStage(userOptions))
}
if services := c.GetServices(); services != nil || t.enabledServices != nil || t.disabledServices != nil || t.defaultTarget != "" {
@ -483,39 +480,6 @@ func (t *imageType) rpmStageOptions(arch architecture, repos []rpmmd.RepoConfig,
}
}
func (t *imageType) 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 (t *imageType) groupStageOptions(groups []blueprint.GroupCustomization) *osbuild.GroupsStageOptions {
options := osbuild.GroupsStageOptions{
Groups: map[string]osbuild.GroupsStageOptionsGroup{},

View file

@ -15,7 +15,6 @@ import (
"github.com/google/uuid"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/crypt"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
)
@ -459,12 +458,10 @@ func (t *imageType) pipeline(c *blueprint.Customizations, options distro.ImageOp
p.AddStage(osbuild.NewGroupsStage(t.groupStageOptions(groups)))
}
if users := c.GetUsers(); len(users) > 0 {
options, err := t.userStageOptions(users)
if err != nil {
return nil, err
}
p.AddStage(osbuild.NewUsersStage(options))
if userOptions, err := osbuild.NewUsersStageOptions(c.GetUsers()); err != nil {
return nil, err
} else if userOptions != nil {
p.AddStage(osbuild.NewUsersStage(userOptions))
}
if services := c.GetServices(); services != nil || t.enabledServices != nil || t.disabledServices != nil || t.defaultTarget != "" {
@ -567,39 +564,6 @@ func (t *imageType) rpmStageOptions(arch architecture, repos []rpmmd.RepoConfig,
}
}
func (t *imageType) 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 (t *imageType) groupStageOptions(groups []blueprint.GroupCustomization) *osbuild.GroupsStageOptions {
options := osbuild.GroupsStageOptions{
Groups: map[string]osbuild.GroupsStageOptionsGroup{},

View file

@ -7,7 +7,6 @@ import (
"path/filepath"
"strings"
"github.com/osbuild/osbuild-composer/internal/crypt"
"github.com/osbuild/osbuild-composer/internal/distro"
osbuild "github.com/osbuild/osbuild-composer/internal/osbuild2"
@ -321,13 +320,18 @@ func (t *imageTypeS2) ostreeTreePipeline(repos []rpmmd.RepoConfig, packages []rp
p.AddStage(osbuild.NewGroupsStage(t.groupStageOptions(groups)))
}
if users := c.GetUsers(); len(users) > 0 {
options, err := t.userStageOptions(users)
if userOptions, err := osbuild.NewUsersStageOptions(c.GetUsers(), false); err != nil {
return nil, err
} else if userOptions != nil {
// 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, err := osbuild.NewUsersStageOptions(c.GetUsers(), true)
if err != nil {
return nil, err
}
p.AddStage(osbuild.NewUsersStage(options))
p.AddStage(osbuild.NewFirstBootStage(t.usersFirstBootOptions(options)))
p.AddStage(osbuild.NewUsersStage(userOptionsSansKeys))
p.AddStage(osbuild.NewFirstBootStage(t.usersFirstBootOptions(userOptions)))
}
if services := c.GetServices(); services != nil || t.enabledServices != nil || t.disabledServices != nil || t.defaultTarget != "" {
@ -528,39 +532,6 @@ func (t *imageTypeS2) selinuxStageOptions() *osbuild.SELinuxStageOptions {
return options
}
func (t *imageTypeS2) 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 (t *imageTypeS2) usersFirstBootOptions(usersStageOptions *osbuild.UsersStageOptions) *osbuild.FirstBootStageOptions {
cmds := make([]string, 0, 3*len(usersStageOptions.Users)+1)
// workaround for creating authorized_keys file for user

View file

@ -242,11 +242,9 @@ func ec2BaseTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec,
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 {
p.AddStage(osbuild.NewUsersStage(userOptions))
}
@ -665,11 +663,9 @@ func osPipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, bpPackag
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 {
p.AddStage(osbuild.NewUsersStage(userOptions))
}
@ -751,12 +747,17 @@ func ostreeTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec,
p.AddStage(osbuild.NewGroupsStage(groupStageOptions(groups)))
}
if users := c.GetUsers(); len(users) > 0 {
userOptions, err := userStageOptions(users)
if userOptions, err := osbuild.NewUsersStageOptions(c.GetUsers(), false); err != nil {
return nil, err
} else if userOptions != nil {
// 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, err := osbuild.NewUsersStageOptions(c.GetUsers(), true)
if err != nil {
return nil, err
}
p.AddStage(osbuild.NewUsersStage(userOptions))
p.AddStage(osbuild.NewUsersStage(userOptionsSansKeys))
p.AddStage(osbuild.NewFirstBootStage(usersFirstBootOptions(userOptions)))
}

View file

@ -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"
)
@ -32,39 +31,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)+1)
// workaround for creating authorized_keys file for user

View file

@ -429,9 +429,9 @@ func osPipeline(t *imageType,
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
// 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, err := osbuild.NewUsersStageOptions(c.GetUsers(), true)
if err != nil {
return nil, err

View file

@ -421,9 +421,9 @@ func osPipeline(t *imageType,
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
// 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, err := osbuild.NewUsersStageOptions(c.GetUsers(), true)
if err != nil {
return nil, err

View file

@ -230,11 +230,9 @@ func ec2BaseTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec,
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 {
p.AddStage(osbuild.NewUsersStage(userOptions))
}
@ -749,11 +747,9 @@ func osPipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, bpPackag
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 {
p.AddStage(osbuild.NewUsersStage(userOptions))
}
@ -830,12 +826,17 @@ func ostreeTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec,
p.AddStage(osbuild.NewGroupsStage(groupStageOptions(groups)))
}
if users := c.GetUsers(); len(users) > 0 {
userOptions, err := userStageOptions(users)
if userOptions, err := osbuild.NewUsersStageOptions(c.GetUsers(), false); err != nil {
return nil, err
} else if userOptions != nil {
// 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, err := osbuild.NewUsersStageOptions(c.GetUsers(), true)
if err != nil {
return nil, err
}
p.AddStage(osbuild.NewUsersStage(userOptions))
p.AddStage(osbuild.NewUsersStage(userOptionsSansKeys))
p.AddStage(osbuild.NewFirstBootStage(usersFirstBootOptions(userOptions)))
}

View file

@ -5,7 +5,6 @@ import (
"path/filepath"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/crypt"
osbuild "github.com/osbuild/osbuild-composer/internal/osbuild2"
)
@ -29,39 +28,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)+1)
// workaround for creating authorized_keys file for user

View file

@ -1,5 +1,10 @@
package osbuild1
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,35 @@ func NewUsersStage(options *UsersStageOptions) *Stage {
Options: options,
}
}
func NewUsersStageOptions(userCustomizations []blueprint.UserCustomization) (*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: uc.Key,
}
users[uc.Name] = user
}
return &UsersStageOptions{Users: users}, nil
}