Add Initial Mariner OS Modifier (EMU) Files (#6824)
This commit is contained in:
Родитель
eebc0beedc
Коммит
a6a19b4da0
|
@ -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
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
Users:
|
||||
- Name: root
|
||||
Password: password
|
||||
|
||||
- Name: test
|
||||
Password: $6$aEzRqlIsXn8I$uvdD6RgzdAao5qUxap/Edc/ABW2Qfvqe4ZK7AjoguwS1rX2Q5l72/4L4OW5lqOdY5pIIahBco3hdR32NAuZ/O1
|
||||
PasswordHashed: true
|
||||
SecondaryGroups:
|
||||
- sudo
|
Загрузка…
Ссылка в новой задаче