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 }