Add Initial Mariner OS Modifier (EMU) Files (#6824)

This commit is contained in:
elainezhao96 2023-11-30 16:05:42 -08:00 коммит произвёл GitHub
Родитель eebc0beedc
Коммит a6a19b4da0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 184 добавлений и 12 удалений

Просмотреть файл

@ -43,6 +43,7 @@ go_tool_list = \
imager \ imager \
isomaker \ isomaker \
liveinstaller \ liveinstaller \
osmodifier \
pkgworker \ pkgworker \
precacher \ precacher \
repoquerywrapper \ repoquerywrapper \

Просмотреть файл

@ -1336,7 +1336,7 @@ func createUserWithPassword(installChroot *safechroot.Chroot, user configuration
// chage works in the same way as invoking "chage -M passwordExpirationInDays username" // chage works in the same way as invoking "chage -M passwordExpirationInDays username"
// i.e. it sets the maximum password expiration date. // i.e. it sets the maximum password expiration date.
func Chage(installChroot *safechroot.Chroot, passwordExpirationInDays int64, username string) (err error) { func Chage(installChroot safechroot.ChrootInterface, passwordExpirationInDays int64, username string) (err error) {
var ( var (
shadow []string shadow []string
usernameWithColon = fmt.Sprintf("%s:", username) usernameWithColon = fmt.Sprintf("%s:", username)
@ -1422,7 +1422,7 @@ func Chage(installChroot *safechroot.Chroot, passwordExpirationInDays int64, use
return fmt.Errorf(`user "%s" not found when trying to change the password expiration date`, username) return fmt.Errorf(`user "%s" not found when trying to change the password expiration date`, username)
} }
func ConfigureUserGroupMembership(installChroot *safechroot.Chroot, username string, primaryGroup string, func ConfigureUserGroupMembership(installChroot safechroot.ChrootInterface, username string, primaryGroup string,
secondaryGroups []string, secondaryGroups []string,
) (err error) { ) (err error) {
const squashErrors = false const squashErrors = false
@ -1453,7 +1453,7 @@ func ConfigureUserGroupMembership(installChroot *safechroot.Chroot, username str
return return
} }
func ConfigureUserStartupCommand(installChroot *safechroot.Chroot, username string, startupCommand string) (err error) { func ConfigureUserStartupCommand(installChroot safechroot.ChrootInterface, username string, startupCommand string) (err error) {
const ( const (
passwdFilePath = "etc/passwd" passwdFilePath = "etc/passwd"
sedDelimiter = "|" sedDelimiter = "|"
@ -1477,7 +1477,7 @@ func ConfigureUserStartupCommand(installChroot *safechroot.Chroot, username stri
return return
} }
func ProvisionUserSSHCerts(installChroot *safechroot.Chroot, username string, sshPubKeyPaths []string) (err error) { func ProvisionUserSSHCerts(installChroot safechroot.ChrootInterface, username string, sshPubKeyPaths []string) (err error) {
var ( var (
pubKeyData []string pubKeyData []string
exists bool exists bool

Просмотреть файл

@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
package safechroot
type ChrootInterface interface {
RootDir() string
Run(toRun func() error) error
UnsafeRun(toRun func() error) error
AddFiles(filesToCopy ...FileToCopy) error
}

Просмотреть файл

@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
package safechroot
// DummyChroot is a placeholder that implements ChrootInterface.
type DummyChroot struct {
}
func (d *DummyChroot) RootDir() string {
return "/"
}
func (d *DummyChroot) Run(toRun func() error) (err error) {
// Only execute the function, no chroot operations
return toRun()
}
func (d *DummyChroot) UnsafeRun(toRun func() error) (err error) {
return toRun()
}
func (d *DummyChroot) AddFiles(filesToCopy ...FileToCopy) (err error) {
return addFilesToDestination(d.RootDir(), filesToCopy...)
}

Просмотреть файл

@ -284,10 +284,15 @@ func (c *Chroot) Initialize(tarPath string, extraDirectories []string, extraMoun
// AddFiles copies each file 'Src' to the relative path chrootRootDir/'Dest' in the chroot. // AddFiles copies each file 'Src' to the relative path chrootRootDir/'Dest' in the chroot.
func (c *Chroot) AddFiles(filesToCopy ...FileToCopy) (err error) { func (c *Chroot) AddFiles(filesToCopy ...FileToCopy) (err error) {
return addFilesToDestination(c.rootDir, filesToCopy...)
}
func addFilesToDestination(destDir string, filesToCopy ...FileToCopy) error {
for _, f := range filesToCopy { for _, f := range filesToCopy {
dest := filepath.Join(c.rootDir, f.Dest) dest := filepath.Join(destDir, f.Dest)
logger.Log.Debugf("Copying '%s' to worker '%s'", f.Src, dest) logger.Log.Debugf("Copying '%s' to worker '%s'", f.Src, dest)
var err error
if f.Permissions != nil { if f.Permissions != nil {
err = file.CopyAndChangeMode(f.Src, dest, os.ModePerm, *f.Permissions) err = file.CopyAndChangeMode(f.Src, dest, os.ModePerm, *f.Permissions)
} else { } else {
@ -296,10 +301,10 @@ func (c *Chroot) AddFiles(filesToCopy ...FileToCopy) (err error) {
if err != nil { if err != nil {
logger.Log.Errorf("Error provisioning worker with '%s'", f.Src) logger.Log.Errorf("Error provisioning worker with '%s'", f.Src)
return return err
} }
} }
return return nil
} }
// CopyOutFile copies file 'srcPath' in the chroot to the host at 'destPath' // CopyOutFile copies file 'srcPath' in the chroot to the host at 'destPath'

Просмотреть файл

@ -47,7 +47,7 @@ func HashPassword(password string) (string, error) {
return hashedPassword, nil return hashedPassword, nil
} }
func UserExists(username string, installChroot *safechroot.Chroot) (bool, error) { func UserExists(username string, installChroot safechroot.ChrootInterface) (bool, error) {
var userExists bool var userExists bool
err := installChroot.UnsafeRun(func() error { err := installChroot.UnsafeRun(func() error {
_, stderr, err := shell.Execute("id", "-u", username) _, stderr, err := shell.Execute("id", "-u", username)
@ -70,7 +70,7 @@ func UserExists(username string, installChroot *safechroot.Chroot) (bool, error)
return userExists, nil return userExists, nil
} }
func AddUser(username string, hashedPassword string, uid string, installChroot *safechroot.Chroot) error { func AddUser(username string, hashedPassword string, uid string, installChroot safechroot.ChrootInterface) error {
var args = []string{username, "-m"} var args = []string{username, "-m"}
if hashedPassword != "" { if hashedPassword != "" {
args = append(args, "-p", hashedPassword) args = append(args, "-p", hashedPassword)

Просмотреть файл

@ -0,0 +1,57 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
package main
import (
"log"
"os"
"github.com/microsoft/CBL-Mariner/toolkit/tools/internal/exe"
"github.com/microsoft/CBL-Mariner/toolkit/tools/internal/logger"
"github.com/microsoft/CBL-Mariner/toolkit/tools/internal/timestamp"
"github.com/microsoft/CBL-Mariner/toolkit/tools/pkg/osmodifierlib"
"github.com/microsoft/CBL-Mariner/toolkit/tools/pkg/profile"
"gopkg.in/alecthomas/kingpin.v2"
)
var (
app = kingpin.New("osmodifier", "Used to modify os")
configFile = app.Flag("config-file", "Path of the os modification config file.").Required().String()
logFile = exe.LogFileFlag(app)
logLevel = exe.LogLevelFlag(app)
profFlags = exe.SetupProfileFlags(app)
timestampFile = app.Flag("timestamp-file", "File that stores timestamps for this program.").String()
)
func main() {
var err error
kingpin.MustParse(app.Parse(os.Args[1:]))
logger.InitBestEffort(*logFile, *logLevel)
prof, err := profile.StartProfiling(profFlags)
if err != nil {
logger.Log.Warnf("Could not start profiling: %s", err)
}
defer prof.StopProfiler()
timestamp.BeginTiming("osmodifier", *timestampFile)
defer timestamp.CompleteTiming()
err = modifyImage()
if err != nil {
log.Fatalf("os modification failed: %v", err)
}
}
func modifyImage() error {
err := osmodifierlib.ModifyOSWithConfigFile(*configFile)
if err != nil {
return err
}
return nil
}

Просмотреть файл

@ -57,7 +57,7 @@ func doCustomizations(buildDir string, baseConfigPath string, config *imagecusto
return err return err
} }
err = addOrUpdateUsers(config.SystemConfig.Users, baseConfigPath, imageChroot) err = AddOrUpdateUsers(config.SystemConfig.Users, baseConfigPath, imageChroot)
if err != nil { if err != nil {
return err return err
} }
@ -207,7 +207,7 @@ func runScripts(baseConfigPath string, scripts []imagecustomizerapi.Script, imag
return nil return nil
} }
func addOrUpdateUsers(users []imagecustomizerapi.User, baseConfigPath string, imageChroot *safechroot.Chroot) error { func AddOrUpdateUsers(users []imagecustomizerapi.User, baseConfigPath string, imageChroot safechroot.ChrootInterface) error {
for _, user := range users { for _, user := range users {
err := addOrUpdateUser(user, baseConfigPath, imageChroot) err := addOrUpdateUser(user, baseConfigPath, imageChroot)
if err != nil { if err != nil {
@ -218,7 +218,7 @@ func addOrUpdateUsers(users []imagecustomizerapi.User, baseConfigPath string, im
return nil return nil
} }
func addOrUpdateUser(user imagecustomizerapi.User, baseConfigPath string, imageChroot *safechroot.Chroot) error { func addOrUpdateUser(user imagecustomizerapi.User, baseConfigPath string, imageChroot safechroot.ChrootInterface) error {
var err error var err error
logger.Log.Infof("Adding/updating user (%s)", user.Name) logger.Log.Infof("Adding/updating user (%s)", user.Name)

Просмотреть файл

@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
package osmodifierlib
import (
"github.com/microsoft/CBL-Mariner/toolkit/tools/imagecustomizerapi"
"github.com/microsoft/CBL-Mariner/toolkit/tools/internal/safechroot"
"github.com/microsoft/CBL-Mariner/toolkit/tools/pkg/imagecustomizerlib"
)
func doModifications(baseConfigPath string, systemConfig *imagecustomizerapi.SystemConfig) error {
var dummyChroot safechroot.ChrootInterface = &safechroot.DummyChroot{}
err := imagecustomizerlib.AddOrUpdateUsers(systemConfig.Users, baseConfigPath, dummyChroot)
if err != nil {
return err
}
return nil
}

Просмотреть файл

@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
package osmodifierlib
import (
"fmt"
"path/filepath"
"github.com/microsoft/CBL-Mariner/toolkit/tools/imagecustomizerapi"
)
func ModifyOSWithConfigFile(configFile string) error {
var err error
var systemConfig imagecustomizerapi.SystemConfig
err = imagecustomizerapi.UnmarshalYamlFile(configFile, &systemConfig)
if err != nil {
return err
}
baseConfigPath, _ := filepath.Split(configFile)
absBaseConfigPath, err := filepath.Abs(baseConfigPath)
if err != nil {
return fmt.Errorf("failed to get absolute path of config file directory:\n%w", err)
}
err = ModifyOS(absBaseConfigPath, &systemConfig)
if err != nil {
return err
}
return nil
}
func ModifyOS(baseConfigPath string, systemConfig *imagecustomizerapi.SystemConfig) error {
err := doModifications(baseConfigPath, systemConfig)
if err != nil {
return err
}
return nil
}

9
toolkit/tools/pkg/osmodifierlib/testdata/addusers-config.yaml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,9 @@
Users:
- Name: root
Password: password
- Name: test
Password: $6$aEzRqlIsXn8I$uvdD6RgzdAao5qUxap/Edc/ABW2Qfvqe4ZK7AjoguwS1rX2Q5l72/4L4OW5lqOdY5pIIahBco3hdR32NAuZ/O1
PasswordHashed: true
SecondaryGroups:
- sudo