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/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{}) {}

View File

@ -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
@ -44,7 +48,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 +62,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 +71,16 @@ func (f *FileCache) RUnlock(key string) {
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 {
sha := sha256.New()
sha.Write([]byte(key))

View File

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