github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/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/setupclient" 18 "github.com/Cloud-Foundations/Dominator/lib/tags" 19 hyper_proto "github.com/Cloud-Foundations/Dominator/proto/hypervisor" 20 ) 21 22 var ( 23 adjacentVM = flag.String("adjacentVM", "", 24 "IP address of VM adjacent (same Hypervisor) to VM being created") 25 consoleType hyper_proto.ConsoleType 26 destroyProtection = flag.Bool("destroyProtection", false, 27 "If true, do not destroy running VM") 28 disableVirtIO = flag.Bool("disableVirtIO", false, 29 "If true, disable virtio drivers, reducing I/O performance") 30 dhcpTimeout = flag.Duration("dhcpTimeout", time.Minute, 31 "Time to wait before timing out on DHCP request from VM") 32 enableNetboot = flag.Bool("enableNetboot", false, 33 "If true, enable boot from network for first boot") 34 fleetManagerHostname = flag.String("fleetManagerHostname", "", 35 "Hostname of Fleet Manager") 36 fleetManagerPortNum = flag.Uint("fleetManagerPortNum", 37 constants.FleetManagerPortNumber, 38 "Port number of Fleet Resource Manager") 39 forceIfNotStopped = flag.Bool("forceIfNotStopped", false, 40 "If true, snapshot or restore VM even if not stopped") 41 hypervisorHostname = flag.String("hypervisorHostname", "", 42 "Hostname of hypervisor") 43 hypervisorPortNum = flag.Uint("hypervisorPortNum", 44 constants.HypervisorPortNumber, "Port number of hypervisor") 45 includeUnhealthy = flag.Bool("includeUnhealthy", false, 46 "If true, list connected but unhealthy hypervisors") 47 imageFile = flag.String("imageFile", "", 48 "Name of RAW image file to boot with") 49 imageName = flag.String("imageName", "", "Name of image to boot with") 50 imageTimeout = flag.Duration("imageTimeout", time.Minute, 51 "Time to wait before timing out on image fetch") 52 imageURL = flag.String("imageURL", "", 53 "Name of URL of image to boot with") 54 localVmCreate = flag.String("localVmCreate", "", 55 "Command to make local VM when exporting. The VM name is given as the argument. The VM JSON is available on stdin") 56 localVmDestroy = flag.String("localVmDestroy", "", 57 "Command to destroy local VM when exporting. The VM name is given as the argument") 58 location = flag.String("location", "", 59 "Location to search for hypervisors") 60 memory flagutil.Size 61 milliCPUs = flag.Uint("milliCPUs", 0, "milli CPUs (default 250)") 62 minFreeBytes = flagutil.Size(256 << 20) 63 ownerGroups flagutil.StringList 64 ownerUsers flagutil.StringList 65 probePortNum = flag.Uint("probePortNum", 0, "Port number on VM to probe") 66 probeTimeout = flag.Duration("probeTimeout", time.Minute*5, 67 "Time to wait before timing out on probing VM port") 68 secondarySubnetIDs flagutil.StringList 69 secondaryVolumeSizes flagutil.SizeList 70 serialPort = flag.Uint("serialPort", 0, 71 "Serial port number on VM") 72 skipBootloader = flag.Bool("skipBootloader", false, 73 "If true, directly boot into the kernel") 74 subnetId = flag.String("subnetId", "", 75 "Subnet ID to launch VM in") 76 requestIPs flagutil.StringList 77 roundupPower = flag.Uint64("roundupPower", 28, 78 "power of 2 to round up root volume size") 79 scanFilename = flag.String("scanFilename", "", 80 "Name of file to write scanned VM root to") 81 snapshotRootOnly = flag.Bool("snapshotRootOnly", false, 82 "If true, snapshot only the root volume") 83 traceMetadata = flag.Bool("traceMetadata", false, 84 "If true, trace metadata calls until interrupted") 85 userDataFile = flag.String("userDataFile", "", 86 "Name file containing user-data accessible from the metadata server") 87 vmHostname = flag.String("vmHostname", "", "Hostname for VM") 88 vmTags tags.Tags 89 vncViewer = flag.String("vncViewer", defaultVncViewer, 90 "Path to VNC viewer") 91 volumeFilename = flag.String("volumeFilename", "", 92 "Name of file to write volume data to") 93 volumeIndex = flag.Uint("volumeIndex", 0, 94 "Index of volume to get or delete") 95 96 logger log.DebugLogger 97 rrDialer *rrdialer.Dialer 98 ) 99 100 func init() { 101 flag.Var(&consoleType, "consoleType", 102 "type of graphical console (default none)") 103 flag.Var(&memory, "memory", "memory (default 1GiB)") 104 flag.Var(&minFreeBytes, "minFreeBytes", 105 "minimum number of free bytes in root volume") 106 flag.Var(&ownerGroups, "ownerGroups", "Groups who own the VM") 107 flag.Var(&ownerUsers, "ownerUsers", "Extra users who own the VM") 108 flag.Var(&requestIPs, "requestIPs", "Request specific IPs, if available") 109 flag.Var(&secondarySubnetIDs, "secondarySubnetIDs", "Secondary Subnet IDs") 110 flag.Var(&secondaryVolumeSizes, "secondaryVolumeSizes", 111 "Sizes for secondary volumes") 112 flag.Var(&vmTags, "vmTags", "Tags to apply to VM") 113 } 114 115 func printUsage() { 116 w := flag.CommandLine.Output() 117 fmt.Fprintln(w, "Usage: vm-control [flags...] command [args...]") 118 fmt.Fprintln(w, "Common flags:") 119 flag.PrintDefaults() 120 fmt.Fprintln(w, "Commands:") 121 commands.PrintCommands(w, subcommands) 122 } 123 124 var subcommands = []commands.Command{ 125 {"add-vm-volumes", "IPaddr", 1, 1, addVmVolumesSubcommand}, 126 {"become-primary-vm-owner", "IPaddr", 1, 1, becomePrimaryVmOwnerSubcommand}, 127 {"change-vm-console-type", "IPaddr", 1, 1, changeVmConsoleTypeSubcommand}, 128 {"change-vm-cpus", "IPaddr", 1, 1, changeVmCPUsSubcommand}, 129 {"change-vm-destroy-protection", "IPaddr", 1, 1, 130 changeVmDestroyProtectionSubcommand}, 131 {"change-vm-memory", "IPaddr", 1, 1, changeVmMemorySubcommand}, 132 {"change-vm-owner-users", "IPaddr", 1, 1, changeVmOwnerUsersSubcommand}, 133 {"change-vm-tags", "IPaddr", 1, 1, changeVmTagsSubcommand}, 134 {"connect-to-vm-console", "IPaddr", 1, 1, connectToVmConsoleSubcommand}, 135 {"connect-to-vm-serial-port", "IPaddr", 1, 1, 136 connectToVmSerialPortSubcommand}, 137 {"copy-vm", "IPaddr", 1, 1, copyVmSubcommand}, 138 {"create-vm", "", 0, 0, createVmSubcommand}, 139 {"delete-vm-volume", "IPaddr", 1, 1, deleteVmVolumeSubcommand}, 140 {"destroy-vm", "IPaddr", 1, 1, destroyVmSubcommand}, 141 {"discard-vm-old-image", "IPaddr", 1, 1, discardVmOldImageSubcommand}, 142 {"discard-vm-old-user-data", "IPaddr", 1, 1, 143 discardVmOldUserDataSubcommand}, 144 {"discard-vm-snapshot", "IPaddr", 1, 1, discardVmSnapshotSubcommand}, 145 {"export-local-vm", "IPaddr", 1, 1, exportLocalVmSubcommand}, 146 {"export-virsh-vm", "IPaddr", 1, 1, exportVirshVmSubcommand}, 147 {"get-vm-info", "IPaddr", 1, 1, getVmInfoSubcommand}, 148 {"get-vm-user-data", "IPaddr", 1, 1, getVmUserDataSubcommand}, 149 {"get-vm-volume", "IPaddr", 1, 1, getVmVolumeSubcommand}, 150 {"import-local-vm", "info-file root-volume", 2, 2, importLocalVmSubcommand}, 151 {"import-virsh-vm", "MACaddr domain [[MAC IP]...]", 2, -1, 152 importVirshVmSubcommand}, 153 {"list-hypervisors", "", 0, 0, listHypervisorsSubcommand}, 154 {"list-locations", "[TopLocation]", 0, 1, listLocationsSubcommand}, 155 {"list-vms", "", 0, 0, listVMsSubcommand}, 156 {"migrate-vm", "IPaddr", 1, 1, migrateVmSubcommand}, 157 {"patch-vm-image", "IPaddr", 1, 1, patchVmImageSubcommand}, 158 {"probe-vm-port", "IPaddr", 1, 1, probeVmPortSubcommand}, 159 {"replace-vm-image", "IPaddr", 1, 1, replaceVmImageSubcommand}, 160 {"replace-vm-user-data", "IPaddr", 1, 1, replaceVmUserDataSubcommand}, 161 {"restore-vm", "source", 1, 1, restoreVmSubcommand}, 162 {"restore-vm-from-snapshot", "IPaddr", 1, 1, 163 restoreVmFromSnapshotSubcommand}, 164 {"restore-vm-image", "IPaddr", 1, 1, restoreVmImageSubcommand}, 165 {"restore-vm-user-data", "IPaddr", 1, 1, restoreVmUserDataSubcommand}, 166 {"set-vm-migrating", "IPaddr", 1, 1, setVmMigratingSubcommand}, 167 {"snapshot-vm", "IPaddr", 1, 1, snapshotVmSubcommand}, 168 {"save-vm", "IPaddr destination", 2, 2, saveVmSubcommand}, 169 {"scan-vm-root", "IPaddr", 1, 1, scanVmRootSubcommand}, 170 {"start-vm", "IPaddr", 1, 1, startVmSubcommand}, 171 {"stop-vm", "IPaddr", 1, 1, stopVmSubcommand}, 172 {"trace-vm-metadata", "IPaddr", 1, 1, traceVmMetadataSubcommand}, 173 {"unset-vm-migrating", "IPaddr", 1, 1, unsetVmMigratingSubcommand}, 174 } 175 176 func doMain() int { 177 if err := loadflags.LoadForCli("vm-control"); err != nil { 178 fmt.Fprintln(os.Stderr, err) 179 return 1 180 } 181 flag.Usage = printUsage 182 flag.Parse() 183 if flag.NArg() < 1 { 184 printUsage() 185 return 2 186 } 187 if memory > 0 && memory < 1<<20 { 188 fmt.Fprintf(os.Stderr, "unreasonably small memory: %s\n", 189 memory.String()) 190 return 3 191 } 192 logger = cmdlogger.New() 193 if err := setupclient.SetupTls(false); err != nil { 194 fmt.Fprintln(os.Stderr, err) 195 return 1 196 } 197 var err error 198 rrDialer, err = rrdialer.New(&net.Dialer{Timeout: time.Second * 10}, "", 199 logger) 200 if err != nil { 201 fmt.Fprintln(os.Stderr, err) 202 return 1 203 } 204 defer rrDialer.WaitForBackgroundResults(time.Second) 205 return commands.RunCommands(subcommands, printUsage, logger) 206 } 207 208 func main() { 209 os.Exit(doMain()) 210 }