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 }