github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/examples/fixmynetboot/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  	"fmt"
    10  	"log"
    11  	"net"
    12  
    13  	"github.com/u-root/u-root/pkg/checker"
    14  )
    15  
    16  // fixmynetboot is a troubleshooting tool that can help you identify issues that
    17  // won't let your system boot over the network.
    18  // NOTE: this is a DEMO tool. It's here only to show you how to write your own
    19  // checks and remediations. Don't use it in production.
    20  
    21  var emergencyShellBanner = `
    22  **************************************************************************
    23  ** Interface checks failed, see the output above to debug the issue.     *
    24  ** Entering the emergency shell, where you can run "fixmynetboot" again, *
    25  ** or any other LinuxBoot command.                                       *
    26  **************************************************************************
    27  `
    28  
    29  var (
    30  	doEmergencyShell = flag.Bool("shell", false, "Run emergency shell if checks fail")
    31  )
    32  
    33  func checkInterface(ifname string) error {
    34  	checklist := []checker.Check{
    35  		{
    36  			Name:        fmt.Sprintf("%s exists", ifname),
    37  			Run:         checker.InterfaceExists(ifname),
    38  			Remediate:   checker.InterfaceRemediate(ifname),
    39  			StopOnError: true,
    40  		},
    41  		{
    42  			Name:        fmt.Sprintf("%s link speed", ifname),
    43  			Run:         checker.LinkSpeed(ifname, 400000),
    44  			Remediate:   nil,
    45  			StopOnError: false},
    46  		{
    47  			Name:        fmt.Sprintf("%s link autoneg", ifname),
    48  			Run:         checker.LinkAutoneg(ifname, true),
    49  			Remediate:   nil,
    50  			StopOnError: false,
    51  		},
    52  		{
    53  			Name:        fmt.Sprintf("%s has link-local", ifname),
    54  			Run:         checker.InterfaceHasLinkLocalAddress(ifname),
    55  			Remediate:   nil,
    56  			StopOnError: true,
    57  		},
    58  		{
    59  			Name:        fmt.Sprintf("%s has global addresses", ifname),
    60  			Run:         checker.InterfaceHasGlobalAddresses("eth0"),
    61  			Remediate:   nil,
    62  			StopOnError: true,
    63  		},
    64  	}
    65  
    66  	return checker.Run(checklist)
    67  }
    68  
    69  func getNonLoopbackInterfaces() ([]string, error) {
    70  	var interfaces []string
    71  	allInterfaces, err := net.Interfaces()
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  	for _, iface := range allInterfaces {
    76  		if iface.Flags&net.FlagLoopback == 0 {
    77  			interfaces = append(interfaces, iface.Name)
    78  		}
    79  	}
    80  	return interfaces, nil
    81  }
    82  
    83  func main() {
    84  	flag.Parse()
    85  	var (
    86  		interfaces []string
    87  		err        error
    88  	)
    89  	ifname := flag.Arg(0)
    90  	if ifname == "" {
    91  		interfaces, err = getNonLoopbackInterfaces()
    92  		if err != nil {
    93  			log.Fatal(err)
    94  		}
    95  	} else {
    96  		interfaces = []string{ifname}
    97  	}
    98  
    99  	for _, ifname := range interfaces {
   100  		if err := checkInterface(ifname); err != nil {
   101  			if !*doEmergencyShell {
   102  				log.Fatal(err)
   103  			}
   104  			if err := checker.EmergencyShell(emergencyShellBanner)(); err != nil {
   105  				log.Fatal(err)
   106  			}
   107  		}
   108  	}
   109  }