如何处理dockerAPI /图像/创build?

Docker API的图像创build/拉(/v1.6/images/create)显然总是返回

HTTP/1.1 200 OK Content-Type: application/json 

无论过程是成功还是失败。

此外,有效载荷是无效的json。

例如:/v1.6/images/create?fromImage=whatevertheflush

收益:

 {"status":"Pulling repository whatevertheflush"}{"error":"Server error: 404 trying to fetch remote history for whatevertheflush","errorDetail":{"code":404,"message":"Server error: 404 trying to fetch remote history for whatevertheflush"}} 

不是有效的JSON,并且HTTP错误不被转发/使用使得处理客户端的错误变得尴尬。

事实上,docker-py只是呕吐有效载荷( https://github.com/dotcloud/docker-py/blob/master/docker/client.py#L374 )。 而来自openstack的DockerHTTPClient尝试返回一个基于http错误代码的值,该值始终为200 …( https://github.com/openstack/nova/blob/master/nova/virt/docker/client.py# L191 )

现在,我理解拉可能需要很长时间,并且开始向客户端stream式传输答案是有道理的,但是我不禁想到这里出了什么问题。

所以,这是三重:

  • 我在这里错过了什么吗?
  • 如果不是的话:如果你正在实现一个客户端应用程序(比如在Python中),你将如何处理这个问题(如果可能的话,优雅:))? 尝试检测有效的JSON块,加载它们,并退出,只要我们“认为”什么是错的?
  • 如果不是这样的话:在将来的docker版本中,这是否会发生改变?

这个特定的端点实际上返回分块编码。 一个例子通过curl:

 $ curl -v -X POST http://localhost:4243/images/create?fromImage=base * About to connect() to localhost port 4243 (#0) * Trying ::1... * Connection refused * Trying 127.0.0.1... * connected * Connected to localhost (127.0.0.1) port 4243 (#0) > POST /images/create?fromImage=base HTTP/1.1 > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5 > Host: localhost:4243 > Accept: */* > < HTTP/1.1 200 OK < Content-Type: application/json < Date: Fri, 07 Feb 2014 04:21:59 GMT < Transfer-Encoding: chunked < * Connection #0 to host localhost left intact {"status":"Pulling repository base"}{"status":"Pulling image (ubuntu-quantl) from base","progressDetail":{},"id":"b750fe79269d"}{"status":"Pulling image (ubuntu-quantl) from base, endpoint: https://cdn-registry-1.docker.io/v1/","progressDetail":{},"id":"b750fe79269d"}{"status":"Pulling dependent layers","progressDetail":{},"id":"b750fe79269d"}{"status":"Download complete","progressDetail":{},"id":"27cf78414709"}{"status":"Download complete","progressDetail":{},"id":"b750fe79269d"}{"status":"Download complete","progressDetail":{},"id":"b750fe79269d"}* Closing connection #0 

现在我不知道你如何去parsing这个Python,但在Ruby中,我可以像这样使用Yajl :

 parts = [] Yajl::Parser.parse(body) { |o| parts << o } puts parts {"status"=>"Pulling repository base"} {"status"=>"Pulling image (ubuntu-quantl) from base", "progressDetail"=>{}, "id"=>"b750fe79269d"} {"status"=>"Pulling image (ubuntu-quantl) from base, endpoint: https://cdn-registry-1.docker.io/v1/", "progressDetail"=>{}, "id"=>"b750fe79269d"} {"status"=>"Pulling dependent layers", "progressDetail"=>{}, "id"=>"b750fe79269d"} {"status"=>"Download complete", "progressDetail"=>{}, "id"=>"27cf78414709"} {"status"=>"Download complete", "progressDetail"=>{}, "id"=>"b750fe79269d"} {"status"=>"Download complete", "progressDetail"=>{}, "id"=>"b750fe79269d"} 

使用Docker v1.9我仍然有这个问题来处理。 在Docker Github存储库中也发现了一个问题: Docker在一些API函数#16925中使用无效的JSON格式

在某些贡献者build议使用Content-Type HTTP头的情况下: application/json; boundary=NL application/json; boundary=NL这不适合我。

然后,当我的自定义分析器挣扎,发现这个问题StackOverflow: 如何处理巨大的JSON字典stream?

以下过程将通过Docker API构build一个图像。

示例Dockerfile:

 # cat Dockerfile FROM ubuntu:14.04 RUN mkdir demo RUN apt-get update RUN apt-get -y install vim 

创build一个包含Dockerfile的tar文件。

 # tar -cvf Dockerfile.tar.gz Dockerfile 

如下所示执行API并获取更多选项,请参阅此处。

 # curl -v -X POST -H "Content-Type:application/tar" --data-binary '@Dockerfile.tar.gz' http://127.0.0.1:5000/build?t=build_test # docker images REPOSITORY TAG IMAGE ID CREATED SIZE build_test latest b1736dd9b698 8 seconds ago 

参考这个:

如何configurationdocker守护进程端口