docker / docker/cli

Enhancement: add a flag to return failure as exit-code for docker cli listing commands

Open
#2,675 0 comments 0 reactions 0 assignees View on GitHub

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, perl or C calling 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.