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 }