github.hscsec.cn/u-root/u-root@v7.0.0+incompatible/cmds/exp/esxiboot/esxiboot.go (about)

     1  // Copyright 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  // esxiboot executes ESXi kernel over the running kernel.
     6  //
     7  // Synopsis:
     8  //     esxiboot [-d --device] [-c --config] [-r --cdrom]
     9  //
    10  // Description:
    11  //     Loads and executes ESXi kernel.
    12  //
    13  // Options:
    14  //     --config=FILE or -c=FILE: set the ESXi config
    15  //     --device=FILE or -d=FILE: set an ESXi disk to boot from
    16  //     --cdrom=FILE or -r=FILE: set an ESXI CDROM to boot from
    17  //     --append: append kernel cmdline arguments
    18  //
    19  // --device is required to kexec installed ESXi instance.
    20  // You don't need it if you kexec ESXi installer.
    21  //
    22  // The config file has the following syntax:
    23  //
    24  // kernel=PATH
    25  // kernelopt=OPTS
    26  // modules=MOD1 [ARGS] --- MOD2 [ARGS] --- ...
    27  //
    28  // Lines starting with '#' are ignored.
    29  
    30  package main
    31  
    32  import (
    33  	"log"
    34  	"os"
    35  	"strings"
    36  
    37  	flag "github.com/spf13/pflag"
    38  	"github.com/u-root/u-root/pkg/boot"
    39  	"github.com/u-root/u-root/pkg/boot/esxi"
    40  	"github.com/u-root/u-root/pkg/mount"
    41  )
    42  
    43  var (
    44  	cfg           = flag.StringP("config", "c", "", "ESXi config file")
    45  	cdrom         = flag.StringP("cdrom", "r", "", "ESXi CDROM boot device")
    46  	diskDev       = flag.StringP("device", "d", "", "ESXi disk boot device")
    47  	appendCmdline = flag.StringArray("append", nil, "Arguments to append to kernel cmdline")
    48  	dryRun        = flag.Bool("dry-run", false, "dry run (just mount + load the kernel, don't kexec)")
    49  )
    50  
    51  func main() {
    52  	flag.Parse()
    53  	if *diskDev == "" && *cfg == "" && *cdrom == "" {
    54  		log.Printf("Either --config, --device, or --cdrom must be specified")
    55  		flag.PrintDefaults()
    56  		os.Exit(1)
    57  	}
    58  
    59  	if len(*diskDev) > 0 {
    60  		imgs, mps, err := esxi.LoadDisk(*diskDev)
    61  		if err != nil {
    62  			log.Fatalf("Failed to load ESXi configuration: %v", err)
    63  		}
    64  
    65  		loaded := false
    66  		for _, img := range imgs {
    67  			if len(*appendCmdline) > 0 {
    68  				img.Cmdline = img.Cmdline + " " + strings.Join(*appendCmdline, " ")
    69  			}
    70  			if err := img.Load(false); err != nil {
    71  				log.Printf("Failed to load ESXi image (%v) into memory: %v", img, err)
    72  			} else {
    73  				log.Printf("Loaded image: %v", img)
    74  				// We loaded one, that's it.
    75  				loaded = true
    76  				break
    77  			}
    78  		}
    79  		for _, mp := range mps {
    80  			if err := mp.Unmount(mount.MNT_DETACH); err != nil {
    81  				log.Printf("Failed to unmount %s: %v", mp, err)
    82  			}
    83  		}
    84  		if !loaded {
    85  			log.Fatalf("Failed to load all ESXi images found.")
    86  		}
    87  	} else {
    88  		var err error
    89  		var img *boot.MultibootImage
    90  		var mp *mount.MountPoint
    91  		if len(*cfg) > 0 {
    92  			img, err = esxi.LoadConfig(*cfg)
    93  		} else if len(*cdrom) > 0 {
    94  			img, mp, err = esxi.LoadCDROM(*cdrom)
    95  		}
    96  		if err != nil {
    97  			log.Fatalf("Failed to load ESXi configuration: %v", err)
    98  		}
    99  		if len(*appendCmdline) > 0 {
   100  			img.Cmdline = img.Cmdline + " " + strings.Join(*appendCmdline, " ")
   101  		}
   102  		if err := img.Load(false); err != nil {
   103  			log.Fatalf("Failed to load ESXi image (%v) into memory: %v", img, err)
   104  		}
   105  		log.Printf("Loaded image: %v", img)
   106  		if mp != nil {
   107  			if err := mp.Unmount(mount.MNT_DETACH); err != nil {
   108  				log.Printf("Failed to unmount %s: %v", mp, err)
   109  			}
   110  		}
   111  	}
   112  
   113  	if *dryRun {
   114  		log.Printf("Dry run: not booting kernel.")
   115  		os.Exit(0)
   116  	}
   117  	if err := boot.Execute(); err != nil {
   118  		log.Fatalf("Failed to boot image: %v", err)
   119  	}
   120  }