github.com/daniellockard/packer@v0.7.6-0.20141210173435-5a9390934716/builder/vmware/iso/step_create_vmx.go (about) 1 package iso 2 3 import ( 4 "fmt" 5 "github.com/mitchellh/multistep" 6 vmwcommon "github.com/mitchellh/packer/builder/vmware/common" 7 "github.com/mitchellh/packer/packer" 8 "io/ioutil" 9 "os" 10 "path/filepath" 11 ) 12 13 type vmxTemplateData struct { 14 Name string 15 GuestOS string 16 DiskName string 17 ISOPath string 18 Version string 19 } 20 21 // This step creates the VMX file for the VM. 22 // 23 // Uses: 24 // config *config 25 // iso_path string 26 // ui packer.Ui 27 // 28 // Produces: 29 // vmx_path string - The path to the VMX file. 30 type stepCreateVMX struct { 31 tempDir string 32 } 33 34 func (s *stepCreateVMX) Run(state multistep.StateBag) multistep.StepAction { 35 config := state.Get("config").(*config) 36 isoPath := state.Get("iso_path").(string) 37 ui := state.Get("ui").(packer.Ui) 38 39 ui.Say("Building and writing VMX file") 40 41 tplData := &vmxTemplateData{ 42 Name: config.VMName, 43 GuestOS: config.GuestOSType, 44 DiskName: config.DiskName, 45 Version: config.Version, 46 ISOPath: isoPath, 47 } 48 49 vmxTemplate := DefaultVMXTemplate 50 if config.VMXTemplatePath != "" { 51 f, err := os.Open(config.VMXTemplatePath) 52 if err != nil { 53 err := fmt.Errorf("Error reading VMX template: %s", err) 54 state.Put("error", err) 55 ui.Error(err.Error()) 56 return multistep.ActionHalt 57 } 58 defer f.Close() 59 60 rawBytes, err := ioutil.ReadAll(f) 61 if err != nil { 62 err := fmt.Errorf("Error reading VMX template: %s", err) 63 state.Put("error", err) 64 ui.Error(err.Error()) 65 return multistep.ActionHalt 66 } 67 68 vmxTemplate = string(rawBytes) 69 } 70 71 vmxContents, err := config.tpl.Process(vmxTemplate, tplData) 72 if err != nil { 73 err := fmt.Errorf("Error procesing VMX template: %s", err) 74 state.Put("error", err) 75 ui.Error(err.Error()) 76 return multistep.ActionHalt 77 } 78 79 vmxDir := config.OutputDir 80 if config.RemoteType != "" { 81 // For remote builds, we just put the VMX in a temporary 82 // directory since it just gets uploaded anyways. 83 vmxDir, err = ioutil.TempDir("", "packer-vmx") 84 if err != nil { 85 err := fmt.Errorf("Error preparing VMX template: %s", err) 86 state.Put("error", err) 87 ui.Error(err.Error()) 88 return multistep.ActionHalt 89 } 90 91 // Set the tempDir so we clean it up 92 s.tempDir = vmxDir 93 } 94 95 vmxPath := filepath.Join(vmxDir, config.VMName+".vmx") 96 if err := vmwcommon.WriteVMX(vmxPath, vmwcommon.ParseVMX(vmxContents)); err != nil { 97 err := fmt.Errorf("Error creating VMX file: %s", err) 98 state.Put("error", err) 99 ui.Error(err.Error()) 100 return multistep.ActionHalt 101 } 102 103 state.Put("vmx_path", vmxPath) 104 105 return multistep.ActionContinue 106 } 107 108 func (s *stepCreateVMX) Cleanup(multistep.StateBag) { 109 if s.tempDir != "" { 110 os.RemoveAll(s.tempDir) 111 } 112 } 113 114 // This is the default VMX template used if no other template is given. 115 // This is hardcoded here. If you wish to use a custom template please 116 // do so by specifying in the builder configuration. 117 const DefaultVMXTemplate = ` 118 .encoding = "UTF-8" 119 bios.bootOrder = "hdd,CDROM" 120 checkpoint.vmState = "" 121 cleanShutdown = "TRUE" 122 config.version = "8" 123 displayName = "{{ .Name }}" 124 ehci.pciSlotNumber = "34" 125 ehci.present = "TRUE" 126 ethernet0.addressType = "generated" 127 ethernet0.bsdName = "en0" 128 ethernet0.connectionType = "nat" 129 ethernet0.displayName = "Ethernet" 130 ethernet0.linkStatePropagation.enable = "FALSE" 131 ethernet0.pciSlotNumber = "33" 132 ethernet0.present = "TRUE" 133 ethernet0.virtualDev = "e1000" 134 ethernet0.wakeOnPcktRcv = "FALSE" 135 extendedConfigFile = "{{ .Name }}.vmxf" 136 floppy0.present = "FALSE" 137 guestOS = "{{ .GuestOS }}" 138 gui.fullScreenAtPowerOn = "FALSE" 139 gui.viewModeAtPowerOn = "windowed" 140 hgfs.linkRootShare = "TRUE" 141 hgfs.mapRootShare = "TRUE" 142 ide1:0.present = "TRUE" 143 ide1:0.fileName = "{{ .ISOPath }}" 144 ide1:0.deviceType = "cdrom-image" 145 isolation.tools.hgfs.disable = "FALSE" 146 memsize = "512" 147 nvram = "{{ .Name }}.nvram" 148 pciBridge0.pciSlotNumber = "17" 149 pciBridge0.present = "TRUE" 150 pciBridge4.functions = "8" 151 pciBridge4.pciSlotNumber = "21" 152 pciBridge4.present = "TRUE" 153 pciBridge4.virtualDev = "pcieRootPort" 154 pciBridge5.functions = "8" 155 pciBridge5.pciSlotNumber = "22" 156 pciBridge5.present = "TRUE" 157 pciBridge5.virtualDev = "pcieRootPort" 158 pciBridge6.functions = "8" 159 pciBridge6.pciSlotNumber = "23" 160 pciBridge6.present = "TRUE" 161 pciBridge6.virtualDev = "pcieRootPort" 162 pciBridge7.functions = "8" 163 pciBridge7.pciSlotNumber = "24" 164 pciBridge7.present = "TRUE" 165 pciBridge7.virtualDev = "pcieRootPort" 166 powerType.powerOff = "soft" 167 powerType.powerOn = "soft" 168 powerType.reset = "soft" 169 powerType.suspend = "soft" 170 proxyApps.publishToHost = "FALSE" 171 replay.filename = "" 172 replay.supported = "FALSE" 173 scsi0.pciSlotNumber = "16" 174 scsi0.present = "TRUE" 175 scsi0.virtualDev = "lsilogic" 176 scsi0:0.fileName = "{{ .DiskName }}.vmdk" 177 scsi0:0.present = "TRUE" 178 scsi0:0.redo = "" 179 sound.startConnected = "FALSE" 180 tools.syncTime = "TRUE" 181 tools.upgrade.policy = "upgradeAtPowerCycle" 182 usb.pciSlotNumber = "32" 183 usb.present = "FALSE" 184 virtualHW.productCompatibility = "hosted" 185 virtualHW.version = "{{ .Version }}" 186 vmci0.id = "1861462627" 187 vmci0.pciSlotNumber = "35" 188 vmci0.present = "TRUE" 189 vmotion.checkpointFBSize = "65536000" 190 `