github.com/ratrocket/u-root@v0.0.0-20180201221235-1cf9f48ee2cf/u-root.go (about)

     1  // Copyright 2015-2017 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  )
    17  
    18  // multiFlag is used for flags that support multiple invocations, e.g. -files
    19  type multiFlag []string
    20  
    21  func (m *multiFlag) String() string {
    22  	return fmt.Sprint(*m)
    23  }
    24  
    25  func (m *multiFlag) Set(value string) error {
    26  	*m = append(*m, value)
    27  	return nil
    28  }
    29  
    30  // Flags for u-root builder.
    31  var (
    32  	build, format, tmpDir, base, outputPath *string
    33  	useExistingInit                         *bool
    34  	extraFiles                              multiFlag
    35  )
    36  
    37  func parseFlags() {
    38  	build = flag.String("build", "source", "u-root build format (e.g. bb or source)")
    39  	format = flag.String("format", "cpio", "Archival format (e.g. cpio)")
    40  
    41  	tmpDir = flag.String("tmpdir", "", "Temporary directory to put binaries in.")
    42  
    43  	base = flag.String("base", "", "Base archive to add files to")
    44  	useExistingInit = flag.Bool("useinit", false, "Use existing init from base archive (only if --base was specified).")
    45  	outputPath = flag.String("o", "", "Path to output initramfs file.")
    46  	flag.Var(&extraFiles, "files", "Additional files, directories, and binaries (with their ldd dependencies) to add to archive. Can be speficified multiple times")
    47  	flag.Parse()
    48  }
    49  
    50  func main() {
    51  	parseFlags()
    52  
    53  	// Main is in a separate functions so defer's run on return.
    54  	if err := Main(); err != nil {
    55  		log.Fatal(err)
    56  	}
    57  }
    58  
    59  func Main() error {
    60  	env := golang.Default()
    61  	if env.CgoEnabled {
    62  		log.Printf("Disabling CGO for u-root...")
    63  		env.CgoEnabled = false
    64  	}
    65  	log.Printf("Build environment: %s", env)
    66  	if env.GOOS != "linux" {
    67  		log.Printf("GOOS is not linux. Did you mean to set GOOS=linux?")
    68  	}
    69  
    70  	builder, err := uroot.GetBuilder(*build)
    71  	if err != nil {
    72  		return err
    73  	}
    74  	archiver, err := uroot.GetArchiver(*format)
    75  	if err != nil {
    76  		return err
    77  	}
    78  
    79  	tempDir := *tmpDir
    80  	if tempDir == "" {
    81  		var err error
    82  		tempDir, err = ioutil.TempDir("", "u-root")
    83  		if err != nil {
    84  			return err
    85  		}
    86  		defer os.RemoveAll(tempDir)
    87  	} else if _, err := os.Stat(tempDir); os.IsNotExist(err) {
    88  		if err := os.MkdirAll(tempDir, 0755); err != nil {
    89  			return fmt.Errorf("temporary directory %q did not exist; tried to mkdir but failed: %v", tempDir, err)
    90  		}
    91  	}
    92  
    93  	// Resolve globs into package imports.
    94  	//
    95  	// Currently allowed formats:
    96  	//   Go package imports; e.g. github.com/u-root/u-root/cmds/ls
    97  	//   Paths to Go package directories; e.g. $GOPATH/src/github.com/u-root/u-root/cmds/*
    98  	pkgs := flag.Args()
    99  	if len(pkgs) == 0 {
   100  		var err error
   101  		pkgs, err = uroot.DefaultPackageImports(env)
   102  		if err != nil {
   103  			return err
   104  		}
   105  	}
   106  
   107  	// Open the target initramfs file.
   108  	w, err := archiver.OpenWriter(*outputPath, env.GOOS, env.GOARCH)
   109  	if err != nil {
   110  		return err
   111  	}
   112  
   113  	var baseFile uroot.ArchiveReader
   114  	if *base != "" {
   115  		bf, err := os.Open(*base)
   116  		if err != nil {
   117  			return err
   118  		}
   119  		defer bf.Close()
   120  		baseFile = archiver.Reader(bf)
   121  	}
   122  
   123  	opts := uroot.Opts{
   124  		Env:             env,
   125  		Builder:         builder,
   126  		Archiver:        archiver,
   127  		TempDir:         tempDir,
   128  		Packages:        pkgs,
   129  		ExtraFiles:      extraFiles,
   130  		OutputFile:      w,
   131  		BaseArchive:     baseFile,
   132  		UseExistingInit: *useExistingInit,
   133  	}
   134  	if err := uroot.CreateInitramfs(opts); err != nil {
   135  		return err
   136  	}
   137  	return nil
   138  }