多个docker过滤器选项是否执行本地AND或OR操作?

时间:2018-10-30 14:35:33

标签: docker

我正在尝试使用多个过滤器执行prune操作。 docs here中对此进行了介绍:

  

过滤标志(--filter)格式为“键=值”。如果有多个过滤器,则传递多个标志(例如--filter“ foo = bar” --filter“ bif = baz”)

文档中没有提及是否使用多个过滤器,例如通过逻辑ANDOR操作将它们组合在一起。

我希望它是一个AND操作,以便我可以执行以下操作:

docker image prune --all --force --filter="label=com.company.product=myproduct" \
    --filter="label!=com.company.project=proj2"

和带有以下标签的Dockerfile不会被修剪:

LABEL com.company.product="myproduct" com.company.project="proj2"

这可能吗?

2 个答案:

答案 0 :(得分:1)

简短答案

这是AND

正在测试...

3 Dockerfiles

FROM alpine
LABEL apples="fruit"

FROM alpine
LABEL oranges="fruit"

FROM alpine
LABEL apples="fruit" oranges="fruit"

3 images

$ docker image ls 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
both                latest              e9e48f31222f        11 seconds ago      4.41MB
oranges             latest              f384e4db9974        33 seconds ago      4.41MB
apples              latest              06fa8c565ec1        51 seconds ago      4.41MB

--filter测试如下*:

$ docker image ls --filter label=apples=fruit
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
both                latest              e9e48f31222f        34 seconds ago       4.41MB
apples              latest              06fa8c565ec1        About a minute ago   4.41MB

$ docker image ls --filter label=oranges=fruit
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
both                latest              e9e48f31222f        44 seconds ago       4.41MB
oranges             latest              f384e4db9974        About a minute ago   4.41MB

$ docker image ls --filter label=apples=fruit --filter label=oranges=fruit
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
both                latest              e9e48f31222f        About a minute ago   4.41MB

修剪

名为both(带有两个标签)的图像被删除:

$ docker image prune -a --filter label=apples=fruit --filter label=oranges=fruit
WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N] y
Deleted Images:
untagged: both:latest
deleted: sha256:e9e48f31222f04dd54cffb4688367338d8e061ef3b1471768c1ef6a7045007ab

*注意:docs中的docker image ls不适用于负过滤!=):

  

预测要删除的内容

     

如果您使用肯定过滤(测试标签的存在或标签是否具有特定值),则可以使用具有相同过滤语法的docker image ls来查看哪些图像与您的过滤器匹配。

     

但是,如果您使用负过滤(测试标签的缺失或标签 没有特定值),则此类型的过滤器不适用于{{1} },因此您无法轻松预测将要删除的图像。此外,docker image ls的确认提示总是警告所有悬空的图像都将被删除,即使您使用的是docker image prune

答案 1 :(得分:0)

tgogo's answer非常适合使用多个否定标签过滤器(将它们进行“或”运算)的情况。这是未记录的,我认为它不能以这种方式工作,因此我已经提交了issue about this,但对于那些现在想要此功能的人来说:

bash -c '{ docker ps -aq --filter "status=exited" && docker ps -aq --filter "label=foo" && docker ps -aq --filter "label=bar"; }' | sort | uniq -u | xargs --no-run-if-empty docker rm

在命令中添加或删除&& docker ps -aq --filter "label=<label exclude from pruning>",以添加或删除否定标签过滤器。其他非否定的过滤器应添加到docker ps的第一个实例中(例如docker ps -aq --filter "status=exited" --filter "until=24h")。 bash -c仅对于不支持上述bash特定语法的shell用户(例如fish)是必需的。