mirror of
https://github.com/containers/podman.git
synced 2025-12-01 18:49:18 +08:00
Bump to Buildah v1.41.0
Bump Buildah to v1.41.0 in preparation for Podman v5.6 Signed-off-by: tomsweeneyredhat <tsweeney@redhat.com>
This commit is contained in:
136
vendor/github.com/containers/buildah/add.go
generated
vendored
136
vendor/github.com/containers/buildah/add.go
generated
vendored
@@ -33,6 +33,7 @@ import (
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/moby/sys/userns"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@@ -102,6 +103,15 @@ type AddAndCopyOptions struct {
|
||||
Parents bool
|
||||
// Timestamp is a timestamp to override on all content as it is being read.
|
||||
Timestamp *time.Time
|
||||
// Link, when set to true, creates an independent layer containing the copied content
|
||||
// that sits on top of existing layers. This layer can be cached and reused
|
||||
// separately, and is not affected by filesystem changes from previous instructions.
|
||||
Link bool
|
||||
// BuildMetadata is consulted only when Link is true. Contains metadata used by
|
||||
// imagebuildah for cache evaluation of linked layers (inheritLabels, unsetAnnotations,
|
||||
// inheritAnnotations, newAnnotations). This field is internally managed and should
|
||||
// not be set by external API users.
|
||||
BuildMetadata string
|
||||
}
|
||||
|
||||
// gitURLFragmentSuffix matches fragments to use as Git reference and build
|
||||
@@ -495,15 +505,75 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
|
||||
}
|
||||
destUIDMap, destGIDMap := convertRuntimeIDMaps(b.IDMappingOptions.UIDMap, b.IDMappingOptions.GIDMap)
|
||||
|
||||
// Create the target directory if it doesn't exist yet.
|
||||
var putRoot, putDir, stagingDir string
|
||||
var createdDirs []string
|
||||
var latestTimestamp time.Time
|
||||
|
||||
mkdirOptions := copier.MkdirOptions{
|
||||
UIDMap: destUIDMap,
|
||||
GIDMap: destGIDMap,
|
||||
ChownNew: chownDirs,
|
||||
}
|
||||
if err := copier.Mkdir(mountPoint, extractDirectory, mkdirOptions); err != nil {
|
||||
return fmt.Errorf("ensuring target directory exists: %w", err)
|
||||
|
||||
// If --link is specified, we create a staging directory to hold the content
|
||||
// that will then become an independent layer
|
||||
if options.Link {
|
||||
containerDir, err := b.store.ContainerDirectory(b.ContainerID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting container directory for %q: %w", b.ContainerID, err)
|
||||
}
|
||||
|
||||
stagingDir, err = os.MkdirTemp(containerDir, "link-stage-")
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating staging directory for link %q: %w", b.ContainerID, err)
|
||||
}
|
||||
|
||||
putRoot = stagingDir
|
||||
|
||||
cleanDest := filepath.Clean(destination)
|
||||
|
||||
if strings.Contains(cleanDest, "..") {
|
||||
return fmt.Errorf("invalid destination path %q: contains path traversal", destination)
|
||||
}
|
||||
|
||||
if renameTarget != "" {
|
||||
putDir = filepath.Dir(filepath.Join(stagingDir, cleanDest))
|
||||
} else {
|
||||
putDir = filepath.Join(stagingDir, cleanDest)
|
||||
}
|
||||
|
||||
putDirAbs, err := filepath.Abs(putDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to resolve absolute path: %w", err)
|
||||
}
|
||||
|
||||
stagingDirAbs, err := filepath.Abs(stagingDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to resolve staging directory absolute path: %w", err)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(putDirAbs, stagingDirAbs+string(os.PathSeparator)) && putDirAbs != stagingDirAbs {
|
||||
return fmt.Errorf("destination path %q escapes staging directory", destination)
|
||||
}
|
||||
if err := copier.Mkdir(putRoot, putDirAbs, mkdirOptions); err != nil {
|
||||
return fmt.Errorf("ensuring target directory exists: %w", err)
|
||||
}
|
||||
tempPath := putDir
|
||||
for tempPath != stagingDir && tempPath != filepath.Dir(tempPath) {
|
||||
if _, err := os.Stat(tempPath); err == nil {
|
||||
createdDirs = append(createdDirs, tempPath)
|
||||
}
|
||||
tempPath = filepath.Dir(tempPath)
|
||||
}
|
||||
} else {
|
||||
if err := copier.Mkdir(mountPoint, extractDirectory, mkdirOptions); err != nil {
|
||||
return fmt.Errorf("ensuring target directory exists: %w", err)
|
||||
}
|
||||
|
||||
putRoot = extractDirectory
|
||||
putDir = extractDirectory
|
||||
}
|
||||
|
||||
// Copy each source in turn.
|
||||
for _, src := range sources {
|
||||
var multiErr *multierror.Error
|
||||
@@ -580,7 +650,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
|
||||
ChmodFiles: nil,
|
||||
IgnoreDevices: userns.RunningInUserNS(),
|
||||
}
|
||||
putErr = copier.Put(extractDirectory, extractDirectory, putOptions, io.TeeReader(pipeReader, hasher))
|
||||
putErr = copier.Put(putRoot, putDir, putOptions, io.TeeReader(pipeReader, hasher))
|
||||
}
|
||||
hashCloser.Close()
|
||||
pipeReader.Close()
|
||||
@@ -658,6 +728,9 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
|
||||
itemsCopied++
|
||||
}
|
||||
st := localSourceStat.Results[globbed]
|
||||
if options.Link && st.ModTime.After(latestTimestamp) {
|
||||
latestTimestamp = st.ModTime
|
||||
}
|
||||
pipeReader, pipeWriter := io.Pipe()
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
@@ -741,12 +814,13 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
|
||||
ChmodFiles: nil,
|
||||
IgnoreDevices: userns.RunningInUserNS(),
|
||||
}
|
||||
putErr = copier.Put(extractDirectory, extractDirectory, putOptions, io.TeeReader(pipeReader, hasher))
|
||||
putErr = copier.Put(putRoot, putDir, putOptions, io.TeeReader(pipeReader, hasher))
|
||||
}
|
||||
hashCloser.Close()
|
||||
pipeReader.Close()
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
if getErr != nil {
|
||||
getErr = fmt.Errorf("reading %q: %w", src, getErr)
|
||||
@@ -776,6 +850,58 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
|
||||
return fmt.Errorf("no items matching glob %q copied (%d filtered out%s): %w", localSourceStat.Glob, len(localSourceStat.Globbed), excludesFile, syscall.ENOENT)
|
||||
}
|
||||
}
|
||||
|
||||
if options.Link {
|
||||
if !latestTimestamp.IsZero() {
|
||||
for _, dir := range createdDirs {
|
||||
if err := os.Chtimes(dir, latestTimestamp, latestTimestamp); err != nil {
|
||||
logrus.Warnf("failed to set timestamp on directory %q: %v", dir, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
var created time.Time
|
||||
if options.Timestamp != nil {
|
||||
created = *options.Timestamp
|
||||
} else if !latestTimestamp.IsZero() {
|
||||
created = latestTimestamp
|
||||
} else {
|
||||
created = time.Unix(0, 0).UTC()
|
||||
}
|
||||
|
||||
command := "ADD"
|
||||
if !extract {
|
||||
command = "COPY"
|
||||
}
|
||||
|
||||
contentType, digest := b.ContentDigester.Digest()
|
||||
summary := contentType
|
||||
if digest != "" {
|
||||
if summary != "" {
|
||||
summary = summary + ":"
|
||||
}
|
||||
summary = summary + digest.Encoded()
|
||||
logrus.Debugf("added content from --link %s", summary)
|
||||
}
|
||||
|
||||
createdBy := "/bin/sh -c #(nop) " + command + " --link " + summary + " in " + destination + " " + options.BuildMetadata
|
||||
history := v1.History{
|
||||
Created: &created,
|
||||
CreatedBy: createdBy,
|
||||
Comment: b.HistoryComment(),
|
||||
}
|
||||
|
||||
linkedLayer := LinkedLayer{
|
||||
History: history,
|
||||
BlobPath: stagingDir,
|
||||
}
|
||||
|
||||
b.AppendedLinkedLayers = append(b.AppendedLinkedLayers, linkedLayer)
|
||||
|
||||
if err := b.Save(); err != nil {
|
||||
return fmt.Errorf("saving builder state after queuing linked layer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user