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  }