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

Download image when starting a container using the compat API #12315

Closed
wants to merge 1 commit into from

Conversation

mscherer
Copy link
Contributor

Docker/moby will automatically pull images when using the API (or the CLI, for
that matter) to create a container, but podman don't. This break the compatibility with
some software.

I tested that using woddpecker CI, and when I use docker on F35 as the backend, it doesn't fail. Using podman-docker fail, with "image uknown".

What this PR does / why we need it:

Align the compatibility API with moby.

How to verify it

There is a attached test case. Otherwise, deploying woodpecker and using podman-docker is the way to go, or do a call the
/v1.33/containers/xxxx/start API with a image not already downloaded (eg, one not in the output of podman images) and see it fail.

Which issue(s) this PR fixes:

None

Special notes for your reviewer:

I am not 100% happy with the code, especially with the fact the call to LookupImage is duplicated. I am however not fluent enough in go to write something more idiomatic.

Docker/moby will automatically pull images when using the API (or the CLI, for
that matter) to create a container, but podman don't. This break the compatibility with
some software.
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Nov 16, 2021

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mscherer
To complete the pull request process, please assign tomsweeneyredhat after the PR has been reviewed.
You can assign the PR to them by writing /assign @tomsweeneyredhat in a comment when ready.

The full list of commands accepted by this bot can be found 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

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

In order to pass CI, you need to sign your commit via git commit --ammend -s and repush.

@containers/podman-maintainers PTAL

@mheon
Copy link
Member

mheon commented Nov 16, 2021

Are we absolutely sure that this is what Docker does? Because Docker definitely documents that they return a 404 from the create endpoint when the image isn't present.

I'd be more inclined to believe our error response is slightly wrong and it's not triggering a conditional that would normally pull the image?

@mheon
Copy link
Member

mheon commented Nov 16, 2021

I went digging in the Moby source, and I can confirm that they do not do this - it's definitely a 404 on image not existing when Create is hit.

@vrothberg
Copy link
Member

Thank you for checking, @mheon! Are the Python bindings doing the pull? Just guessing.

@mheon
Copy link
Member

mheon commented Nov 16, 2021

Possible? Didn't check around there.
I know that some Docker clients do a blind /containers/create call, and checks the HTTP return with a string comparison (despite having a dedicated HTTP return code, 404, for "no such image") on the returned error, and from there attempt a pull if they think it's a missing image. My suspicion is that is what is happening and our error might not match precisely enough for this to work.

@mscherer
Copy link
Contributor Author

Ok, I will check woodpecker code. I just tested with docker and podman (with and without the patch), and indeed, it worked with docker, but I should have searched further rather than just jump in coding.

@mscherer
Copy link
Contributor Author

Ok so indeed, here is what is returned by docker (along a 404):

{"message":"No such image: a6543/test_git_plugin:latest"}

and so woodpecker do "POST /v1.33/images/create?fromImage=a6543%2Ftest_git_plugin&tag=latest"

I will compare with the same trace from podman.

@mscherer
Copy link
Contributor Author

And what podman HEAD answer:

{"cause":"image not known","message":"docker.io/a6543/test_git_plugin:latest: image not known","response":404}

@mscherer
Copy link
Contributor Author

Ok so indeed, the retry is on woodpecker side on https://github.com/woodpecker-ci/woodpecker/blob/master/pipeline/backend/docker/docker.go#L91-L92

        _, err := e.client.ContainerCreate(ctx, config, hostConfig, nil, nil, proc.Name)
        if client.IsErrNotFound(err) {

Client is from github.com/moby/moby/client, https://github.com/moby/moby/blob/master/client/errors.go#L43

So the issue is not just "some client", but anything that use the official binding. I will close that PR, try to fix, and reopen a new one once I found it.

@mscherer mscherer closed this Nov 16, 2021
@rhatdan
Copy link
Member

rhatdan commented Nov 16, 2021

Would this have fixed the problem:

diff --git a/pkg/api/handlers/utils/errors.go b/pkg/api/handlers/utils/errors.go
index 4a8005bfd..22894d414 100644
--- a/pkg/api/handlers/utils/errors.go
+++ b/pkg/api/handlers/utils/errors.go
@@ -26,7 +26,7 @@ func Error(w http.ResponseWriter, apiMessage string, code int, err error) {
        // Log detailed message of what happened to machine running podman service
        log.Infof("Request Failed(%s): %s", http.StatusText(code), err.Error())
        em := errorhandling.ErrorModel{
-               Because:      (errors.Cause(err)).Error(),
+               Because:      strings.ReplaceAll((errors.Cause(err)).Error(), "image not known", "No such image"),
                Message:      err.Error(),
                ResponseCode: code,
        }

@mscherer
Copy link
Contributor Author

Nope. It still say "image not known"

@mscherer
Copy link
Contributor Author

Or rather, the json returned is:

{"cause":"No such image","message":"docker.io/a6543/test_git_plugin:latest: image not known","response":404}

So it change "cause", but not "message".

@mscherer
Copy link
Contributor Author

diff --git a/pkg/api/handlers/utils/errors.go b/pkg/api/handlers/utils/errors.go
index 4a8005bfd..438dce399 100644
--- a/pkg/api/handlers/utils/errors.go
+++ b/pkg/api/handlers/utils/errors.go
@@ -3,7 +3,7 @@ package utils
 import (
        "fmt"
        "net/http"
-
+"strings"
        "github.com/containers/podman/v3/libpod/define"
        "github.com/containers/podman/v3/pkg/errorhandling"
        "github.com/containers/storage"
@@ -26,8 +26,8 @@ func Error(w http.ResponseWriter, apiMessage string, code int, err error) {
        // Log detailed message of what happened to machine running podman service
        log.Infof("Request Failed(%s): %s", http.StatusText(code), err.Error())
        em := errorhandling.ErrorModel{
-               Because:      (errors.Cause(err)).Error(),
-               Message:      err.Error(),
+               Because:      strings.ReplaceAll((errors.Cause(err)).Error(), "image not known", "No such image"),
+               Message:      strings.ReplaceAll(err.Error(), "image not known", "No such image"),
                ResponseCode: code,
        }
        WriteJSON(w, code, em)

seems to work (or rather, seems to complain about "Error response from daemon: failed to resolve image name: short-name resolution enforced but cannot prompt without a TTY" (which is weird, because this is not a short-name)

@mscherer
Copy link
Contributor Author

ok so the short-name issue is on woodpecker side.

Just changing the message is enough to fix the logic from moby client.

mscherer added a commit to mscherer/podman that referenced this pull request Nov 16, 2021
Fix containers#12315

Signed-off-by: Michael Scherer <misc@redhat.com>
mheon pushed a commit to mheon/libpod that referenced this pull request Dec 6, 2021
Fix containers#12315

Signed-off-by: Michael Scherer <misc@redhat.com>
@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 Sep 22, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants