-
Notifications
You must be signed in to change notification settings - Fork 386
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
Allow SAVE ARTIFACT after a --push
#735
Conversation
s *solver | ||
opt Opt | ||
resolver *buildcontext.Resolver | ||
builtMain bool |
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 concept as phases; just need to know one thing instead of a list index... we may need phases in future
@@ -124,6 +125,9 @@ func (b *Builder) convertAndBuild(ctx context.Context, target domain.Target, opt | |||
destPathWhitelist := make(map[string]bool) | |||
manifestLists := make(map[string][]manifest) // parent image -> child images | |||
var mts *states.MultiTarget | |||
depIndex := 0 | |||
imageIndex := 0 | |||
dirIndex := 0 |
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.
Indexes need to increase monotonically across all artifacts to avoid overwriting issues, so keep them out side and close on them
} | ||
return sts.SaveLocals | ||
} | ||
|
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.
Similar things to phases to enable use of the gwClient. However, its not quite the same as before where the state tracks it. Kept it simpler using the existing RunPush struct, and phases only happen here in builder where they are cared about now.
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.
Open to pushing this down and cleaning up some more; perhaps as a separate PR though? Its just touching a lot to do that
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 sure what you have in mind by "cleaning up some more"?
This looks pretty good BTW.
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.
Cleaning up meaning pushing this down into the states package. Think of it as phases-lite; so the builder doesn't have to be so grabby with SingleTargets fields
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 think the way it is in this PR is simple enough. We could do that if things get more complex.
llb.WithCustomNamef( | ||
"%sSAVE ARTIFACT %s%s %s AS LOCAL %s", | ||
c.vertexPrefix(false), strIf(ifExists, "--if-exists "), saveFrom, artifact.String(), saveAsLocalTo)) | ||
} |
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.
State to copy from depends on if we are pushing
@@ -462,7 +458,7 @@ func (l *listener) ExitSaveArtifact(c *parser.SaveArtifactContext) { | |||
saveFrom := l.expandArgs(fs.Args()[0], false) | |||
saveTo = l.expandArgs(saveTo, false) | |||
saveAsLocalTo = l.expandArgs(saveAsLocalTo, false) | |||
err = l.converter.SaveArtifact(l.ctx, saveFrom, saveTo, saveAsLocalTo, *keepTs, *keepOwn, *ifExists) | |||
err = l.converter.SaveArtifact(l.ctx, saveFrom, saveTo, saveAsLocalTo, *keepTs, *keepOwn, *ifExists, l.pushOnlyAllowed) |
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.
pushOnlyAllowed
is here to signify we have encountered a push. Could rename this var; but didn't because im not globally allowing everything like 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.
If you wanted you could do
err = l.converter.SaveArtifact(l.ctx, saveFrom, saveTo, saveAsLocalTo, *keepTs, *keepOwn, *ifExists, l.pushOnlyAllowed) | |
isPushPhase := l.pushOnlyAllowed | |
err = l.converter.SaveArtifact(l.ctx, saveFrom, saveTo, saveAsLocalTo, *keepTs, *keepOwn, *ifExists, isPushPhase) |
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.
Ehhhhhhhh that feels like extra ceremony. Not worth it IMO; I would rather rename it to pushEncountered
across all of converter if I went renaming; since that preserves the business logic meaning well enough
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 like ceremonies :-)
RUN --privileged \ | ||
--entrypoint \ | ||
--mount=type=tmpfs,target=/tmp/earthly \ | ||
-- +copy-test 2>&1 | perl -pe 'BEGIN {$status=1} END {exit $status} $status=0 if /not found/;' |
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.
Can't copy artifacts that were saved in a different targets --push
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 looks pretty good - left an important comment, though.
I assume the output has two ===== SUCCESS ======
lines, right? We should print out a more obvious distinction for the two phases. Maybe ===== Build phase SUCCESS ======
and ===== Push phase SUCCESS ======
. Or something like that - whatever looks pretty enough.
func (b *Builder) stateToRef(ctx context.Context, gwClient gwclient.Client, state llb.State, platform *specs.Platform) (gwclient.Reference, error) { | ||
if b.opt.NoCache { | ||
if b.opt.NoCache || b.builtMain { |
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 doesn't look right. I think it should be
if b.opt.NoCache || b.builtMain { | |
if b.opt.NoCache && !b.builtMain { |
Meaning that for the push phase, we do not add the ignore cache flag here (instead we rely on the converter having added this flag to individual commands).
If we add the ignore cache flag here for the push phase, then everything the push phase depends on (including the main phase) will be executed with no cache - so the main phase ends up being executed twice.
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.
What you initially suggested is what I had before; but I noticed that solving the states for the separate artifacts was showing up as cached. I used to have some ls
sentinels in here to show when things were being re-run, but I must have pulled them out before swapping to this.
I was trying to get SAVE ARTIFACT
inside --push
to also not cache when running with --no-cache
. Ill rework this some to get both scenarios working
} | ||
return sts.SaveLocals | ||
} | ||
|
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 sure what you have in mind by "cleaning up some more"?
This looks pretty good BTW.
@vladaionescu I agree on more distinctive success lines. Though, that is also the current behavior. Sticking the name in the line feels fine; All the alternatives I can think of would require a little more work. |
Yeah, let's stick the name in. I think the current behavior is inconsistent: only prints success once, but can print both success and then fail. |
@vladaionescu Updated to your logic. The one downside to this is that unchanged artifacts after |
How do you feel about solving artifacts state with something like this: func (b *Builder) artifactStateToRef(ctx context.Context, gwClient gwclient.Client, state llb.State, platform *specs.Platform) (gwclient.Reference, error) {
if b.opt.NoCache || b.builtMain{
state = state.SetMarshalDefaults(llb.IgnoreCache)
}
return llbutil.StateToRef(ctx, gwClient, state, platform, b.opt.CacheImports)
} The idea being that we never use cache for artifacts after a push, regardless of the CLI flag. |
Sounds good - I think we had that bug before too. |
…le push phase in general
No description provided.