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

     1  package main
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io"
     7  	"net"
     8  
     9  	"github.com/Cloud-Foundations/Dominator/lib/errors"
    10  	"github.com/Cloud-Foundations/Dominator/lib/log"
    11  	proto "github.com/Cloud-Foundations/Dominator/proto/hypervisor"
    12  )
    13  
    14  func replaceVmUserDataSubcommand(args []string, logger log.DebugLogger) error {
    15  	if err := replaceVmUserData(args[0], logger); err != nil {
    16  		return fmt.Errorf("Error replacing VM user data: %s", err)
    17  	}
    18  	return nil
    19  }
    20  
    21  func replaceVmUserData(vmHostname string, logger log.DebugLogger) error {
    22  	if vmIP, hypervisor, err := lookupVmAndHypervisor(vmHostname); err != nil {
    23  		return err
    24  	} else {
    25  		return replaceVmUserDataOnHypervisor(hypervisor, vmIP, logger)
    26  	}
    27  }
    28  
    29  func replaceVmUserDataOnHypervisor(hypervisor string, ipAddr net.IP,
    30  	logger log.DebugLogger) error {
    31  	if *userDataFile == "" {
    32  		return errors.New("no user data file specified")
    33  	}
    34  	file, size, err := getReader(*userDataFile)
    35  	if err != nil {
    36  		return err
    37  	}
    38  	defer file.Close()
    39  	request := proto.ReplaceVmUserDataRequest{
    40  		IpAddress: ipAddr,
    41  		Size:      uint64(size),
    42  	}
    43  	userDataReader := bufio.NewReader(io.LimitReader(file, size))
    44  	client, err := dialHypervisor(hypervisor)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	defer client.Close()
    49  	conn, err := client.Call("Hypervisor.ReplaceVmUserData")
    50  	if err != nil {
    51  		return err
    52  	}
    53  	defer conn.Close()
    54  	if err := conn.Encode(request); err != nil {
    55  		return err
    56  	}
    57  	logger.Debugln(0, "uploading user data")
    58  	if _, err := io.Copy(conn, userDataReader); err != nil {
    59  		return err
    60  	}
    61  	if err := conn.Flush(); err != nil {
    62  		return err
    63  	}
    64  	var response proto.ReplaceVmUserDataResponse
    65  	if err := conn.Decode(&response); err != nil {
    66  		return err
    67  	}
    68  	return errors.New(response.Error)
    69  }