Enhancement: add a flag to return failure as exit-code for docker cli listing commands
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 6.1k
- Forks
- 2.2k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 43
Description
Enhancement: add a flag to return failure as exit-code for docker cli listing commands
The objective of this feature request is to make easier for checking when a docker resource exists while writing a script.
Proposal
Add a flag in the listing commands on docker cli that instructs the command to return a non-zero exit code when it didn't found any resource matching the input parameters of the command.
Some possible flag name examples:
--must-find--bail-out--miss-fails--must-exists--yield-failure
Use Cases
Some examples of how using a flag like --must-find can simplify docker cli usage:
#1 Directly testing in if clause the exit code of a command with flag --must-find
if docker ps --all --quiet --filter 'name=non_my_existing_container' --must-find; then
docker container create --name my_existing_container hello-world
else
docker start my_existing_container
fi
#2 Using && or || logic operators for testing exit code of a command with flag --must-find
docker ps --all --quiet --filter 'name=non_my_existing_container' --must-find && docker start my_existing_container || docker container create --name my_existing_container hello-world
#3 Using $? for testing previous exit code of a command with flag --must-find
docker ps --all --quiet --filter 'name=non_my_existing_container'
if [ $? ]; then
docker container create --name my_existing_container hello-world
else
docker start my_existing_container
fi
Contrast the above examples with the current required workaround:
#4 Current behavior is error prone, hard to read, hard to get right and
# depends on shell implementation compatibility and extensions
if [ -z "`docker ps --quiet --all --filter 'name=non_my_existing_container'`" ]; then
docker container create --name my_existing_container hello-world
else
docker start my_existing_container
fi
Improved commands
This flag can apply to the most common docker cli commands like:
- docker ps
- docker container ls
- docker container port
- docker volume ls
- docker image ls
- docker search
- docker network ls
- docker plugin ls
It would enhance the functionality provided by the flag --filter and the combined behavior will allow further possibilities to the user.
Also this flag can apply to the cluster/swarn commands like:
- docker node ls
- docker service ls
- docker config ls
- docker registry ls
- docker secret ls
- docker stack ps
- docker app ls
Benefits
It will allow quickly and easily answer pretty common patterns for questions like:
- There is a container named "my_container" this computer?
- There is a volume named "my_container" this computer?
- The container "my_container" is running in this computer?
Surely there are many ways for getting the same information by parsing docker cli output. For instance the docker ps example above could have a workaround like:
$ test -n "`docker ps --quiet --all --filter 'name=non_my_existing_container'`" ; echo " # returned code: $? #"
# returned code: 1 #
$ test -n "`docker ps --quiet --all --filter 'name=my_existing_container'`" ; echo " # returned code: $? #"
# returned code: 0 #
However by creating a flag for this behavior has the following benefits:
- Simplify the script creation when using these patterns for checking the existence of docker resources.
- Avoid repeating hacks, boilerplate and glue code in scripts for detecting these patterns.
- Reduce unespected errors raised by mistakes in coding scripts because:
- Most of shell languages and command REPLs have surprising distinct behaviors on small differences.
- Many of these tools are tricky to debug, very error prone, faily silent and have a handfull options affecting they behaviors.
- Help standartize the behavior of these patterns across environments like:
- different operating systems like Linux, Windows, MacOs and others.
- different shells like bash, zsh, tcsh, powershell, windows cmd, etc...
- different shell behavior options like
pipefail,posix,allexport, etc... - different solutions on languages like
python,perlorCcalling docker cli.
- Make easier to learn and write scripts with docker cli:
- This will let the user focus on the functionality provided by docker instead of the fighting the scripting language.
- Reduce the effort for getting the work done by delivering the common needs of the users.
Current Behavior
Most of the listing commands in docker cli return a exit code 0 either when they found or didn't found any result.
For instance, docker ps always return 0 as exit code in this shell snippet:
$ docker container create --name my_existing_container hello-world
670d1e0421e89daecf0c9a79373b1aee60fea4ce39b3cec98e5797a71fbd506e
$ docker ps --all --filter 'name=my_existing_container' ; echo " # returned code: $? #"
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
670d1e0421e8 hello-world "/hello" About a minute ago Created my_existing_container
# returned code: 0 #
$ docker ps --all --filter 'name=non_my_existing_container' ; echo " # returned code: $? #"
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# returned code: 0 #
One could argue this behavior is correct because the command didn't failed. But there is many examples of commands returing non-zero exit code on this found/not found pattern:
$ touch existing.file
$ ls -l existing.file ; echo " # returned code: $? #"
-rw-rw-r-- 1 juarezr juarezr 0 ago 13 11:09 existing.file
# returned code: 0 #
$ ls -l non.existing.file ; echo " # returned code: $? #"
ls: cannot access 'non.existing.file': No such file or directory
# returned code: 2 #
Also some docker cli commands expose zero/non-zero exit codes on some existing/non-existing patterns:
$ docker start my_existing_container ; echo " # returned code: $? #"
my_existing_container
# returned code: 0 #
$ docker start non_my_existing_container ; echo " # returned code: $? #"
Error response from daemon: No such container: non_my_existing_container
Error: failed to start containers: non_my_existing_container
# returned code: 1 #
Other examples
$ docker volume create hello_world
hello_world
$ docker volume ls --filter 'label=hello_world' ; echo " # returned code: $? #"
DRIVER VOLUME NAME
# returned code: 0 #
$ docker volume ls --filter 'name=hello_world' ; echo " # returned code: $? #"
DRIVER VOLUME NAME
local hello_world
# returned code: 0 #
$ docker volume ls --filter 'name=non_existing' ; echo " # returned code: $? #"
DRIVER VOLUME NAME
# returned code: 0 #
$ docker container ls --filter 'name=non_my_existing_container' ; echo " # returned code: $? #"
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# returned code: 0 #
$ docker container ls --filter 'name=my_existing_container' ; echo " # returned code: $? #"
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# returned code: 0 #
$ docker search --filter 'is-official=true' hello-world ; echo " # returned code: $? #"
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
hello-world Hello World! (an example of minimal Dockeriz… 1260 [OK]
# returned code: 0 #
$ docker search --filter 'is-official=true' non_existing ; echo " # returned code: $? #"
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
# returned code: 0 #
$ docker container port my_existing_container ; echo " # returned code: $? #"
# returned code: 0 #
$ docker image ls ; echo " # returned code: $? #"
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 7 months ago 13.3kB
# returned code: 0 #
$ docker image ls --filter 'before=hello-world' ; echo " # returned code: $? #"
REPOSITORY TAG IMAGE ID CREATED SIZE
# returned code: 0 #
$ docker plugin ls ; echo " # returned code: $? #"
ID NAME DESCRIPTION ENABLED
# returned code: 0 #
$ docker app list ; echo " # returned code: $? #"
INSTALLATION APPLICATION LAST ACTION RESULT CREATED MODIFIED REFERENCE
# returned code: 0 #
$ docker network ls ; echo " # returned code: $? #"
NETWORK ID NAME DRIVER SCOPE
16219e1b752a airflow_network bridge local
513f40dbdbf7 bridge bridge local
5834572dfcd2 docker_default bridge local
87a6183b0654 host host local
cac2331e4505 none null local
e8a090b9b386 rundeck_default bridge local
# returned code: 0 #
$ docker network ls --filter 'name=non_existing' ; echo " # returned code: $? #"
NETWORK ID NAME DRIVER SCOPE
# returned code: 0 #
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The request covers Docker CLI listing commands including ps, container ls, volume ls, image ls, search, network ls, plugin ls, and cluster commands. Start by comparing the current exit-code behavior of these commands and their existing flag conventions. Done means an agreed flag consistently returns a non-zero status when no resources match, with coverage for the affected commands.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, go
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100