github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/hypervisor/rpcd/netbootMachine.go (about)

     1  package rpcd
     2  
     3  import (
     4  	"net"
     5  	"time"
     6  
     7  	"github.com/Cloud-Foundations/Dominator/lib/errors"
     8  	"github.com/Cloud-Foundations/Dominator/lib/srpc"
     9  	"github.com/Cloud-Foundations/Dominator/proto/hypervisor"
    10  )
    11  
    12  func (t *srpcType) NetbootMachine(conn *srpc.Conn,
    13  	request hypervisor.NetbootMachineRequest,
    14  	reply *hypervisor.NetbootMachineResponse) error {
    15  	*reply = hypervisor.NetbootMachineResponse{
    16  		errors.ErrorToString(t.netbootMachine(request))}
    17  	return nil
    18  }
    19  
    20  func (t *srpcType) netbootMachine(
    21  	request hypervisor.NetbootMachineRequest) error {
    22  	err := t.dhcpServer.AddNetbootLease(request.Address, request.Hostname,
    23  		request.Subnet)
    24  	if err != nil {
    25  		return err
    26  	}
    27  	t.tftpbootServer.RegisterFiles(request.Address.IpAddress, request.Files)
    28  	if request.WaitTimeout <= 0 {
    29  		request.WaitTimeout = time.Minute
    30  	}
    31  	if request.FilesExpiration < request.WaitTimeout+time.Second {
    32  		request.FilesExpiration = request.WaitTimeout + time.Second
    33  	}
    34  	if request.OfferExpiration < request.WaitTimeout+time.Second {
    35  		request.OfferExpiration = request.WaitTimeout + time.Second
    36  	}
    37  	go expireLeaseAfter(t.dhcpServer, request.Address.IpAddress,
    38  		request.OfferExpiration)
    39  	timer := time.NewTimer(request.WaitTimeout)
    40  	for count := 0; count < int(request.NumAcknowledgementsToWaitFor); {
    41  		ackChannel := t.dhcpServer.MakeAcknowledgmentChannel(
    42  			request.Address.IpAddress)
    43  		select {
    44  		case <-ackChannel:
    45  			count++
    46  		case <-timer.C:
    47  			if len(request.Files) > 0 {
    48  				t.tftpbootServer.UnregisterFiles(request.Address.IpAddress)
    49  			}
    50  			return errors.New("timed out receiving lease acknowledgement")
    51  		}
    52  	}
    53  	t.dhcpServer.RemoveLease(request.Address.IpAddress)
    54  	if len(request.Files) > 0 {
    55  		go expireFilesAfter(t.tftpbootServer, request.Address.IpAddress,
    56  			request.FilesExpiration)
    57  	}
    58  	return nil
    59  }
    60  
    61  func expireFilesAfter(tftpbootServer TftpbootServer, ipAddr net.IP,
    62  	timeout time.Duration) {
    63  	time.Sleep(timeout)
    64  	tftpbootServer.UnregisterFiles(ipAddr)
    65  }
    66  
    67  func expireLeaseAfter(dhcpServer DhcpServer, ipAddr net.IP,
    68  	timeout time.Duration) {
    69  	time.Sleep(timeout)
    70  	dhcpServer.RemoveLease(ipAddr)
    71  }