From 9655be55822ed18c5039ca6e35bdabafc2ef456a Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Mon, 11 Nov 2013 15:51:30 -0800 Subject: [PATCH 1/3] builder/vmware: Path related fixes in esx5 driver - Fix mkdir of packer_cache in ESX5Driver.UploadISO - Fix vmx path in ESX5Driver.IsRunning --- builder/vmware/driver_esx5.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/vmware/driver_esx5.go b/builder/vmware/driver_esx5.go index 92fca7f3c..cdf8df3bf 100644 --- a/builder/vmware/driver_esx5.go +++ b/builder/vmware/driver_esx5.go @@ -42,7 +42,7 @@ func (d *ESX5Driver) CreateDisk(diskPathLocal string, size string, typeId string } func (d *ESX5Driver) IsRunning(vmxPathLocal string) (bool, error) { - vmxPath := d.datastorePath(vmxPathLocal) + vmxPath := filepath.Join(d.outputDir, filepath.Base(vmxPathLocal)) state, err := d.run(nil, "vim-cmd", "vmsvc/power.getstate", vmxPath) if err != nil { return false, err @@ -84,11 +84,11 @@ func (d *ESX5Driver) UploadISO(localPath string) (string, error) { return "", err } - if err := d.mkdir(filepath.Dir(targetFile)); err != nil { + finalPath := d.datastorePath(targetFile) + if err := d.mkdir(filepath.Dir(finalPath)); err != nil { return "", err } - finalPath := d.datastorePath(targetFile) if err := d.upload(finalPath, localPath); err != nil { return "", err } From 3f5a02cf2a9dc032725c9280f43f81f80eb1e3cb Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Tue, 12 Nov 2013 12:49:57 -0800 Subject: [PATCH 2/3] builder/vmware: Add ListFiles and Remove methods to OutputDir interface - Fixes builder/vmware when using RemoteType esx5, as there is no longer a local OutputDir --- builder/vmware/builder.go | 17 +------ builder/vmware/driver_esx5.go | 28 ++++++++++++ builder/vmware/output_dir.go | 23 ++++++++++ builder/vmware/step_clean_files.go | 55 +++++++++++------------ builder/vmware/step_prepare_output_dir.go | 2 + 5 files changed, 80 insertions(+), 45 deletions(-) diff --git a/builder/vmware/builder.go b/builder/vmware/builder.go index 786a9d1e9..4d76a2b57 100644 --- a/builder/vmware/builder.go +++ b/builder/vmware/builder.go @@ -10,7 +10,6 @@ import ( "log" "math/rand" "os" - "path/filepath" "strings" "text/template" "time" @@ -459,20 +458,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe } // Compile the artifact list - files := make([]string, 0, 10) - visit := func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if !info.IsDir() { - files = append(files, path) - } - - return nil - } - - if err := filepath.Walk(b.config.OutputDir, visit); err != nil { + files, err := state.Get("dir").(OutputDir).ListFiles() + if err != nil { return nil, err } diff --git a/builder/vmware/driver_esx5.go b/builder/vmware/driver_esx5.go index cdf8df3bf..825092abd 100644 --- a/builder/vmware/driver_esx5.go +++ b/builder/vmware/driver_esx5.go @@ -1,6 +1,7 @@ package vmware import ( + "bufio" "bytes" gossh "code.google.com/p/go.crypto/ssh" "encoding/csv" @@ -214,10 +215,37 @@ func (d *ESX5Driver) DirExists() (bool, error) { return err == nil, nil } +func (d *ESX5Driver) ListFiles() ([]string, error) { + stdout, err := d.ssh("ls -1p "+d.outputDir, nil) + if err != nil { + return nil, err + } + + files := make([]string, 0, 10) + reader := bufio.NewReader(stdout) + for { + line, _, err := reader.ReadLine() + if err == io.EOF { + break + } + if line[len(line)-1] == '/' { + continue + } + + files = append(files, filepath.Join(d.outputDir, string(line))) + } + + return files, nil +} + func (d *ESX5Driver) MkdirAll() error { return d.mkdir(d.outputDir) } +func (d *ESX5Driver) Remove(path string) error { + return d.sh("rm", path) +} + func (d *ESX5Driver) RemoveAll() error { return d.sh("rm", "-rf", d.outputDir) } diff --git a/builder/vmware/output_dir.go b/builder/vmware/output_dir.go index 3b38e14ab..c88e3f41b 100644 --- a/builder/vmware/output_dir.go +++ b/builder/vmware/output_dir.go @@ -2,6 +2,7 @@ package vmware import ( "os" + "path/filepath" ) // OutputDir is an interface type that abstracts the creation and handling @@ -10,7 +11,9 @@ import ( // VMware products as well as local. type OutputDir interface { DirExists() (bool, error) + ListFiles() ([]string, error) MkdirAll() error + Remove(string) error RemoveAll() error SetOutputDir(string) } @@ -26,10 +29,30 @@ func (d *localOutputDir) DirExists() (bool, error) { return err == nil, nil } +func (d *localOutputDir) ListFiles() ([]string, error) { + files := make([]string, 0, 10) + + visit := func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if !info.IsDir() { + files = append(files, path) + } + return nil + } + + return files, filepath.Walk(d.dir, visit) +} + func (d *localOutputDir) MkdirAll() error { return os.MkdirAll(d.dir, 0755) } +func (d *localOutputDir) Remove(path string) error { + return os.Remove(path) +} + func (d *localOutputDir) RemoveAll() error { return os.RemoveAll(d.dir) } diff --git a/builder/vmware/step_clean_files.go b/builder/vmware/step_clean_files.go index f429b4464..cf78d45dc 100644 --- a/builder/vmware/step_clean_files.go +++ b/builder/vmware/step_clean_files.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" - "os" "path/filepath" ) @@ -16,7 +15,7 @@ var KeepFileExtensions = []string{".nvram", ".vmdk", ".vmsd", ".vmx", ".vmxf"} // This step removes unnecessary files from the final result. // // Uses: -// config *config +// dir OutputDir // ui packer.Ui // // Produces: @@ -24,41 +23,37 @@ var KeepFileExtensions = []string{".nvram", ".vmdk", ".vmsd", ".vmx", ".vmxf"} type stepCleanFiles struct{} func (stepCleanFiles) Run(state multistep.StateBag) multistep.StepAction { - config := state.Get("config").(*config) + dir := state.Get("dir").(OutputDir) ui := state.Get("ui").(packer.Ui) ui.Say("Deleting unnecessary VMware files...") - visit := func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if !info.IsDir() { - // If the file isn't critical to the function of the - // virtual machine, we get rid of it. - keep := false - ext := filepath.Ext(path) - for _, goodExt := range KeepFileExtensions { - if goodExt == ext { - keep = true - break - } - } - - if !keep { - ui.Message(fmt.Sprintf("Deleting: %s", path)) - return os.Remove(path) - } - } - - return nil - } - - if err := filepath.Walk(config.OutputDir, visit); err != nil { + files, err := dir.ListFiles() + if err != nil { state.Put("error", err) return multistep.ActionHalt } + for _, path := range files { + // If the file isn't critical to the function of the + // virtual machine, we get rid of it. + keep := false + ext := filepath.Ext(path) + for _, goodExt := range KeepFileExtensions { + if goodExt == ext { + keep = true + break + } + } + + if !keep { + ui.Message(fmt.Sprintf("Deleting: %s", path)) + if err = dir.Remove(path); err != nil { + state.Put("error", err) + return multistep.ActionHalt + } + } + } + return multistep.ActionContinue } diff --git a/builder/vmware/step_prepare_output_dir.go b/builder/vmware/step_prepare_output_dir.go index f4b31fb4b..ae5a3ba80 100644 --- a/builder/vmware/step_prepare_output_dir.go +++ b/builder/vmware/step_prepare_output_dir.go @@ -36,6 +36,8 @@ func (s *stepPrepareOutputDir) Run(state multistep.StateBag) multistep.StepActio s.dir = dir + state.Put("dir", dir) + return multistep.ActionContinue } From 4af1c7f1b2588452004c306de59290f4b001ebd2 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Tue, 12 Nov 2013 13:11:02 -0800 Subject: [PATCH 3/3] builder/vmware: Double check that OutputDirectory does not already exist The initial check in Builder.Prepare does not use the OutputDir interface. stepPrepareOutputDir also checks if OutputDir exists, error out there unless using -force so we get the same behavior when RemoteType is esx5. --- builder/vmware/step_prepare_output_dir.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/builder/vmware/step_prepare_output_dir.go b/builder/vmware/step_prepare_output_dir.go index ae5a3ba80..bd5ae45b8 100644 --- a/builder/vmware/step_prepare_output_dir.go +++ b/builder/vmware/step_prepare_output_dir.go @@ -1,6 +1,7 @@ package vmware import ( + "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" "log" @@ -24,9 +25,14 @@ func (s *stepPrepareOutputDir) Run(state multistep.StateBag) multistep.StepActio return multistep.ActionHalt } - if exists && config.PackerForce { - ui.Say("Deleting previous output directory...") - dir.RemoveAll() + if exists { + if config.PackerForce { + ui.Say("Deleting previous output directory...") + dir.RemoveAll() + } else { + state.Put("error", fmt.Errorf("Output directory '%s' already exists.", config.OutputDir)) + return multistep.ActionHalt + } } if err := dir.MkdirAll(); err != nil {