3

According to the https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/list-tasks, filter can be only used to get running containers with a particular service name. For some reason, I am getting a full list of all tasks regardless of their names or desired states. I can't find any proper examples of using curl with JSON requests with Docker API. I'm using the following command:

A)

curl -X GET -H "Content-Type: application/json" -d '{"filters":[{ "service":"demo", "desired-state":"running" }]}' https://HOSTNAME:2376/tasks --cert ~/.docker/cert.pem --key ~/.docker/key.pem --cacert ~/.docker/ca.pem

Returns everything

B) trying to get something working from Docker Remote API Filter Exited

curl https://HOSTNAME:2376/containers/json?all=1&filters={%22status%22:[%22exited%22]} --cert ~/.docker/cert.pem   --key ~/.docker/key.pem   --cacert ~/.docker/ca.pem

This one returns "curl: (60) Peer's Certificate issuer is not recognized.", so I guess that curl request is malformed.

I have asked on Docker forums and they helped a little. I'm amazed that there are no proper documentation anywhere on the internet on how to use Docker API with curl or is it so obvious and I don't understand something?

Kara
  • 6,115
  • 16
  • 50
  • 57
Stobor
  • 65
  • 1
  • 6
  • You're getting a certificate error. What if you just add `-k` to the curl command line, which causes curl to accept unknown certificates? Does that solve the problem? The answer to that question may help figure out where you need to look for a solution. – larsks Oct 11 '16 at 15:20
  • ** certificates are not the problem, i can curl the required info if i don't use filters. p.s. adding -k does nothing – Stobor Oct 12 '16 at 07:59

3 Answers3

5

I should prefix this with the fact that I have never seen curl erroneously report a certificate error when there was some sort of other issue in play, but I will trust your assertion that this is not a certificate problem.


I thought at first that your argument to filters was incorrect, because according to the API reference, the filters parameter is...

a JSON encoded value of the filters (a map[string][]string) to process on the containers list.

I wasn't exactly sure how to interpret map[string][]string, so I set up a logging proxy (see below) between my Docker client and server and ran docker ps -f status=exited, which produced the following request:

GET /v1.24/containers/json?filters=%7B%22status%22%3A%7B%22exited%22%3Atrue%7D%7D HTTP/1.1\r

If we decode the argument to filters, we see that it is:

{"status":{"exited":true}}

Whereas you are passing:

{"status":["exited"]}

So that's different, obviously, and I was assuming that was the source of the problem...but when trying to verify that, I ran into a curious problem. I can't even run your curl command line as written, because curl tries to perform some globbing behavior due to the braces:

$ curl http://localhost:2376/containers/json'?filters={%22status%22:[%22exited%22]}'
curl: (3) [globbing] nested brace in column 67

If I correctly quote your arguments to filter:

$ python -c 'import urllib; print urllib.quote("""{"status":["exited"]}""")'
%7B%22status%22%3A%5B%22exited%22%5D%7D

It seems to work just fine:

$ curl http://localhost:2376/containers/json'?filters=%7B%22status%22%3A%5B%22exited%22%5D%7D'
[{"Id":...

I can get the same behavior if I use your original expression and pass -g (aka --globoff) to disable the brace expansion:

$ curl -g http://localhost:2376/containers/json'?filters={%22status%22:[%22exited%22]}'
[{"Id":...

One thing I would like to emphasize is the utility of sticking a proxy between the docker client and server. If you ever find yourself asking, "how do I use this API?", an excellent answer is to see exactly what the Docker client is doing in the same situation.


Setting up a simple logging proxy:

socat -v tcp-listen:2376,fork,reuseaddr unix-connect:/run/docker.sock
larsks
  • 277,717
  • 41
  • 399
  • 399
  • Can you share how to set a logging proxy for that purpose ? – elpddev Apr 21 '17 at 11:37
  • I feel like something important is missing here: the docs don't include "status" as one of the "available filters". Is there a more complete documentation on these filters out there, or were you guys just experimenting with filters and found that this works? – George Aristy Sep 29 '18 at 15:44
  • The [Filtering](https://docs.docker.com/engine/reference/commandline/ps/#filtering) section of the `docker ps` manual shows the `status`keyword. – larsks Sep 29 '18 at 20:19
0

You can create a logging proxy using socat. Here is an example.

docker run -v /var/run/docker.sock:/var/run/docker.sock -p 127.0.0.1:1234:1234 bobrik/socat -v TCP-LISTEN:1234,fork UNIX-CONNECT:/var/run/docker.sock

Then run a command like so in another window.

docker -H localhost:1234 run --rm -p 2222:2222  hello-world

This example uses docker on ubuntu.

myagkiy znak
  • 9
  • 1
  • 2
-2

A docker REST proxy can be simple like this:

https://github.com/laoshanxi/app-mesh/blob/main/src/sdk/docker/docker-rest.go

Then you can curl like this:

curl -g http://127.0.0.1:6058/containers/json'?filters={%22name%22:[%22jenkins%22]}'
4b0
  • 21,981
  • 30
  • 95
  • 142
Jack
  • 1