diff --git a/builder/common/step_create_floppy.go b/builder/common/step_create_floppy.go index ee99e9f5d..9e0bf4e33 100644 --- a/builder/common/step_create_floppy.go +++ b/builder/common/step_create_floppy.go @@ -18,6 +18,8 @@ import ( // root level are supported. type StepCreateFloppy struct { Files []string + + floppyPath string } func (s *StepCreateFloppy) Run(state map[string]interface{}) multistep.StepAction { @@ -37,6 +39,9 @@ func (s *StepCreateFloppy) Run(state map[string]interface{}) multistep.StepActio } defer floppyF.Close() + // Set the path so we can remove it later + s.floppyPath = floppyF.Name() + log.Printf("Floppy path: %s", floppyF.Name()) // Set the size of the file to be a floppy sized @@ -91,12 +96,16 @@ func (s *StepCreateFloppy) Run(state map[string]interface{}) multistep.StepActio } // Set the path to the floppy so it can be used later - state["floppy_path"] = floppyF.Name() + state["floppy_path"] = s.floppyPath return multistep.ActionHalt } func (s *StepCreateFloppy) Cleanup(map[string]interface{}) { + if s.floppyPath != "" { + log.Printf("Deleting floppy disk: %s", s.floppyPath) + os.Remove(s.floppyPath) + } } func (s *StepCreateFloppy) addSingleFile(dir fs.Directory, src string) error { diff --git a/builder/vmware/builder.go b/builder/vmware/builder.go index e48103c73..708f3c988 100644 --- a/builder/vmware/builder.go +++ b/builder/vmware/builder.go @@ -28,6 +28,7 @@ type Builder struct { type config struct { DiskName string `mapstructure:"vmdk_name"` DiskSize uint `mapstructure:"disk_size"` + FloppyFiles []string `mapstructure:"floppy_files"` GuestOSType string `mapstructure:"guest_os_type"` ISOMD5 string `mapstructure:"iso_md5"` ISOUrl string `mapstructure:"iso_url"` @@ -76,6 +77,10 @@ func (b *Builder) Prepare(raws ...interface{}) error { b.config.DiskSize = 40000 } + if b.config.FloppyFiles == nil { + b.config.FloppyFiles = make([]string, 0) + } + if b.config.GuestOSType == "" { b.config.GuestOSType = "other" } @@ -230,6 +235,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &stepPrepareTools{}, &stepDownloadISO{}, &stepPrepareOutputDir{}, + &common.StepCreateFloppy{ + Files: b.config.FloppyFiles, + }, &stepCreateDisk{}, &stepCreateVMX{}, &stepHTTPServer{}, @@ -241,6 +249,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &stepProvision{}, &stepShutdown{}, &stepCleanFiles{}, + &stepCleanVMX{}, &stepCompactDisk{}, } diff --git a/builder/vmware/builder_test.go b/builder/vmware/builder_test.go index 8d32636d8..0cf8a42b1 100644 --- a/builder/vmware/builder_test.go +++ b/builder/vmware/builder_test.go @@ -4,6 +4,7 @@ import ( "github.com/mitchellh/packer/packer" "io/ioutil" "os" + "reflect" "testing" "time" ) @@ -107,6 +108,33 @@ func TestBuilderPrepare_DiskSize(t *testing.T) { } } +func TestBuilderPrepare_FloppyFiles(t *testing.T) { + var b Builder + config := testConfig() + + delete(config, "floppy_files") + err := b.Prepare(config) + if err != nil { + t.Fatalf("bad err: %s", err) + } + + if len(b.config.FloppyFiles) != 0 { + t.Fatalf("bad: %#v", b.config.FloppyFiles) + } + + config["floppy_files"] = []string{"foo", "bar"} + b = Builder{} + err = b.Prepare(config) + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + expected := []string{"foo", "bar"} + if !reflect.DeepEqual(b.config.FloppyFiles, expected) { + t.Fatalf("bad: %#v", b.config.FloppyFiles) + } +} + func TestBuilderPrepare_HTTPPort(t *testing.T) { var b Builder config := testConfig() diff --git a/builder/vmware/step_clean_vmx.go b/builder/vmware/step_clean_vmx.go new file mode 100644 index 000000000..595b90e01 --- /dev/null +++ b/builder/vmware/step_clean_vmx.go @@ -0,0 +1,72 @@ +package vmware + +import ( + "fmt" + "github.com/mitchellh/multistep" + "github.com/mitchellh/packer/packer" + "io/ioutil" + "log" + "os" + "strings" +) + +// This step cleans up the VMX by removing or changing this prior to +// being ready for use. +// +// Uses: +// ui packer.Ui +// vmx_path string +// +// Produces: +// +type stepCleanVMX struct{} + +func (s stepCleanVMX) Run(state map[string]interface{}) multistep.StepAction { + if _, ok := state["floppy_path"]; !ok { + return multistep.ActionContinue + } + + ui := state["ui"].(packer.Ui) + vmxPath := state["vmx_path"].(string) + + vmxData, err := s.readVMX(vmxPath) + if err != nil { + state["error"] = fmt.Errorf("Error reading VMX: %s", err) + return multistep.ActionHalt + } + + // Delete the floppy0 entries so the floppy is no longer mounted + ui.Say("Unmounting floppy from VMX...") + for k, _ := range vmxData { + if strings.HasPrefix(k, "floppy0.") { + log.Printf("Deleting key: %s", k) + delete(vmxData, k) + } + } + vmxData["floppy0.present"] = "FALSE" + + // Rewrite the VMX + if err := WriteVMX(vmxPath, vmxData); err != nil { + state["error"] = fmt.Errorf("Error writing VMX: %s", err) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (stepCleanVMX) Cleanup(map[string]interface{}) {} + +func (stepCleanVMX) readVMX(vmxPath string) (map[string]string, error) { + vmxF, err := os.Open(vmxPath) + if err != nil { + return nil, err + } + defer vmxF.Close() + + vmxBytes, err := ioutil.ReadAll(vmxF) + if err != nil { + return nil, err + } + + return ParseVMX(string(vmxBytes)), nil +} diff --git a/builder/vmware/step_create_vmx.go b/builder/vmware/step_create_vmx.go index 56e1962ce..8165fb36b 100644 --- a/builder/vmware/step_create_vmx.go +++ b/builder/vmware/step_create_vmx.go @@ -36,10 +36,10 @@ func (stepCreateVMX) Run(state map[string]interface{}) multistep.StepAction { ui.Say("Building and writing VMX file") tplData := &vmxTemplateData{ - config.VMName, - config.GuestOSType, - config.DiskName, - isoPath, + Name: config.VMName, + GuestOS: config.GuestOSType, + DiskName: config.DiskName, + ISOPath: isoPath, } var buf bytes.Buffer @@ -55,6 +55,13 @@ func (stepCreateVMX) Run(state map[string]interface{}) multistep.StepAction { } } + if floppyPathRaw, ok := state["floppy_path"]; ok { + log.Println("Floppy path present, setting in VMX") + vmxData["floppy0.present"] = "TRUE" + vmxData["floppy0.fileType"] = "file" + vmxData["floppy0.fileName"] = floppyPathRaw.(string) + } + vmxPath := filepath.Join(config.OutputDir, config.VMName+".vmx") if err := WriteVMX(vmxPath, vmxData); err != nil { err := fmt.Errorf("Error creating VMX file: %s", err)