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