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  }