Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/stacker/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func GetBase(o BaseLayerOpts) error {
return err
}

_, err := acquireUrl(o.Config, o.Storage, o.Layer.From.Url, cacheDir, "", "", nil, -1, -1, o.Progress)
_, _, err := acquireUrl(o.Config, o.Storage, o.Layer.From.Url, cacheDir, "", "", nil, -1, -1, o.Progress)
return err
/* now we can do all the containers/image types */
case types.OCILayer:
Expand Down
63 changes: 39 additions & 24 deletions pkg/stacker/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,26 @@ func filesDiffer(p1 string, info1 os.FileInfo, p2 string, info2 os.FileInfo) (bo
return !eq, nil
}

func verifyImportFileHash(imp string, hash string) error {
if len(hash) == 0 {
return nil
}
// check that the file's hash matches the given hash.
// If the given hash is "", that is treated as a match.
// always return the actual hash.
func verifyImportFileHash(imp string, hash string) (string, error) {
actualHash, err := lib.HashFile(imp, false)
if err != nil {
return err
return actualHash, err
}

actualHash = strings.TrimPrefix(actualHash, "sha256:")
if len(hash) == 0 {
return actualHash, nil
}

if actualHash != strings.ToLower(hash) {
return errors.Errorf("The requested hash of %s import is different than the actual hash: %s != %s",
return actualHash, errors.Errorf("The requested hash of %s import is different than the actual hash: %s != %s",
imp, hash, actualHash)
}

return nil
return actualHash, nil
}

func importFile(imp string, cacheDir string, hash string, idest string, mode *fs.FileMode, uid, gid int) (string, error) {
Expand All @@ -92,7 +96,7 @@ func importFile(imp string, cacheDir string, hash string, idest string, mode *fs
}

if !e1.IsDir() {
err := verifyImportFileHash(imp, hash)
_, err := verifyImportFileHash(imp, hash)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -240,22 +244,25 @@ func validateHash(hash string) error {
return nil
}

// downloads or copies import url depending on scheme, and returns the path and
// hash of the downloaded file
func acquireUrl(c types.StackerConfig, storage types.Storage, i string, cache string, expectedHash string,
idest string, mode *fs.FileMode, uid, gid int, progress bool,
) (string, error) {
) (string, string, error) {
url, err := types.NewDockerishUrl(i)
if err != nil {
return "", err
return "", "", err
}

// validate the given hash
if err = validateHash(expectedHash); err != nil {
return "", err
return "", "", err
}

// It's just a path, let's copy it to .stacker.
if url.Scheme == "" {
return importFile(i, cache, expectedHash, idest, mode, uid, gid)
path, err := importFile(i, cache, expectedHash, idest, mode, uid, gid)
return path, "", err
} else if url.Scheme == "http" || url.Scheme == "https" {
// otherwise, we need to download it
// first verify the hashes
Expand All @@ -268,10 +275,11 @@ func acquireUrl(c types.StackerConfig, storage types.Storage, i string, cache st
log.Debugf("Remote file: hash: %s length: %s", remoteHash, remoteSize)
// verify if the given hash from stackerfile matches the remote one.
if len(expectedHash) > 0 && len(remoteHash) > 0 && strings.ToLower(expectedHash) != remoteHash {
return "", errors.Errorf("The requested hash of %s import is different than the actual hash: %s != %s",
return "", "", errors.Errorf("The requested hash of %s import is different than the actual hash: %s != %s",
i, expectedHash, remoteHash)
}
return Download(cache, i, progress, expectedHash, remoteHash, remoteSize, idest, mode, uid, gid)
path, err := Download(cache, i, progress, expectedHash, remoteHash, remoteSize, idest, mode, uid, gid)
return path, remoteHash, err
} else if url.Scheme == "stacker" {
// we always Grab() things from stacker://, because we need to
// mount the container's rootfs to get them and don't
Expand All @@ -280,23 +288,19 @@ func acquireUrl(c types.StackerConfig, storage types.Storage, i string, cache st
p := path.Join(cache, path.Base(url.Path))
snap, cleanup, err := storage.TemporaryWritableSnapshot(url.Host)
if err != nil {
return "", err
return "", "", err
}
defer cleanup()
err = Grab(c, storage, snap, url.Path, cache, idest, mode, uid, gid)
if err != nil {
return "", err
return "", "", err
}

err = verifyImportFileHash(p, expectedHash)
if err != nil {
return "", err
}

return p, nil
// return "" as the hash, it is not checked
return p, "", nil
}

return "", errors.Errorf("unsupported url scheme %s", i)
return "", "", errors.Errorf("unsupported url scheme %s", i)
}

func CleanImportsDir(c types.StackerConfig, name string, imports types.Imports, cache *BuildCache) error {
Expand Down Expand Up @@ -360,6 +364,7 @@ func Import(c types.StackerConfig, storage types.Storage, name string, imports t
return errors.Wrapf(err, "couldn't read existing directory")
}

importHashes := map[string]string{}
for _, i := range imports {
cache := dir

Expand All @@ -382,11 +387,16 @@ func Import(c types.StackerConfig, storage types.Storage, name string, imports t
cache = tmpdir
}

name, err := acquireUrl(c, storage, i.Path, cache, i.Hash, i.Dest, i.Mode, i.Uid, i.Gid, progress)
name, downloadedFileHash, err := acquireUrl(c, storage, i.Path, cache, i.Hash, i.Dest, i.Mode, i.Uid, i.Gid, progress)
if err != nil {
return err
}

// "" is returned for local files, ignore they won't be checked anyway
if downloadedFileHash != "" {
importHashes[i.Path] = downloadedFileHash
}

for i, ext := range existing {
if ext.Name() == path.Base(name) {
existing = append(existing[:i], existing[i+1:]...)
Expand All @@ -403,5 +413,10 @@ func Import(c types.StackerConfig, storage types.Storage, name string, imports t
}
}

log.Infof("imported file hashes (after substitutions):")
for path, hash := range importHashes {
log.Infof(" - path: %q\n hash: %q", path, hash)
}

return nil
}
16 changes: 10 additions & 6 deletions pkg/stacker/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,21 @@ func Download(cacheDir string, url string, progress bool, expectedHash, remoteHa
if err != nil {
return "", err
}
if expectedHash != "" {
log.Infof("Checking shasum of downloaded file")

downloadHash, err := lib.HashFile(name, false)
if err != nil {
return "", err
}
downloadHash, err := lib.HashFile(name, false)
if err != nil {
return "", err
}

if expectedHash != "" {
log.Infof("Checking shasum of downloaded file")
downloadHash = strings.TrimPrefix(downloadHash, "sha256:")
log.Debugf("Downloaded file hash: %s", downloadHash)

if downloadHash != remoteHash {
log.Warnf("Downloaded file hash %q does not match hash from HTTP header %q", downloadHash, remoteHash)
}

if expectedHash != downloadHash {
os.RemoveAll(name)
return "", errors.Errorf("Downloaded file hash does not match. Expected: %s Actual: %s", expectedHash, downloadHash)
Expand Down