github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/cmd/vm-control/getVmUserData.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"io/ioutil"
     7  	"net"
     8  	"os"
     9  
    10  	"github.com/Cloud-Foundations/Dominator/lib/errors"
    11  	"github.com/Cloud-Foundations/Dominator/lib/log"
    12  	"github.com/Cloud-Foundations/Dominator/lib/srpc"
    13  	proto "github.com/Cloud-Foundations/Dominator/proto/hypervisor"
    14  )
    15  
    16  func callGetVmUserData(client *srpc.Client,
    17  	ipAddr net.IP) (io.ReadCloser, uint64, error) {
    18  	conn, err := client.Call("Hypervisor.GetVmUserData")
    19  	if err != nil {
    20  		return nil, 0, err
    21  	}
    22  	doClose := true
    23  	defer func() {
    24  		if doClose {
    25  			conn.Close()
    26  		}
    27  	}()
    28  	request := proto.GetVmUserDataRequest{IpAddress: ipAddr}
    29  	if err := conn.Encode(request); err != nil {
    30  		return nil, 0, err
    31  	}
    32  	if err := conn.Flush(); err != nil {
    33  		return nil, 0, err
    34  	}
    35  	var response proto.GetVmUserDataResponse
    36  	if err := conn.Decode(&response); err != nil {
    37  		return nil, 0, err
    38  	}
    39  	if err := errors.New(response.Error); err != nil {
    40  		return nil, 0, err
    41  	}
    42  	doClose = false
    43  	return conn, response.Length, nil
    44  }
    45  
    46  func getVmUserDataSubcommand(args []string, logger log.DebugLogger) error {
    47  	if err := getVmUserData(args[0], logger); err != nil {
    48  		return fmt.Errorf("Error getting VM user data: %s", err)
    49  	}
    50  	return nil
    51  }
    52  
    53  func getVmUserData(vmHostname string, logger log.DebugLogger) error {
    54  	if vmIP, hypervisor, err := lookupVmAndHypervisor(vmHostname); err != nil {
    55  		return err
    56  	} else {
    57  		return getVmUserDataOnHypervisor(hypervisor, vmIP, logger)
    58  	}
    59  }
    60  
    61  func getVmUserDataOnHypervisor(hypervisor string, ipAddr net.IP,
    62  	logger log.DebugLogger) error {
    63  	if *userDataFile == "" {
    64  		return errors.New("no user data file specified")
    65  	}
    66  	client, err := dialHypervisor(hypervisor)
    67  	if err != nil {
    68  		return err
    69  	}
    70  	defer client.Close()
    71  	conn, length, err := callGetVmUserData(client, ipAddr)
    72  	if err != nil {
    73  		return err
    74  	}
    75  	defer conn.Close()
    76  	file, err := os.OpenFile(*userDataFile, os.O_WRONLY|os.O_CREATE,
    77  		privateFilePerms)
    78  	if err != nil {
    79  		io.CopyN(ioutil.Discard, conn, int64(length))
    80  		return err
    81  	}
    82  	defer file.Close()
    83  	logger.Debugln(0, "downloading user data")
    84  	if _, err := io.CopyN(file, conn, int64(length)); err != nil {
    85  		return err
    86  	}
    87  	return nil
    88  }