github.com/StackPointCloud/packer@v0.10.2-0.20180716202532-b28098e0f79b/builder/hyperv/common/step_create_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 creates the actual virtual machine. 15 // 16 // Produces: 17 // VMName string - The name of the VM 18 type StepCreateVM struct { 19 VMName string 20 SwitchName string 21 HarddrivePath string 22 RamSize uint 23 DiskSize uint 24 DiskBlockSize uint 25 Generation uint 26 Cpu uint 27 EnableMacSpoofing bool 28 EnableDynamicMemory bool 29 EnableSecureBoot bool 30 SecureBootTemplate string 31 EnableVirtualizationExtensions bool 32 AdditionalDiskSize []uint 33 DifferencingDisk bool 34 MacAddress string 35 SkipExport bool 36 OutputDir string 37 FixedVHD bool 38 } 39 40 func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { 41 driver := state.Get("driver").(Driver) 42 ui := state.Get("ui").(packer.Ui) 43 ui.Say("Creating virtual machine...") 44 45 path := state.Get("packerTempDir").(string) 46 47 // Determine if we even have an existing virtual harddrive to attach 48 harddrivePath := "" 49 if harddrivePathRaw, ok := state.GetOk("iso_path"); ok { 50 extension := strings.ToLower(filepath.Ext(harddrivePathRaw.(string))) 51 if extension == ".vhd" || extension == ".vhdx" { 52 harddrivePath = harddrivePathRaw.(string) 53 } else { 54 log.Println("No existing virtual harddrive, not attaching.") 55 } 56 } else { 57 log.Println("No existing virtual harddrive, not attaching.") 58 } 59 60 vhdPath := state.Get("packerVhdTempDir").(string) 61 62 // inline vhd path if export is skipped 63 if s.SkipExport { 64 vhdPath = filepath.Join(s.OutputDir, "Virtual Hard Disks") 65 } 66 67 // convert the MB to bytes 68 ramSize := int64(s.RamSize * 1024 * 1024) 69 diskSize := int64(s.DiskSize * 1024 * 1024) 70 diskBlockSize := int64(s.DiskBlockSize * 1024 * 1024) 71 72 err := driver.CreateVirtualMachine(s.VMName, path, harddrivePath, vhdPath, ramSize, diskSize, diskBlockSize, s.SwitchName, s.Generation, s.DifferencingDisk, s.FixedVHD) 73 if err != nil { 74 err := fmt.Errorf("Error creating virtual machine: %s", err) 75 state.Put("error", err) 76 ui.Error(err.Error()) 77 return multistep.ActionHalt 78 } 79 80 err = driver.SetVirtualMachineCpuCount(s.VMName, s.Cpu) 81 if err != nil { 82 err := fmt.Errorf("Error setting virtual machine cpu count: %s", err) 83 state.Put("error", err) 84 ui.Error(err.Error()) 85 return multistep.ActionHalt 86 } 87 88 err = driver.SetVirtualMachineDynamicMemory(s.VMName, s.EnableDynamicMemory) 89 if err != nil { 90 err := fmt.Errorf("Error setting virtual machine dynamic memory: %s", err) 91 state.Put("error", err) 92 ui.Error(err.Error()) 93 return multistep.ActionHalt 94 } 95 96 if s.EnableMacSpoofing { 97 err = driver.SetVirtualMachineMacSpoofing(s.VMName, s.EnableMacSpoofing) 98 if err != nil { 99 err := fmt.Errorf("Error setting virtual machine mac spoofing: %s", err) 100 state.Put("error", err) 101 ui.Error(err.Error()) 102 return multistep.ActionHalt 103 } 104 } 105 106 if s.Generation == 2 { 107 err = driver.SetVirtualMachineSecureBoot(s.VMName, s.EnableSecureBoot, s.SecureBootTemplate) 108 if err != nil { 109 err := fmt.Errorf("Error setting secure boot: %s", err) 110 state.Put("error", err) 111 ui.Error(err.Error()) 112 return multistep.ActionHalt 113 } 114 } 115 116 if s.EnableVirtualizationExtensions { 117 //This is only supported on Windows 10 and Windows Server 2016 onwards 118 err = driver.SetVirtualMachineVirtualizationExtensions(s.VMName, s.EnableVirtualizationExtensions) 119 if err != nil { 120 err := fmt.Errorf("Error setting virtual machine virtualization extensions: %s", err) 121 state.Put("error", err) 122 ui.Error(err.Error()) 123 return multistep.ActionHalt 124 } 125 } 126 127 if len(s.AdditionalDiskSize) > 0 { 128 for index, size := range s.AdditionalDiskSize { 129 diskSize := int64(size * 1024 * 1024) 130 diskFile := fmt.Sprintf("%s-%d.vhdx", s.VMName, index) 131 err = driver.AddVirtualMachineHardDrive(s.VMName, vhdPath, diskFile, diskSize, diskBlockSize, "SCSI") 132 if err != nil { 133 err := fmt.Errorf("Error creating and attaching additional disk drive: %s", err) 134 state.Put("error", err) 135 ui.Error(err.Error()) 136 return multistep.ActionHalt 137 } 138 } 139 } 140 141 if s.MacAddress != "" { 142 err = driver.SetVmNetworkAdapterMacAddress(s.VMName, s.MacAddress) 143 if err != nil { 144 err := fmt.Errorf("Error setting MAC address: %s", err) 145 state.Put("error", err) 146 ui.Error(err.Error()) 147 return multistep.ActionHalt 148 } 149 } 150 151 // Set the final name in the state bag so others can use it 152 state.Put("vmName", s.VMName) 153 154 return multistep.ActionContinue 155 } 156 157 func (s *StepCreateVM) Cleanup(state multistep.StateBag) { 158 if s.VMName == "" { 159 return 160 } 161 162 driver := state.Get("driver").(Driver) 163 ui := state.Get("ui").(packer.Ui) 164 ui.Say("Unregistering and deleting virtual machine...") 165 166 err := driver.DeleteVirtualMachine(s.VMName) 167 if err != nil { 168 ui.Error(fmt.Sprintf("Error deleting virtual machine: %s", err)) 169 } 170 171 // TODO: Clean up created VHDX 172 }