From 831440563c79bb96bb65613344b6d6208d2e3366 Mon Sep 17 00:00:00 2001 From: Joey Riches Date: Fri, 30 Aug 2024 16:12:00 +0100 Subject: [PATCH 1/3] builder: Don't use fakeroot We're inside of a clean rootfs container, we can just build as root, using fakeroot is unnecessary. --- builder/build.go | 7 ++++--- builder/util.go | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/builder/build.go b/builder/build.go index 92d426f..c2c6ec7 100644 --- a/builder/build.go +++ b/builder/build.go @@ -322,11 +322,12 @@ func (p *Package) BuildYpkg(notif PidNotifier, usr *UserInfo, pman *EopkgManager return err } - wdir := p.GetWorkDirInternal() - ymlFile := filepath.Join(wdir, filepath.Base(p.Path)) + workDir := p.GetWorkDirInternal() + ymlFile := filepath.Join(workDir, filepath.Base(p.Path)) + buildDir := filepath.Join(BuildUserHome, "YPKG") // Now build the package - cmd := fmt.Sprintf("/bin/su %s -- fakeroot ypkg-build -D %s %s", BuildUser, wdir, ymlFile) + cmd := fmt.Sprintf("ypkg-build -D %s -B %s %s", workDir, buildDir, ymlFile) if DisableColors { cmd += " -n" } diff --git a/builder/util.go b/builder/util.go index 5577885..dc1191d 100644 --- a/builder/util.go +++ b/builder/util.go @@ -24,6 +24,7 @@ import ( "log/slog" "os" "os/exec" + "path" "path/filepath" "slices" "strconv" @@ -153,6 +154,8 @@ func SaneEnvironment(username, home string) []string { fmt.Sprintf("HOME=%s", home), fmt.Sprintf("USER=%s", username), fmt.Sprintf("USERNAME=%s", username), + fmt.Sprintf("CCACHE_DIR=%s", path.Join(BuildUserHome, ".ccache")), + fmt.Sprintf("SCCACHE_DIR=%s", path.Join(BuildUserHome, ".cache", "sccache")), } // Consider an option to even filter these out permitted := []string{ From aebc307b4488bc7946a6799ecfa85dfc2d14768c Mon Sep 17 00:00:00 2001 From: Joey Riches Date: Thu, 12 Sep 2024 21:50:33 +0100 Subject: [PATCH 2/3] builder/util: Add ChrootShell() function Intended to replace ChrootExecStdin() in order to maintain more control over how we chroot in the environment. --- builder/util.go | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/builder/util.go b/builder/util.go index dc1191d..4f6a627 100644 --- a/builder/util.go +++ b/builder/util.go @@ -230,6 +230,68 @@ func ChrootExecStdin(notif PidNotifier, dir, command string) error { return c.Wait() } +func ChrootShell(notif PidNotifier, dir, command, workdir string) error { + + // Hold an fd for the og root + fd, err := os.Open("/") + if err != nil { + return err + } + + // Remember our working directory + wd, err := os.Getwd() + if err != nil { + return err + } + + // Ensure chroot directory is available + if err := os.Chdir(dir); err != nil { + return err + } + + if err := syscall.Chroot(dir); err != nil { + fd.Close() + return err + } + + if err := os.Chdir("/"); err != nil { + return err + } + + // Spawn a shell + args := []string{"--login"} + c := exec.Command("/bin/bash", args...) + c.Stdout = os.Stdout + c.Stderr = os.Stdout + c.Stdin = os.Stdin + c.Env = ChrootEnvironment + c.Dir = workdir + + if err := c.Start(); err != nil { + goto CLEANUP + } + + notif.SetActivePID(c.Process.Pid) + + if err := c.Wait(); err != nil { + goto CLEANUP + } + +CLEANUP: + // Return to our original root and working directory + defer fd.Close() + if err := fd.Chdir(); err != nil { + return err + } + if err := syscall.Chroot("."); err != nil { + return err + } + if err := os.Chdir(wd); err != nil { + return err + } + return err +} + func StartSccache(dir string) { var buf bytes.Buffer From 2a9786f08981626b9c079677b6a2daf91a08d2f1 Mon Sep 17 00:00:00 2001 From: Joey Riches Date: Sun, 15 Sep 2024 13:37:13 +0100 Subject: [PATCH 3/3] builder/chroot: Use ChrootShell() instead of ChrootExecStdin() With ChrootShell() we can drop usage of the chroot binary, as well as choose the initial workdir to spawn in to. As the files are now build as root, they are owned by root so chroot as root but start at the buildUser home directory. --- builder/chroot.go | 10 ++-------- builder/util.go | 27 +++++++++++++++------------ 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/builder/chroot.go b/builder/chroot.go index 017ec22..cf385c8 100644 --- a/builder/chroot.go +++ b/builder/chroot.go @@ -66,14 +66,8 @@ func (p *Package) Chroot(notif PidNotifier, pman *EopkgManager, overlay *Overlay // Allow bash to work commands.SetStdin(os.Stdin) - // Legacy package format requires root, stay as root. - user := BuildUser - if p.Type == PackageTypeXML { - user = "root" - } - - loginCommand := fmt.Sprintf("/bin/su - %s -s %s", user, BuildUserShell) - err := ChrootExecStdin(notif, overlay.MountPoint, loginCommand) + loginCommand := fmt.Sprintf("/bin/su - root -s %s", BuildUserShell) + err := ChrootShell(notif, overlay.MountPoint, loginCommand, BuildUserHome) commands.SetStdin(nil) notif.SetActivePID(0) diff --git a/builder/util.go b/builder/util.go index 4f6a627..98ae682 100644 --- a/builder/util.go +++ b/builder/util.go @@ -231,7 +231,6 @@ func ChrootExecStdin(notif PidNotifier, dir, command string) error { } func ChrootShell(notif PidNotifier, dir, command, workdir string) error { - // Hold an fd for the og root fd, err := os.Open("/") if err != nil { @@ -239,22 +238,22 @@ func ChrootShell(notif PidNotifier, dir, command, workdir string) error { } // Remember our working directory - wd, err := os.Getwd() - if err != nil { - return err + wd, err2 := os.Getwd() + if err2 != nil { + return err2 } // Ensure chroot directory is available - if err := os.Chdir(dir); err != nil { + if err = os.Chdir(dir); err != nil { return err } - if err := syscall.Chroot(dir); err != nil { + if err = syscall.Chroot(dir); err != nil { fd.Close() return err } - if err := os.Chdir("/"); err != nil { + if err = os.Chdir("/"); err != nil { return err } @@ -267,28 +266,32 @@ func ChrootShell(notif PidNotifier, dir, command, workdir string) error { c.Env = ChrootEnvironment c.Dir = workdir - if err := c.Start(); err != nil { + if err = c.Start(); err != nil { goto CLEANUP } notif.SetActivePID(c.Process.Pid) - if err := c.Wait(); err != nil { + if err = c.Wait(); err != nil { goto CLEANUP } CLEANUP: // Return to our original root and working directory defer fd.Close() - if err := fd.Chdir(); err != nil { + + if err = fd.Chdir(); err != nil { return err } - if err := syscall.Chroot("."); err != nil { + + if err = syscall.Chroot("."); err != nil { return err } - if err := os.Chdir(wd); err != nil { + + if err = os.Chdir(wd); err != nil { return err } + return err }