Files
postmarketos-mkinitfs/internal/bootdeploy/bootdeploy.go
Clayton Craft d87a33a751 bootdeploy: remove dependency on misc.Exists
Checking for the app is unnecessary, since the cmd.Run later will fail
if it doesn't exist. This allows dropping the dependency on misc.Exists.

There's also no reason to print that the command failed, just return the
error.
2023-02-21 12:41:18 -08:00

149 lines
3.1 KiB
Go

package bootdeploy
import (
"errors"
"io"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
)
type BootDeploy struct {
inDir string
outDir string
ubootBoardname string
}
// New returns a new BootDeploy, which then runs:
//
// boot-deploy -d indir -o outDir
//
// ubootBoardname is used for copying in some u-boot files prior to running
// boot-deploy. This is optional, passing an empty string is ok if this is not
// needed.
func New(inDir, outDir, ubootBoardname string) *BootDeploy {
return &BootDeploy{
inDir: inDir,
outDir: outDir,
ubootBoardname: ubootBoardname,
}
}
func (b *BootDeploy) Run() error {
if err := copyUbootFiles(b.inDir, b.ubootBoardname); errors.Is(err, os.ErrNotExist) {
log.Println("u-boot files copying skipped: ", err)
} else {
if err != nil {
log.Fatal("copyUbootFiles: ", err)
}
}
return bootDeploy(b.inDir, b.outDir)
}
func bootDeploy(workDir string, outDir string) error {
// boot-deploy expects the kernel to be in the same dir as initramfs.
// Assume that the kernel is in the output dir...
kernels, _ := filepath.Glob(filepath.Join(outDir, "vmlinuz*"))
if len(kernels) == 0 {
return errors.New("Unable to find any kernels at " + filepath.Join(outDir, "vmlinuz*"))
}
// Pick a kernel that does not have suffixes added by boot-deploy
var kernFile string
for _, f := range kernels {
if strings.HasSuffix(f, "-dtb") || strings.HasSuffix(f, "-mtk") {
continue
}
kernFile = f
break
}
kernFd, err := os.Open(kernFile)
if err != nil {
return err
}
defer kernFd.Close()
kernFileCopy, err := os.Create(filepath.Join(workDir, "vmlinuz"))
if err != nil {
return err
}
if _, err = io.Copy(kernFileCopy, kernFd); err != nil {
return err
}
kernFileCopy.Close()
// boot-deploy -i initramfs -k vmlinuz-postmarketos-rockchip -d /tmp/cpio -o /tmp/foo initramfs-extra
cmd := exec.Command("boot-deploy",
"-i", "initramfs",
"-k", "vmlinuz",
"-d", workDir,
"-o", outDir,
"initramfs-extra")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
return nil
}
// Copy copies the file at srcFile path to a new file at dstFile path
func copy(srcFile, dstFile string) error {
out, err := os.Create(dstFile)
if err != nil {
return err
}
defer func() {
errClose := out.Close()
if err == nil {
err = errClose
}
}()
in, err := os.Open(srcFile)
if err != nil {
return err
}
defer in.Close()
_, err = io.Copy(out, in)
if err != nil {
return err
}
return nil
}
// copyUbootFiles uses deviceinfo_uboot_boardname to copy u-boot files required
// for running boot-deploy
func copyUbootFiles(path, ubootBoardname string) error {
if ubootBoardname == "" {
return nil
}
srcDir := filepath.Join("/usr/share/u-boot", ubootBoardname)
entries, err := os.ReadDir(srcDir)
if err != nil {
return err
}
for _, entry := range entries {
sourcePath := filepath.Join(srcDir, entry.Name())
destPath := filepath.Join(path, entry.Name())
if err := copy(sourcePath, destPath); err != nil {
return err
}
}
return nil
}