Skip to content

Commit

Permalink
Wire templates into mkuimage
Browse files Browse the repository at this point in the history
mkuimage defaults for init & shell are removed. Templates can be used
instead.

Signed-off-by: Chris Koch <[email protected]>
  • Loading branch information
hugelgupf committed Feb 18, 2024
1 parent 4d02d3e commit c7e5cd4
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 23 deletions.
55 changes: 42 additions & 13 deletions cmd/mkuimage/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/dustin/go-humanize"
"github.com/u-root/gobusybox/src/pkg/golang"
"github.com/u-root/mkuimage/uimage"
"github.com/u-root/mkuimage/uimage/templates"
"github.com/u-root/mkuimage/uimage/uflags"
"github.com/u-root/uio/llog"
)
Expand All @@ -26,6 +27,11 @@ var (
errEmptyFilesArg = errors.New("empty argument to -files")
)

var (
config = flag.String("config", "", "Config to pick from templates")
configFile = flag.String("config-file", "", "Config file to read from (default: finds .mkuimage.yaml in cwd or parents)")
)

// checkArgs checks for common mistakes that cause confusion.
// 1. -files as the last argument
// 2. -files followed by any switch, indicating a shell expansion problem
Expand Down Expand Up @@ -61,20 +67,12 @@ func main() {
log.Fatal(err)
}

var sh string
if golang.Default().GOOS != "plan9" {
sh = "gosh"
}

env := golang.Default(golang.DisableCGO())
f := &uflags.Flags{
Commands: uflags.CommandFlags{
Env: env,
Builder: "bb",
BuildOpts: &golang.BuildOpts{},
},
Init: "init",
Shell: sh,
ArchiveFormat: "cpio",
OutputFile: defaultFile(env),
}
Expand All @@ -84,15 +82,32 @@ func main() {
l.RegisterVerboseFlag(flag.CommandLine, "v", slog.LevelDebug)
flag.Parse()

var tpl *templates.Templates
var err error
if *configFile != "" {
tpl, err = templates.TemplateFromFile(*configFile)
if err != nil {
l.Errorf("Failed to read template: %v", err)
os.Exit(1)
}
} else {
tpl, err = templates.Template()
// Only complain about not finding a template if user requested a templated config.
if err != nil && *config != "" {
l.Errorf("Could not find template file: %v", err)
os.Exit(1)
}
}

l.Infof("Build environment: %s", env)
if env.GOOS != "linux" {
l.Warnf("GOOS is not linux. Did you mean to set GOOS=linux?")
}

// Main is in a separate functions so defers run on return.
if err := Main(l, f); err != nil {
if err := Main(l, env, tpl, f); err != nil {
l.Errorf("Build error: %v", err)
return
os.Exit(1)
}

if stat, err := os.Stat(f.OutputFile); err == nil && f.ArchiveFormat == "cpio" {
Expand Down Expand Up @@ -124,8 +139,7 @@ func defaultFile(env *golang.Environ) string {

// Main is a separate function so defers are run on return, which they wouldn't
// on exit.
func Main(l *llog.Logger, f *uflags.Flags) error {
env := f.Commands.Env
func Main(l *llog.Logger, env *golang.Environ, tpl *templates.Templates, f *uflags.Flags) error {
v, err := env.Version()
if err != nil {
l.Infof("Could not get environment's Go version, using runtime's version: %v", err)
Expand Down Expand Up @@ -160,9 +174,24 @@ func Main(l *llog.Logger, f *uflags.Flags) error {

// Set default output.
m := []uimage.Modifier{
uimage.WithReplaceEnv(env),
uimage.WithCPIOOutput(defaultFile(env)),
}
more, err := f.Modifiers(flag.Args()...)
// Evaluate template first -- template settings may always be
// appended/overridden by further flag-based settings.
if *config != "" {
mods, err := tpl.Uimage(*config)
if err != nil {
return err
}
m = append(m, mods...)
}
pkgs := flag.Args()
// Expand command templates.
if tpl != nil {
pkgs = tpl.CommandsFor(pkgs...)
}
more, err := f.Modifiers(pkgs...)
if err != nil {
return err
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/mkuimage/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ func TestUrootCmdline(t *testing.T) {
}

func buildIt(t *testing.T, execPath string, args, env []string, want error, gocoverdir string) (*os.File, []byte, error) {
t.Helper()
//t.Helper()
initramfs, err := os.CreateTemp(t.TempDir(), "u-root-")
if err != nil {
return nil, nil, err
Expand All @@ -240,7 +240,8 @@ func buildIt(t *testing.T, execPath string, args, env []string, want error, goco
c.Env = append(os.Environ(), env...)
c.Env = append(c.Env, golang.Default().Env()...)
c.Env = append(c.Env, "GOCOVERDIR="+gocoverdir)
if out, err := c.CombinedOutput(); err != want {
out, err := c.CombinedOutput()
if err != want {
return nil, nil, fmt.Errorf("Error: %v\nOutput:\n%s", err, out)
} else if err != nil {
return initramfs, nil, err
Expand Down
26 changes: 18 additions & 8 deletions uimage/uflags/uflags.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ import (

// CommandFlags are flags related to Go commands to be built by mkuimage.
type CommandFlags struct {
Env *golang.Environ
NoCommands bool
Builder string
ShellBang bool
Mod golang.ModBehavior
BuildTags []string
BuildOpts *golang.BuildOpts
}

Expand All @@ -37,34 +38,43 @@ func (c *CommandFlags) RegisterFlags(f *flag.FlagSet) {
// Register an alias for -go-no-strip for backwards compatibility.
f.BoolVar(&c.BuildOpts.NoStrip, "no-strip", false, "Build unstripped binaries")

if c.Env == nil {
c.Env = golang.Default()
// Flags for golang.Environ.
defMod := ""
if golang.Default().GO111MODULE != "off" {
defMod = "readonly"
}
c.Env.RegisterFlags(f)
f.StringVar((*string)(&c.Mod), "go-mod", defMod, "Value of -mod to go commands (allowed: (empty), vendor, mod, readonly)")
// Register an alias for -go-build-tags for backwards compatibility.
f.Var((*uflag.Strings)(&c.Env.BuildTags), "tags", "Go build tags -- repeat the flag for multiple values")
f.Var((*uflag.Strings)(&c.BuildTags), "tags", "Go build tags -- repeat the flag for multiple values")
f.Var((*uflag.Strings)(&c.BuildTags), "go-build-tags", "Go build tags -- repeat the flag for multiple values")
}

// Modifiers turns the flag values into uimage modifiers.
func (c *CommandFlags) Modifiers(packages ...string) ([]uimage.Modifier, error) {
if c.NoCommands {
// Later modifiers may still add packages, so let's set the right environment.
return []uimage.Modifier{
uimage.WithReplaceEnv(c.Env),
uimage.WithEnv(golang.WithBuildTag(c.BuildTags...), func(e *golang.Environ) {
e.Mod = c.Mod
}),
}, nil
}

switch c.Builder {
case "bb", "gbb":
return []uimage.Modifier{
uimage.WithReplaceEnv(c.Env),
uimage.WithEnv(golang.WithBuildTag(c.BuildTags...), func(e *golang.Environ) {
e.Mod = c.Mod
}),
uimage.WithBusyboxCommands(packages...),
uimage.WithShellBang(c.ShellBang),
uimage.WithBusyboxBuildOpts(c.BuildOpts),
}, nil
case "binary":
return []uimage.Modifier{
uimage.WithReplaceEnv(c.Env),
uimage.WithEnv(golang.WithBuildTag(c.BuildTags...), func(e *golang.Environ) {
e.Mod = c.Mod
}),
uimage.WithCommands(c.BuildOpts, builder.Binary, packages...),
}, nil
default:
Expand Down

0 comments on commit c7e5cd4

Please sign in to comment.