Commit f01b21c6 authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

builder/vmware: StepCleanVMX

parent 8f8ea60b
package iso package common
import ( import (
"fmt" "fmt"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
vmwcommon "github.com/mitchellh/packer/builder/vmware/common"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"io/ioutil"
"log" "log"
"os"
"regexp" "regexp"
"strings" "strings"
) )
...@@ -21,16 +18,15 @@ import ( ...@@ -21,16 +18,15 @@ import (
// //
// Produces: // Produces:
// <nothing> // <nothing>
type stepCleanVMX struct{} type StepCleanVMX struct{}
func (s stepCleanVMX) Run(state multistep.StateBag) multistep.StepAction { func (s StepCleanVMX) Run(state multistep.StateBag) multistep.StepAction {
isoPath := state.Get("iso_path").(string)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
vmxPath := state.Get("vmx_path").(string) vmxPath := state.Get("vmx_path").(string)
ui.Say("Cleaning VMX prior to finishing up...") ui.Say("Cleaning VMX prior to finishing up...")
vmxData, err := s.readVMX(vmxPath) vmxData, err := ReadVMX(vmxPath)
if err != nil { if err != nil {
state.Put("error", fmt.Errorf("Error reading VMX: %s", err)) state.Put("error", fmt.Errorf("Error reading VMX: %s", err))
return multistep.ActionHalt return multistep.ActionHalt
...@@ -48,26 +44,30 @@ func (s stepCleanVMX) Run(state multistep.StateBag) multistep.StepAction { ...@@ -48,26 +44,30 @@ func (s stepCleanVMX) Run(state multistep.StateBag) multistep.StepAction {
vmxData["floppy0.present"] = "FALSE" vmxData["floppy0.present"] = "FALSE"
} }
ui.Message("Detaching ISO from CD-ROM device...") if isoPathRaw, ok := state.GetOk("iso_path"); ok {
devRe := regexp.MustCompile(`^ide\d:\d\.`) isoPath := isoPathRaw.(string)
for k, _ := range vmxData {
match := devRe.FindString(k) ui.Message("Detaching ISO from CD-ROM device...")
if match == "" { devRe := regexp.MustCompile(`^ide\d:\d\.`)
continue for k, _ := range vmxData {
} match := devRe.FindString(k)
if match == "" {
continue
}
filenameKey := match + "filename" filenameKey := match + "filename"
if filename, ok := vmxData[filenameKey]; ok { if filename, ok := vmxData[filenameKey]; ok {
if filename == isoPath { if filename == isoPath {
// Change the CD-ROM device back to auto-detect to eject // Change the CD-ROM device back to auto-detect to eject
vmxData[filenameKey] = "auto detect" vmxData[filenameKey] = "auto detect"
vmxData[match+"devicetype"] = "cdrom-raw" vmxData[match+"devicetype"] = "cdrom-raw"
}
} }
} }
} }
// Rewrite the VMX // Rewrite the VMX
if err := vmwcommon.WriteVMX(vmxPath, vmxData); err != nil { if err := WriteVMX(vmxPath, vmxData); err != nil {
state.Put("error", fmt.Errorf("Error writing VMX: %s", err)) state.Put("error", fmt.Errorf("Error writing VMX: %s", err))
return multistep.ActionHalt return multistep.ActionHalt
} }
...@@ -75,19 +75,4 @@ func (s stepCleanVMX) Run(state multistep.StateBag) multistep.StepAction { ...@@ -75,19 +75,4 @@ func (s stepCleanVMX) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionContinue return multistep.ActionContinue
} }
func (stepCleanVMX) Cleanup(multistep.StateBag) {} func (StepCleanVMX) Cleanup(multistep.StateBag) {}
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 vmwcommon.ParseVMX(string(vmxBytes)), nil
}
package common
import (
"io/ioutil"
"os"
"testing"
"github.com/mitchellh/multistep"
)
func TestStepCleanVMX_impl(t *testing.T) {
var _ multistep.Step = new(StepCleanVMX)
}
func TestStepCleanVMX(t *testing.T) {
state := testState(t)
step := new(StepCleanVMX)
vmxPath := testVMXFile(t)
defer os.Remove(vmxPath)
state.Put("vmx_path", vmxPath)
// Test the run
if action := step.Run(state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); ok {
t.Fatal("should NOT have error")
}
}
func TestStepCleanVMX_floppyPath(t *testing.T) {
state := testState(t)
step := new(StepCleanVMX)
vmxPath := testVMXFile(t)
defer os.Remove(vmxPath)
if err := ioutil.WriteFile(vmxPath, []byte(testVMXFloppyPath), 0644); err != nil {
t.Fatalf("err: %s", err)
}
state.Put("floppy_path", "foo")
state.Put("vmx_path", vmxPath)
// Test the run
if action := step.Run(state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); ok {
t.Fatal("should NOT have error")
}
// Test the resulting data
vmxContents, err := ioutil.ReadFile(vmxPath)
if err != nil {
t.Fatalf("err: %s", err)
}
vmxData := ParseVMX(string(vmxContents))
cases := []struct {
Key string
Value string
}{
{"floppy0.present", "FALSE"},
{"floppy0.filetype", ""},
{"floppy0.filename", ""},
}
for _, tc := range cases {
if tc.Value == "" {
if _, ok := vmxData[tc.Key]; ok {
t.Fatalf("should not have key: %s", tc.Key)
}
} else {
if vmxData[tc.Key] != tc.Value {
t.Fatalf("bad: %s %#v", tc.Key, vmxData[tc.Key])
}
}
}
}
func TestStepCleanVMX_isoPath(t *testing.T) {
state := testState(t)
step := new(StepCleanVMX)
vmxPath := testVMXFile(t)
defer os.Remove(vmxPath)
if err := ioutil.WriteFile(vmxPath, []byte(testVMXISOPath), 0644); err != nil {
t.Fatalf("err: %s", err)
}
state.Put("iso_path", "foo")
state.Put("vmx_path", vmxPath)
// Test the run
if action := step.Run(state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); ok {
t.Fatal("should NOT have error")
}
// Test the resulting data
vmxContents, err := ioutil.ReadFile(vmxPath)
if err != nil {
t.Fatalf("err: %s", err)
}
vmxData := ParseVMX(string(vmxContents))
cases := []struct {
Key string
Value string
}{
{"ide0:0.filename", "auto detect"},
{"ide0:0.devicetype", "cdrom-raw"},
{"ide0:1.filename", "bar"},
{"foo", "bar"},
}
for _, tc := range cases {
if tc.Value == "" {
if _, ok := vmxData[tc.Key]; ok {
t.Fatalf("should not have key: %s", tc.Key)
}
} else {
if vmxData[tc.Key] != tc.Value {
t.Fatalf("bad: %s %#v", tc.Key, vmxData[tc.Key])
}
}
}
}
const testVMXFloppyPath = `
floppy0.present = "TRUE"
floppy0.filetype = "file"
`
const testVMXISOPath = `
ide0:0.filename = "foo"
ide0:1.filename = "bar"
foo = "bar"
`
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"log" "log"
"os" "os"
"regexp" "regexp"
...@@ -68,3 +69,13 @@ func WriteVMX(path string, data map[string]string) (err error) { ...@@ -68,3 +69,13 @@ func WriteVMX(path string, data map[string]string) (err error) {
return return
} }
// ReadVMX takes a path to a VMX file and reads it into a k/v mapping.
func ReadVMX(path string) (map[string]string, error) {
data, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
return ParseVMX(string(data)), nil
}
...@@ -412,7 +412,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -412,7 +412,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
&common.StepProvision{}, &common.StepProvision{},
&stepShutdown{}, &stepShutdown{},
&vmwcommon.StepCleanFiles{}, &vmwcommon.StepCleanFiles{},
&stepCleanVMX{}, &vmwcommon.StepCleanVMX{},
&stepCompactDisk{}, &stepCompactDisk{},
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment