github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/cmd/hyper-control/main.go (about)

     1  package main
     2  
     3  import (
     4  	"crypto/tls"
     5  	"flag"
     6  	"fmt"
     7  	"net"
     8  	"os"
     9  	"time"
    10  
    11  	"github.com/Cloud-Foundations/Dominator/lib/constants"
    12  	"github.com/Cloud-Foundations/Dominator/lib/flags/commands"
    13  	"github.com/Cloud-Foundations/Dominator/lib/flags/loadflags"
    14  	"github.com/Cloud-Foundations/Dominator/lib/flagutil"
    15  	"github.com/Cloud-Foundations/Dominator/lib/log/cmdlogger"
    16  	"github.com/Cloud-Foundations/Dominator/lib/net/rrdialer"
    17  	"github.com/Cloud-Foundations/Dominator/lib/srpc"
    18  	"github.com/Cloud-Foundations/Dominator/lib/srpc/setupclient"
    19  	"github.com/Cloud-Foundations/Dominator/lib/tags"
    20  	proto "github.com/Cloud-Foundations/Dominator/proto/hypervisor"
    21  )
    22  
    23  var (
    24  	externalLeaseHostnames flagutil.StringList
    25  	externalLeaseAddresses proto.AddressList
    26  	fleetManagerHostname   = flag.String("fleetManagerHostname", "",
    27  		"Hostname of Fleet Manager")
    28  	fleetManagerPortNum = flag.Uint("fleetManagerPortNum",
    29  		constants.FleetManagerPortNumber,
    30  		"Port number of Fleet Resource Manager")
    31  	hypervisorHostname = flag.String("hypervisorHostname", "",
    32  		"Hostname of hypervisor")
    33  	hypervisorPortNum = flag.Uint("hypervisorPortNum",
    34  		constants.HypervisorPortNumber, "Port number of hypervisor")
    35  	hypervisorTags      tags.Tags
    36  	imageServerHostname = flag.String("imageServerHostname", "localhost",
    37  		"Hostname of image server")
    38  	imageServerPortNum = flag.Uint("imageServerPortNum",
    39  		constants.ImageServerPortNumber,
    40  		"Port number of image server")
    41  	installerImageStream = flag.String("installerImageStream", "",
    42  		"Name of default image stream for building bootable installer ISO")
    43  	installerPortNum = flag.Uint("installerPortNum",
    44  		constants.InstallerPortNumber, "Port number of installer")
    45  	location = flag.String("location", "",
    46  		"Location to search for hypervisors")
    47  	offerTimeout = flag.Duration("offerTimeout", time.Minute+time.Second,
    48  		"How long to offer DHCP OFFERs and ACKs")
    49  	memory              = flagutil.Size(4 << 30)
    50  	netbootFiles        tags.Tags
    51  	netbootFilesTimeout = flag.Duration("netbootFilesTimeout",
    52  		time.Minute+time.Second,
    53  		"How long to provide files via TFTP after last DHCP ACK")
    54  	netbootTimeout = flag.Duration("netbootTimeout", time.Minute,
    55  		"Time to wait for DHCP ACKs to be sent")
    56  	networkInterfacesFile = flag.String("networkInterfacesFile", "",
    57  		"File containing network interfaces for show-network-configuration")
    58  	numAcknowledgementsToWaitFor = flag.Uint("numAcknowledgementsToWaitFor",
    59  		2, "Number of DHCP ACKs to wait for")
    60  	randomSeedBytes = flag.Uint("randomSeedBytes", 0,
    61  		"Number of bytes of random seed data to inject into installing machine")
    62  	storageLayoutFilename = flag.String("storageLayoutFilename", "",
    63  		"Name of file containing storage layout for installing machine")
    64  	subnetIDs       flagutil.StringList
    65  	targetImageName = flag.String("targetImageName", "",
    66  		"Name of image to install for netboot-{host,vm}")
    67  	topologyDir = flag.String("topologyDir", "",
    68  		"Name of local topology directory in Git repository")
    69  	useKexec = flag.Bool("useKexec", false,
    70  		"If true, use kexec to reboot into newly installed OS")
    71  	vncViewer   = flag.String("vncViewer", "", "Path to VNC viewer for VM")
    72  	volumeSizes = flagutil.SizeList{16 << 30}
    73  
    74  	rrDialer *rrdialer.Dialer
    75  )
    76  
    77  func init() {
    78  	flag.Var(&externalLeaseAddresses, "externalLeaseAddresses",
    79  		"List of addresses for register-external-leases")
    80  	flag.Var(&externalLeaseHostnames, "externalLeaseHostnames",
    81  		"Optional list of hostnames for register-external-leases")
    82  	flag.Var(&hypervisorTags, "hypervisorTags", "Tags to apply to Hypervisor")
    83  	flag.Var(&memory, "memory", "memory for VM")
    84  	flag.Var(&netbootFiles, "netbootFiles", "Extra files served by TFTP server")
    85  	flag.Var(&subnetIDs, "subnetIDs", "Subnet IDs for VM")
    86  	flag.Var(&volumeSizes, "volumeSizes", "Sizes for volumes for VM")
    87  }
    88  
    89  func printUsage() {
    90  	w := flag.CommandLine.Output()
    91  	fmt.Fprintln(w, "Usage: hyper-control [flags...] command [args...]")
    92  	fmt.Fprintln(w, "Common flags:")
    93  	flag.PrintDefaults()
    94  	fmt.Fprintln(w, "Commands:")
    95  	commands.PrintCommands(w, subcommands)
    96  }
    97  
    98  var subcommands = []commands.Command{
    99  	{"add-address", "MACaddr [IPaddr]", 1, 2, addAddressSubcommand},
   100  	{"add-subnet", "ID IPgateway IPmask DNSserver...", 4, -1,
   101  		addSubnetSubcommand},
   102  	{"change-tags", "", 0, 0, changeTagsSubcommand},
   103  	{"get-machine-info", "hostname", 1, 1, getMachineInfoSubcommand},
   104  	{"get-updates", "", 0, 0, getUpdatesSubcommand},
   105  	{"installer-shell", "hostname", 1, 1, installerShellSubcommand},
   106  	{"make-installer-iso", "hostname dirname", 2, 2,
   107  		makeInstallerIsoSubcommand},
   108  	{"move-ip-address", "IPaddr", 1, 1, moveIpAddressSubcommand},
   109  	{"netboot-host", "hostname", 1, 1, netbootHostSubcommand},
   110  	{"netboot-machine", "MACaddr IPaddr [hostname]", 2, 3,
   111  		netbootMachineSubcommand},
   112  	{"netboot-vm", "", 0, 0, netbootVmSubcommand},
   113  	{"power-off", "", 0, 0, powerOffSubcommand},
   114  	{"power-on", "", 0, 0, powerOnSubcommand},
   115  	{"register-external-leases", "", 0, 0, registerExternalLeasesSubcommand},
   116  	{"reinstall", "", 0, 0, reinstallSubcommand},
   117  	{"remove-excess-addresses", "MaxFreeAddr", 1, 1,
   118  		removeExcessAddressesSubcommand},
   119  	{"remove-ip-address", "IPaddr", 1, 1, removeIpAddressSubcommand},
   120  	{"remove-mac-address", "MACaddr", 1, 1, removeMacAddressSubcommand},
   121  	{"rollout-image", "name", 1, 1, rolloutImageSubcommand},
   122  	{"show-network-configuration", "", 0, 0,
   123  		showNetworkConfigurationSubcommand},
   124  	{"update-network-configuration", "", 0, 0,
   125  		updateNetworkConfigurationSubcommand},
   126  	{"write-netboot-files", "hostname dirname", 2, 2,
   127  		writeNetbootFilesSubcommand},
   128  }
   129  
   130  func loadCerts() error {
   131  	err := setupclient.SetupTls(false)
   132  	if err == nil {
   133  		return nil
   134  	}
   135  	if !os.IsNotExist(err) {
   136  		return err
   137  	}
   138  	if os.Geteuid() != 0 {
   139  		return err
   140  	}
   141  	cert, e := tls.LoadX509KeyPair("/etc/ssl/hypervisor/cert.pem",
   142  		"/etc/ssl/hypervisor/key.pem")
   143  	if e != nil {
   144  		return err
   145  	}
   146  	srpc.RegisterClientTlsConfig(&tls.Config{
   147  		InsecureSkipVerify: true,
   148  		MinVersion:         tls.VersionTLS12,
   149  		Certificates:       []tls.Certificate{cert},
   150  	})
   151  	return nil
   152  }
   153  
   154  func doMain() int {
   155  	if err := loadflags.LoadForCli("hyper-control"); err != nil {
   156  		fmt.Fprintln(os.Stderr, err)
   157  		return 1
   158  	}
   159  	flag.Usage = printUsage
   160  	flag.Parse()
   161  	if flag.NArg() < 1 {
   162  		printUsage()
   163  		return 2
   164  	}
   165  	logger := cmdlogger.New()
   166  	if err := loadCerts(); err != nil {
   167  		fmt.Fprintln(os.Stderr, err)
   168  		return 1
   169  	}
   170  	var err error
   171  	rrDialer, err = rrdialer.New(&net.Dialer{Timeout: time.Second * 10}, "",
   172  		logger)
   173  	if err != nil {
   174  		fmt.Fprintln(os.Stderr, err)
   175  		return 1
   176  	}
   177  	defer rrDialer.WaitForBackgroundResults(time.Second)
   178  	return commands.RunCommands(subcommands, printUsage, logger)
   179  }
   180  
   181  func main() {
   182  	os.Exit(doMain())
   183  }