Vendor in latest containers/buildah

Pulls in fix for COPY --from when using --layers

Signed-off-by: Urvashi Mohnani <umohnani@redhat.com>
This commit is contained in:
Urvashi Mohnani
2018-11-20 20:07:17 +00:00
parent fe4f09493f
commit bd61c779ca
10 changed files with 153 additions and 44 deletions

View File

@@ -222,7 +222,7 @@ type Executor struct {
forceRmIntermediateCtrs bool
containerIDs []string // Stores the IDs of the successful intermediate containers used during layer build
imageMap map[string]string // Used to map images that we create to handle the AS construct.
copyFrom string // Used to keep track of the --from flag from COPY and ADD
}
// withName creates a new child executor that will be used whenever a COPY statement uses --from=NAME.
@@ -826,6 +826,18 @@ func (b *Executor) Execute(ctx context.Context, stage imagebuilder.Stage) error
err error
imgID string
)
b.copyFrom = ""
// Check if --from exists in the step command of COPY or ADD
// If it exists, set b.copyfrom to that value
for _, n := range step.Flags {
if strings.Contains(n, "--from") && (step.Command == "copy" || step.Command == "add") {
arr := strings.Split(n, "=")
b.copyFrom = b.named[arr[1]].mountPoint
break
}
}
// checkForLayers will be true if b.layers is true and a cached intermediate image is found.
// checkForLayers is set to false when either there is no cached image or a break occurs where
// the instructions in the Dockerfile change from a previous build.
@@ -848,6 +860,7 @@ func (b *Executor) Execute(ctx context.Context, stage imagebuilder.Stage) error
if err := b.copyExistingImage(ctx, cacheID); err != nil {
return err
}
b.containerIDs = append(b.containerIDs, b.builder.ContainerID)
break
}
@@ -1009,6 +1022,11 @@ func (b *Executor) getFilesToCopy(node *parser.Node) ([]string, error) {
currNode = currNode.Next
continue
}
if b.copyFrom != "" {
src = append(src, filepath.Join(b.copyFrom, currNode.Value))
currNode = currNode.Next
continue
}
matches, err := filepath.Glob(filepath.Join(b.contextDir, currNode.Value))
if err != nil {
return nil, errors.Wrapf(err, "error finding match for pattern %q", currNode.Value)
@@ -1049,7 +1067,12 @@ func (b *Executor) copiedFilesMatch(node *parser.Node, historyTime *time.Time) (
// Change the time format to ensure we don't run into a parsing error when converting again from string
// to time.Time. It is a known Go issue that the conversions cause errors sometimes, so specifying a particular
// time format here when converting to a string.
timeIsGreater, err := resolveModifiedTime(b.contextDir, item, historyTime.Format(time.RFC3339Nano))
// If the COPY has --from in the command, change the rootdir to mountpoint of the container it is copying from
rootdir := b.contextDir
if b.copyFrom != "" {
rootdir = b.copyFrom
}
timeIsGreater, err := resolveModifiedTime(rootdir, item, historyTime.Format(time.RFC3339Nano))
if err != nil {
return false, errors.Wrapf(err, "error resolving symlinks and comparing modified times: %q", item)
}
@@ -1342,7 +1365,10 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options BuildOpt
return "", nil, errors.Wrapf(err, "error creating build executor")
}
b := imagebuilder.NewBuilder(options.Args)
stages := imagebuilder.NewStages(mainNode, b)
stages, err := imagebuilder.NewStages(mainNode, b)
if err != nil {
return "", nil, errors.Wrap(err, "error reading multiple stages")
}
return exec.Build(ctx, stages)
}

View File

@@ -140,6 +140,13 @@ func modTimeIsGreater(rootdir, path string, historyTime string) (bool, error) {
// Since we are chroot in rootdir, only want the path of the actual filename, i.e path - rootdir.
// +1 to account for the extra "/" (e.g rootdir=/home/user/mydir, path=/home/user/mydir/myfile.json)
err = filepath.Walk(path[len(rootdir)+1:], func(path string, info os.FileInfo, err error) error {
// If using cached images, it is possible for files that are being copied to come from
// previous build stages. But if using cached images, then the copied file won't exist
// since a container won't have been created for the previous build stage and info will be nil.
// In that case just return nil and continue on with using the cached image for the whole build process.
if info == nil {
return nil
}
modTime := info.ModTime()
if info.Mode()&os.ModeSymlink == os.ModeSymlink {
// Evaluate any symlink that occurs to get updated modified information

View File

@@ -111,3 +111,28 @@ func TempDirForURL(dir, prefix, url string) (name string, subdir string, err err
func InitReexec() bool {
return buildah.InitReexec()
}
// ReposToMap parses the specified repotags and returns a map with repositories
// as keys and the corresponding arrays of tags as values.
func ReposToMap(repotags []string) map[string][]string {
// map format is repo -> tag
repos := make(map[string][]string)
for _, repo := range repotags {
var repository, tag string
if strings.Contains(repo, ":") {
li := strings.LastIndex(repo, ":")
repository = repo[0:li]
tag = repo[li+1:]
} else if len(repo) > 0 {
repository = repo
tag = "<none>"
} else {
logrus.Warnf("Found image with empty name")
}
repos[repository] = append(repos[repository], tag)
}
if len(repos) == 0 {
repos["<none>"] = []string{"<none>"}
}
return repos
}