github.com/mem/u-root@v2.0.1-0.20181004165302-9b18b4636a33+incompatible/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/elvish", 63 "github.com/u-root/u-root/cmds/false", 64 "github.com/u-root/u-root/cmds/field", 65 "github.com/u-root/u-root/cmds/find", 66 "github.com/u-root/u-root/cmds/free", 67 "github.com/u-root/u-root/cmds/freq", 68 "github.com/u-root/u-root/cmds/gpgv", 69 "github.com/u-root/u-root/cmds/gpt", 70 "github.com/u-root/u-root/cmds/grep", 71 "github.com/u-root/u-root/cmds/gzip", 72 "github.com/u-root/u-root/cmds/hexdump", 73 "github.com/u-root/u-root/cmds/hostname", 74 "github.com/u-root/u-root/cmds/id", 75 "github.com/u-root/u-root/cmds/init", 76 "github.com/u-root/u-root/cmds/insmod", 77 "github.com/u-root/u-root/cmds/installcommand", 78 "github.com/u-root/u-root/cmds/io", 79 "github.com/u-root/u-root/cmds/ip", 80 "github.com/u-root/u-root/cmds/kexec", 81 "github.com/u-root/u-root/cmds/kill", 82 "github.com/u-root/u-root/cmds/lddfiles", 83 "github.com/u-root/u-root/cmds/ln", 84 "github.com/u-root/u-root/cmds/losetup", 85 "github.com/u-root/u-root/cmds/ls", 86 "github.com/u-root/u-root/cmds/lsmod", 87 "github.com/u-root/u-root/cmds/mkdir", 88 "github.com/u-root/u-root/cmds/mkfifo", 89 "github.com/u-root/u-root/cmds/mknod", 90 "github.com/u-root/u-root/cmds/modprobe", 91 "github.com/u-root/u-root/cmds/mount", 92 "github.com/u-root/u-root/cmds/msr", 93 "github.com/u-root/u-root/cmds/mv", 94 "github.com/u-root/u-root/cmds/netcat", 95 "github.com/u-root/u-root/cmds/ntpdate", 96 "github.com/u-root/u-root/cmds/pci", 97 "github.com/u-root/u-root/cmds/ping", 98 "github.com/u-root/u-root/cmds/printenv", 99 "github.com/u-root/u-root/cmds/ps", 100 "github.com/u-root/u-root/cmds/pwd", 101 "github.com/u-root/u-root/cmds/pxeboot", 102 "github.com/u-root/u-root/cmds/readlink", 103 "github.com/u-root/u-root/cmds/rm", 104 "github.com/u-root/u-root/cmds/rmmod", 105 "github.com/u-root/u-root/cmds/rsdp", 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/elvish", 141 "github.com/u-root/u-root/cmds/find", 142 "github.com/u-root/u-root/cmds/free", 143 "github.com/u-root/u-root/cmds/gpgv", 144 "github.com/u-root/u-root/cmds/grep", 145 "github.com/u-root/u-root/cmds/gzip", 146 "github.com/u-root/u-root/cmds/hostname", 147 "github.com/u-root/u-root/cmds/id", 148 "github.com/u-root/u-root/cmds/init", 149 "github.com/u-root/u-root/cmds/insmod", 150 "github.com/u-root/u-root/cmds/io", 151 "github.com/u-root/u-root/cmds/ip", 152 "github.com/u-root/u-root/cmds/kexec", 153 "github.com/u-root/u-root/cmds/kill", 154 "github.com/u-root/u-root/cmds/ln", 155 "github.com/u-root/u-root/cmds/losetup", 156 "github.com/u-root/u-root/cmds/ls", 157 "github.com/u-root/u-root/cmds/lsmod", 158 "github.com/u-root/u-root/cmds/mkdir", 159 "github.com/u-root/u-root/cmds/mknod", 160 "github.com/u-root/u-root/cmds/modprobe", 161 "github.com/u-root/u-root/cmds/mount", 162 "github.com/u-root/u-root/cmds/msr", 163 "github.com/u-root/u-root/cmds/mv", 164 "github.com/u-root/u-root/cmds/pci", 165 "github.com/u-root/u-root/cmds/ping", 166 "github.com/u-root/u-root/cmds/printenv", 167 "github.com/u-root/u-root/cmds/ps", 168 "github.com/u-root/u-root/cmds/pwd", 169 "github.com/u-root/u-root/cmds/readlink", 170 "github.com/u-root/u-root/cmds/rm", 171 "github.com/u-root/u-root/cmds/rmmod", 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/elvish", 197 "github.com/u-root/u-root/cmds/find", 198 "github.com/u-root/u-root/cmds/grep", 199 "github.com/u-root/u-root/cmds/id", 200 "github.com/u-root/u-root/cmds/init", 201 "github.com/u-root/u-root/cmds/insmod", 202 "github.com/u-root/u-root/cmds/ip", 203 "github.com/u-root/u-root/cmds/kill", 204 "github.com/u-root/u-root/cmds/ls", 205 "github.com/u-root/u-root/cmds/modprobe", 206 "github.com/u-root/u-root/cmds/mount", 207 "github.com/u-root/u-root/cmds/pci", 208 "github.com/u-root/u-root/cmds/ping", 209 "github.com/u-root/u-root/cmds/ps", 210 "github.com/u-root/u-root/cmds/pwd", 211 "github.com/u-root/u-root/cmds/rm", 212 "github.com/u-root/u-root/cmds/rmmod", 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. By default, this is a couple of directories like /bin, /etc, etc.") 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", "elvish", "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 } else { 319 baseFile = uroot.DefaultRamfs.Reader() 320 } 321 322 opts := uroot.Opts{ 323 Env: env, 324 // The command-line tool only allows specifying one build mode 325 // right now. 326 Commands: []uroot.Commands{ 327 { 328 Builder: builder, 329 Packages: pkgs, 330 }, 331 }, 332 TempDir: tempDir, 333 ExtraFiles: extraFiles, 334 OutputFile: w, 335 BaseArchive: baseFile, 336 UseExistingInit: *useExistingInit, 337 InitCmd: *initCmd, 338 DefaultShell: *defaultShell, 339 } 340 logger := log.New(os.Stderr, "", log.LstdFlags) 341 return uroot.CreateInitramfs(logger, opts) 342 }