stage_executor: reset platform in systemcontext for stages
Every stage now has its own copy of systemcontext. On processing of every stage platform spec in systemcontext must be correctly reset. Closes: https://github.com/containers/buildah/issues/5968 Signed-off-by: flouthoc <flouthoc.git@gmail.com>
This commit is contained in:
parent
7509c34542
commit
022ff233fc
|
@ -372,9 +372,12 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o
|
|||
// startStage creates a new stage executor that will be referenced whenever a
|
||||
// COPY or ADD statement uses a --from=NAME flag.
|
||||
func (b *Executor) startStage(ctx context.Context, stage *imagebuilder.Stage, stages imagebuilder.Stages, output string) *StageExecutor {
|
||||
// create a copy of systemContext for each stage executor.
|
||||
systemContext := *b.systemContext
|
||||
stageExec := &StageExecutor{
|
||||
ctx: ctx,
|
||||
executor: b,
|
||||
systemContext: &systemContext,
|
||||
log: b.log,
|
||||
index: stage.Position,
|
||||
stages: stages,
|
||||
|
|
|
@ -59,6 +59,7 @@ import (
|
|||
// name to the image that it produces.
|
||||
type StageExecutor struct {
|
||||
ctx context.Context
|
||||
systemContext *types.SystemContext
|
||||
executor *Executor
|
||||
log func(format string, args ...interface{})
|
||||
index int
|
||||
|
@ -584,8 +585,8 @@ func (s *StageExecutor) performCopy(excludes []string, copies ...imagebuilder.Co
|
|||
// The values for these next two fields are ultimately
|
||||
// based on command line flags with names that sound
|
||||
// much more generic.
|
||||
CertPath: s.executor.systemContext.DockerCertPath,
|
||||
InsecureSkipTLSVerify: s.executor.systemContext.DockerInsecureSkipTLSVerify,
|
||||
CertPath: s.systemContext.DockerCertPath,
|
||||
InsecureSkipTLSVerify: s.systemContext.DockerInsecureSkipTLSVerify,
|
||||
MaxRetries: s.executor.maxPullPushRetries,
|
||||
RetryDelay: s.executor.retryPullPushDelay,
|
||||
Parents: copy.Parents,
|
||||
|
@ -841,7 +842,7 @@ func (s *StageExecutor) Run(run imagebuilder.Run, config docker.Config) error {
|
|||
Stderr: s.executor.err,
|
||||
Stdin: stdin,
|
||||
Stdout: s.executor.out,
|
||||
SystemContext: s.executor.systemContext,
|
||||
SystemContext: s.systemContext,
|
||||
Terminal: buildah.WithoutTerminal,
|
||||
User: config.User,
|
||||
WorkingDir: config.WorkingDir,
|
||||
|
@ -966,19 +967,20 @@ func (s *StageExecutor) prepare(ctx context.Context, from string, initializeIBCo
|
|||
}
|
||||
}
|
||||
|
||||
builderSystemContext := s.executor.systemContext
|
||||
// get platform string from stage
|
||||
if stage.Builder.Platform != "" {
|
||||
os, arch, variant, err := parse.Platform(stage.Builder.Platform)
|
||||
// In a multi-stage build where `FROM --platform=<>` was used then we must
|
||||
// reset context for new stages so that new stages don't inherit unexpected
|
||||
// `--platform` from prior stages.
|
||||
if stage.Builder.Platform != "" || (len(s.stages) > 1 && (s.systemContext.ArchitectureChoice == "" && s.systemContext.VariantChoice == "" && s.systemContext.OSChoice == "")) {
|
||||
imageOS, imageArch, imageVariant, err := parse.Platform(stage.Builder.Platform)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse platform %q: %w", stage.Builder.Platform, err)
|
||||
}
|
||||
if arch != "" || variant != "" {
|
||||
builderSystemContext.ArchitectureChoice = arch
|
||||
builderSystemContext.VariantChoice = variant
|
||||
if imageArch != "" || imageVariant != "" {
|
||||
s.systemContext.ArchitectureChoice = imageArch
|
||||
s.systemContext.VariantChoice = imageVariant
|
||||
}
|
||||
if os != "" {
|
||||
builderSystemContext.OSChoice = os
|
||||
if imageOS != "" {
|
||||
s.systemContext.OSChoice = imageOS
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -992,7 +994,7 @@ func (s *StageExecutor) prepare(ctx context.Context, from string, initializeIBCo
|
|||
BlobDirectory: s.executor.blobDirectory,
|
||||
SignaturePolicyPath: s.executor.signaturePolicyPath,
|
||||
ReportWriter: s.executor.reportWriter,
|
||||
SystemContext: builderSystemContext,
|
||||
SystemContext: s.systemContext,
|
||||
Isolation: s.executor.isolation,
|
||||
NamespaceOptions: s.executor.namespaceOptions,
|
||||
ConfigureNetwork: s.executor.configureNetwork,
|
||||
|
@ -2058,7 +2060,7 @@ func (s *StageExecutor) tagExistingImage(ctx context.Context, cacheID, output st
|
|||
return "", nil, err
|
||||
}
|
||||
|
||||
policyContext, err := util.GetPolicyContext(s.executor.systemContext)
|
||||
policyContext, err := util.GetPolicyContext(s.systemContext)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
@ -2171,7 +2173,7 @@ func (s *StageExecutor) pushCache(ctx context.Context, src, cacheKey string) err
|
|||
Compression: s.executor.compression,
|
||||
SignaturePolicyPath: s.executor.signaturePolicyPath,
|
||||
Store: s.executor.store,
|
||||
SystemContext: s.executor.systemContext,
|
||||
SystemContext: s.systemContext,
|
||||
BlobDirectory: s.executor.blobDirectory,
|
||||
SignBy: s.executor.signBy,
|
||||
MaxRetries: s.executor.maxPullPushRetries,
|
||||
|
@ -2209,7 +2211,7 @@ func (s *StageExecutor) pullCache(ctx context.Context, cacheKey string) (referen
|
|||
options := buildah.PullOptions{
|
||||
SignaturePolicyPath: s.executor.signaturePolicyPath,
|
||||
Store: s.executor.store,
|
||||
SystemContext: s.executor.systemContext,
|
||||
SystemContext: s.systemContext,
|
||||
BlobDirectory: s.executor.blobDirectory,
|
||||
MaxRetries: s.executor.maxPullPushRetries,
|
||||
RetryDelay: s.executor.retryPullPushDelay,
|
||||
|
@ -2431,7 +2433,7 @@ func (s *StageExecutor) commit(ctx context.Context, createdBy string, emptyLayer
|
|||
SignaturePolicyPath: s.executor.signaturePolicyPath,
|
||||
ReportWriter: writer,
|
||||
PreferredManifestType: s.executor.outputFormat,
|
||||
SystemContext: s.executor.systemContext,
|
||||
SystemContext: s.systemContext,
|
||||
Squash: squash,
|
||||
OmitHistory: s.executor.commonBuildOptions.OmitHistory,
|
||||
EmptyLayer: emptyLayer,
|
||||
|
|
|
@ -6573,6 +6573,18 @@ _EOF
|
|||
done
|
||||
}
|
||||
|
||||
@test "build must reset platform for stages if needed" {
|
||||
run_buildah info --format '{{.host.arch}}'
|
||||
myarch="$output"
|
||||
otherarch="arm64"
|
||||
# just make sure that other arch is not equivalent to host arch
|
||||
if [[ "$otherarch" == "$myarch" ]]; then
|
||||
otherarch="amd64"
|
||||
fi
|
||||
run_buildah build $WITH_POLICY_JSON --build-arg FOREIGNARCH=$otherarch -f $BUDFILES/multiarch/Containerfile.reset-platform $BUDFILES/multiarch
|
||||
run_buildah build $WITH_POLICY_JSON --build-arg TARGETPLATFORM=linux/$myarch --build-arg FOREIGNARCH=$otherarch -f $BUDFILES/multiarch/Containerfile.reset-platform $BUDFILES/multiarch
|
||||
}
|
||||
|
||||
# * Performs multi-stage build with label1=value1 and verifies
|
||||
# * Relabels build with label1=value2 and verifies
|
||||
# * Rebuild with label1=value1 and makes sure everything is used from cache
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
ARG FOREIGNARCH
|
||||
FROM --platform=linux/$FOREIGNARCH busybox AS foreign
|
||||
FROM busybox
|
||||
COPY --from=foreign /bin/busybox /bin/busybox.foreign
|
||||
RUN arch
|
||||
RUN ls -l /bin/busybox /bin/busybox.foreign
|
||||
RUN ! cmp /bin/busybox /bin/busybox.foreign
|
Loading…
Reference in New Issue