Skip to content

Add context-aware versions of several functions and some methods - #7007

Open
nalind wants to merge 3 commits into
podman-container-tools:mainfrom
nalind:cancellation
Open

Add context-aware versions of several functions and some methods#7007
nalind wants to merge 3 commits into
podman-container-tools:mainfrom
nalind:cancellation

Conversation

@nalind

@nalind nalind commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?

/kind other

What this PR does / why we need it:

Introduce versions of a number of functions and some methods which take a context.Context, to least try to provide proper cancellation support.

When copier.Get() returns an error, also write a non-NUL string after whatever it's already written, so that a tar.Reader that reads what it output will also flag the malformed header with an unexpected error.

In the CLI, pass our default global context down in places where we didn't before, connect it to an experimental timeout flag, and have it cancel on os.Interrupt signals, too.

How to verify it

New/updated unit tests!

Which issue(s) this PR fixes:

None

Special notes for your reviewer:

Does this PR introduce a user-facing change?

None

@nalind
nalind force-pushed the cancellation branch 8 times, most recently from f089937 to 308bdb1 Compare July 29, 2026 00:47

@Luap99 Luap99 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack, thanks. I have not looked at all the API changes but I think the context creation is with oncevalue is broken like that

Comment thread cmd/buildah/common.go Outdated
}

func getContextWithCancel() (context.Context, context.CancelFunc) {
return sync.OnceValues(func() (context.Context, context.CancelFunc) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cannot work can it? Calling sync.OnceValues every single time means you get a new context every single time.
sync.OnceValues must either be assigned to a global variable here

var getContextWithCancel =  sync.OnceValues(func() (context.Context, context.CancelFunc) {...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oof, yeah, that would've been too easy to keep self-contained. Reworking it.

Comment thread cmd/buildah/main.go
os.Setenv("TMPDIR", parse.GetTempDir())

if err := rootCmd.Execute(); err != nil {
err := rootCmd.Execute()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW there is ExecuteContext though which sets the ctx field for the cmd though I guess that is not used anywhere so it does not matter really.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think trying to pass the context to ExecuteContext() would create an order of initialization problem - the one we initialize is affected by the CLI flags, and they haven't been parsed yet at that point.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you are right, however having the sync.Once makes it very easy to have this being called anywhere before that as well and then not noticing the flag takes no effect. But I guess that should be possible to catch with tests?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! It turns out that called for more checking for cancellation at various places, but I added a test for at least one of them.

Comment thread internal/ctxreader/ctxreader_test.go Outdated
Comment on lines +19 to +20
defer cancel()
time.Sleep(1 * time.Millisecond)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can avoid the sleep, just call cancel() without defer which should be enough

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed it.

@nalind
nalind force-pushed the cancellation branch 2 times, most recently from b2553e5 to f48b3fe Compare July 29, 2026 14:44
@packit-as-a-service

Copy link
Copy Markdown

Ephemeral COPR build failed. @containers/packit-build please check.

@vtushar06

Copy link
Copy Markdown

@Luap99 once this lands and gets vendored I can check whether the prune --build flake in podman#28868 stops showing..

@nalind
nalind force-pushed the cancellation branch 6 times, most recently from 941e3a0 to ac51c68 Compare July 31, 2026 19:02
@nalind

nalind commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Rebased and fixed some warnings that the "usestdlibvars" linter would warn about.

@Luap99 Luap99 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

nalind added 3 commits August 7, 2026 10:34
Fixup cases where we were passing a format specifier for the error
detail when calling an assert or require helper function, but not using
the variant of the helper function that expects a format specifier, and
cases where we weren't passing a format specifier, but were using the
variant that expects one.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Introduce versions of a number of functions and some methods which take
a context.Context, to least try to provide proper cancellation support.

When copier.Get() returns an error, also write a non-NUL string after
whatever it's already written, so that a tar.Reader that reads what it
output will also flag the malformed header with an unexpected error.

In main(), connect the global default context to use a timeout set by an
experimental timeout flag, and to be canceled on the interrupt signal.

Add cancellation checks in a number of functions.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
@nalind
nalind force-pushed the cancellation branch 2 times, most recently from e702fea to 388f430 Compare August 7, 2026 14:34
@nalind

nalind commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Reordered a couple of the commits to trigger CI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants