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

     1  package rpcd
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/Cloud-Foundations/Dominator/lib/errors"
     7  	"github.com/Cloud-Foundations/Dominator/lib/srpc"
     8  	"github.com/Cloud-Foundations/Dominator/proto/hypervisor"
     9  )
    10  
    11  func (t *srpcType) TraceVmMetadata(conn *srpc.Conn) error {
    12  	var request hypervisor.TraceVmMetadataRequest
    13  	if err := conn.Decode(&request); err != nil {
    14  		return err
    15  	}
    16  	pathChannel := make(chan string, 1024)
    17  	err := t.manager.RegisterVmMetadataNotifier(request.IpAddress,
    18  		conn.GetAuthInformation(), pathChannel)
    19  	if err == nil {
    20  		defer func() {
    21  			t.manager.UnregisterVmMetadataNotifier(request.IpAddress,
    22  				pathChannel)
    23  		}()
    24  	}
    25  	var response hypervisor.TraceVmMetadataResponse
    26  	response.Error = errors.ErrorToString(err)
    27  	if err := conn.Encode(response); err != nil {
    28  		return err
    29  	}
    30  	if err := conn.Flush(); err != nil {
    31  		return err
    32  	}
    33  	if err != nil {
    34  		return nil
    35  	}
    36  	closeChannel := conn.GetCloseNotifier()
    37  	flushDelay := time.Millisecond * 100
    38  	flushTimer := time.NewTimer(flushDelay)
    39  	for {
    40  		select {
    41  		case path, ok := <-pathChannel:
    42  			if !ok {
    43  				_, err := conn.Write([]byte("VM destroyed\n\n"))
    44  				return err
    45  			}
    46  			if _, err := conn.Write([]byte(path + "\n")); err != nil {
    47  				return err
    48  			}
    49  			flushTimer.Reset(flushDelay)
    50  		case <-flushTimer.C:
    51  			if err := conn.Flush(); err != nil {
    52  				return err
    53  			}
    54  		case err := <-closeChannel:
    55  			if err == nil {
    56  				t.logger.Debugf(0, "metadata trace client disconnected: %s\n",
    57  					conn.RemoteAddr())
    58  				return nil
    59  			}
    60  			t.logger.Println(err)
    61  			return err
    62  		}
    63  	}
    64  }