Skip to content
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

Add status messages to podman --remote commit #20377

Merged
merged 1 commit into from
Nov 2, 2023

Conversation

rhatdan
Copy link
Member

@rhatdan rhatdan commented Oct 16, 2023

Fixes: #19947

Does this PR introduce a user-facing change?

podman --remote commit now shows additional information when committing.

@openshift-ci openshift-ci bot added release-note approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Oct 16, 2023
@github-actions github-actions bot added the kind/api-change Change to remote API; merits scrutiny label Oct 16, 2023
@packit-as-a-service
Copy link

Cockpit tests failed for commit 019ef12e449182bf735e8db61a21c38e33b6d515. @martinpitt, @jelly, @mvollmer please check.

@martinpitt
Copy link
Contributor

The cockpit-podman failure is right, this breaks commit error messages in the API. Create a container (immediately stops), enable the API, and commit the container:

podman run --name c1 quay.io/libpod/busybox true
systemctl start podman.socket
curl --unix /run/podman/podman.sock -XPOST 'http://none/v1.12/libpod/commit?container=c1&repo=localhost/FOO'

With current podman it fails properly, with a 500 status code:

{"cause":"repository name must be lowercase","message":"CommitFailure: repository name must be lowercase","response":500}

And the journal logs the failure:

podman[1751]: @ - - [17/Oct/2023:04:51:43 +0000] "POST /v1.12/libpod/commit?container=c1&repo=localhost/FOO HTTP/1.1" 500 122 "" "curl/8.0.1"

With this PR, the call claims success (but of course does not actually create an image):

{"stream":"repository name must be lowercase\n"}

i.e. no real error code; and the journal logs a success, too:

podman[1300]: @ - - [17/Oct/2023:04:49:26 +0000] "POST /v1.12/libpod/commit?container=c1&repo=localhost/FOO HTTP/1.1" 200 49 "" "curl/8.0.1"

if err == nil {
success = true
} else {
stdout.Write([]byte(err.Error() + "\n"))
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to be the problem: merely printing the error is not the same as actually posting it through utils.Error as in line 524 -- I don't know how Go works, but I suspect that this err is only scoped inside this go func, and doesn't exist any more outside, so this construction short-circuits the error handling below.

@rhatdan rhatdan force-pushed the commit branch 2 times, most recently from cc9f27c to b813806 Compare October 17, 2023 18:37
Copy link
Member

@vrothberg vrothberg left a comment

Choose a reason for hiding this comment

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

Some comments on the error handling. We should also add a test for an error scenario and make sure that the local and remote clients return the same error.

go func() {
defer cancel()
commitImage, err = ctr.Commit(r.Context(), destImage, options)
if err == nil {
Copy link
Member

Choose a reason for hiding this comment

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

I think we should preserve the error. The error can be returned in case we didn´t stream yet. The pull endpoints do that.

Copy link
Member

Choose a reason for hiding this comment

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

Could write it to an error channel and use that in the switch table below.

Copy link
Member Author

Choose a reason for hiding this comment

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

I do not know how to trigger a failure on this. If a user specifies a bad container name, this is caught before the commit line. It would be a very strange occurance like OOM or OODisk space to cause this to fail. Unless you have an idea.

Copy link
Member

Choose a reason for hiding this comment

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

I'd try specifying some bogus change values:

podman (main) $ ./bin/podman commit --change BOGUS=FOO 123
Error: invalid change "BOGUS=FOO" - invalid instruction BOGUS

Copy link
Member

Choose a reason for hiding this comment

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

Using this branch, I get the following output with podman-remote:

podman (commit) $ ./bin/podman-remote commit --change BOGUS=FOO 123
Error: 

With 4.7, I get:

podman (commit) $ /usr/bin/podman-remote commit --change BOGUS=FOO 123
Error: CommitFailure: invalid change "BOGUS=FOO" - invalid instruction BOGU

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed

pkg/api/handlers/libpod/images.go Show resolved Hide resolved
pkg/api/handlers/libpod/images.go Show resolved Hide resolved
// description: format of the image manifest and metadata (default "oci")
// description: the repository name for the created image
// - in: query
// name: Stream
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// name: Stream
// name: stream

Stream string `json:"stream,omitempty"`
Error *jsonmessage.JSONError `json:"errorDetail,omitempty"`
// NOTE: `error` is being deprecated check https://github.com/moby/moby/blob/master/pkg/jsonmessage/jsonmessage.go#L148
ErrorMessage string `json:"error,omitempty"` // deprecate this slowly
Copy link
Member

Choose a reason for hiding this comment

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

Looks like a copy-paste issue: Why add this as a new field when the plan is to deprecate it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Cut and paste from Build
Fixed.

pkg/bindings/containers/commit.go Outdated Show resolved Hide resolved
}
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/json")
flush()
Copy link
Member

Choose a reason for hiding this comment

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

This happens too early. At that point, we may already have an error from Commit(), so we should only send OK and the content-type on first successful stream.

Copy link
Member Author

Choose a reason for hiding this comment

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

Moved to right after commit message above.

// Channels all mux'ed in select{} below to follow API commit protocol
stdout := channel.NewWriter(make(chan []byte))
defer stdout.Close()
stderr := channel.NewWriter(make(chan []byte))
Copy link
Member

Choose a reason for hiding this comment

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

IMO this should just be a chan error so we could - in theory - do error checks later on.

// Channels all mux'ed in select{} below to follow API commit protocol
options.CommitOptions.ReportWriter = stdout
var commitImage *libimage.Image
success := false
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need this anymore. The order in the switch table will hit the error before streaming.

logrus.Errorf("%v", err)
}
flush()
case e := <-stderr.Chan():
Copy link
Member

Choose a reason for hiding this comment

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

This is not being tested at the moment. I desire a test where the commit fails. Then we can make sure that the error reporting works correctly.

Copy link
Member

@vrothberg vrothberg left a comment

Choose a reason for hiding this comment

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

Error handling isn't working yet. Let's please add a new test to check for errors.

// Channels all mux'ed in select{} below to follow API commit protocol
options.CommitOptions.ReportWriter = stdout
var commitImage *libimage.Image
failed := false
Copy link
Member

Choose a reason for hiding this comment

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

We don't need that variable. The error channel signals when there was an error and it will be checked before the stream case in the switch table.

flush()
case err := <-errorChan:
writeStatusCode(http.StatusInternalServerError)
m.Stream = err.Error()
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
m.Stream = err.Error()
m.ErrorMessage = err.Error()

body := response.Body.(io.Reader)
dec := json.NewDecoder(body)
for {
var s struct {
Copy link
Member

Choose a reason for hiding this comment

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

The structs and JSON identifiers still differ. Let's move it into a place that both can share.

Copy link
Member

Choose a reason for hiding this comment

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

@rhatdan that's still open.

@packit-as-a-service
Copy link

Cockpit tests failed for commit 7b301309b7f425c1cf8e036c843d359c92b41793. @martinpitt, @jelly, @mvollmer please check.

@martinpitt
Copy link
Contributor

So that cockpit test failure is interesting, I think we need to discuss this a bit. This happens in a test which tries to commit a container with name "TEST". This is invalid, and is expected to report an error "repository name must be lowercase" through the API. The test functionally passes, but it stumbles over an additional logging of the API error on the browser console. I will adjust cockpit-podman's tests to ignore this browser error, which will unblock this PR.

However, there's one weirdness: The full error message is now:

repository name must be lowercase: Internal Server Error

which is a bit smelly? Why not just the first half? That "Internal Server Error" is misleading. Is that intended?

@martinpitt
Copy link
Contributor

martinpitt commented Oct 23, 2023

To clarify: The current test expects the error message with this pattern:

 "Failed to commit container .*: CommitFailure: repository name must be lowercase"

This PR drops the CommitFailure: part, and I'll adjust cockpit-podman's tests. However, the test does not expect the "Internal Server Error" suffix. Of course we can make the test ignore it, but it doesn't feel intended?

martinpitt added a commit to martinpitt/cockpit-podman that referenced this pull request Oct 23, 2023
Drop the "CommitFailure:" part from the expected browser error when
trying to commit a container with an invalid name. This is unnecessarily
strict, and containers/podman#20377 is going to
change it.
type BuildResponse struct {
Stream string `json:"stream,omitempty"`
Error *jsonmessage.JSONError `json:"errorDetail,omitempty"`
// NOTE: `error` is being deprecated check https://github.com/moby/moby/blob/master/pkg/jsonmessage/jsonmessage.go#L148
Copy link
Member

Choose a reason for hiding this comment

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

Same comment as above: Why use/introduce a new struct with already deprecated fields?

Copy link
Member

Choose a reason for hiding this comment

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

@rhatdan that's still open.

jelly pushed a commit to cockpit-project/cockpit-podman that referenced this pull request Oct 24, 2023
Drop the "CommitFailure:" part from the expected browser error when
trying to commit a container with an invalid name. This is unnecessarily
strict, and containers/podman#20377 is going to
change it.
@rhatdan rhatdan force-pushed the commit branch 5 times, most recently from d7343b1 to 53d92f1 Compare October 24, 2023 16:44
@packit-as-a-service
Copy link

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

@rhatdan rhatdan force-pushed the commit branch 2 times, most recently from f5da8a1 to f799a01 Compare October 24, 2023 20:21
@rhatdan
Copy link
Member Author

rhatdan commented Nov 1, 2023

@mheon
Copy link
Member

mheon commented Nov 1, 2023

LGTM, though there are a few open comments still

Copy link
Member

@vrothberg vrothberg left a comment

Choose a reason for hiding this comment

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

Added new comments on the few remaining open ones.

type BuildResponse struct {
Stream string `json:"stream,omitempty"`
Error *jsonmessage.JSONError `json:"errorDetail,omitempty"`
// NOTE: `error` is being deprecated check https://github.com/moby/moby/blob/master/pkg/jsonmessage/jsonmessage.go#L148
Copy link
Member

Choose a reason for hiding this comment

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

@rhatdan that's still open.

body := response.Body.(io.Reader)
dec := json.NewDecoder(body)
for {
var s struct {
Copy link
Member

Choose a reason for hiding this comment

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

@rhatdan that's still open.

Stream string `json:"stream,omitempty"`
Error string `json:"error,omitempty"`
Stream string `json:"stream,omitempty"`
Error *jsonmessage.JSONError `json:"errorDetail,omitempty"`
}
Copy link
Member

Choose a reason for hiding this comment

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

This could re-use the new struct, could it?

Copy link
Member Author

Choose a reason for hiding this comment

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

The deprecated warning is still being used in the docker compat bindings, so I can't remove.

Copy link
Member

Choose a reason for hiding this comment

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

Can we use another/new struct? I would have hard time trying to understand the reasoning in the future. A new struct wouldn't raise the question of why only parts are used and what's deprecated etc.

@TomSweeneyRedHat
Copy link
Member

LGTM
once @vrothberg is hip with it.

Copy link
Member

@vrothberg vrothberg left a comment

Choose a reason for hiding this comment

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

/lgtm

Let's get it in. I bikesheded enough. Thanks, @rhatdan !

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Nov 2, 2023
Copy link
Contributor

openshift-ci bot commented Nov 2, 2023

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: rhatdan, vrothberg

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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot merged commit 54fca1f into containers:main Nov 2, 2023
100 checks passed
Comment on lines +44 to +45
Expect(session).Should(Exit(0))
Expect(session.ErrorToString()).To(BeEmpty())
Copy link
Member

Choose a reason for hiding this comment

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

Shortcut (for future reference): To(ExitCleanly()). My bad for not catching this in time.

@github-actions github-actions bot added the locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments. label Feb 1, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. kind/api-change Change to remote API; merits scrutiny lgtm Indicates that a PR is ready to be merged. locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments. release-note
Projects
None yet
Development

Successfully merging this pull request may close these issues.

commit: no progress messages when remote
6 participants