github.com/StackPointCloud/packer@v0.10.2-0.20180716202532-b28098e0f79b/builder/hyperv/common/step_clone_vm.go (about) 1 package common 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "path/filepath" 8 "strings" 9 10 "github.com/hashicorp/packer/helper/multistep" 11 "github.com/hashicorp/packer/packer" 12 ) 13 14 // This step clones an existing virtual machine. 15 // 16 // Produces: 17 // VMName string - The name of the VM 18 type StepCloneVM struct { 19 CloneFromVMXCPath string 20 CloneFromVMName string 21 CloneFromSnapshotName string 22 CloneAllSnapshots bool 23 VMName string 24 SwitchName string 25 RamSize uint 26 Cpu uint 27 EnableMacSpoofing bool 28 EnableDynamicMemory bool 29 EnableSecureBoot bool 30 SecureBootTemplate string 31 EnableVirtualizationExtensions bool 32 MacAddress string 33 } 34 35 func (s *StepCloneVM) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { 36 driver := state.Get("driver").(Driver) 37 ui := state.Get("ui").(packer.Ui) 38 ui.Say("Cloning virtual machine...") 39 40 path := state.Get("packerTempDir").(string) 41 42 // Determine if we even have an existing virtual harddrive to attach 43 harddrivePath := "" 44 if harddrivePathRaw, ok := state.GetOk("iso_path"); ok { 45 extension := strings.ToLower(filepath.Ext(harddrivePathRaw.(string))) 46 if extension == ".vhd" || extension == ".vhdx" { 47 harddrivePath = harddrivePathRaw.(string) 48 } else { 49 log.Println("No existing virtual harddrive, not attaching.") 50 } 51 } else { 52 log.Println("No existing virtual harddrive, not attaching.") 53 } 54 55 // convert the MB to bytes 56 ramSize := int64(s.RamSize * 1024 * 1024) 57 58 err := driver.CloneVirtualMachine(s.CloneFromVMXCPath, s.CloneFromVMName, s.CloneFromSnapshotName, s.CloneAllSnapshots, s.VMName, path, harddrivePath, ramSize, s.SwitchName) 59 if err != nil { 60 err := fmt.Errorf("Error cloning virtual machine: %s", err) 61 state.Put("error", err) 62 ui.Error(err.Error()) 63 return multistep.ActionHalt 64 } 65 66 err = driver.SetVirtualMachineCpuCount(s.VMName, s.Cpu) 67 if err != nil { 68 err := fmt.Errorf("Error creating setting virtual machine cpu: %s", err) 69 state.Put("error", err) 70 ui.Error(err.Error()) 71 return multistep.ActionHalt 72 } 73 74 if s.EnableDynamicMemory { 75 err = driver.SetVirtualMachineDynamicMemory(s.VMName, s.EnableDynamicMemory) 76 if err != nil { 77 err := fmt.Errorf("Error creating setting virtual machine dynamic memory: %s", err) 78 state.Put("error", err) 79 ui.Error(err.Error()) 80 return multistep.ActionHalt 81 } 82 } 83 84 if s.EnableMacSpoofing { 85 err = driver.SetVirtualMachineMacSpoofing(s.VMName, s.EnableMacSpoofing) 86 if err != nil { 87 err := fmt.Errorf("Error creating setting virtual machine mac spoofing: %s", err) 88 state.Put("error", err) 89 ui.Error(err.Error()) 90 return multistep.ActionHalt 91 } 92 } 93 94 generation, err := driver.GetVirtualMachineGeneration(s.VMName) 95 if err != nil { 96 err := fmt.Errorf("Error detecting vm generation: %s", err) 97 state.Put("error", err) 98 ui.Error(err.Error()) 99 return multistep.ActionHalt 100 } 101 102 if generation == 2 { 103 104 err = driver.SetVirtualMachineSecureBoot(s.VMName, s.EnableSecureBoot, s.SecureBootTemplate) 105 if err != nil { 106 err := fmt.Errorf("Error setting secure boot: %s", err) 107 state.Put("error", err) 108 ui.Error(err.Error()) 109 return multistep.ActionHalt 110 } 111 } 112 113 if s.EnableVirtualizationExtensions { 114 //This is only supported on Windows 10 and Windows Server 2016 onwards 115 err = driver.SetVirtualMachineVirtualizationExtensions(s.VMName, s.EnableVirtualizationExtensions) 116 if err != nil { 117 err := fmt.Errorf("Error creating setting virtual machine virtualization extensions: %s", err) 118 state.Put("error", err) 119 ui.Error(err.Error()) 120 return multistep.ActionHalt 121 } 122 } 123 124 if s.MacAddress != "" { 125 err = driver.SetVmNetworkAdapterMacAddress(s.VMName, s.MacAddress) 126 if err != nil { 127 err := fmt.Errorf("Error setting MAC address: %s", err) 128 state.Put("error", err) 129 ui.Error(err.Error()) 130 return multistep.ActionHalt 131 } 132 } 133 134 // Set the final name in the state bag so others can use it 135 state.Put("vmName", s.VMName) 136 137 return multistep.ActionContinue 138 } 139 140 func (s *StepCloneVM) Cleanup(state multistep.StateBag) { 141 if s.VMName == "" { 142 return 143 } 144 145 driver := state.Get("driver").(Driver) 146 ui := state.Get("ui").(packer.Ui) 147 ui.Say("Unregistering and deleting virtual machine...") 148 149 err := driver.DeleteVirtualMachine(s.VMName) 150 if err != nil { 151 ui.Error(fmt.Sprintf("Error deleting virtual machine: %s", err)) 152 } 153 }