github.com/Cloud-Foundations/Dominator@v0.3.4/cmd/vm-control/patchVmImage.go (about)

     1  package main
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net"
     7  	"os"
     8  
     9  	hyperclient "github.com/Cloud-Foundations/Dominator/hypervisor/client"
    10  	"github.com/Cloud-Foundations/Dominator/lib/log"
    11  	"github.com/Cloud-Foundations/Dominator/lib/srpc"
    12  	proto "github.com/Cloud-Foundations/Dominator/proto/hypervisor"
    13  )
    14  
    15  func patchVmImageSubcommand(args []string, logger log.DebugLogger) error {
    16  	if err := patchVmImage(args[0], logger); err != nil {
    17  		return fmt.Errorf("error patching VM image: %s", err)
    18  	}
    19  	return nil
    20  }
    21  
    22  func callPatchVmImage(client *srpc.Client, request proto.PatchVmImageRequest,
    23  	reply *proto.PatchVmImageResponse, logger log.DebugLogger) error {
    24  	conn, err := client.Call("Hypervisor.PatchVmImage")
    25  	if err != nil {
    26  		return err
    27  	}
    28  	defer conn.Close()
    29  	if err := conn.Encode(request); err != nil {
    30  		return err
    31  	}
    32  	if err := conn.Flush(); err != nil {
    33  		return err
    34  	}
    35  	for {
    36  		var response proto.PatchVmImageResponse
    37  		if err := conn.Decode(&response); err != nil {
    38  			return err
    39  		}
    40  		if response.Error != "" {
    41  			return errors.New(response.Error)
    42  		}
    43  		if response.ProgressMessage != "" {
    44  			logger.Debugln(0, response.ProgressMessage)
    45  		}
    46  		if response.Final {
    47  			*reply = response
    48  			return nil
    49  		}
    50  	}
    51  }
    52  
    53  func patchVmImage(vmHostname string, logger log.DebugLogger) error {
    54  	if vmIP, hypervisor, err := lookupVmAndHypervisor(vmHostname); err != nil {
    55  		return err
    56  	} else {
    57  		return patchVmImageOnHypervisor(hypervisor, vmIP, logger)
    58  	}
    59  }
    60  
    61  func patchVmImageOnHypervisor(hypervisor string, ipAddr net.IP,
    62  	logger log.DebugLogger) error {
    63  	request := proto.PatchVmImageRequest{
    64  		ImageName:    *imageName,
    65  		ImageTimeout: *imageTimeout,
    66  		IpAddress:    ipAddr,
    67  		SkipBackup:   *skipBackup,
    68  	}
    69  	client, err := dialHypervisor(hypervisor)
    70  	if err != nil {
    71  		return err
    72  	}
    73  	defer client.Close()
    74  	var reply proto.PatchVmImageResponse
    75  	err = callPatchVmImage(client, request, &reply, logger)
    76  	if err != nil {
    77  		return err
    78  	}
    79  	if *patchLogFilename == "" {
    80  		return nil
    81  	}
    82  	patchLog, _, err := hyperclient.GetVmLastPatchLog(client, ipAddr)
    83  	if err != nil {
    84  		return err
    85  	}
    86  	file, err := os.Create(*patchLogFilename)
    87  	if err != nil {
    88  		return err
    89  	}
    90  	defer file.Close()
    91  	_, err = file.Write(patchLog)
    92  	return err
    93  }