Merge pull request #619 from dougm/esx-paths

builder/vmware: Path related fixes in esx5 driver
This commit is contained in:
Mitchell Hashimoto 2013-11-18 15:56:15 -08:00
commit 1d3038ddf2
5 changed files with 92 additions and 51 deletions

View File

@ -10,7 +10,6 @@ import (
"log" "log"
"math/rand" "math/rand"
"os" "os"
"path/filepath"
"strings" "strings"
"text/template" "text/template"
"time" "time"
@ -459,20 +458,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
} }
// Compile the artifact list // Compile the artifact list
files := make([]string, 0, 10) files, err := state.Get("dir").(OutputDir).ListFiles()
visit := func(path string, info os.FileInfo, err error) error { if err != nil {
if err != nil {
return err
}
if !info.IsDir() {
files = append(files, path)
}
return nil
}
if err := filepath.Walk(b.config.OutputDir, visit); err != nil {
return nil, err return nil, err
} }

View File

@ -1,6 +1,7 @@
package vmware package vmware
import ( import (
"bufio"
"bytes" "bytes"
gossh "code.google.com/p/go.crypto/ssh" gossh "code.google.com/p/go.crypto/ssh"
"encoding/csv" "encoding/csv"
@ -42,7 +43,7 @@ func (d *ESX5Driver) CreateDisk(diskPathLocal string, size string, typeId string
} }
func (d *ESX5Driver) IsRunning(vmxPathLocal string) (bool, error) { 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) state, err := d.run(nil, "vim-cmd", "vmsvc/power.getstate", vmxPath)
if err != nil { if err != nil {
return false, err return false, err
@ -84,11 +85,11 @@ func (d *ESX5Driver) UploadISO(localPath string) (string, error) {
return "", err 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 return "", err
} }
finalPath := d.datastorePath(targetFile)
if err := d.upload(finalPath, localPath); err != nil { if err := d.upload(finalPath, localPath); err != nil {
return "", err return "", err
} }
@ -214,10 +215,37 @@ func (d *ESX5Driver) DirExists() (bool, error) {
return err == nil, nil 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 { func (d *ESX5Driver) MkdirAll() error {
return d.mkdir(d.outputDir) return d.mkdir(d.outputDir)
} }
func (d *ESX5Driver) Remove(path string) error {
return d.sh("rm", path)
}
func (d *ESX5Driver) RemoveAll() error { func (d *ESX5Driver) RemoveAll() error {
return d.sh("rm", "-rf", d.outputDir) return d.sh("rm", "-rf", d.outputDir)
} }

View File

@ -2,6 +2,7 @@ package vmware
import ( import (
"os" "os"
"path/filepath"
) )
// OutputDir is an interface type that abstracts the creation and handling // OutputDir is an interface type that abstracts the creation and handling
@ -10,7 +11,9 @@ import (
// VMware products as well as local. // VMware products as well as local.
type OutputDir interface { type OutputDir interface {
DirExists() (bool, error) DirExists() (bool, error)
ListFiles() ([]string, error)
MkdirAll() error MkdirAll() error
Remove(string) error
RemoveAll() error RemoveAll() error
SetOutputDir(string) SetOutputDir(string)
} }
@ -26,10 +29,30 @@ func (d *localOutputDir) DirExists() (bool, error) {
return err == nil, nil 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 { func (d *localOutputDir) MkdirAll() error {
return os.MkdirAll(d.dir, 0755) return os.MkdirAll(d.dir, 0755)
} }
func (d *localOutputDir) Remove(path string) error {
return os.Remove(path)
}
func (d *localOutputDir) RemoveAll() error { func (d *localOutputDir) RemoveAll() error {
return os.RemoveAll(d.dir) return os.RemoveAll(d.dir)
} }

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"os"
"path/filepath" "path/filepath"
) )
@ -16,7 +15,7 @@ var KeepFileExtensions = []string{".nvram", ".vmdk", ".vmsd", ".vmx", ".vmxf"}
// This step removes unnecessary files from the final result. // This step removes unnecessary files from the final result.
// //
// Uses: // Uses:
// config *config // dir OutputDir
// ui packer.Ui // ui packer.Ui
// //
// Produces: // Produces:
@ -24,41 +23,37 @@ var KeepFileExtensions = []string{".nvram", ".vmdk", ".vmsd", ".vmx", ".vmxf"}
type stepCleanFiles struct{} type stepCleanFiles struct{}
func (stepCleanFiles) Run(state multistep.StateBag) multistep.StepAction { 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 := state.Get("ui").(packer.Ui)
ui.Say("Deleting unnecessary VMware files...") ui.Say("Deleting unnecessary VMware files...")
visit := func(path string, info os.FileInfo, err error) error { files, err := dir.ListFiles()
if err != nil { 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 {
state.Put("error", err) state.Put("error", err)
return multistep.ActionHalt 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 return multistep.ActionContinue
} }

View File

@ -1,6 +1,7 @@
package vmware package vmware
import ( import (
"fmt"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"log" "log"
@ -24,9 +25,14 @@ func (s *stepPrepareOutputDir) Run(state multistep.StateBag) multistep.StepActio
return multistep.ActionHalt return multistep.ActionHalt
} }
if exists && config.PackerForce { if exists {
ui.Say("Deleting previous output directory...") if config.PackerForce {
dir.RemoveAll() 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 { if err := dir.MkdirAll(); err != nil {
@ -36,6 +42,8 @@ func (s *stepPrepareOutputDir) Run(state multistep.StateBag) multistep.StepActio
s.dir = dir s.dir = dir
state.Put("dir", dir)
return multistep.ActionContinue return multistep.ActionContinue
} }