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