Skip to content

Commit

Permalink
More u-root build tests
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Koch <[email protected]>
  • Loading branch information
hugelgupf committed Feb 8, 2024
1 parent 44f9530 commit d28e7cb
Show file tree
Hide file tree
Showing 4 changed files with 303 additions and 39 deletions.
30 changes: 23 additions & 7 deletions uroot/initramfs/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (af *Files) addFile(src string, dest string, follow bool) error {
// a record or file, we want to include its children anyway.
sInfo, err := os.Lstat(src)
if err != nil {
return fmt.Errorf("adding %q to archive failed because Lstat failed: %v", src, err)
return fmt.Errorf("adding %q to archive failed because Lstat failed: %w", src, err)
}

// Recursively add children.
Expand All @@ -92,15 +92,23 @@ func (af *Files) addFile(src string, dest string, follow bool) error {
}

if record, ok := af.Records[dest]; ok {
return fmt.Errorf("record for %q already exists in archive: %v", dest, record)
return &os.PathError{
Op: "add to archive",
Path: dest,
Err: fmt.Errorf("%w: is %v", os.ErrExist, record),
}
}

if srcFile, ok := af.Files[dest]; ok {
// Just a duplicate.
if src == srcFile {
return nil
}
return fmt.Errorf("record for %q already exists in archive (is %q)", dest, src)
return &os.PathError{
Op: "add to archive",
Path: dest,
Err: fmt.Errorf("%w: backed by %q", os.ErrExist, src),
}
}

af.Files[dest] = src
Expand Down Expand Up @@ -137,13 +145,21 @@ func (af *Files) AddRecord(r cpio.Record) error {
}

if src, ok := af.Files[r.Name]; ok {
return fmt.Errorf("record for %q already exists in archive: file %q", r.Name, src)
return &os.PathError{
Op: "add to archive",
Path: r.Name,
Err: fmt.Errorf("%w: backed by %q", os.ErrExist, src),
}
}
if rr, ok := af.Records[r.Name]; ok {
if rr.Info == r.Info {
if record, ok := af.Records[r.Name]; ok {
if record.Info == r.Info {
return nil
}
return fmt.Errorf("record for %q already exists in archive: %v", r.Name, rr)
return &os.PathError{
Op: "add to archive",
Path: r.Name,
Err: fmt.Errorf("%w: is %v", os.ErrExist, record),
}
}

af.Records[r.Name] = r
Expand Down
15 changes: 15 additions & 0 deletions uroot/initramfs/test/ramfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ func (hf HasFile) Validate(a *cpio.Archive) error {
return fmt.Errorf("archive does not contain %s, but should", hf.Path)
}

type HasDir struct {
Path string
}

func (h HasDir) Validate(a *cpio.Archive) error {
r, ok := a.Get(h.Path)
if !ok {
return fmt.Errorf("archive does not contain %s, but should", h.Path)
}
if r.Mode&cpio.S_IFDIR == 0 {
return fmt.Errorf("file %v should be directory, but isn't", h.Path)
}
return nil
}

type HasContent struct {
Path string
Content string
Expand Down
32 changes: 21 additions & 11 deletions uroot/uroot.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package uroot

import (
"debug/elf"
"errors"
"fmt"
"os"
"path"
Expand Down Expand Up @@ -233,7 +234,7 @@ type Opts struct {
// CreateInitramfs creates an initramfs built to opts' specifications.
func CreateInitramfs(logger ulog.Logger, opts Opts) error {
if _, err := os.Stat(opts.TempDir); os.IsNotExist(err) {
return fmt.Errorf("temp dir %q must exist: %v", opts.TempDir, err)
return fmt.Errorf("temp dir %q must exist: %w", opts.TempDir, err)
}
if opts.OutputFile == nil {
return fmt.Errorf("must give output file")
Expand All @@ -254,7 +255,7 @@ func CreateInitramfs(logger ulog.Logger, opts Opts) error {
for index, cmds := range opts.Commands {
paths, err := findpkg.ResolveGlobs(logger, env, lookupEnv, cmds.Packages)
if err != nil {
return err
return fmt.Errorf("%w: %w", errResolvePackage, err)
}
opts.Commands[index].Packages = paths
}
Expand Down Expand Up @@ -294,21 +295,21 @@ func CreateInitramfs(logger ulog.Logger, opts Opts) error {
return err
}
if err := opts.addSymlinkTo(logger, archive, opts.UinitCmd, "bin/uinit"); err != nil {
return fmt.Errorf("%v: specify -uinitcmd=\"\" to ignore this error and build without a uinit", err)
return fmt.Errorf("%w: %w", err, errUinitSymlink)
}
if len(opts.UinitArgs) > 0 {
if err := archive.AddRecord(cpio.StaticFile("etc/uinit.flags", fileflag.ArgvToFile(opts.UinitArgs), 0o444)); err != nil {
return fmt.Errorf("%v: could not add uinit arguments from UinitArgs (-uinitcmd) to initramfs", err)
return fmt.Errorf("%w: %w", err, errUinitArgs)
}
}
if err := opts.addSymlinkTo(logger, archive, opts.InitCmd, "init"); err != nil {
return fmt.Errorf("%v: specify -initcmd=\"\" to ignore this error and build without an init (or, did you specify a list, and are you missing github.com/u-root/u-root/cmds/core/init?)", err)
return fmt.Errorf("%w: %w", err, errInitSymlink)
}
if err := opts.addSymlinkTo(logger, archive, opts.DefaultShell, "bin/sh"); err != nil {
return fmt.Errorf("%v: specify -defaultsh=\"\" to ignore this error and build without a shell", err)
return fmt.Errorf("%w: %w", err, errDefaultshSymlink)
}
if err := opts.addSymlinkTo(logger, archive, opts.DefaultShell, "bin/defaultsh"); err != nil {
return fmt.Errorf("%v: specify -defaultsh=\"\" to ignore this error and build without a shell", err)
return fmt.Errorf("%w: %w", err, errDefaultshSymlink)
}

// Finally, write the archive.
Expand All @@ -318,6 +319,15 @@ func CreateInitramfs(logger ulog.Logger, opts Opts) error {
return nil
}

var (
errResolvePackage = errors.New("failed to resolve package paths")
errInitSymlink = errors.New("specify -initcmd=\"\" to ignore this error and build without an init (or, did you specify a list, and are you missing github.com/u-root/u-root/cmds/core/init?)")
errUinitSymlink = errors.New("specify -uinitcmd=\"\" to ignore this error and build without a uinit")
errDefaultshSymlink = errors.New("specify -defaultsh=\"\" to ignore this error and build without a shell")
errSymlink = errors.New("could not create symlink")
errUinitArgs = errors.New("could not add uinit arguments")
)

func (o *Opts) addSymlinkTo(logger ulog.Logger, archive *initramfs.Opts, command string, source string) error {
if len(command) == 0 {
return nil
Expand All @@ -326,7 +336,7 @@ func (o *Opts) addSymlinkTo(logger ulog.Logger, archive *initramfs.Opts, command
target, err := resolveCommandOrPath(command, o.Commands)
if err != nil {
if o.Commands != nil {
return fmt.Errorf("could not create symlink from %q to %q: %v", source, command, err)
return fmt.Errorf("%w from %q to %q: %w", errSymlink, source, command, err)
}
logger.Printf("Could not create symlink from %q to %q: %v", source, command, err)
return nil
Expand All @@ -343,7 +353,7 @@ func (o *Opts) addSymlinkTo(logger ulog.Logger, archive *initramfs.Opts, command
}

if err := archive.AddRecord(cpio.Symlink(source, relTarget)); err != nil {
return fmt.Errorf("failed to add symlink %s -> %s to initramfs: %v", source, relTarget, err)
return fmt.Errorf("failed to add symlink %s -> %s to initramfs: %w", source, relTarget, err)
}
return nil
}
Expand Down Expand Up @@ -405,10 +415,10 @@ func ParseExtraFiles(logger ulog.Logger, archive *initramfs.Files, extraFiles []
}
src, err := filepath.Abs(src)
if err != nil {
return fmt.Errorf("couldn't find absolute path for %q: %v", src, err)
return fmt.Errorf("couldn't find absolute path for %q: %w", src, err)
}
if err := archive.AddFile(src, dst); err != nil {
return fmt.Errorf("couldn't add %q to archive: %v", file, err)
return fmt.Errorf("couldn't add %q to archive: %w", file, err)
}

if lddDeps {
Expand Down
Loading

0 comments on commit d28e7cb

Please sign in to comment.