Skip to content

Commit

Permalink
uimage API: add arbitrary CPIO records
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Koch <[email protected]>
  • Loading branch information
hugelgupf committed Feb 16, 2024
1 parent e3faa6a commit 5c0bcd2
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 0 deletions.
9 changes: 9 additions & 0 deletions uimage/initramfs/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ type Opts struct {
// If this is false, the "init" file in BaseArchive will be renamed
// "inito" (for init-original) in the output archive.
UseExistingInit bool

// Records are additional CPIO records to include in the initramfs.
Records []cpio.Record
}

// Write uses the given options to determine which files to write to the output
Expand Down Expand Up @@ -99,6 +102,12 @@ func Write(opts *Opts) error {
}
}

for _, r := range opts.Records {
if err := opts.Files.AddRecord(r); err != nil {
return err
}
}

out, err := opts.OutputFile.OpenWriter()
if err != nil {
return err
Expand Down
42 changes: 42 additions & 0 deletions uimage/initramfs/files_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,48 @@ func TestOptsWrite(t *testing.T) {
cpio.Trailer: cpio.TrailerRecord,
},
},
{
desc: "base archive with init and extra records conflict",
opts: &Opts{
Files: &Files{
Records: map[string]cpio.Record{
"init": cpio.StaticFile("init", "huh", 0o111),
},
},
BaseArchive: &Archive{Archive: archive(t,
cpio.StaticFile("init", "boo", 0o555),
)},
Records: []cpio.Record{
cpio.StaticFile("init", "huh", 0o111),
},
UseExistingInit: true,
},
errs: []error{os.ErrExist},

Check failure on line 655 in uimage/initramfs/files_test.go

View workflow job for this annotation

GitHub Actions / Build and test (1.21.x, ubuntu-latest)

unknown field errs in struct literal of type struct{desc string; opts *Opts; output *cpio.Archive; want Records; err error}

Check failure on line 655 in uimage/initramfs/files_test.go

View workflow job for this annotation

GitHub Actions / Race test (1.21.x, ubuntu-latest)

unknown field errs in struct literal of type struct{desc string; opts *Opts; output *cpio.Archive; want Records; err error}

Check failure on line 655 in uimage/initramfs/files_test.go

View workflow job for this annotation

GitHub Actions / Build and test (1.22.x, ubuntu-latest)

unknown field errs in struct literal of type struct{desc string; opts *Opts; output *cpio.Archive; want Records; err error}

Check failure on line 655 in uimage/initramfs/files_test.go

View workflow job for this annotation

GitHub Actions / Race test (1.22.x, ubuntu-latest)

unknown field errs in struct literal of type struct{desc string; opts *Opts; output *cpio.Archive; want Records; err error}
output: &cpio.Archive{
Files: make(map[string]cpio.Record),
},
},
{
desc: "extra records",
opts: &Opts{
Files: &Files{
Records: map[string]cpio.Record{
"init": cpio.StaticFile("init", "huh", 0o111),
},
},
Records: []cpio.Record{
cpio.StaticFile("etc/foo", "huh", 0o111),
},
},
output: &cpio.Archive{
Files: make(map[string]cpio.Record),
},
want: Records{
"init": cpio.StaticFile("init", "boo", 0o555),
"etc/foo": cpio.StaticFile("etc/foo", "huh", 0o111),
cpio.Trailer: cpio.TrailerRecord,
},
},
} {
t.Run(fmt.Sprintf("Test %02d (%s)", i, tt.desc), func(t *testing.T) {
tt.opts.OutputFile = &Archive{tt.output}
Expand Down
12 changes: 12 additions & 0 deletions uimage/uimage.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ type Opts struct {
//
// This must be specified to have a default shell.
DefaultShell string

// Records are additional CPIO records to include in the initramfs.
Records []cpio.Record
}

// Modifier modifies uimage options.
Expand Down Expand Up @@ -503,6 +506,14 @@ func WithTempDir(dir string) Modifier {
}
}

// WithRecord adds CPIO records to include in the initramfs.
func WithRecord(r ...cpio.Record) Modifier {
return func(o *Opts) error {
o.Records = append(o.Records, r...)
return nil
}
}

// Create creates an initramfs from mods specifications.
func Create(l *llog.Logger, mods ...Modifier) error {
o, err := OptionsFor(mods...)
Expand Down Expand Up @@ -571,6 +582,7 @@ func CreateInitramfs(l *llog.Logger, opts Opts) error {
OutputFile: opts.OutputFile,
BaseArchive: opts.BaseArchive,
UseExistingInit: opts.UseExistingInit,
Records: opts.Records,
}
if err := ParseExtraFiles(l, archive.Files, opts.ExtraFiles, !opts.SkipLDD); err != nil {
return err
Expand Down
76 changes: 76 additions & 0 deletions uimage/uimage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,46 @@ func TestCreateInitramfs(t *testing.T) {
itest.IsEmpty{},
},
},
{
name: "extra records conflict",
opts: Opts{
Env: golang.Default(golang.DisableCGO()),
TempDir: dir,
InitCmd: "init",
DefaultShell: "ls",
Records: []cpio.Record{
cpio.StaticFile("bbin/ls", "foo", 0o111),
},
Commands: BusyboxCmds(
"github.com/u-root/u-root/cmds/core/init",
"github.com/u-root/u-root/cmds/core/ls",
),
},
errs: []error{os.ErrExist},
validators: []itest.ArchiveValidator{
itest.IsEmpty{},
},
},
{
name: "extra records",
opts: Opts{
Env: golang.Default(golang.DisableCGO()),
TempDir: dir,
InitCmd: "init",
DefaultShell: "ls",
Records: []cpio.Record{
cpio.StaticFile("etc/foo", "foo", 0o111),
},
Commands: BusyboxCmds(
"github.com/u-root/u-root/cmds/core/init",
"github.com/u-root/u-root/cmds/core/ls",
),
},
validators: []itest.ArchiveValidator{
itest.HasFile{Path: "bbin/bb"},
itest.HasRecord{R: cpio.StaticFile("etc/foo", "foo", 0o111)},
},
},
} {
t.Run(fmt.Sprintf("Test %d [%s]", i, tt.name), func(t *testing.T) {
archive := cpio.InMemArchive()
Expand Down Expand Up @@ -992,6 +1032,42 @@ func TestCreateInitramfsWithAPI(t *testing.T) {
itest.IsEmpty{},
},
},
{
name: "extra records conflict",
opts: []Modifier{
WithTempDir(dir),
WithEnv(golang.DisableCGO()),
WithInit("init"),
WithShell("ls"),
WithRecord(cpio.StaticFile("bbin/ls", "foo", 0o111)),
WithBusyboxCommands(
"github.com/u-root/u-root/cmds/core/init",
"github.com/u-root/u-root/cmds/core/ls",
),
},
errs: []error{os.ErrExist},
validators: []itest.ArchiveValidator{
itest.IsEmpty{},
},
},
{
name: "extra records",
opts: []Modifier{
WithTempDir(dir),
WithEnv(golang.DisableCGO()),
WithInit("init"),
WithShell("ls"),
WithRecord(cpio.StaticFile("etc/foo", "foo", 0o111)),
WithBusyboxCommands(
"github.com/u-root/u-root/cmds/core/init",
"github.com/u-root/u-root/cmds/core/ls",
),
},
validators: []itest.ArchiveValidator{
itest.HasFile{Path: "bbin/bb"},
itest.HasRecord{R: cpio.StaticFile("etc/foo", "foo", 0o111)},
},
},
} {
t.Run(fmt.Sprintf("Test %d [%s]", i, tt.name), func(t *testing.T) {
archive := cpio.InMemArchive()
Expand Down

0 comments on commit 5c0bcd2

Please sign in to comment.