Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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},
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