From fd1ec31a1dcf1dc38fbb59fd01405c82fdd90511 Mon Sep 17 00:00:00 2001 From: Emil Sit Date: Sat, 20 Jul 2013 00:15:14 -0400 Subject: [PATCH 1/3] packer/cache: Extract cache path calculation to method --- packer/cache.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packer/cache.go b/packer/cache.go index 6f8d14134..6c2ed0207 100644 --- a/packer/cache.go +++ b/packer/cache.go @@ -44,7 +44,7 @@ func (f *FileCache) Lock(key string) string { rw := f.rwLock(hashKey) rw.Lock() - return filepath.Join(f.CacheDir, hashKey) + return f.cachePath(key, hashKey) } func (f *FileCache) Unlock(key string) { @@ -58,7 +58,7 @@ func (f *FileCache) RLock(key string) (string, bool) { rw := f.rwLock(hashKey) rw.RLock() - return filepath.Join(f.CacheDir, hashKey), true + return f.cachePath(key, hashKey), true } func (f *FileCache) RUnlock(key string) { @@ -67,6 +67,10 @@ func (f *FileCache) RUnlock(key string) { rw.RUnlock() } +func (f *FileCache) cachePath(key string, hashKey string) string { + return filepath.Join(f.CacheDir, hashKey) +} + func (f *FileCache) hashKey(key string) string { sha := sha256.New() sha.Write([]byte(key)) From 27da543a41dd2ce01cb0532ea9a615c0f8be2de7 Mon Sep 17 00:00:00 2001 From: Emil Sit Date: Sat, 20 Jul 2013 00:19:05 -0400 Subject: [PATCH 2/3] packer/cache: Preserve any extension found on keys This allows us to hand cache paths to any programs that may want to interpret file extensions in order to behave differently. For example, VirtualBox may want ISO images to end with .iso. --- packer/cache.go | 12 +++++++++++- packer/cache_test.go | 13 +++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/packer/cache.go b/packer/cache.go index 6c2ed0207..9d69f0c56 100644 --- a/packer/cache.go +++ b/packer/cache.go @@ -4,6 +4,7 @@ import ( "crypto/sha256" "encoding/hex" "path/filepath" + "regexp" "sync" ) @@ -14,6 +15,9 @@ type Cache interface { // Packer guarantees that no other process will write to this file while // the lock is held. // + // If the key has an extension (e.g., file.ext), the resulting path + // will have that extension as well. + // // The cache will block and wait for the lock. Lock(string) string @@ -68,7 +72,13 @@ func (f *FileCache) RUnlock(key string) { } func (f *FileCache) cachePath(key string, hashKey string) string { - return filepath.Join(f.CacheDir, hashKey) + var suffixPattern = regexp.MustCompile(`(\.\w+)$`) + matches := suffixPattern.FindStringSubmatch(key) + suffix := "" + if matches != nil { + suffix = matches[0] + } + return filepath.Join(f.CacheDir, hashKey+suffix) } func (f *FileCache) hashKey(key string) string { diff --git a/packer/cache_test.go b/packer/cache_test.go index 1be344ecc..5fe6f50d0 100644 --- a/packer/cache_test.go +++ b/packer/cache_test.go @@ -3,6 +3,7 @@ package packer import ( "io/ioutil" "os" + "strings" "testing" ) @@ -36,19 +37,23 @@ func TestFileCache(t *testing.T) { defer os.RemoveAll(cacheDir) cache := &FileCache{CacheDir: cacheDir} - path := cache.Lock("foo") + path := cache.Lock("foo.iso") + + if !strings.HasSuffix(path, ".iso") { + t.Fatalf("path doesn't end with suffix '%s': '%s'", ".iso", path) + } err = ioutil.WriteFile(path, []byte("data"), 0666) if err != nil { t.Fatalf("error writing: %s", err) } - cache.Unlock("foo") + cache.Unlock("foo.iso") - path, ok := cache.RLock("foo") + path, ok := cache.RLock("foo.iso") if !ok { t.Fatal("cache says key doesn't exist") } - defer cache.RUnlock("foo") + defer cache.RUnlock("foo.iso") data, err := ioutil.ReadFile(path) if err != nil { From bc4b2d079d5a27838176ef07ac850e342ae8d756 Mon Sep 17 00:00:00 2001 From: Emil Sit Date: Sat, 20 Jul 2013 00:26:46 -0400 Subject: [PATCH 3/3] Revert "builder/virtualbox: Copy ISO because VirtualBox can't recognize" This reverts commit 688be43811007d33b9c70dec93b43782a4f71c06; instead of copying the ISO (which can be huge), we have adjusted the cache path to include the extension of the source file. Conflicts: builder/virtualbox/step_download_iso.go --- builder/virtualbox/step_download_iso.go | 48 +++---------------------- 1 file changed, 4 insertions(+), 44 deletions(-) diff --git a/builder/virtualbox/step_download_iso.go b/builder/virtualbox/step_download_iso.go index 62a3a8d21..40553dca2 100644 --- a/builder/virtualbox/step_download_iso.go +++ b/builder/virtualbox/step_download_iso.go @@ -6,11 +6,7 @@ import ( "github.com/mitchellh/multistep" "github.com/mitchellh/packer/builder/common" "github.com/mitchellh/packer/packer" - "io" - "io/ioutil" "log" - "os" - "path/filepath" "time" ) @@ -23,11 +19,9 @@ import ( // // Produces: // iso_path string -type stepDownloadISO struct { - isoCopyDir string -} +type stepDownloadISO struct{} -func (s *stepDownloadISO) Run(state map[string]interface{}) multistep.StepAction { +func (s stepDownloadISO) Run(state map[string]interface{}) multistep.StepAction { cache := state["cache"].(packer.Cache) config := state["config"].(*config) ui := state["ui"].(packer.Ui) @@ -84,44 +78,10 @@ DownloadWaitLoop: } } - // VirtualBox is really dumb and can't figure out that the file is an - // ISO unless it has a ".iso" extension. We can't modify the cache - // filenames so we just do a copy. - tempdir, err := ioutil.TempDir("", "packer") - if err != nil { - state["error"] = fmt.Errorf("Error copying ISO: %s", err) - return multistep.ActionHalt - } - s.isoCopyDir = tempdir - - f, err := os.Create(filepath.Join(tempdir, "image.iso")) - if err != nil { - state["error"] = fmt.Errorf("Error copying ISO: %s", err) - return multistep.ActionHalt - } - defer f.Close() - - sourceF, err := os.Open(cachePath) - if err != nil { - state["error"] = fmt.Errorf("Error copying ISO: %s", err) - return multistep.ActionHalt - } - defer sourceF.Close() - - log.Printf("Copying ISO to temp location: %s", tempdir) - if _, err := io.Copy(f, sourceF); err != nil { - state["error"] = fmt.Errorf("Error copying ISO: %s", err) - return multistep.ActionHalt - } - log.Printf("Path to ISO on disk: %s", cachePath) - state["iso_path"] = f.Name() + state["iso_path"] = cachePath return multistep.ActionContinue } -func (s *stepDownloadISO) Cleanup(map[string]interface{}) { - if s.isoCopyDir != "" { - os.RemoveAll(s.isoCopyDir) - } -} +func (stepDownloadISO) Cleanup(map[string]interface{}) {}