github.com/hugelgupf/u-root@v0.0.0-20191023214958-4807c632154c/cmds/boot/uinit/main.go (about)

     1  // Copyright 2017-2019 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  	"log"
    10  	"os"
    11  	"os/exec"
    12  	"os/signal"
    13  	"time"
    14  
    15  	"github.com/u-root/u-root/pkg/booter"
    16  )
    17  
    18  var (
    19  	allowInteractive = flag.Bool("i", true, "Allow user to interrupt boot process and run commands")
    20  	doQuiet          = flag.Bool("q", false, "Disable verbose output")
    21  	interval         = flag.Int("I", 1, "Interval in seconds before looping to the next boot command")
    22  	noDefaultBoot    = flag.Bool("nodefault", false, "Do not attempt default boot entries if regular ones fail")
    23  )
    24  
    25  var defaultBootsequence = [][]string{
    26  	{"fbnetboot", "-userclass", "linuxboot"},
    27  	{"localboot", "-grub"},
    28  }
    29  
    30  func main() {
    31  	flag.Parse()
    32  
    33  	log.Print(`
    34                       ____            _                 _                 _   
    35                      / ___| _   _ ___| |_ ___ _ __ ___ | |__   ___   ___ | |_ 
    36                      \___ \| | | / __| __/ _ \ '_ ` + "`" + ` _ \| '_ \ / _ \ / _ \| __|
    37                       ___) | |_| \__ \ ||  __/ | | | | | |_) | (_) | (_) | |_ 
    38                      |____/ \__, |___/\__\___|_| |_| |_|_.__/ \___/ \___/ \__|
    39                             |___/
    40  `)
    41  
    42  	sleepInterval := time.Duration(*interval) * time.Second
    43  
    44  	if *allowInteractive {
    45  		log.Printf("**************************************************************************")
    46  		log.Print("Starting boot sequence, press CTRL-C within 5 seconds to drop into a shell")
    47  		log.Printf("**************************************************************************")
    48  		time.Sleep(5 * time.Second)
    49  	} else {
    50  		signal.Ignore()
    51  	}
    52  
    53  	// Get and show boot entries
    54  	bootEntries := booter.GetBootEntries()
    55  	log.Printf("BOOT ENTRIES:")
    56  	for _, entry := range bootEntries {
    57  		log.Printf("    %v) %+v", entry.Name, string(entry.Config))
    58  	}
    59  	for _, entry := range bootEntries {
    60  		log.Printf("Trying boot entry %s: %s", entry.Name, string(entry.Config))
    61  		if err := entry.Booter.Boot(); err != nil {
    62  			log.Printf("Warning: failed to boot with configuration: %+v", entry)
    63  		}
    64  		if !*doQuiet {
    65  			log.Printf("Sleeping %v before attempting next boot command", sleepInterval)
    66  		}
    67  		time.Sleep(sleepInterval)
    68  	}
    69  
    70  	// if boot entries failed, use the default boot sequence
    71  	log.Printf("Boot entries failed")
    72  
    73  	if !*noDefaultBoot {
    74  		log.Print("Falling back to the default boot sequence")
    75  		for {
    76  			for _, bootcmd := range defaultBootsequence {
    77  				if !*doQuiet {
    78  					bootcmd = append(bootcmd, "-d")
    79  				}
    80  				log.Printf("Running boot command: %v", bootcmd)
    81  				cmd := exec.Command(bootcmd[0], bootcmd[1:]...)
    82  				cmd.Stdout = os.Stdout
    83  				cmd.Stderr = os.Stderr
    84  				if err := cmd.Run(); err != nil {
    85  					log.Printf("Error executing %v: %v", cmd, err)
    86  				}
    87  			}
    88  			if !*doQuiet {
    89  				log.Printf("Sleeping %v before attempting next boot command", sleepInterval)
    90  			}
    91  			time.Sleep(sleepInterval)
    92  		}
    93  	}
    94  }