[Proposal] docker pull return code
This is a follow up to https://github.com/moby/moby/issues/27658 //cc @neilhwatson @KristofErr @DenerKup @gregmartyn
It seems like docker pull returning different exit codes would be helpful for automating failures.
For example, to distinguish between image name doesn't exist and registry is wrong.
I think this could be useful not only for docker pull command.
I'm facing the same 'issue' with docker ps command.
for instance:
-bash-4.2# docker ps -q -a --filter='name=i-dont-exist,status=running'
-bash-4.2# echo $?
0
-bash-4.2# docker ps -q -a --filter='name=existing-container,status=running'
720021bf480f
-bash-4.2# echo $?
0
-bash-4.2#
in that case, it could be cool to have docker ps command returning something different than 0 if there is no match with what has been filtered.
@guits When something returns empty list because there are no elements or nothing matches filters it looks more like a program success neither than failure. So it is controversial issue. Maybe its better to create a separate thread for this.
In the CLI world I think folks expect searches to function like grep which returns none zero when no match is found.
I see a couple of different cases here:
- Stuff goes wrong (different statuses depending on what went wrong)
- Image was already up-to-date
- Image has been updated and is now up-to-date
I'd like to distinguish between 2 and 3 (or at least have the option to distinguish between them), so that I know whether I have to restart the running containers or not.
@rubdos Distinguishing between (2) and (3) by non-zero exit code would be detrimental for CI systems that interpret non-zero codes as failure. If (2) or (3) were to exit with non-zero status, it would require all developers to call docker pull || true. And this would mask real errors, e.g. (1). Totally wrong. In general, non-zero exit statuses mean failure - and in both cases (2) and (3) exit status zero should be returned.
so that I know whether I have to restart the running containers or not.
If your goal is to "watch" for new image versions, you should use API to check for changes.
This would be useful when automating docker pull; it would be possible to detect if an image for a running service has been updated, and only restart the service if the image has been updated
Another use case for automating docker pull.
We have a nightly job that does a pull/retag/push of a bunch of images. Currently there are two typical reasons that a pull might fail in our environment:
- The docker host runs out of disk space, or
- The registry server is being bounced.
In the first case I would like to do a system prune to clear up disk space, and then retry, in the second case I just want to wait a minute and retry. It would be useful for us to be able to distinguish between "I found the image, but couldn't download it for some reason", and "I couldn't reach the server", and "Something else failed".
Also see https://github.com/docker/cli/issues/1683
@rubdos Distinguishing between (2) and (3) by non-zero exit code would be detrimental for CI systems that interpret non-zero codes as failure. If (2) or (3) were to exit with non-zero status, it would require all developers to call
docker pull || true. And this would mask real errors, e.g. (1). Totally wrong. In general, non-zero exit statuses mean failure - and in both cases (2) and (3) exit status zero should be returned.
Ack. Maybe docker pull could have an option that sets status codes for (2) and (3). I feel like there's still people that want it.
so that I know whether I have to restart the running containers or not.
If your goal is to "watch" for new image versions, you should use API to check for changes.
Fair point, although docker pull [image] --extended-exit-codes would feel like a very cheap way to avoid calling APIs.
Any update on whether docker commands [will] return extended-exit-codes ?
Fair point, although
docker pull [image] --extended-exit-codeswould feel like a very cheap way to avoid calling APIs.
No, it's not "cheap", it's just the right price. There is a good reason people want to avoid calling APIs: it's hard, i.e. cognitively "expensive".
Bash is a perfectly viable language for certain situations. No need for a cannon (APIs) when an exit code can do just fine.
While a non-zero exit code would be nice when docker pull doesn't pull anything, it's not difficult to grep for the state you want and use grep's exit code:
docker pull python3:latest | grep '^Status: Downloaded newer image' && new_py_img_pulled.sh
If something is needed to be done when new Python image not detected, grep for ^Status: Image is up to date.
Yes, definitely Docker pull and some other commands are missing proper exit codes. I do not agree that application return codes other than 0 only if something went wrong. It depends on application. Besides if you wish to distinguish between error and non error behavior you may use (or not use) error stream. Now due to lack of error codes my CI is full of python regexes parsing output stream from docker to do tasks. Verbose outputs are a no-go for process automation and --filter flag does not suffice.
I do not agree that application return codes other than 0 only if something went wrong.
Returning non-zero status codes for "success" cases will break many things, and will not be a realistic option.
@VertigoRay that approach does work, for now at least; I don't like having to depend on magic strings though 😞
I do not agree that application return codes other than 0 only if something went wrong.
Returning non-zero status codes for "success" cases will break many things, and will not be a realistic option.
What about --extended-exit-codes as suggested above?
If something is needed to be done when new Python image not detected, grep for
^Status: Image is up to date.
NO. Parsing natural language output is criminally wrong, if only because English is not the only natural language in existence, and software gets localized.
@rulatir I was merely suggesting a workaround until docker fixes this blatant issue. It's asinine that the product development team didn't think this through during initial development. I'm sure a lot of us spend a lot of time writing and documenting hacks for poorly (yes, poorly) implemented systems, including but not limited to Docker's pull command. As for the hack/workaround that your dismissing with an terse remark, let me explain it for you: write the work around in the localized language of the system, don't change the language for the automated process, document the hack, write tests for it for pre-upgrade CI processes, and review the need for the hack annually. Hopefully docker will fix this issue by your first review.
@thaJeztah is correct, returning non-zero will not be a realistic option without explicitly requesting the ad. @gregmartyn I agree that a solution like --extended-exit-codes is better option. Extending on that, a bitwise system would be desirable to pull multiple statuses from the same exit code.
Other solutions that I've slapped together relied on the command being able to dump a status to in a parse-able format. For example, you might add a more verbose status message that can be redirected to a json file, such as outToJson=/tmp/docker_pull.json. If the process exits 0, you would know that the command ran successfully and you could go check the status in the json file. The json files would have to have status codes and more advanced status tracing to allow even the most complex status be processes via CI and handled. Just throwing another non-language option into the mix without changing exit codes and allowing for complex scenarios.
I'm doing an automated setup, I would like to get more specific exit codes when it fails, e.g.
Error response from daemon: Head "https://mysite/manifests/latest": denied: access forbidden
This just returns '1',
In this case I would like to just be able to write that you need to login etc. at the moment I have to parse the output, and that just feels like a hack.