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 }