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 \
isomaker \
liveinstaller \
osmodifier \
pkgworker \
precacher \
repoquerywrapper \

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

@ -1336,7 +1336,7 @@ func createUserWithPassword(installChroot *safechroot.Chroot, user configuration
// chage works in the same way as invoking "chage -M passwordExpirationInDays username"
// 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 (
shadow []string
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)
}
func ConfigureUserGroupMembership(installChroot *safechroot.Chroot, username string, primaryGroup string,
func ConfigureUserGroupMembership(installChroot safechroot.ChrootInterface, username string, primaryGroup string,
secondaryGroups []string,
) (err error) {
const squashErrors = false
@ -1453,7 +1453,7 @@ func ConfigureUserGroupMembership(installChroot *safechroot.Chroot, username str
return
}
func ConfigureUserStartupCommand(installChroot *safechroot.Chroot, username string, startupCommand string) (err error) {
func ConfigureUserStartupCommand(installChroot safechroot.ChrootInterface, username string, startupCommand string) (err error) {
const (
passwdFilePath = "etc/passwd"
sedDelimiter = "|"
@ -1477,7 +1477,7 @@ func ConfigureUserStartupCommand(installChroot *safechroot.Chroot, username stri
return
}
func ProvisionUserSSHCerts(installChroot *safechroot.Chroot, username string, sshPubKeyPaths []string) (err error) {
func ProvisionUserSSHCerts(installChroot safechroot.ChrootInterface, username string, sshPubKeyPaths []string) (err error) {
var (
pubKeyData []string
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.
func (c *Chroot) AddFiles(filesToCopy ...FileToCopy) (err error) {
return addFilesToDestination(c.rootDir, filesToCopy...)
}
func addFilesToDestination(destDir string, filesToCopy ...FileToCopy) error {
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)
var err error
if f.Permissions != nil {
err = file.CopyAndChangeMode(f.Src, dest, os.ModePerm, *f.Permissions)
} else {
@ -296,10 +301,10 @@ func (c *Chroot) AddFiles(filesToCopy ...FileToCopy) (err error) {
if err != nil {
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'

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

@ -47,7 +47,7 @@ func HashPassword(password string) (string, error) {
return hashedPassword, nil
}
func UserExists(username string, installChroot *safechroot.Chroot) (bool, error) {
func UserExists(username string, installChroot safechroot.ChrootInterface) (bool, error) {
var userExists bool
err := installChroot.UnsafeRun(func() error {
_, stderr, err := shell.Execute("id", "-u", username)
@ -70,7 +70,7 @@ func UserExists(username string, installChroot *safechroot.Chroot) (bool, error)
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"}
if 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
}
err = addOrUpdateUsers(config.SystemConfig.Users, baseConfigPath, imageChroot)
err = AddOrUpdateUsers(config.SystemConfig.Users, baseConfigPath, imageChroot)
if err != nil {
return err
}
@ -207,7 +207,7 @@ func runScripts(baseConfigPath string, scripts []imagecustomizerapi.Script, imag
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 {
err := addOrUpdateUser(user, baseConfigPath, imageChroot)
if err != nil {
@ -218,7 +218,7 @@ func addOrUpdateUsers(users []imagecustomizerapi.User, baseConfigPath string, im
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
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