-
Notifications
You must be signed in to change notification settings - Fork 807
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
buildah build
: use the same overlay for the context directory for the whole build
#5975
base: main
Are you sure you want to change the base?
Conversation
51a061b
to
9d7189f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much for working on this! I just skimmed the code, will try testing it soon
@@ -63,6 +63,13 @@ func MountWithOptions(contentDir, source, dest string, opts *Options) (mount spe | |||
if err := os.Chown(upperDir, int(stat.Uid), int(stat.Gid)); err != nil { | |||
return mount, err | |||
} | |||
times := []syscall.Timeval{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why out of curiosity? Is this helping ensure reproducibility? We aren't serializing anything related to the timestamps of this directory to e.g. a tar stream are we?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without it, two different runs would appear to have different timestamps on the top level of the build context directory, breaking one of the tests added by #5691.
// indicates whether we did, in fact, mount an overlay; a cleanup function | ||
// which should be called when the location is no longer needed (on success); | ||
// and a non-nil fatal error if any of that failed. | ||
func platformSetupContextDirectoryOverlay(store storage.Store, options *define.BuildOptions) (string, string, string, bool, func(), error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Return values are a bit unwieldy, maybe a struct
instead? Although I guess the single caller unpacks them anyways, so doesn't matter. Yeah, one caller, so makes sense as is.
pkg/cli/build.go
Outdated
@@ -113,7 +113,7 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) ( | |||
if c.Flag("build-context").Changed { | |||
for _, contextString := range iopts.BuildContext { | |||
av := strings.SplitN(contextString, "=", 2) | |||
if len(av) > 1 { | |||
if len(av) > 1 && av[0] != "" && av[1] != "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is basically so we skip over -v :
or something? This could use a comment, maybe even we have a const DefaultBuildContextKey = ""
and then reference it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushing the check on av[1]
down into GetAdditionalBuildContext()
makes it a little easier to follow, added a comment here and put more checks in there.
@@ -673,7 +673,7 @@ symlink(subdir)" | |||
_prefetch busybox | |||
run_buildah 125 build -t testbud3 $WITH_POLICY_JSON $BUDFILES/dockerignore3 | |||
expect_output --substring 'building.*"COPY test1.txt /upload/test1.txt".*no such file or directory' | |||
expect_output --substring $(realpath "$BUDFILES/dockerignore3/.dockerignore") | |||
expect_output --substring 'filtered out using /[^ ]*/.dockerignore' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not obvious to me how this test change is related...did the build there try to modify the context directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name of the directory which contains the .dockerignore file and which is included in the error message is no longer the one passed on the command line, so the exact string comparison began failing. It was either change the test to not care about the specific path, or lie about the file's location to get the test to pass as it was, so I changed the test.
1e2d39c
to
82ee991
Compare
imagebuildah/stage_executor.go
Outdated
@@ -916,6 +929,58 @@ func (s *StageExecutor) UnrecognizedInstruction(step *imagebuilder.Step) error { | |||
return errors.New(err) | |||
} | |||
|
|||
// do our best to ensure that image specifiers that include a transport that | |||
// uses path names are scoped to the build context directory |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be secure and reliable to get a directory fd for the context overlay mount, and then use openat(..., RESOLVE_IN_ROOT)
to access the file, then...the ugly part is that the containers-storage APIs want path strings still, but we could pass e.g. oci:/proc/self/fd/N
right? I've done that elsewhere I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proper safety for such references is a much larger patch.
Trying to test this, but unrelated to the contents of this PR, I get the same problem trying git main:
Is there something I need to do here to sync up the buildah binary with the default network config? Odd... |
Nevermind of course after I posted my "wait these are weird denials" mental flag tripped and of course it's SELinux; a |
OK so this works for me:
So that's already a lot cleaner, thanks! There is an important note here that this does break compatibility with the previous dockerfiles, I get:
Looks like changing Now that I dig in a bit more, one unfortunate thing here is that the need to use the When I unpack and inspect the resulting image, we have this final layer with
with floating timestamps. That said hmm, actually in this case actually it works to do But the sad thing is that these things just keep piling on...now for me we have a new one of these in Konflux which is injecting content_sets which also has no attempt made to generate timestamp-reproducible data right now either (and it uses buildah too, so it inherits that, but we still need to ensure the timestamps of the files that we actually write and aren't synthetic container runtime artifacts are canonicalized too) So in the end, I think we'll definitely try to |
Not being strict about the arguments for |
63f0cda
to
5b05378
Compare
e980b6c
to
c7c4667
Compare
53b3831
to
30a0864
Compare
@@ -546,7 +546,7 @@ func (s *StageExecutor) performCopy(excludes []string, copies ...imagebuilder.Co | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(not commenting on the content of this commit) there's a typo in the commit subject
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dang it, that's embarrassing. Fixing.
imagebuildah/stage_executor.go
Outdated
// names are evaluated relative to "contextDir", it will create a copy of the | ||
// original image, under "tmpdir", which contains no symbolic links. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a blocker but there's already a lot of copying involved in this flow (needing to make a physically separate oci
directory as we can't directly write to c/storage in this flow)...forcing another copy is unfortunate. Especially because I don't believe it's strictly necessary since as far as I understand, there shouldn't be any untrusted processes running at this point, so we don't need to worry about concurrent mutation.
And for symlink following again I think the right fix is to have the underlying code use openat2(RESOLVE_IN_ROOT, ...)
or so. I know you said there are use cases that rely on symlink following, but it seems to me we could make the "resolve in root" an option when opening the transport at least.
And if we do that there'd be a lot less code here...it'd just be calling transport.ResolveInRoot()
or so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a blocker but there's already a lot of copying involved in this flow (needing to make a physically separate
oci
directory as we can't directly write to c/storage in this flow)...forcing another copy is unfortunate. Especially because I don't believe it's strictly necessary since as far as I understand, there shouldn't be any untrusted processes running at this point, so we don't need to worry about concurrent mutation.
We have a --jobs
CLI flag and equivalent API setting, so I must disagree.
5acfff7
to
cd22688
Compare
@containers/buildah-maintainers PTAL |
cd22688
to
18a5886
Compare
@@ -980,7 +1286,7 @@ func (s *StageExecutor) prepare(ctx context.Context, from string, initializeIBCo | |||
|
|||
builderOptions := buildah.BuilderOptions{ | |||
Args: ib.Args, | |||
FromImage: from, | |||
FromImage: sanitizedFrom, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A small question since I did not understand it completely, why are are we creating copy of entire image for every stage ? Is it just to make sure no symbolic links are present ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed here #5975 (comment) and again here #5975 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be fair to ask and see about how much overhead does this patch adds both disk
usage wise and speed
time.
I could be wrong but I could think of use-case where a stage copied lot of external artifacts but only parts of it are being used in further stages, this will end up creating copies for every future stage even though those parts are not being used by future stages.
Should we consider making this behavior optional ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be fair to ask and see about how much overhead does this patch adds both
disk
usage wise andspeed
time.
The disk cost is a second copy of the base image being copied to a temporary location.
The speed cost is the cost of copying that content, which is unavoidably higher if we're using fuse-overlayfs, and likewise reading contents from the build context through that overlay to avoid inconsistencies.
I could be wrong but I could think of use-case where a stage copied lot of external artifacts but only parts of it are being used in further stages, this will end up creating copies for every future stage even though those parts are not being used by future stages.
I don't understand what you're describing here. Can you elaborate on that? Initializing a stage using a previous stage's result as its base doesn't involve the build context directory, so I don't follow where additional copies would appear.
Should we consider making this behavior optional ?
Using an overlay over the build context directory is not something we should turn off. Turning off sharing like this PR introduces doesn't reduce any of the costs that are incurred when they're not shared, so I don't really see the benefit of adding complexity there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what you're describing here. Can you elaborate on that? Initializing a stage using a previous stage's result as its base doesn't involve the build context directory, so I don't follow where additional copies would appear.
I was thinking for use-case something like this
FROM alpine as first
COPY /large-fileA-from-host .
COPY /large-fileB-from-host .
COPY /large-fileC-from-host .
FROM first as second
# Use only large-file-A in this stage
# but this will create another copy of `first` containing all three files
FROM first as third
# Use only large-file-B in this stage
# # but this will create another copy of `first` containing all three files
FROM first as fourth
# Use only large-file-C in this stage
# but this will create another copy of `first` containing all three files
@nalind If i understand correctly for all the three stages second
, third
and fourth
a separate copy of first
stage will be created , am i correct ? and I am not sure if buildah was doing this before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The stages nicknamed "second", "third", and "fourth" would each start with their own working container based on the image that was committed at the end of the stage nicknamed "first", as before. This PR doesn't affect how we handle the root filesystems of working containers, or committing images.
The COPY instructions have to read contents through the mounted overlay for consistency's sake, but I don't see additional copies of them being made here. Since they're not being modified, they'd be read directly from the build context directory that's being used as the "lowerdir" for the overlay, without being "copied up".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah i see sounds fair to me.
// those it accepts which refer to filesystem objects, where relative path | ||
// names are evaluated relative to "contextDir", it will create a copy of the | ||
// original image, under "tmpdir", which contains no symbolic links. | ||
func (s *StageExecutor) sanitizeFrom(from, tmpdir string) (newFrom string, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we document what is value contained in newFrom
string ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding.
imagebuildah/stage_executor.go
Outdated
// sanitizeImageReference limits which image transports we'll accept. For | ||
// those it accepts which refer to filesystem objects, where relative path | ||
// names are evaluated relative to "contextDir", it will create a copy of the | ||
// original image, under "tmpdir", which contains no symbolic links. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we document what is value contained in newFrom
string ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding.
@@ -394,7 +403,7 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options define.B | |||
return id, ref, nil | |||
} | |||
|
|||
func buildDockerfilesOnce(ctx context.Context, store storage.Store, logger *logrus.Logger, logPrefix string, options define.BuildOptions, containerFiles []string, dockerfilecontents [][]byte) (string, reference.Canonical, error) { | |||
func buildDockerfilesOnce(ctx context.Context, store storage.Store, logger *logrus.Logger, logPrefix string, options define.BuildOptions, containerFiles []string, dockerfilecontents [][]byte, processLabel, mountLabel string, usingContextOverlay bool) (string, reference.Canonical, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit and not a blocker probably a todo for future: probably buildDockerfilesOnce
should start consuming a struct
.
imagebuildah/build_linux.go
Outdated
) | ||
|
||
// platformSetupContextDirectoryOverlay() may set up an overlay _over_ the | ||
// build context directory, and sorts out labeling. Returns either the new |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment says returns base build context or the old location
I can't see in which case it returns old location
is it relevant still ? Maybe worth adding a comment when does it returns old location
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, it never returns the original location. Updating the godoc.
imagebuildah/stage_executor.go
Outdated
// those it accepts which refer to filesystem objects, where relative path | ||
// names are evaluated relative to "contextDir", it will create a copy of the | ||
// original image, under "tmpdir", which contains no symbolic links. | ||
func sanitizeImageName(transportName, restOfImageName, contextDir, tmpdir string) (newFrom string, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe as a refactor we can break this function into several helper function for each transport
it will help with the readability and maintenance.
imagebuildah/build_notlinux.go
Outdated
|
||
// platformSetupContextDirectoryOverlay() may set up an overlay _over_ the | ||
// build context directory, and sorts out labeling. Returns either the new | ||
// location which should be used as the base build context or the old location; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as https://github.com/containers/buildah/pull/5975/files#r1981811503 I think comment needs to be fixed.
019c57c
to
97eca26
Compare
Would this address #5988 also or is that something different? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few misc. comments, but I’m generally unfamiliar with the codebase and structure, so I didn’t really check lifetimes / interactions / … .
The StageMountPoints[""]
case worries me. Would adding an extra field (StageContextMount *StageMountDetails // nil if N/A
) work?
(Generally the functions have too many unnamed parameters and unnamed return values for my personal taste, but this is totally up to maintainers of this project.)
// this is a normal-looking image-in-a-registry-or-named-in-storage name | ||
return from, nil | ||
} | ||
if img, err := s.executor.store.Image(from); img != nil && err == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
… is it expected that Containerfiles can refer to image IDs? That can potentially allow builds on a shared host to refer to images which the invoking user has no right to pull, if the invoking user can somehow determine the config digest.
OTOH… I can imagine that there might be uses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Internally, we rewrite references to nicknames of previous stages to their IDs before we get to this point, since they don't get names assigned to them.
imagebuildah/stage_executor.go
Outdated
if linkname != "/" { | ||
linkname = strings.TrimPrefix(linkname, "/") | ||
} | ||
if _, validTarget := seenEntries[linkname]; !validTarget { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it generally guaranteed that symlink destinations exist in tar files before the symlinks that refer to them?
Generally, symlinks can be dangling and refer to nothing…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not generally, but in the very specific case of docker-archives, that does appear to be something we can safely expect, at least from containers/image.
imagebuildah/stage_executor.go
Outdated
// names are evaluated relative to "contextDir", it will create a copy of the | ||
// original image, under "tmpdir", which contains no symbolic links. It it | ||
// returns a parseable reference to the image which should be used. | ||
func sanitizeImageName(transportName, restOfImageName, contextDir, tmpdir string) (newFrom string, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Absolutely non-blocking: I’d personally be trying to structure this as an object with methods, in a separate file, or maybe even a separate internal subpackage. E.g. the nested functions are impossible to unit-test.)
imagebuildah/stage_executor.go
Outdated
if err := tw.WriteHeader(hdr); err != nil { | ||
return fmt.Errorf("rewriting archive of base image: %w", err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Nit: I think this can be moved after the switch
. It works fine as is.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving it.
imagebuildah/stage_executor.go
Outdated
|
||
// write this header/content combination to a tar writer, making sure | ||
// that it doesn't include any symbolic links that point to something | ||
// outside of the archive |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// outside of the archive | |
// outside of the archive. Overwrites contents of `hdr`. |
imagebuildah/stage_executor.go
Outdated
defer func() { | ||
if !succeeded { | ||
if err := os.RemoveAll(newImageDestination); err != nil { | ||
logrus.Warn(err) | ||
} | ||
} | ||
}() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This already exists before the switch
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, a relic from an earlier revision. Dropping.
imagebuildah/stage_executor.go
Outdated
// start reading the archived content | ||
defer func() { | ||
if err := imageArchive.Close(); err != nil { | ||
logrus.Warn(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In various similar situations: either the error can be ignored, or the user should be given enough context to actually do something about it (at least the path).
imagebuildah/stage_executor.go
Outdated
// if the archive we're parsing is expected to have an archive as its only item, | ||
// assume it's the first (and hopefully, only) item, and switch to stepping through | ||
// it as the archive | ||
if isEmbeddedArchive { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-blocking: Why does all this logic exist? For the -archive:
transports, I’d expect an unmodified copy of the single tarball file, as a first guess.
Is the goal here to provide a seekable uncompressed file so that the -archive:
transports don’t make a second on-disk copy? That would be an improvement for docker-archive
, but oci-archive
currently just decompresses the whole thing to disk, so having the intermediate copy uncompressed increases the size without a benefit I can see.
(Also, this code exposes writeToArchive
/writeToDirectory
to more opportunities for the attacker to prepare unexpected tar metadata, compared to the cases where we are creating the tar files ourselves.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't know that these locations contain contents we can trust, so the goal is to filter out things that we know would be problematic or even out of the ordinary. I can't claim it's perfect, though.
@@ -248,6 +249,7 @@ func GetBindMount(sys *types.SystemContext, args []string, contextDir string, st | |||
if additionalMountPoints != nil { | |||
if val, ok := additionalMountPoints[fromWhere]; ok { | |||
mountPoint = val.MountPoint | |||
skipOverlay = val.IsWritesDiscardedOverlay |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn’t this ~always false
because fromWhere != ""
? OTOH maybe the consistency is nice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should almost always be true
, except for the default build context on non-Linux platforms, where we don't have the ability to use read-write overlays yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IsWritesDiscardedOverlay
is only ever mentioned in a “write” position once, when setting stageMountPoints[""]
; on this code path, fromWhere != ""
, so we should see the default field value of false
; am I misreading this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, right, we haven't mounted an overlay there yet when it's something else. You're reading it right.
@@ -208,19 +213,34 @@ func CommonBuildOptionsFromFlagSet(flags *pflag.FlagSet, findFlagFunc func(name | |||
|
|||
// GetAdditionalBuildContext consumes raw string and returns parsed AdditionalBuildContext | |||
func GetAdditionalBuildContext(value string) (define.AdditionalBuildContext, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Locally, it’s not obvious that the checks for ""
are important; probably worth a more detailed comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding a note there.
97eca26
to
b41e78a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: flouthoc, nalind The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The resolution of my earlier comments LGTM.
I don’t know whether that should count as a review… If necessary, ping me and I’ll return to this and actually study the imagebuildah
structure as a whole.
b41e78a
to
7e6b859
Compare
In addition to setting the (usually recently-created) upper directory's ownership and permissions to match those of the lower (the location of which wasn't known when the upper was created), set the timestamps to match, too. Signed-off-by: Nalin Dahyabhai <[email protected]>
When chown()ing the upper directory to match the lower directory, if the ownership of the lower directory is the overflow UID:GID, ignore EINVAL. Signed-off-by: Nalin Dahyabhai <[email protected]>
Mount a read-write overlay directory over the build context directory to restore the ability to use it as a covert cache of sorts during the lifetime of the build, but in a way that still ensures that we don't modify the real build context directory. N.B.: builds where FROM in one stage referenced a relative path which had been written to a bind-mounted default build context directory by an earlier stage broke when we started making those bind mounts into overlays to prevent/discard modifications to that directory, and while this extends the lifetime of that overlay so that it's consistent throughout the build, those relative path names are still going to point to the wrong location. Since we need to determine SELinux labeling before mounting the overlay, go ahead and calculate the labels to use before creating the first builder, and remove the logic that had whichever stage thought it was the first one set them in its parent object for use by other stages, in what was probably a racey way. Signed-off-by: Nalin Dahyabhai <[email protected]>
Try to limit which image transports we accept in stages, and scope the ones that use path names to the context directory. At some point anything that isn't an image ID or pullable spec should start being rejected. Signed-off-by: Nalin Dahyabhai <[email protected]>
Add a missing "not" to an error message. Signed-off-by: Nalin Dahyabhai <[email protected]>
7e6b859
to
2d7ce30
Compare
LGTM |
This is going to exacerbate #5988 for people who are running into it. |
What type of PR is this?
/kind feature
What this PR does / why we need it:
Change how we handle bind mounts of the build context directory from using a different upper for each read-write mount into it, to using one that lasts the duration of the full build.
We broke workflows which wrote content to the build context in one stage and then attempted to use archive or layout locations in the build context in a subsequent stage when we fixed CVE-2024-11218, and this should get them working again. Because that content was often addressed using relative path names which are no longer correct for the written location, we try to compensate by rewriting some types of references and straight-up rejecting some others.
How to verify it
New integration test! And some updated ones, too!
Which issue(s) this PR fixes:
Proposed fix for #5952.
Special notes for your reviewer:
Does this PR introduce a user-facing change?