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