github.phpd.cn/hashicorp/packer@v1.3.2/builder/vmware/common/step_configure_vmx.go (about) 1 package common 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "regexp" 8 "strings" 9 10 "github.com/hashicorp/packer/helper/multistep" 11 "github.com/hashicorp/packer/packer" 12 ) 13 14 // This step configures a VMX by setting some default settings as well 15 // as taking in custom data to set, attaching a floppy if it exists, etc. 16 // 17 // Uses: 18 // vmx_path string 19 // 20 // Produces: 21 // display_name string - Value of the displayName key set in the VMX file 22 type StepConfigureVMX struct { 23 CustomData map[string]string 24 SkipFloppy bool 25 } 26 27 func (s *StepConfigureVMX) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { 28 ui := state.Get("ui").(packer.Ui) 29 vmxPath := state.Get("vmx_path").(string) 30 31 vmxData, err := ReadVMX(vmxPath) 32 if err != nil { 33 err := fmt.Errorf("Error reading VMX file: %s", err) 34 state.Put("error", err) 35 ui.Error(err.Error()) 36 return multistep.ActionHalt 37 } 38 39 // Set this so that no dialogs ever appear from Packer. 40 vmxData["msg.autoanswer"] = "true" 41 42 // Create a new UUID for this VM, since it is a new VM 43 vmxData["uuid.action"] = "create" 44 45 // Delete any generated addresses since we want to regenerate 46 // them. Conflicting MAC addresses is a bad time. 47 addrRegex := regexp.MustCompile(`(?i)^ethernet\d+\.generatedAddress`) 48 for k := range vmxData { 49 if addrRegex.MatchString(k) { 50 delete(vmxData, k) 51 } 52 } 53 54 // Set custom data 55 for k, v := range s.CustomData { 56 log.Printf("Setting VMX: '%s' = '%s'", k, v) 57 k = strings.ToLower(k) 58 vmxData[k] = v 59 } 60 61 // Set a floppy disk, but only if we should 62 if !s.SkipFloppy { 63 // Set a floppy disk if we have one 64 if floppyPathRaw, ok := state.GetOk("floppy_path"); ok { 65 log.Println("Floppy path present, setting in VMX") 66 vmxData["floppy0.present"] = "TRUE" 67 vmxData["floppy0.filetype"] = "file" 68 vmxData["floppy0.filename"] = floppyPathRaw.(string) 69 } 70 } 71 72 if err := WriteVMX(vmxPath, vmxData); err != nil { 73 err := fmt.Errorf("Error writing VMX file: %s", err) 74 state.Put("error", err) 75 ui.Error(err.Error()) 76 return multistep.ActionHalt 77 } 78 79 // If the build is taking place on a remote ESX server, the displayName 80 // will be needed for discovery of the VM's IP address and for export 81 // of the VM. The displayName key should always be set in the VMX file, 82 // so error if we don't find it 83 if displayName, ok := vmxData["displayname"]; !ok { // Packer converts key names to lowercase! 84 err := fmt.Errorf("Error: Could not get value of displayName from VMX data") 85 state.Put("error", err) 86 ui.Error(err.Error()) 87 return multistep.ActionHalt 88 } else { 89 state.Put("display_name", displayName) 90 } 91 92 return multistep.ActionContinue 93 } 94 95 func (s *StepConfigureVMX) Cleanup(state multistep.StateBag) { 96 }