builder/vmware: support floppy_files for mounting a floppy disk

This commit is contained in:
Mitchell Hashimoto 2013-07-08 20:56:23 -07:00
parent c8019f10e6
commit 9ec94fc6a1
5 changed files with 130 additions and 5 deletions

View File

@ -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 {

View File

@ -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{},
}

View File

@ -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()

View File

@ -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:
// <nothing>
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
}

View File

@ -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)