github.com/Cloud-Foundations/Dominator@v0.3.4/hypervisor/manager/api.go (about) 1 package manager 2 3 import ( 4 "io" 5 "net" 6 "path/filepath" 7 "sync" 8 "time" 9 10 "github.com/Cloud-Foundations/Dominator/lib/filesystem" 11 "github.com/Cloud-Foundations/Dominator/lib/filter" 12 "github.com/Cloud-Foundations/Dominator/lib/lockwatcher" 13 "github.com/Cloud-Foundations/Dominator/lib/log" 14 "github.com/Cloud-Foundations/Dominator/lib/objectserver/cachingreader" 15 "github.com/Cloud-Foundations/Dominator/lib/srpc" 16 "github.com/Cloud-Foundations/Dominator/lib/tags" 17 proto "github.com/Cloud-Foundations/Dominator/proto/hypervisor" 18 ) 19 20 const ( 21 IdentityCertFile = "identity.cert" 22 IdentityKeyFile = "identity.key" 23 UserDataFile = "user-data.raw" 24 ) 25 26 type addressPoolType struct { 27 Free []proto.Address 28 Registered []proto.Address 29 } 30 31 type DhcpServer interface { 32 AddLease(address proto.Address, hostname string) error 33 AddSubnet(subnet proto.Subnet) 34 MakeAcknowledgmentChannel(ipAddr net.IP) <-chan struct{} 35 MakeRequestChannel(macAddr string) <-chan net.IP 36 RemoveLease(ipAddr net.IP) 37 RemoveSubnet(subnetId string) 38 } 39 40 type Manager struct { 41 StartOptions 42 healthStatusMutex sync.RWMutex 43 healthStatus string 44 lockWatcher *lockwatcher.LockWatcher 45 memTotalInMiB uint64 46 notifiersMutex sync.Mutex 47 notifiers map[<-chan proto.Update]chan<- proto.Update 48 numCPUs uint 49 rootCookie []byte 50 serialNumber string 51 shuttingDown bool 52 summaryMutex sync.RWMutex 53 summary *summaryData 54 volumeDirectories []string 55 volumeInfos map[string]VolumeInfo // Key: volumeDirectory. 56 mutex sync.RWMutex // Lock everything below (those can change). 57 addressPool addressPoolType 58 disabled bool 59 objectCache *cachingreader.ObjectServer 60 ownerGroups map[string]struct{} 61 ownerUsers map[string]struct{} 62 subnets map[string]proto.Subnet // Key: Subnet ID. 63 subnetChannels []chan<- proto.Subnet 64 totalVolumeBytes uint64 65 vms map[string]*vmInfoType // Key: IP address. 66 vsocketsEnabled bool 67 uuid string 68 } 69 70 type StartOptions struct { 71 BridgeMap map[string]net.Interface // Key: interface name. 72 DhcpServer DhcpServer 73 ImageServerAddress string 74 LockCheckInterval time.Duration 75 LockLogTimeout time.Duration 76 Logger log.DebugLogger 77 ObjectCacheBytes uint64 78 ShowVgaConsole bool 79 StateDir string 80 Username string 81 VlanIdToBridge map[uint]string // Key: VLAN ID, value: bridge interface. 82 VolumeDirectories []string 83 } 84 85 type summaryData struct { 86 availableMilliCPU uint 87 memUnallocated uint64 88 numFreeAddresses uint 89 numRegisteredAddresses uint 90 numRunning uint 91 numStopped uint 92 numSubnets uint 93 ownerGroups []string 94 ownerUsers []string 95 updatedAt time.Time 96 } 97 98 type vmInfoType struct { 99 lockWatcher *lockwatcher.LockWatcher 100 mutex sync.RWMutex 101 accessToken []byte 102 accessTokenCleanupNotifier chan<- struct{} 103 commandInput chan<- string 104 commandOutput chan byte 105 destroyTimer *time.Timer 106 dirname string 107 doNotWriteOrSend bool 108 hasHealthAgent bool 109 ipAddress string 110 logger log.DebugLogger 111 manager *Manager 112 metadataChannels map[chan<- string]struct{} 113 monitorSockname string 114 blockMutations bool 115 ownerUsers map[string]struct{} 116 serialInput io.Writer 117 serialOutput chan<- byte 118 stoppedNotifier chan<- struct{} 119 proto.LocalVmInfo 120 } 121 122 type VolumeInfo struct { 123 CanTrim bool 124 MountPoint string 125 } 126 127 func New(startOptions StartOptions) (*Manager, error) { 128 return newManager(startOptions) 129 } 130 131 func (m *Manager) AcknowledgeVm(ipAddr net.IP, 132 authInfo *srpc.AuthInformation) error { 133 return m.acknowledgeVm(ipAddr, authInfo) 134 } 135 136 func (m *Manager) AddAddressesToPool(addresses []proto.Address) error { 137 return m.addAddressesToPool(addresses) 138 } 139 140 func (m *Manager) AddVmVolumes(ipAddr net.IP, 141 authInfo *srpc.AuthInformation, volumeSizes []uint64) error { 142 return m.addVmVolumes(ipAddr, authInfo, volumeSizes) 143 } 144 145 func (m *Manager) BecomePrimaryVmOwner(ipAddr net.IP, 146 authInfo *srpc.AuthInformation) error { 147 return m.becomePrimaryVmOwner(ipAddr, authInfo) 148 } 149 150 func (m *Manager) ChangeOwners(ownerGroups, ownerUsers []string) error { 151 return m.changeOwners(ownerGroups, ownerUsers) 152 } 153 154 func (m *Manager) ChangeVmConsoleType(ipAddr net.IP, 155 authInfo *srpc.AuthInformation, consoleType proto.ConsoleType) error { 156 return m.changeVmConsoleType(ipAddr, authInfo, consoleType) 157 } 158 159 func (m *Manager) ChangeVmDestroyProtection(ipAddr net.IP, 160 authInfo *srpc.AuthInformation, destroyProtection bool) error { 161 return m.changeVmDestroyProtection(ipAddr, authInfo, destroyProtection) 162 } 163 164 func (m *Manager) ChangeVmOwnerUsers(ipAddr net.IP, 165 authInfo *srpc.AuthInformation, extraUsers []string) error { 166 return m.changeVmOwnerUsers(ipAddr, authInfo, extraUsers) 167 } 168 169 func (m *Manager) ChangeVmSize(authInfo *srpc.AuthInformation, 170 req proto.ChangeVmSizeRequest) error { 171 return m.changeVmSize(authInfo, req) 172 } 173 174 func (m *Manager) ChangeVmTags(ipAddr net.IP, authInfo *srpc.AuthInformation, 175 tgs tags.Tags) error { 176 return m.changeVmTags(ipAddr, authInfo, tgs) 177 } 178 179 func (m *Manager) ChangeVmVolumeSize(ipAddr net.IP, 180 authInfo *srpc.AuthInformation, index uint, size uint64) error { 181 return m.changeVmVolumeSize(ipAddr, authInfo, index, size) 182 } 183 184 func (m *Manager) CheckOwnership(authInfo *srpc.AuthInformation) bool { 185 return m.checkOwnership(authInfo) 186 } 187 188 func (m *Manager) CheckVmHasHealthAgent(ipAddr net.IP) (bool, error) { 189 return m.checkVmHasHealthAgent(ipAddr) 190 } 191 192 func (m *Manager) CheckVsocketsEnabled() bool { 193 return m.vsocketsEnabled 194 } 195 196 func (m *Manager) CloseUpdateChannel(channel <-chan proto.Update) { 197 m.closeUpdateChannel(channel) 198 } 199 200 func (m *Manager) CommitImportedVm(ipAddr net.IP, 201 authInfo *srpc.AuthInformation) error { 202 return m.commitImportedVm(ipAddr, authInfo) 203 } 204 205 func (m *Manager) ConnectToVmConsole(ipAddr net.IP, 206 authInfo *srpc.AuthInformation) (net.Conn, error) { 207 return m.connectToVmConsole(ipAddr, authInfo) 208 } 209 210 func (m *Manager) ConnectToVmManager(ipAddr net.IP) ( 211 chan<- byte, <-chan byte, error) { 212 return m.connectToVmManager(ipAddr) 213 } 214 215 func (m *Manager) ConnectToVmSerialPort(ipAddr net.IP, 216 authInfo *srpc.AuthInformation, 217 portNumber uint) (chan<- byte, <-chan byte, error) { 218 return m.connectToVmSerialPort(ipAddr, authInfo, portNumber) 219 } 220 221 func (m *Manager) CopyVm(conn *srpc.Conn, request proto.CopyVmRequest) error { 222 return m.copyVm(conn, request) 223 } 224 225 func (m *Manager) CreateVm(conn *srpc.Conn) error { 226 return m.createVm(conn) 227 } 228 229 func (m *Manager) DebugVmImage(conn *srpc.Conn, 230 authInfo *srpc.AuthInformation) error { 231 return m.debugVmImage(conn, authInfo) 232 } 233 234 func (m *Manager) DeleteVmVolume(ipAddr net.IP, authInfo *srpc.AuthInformation, 235 accessToken []byte, volumeIndex uint) error { 236 return m.deleteVmVolume(ipAddr, authInfo, accessToken, volumeIndex) 237 } 238 239 func (m *Manager) DestroyVm(ipAddr net.IP, 240 authInfo *srpc.AuthInformation, accessToken []byte) error { 241 return m.destroyVm(ipAddr, authInfo, accessToken) 242 } 243 244 func (m *Manager) DiscardVmAccessToken(ipAddr net.IP, 245 authInfo *srpc.AuthInformation, accessToken []byte) error { 246 return m.discardVmAccessToken(ipAddr, authInfo, accessToken) 247 } 248 249 func (m *Manager) DiscardVmOldImage(ipAddr net.IP, 250 authInfo *srpc.AuthInformation) error { 251 return m.discardVmOldImage(ipAddr, authInfo) 252 } 253 254 func (m *Manager) DiscardVmOldUserData(ipAddr net.IP, 255 authInfo *srpc.AuthInformation) error { 256 return m.discardVmOldUserData(ipAddr, authInfo) 257 } 258 259 func (m *Manager) DiscardVmSnapshot(ipAddr net.IP, 260 authInfo *srpc.AuthInformation) error { 261 return m.discardVmSnapshot(ipAddr, authInfo) 262 } 263 264 func (m *Manager) ExportLocalVm(authInfo *srpc.AuthInformation, 265 request proto.ExportLocalVmRequest) (*proto.ExportLocalVmInfo, error) { 266 return m.exportLocalVm(authInfo, request) 267 } 268 269 func (m *Manager) GetCapacity() proto.GetCapacityResponse { 270 return proto.GetCapacityResponse{ 271 MemoryInMiB: m.memTotalInMiB, 272 NumCPUs: m.numCPUs, 273 TotalVolumeBytes: m.totalVolumeBytes, 274 } 275 } 276 277 func (m *Manager) GetHealthStatus() string { 278 return m.getHealthStatus() 279 } 280 281 func (m *Manager) GetImageServerAddress() string { 282 return m.ImageServerAddress 283 } 284 285 func (m *Manager) GetNumVMs() (uint, uint) { 286 return m.getNumVMs() 287 } 288 289 func (m *Manager) GetRootCookiePath() string { 290 return filepath.Join(m.StartOptions.StateDir, "root-cookie") 291 } 292 293 func (m *Manager) GetVolumeDirectories() map[string]VolumeInfo { 294 return m.volumeInfos 295 } 296 297 func (m *Manager) GetVmAccessToken(ipAddr net.IP, 298 authInfo *srpc.AuthInformation, lifetime time.Duration) ([]byte, error) { 299 return m.getVmAccessToken(ipAddr, authInfo, lifetime) 300 } 301 302 func (m *Manager) GetVmBootLog(ipAddr net.IP) (io.ReadCloser, error) { 303 return m.getVmBootLog(ipAddr) 304 } 305 306 func (m *Manager) GetVmCID(ipAddr net.IP) (uint32, error) { 307 return m.getVmCID(ipAddr) 308 } 309 310 func (m *Manager) GetVmFileData(ipAddr net.IP, filename string) ( 311 io.ReadCloser, error) { 312 rc, _, err := m.getVmFileReader(ipAddr, 313 &srpc.AuthInformation{HaveMethodAccess: true}, 314 nil, filename) 315 return rc, err 316 } 317 318 func (m *Manager) GetVmInfo(ipAddr net.IP) (proto.VmInfo, error) { 319 return m.getVmInfo(ipAddr) 320 } 321 322 func (m *Manager) GetVmLastPatchLog(ipAddr net.IP) ( 323 io.ReadCloser, uint64, time.Time, error) { 324 return m.getVmLastPatchLog(ipAddr) 325 } 326 327 func (m *Manager) GetVmLockWatcher(ipAddr net.IP) ( 328 *lockwatcher.LockWatcher, error) { 329 return m.getVmLockWatcher(ipAddr) 330 } 331 332 func (m *Manager) GetVmUserData(ipAddr net.IP) (io.ReadCloser, error) { 333 rc, _, err := m.getVmFileReader(ipAddr, 334 &srpc.AuthInformation{HaveMethodAccess: true}, 335 nil, UserDataFile) 336 return rc, err 337 } 338 339 func (m *Manager) GetVmUserDataRPC(ipAddr net.IP, 340 authInfo *srpc.AuthInformation, accessToken []byte) ( 341 io.ReadCloser, uint64, error) { 342 return m.getVmFileReader(ipAddr, authInfo, accessToken, UserDataFile) 343 } 344 345 func (m *Manager) GetVmVolume(conn *srpc.Conn) error { 346 return m.getVmVolume(conn) 347 } 348 349 func (m *Manager) GetUUID() (string, error) { 350 return m.uuid, nil 351 } 352 353 func (m *Manager) HoldLock(timeout time.Duration, writeLock bool) error { 354 return m.holdLock(timeout, writeLock) 355 } 356 357 func (m *Manager) HoldVmLock(ipAddr net.IP, timeout time.Duration, 358 writeLock bool, authInfo *srpc.AuthInformation) error { 359 return m.holdVmLock(ipAddr, timeout, writeLock, authInfo) 360 } 361 362 func (m *Manager) ImportLocalVm(authInfo *srpc.AuthInformation, 363 request proto.ImportLocalVmRequest) error { 364 return m.importLocalVm(authInfo, request) 365 } 366 367 func (m *Manager) ListAvailableAddresses() []proto.Address { 368 return m.listAvailableAddresses() 369 } 370 371 func (m *Manager) ListRegisteredAddresses() []proto.Address { 372 return m.listRegisteredAddresses() 373 } 374 375 func (m *Manager) ListSubnets(doSort bool) []proto.Subnet { 376 return m.listSubnets(doSort) 377 } 378 379 func (m *Manager) ListVMs(request proto.ListVMsRequest) []string { 380 return m.listVMs(request) 381 } 382 383 func (m *Manager) ListVolumeDirectories() []string { 384 return m.volumeDirectories 385 } 386 387 func (m *Manager) MakeSubnetChannel() <-chan proto.Subnet { 388 return m.makeSubnetChannel() 389 } 390 391 func (m *Manager) MakeUpdateChannel() <-chan proto.Update { 392 return m.makeUpdateChannel() 393 } 394 395 func (m *Manager) MigrateVm(conn *srpc.Conn) error { 396 return m.migrateVm(conn) 397 } 398 399 func (m *Manager) NotifyVmMetadataRequest(ipAddr net.IP, path string) { 400 m.notifyVmMetadataRequest(ipAddr, path) 401 } 402 403 func (m *Manager) PatchVmImage(conn *srpc.Conn, 404 request proto.PatchVmImageRequest) error { 405 return m.patchVmImage(conn, request) 406 } 407 408 func (m *Manager) PowerOff(stopVMs bool) error { 409 return m.powerOff(stopVMs) 410 } 411 412 func (m *Manager) PrepareVmForMigration(ipAddr net.IP, 413 authInfo *srpc.AuthInformation, accessToken []byte, enable bool) error { 414 return m.prepareVmForMigration(ipAddr, authInfo, accessToken, enable) 415 } 416 417 func (m *Manager) RebootVm(ipAddr net.IP, authInfo *srpc.AuthInformation, 418 dhcpTimeout time.Duration) (bool, error) { 419 return m.rebootVm(ipAddr, authInfo, dhcpTimeout) 420 } 421 422 func (m *Manager) RemoveAddressesFromPool(addresses []proto.Address) error { 423 return m.removeAddressesFromPool(addresses) 424 } 425 426 func (m *Manager) RemoveExcessAddressesFromPool(maxFree map[string]uint) error { 427 return m.removeExcessAddressesFromPool(maxFree) 428 } 429 430 func (m *Manager) RegisterVmMetadataNotifier(ipAddr net.IP, 431 authInfo *srpc.AuthInformation, pathChannel chan<- string) error { 432 return m.registerVmMetadataNotifier(ipAddr, authInfo, pathChannel) 433 } 434 435 func (m *Manager) ReplaceVmCredentials( 436 request proto.ReplaceVmCredentialsRequest, 437 authInfo *srpc.AuthInformation) error { 438 return m.replaceVmCredentials(request, authInfo) 439 } 440 441 func (m *Manager) ReplaceVmImage(conn *srpc.Conn, 442 authInfo *srpc.AuthInformation) error { 443 return m.replaceVmImage(conn, authInfo) 444 } 445 446 func (m *Manager) ReplaceVmUserData(ipAddr net.IP, reader io.Reader, 447 size uint64, authInfo *srpc.AuthInformation) error { 448 return m.replaceVmUserData(ipAddr, reader, size, authInfo) 449 } 450 451 func (m *Manager) RestoreVmFromSnapshot(ipAddr net.IP, 452 authInfo *srpc.AuthInformation, forceIfNotStopped bool) error { 453 return m.restoreVmFromSnapshot(ipAddr, authInfo, forceIfNotStopped) 454 } 455 456 func (m *Manager) RestoreVmImage(ipAddr net.IP, 457 authInfo *srpc.AuthInformation) error { 458 return m.restoreVmImage(ipAddr, authInfo) 459 } 460 461 func (m *Manager) RestoreVmUserData(ipAddr net.IP, 462 authInfo *srpc.AuthInformation) error { 463 return m.restoreVmUserData(ipAddr, authInfo) 464 } 465 466 func (m *Manager) ReorderVmVolumes(ipAddr net.IP, 467 authInfo *srpc.AuthInformation, accessToken []byte, 468 volumeIndices []uint) error { 469 return m.reorderVmVolumes(ipAddr, authInfo, accessToken, volumeIndices) 470 } 471 472 func (m *Manager) ScanVmRoot(ipAddr net.IP, authInfo *srpc.AuthInformation, 473 scanFilter *filter.Filter) (*filesystem.FileSystem, error) { 474 return m.scanVmRoot(ipAddr, authInfo, scanFilter) 475 } 476 477 func (m *Manager) SetDisabledState(disable bool) error { 478 return m.setDisabledState(disable) 479 } 480 481 func (m *Manager) ShutdownVMsAndExit() { 482 m.shutdownVMsAndExit() 483 } 484 485 func (m *Manager) SnapshotVm(ipAddr net.IP, authInfo *srpc.AuthInformation, 486 forceIfNotStopped, snapshotRootOnly bool) error { 487 return m.snapshotVm(ipAddr, authInfo, forceIfNotStopped, snapshotRootOnly) 488 } 489 490 func (m *Manager) StartVm(ipAddr net.IP, authInfo *srpc.AuthInformation, 491 accessToken []byte, dhcpTimeout time.Duration) ( 492 bool, error) { 493 return m.startVm(ipAddr, authInfo, accessToken, dhcpTimeout) 494 } 495 496 func (m *Manager) StopVm(ipAddr net.IP, authInfo *srpc.AuthInformation, 497 accessToken []byte) error { 498 return m.stopVm(ipAddr, authInfo, accessToken) 499 } 500 501 func (m *Manager) UpdateSubnets(request proto.UpdateSubnetsRequest) error { 502 return m.updateSubnets(request) 503 } 504 505 func (m *Manager) UnregisterVmMetadataNotifier(ipAddr net.IP, 506 pathChannel chan<- string) error { 507 return m.unregisterVmMetadataNotifier(ipAddr, pathChannel) 508 } 509 510 func (m *Manager) WriteHtml(writer io.Writer) { 511 m.writeHtml(writer) 512 }