Merge pull request #205 from sit/preserve-cache-suffix

Preserve suffix of files put in the cache.
This commit is contained in:
Mitchell Hashimoto 2013-07-20 16:40:31 -07:00
commit d999d1c5dd
3 changed files with 29 additions and 50 deletions

View File

@ -6,11 +6,7 @@ import (
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
"github.com/mitchellh/packer/builder/common" "github.com/mitchellh/packer/builder/common"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"io"
"io/ioutil"
"log" "log"
"os"
"path/filepath"
"time" "time"
) )
@ -23,11 +19,9 @@ import (
// //
// Produces: // Produces:
// iso_path string // iso_path string
type stepDownloadISO struct { type stepDownloadISO struct{}
isoCopyDir string
}
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) cache := state["cache"].(packer.Cache)
config := state["config"].(*config) config := state["config"].(*config)
ui := state["ui"].(packer.Ui) 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) log.Printf("Path to ISO on disk: %s", cachePath)
state["iso_path"] = f.Name() state["iso_path"] = cachePath
return multistep.ActionContinue return multistep.ActionContinue
} }
func (s *stepDownloadISO) Cleanup(map[string]interface{}) { func (stepDownloadISO) Cleanup(map[string]interface{}) {}
if s.isoCopyDir != "" {
os.RemoveAll(s.isoCopyDir)
}
}

View File

@ -4,6 +4,7 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"path/filepath" "path/filepath"
"regexp"
"sync" "sync"
) )
@ -14,6 +15,9 @@ type Cache interface {
// Packer guarantees that no other process will write to this file while // Packer guarantees that no other process will write to this file while
// the lock is held. // 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. // The cache will block and wait for the lock.
Lock(string) string Lock(string) string
@ -44,7 +48,7 @@ func (f *FileCache) Lock(key string) string {
rw := f.rwLock(hashKey) rw := f.rwLock(hashKey)
rw.Lock() rw.Lock()
return filepath.Join(f.CacheDir, hashKey) return f.cachePath(key, hashKey)
} }
func (f *FileCache) Unlock(key string) { func (f *FileCache) Unlock(key string) {
@ -58,7 +62,7 @@ func (f *FileCache) RLock(key string) (string, bool) {
rw := f.rwLock(hashKey) rw := f.rwLock(hashKey)
rw.RLock() rw.RLock()
return filepath.Join(f.CacheDir, hashKey), true return f.cachePath(key, hashKey), true
} }
func (f *FileCache) RUnlock(key string) { func (f *FileCache) RUnlock(key string) {
@ -67,6 +71,16 @@ func (f *FileCache) RUnlock(key string) {
rw.RUnlock() rw.RUnlock()
} }
func (f *FileCache) cachePath(key string, hashKey string) string {
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 { func (f *FileCache) hashKey(key string) string {
sha := sha256.New() sha := sha256.New()
sha.Write([]byte(key)) sha.Write([]byte(key))

View File

@ -3,6 +3,7 @@ package packer
import ( import (
"io/ioutil" "io/ioutil"
"os" "os"
"strings"
"testing" "testing"
) )
@ -36,19 +37,23 @@ func TestFileCache(t *testing.T) {
defer os.RemoveAll(cacheDir) defer os.RemoveAll(cacheDir)
cache := &FileCache{CacheDir: 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) err = ioutil.WriteFile(path, []byte("data"), 0666)
if err != nil { if err != nil {
t.Fatalf("error writing: %s", err) 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 { if !ok {
t.Fatal("cache says key doesn't exist") t.Fatal("cache says key doesn't exist")
} }
defer cache.RUnlock("foo") defer cache.RUnlock("foo.iso")
data, err := ioutil.ReadFile(path) data, err := ioutil.ReadFile(path)
if err != nil { if err != nil {