gopkg.in/hugelgupf/u-root.v7@v7.0.0-20180831062900-6a07824681b2/u-root.go (about)

     1  // Copyright 2015-2018 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"flag"
     9  	"fmt"
    10  	"io/ioutil"
    11  	"log"
    12  	"os"
    13  
    14  	"github.com/u-root/u-root/pkg/golang"
    15  	"github.com/u-root/u-root/pkg/uroot"
    16  	"github.com/u-root/u-root/pkg/uroot/builder"
    17  	"github.com/u-root/u-root/pkg/uroot/initramfs"
    18  )
    19  
    20  // multiFlag is used for flags that support multiple invocations, e.g. -files
    21  type multiFlag []string
    22  
    23  func (m *multiFlag) String() string {
    24  	return fmt.Sprint(*m)
    25  }
    26  
    27  func (m *multiFlag) Set(value string) error {
    28  	*m = append(*m, value)
    29  	return nil
    30  }
    31  
    32  // Flags for u-root builder.
    33  var (
    34  	build, format, tmpDir, base, outputPath *string
    35  	initCmd                                 *string
    36  	defaultShell                            *string
    37  	useExistingInit                         *bool
    38  	extraFiles                              multiFlag
    39  	templates                               = map[string][]string{
    40  		"all": {
    41  			"github.com/u-root/u-root/cmds/*",
    42  		},
    43  		// Core should be things you don't want to live without.
    44  		"core": {
    45  			"github.com/u-root/u-root/cmds/ansi",
    46  			"github.com/u-root/u-root/cmds/boot",
    47  			"github.com/u-root/u-root/cmds/cat",
    48  			"github.com/u-root/u-root/cmds/cbmem",
    49  			"github.com/u-root/u-root/cmds/chmod",
    50  			"github.com/u-root/u-root/cmds/chroot",
    51  			"github.com/u-root/u-root/cmds/cmp",
    52  			"github.com/u-root/u-root/cmds/console",
    53  			"github.com/u-root/u-root/cmds/cp",
    54  			"github.com/u-root/u-root/cmds/cpio",
    55  			"github.com/u-root/u-root/cmds/date",
    56  			"github.com/u-root/u-root/cmds/dd",
    57  			"github.com/u-root/u-root/cmds/df",
    58  			"github.com/u-root/u-root/cmds/dhclient",
    59  			"github.com/u-root/u-root/cmds/dirname",
    60  			"github.com/u-root/u-root/cmds/dmesg",
    61  			"github.com/u-root/u-root/cmds/echo",
    62  			"github.com/u-root/u-root/cmds/false",
    63  			"github.com/u-root/u-root/cmds/field",
    64  			"github.com/u-root/u-root/cmds/find",
    65  			"github.com/u-root/u-root/cmds/free",
    66  			"github.com/u-root/u-root/cmds/freq",
    67  			"github.com/u-root/u-root/cmds/gpgv",
    68  			"github.com/u-root/u-root/cmds/gpt",
    69  			"github.com/u-root/u-root/cmds/grep",
    70  			"github.com/u-root/u-root/cmds/gzip",
    71  			"github.com/u-root/u-root/cmds/hexdump",
    72  			"github.com/u-root/u-root/cmds/hostname",
    73  			"github.com/u-root/u-root/cmds/id",
    74  			"github.com/u-root/u-root/cmds/init",
    75  			"github.com/u-root/u-root/cmds/insmod",
    76  			"github.com/u-root/u-root/cmds/installcommand",
    77  			"github.com/u-root/u-root/cmds/io",
    78  			"github.com/u-root/u-root/cmds/ip",
    79  			"github.com/u-root/u-root/cmds/kexec",
    80  			"github.com/u-root/u-root/cmds/kill",
    81  			"github.com/u-root/u-root/cmds/lddfiles",
    82  			"github.com/u-root/u-root/cmds/ln",
    83  			"github.com/u-root/u-root/cmds/losetup",
    84  			"github.com/u-root/u-root/cmds/ls",
    85  			"github.com/u-root/u-root/cmds/lsmod",
    86  			"github.com/u-root/u-root/cmds/mkdir",
    87  			"github.com/u-root/u-root/cmds/mkfifo",
    88  			"github.com/u-root/u-root/cmds/mknod",
    89  			"github.com/u-root/u-root/cmds/modprobe",
    90  			"github.com/u-root/u-root/cmds/mount",
    91  			"github.com/u-root/u-root/cmds/msr",
    92  			"github.com/u-root/u-root/cmds/mv",
    93  			"github.com/u-root/u-root/cmds/netcat",
    94  			"github.com/u-root/u-root/cmds/ntpdate",
    95  			"github.com/u-root/u-root/cmds/pci",
    96  			"github.com/u-root/u-root/cmds/ping",
    97  			"github.com/u-root/u-root/cmds/printenv",
    98  			"github.com/u-root/u-root/cmds/ps",
    99  			"github.com/u-root/u-root/cmds/pwd",
   100  			"github.com/u-root/u-root/cmds/pxeboot",
   101  			"github.com/u-root/u-root/cmds/readlink",
   102  			"github.com/u-root/u-root/cmds/rm",
   103  			"github.com/u-root/u-root/cmds/rmmod",
   104  			"github.com/u-root/u-root/cmds/rsdp",
   105  			"github.com/u-root/u-root/cmds/rush",
   106  			"github.com/u-root/u-root/cmds/seq",
   107  			"github.com/u-root/u-root/cmds/shutdown",
   108  			"github.com/u-root/u-root/cmds/sleep",
   109  			"github.com/u-root/u-root/cmds/sort",
   110  			"github.com/u-root/u-root/cmds/stty",
   111  			"github.com/u-root/u-root/cmds/switch_root",
   112  			"github.com/u-root/u-root/cmds/sync",
   113  			"github.com/u-root/u-root/cmds/tail",
   114  			"github.com/u-root/u-root/cmds/tee",
   115  			"github.com/u-root/u-root/cmds/true",
   116  			"github.com/u-root/u-root/cmds/truncate",
   117  			"github.com/u-root/u-root/cmds/umount",
   118  			"github.com/u-root/u-root/cmds/uname",
   119  			"github.com/u-root/u-root/cmds/uniq",
   120  			"github.com/u-root/u-root/cmds/unshare",
   121  			"github.com/u-root/u-root/cmds/validate",
   122  			"github.com/u-root/u-root/cmds/vboot",
   123  			"github.com/u-root/u-root/cmds/wc",
   124  			"github.com/u-root/u-root/cmds/wget",
   125  			"github.com/u-root/u-root/cmds/which",
   126  		},
   127  		// Minimal should be things you can't live without.
   128  		"minimal": {
   129  			"github.com/u-root/u-root/cmds/cat",
   130  			"github.com/u-root/u-root/cmds/chmod",
   131  			"github.com/u-root/u-root/cmds/cmp",
   132  			"github.com/u-root/u-root/cmds/console",
   133  			"github.com/u-root/u-root/cmds/cp",
   134  			"github.com/u-root/u-root/cmds/date",
   135  			"github.com/u-root/u-root/cmds/dd",
   136  			"github.com/u-root/u-root/cmds/df",
   137  			"github.com/u-root/u-root/cmds/dhclient",
   138  			"github.com/u-root/u-root/cmds/dmesg",
   139  			"github.com/u-root/u-root/cmds/echo",
   140  			"github.com/u-root/u-root/cmds/find",
   141  			"github.com/u-root/u-root/cmds/free",
   142  			"github.com/u-root/u-root/cmds/gpgv",
   143  			"github.com/u-root/u-root/cmds/grep",
   144  			"github.com/u-root/u-root/cmds/gzip",
   145  			"github.com/u-root/u-root/cmds/hostname",
   146  			"github.com/u-root/u-root/cmds/id",
   147  			"github.com/u-root/u-root/cmds/init",
   148  			"github.com/u-root/u-root/cmds/insmod",
   149  			"github.com/u-root/u-root/cmds/io",
   150  			"github.com/u-root/u-root/cmds/ip",
   151  			"github.com/u-root/u-root/cmds/kexec",
   152  			"github.com/u-root/u-root/cmds/kill",
   153  			"github.com/u-root/u-root/cmds/ln",
   154  			"github.com/u-root/u-root/cmds/losetup",
   155  			"github.com/u-root/u-root/cmds/ls",
   156  			"github.com/u-root/u-root/cmds/lsmod",
   157  			"github.com/u-root/u-root/cmds/mkdir",
   158  			"github.com/u-root/u-root/cmds/mknod",
   159  			"github.com/u-root/u-root/cmds/modprobe",
   160  			"github.com/u-root/u-root/cmds/mount",
   161  			"github.com/u-root/u-root/cmds/msr",
   162  			"github.com/u-root/u-root/cmds/mv",
   163  			"github.com/u-root/u-root/cmds/pci",
   164  			"github.com/u-root/u-root/cmds/ping",
   165  			"github.com/u-root/u-root/cmds/printenv",
   166  			"github.com/u-root/u-root/cmds/ps",
   167  			"github.com/u-root/u-root/cmds/pwd",
   168  			"github.com/u-root/u-root/cmds/readlink",
   169  			"github.com/u-root/u-root/cmds/rm",
   170  			"github.com/u-root/u-root/cmds/rmmod",
   171  			"github.com/u-root/u-root/cmds/rush",
   172  			"github.com/u-root/u-root/cmds/seq",
   173  			"github.com/u-root/u-root/cmds/shutdown",
   174  			"github.com/u-root/u-root/cmds/sleep",
   175  			"github.com/u-root/u-root/cmds/sync",
   176  			"github.com/u-root/u-root/cmds/tail",
   177  			"github.com/u-root/u-root/cmds/tee",
   178  			"github.com/u-root/u-root/cmds/truncate",
   179  			"github.com/u-root/u-root/cmds/umount",
   180  			"github.com/u-root/u-root/cmds/uname",
   181  			"github.com/u-root/u-root/cmds/unshare",
   182  			"github.com/u-root/u-root/cmds/wc",
   183  			"github.com/u-root/u-root/cmds/wget",
   184  			"github.com/u-root/u-root/cmds/which",
   185  		},
   186  		// coreboot-app minimal environment
   187  		"coreboot-app": {
   188  			"github.com/u-root/u-root/cmds/cat",
   189  			"github.com/u-root/u-root/cmds/cbmem",
   190  			"github.com/u-root/u-root/cmds/chroot",
   191  			"github.com/u-root/u-root/cmds/console",
   192  			"github.com/u-root/u-root/cmds/cp",
   193  			"github.com/u-root/u-root/cmds/dd",
   194  			"github.com/u-root/u-root/cmds/dhclient",
   195  			"github.com/u-root/u-root/cmds/dmesg",
   196  			"github.com/u-root/u-root/cmds/find",
   197  			"github.com/u-root/u-root/cmds/grep",
   198  			"github.com/u-root/u-root/cmds/id",
   199  			"github.com/u-root/u-root/cmds/init",
   200  			"github.com/u-root/u-root/cmds/insmod",
   201  			"github.com/u-root/u-root/cmds/ip",
   202  			"github.com/u-root/u-root/cmds/kill",
   203  			"github.com/u-root/u-root/cmds/ls",
   204  			"github.com/u-root/u-root/cmds/modprobe",
   205  			"github.com/u-root/u-root/cmds/mount",
   206  			"github.com/u-root/u-root/cmds/pci",
   207  			"github.com/u-root/u-root/cmds/ping",
   208  			"github.com/u-root/u-root/cmds/ps",
   209  			"github.com/u-root/u-root/cmds/pwd",
   210  			"github.com/u-root/u-root/cmds/rm",
   211  			"github.com/u-root/u-root/cmds/rmmod",
   212  			"github.com/u-root/u-root/cmds/rush",
   213  			"github.com/u-root/u-root/cmds/shutdown",
   214  			"github.com/u-root/u-root/cmds/sshd",
   215  			"github.com/u-root/u-root/cmds/switch_root",
   216  			"github.com/u-root/u-root/cmds/tail",
   217  			"github.com/u-root/u-root/cmds/tee",
   218  			"github.com/u-root/u-root/cmds/uname",
   219  			"github.com/u-root/u-root/cmds/wget",
   220  		},
   221  	}
   222  )
   223  
   224  func init() {
   225  	build = flag.String("build", "source", "u-root build format (e.g. bb or source).")
   226  	format = flag.String("format", "cpio", "Archival format.")
   227  
   228  	tmpDir = flag.String("tmpdir", "", "Temporary directory to put binaries in.")
   229  
   230  	base = flag.String("base", "", "Base archive to add files to.")
   231  	useExistingInit = flag.Bool("useinit", false, "Use existing init from base archive (only if --base was specified).")
   232  	outputPath = flag.String("o", "", "Path to output initramfs file.")
   233  
   234  	initCmd = flag.String("initcmd", "init", "Symlink target for /init. Can be an absolute path or a u-root command name.")
   235  	defaultShell = flag.String("defaultsh", "rush", "Default shell. Can be an absolute path or a u-root command name.")
   236  
   237  	flag.Var(&extraFiles, "files", "Additional files, directories, and binaries (with their ldd dependencies) to add to archive. Can be speficified multiple times.")
   238  }
   239  
   240  func main() {
   241  	flag.Parse()
   242  
   243  	// Main is in a separate functions so defers run on return.
   244  	if err := Main(); err != nil {
   245  		log.Fatal(err)
   246  	}
   247  	log.Printf("Successfully wrote initramfs.")
   248  }
   249  
   250  // Main is a separate function so defers are run on return, which they wouldn't
   251  // on exit.
   252  func Main() error {
   253  	env := golang.Default()
   254  	if env.CgoEnabled {
   255  		log.Printf("Disabling CGO for u-root...")
   256  		env.CgoEnabled = false
   257  	}
   258  	log.Printf("Build environment: %s", env)
   259  	if env.GOOS != "linux" {
   260  		log.Printf("GOOS is not linux. Did you mean to set GOOS=linux?")
   261  	}
   262  
   263  	builder, err := builder.GetBuilder(*build)
   264  	if err != nil {
   265  		return err
   266  	}
   267  	archiver, err := initramfs.GetArchiver(*format)
   268  	if err != nil {
   269  		return err
   270  	}
   271  
   272  	tempDir := *tmpDir
   273  	if tempDir == "" {
   274  		var err error
   275  		tempDir, err = ioutil.TempDir("", "u-root")
   276  		if err != nil {
   277  			return err
   278  		}
   279  		defer os.RemoveAll(tempDir)
   280  	} else if _, err := os.Stat(tempDir); os.IsNotExist(err) {
   281  		if err := os.MkdirAll(tempDir, 0755); err != nil {
   282  			return fmt.Errorf("temporary directory %q did not exist; tried to mkdir but failed: %v", tempDir, err)
   283  		}
   284  	}
   285  
   286  	// Resolve globs into package imports.
   287  	//
   288  	// Currently allowed formats:
   289  	//   Go package imports; e.g. github.com/u-root/u-root/cmds/ls (must be in $GOPATH)
   290  	//   Paths to Go package directories; e.g. $GOPATH/src/github.com/u-root/u-root/cmds/*
   291  	var pkgs []string
   292  	for _, a := range flag.Args() {
   293  		p, ok := templates[a]
   294  		if !ok {
   295  			pkgs = append(pkgs, a)
   296  			continue
   297  		}
   298  		pkgs = append(pkgs, p...)
   299  	}
   300  	if len(pkgs) == 0 {
   301  		pkgs = []string{"github.com/u-root/u-root/cmds/*"}
   302  	}
   303  
   304  	// Open the target initramfs file.
   305  	w, err := archiver.OpenWriter(*outputPath, env.GOOS, env.GOARCH)
   306  	if err != nil {
   307  		return err
   308  	}
   309  
   310  	var baseFile initramfs.Reader
   311  	if *base != "" {
   312  		bf, err := os.Open(*base)
   313  		if err != nil {
   314  			return err
   315  		}
   316  		defer bf.Close()
   317  		baseFile = archiver.Reader(bf)
   318  	}
   319  
   320  	opts := uroot.Opts{
   321  		Env: env,
   322  		// The command-line tool only allows specifying one build mode
   323  		// right now.
   324  		Commands: []uroot.Commands{
   325  			{
   326  				Builder:  builder,
   327  				Packages: pkgs,
   328  			},
   329  		},
   330  		TempDir:         tempDir,
   331  		ExtraFiles:      extraFiles,
   332  		OutputFile:      w,
   333  		BaseArchive:     baseFile,
   334  		UseExistingInit: *useExistingInit,
   335  		InitCmd:         *initCmd,
   336  		DefaultShell:    *defaultShell,
   337  	}
   338  	return uroot.CreateInitramfs(opts)
   339  }