github.com/Cloud-Foundations/Dominator@v0.3.4/cmd/vm-control/main.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"net"
     7  	"os"
     8  	"time"
     9  
    10  	"github.com/Cloud-Foundations/Dominator/lib/constants"
    11  	"github.com/Cloud-Foundations/Dominator/lib/flags/commands"
    12  	"github.com/Cloud-Foundations/Dominator/lib/flags/loadflags"
    13  	"github.com/Cloud-Foundations/Dominator/lib/flagutil"
    14  	"github.com/Cloud-Foundations/Dominator/lib/log"
    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  	hyper_proto "github.com/Cloud-Foundations/Dominator/proto/hypervisor"
    21  )
    22  
    23  var (
    24  	adjacentVM = flag.String("adjacentVM", "",
    25  		"IP address of VM adjacent (same Hypervisor) to VM being created")
    26  	consoleType        hyper_proto.ConsoleType
    27  	destroyOnPowerdown = flag.Bool("destroyOnPowerdown", false,
    28  		"If true, destroy VM if it powers down internally")
    29  	destroyProtection = flag.Bool("destroyProtection", false,
    30  		"If true, do not destroy running VM")
    31  	disableVirtIO = flag.Bool("disableVirtIO", false,
    32  		"If true, disable virtio drivers, reducing I/O performance")
    33  	dhcpTimeout = flag.Duration("dhcpTimeout", time.Minute,
    34  		"Time to wait before timing out on DHCP request from VM")
    35  	doNotStart = flag.Bool("doNotStart", false,
    36  		"If true, do not start VM when creating")
    37  	enableNetboot = flag.Bool("enableNetboot", false,
    38  		"If true, enable boot from network for first boot")
    39  	extraKernelOptions = flag.String("extraKernelOptions", "",
    40  		"Extra options to pass to kernel")
    41  	fleetManagerHostname = flag.String("fleetManagerHostname", "",
    42  		"Hostname of Fleet Manager")
    43  	fleetManagerPortNum = flag.Uint("fleetManagerPortNum",
    44  		constants.FleetManagerPortNumber,
    45  		"Port number of Fleet Resource Manager")
    46  	forceIfNotStopped = flag.Bool("forceIfNotStopped", false,
    47  		"If true, snapshot or restore VM even if not stopped")
    48  	hypervisorHostname = flag.String("hypervisorHostname", "",
    49  		"Hostname of hypervisor")
    50  	hypervisorPortNum = flag.Uint("hypervisorPortNum",
    51  		constants.HypervisorPortNumber, "Port number of hypervisor")
    52  	hypervisorTagsToMatch tags.MatchTags
    53  	identityCertFile      = flag.String("identityCertFile", "",
    54  		"Filename of PEM-encoded cetificate availabe from metadata service ")
    55  	identityKeyFile = flag.String("identityKeyFile", "",
    56  		"Filename of PEM-encoded key available from metadata service ")
    57  	includeUnhealthy = flag.Bool("includeUnhealthy", false,
    58  		"If true, list connected but unhealthy hypervisors")
    59  	imageFile = flag.String("imageFile", "",
    60  		"Name of RAW image file to boot with")
    61  	imageName    = flag.String("imageName", "", "Name of image to boot with")
    62  	imageTimeout = flag.Duration("imageTimeout", time.Minute,
    63  		"Time to wait before timing out on image fetch")
    64  	imageURL = flag.String("imageURL", "",
    65  		"Name of URL of image to boot with")
    66  	initialiseSecondaryVolumes = flag.Bool("initialiseSecondaryVolumes", false,
    67  		"If true, initialise secondary volumes")
    68  	localVmCreate = flag.String("localVmCreate", "",
    69  		"Command to make local VM when exporting. The VM name is given as the argument. The VM JSON is available on stdin")
    70  	localVmDestroy = flag.String("localVmDestroy", "",
    71  		"Command to destroy local VM when exporting. The VM name is given as the argument")
    72  	location = flag.String("location", "",
    73  		"Location to search for hypervisors")
    74  	memory           flagutil.Size
    75  	milliCPUs        = flag.Uint("milliCPUs", 0, "milli CPUs (default 250)")
    76  	placement        placementType
    77  	placementCommand = flag.String("placementCommand", "",
    78  		"Command to make placement decisions when creating/copying/moving VM")
    79  	minFreeBytes     = flagutil.Size(256 << 20)
    80  	overlayDirectory = flag.String("overlayDirectory", "",
    81  		"Directory tree of files to overlay on top of the image")
    82  	overlayPrefix = flag.String("overlayPrefix", "/",
    83  		"Prefix to add to overlay filenames")
    84  	ownerGroups      flagutil.StringList
    85  	ownerUsers       flagutil.StringList
    86  	patchLogFilename = flag.String("patchLogFilename", "",
    87  		"Name file to write VM patch log to")
    88  	probePortNum = flag.Uint("probePortNum", 0, "Port number on VM to probe")
    89  	probeTimeout = flag.Duration("probeTimeout", time.Minute*5,
    90  		"Time to wait before timing out on probing VM port")
    91  	secondarySubnetIDs         flagutil.StringList
    92  	secondaryVolumeSizes       flagutil.SizeList
    93  	secondaryVolumesInitParams = flag.String("secondaryVolumesInitParams", "",
    94  		"File containing initialisation parameters for secondary volumes")
    95  	serialPort = flag.Uint("serialPort", 0,
    96  		"Serial port number on VM")
    97  	skipBackup = flag.Bool("skipBackup", false,
    98  		"If true, do not make a backup when patching/replacing the VM image")
    99  	skipBootloader = flag.Bool("skipBootloader", false,
   100  		"If true, directly boot into the kernel")
   101  	skipMemoryCheck = flag.Bool("skipMemoryCheck", false,
   102  		"If true, skip memory availability check before creating VM")
   103  	subnetId = flag.String("subnetId", "",
   104  		"Subnet ID to launch VM in")
   105  	requestIPs   flagutil.StringList
   106  	roundupPower = flag.Uint64("roundupPower", 28,
   107  		"power of 2 to round up root volume size")
   108  	scanFilename = flag.String("scanFilename", "",
   109  		"Name of file to write scanned VM root to")
   110  	snapshotRootOnly = flag.Bool("snapshotRootOnly", false,
   111  		"If true, snapshot only the root volume")
   112  	traceMetadata = flag.Bool("traceMetadata", false,
   113  		"If true, trace metadata calls until interrupted")
   114  	userDataFile = flag.String("userDataFile", "",
   115  		"Name file containing user-data accessible from the metadata server")
   116  	virtualCPUs = flag.Uint("vCPUs", 0,
   117  		"virtual CPUs (default rounds up milliCPUs)")
   118  	vmHostname    = flag.String("vmHostname", "", "Hostname for VM")
   119  	vmTags        tags.Tags
   120  	vmTagsToMatch tags.MatchTags
   121  	vncViewer     = flag.String("vncViewer", defaultVncViewer,
   122  		"Path to VNC viewer")
   123  	volumeFilename = flag.String("volumeFilename", "",
   124  		"Name of file to write volume data to")
   125  	volumeIndex = flag.Uint("volumeIndex", 0,
   126  		"Index of volume to get or delete")
   127  	volumeIndices flagutil.UintList
   128  	volumeSize    flagutil.Size
   129  	volumeTypes   volumeTypeList
   130  
   131  	logger   log.DebugLogger
   132  	rrDialer *rrdialer.Dialer
   133  )
   134  
   135  func init() {
   136  	flag.Var(&consoleType, "consoleType",
   137  		"type of graphical console (default none)")
   138  	flag.Var(&hypervisorTagsToMatch, "hypervisorTagsToMatch",
   139  		"Tags to match when getting/listing or creating/copying/moving VMs")
   140  	flag.Var(&memory, "memory", "memory (default 1GiB)")
   141  	flag.Var(&minFreeBytes, "minFreeBytes",
   142  		"minimum number of free bytes in root volume")
   143  	flag.Var(&placement, "placement",
   144  		"Placement choice when selecting Hypervisor to create/copy/move VM")
   145  	flag.Var(&ownerGroups, "ownerGroups", "Groups who own the VM")
   146  	flag.Var(&ownerUsers, "ownerUsers", "Extra users who own the VM")
   147  	flag.Var(&requestIPs, "requestIPs", "Request specific IPs, if available")
   148  	flag.Var(&secondarySubnetIDs, "secondarySubnetIDs", "Secondary Subnet IDs")
   149  	flag.Var(&secondaryVolumeSizes, "secondaryVolumeSizes",
   150  		"Sizes for secondary volumes")
   151  	flag.Var(&vmTags, "vmTags", "Tags to apply to VM")
   152  	flag.Var(&vmTagsToMatch, "vmTagsToMatch", "Tags to match when listing")
   153  	flag.Var(&volumeIndices, "volumeIndices", "Index of volumes")
   154  	flag.Var(&volumeSize, "volumeSize", "New size of specified volume")
   155  	flag.Var(&volumeTypes, "volumeTypes",
   156  		"Types for volumes (default persistent)")
   157  }
   158  
   159  func printUsage() {
   160  	w := flag.CommandLine.Output()
   161  	fmt.Fprintln(w, "Usage: vm-control [flags...] command [args...]")
   162  	fmt.Fprintln(w, "Common flags:")
   163  	flag.PrintDefaults()
   164  	fmt.Fprintln(w, "Commands:")
   165  	commands.PrintCommands(w, subcommands)
   166  }
   167  
   168  var subcommands = []commands.Command{
   169  	{"add-vm-volumes", "IPaddr", 1, 1, addVmVolumesSubcommand},
   170  	{"become-primary-vm-owner", "IPaddr", 1, 1, becomePrimaryVmOwnerSubcommand},
   171  	{"change-vm-console-type", "IPaddr", 1, 1, changeVmConsoleTypeSubcommand},
   172  	{"change-vm-cpus", "IPaddr", 1, 1, changeVmCPUsSubcommand},
   173  	{"change-vm-destroy-protection", "IPaddr", 1, 1,
   174  		changeVmDestroyProtectionSubcommand},
   175  	{"change-vm-memory", "IPaddr", 1, 1, changeVmMemorySubcommand},
   176  	{"change-vm-owner-users", "IPaddr", 1, 1, changeVmOwnerUsersSubcommand},
   177  	{"change-vm-tags", "IPaddr", 1, 1, changeVmTagsSubcommand},
   178  	{"change-vm-vcpus", "IPaddr", 1, 1, changeVmVirtualCPUsSubcommand},
   179  	{"change-vm-volume-size", "IPaddr", 1, 1, changeVmVolumeSizeSubcommand},
   180  	{"connect-to-vm-console", "IPaddr", 1, 1, connectToVmConsoleSubcommand},
   181  	{"connect-to-vm-serial-port", "IPaddr", 1, 1,
   182  		connectToVmSerialPortSubcommand},
   183  	{"copy-vm", "IPaddr", 1, 1, copyVmSubcommand},
   184  	{"create-vm", "", 0, 0, createVmSubcommand},
   185  	{"debug-vm-image", "IPaddr", 1, 1, debugVmImageSubcommand},
   186  	{"delete-vm-volume", "IPaddr", 1, 1, deleteVmVolumeSubcommand},
   187  	{"destroy-vm", "IPaddr", 1, 1, destroyVmSubcommand},
   188  	{"discard-vm-old-image", "IPaddr", 1, 1, discardVmOldImageSubcommand},
   189  	{"discard-vm-old-user-data", "IPaddr", 1, 1,
   190  		discardVmOldUserDataSubcommand},
   191  	{"discard-vm-snapshot", "IPaddr", 1, 1, discardVmSnapshotSubcommand},
   192  	{"export-local-vm", "IPaddr", 1, 1, exportLocalVmSubcommand},
   193  	{"export-virsh-vm", "IPaddr", 1, 1, exportVirshVmSubcommand},
   194  	{"get-hypervisors", "", 0, 0, getHypervisorsSubcommand},
   195  	{"get-vm-info", "IPaddr", 1, 1, getVmInfoSubcommand},
   196  	{"get-vm-user-data", "IPaddr", 1, 1, getVmUserDataSubcommand},
   197  	{"get-vm-volume", "IPaddr", 1, 1, getVmVolumeSubcommand},
   198  	{"import-local-vm", "info-file root-volume", 2, 2, importLocalVmSubcommand},
   199  	{"import-virsh-vm", "MACaddr domain [[MAC IP]...]", 2, -1,
   200  		importVirshVmSubcommand},
   201  	{"list-hypervisors", "", 0, 0, listHypervisorsSubcommand},
   202  	{"list-locations", "[TopLocation]", 0, 1, listLocationsSubcommand},
   203  	{"list-vms", "", 0, 0, listVMsSubcommand},
   204  	{"migrate-vm", "IPaddr", 1, 1, migrateVmSubcommand},
   205  	{"patch-vm-image", "IPaddr", 1, 1, patchVmImageSubcommand},
   206  	{"probe-vm-port", "IPaddr", 1, 1, probeVmPortSubcommand},
   207  	{"reboot-vm", "IPaddr", 1, 1, rebootVmSubcommand},
   208  	{"replace-vm-credentials", "IPaddr", 1, 1, replaceVmCredentialsSubcommand},
   209  	{"replace-vm-image", "IPaddr", 1, 1, replaceVmImageSubcommand},
   210  	{"replace-vm-user-data", "IPaddr", 1, 1, replaceVmUserDataSubcommand},
   211  	{"restore-vm", "source", 1, 1, restoreVmSubcommand},
   212  	{"restore-vm-from-snapshot", "IPaddr", 1, 1,
   213  		restoreVmFromSnapshotSubcommand},
   214  	{"restore-vm-image", "IPaddr", 1, 1, restoreVmImageSubcommand},
   215  	{"restore-vm-user-data", "IPaddr", 1, 1, restoreVmUserDataSubcommand},
   216  	{"reorder-vm-volumes", "IPaddr", 1, 1, reorderVmVolumesSubcommand},
   217  	{"set-vm-migrating", "IPaddr", 1, 1, setVmMigratingSubcommand},
   218  	{"snapshot-vm", "IPaddr", 1, 1, snapshotVmSubcommand},
   219  	{"save-vm", "IPaddr destination", 2, 2, saveVmSubcommand},
   220  	{"scan-vm-root", "IPaddr", 1, 1, scanVmRootSubcommand},
   221  	{"start-vm", "IPaddr", 1, 1, startVmSubcommand},
   222  	{"stop-vm", "IPaddr", 1, 1, stopVmSubcommand},
   223  	{"trace-vm-metadata", "IPaddr", 1, 1, traceVmMetadataSubcommand},
   224  	{"unset-vm-migrating", "IPaddr", 1, 1, unsetVmMigratingSubcommand},
   225  }
   226  
   227  func doMain() int {
   228  	if err := loadflags.LoadForCli("vm-control"); err != nil {
   229  		fmt.Fprintln(os.Stderr, err)
   230  		return 1
   231  	}
   232  	flag.Usage = printUsage
   233  	flag.Parse()
   234  	if flag.NArg() < 1 {
   235  		printUsage()
   236  		return 2
   237  	}
   238  	if memory > 0 && memory < 1<<20 {
   239  		fmt.Fprintf(os.Stderr, "unreasonably small memory: %s\n",
   240  			memory.String())
   241  		return 3
   242  	}
   243  	logger = cmdlogger.New()
   244  	srpc.SetDefaultLogger(logger)
   245  	if err := setupclient.SetupTls(false); err != nil {
   246  		fmt.Fprintln(os.Stderr, err)
   247  		return 1
   248  	}
   249  	var err error
   250  	rrDialer, err = rrdialer.New(&net.Dialer{Timeout: time.Second * 10}, "",
   251  		logger)
   252  	if err != nil {
   253  		fmt.Fprintln(os.Stderr, err)
   254  		return 1
   255  	}
   256  	defer rrDialer.WaitForBackgroundResults(time.Second)
   257  	return commands.RunCommands(subcommands, printUsage, logger)
   258  }
   259  
   260  func main() {
   261  	os.Exit(doMain())
   262  }