mirror of
https://github.com/moby/moby.git
synced 2026-01-16 18:31:41 +00:00
Compare commits
118 Commits
master
...
v1.11.0-rc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5e2b400ec | ||
|
|
fd018754e2 | ||
|
|
a573ab1f81 | ||
|
|
c774c390b1 | ||
|
|
896f8b337e | ||
|
|
40ff845220 | ||
|
|
60be8487c1 | ||
|
|
5e5e07e106 | ||
|
|
9e4c6c75f5 | ||
|
|
5d1b0aecd0 | ||
|
|
f685fe1a99 | ||
|
|
9e62a2aad2 | ||
|
|
460806241c | ||
|
|
651cace5ee | ||
|
|
e941f698da | ||
|
|
cc5c9013d9 | ||
|
|
c17ee39d12 | ||
|
|
eeb30821ea | ||
|
|
38c206f97b | ||
|
|
346c5297b0 | ||
|
|
e66633c39e | ||
|
|
2f69842afa | ||
|
|
c5d179891f | ||
|
|
4d7d1736bd | ||
|
|
a5b5bdbbb4 | ||
|
|
9e3bfd5864 | ||
|
|
bab77d4991 | ||
|
|
4e1ff10d60 | ||
|
|
2936442f9d | ||
|
|
c5769cf53b | ||
|
|
b84d18ec21 | ||
|
|
2e92a84fa8 | ||
|
|
deb08a1012 | ||
|
|
4b21fdc96a | ||
|
|
1818ca9d75 | ||
|
|
9db0bd88f5 | ||
|
|
b98f05b4f4 | ||
|
|
ed2fcd9a2a | ||
|
|
1e67fdf3e4 | ||
|
|
2a60e5cac6 | ||
|
|
c319887dbb | ||
|
|
3fd08cc5e6 | ||
|
|
cd062fd3b3 | ||
|
|
55186eae32 | ||
|
|
76215b3268 | ||
|
|
f97f3e98fc | ||
|
|
7500c8cc72 | ||
|
|
c3eed8430c | ||
|
|
073d7841b4 | ||
|
|
8b0179c771 | ||
|
|
85d1517184 | ||
|
|
b59dced332 | ||
|
|
89ede3ae23 | ||
|
|
8facb73a8f | ||
|
|
c4fa814ecd | ||
|
|
e9279d57f7 | ||
|
|
01c531a72e | ||
|
|
a17e61c020 | ||
|
|
19b22712c0 | ||
|
|
e6629d4c10 | ||
|
|
0c598f34b6 | ||
|
|
e799da7e6a | ||
|
|
50552642ca | ||
|
|
474631498c | ||
|
|
08ccfd36e1 | ||
|
|
c3b3f8201a | ||
|
|
81a3a72727 | ||
|
|
70c594508f | ||
|
|
1fa9574e2b | ||
|
|
4a59dc5a41 | ||
|
|
c4b33d5334 | ||
|
|
197d61d01a | ||
|
|
abe8c11e36 | ||
|
|
08d09e7733 | ||
|
|
e23f622d38 | ||
|
|
73f7f515be | ||
|
|
501b0c387d | ||
|
|
cf1d012fda | ||
|
|
ad37aac45b | ||
|
|
f66010ad31 | ||
|
|
34fca93daf | ||
|
|
048db1da22 | ||
|
|
e768fc8468 | ||
|
|
31755449e1 | ||
|
|
fef9c5b432 | ||
|
|
519ac1252c | ||
|
|
89276c679e | ||
|
|
5a71ca6739 | ||
|
|
92c9bab6ab | ||
|
|
f04334ea04 | ||
|
|
ea799625bd | ||
|
|
3ef31215f4 | ||
|
|
4b03e857de | ||
|
|
c5e8051c81 | ||
|
|
6d324b4192 | ||
|
|
060330bf46 | ||
|
|
413155df6e | ||
|
|
48ce060e8c | ||
|
|
6106313b20 | ||
|
|
ae4f265053 | ||
|
|
4fc85b47fc | ||
|
|
3e890411bc | ||
|
|
1987d6e5df | ||
|
|
e4995d1517 | ||
|
|
6558158dc3 | ||
|
|
c985e2b84b | ||
|
|
6be088a3eb | ||
|
|
8c390f0987 | ||
|
|
d8ba21d07d | ||
|
|
b9d6c87592 | ||
|
|
03238022c8 | ||
|
|
1f8ea55c3d | ||
|
|
6fa49df0d9 | ||
|
|
32a5308237 | ||
|
|
76489af40f | ||
|
|
fad79467dd | ||
|
|
e651c1b2b9 | ||
|
|
b6f3c16ddc |
82
.mailmap
82
.mailmap
@@ -93,7 +93,8 @@ Sven Dowideit <SvenDowideit@home.org.au> <¨SvenDowideit@home.org.au¨>
|
||||
Sven Dowideit <SvenDowideit@home.org.au> <SvenDowideit@users.noreply.github.com>
|
||||
Sven Dowideit <SvenDowideit@home.org.au> <sven@t440s.home.gateway>
|
||||
<alexl@redhat.com> <alexander.larsson@gmail.com>
|
||||
Alexandr Morozov <lk4d4math@gmail.com>
|
||||
Alexander Morozov <lk4d4@docker.com> <lk4d4math@gmail.com>
|
||||
Alexander Morozov <lk4d4@docker.com>
|
||||
<git.nivoc@neverbox.com> <kuehnle@online.de>
|
||||
O.S. Tezer <ostezer@gmail.com>
|
||||
<ostezer@gmail.com> <ostezer@users.noreply.github.com>
|
||||
@@ -106,7 +107,9 @@ Roberto G. Hashioka <roberto.hashioka@docker.com> <roberto_hashioka@hotmail.com>
|
||||
Sridhar Ratnakumar <sridharr@activestate.com>
|
||||
Sridhar Ratnakumar <sridharr@activestate.com> <github@srid.name>
|
||||
Liang-Chi Hsieh <viirya@gmail.com>
|
||||
Aleksa Sarai <cyphar@cyphar.com>
|
||||
Aleksa Sarai <asarai@suse.de>
|
||||
Aleksa Sarai <asarai@suse.de> <asarai@suse.com>
|
||||
Aleksa Sarai <asarai@suse.de> <cyphar@cyphar.com>
|
||||
Will Weaver <monkey@buildingbananas.com>
|
||||
Timothy Hobbs <timothyhobbs@seznam.cz>
|
||||
Nathan LeClaire <nathan.leclaire@docker.com> <nathan.leclaire@gmail.com>
|
||||
@@ -117,24 +120,27 @@ Nathan LeClaire <nathan.leclaire@docker.com> <nathanleclaire@gmail.com>
|
||||
<marc@marc-abramowitz.com> <msabramo@gmail.com>
|
||||
Matthew Heon <mheon@redhat.com> <mheon@mheonlaptop.redhat.com>
|
||||
<bernat@luffy.cx> <vincent@bernat.im>
|
||||
<bernat@luffy.cx> <Vincent.Bernat@exoscale.ch>
|
||||
<p@pwaller.net> <peter@scraperwiki.com>
|
||||
<andrew.weiss@outlook.com> <andrew.weiss@microsoft.com>
|
||||
Francisco Carriedo <fcarriedo@gmail.com>
|
||||
<julienbordellier@gmail.com> <git@julienbordellier.com>
|
||||
<ahmetb@microsoft.com> <ahmetalpbalkan@gmail.com>
|
||||
<lk4d4@docker.com> <lk4d4math@gmail.com>
|
||||
<arnaud.porterie@docker.com> <icecrime@gmail.com>
|
||||
<baloo@gandi.net> <superbaloo+registrations.github@superbaloo.net>
|
||||
Brian Goff <cpuguy83@gmail.com>
|
||||
<cpuguy83@gmail.com> <bgoff@cpuguy83-mbp.home>
|
||||
<ewindisch@docker.com> <eric@windisch.us>
|
||||
<eric@windisch.us> <ewindisch@docker.com>
|
||||
<frank.rosquin+github@gmail.com> <frank.rosquin@gmail.com>
|
||||
Hollie Teal <hollie@docker.com>
|
||||
<hollie@docker.com> <hollie.teal@docker.com>
|
||||
<hollie@docker.com> <hollietealok@users.noreply.github.com>
|
||||
<huu@prismskylabs.com> <whoshuu@gmail.com>
|
||||
Jessica Frazelle <jess@docker.com> Jessie Frazelle <jfrazelle@users.noreply.github.com>
|
||||
<jess@docker.com> <jfrazelle@users.noreply.github.com>
|
||||
Jessica Frazelle <jess@mesosphere.com>
|
||||
Jessica Frazelle <jess@mesosphere.com> <jfrazelle@users.noreply.github.com>
|
||||
Jessica Frazelle <jess@mesosphere.com> <acidburn@docker.com>
|
||||
Jessica Frazelle <jess@mesosphere.com> <jess@docker.com>
|
||||
Jessica Frazelle <jess@mesosphere.com> <princess@docker.com>
|
||||
<konrad.wilhelm.kleine@gmail.com> <kwk@users.noreply.github.com>
|
||||
<tintypemolly@gmail.com> <tintypemolly@Ohui-MacBook-Pro.local>
|
||||
<estesp@linux.vnet.ibm.com> <estesp@gmail.com>
|
||||
@@ -142,6 +148,8 @@ Jessica Frazelle <jess@docker.com> Jessie Frazelle <jfrazelle@users.noreply.gith
|
||||
Thomas LEVEIL <thomasleveil@gmail.com> Thomas LÉVEIL <thomasleveil@users.noreply.github.com>
|
||||
<oi@truffles.me.uk> <timruffles@googlemail.com>
|
||||
<Vincent.Bernat@exoscale.ch> <bernat@luffy.cx>
|
||||
Antonio Murdaca <antonio.murdaca@gmail.com> <amurdaca@redhat.com>
|
||||
Antonio Murdaca <antonio.murdaca@gmail.com> <runcom@redhat.com>
|
||||
Antonio Murdaca <antonio.murdaca@gmail.com> <me@runcom.ninja>
|
||||
Antonio Murdaca <antonio.murdaca@gmail.com> <runcom@linux.com>
|
||||
Antonio Murdaca <antonio.murdaca@gmail.com> <runcom@users.noreply.github.com>
|
||||
@@ -151,8 +159,9 @@ Deshi Xiao <dxiao@redhat.com> <xiaods@gmail.com>
|
||||
Doug Davis <dug@us.ibm.com> <duglin@users.noreply.github.com>
|
||||
Jacob Atzen <jacob@jacobatzen.dk> <jatzen@gmail.com>
|
||||
Jeff Nickoloff <jeff.nickoloff@gmail.com> <jeff@allingeek.com>
|
||||
<jess@docker.com> <princess@docker.com>
|
||||
John Howard (VM) <John.Howard@microsoft.com> John Howard <jhoward@microsoft.com>
|
||||
John Howard (VM) <John.Howard@microsoft.com>
|
||||
John Howard (VM) <John.Howard@microsoft.com> <john.howard@microsoft.com>
|
||||
John Howard (VM) <John.Howard@microsoft.com> <jhoward@microsoft.com>
|
||||
Madhu Venugopal <madhu@socketplane.io> <madhu@docker.com>
|
||||
Mary Anthony <mary.anthony@docker.com> <mary@docker.com>
|
||||
Mary Anthony <mary.anthony@docker.com> moxiegirl <mary@docker.com>
|
||||
@@ -169,3 +178,60 @@ bin liu <liubin0329@users.noreply.github.com> <liubin0329@gmail.com>
|
||||
John Howard (VM) <John.Howard@microsoft.com> jhowardmsft <jhoward@microsoft.com>
|
||||
Ankush Agarwal <ankushagarwal11@gmail.com> <ankushagarwal@users.noreply.github.com>
|
||||
Tangi COLIN <tangicolin@gmail.com> tangicolin <tangicolin@gmail.com>
|
||||
Allen Sun <allen.sun@daocloud.io>
|
||||
Adrien Gallouët <adrien@gallouet.fr> <angt@users.noreply.github.com>
|
||||
<aanm90@gmail.com> <martins@noironetworks.com>
|
||||
Anuj Bahuguna <anujbahuguna.dev@gmail.com>
|
||||
Anusha Ragunathan <anusha.ragunathan@docker.com> <anusha@docker.com>
|
||||
Avi Miller <avi.miller@oracle.com> <avi.miller@gmail.com>
|
||||
Brent Salisbury <brent.salisbury@docker.com> <brent@docker.com>
|
||||
Chander G <chandergovind@gmail.com>
|
||||
Chun Chen <ramichen@tencent.com> <chenchun.feed@gmail.com>
|
||||
Ying Li <cyli@twistedmatrix.com>
|
||||
Daehyeok Mun <daehyeok@gmail.com> <daehyeok@daehyeok-ui-MacBook-Air.local>
|
||||
<dqminh@cloudflare.com> <dqminh89@gmail.com>
|
||||
Daniel, Dao Quang Minh <dqminh@cloudflare.com>
|
||||
Daniel Nephin <dnephin@docker.com> <dnephin@gmail.com>
|
||||
Dave Tucker <dt@docker.com> <dave@dtucker.co.uk>
|
||||
Doug Tangren <d.tangren@gmail.com>
|
||||
Frederick F. Kautz IV <fkautz@redhat.com> <fkautz@alumni.cmu.edu>
|
||||
Ben Golub <ben.golub@dotcloud.com>
|
||||
Harold Cooper <hrldcpr@gmail.com>
|
||||
hsinko <21551195@zju.edu.cn> <hsinko@users.noreply.github.com>
|
||||
Josh Hawn <josh.hawn@docker.com> <jlhawn@berkeley.edu>
|
||||
Justin Cormack <justin.cormack@docker.com>
|
||||
<justin.cormack@docker.com> <justin.cormack@unikernel.com>
|
||||
<justin.cormack@docker.com> <justin@specialbusservice.com>
|
||||
Kamil Domański <kamil@domanski.co>
|
||||
Lei Jitang <leijitang@huawei.com>
|
||||
<leijitang@huawei.com> <leijitang@gmail.com>
|
||||
Linus Heckemann <lheckemann@twig-world.com>
|
||||
<lheckemann@twig-world.com> <anonymouse2048@gmail.com>
|
||||
Lynda O'Leary <lyndaoleary29@gmail.com>
|
||||
<lyndaoleary29@gmail.com> <lyndaoleary@hotmail.com>
|
||||
Marianna Tessel <mtesselh@gmail.com>
|
||||
Michael Huettermann <michael@huettermann.net>
|
||||
Moysés Borges <moysesb@gmail.com>
|
||||
<moysesb@gmail.com> <moyses.furtado@wplex.com.br>
|
||||
Nigel Poulton <nigelpoulton@hotmail.com>
|
||||
Qiang Huang <h.huangqiang@huawei.com>
|
||||
<h.huangqiang@huawei.com> <qhuang@10.0.2.15>
|
||||
Boaz Shuster <ripcurld.github@gmail.com>
|
||||
Shuwei Hao <haosw@cn.ibm.com>
|
||||
<haosw@cn.ibm.com> <haoshuwei24@gmail.com>
|
||||
Soshi Katsuta <soshi.katsuta@gmail.com>
|
||||
<soshi.katsuta@gmail.com> <katsuta_soshi@cyberagent.co.jp>
|
||||
Stefan Berger <stefanb@linux.vnet.ibm.com>
|
||||
<stefanb@linux.vnet.ibm.com> <stefanb@us.ibm.com>
|
||||
Stephen Day <stephen.day@docker.com>
|
||||
<stephen.day@docker.com> <stevvooe@users.noreply.github.com>
|
||||
Toli Kuznets <toli@docker.com>
|
||||
Tristan Carel <tristan@cogniteev.com>
|
||||
<tristan@cogniteev.com> <tristan.carel@gmail.com>
|
||||
Vincent Demeester <vincent@sbr.pm>
|
||||
<vincent@sbr.pm> <vincent+github@demeester.fr>
|
||||
Vishnu Kannan <vishnuk@google.com>
|
||||
xlgao-zju <xlgao@zju.edu.cn> xlgao <xlgao@zju.edu.cn>
|
||||
yuchangchun <yuchangchun1@huawei.com> y00277921 <yuchangchun1@huawei.com>
|
||||
<zij@case.edu> <zjaffee@us.ibm.com>
|
||||
|
||||
|
||||
163
CHANGELOG.md
163
CHANGELOG.md
@@ -2,9 +2,148 @@
|
||||
|
||||
Items starting with `DEPRECATE` are important deprecation notices. For more
|
||||
information on the list of deprecated flags and APIs please have a look at
|
||||
https://docs.docker.com/misc/deprecated/ where target removal dates can also
|
||||
https://docs.docker.com/engine/deprecated/ where target removal dates can also
|
||||
be found.
|
||||
|
||||
## 1.11.0 (2016-04-12)
|
||||
|
||||
**IMPORTANT**: With Docker 1.11, a Linux docker installation is now made of 4 binaries (`docker`, [`docker-containerd`](https://github.com/docker/containerd), [`docker-containerd-shim`](https://github.com/docker/containerd) and [`docker-runc`](https://github.com/opencontainers/runc)). If you have scripts relying on docker being a single static binaries, please make sure to update them. Interaction with the daemon stay the same otherwise, the usage of the other binaries should be transparent. A Windows docker installation remains a single binary, `docker.exe`.
|
||||
|
||||
### Builder
|
||||
|
||||
- Fix docker not sending credentials during build if content trust is enabled ([#21693](https://github.com/docker/docker/pull/21693))
|
||||
- Fix a bug where Docker would not used the correct uid/gid when processing the `WORKDIR` command ([#21033](https://github.com/docker/docker/pull/21033))
|
||||
- Fix a bug where copy operations with userns would not use the proper uid/gid ([#20782](https://github.com/docker/docker/pull/20782), [#21162](https://github.com/docker/docker/pull/21162))
|
||||
|
||||
### Client
|
||||
|
||||
* Usage of the `:` separator for security option has been deprecated. `=` should be used instead ([#21232](https://github.com/docker/docker/pull/21232))
|
||||
+ The client user agent is now passed to the registry on `pull`, `build`, `push`, `login` and `search` operations ([#21306](https://github.com/docker/docker/pull/21306), [#21373](https://github.com/docker/docker/pull/21373))
|
||||
* Allow setting the Domainname and Hostname separately through the API ([#20200](https://github.com/docker/docker/pull/20200))
|
||||
* Docker info will now warn users if it can not detect the kernel version or the operating system ([#21128](https://github.com/docker/docker/pull/21128))
|
||||
- Fix an issue where `docker stats --no-stream` output could be all 0s ([#20803](https://github.com/docker/docker/pull/20803))
|
||||
- Fix a bug where some newly started container would not appear in a running `docker stats` command ([#20792](https://github.com/docker/docker/pull/20792))
|
||||
* Post processing is no longer enabled for linux-cgo terminals ([#20587](https://github.com/docker/docker/pull/20587))
|
||||
- Values to `--hostname` are now refused if they do not comply with [RFC1123](https://tools.ietf.org/html/rfc1123) ([#20566](https://github.com/docker/docker/pull/20566))
|
||||
+ Docker learned how to use a SOCKS proxy ([#20366](https://github.com/docker/docker/pull/20366), [#18373](https://github.com/docker/docker/pull/18373))
|
||||
+ Docker now supports external credential stores ([#20107](https://github.com/docker/docker/pull/20107))
|
||||
* `docker ps` now supports displaying the list of volumes mounted inside a container ([#20017](https://github.com/docker/docker/pull/20017))
|
||||
* `docker info` now also report Docker's root directory location ([#19986](https://github.com/docker/docker/pull/19986))
|
||||
- Docker now prohibits login in with an empty username (spaces are trimmed) ([#19806](https://github.com/docker/docker/pull/19806))
|
||||
* Docker events attributes are now sorted by key ([#19761](https://github.com/docker/docker/pull/19761))
|
||||
* `docker ps` no longer show exported port for stopped containers ([#19483](https://github.com/docker/docker/pull/19483))
|
||||
- Docker now cleans after itself if a save/export command fails ([#17849](https://github.com/docker/docker/pull/17849))
|
||||
* Docker load learned how to display a progress bar ([#17329](https://github.com/docker/docker/pull/17329), [#120078](https://github.com/docker/docker/pull/20078))
|
||||
|
||||
### Distribution
|
||||
|
||||
- Fix the download manager closing the tempfile twice ([#21676](https://github.com/docker/docker/pull/21676))
|
||||
- Fix a panic that occurred when pulling an images with 0 layers ([#21222](https://github.com/docker/docker/pull/21222))
|
||||
- Fix a panic that could occur on error while pushing to a registry with a misconfigured token service ([#21212](https://github.com/docker/docker/pull/21212))
|
||||
+ All first-level delegation roles are now signed when doing a trusted push ([#21046](https://github.com/docker/docker/pull/21046))
|
||||
+ OAuth support for registries was added ([#20970](https://github.com/docker/docker/pull/20970))
|
||||
* `docker login` now handles token using the implementation found in [docker/distribution](https://github.com/docker/distribution) ([#20832](https://github.com/docker/docker/pull/20832))
|
||||
* `docker login` will no longer prompt for an email ([#20565](https://github.com/docker/docker/pull/20565))
|
||||
* Docker will now fallback to registry V1 if no basic auth credentials are available ([#20241](https://github.com/docker/docker/pull/20241))
|
||||
* Docker will now try to resume layer download where it left off after a network error/timeout ([#19840](https://github.com/docker/docker/pull/19840))
|
||||
- Fix generated manifest mediaType when pushing cross-repository ([#19509](https://github.com/docker/docker/pull/19509))
|
||||
|
||||
### Logging
|
||||
|
||||
- Fix a race in the journald log driver ([#21311](https://github.com/docker/docker/pull/21311))
|
||||
* Docker syslog driver now uses the RFC-5424 format when emitting logs ([#20121](https://github.com/docker/docker/pull/20121))
|
||||
* Docker GELF log driver now allows to specify the compression algorithm and level via the `gelf-compression-type` and `gelf-compression-level` options ([#19831](https://github.com/docker/docker/pull/19831))
|
||||
* Docker daemon learned to output uncolorized logs via the `--raw-logs` options ([#19794](https://github.com/docker/docker/pull/19794))
|
||||
+ Docker, on Windows platform, now includes an ETW (Event Tracing in Windows) logging driver named `etwlogs` ([#19689](https://github.com/docker/docker/pull/19689))
|
||||
* Journald log driver learned how to handle tags ([#19564](https://github.com/docker/docker/pull/19564))
|
||||
+ The fluentd log driver learned the following options: `fluentd-address`, `fluentd-buffer-limit`, `fluentd-retry-wait`, `fluentd-max-retries` and `fluentd-async-connect` ([#19439](https://github.com/docker/docker/pull/19439))
|
||||
+ Docker learned to send log to Google Cloud via the new `gcplogs` logging driver. ([#18766](https://github.com/docker/docker/pull/18766))
|
||||
|
||||
|
||||
### Misc
|
||||
|
||||
+ When saving linked images together with `docker save` a subsequent `docker load` will correctly restore their parent/child relationship ([#21385](https://github.com/docker/docker/pull/c))
|
||||
+ Support for building the Docker cli for OpenBSD was added ([#21325](https://github.com/docker/docker/pull/21325))
|
||||
+ Labels can now be applied at network, volume and image creation ([#21270](https://github.com/docker/docker/pull/21270))
|
||||
* The `dockremap` is now created as a system user ([#21266](https://github.com/docker/docker/pull/21266))
|
||||
- Fix a few response body leaks ([#21258](https://github.com/docker/docker/pull/21258))
|
||||
- Docker, when run as a service with systemd, will now properly manage its processes cgroups ([#20633](https://github.com/docker/docker/pull/20633))
|
||||
* Docker info now reports the value of cgroup KernelMemory or emits a warning if it is not supported ([#20863](https://github.com/docker/docker/pull/20863))
|
||||
* Docker info now also reports the cgroup driver in use ([#20388](https://github.com/docker/docker/pull/20388))
|
||||
* Docker completion is now available on PowerShell ([#19894](https://github.com/docker/docker/pull/19894))
|
||||
* `dockerinit` is no more ([#19490](https://github.com/docker/docker/pull/19490),[#19851](https://github.com/docker/docker/pull/19851))
|
||||
+ Support for building Docker on arm64 was added ([#19013](https://github.com/docker/docker/pull/19013))
|
||||
+ Experimental support for building docker.exe in a native Windows Docker installation ([#18348](https://github.com/docker/docker/pull/18348))
|
||||
|
||||
### Networking
|
||||
|
||||
- Fix panic if a node is forcibly removed from the cluster ([#21671](https://github.com/docker/docker/pull/21671))
|
||||
- Fix "error creating vxlan interface" when starting a container in a Swarm cluster ([#21671](https://github.com/docker/docker/pull/21671))
|
||||
- Fix `host` and `none` networks to disappear until restart when SIGHUP is used to reload cluster configuration ([#21671](https://github.com/docker/docker/pull/21671))
|
||||
- Fix a bug where IPv6 addresses were not properly handled ([#20842](https://github.com/docker/docker/pull/20842))
|
||||
* `docker network inspect` will now report all endpoints whether they have an active container or not ([#21160](https://github.com/docker/docker/pull/21160))
|
||||
+ Experimental support for the MacVlan and IPVlan network drivers have been added ([#21122](https://github.com/docker/docker/pull/21122))
|
||||
* Output of `docker network ls` is now sorted by network name ([#20383](https://github.com/docker/docker/pull/20383))
|
||||
- Fix a bug where Docker would allow a network to be created with the reserved `default` name ([#19431](https://github.com/docker/docker/pull/19431))
|
||||
* `docker network inspect` now returns whether a network is internal or not ([#19357](https://github.com/docker/docker/pull/19357))
|
||||
+ Control IPv6 via explicit option when creating a network (`docker network create --ipv6`). This shows up as a new `EnableIPv6` field in `docker network inspect` ([#17513](https://github.com/docker/docker/pull/17513))
|
||||
* Support for AAAA Records (aka IPv6 Service Discovery) in embedded DNS Server [#21396](https://github.com/docker/docker/pull/21396)
|
||||
* Multiple A/AAAA records from embedded DNS Server for DNS Round robin [#21019](https://github.com/docker/docker/pull/21019)
|
||||
|
||||
### Plugins
|
||||
|
||||
- Fix a file descriptor leak that would occur every time plugins were enumerated ([#20686](https://github.com/docker/docker/pull/20686))
|
||||
- Fix an issue where Authz plugin would corrupt the payload body when faced with a large amount of data ([#20602](https://github.com/docker/docker/pull/20602))
|
||||
|
||||
### Runtime
|
||||
|
||||
- Fix a panic that could occur when cleanup after a container started with invalid parameters ([#21716](https://github.com/docker/docker/pull/21716))
|
||||
- Fix a race with event timers stopping early ([#21692](https://github.com/docker/docker/pull/21692))
|
||||
- Fix race conditions in the layer store, potentially corrupting the map and crashing the process ([#21677](https://github.com/docker/docker/pull/21677))
|
||||
- Un-deprecate auto-creation of host directories for mounts. This feature was marked deprecated in ([#21666](https://github.com/docker/docker/pull/21666))
|
||||
Docker 1.9, but was decided to be too much of an backward-incompatible change, so it was decided to keep the feature.
|
||||
- Fix an issue where parallel aufs mount calls produce invalid argument error ([#21552](https://github.com/docker/docker/pull/21552))
|
||||
+ It is now possible for containers to share the NET and IPC namespaces when `userns` is enabled ([#21383](https://github.com/docker/docker/pull/21383))
|
||||
+ `docker inspect <image-id>` will now expose the rootfs layers ([#21370](https://github.com/docker/docker/pull/21370))
|
||||
+ Docker Windows gained a minimal `top` implementation ([#21354](https://github.com/docker/docker/pull/21354))
|
||||
* Docker learned to report the faulty exe when a container cannot be started due to its condition ([#21345](https://github.com/docker/docker/pull/21345))
|
||||
* Docker with device mapper will now refuse to run if `udev sync` is not available ([#21097](https://github.com/docker/docker/pull/21097))
|
||||
- Fix a bug where Docker would not validate the config file upon configuration reload ([#21089](https://github.com/docker/docker/pull/21089))
|
||||
- Fix a hang that would happen on attach if initial start was to fail ([#21048](https://github.com/docker/docker/pull/21048))
|
||||
- Fix an issue where registry service options in the daemon configuration file were not properly taken into account ([#21045](https://github.com/docker/docker/pull/21045))
|
||||
- Fix a race between the exec and resize operations ([#21022](https://github.com/docker/docker/pull/21022))
|
||||
- Fix an issue where nanoseconds were not correctly taken in account when filtering Docker events ([#21013](https://github.com/docker/docker/pull/21013))
|
||||
- Fix the handling of Docker command when passed a 64 bytes id ([#21002](https://github.com/docker/docker/pull/21002))
|
||||
* Docker will now return a `204` (i.e http.StatusNoContent) code when it successfully deleted a network ([#20977](https://github.com/docker/docker/pull/20977))
|
||||
- Fix a bug where the daemon would wait indefinitely in case the process it was about to killed had already exited on its own ([#20967](https://github.com/docker/docker/pull/20967)
|
||||
* The devmapper driver learned the `dm.min_free_space` option. If the mapped device free space reaches the passed value, new device creation will be prohibited. ([#20786](https://github.com/docker/docker/pull/20786))
|
||||
+ Docker can now prevent processes in container to gain new privileges via the `--security-opt=no-new-privileges` flag ([#20727](https://github.com/docker/docker/pull/20727))
|
||||
- Starting a container with the `--device` option will now correctly resolves symlinks ([#20684](https://github.com/docker/docker/pull/20684))
|
||||
+ Docker now relies on [`containerd`](https://github.com/docker/containerd) and [`runc`](https://github.com/opencontainers/runc) to spawn containers. ([#20662](https://github.com/docker/docker/pull/20662))
|
||||
- Fix docker configuration reloading to only alter value present in the given config file ([#20604](https://github.com/docker/docker/pull/20604))
|
||||
+ Docker now allows setting a container hostname via the `--hostname` flag when `--net=host` ([#20177](https://github.com/docker/docker/pull/20177))
|
||||
+ Docker now allows executing privileged container while running with `--userns-remap` if both `--privileged` and the new `--userns=host` flag are specified ([#20111](https://github.com/docker/docker/pull/20111))
|
||||
- Fix Docker not cleaning up correctly old containers upon restarting after a crash ([#19679](https://github.com/docker/docker/pull/19679))
|
||||
* Docker will now error out if it doesn't recognize a configuration key within the config file ([#19517](https://github.com/docker/docker/pull/19517))
|
||||
- Fix container loading, on daemon startup, when they depends on a plugin running within a container ([#19500](https://github.com/docker/docker/pull/19500))
|
||||
* `docker update` learned how to change a container restart policy ([#19116](https://github.com/docker/docker/pull/19116))
|
||||
* `docker inspect` now also returns a new `State` field containing the container state in a human readable way (i.e. one of `created`, `restarting`, `running`, `paused`, `exited` or `dead`)([#18966](https://github.com/docker/docker/pull/18966))
|
||||
+ Docker learned to limit the number of active pids (i.e. processes) within the container via the `pids-limit` flags. NOTE: This requires `CGROUP_PIDS=y` to be in the kernel configuration. ([#18697](https://github.com/docker/docker/pull/18697))
|
||||
- `docker load` now has a `--quiet` option to suppress the load output ([#20078](https://github.com/docker/docker/pull/20078))
|
||||
|
||||
### Security
|
||||
|
||||
* Object with the `pcp_pmcd_t` selinux type were given management access to `/var/lib/docker(/.*)?` ([#21370](https://github.com/docker/docker/pull/21370))
|
||||
* `restart_syscall`, `copy_file_range`, `mlock2` joined the list of allowed calls in the default seccomp profile ([#21117](https://github.com/docker/docker/pull/21117), [#21262](https://github.com/docker/docker/pull/21262))
|
||||
* `send`, `recv` and `x32` were added to the list of allowed syscalls and arch in the default seccomp profile ([#19432](https://github.com/docker/docker/pull/19432))
|
||||
|
||||
### Volumes
|
||||
|
||||
* Output of `docker volume ls` is now sorted by volume name ([#20389](https://github.com/docker/docker/pull/20389))
|
||||
* Local volumes can now accepts options similar to the unix `mount` tool ([#20262](https://github.com/docker/docker/pull/20262))
|
||||
- Fix an issue where one letter directory name could not be used as source for volumes ([#21106](https://github.com/docker/docker/pull/21106))
|
||||
+ `docker run -v` now accepts a new flag `nocopy`. This tell the runtime not to copy the container path content into the volume (which is the default behavior) ([#21223](https://github.com/docker/docker/pull/21223))
|
||||
|
||||
## 1.10.3 (2016-03-10)
|
||||
|
||||
### Runtime
|
||||
@@ -25,9 +164,9 @@ be found.
|
||||
|
||||
### Security
|
||||
|
||||
- Fix linux32 emulation to fail during docker build [#20672](https://github.com/docker/docker/pull/20672)
|
||||
- Fix linux32 emulation to fail during docker build [#20672](https://github.com/docker/docker/pull/20672)
|
||||
It was due to the `personality` syscall being blocked by the default seccomp profile.
|
||||
- Fix Oracle XE 10g failing to start in a container [#20981](https://github.com/docker/docker/pull/20981)
|
||||
- Fix Oracle XE 10g failing to start in a container [#20981](https://github.com/docker/docker/pull/20981)
|
||||
It was due to the `ipc` syscall being blocked by the default seccomp profile.
|
||||
- Fix user namespaces not working on Linux From Scratch [#20685](https://github.com/docker/docker/pull/20685)
|
||||
- Fix issue preventing daemon to start if userns is enabled and the `subuid` or `subgid` files contain comments [#20725](https://github.com/docker/docker/pull/20725)
|
||||
@@ -113,7 +252,7 @@ Engine 1.10 migrator can be found on Docker Hub: https://hub.docker.com/r/docker
|
||||
+ Add `--tmpfs` flag to `docker run` to create a tmpfs mount in a container [#13587](https://github.com/docker/docker/pull/13587)
|
||||
+ Add `--format` flag to `docker images` command [#17692](https://github.com/docker/docker/pull/17692)
|
||||
+ Allow to set daemon configuration in a file and hot-reload it with the `SIGHUP` signal [#18587](https://github.com/docker/docker/pull/18587)
|
||||
+ Updated docker events to include more meta-data and event types [#18888](https://github.com/docker/docker/pull/18888)
|
||||
+ Updated docker events to include more meta-data and event types [#18888](https://github.com/docker/docker/pull/18888)
|
||||
This change is backward compatible in the API, but not on the CLI.
|
||||
+ Add `--blkio-weight-device` flag to `docker run` [#13959](https://github.com/docker/docker/pull/13959)
|
||||
+ Add `--device-read-bps` and `--device-write-bps` flags to `docker run` [#14466](https://github.com/docker/docker/pull/14466)
|
||||
@@ -148,18 +287,18 @@ Engine 1.10 migrator can be found on Docker Hub: https://hub.docker.com/r/docker
|
||||
+ Add support for custom seccomp profiles in `--security-opt` [#17989](https://github.com/docker/docker/pull/17989)
|
||||
+ Add default seccomp profile [#18780](https://github.com/docker/docker/pull/18780)
|
||||
+ Add `--authorization-plugin` flag to `daemon` to customize ACLs [#15365](https://github.com/docker/docker/pull/15365)
|
||||
+ Docker Content Trust now supports the ability to read and write user delegations [#18887](https://github.com/docker/docker/pull/18887)
|
||||
This is an optional, opt-in feature that requires the explicit use of the Notary command-line utility in order to be enabled.
|
||||
+ Docker Content Trust now supports the ability to read and write user delegations [#18887](https://github.com/docker/docker/pull/18887)
|
||||
This is an optional, opt-in feature that requires the explicit use of the Notary command-line utility in order to be enabled.
|
||||
Enabling delegation support in a specific repository will break the ability of Docker 1.9 and 1.8 to pull from that repository, if content trust is enabled.
|
||||
* Allow SELinux to run in a container when using the BTRFS storage driver [#16452](https://github.com/docker/docker/pull/16452)
|
||||
|
||||
### Distribution
|
||||
|
||||
* Use content-addressable storage for images and layers [#17924](https://github.com/docker/docker/pull/17924)
|
||||
Note that a migration is performed the first time docker is run; it can take a significant amount of time depending on the number of images and containers present.
|
||||
Images no longer depend on the parent chain but contain a list of layer references.
|
||||
* Use content-addressable storage for images and layers [#17924](https://github.com/docker/docker/pull/17924)
|
||||
Note that a migration is performed the first time docker is run; it can take a significant amount of time depending on the number of images and containers present.
|
||||
Images no longer depend on the parent chain but contain a list of layer references.
|
||||
`docker load`/`docker save` tarballs now also contain content-addressable image configurations.
|
||||
For more information: https://github.com/docker/docker/wiki/Engine-v1.10.0-content-addressability-migration
|
||||
For more information: https://github.com/docker/docker/wiki/Engine-v1.10.0-content-addressability-migration
|
||||
* Add support for the new [manifest format ("schema2")](https://github.com/docker/distribution/blob/master/docs/spec/manifest-v2-2.md) [#18785](https://github.com/docker/docker/pull/18785)
|
||||
* Lots of improvements for push and pull: performance++, retries on failed downloads, cancelling on client disconnect [#18353](https://github.com/docker/docker/pull/18353), [#18418](https://github.com/docker/docker/pull/18418), [#19109](https://github.com/docker/docker/pull/19109), [#18353](https://github.com/docker/docker/pull/18353)
|
||||
* Limit v1 protocol fallbacks [#18590](https://github.com/docker/docker/pull/18590)
|
||||
@@ -201,8 +340,8 @@ Engine 1.10 migrator can be found on Docker Hub: https://hub.docker.com/r/docker
|
||||
### Volumes
|
||||
|
||||
+ Add support to set the mount propagation mode for a volume [#17034](https://github.com/docker/docker/pull/17034)
|
||||
* Add `ls` and `inspect` endpoints to volume plugin API [#16534](https://github.com/docker/docker/pull/16534)
|
||||
Existing plugins need to make use of these new APIs to satisfy users' expectation
|
||||
* Add `ls` and `inspect` endpoints to volume plugin API [#16534](https://github.com/docker/docker/pull/16534)
|
||||
Existing plugins need to make use of these new APIs to satisfy users' expectation
|
||||
For that, please use the new MIME type `application/vnd.docker.plugins.v1.2+json` [#19549](https://github.com/docker/docker/pull/19549)
|
||||
- Fix data not being copied to named volumes [#19175](https://github.com/docker/docker/pull/19175)
|
||||
- Fix issues preventing volume drivers from being containerized [#19500](https://github.com/docker/docker/pull/19500)
|
||||
|
||||
31
Dockerfile
31
Dockerfile
@@ -33,14 +33,20 @@ RUN echo deb http://ppa.launchpad.net/zfs-native/stable/ubuntu trusty main > /et
|
||||
# add llvm repo
|
||||
RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 6084F3CF814B57C1CF12EFD515CF4D18AF4F7421 \
|
||||
|| apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 6084F3CF814B57C1CF12EFD515CF4D18AF4F7421
|
||||
RUN echo deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty main > /etc/apt/sources.list.d/llvm.list
|
||||
RUN echo deb http://llvm.org/apt/jessie/ llvm-toolchain-jessie-3.8 main > /etc/apt/sources.list.d/llvm.list
|
||||
|
||||
# allow replacing httpredir mirror
|
||||
ARG APT_MIRROR=httpredir.debian.org
|
||||
RUN sed -i s/httpredir.debian.org/$APT_MIRROR/g /etc/apt/sources.list
|
||||
|
||||
# Packaged dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
apparmor \
|
||||
apt-utils \
|
||||
aufs-tools \
|
||||
automake \
|
||||
bash-completion \
|
||||
bsdmainutils \
|
||||
btrfs-tools \
|
||||
build-essential \
|
||||
clang-3.8 \
|
||||
@@ -64,12 +70,13 @@ RUN apt-get update && apt-get install -y \
|
||||
python-mock \
|
||||
python-pip \
|
||||
python-websocket \
|
||||
s3cmd=1.5.0* \
|
||||
ubuntu-zfs \
|
||||
xfsprogs \
|
||||
libzfs-dev \
|
||||
tar \
|
||||
zip \
|
||||
--no-install-recommends \
|
||||
&& pip install awscli==1.10.15 \
|
||||
&& ln -snf /usr/bin/clang-3.8 /usr/local/bin/clang \
|
||||
&& ln -snf /usr/bin/clang++-3.8 /usr/local/bin/clang++
|
||||
|
||||
@@ -96,7 +103,7 @@ RUN set -x \
|
||||
&& export OSXCROSS_PATH="/osxcross" \
|
||||
&& git clone https://github.com/tpoechtrager/osxcross.git $OSXCROSS_PATH \
|
||||
&& ( cd $OSXCROSS_PATH && git checkout -q $OSX_CROSS_COMMIT) \
|
||||
&& curl -sSL https://s3.dockerproject.org/darwin/${OSX_SDK}.tar.xz -o "${OSXCROSS_PATH}/tarballs/${OSX_SDK}.tar.xz" \
|
||||
&& curl -sSL https://s3.dockerproject.org/darwin/v2/${OSX_SDK}.tar.xz -o "${OSXCROSS_PATH}/tarballs/${OSX_SDK}.tar.xz" \
|
||||
&& UNATTENDED=yes OSX_VERSION_MIN=10.6 ${OSXCROSS_PATH}/build.sh
|
||||
ENV PATH /osxcross/target/bin:$PATH
|
||||
|
||||
@@ -119,7 +126,7 @@ RUN set -x \
|
||||
# IMPORTANT: If the version of Go is updated, the Windows to Linux CI machines
|
||||
# will need updating, to avoid errors. Ping #docker-maintainers on IRC
|
||||
# with a heads-up.
|
||||
ENV GO_VERSION 1.6
|
||||
ENV GO_VERSION 1.5.3
|
||||
RUN curl -fsSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" \
|
||||
| tar -xzC /usr/local
|
||||
ENV PATH /go/bin:/usr/local/go/bin:$PATH
|
||||
@@ -170,12 +177,13 @@ RUN set -x \
|
||||
# Install notary server
|
||||
ENV NOTARY_VERSION docker-v1.11-3
|
||||
RUN set -x \
|
||||
&& export GO15VENDOREXPERIMENT=1 \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \
|
||||
&& (cd "$GOPATH/src/github.com/docker/notary" && git checkout -q "$NOTARY_VERSION") \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH" \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/vendor:$GOPATH" \
|
||||
go build -o /usr/local/bin/notary-server github.com/docker/notary/cmd/notary-server \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH" \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/vendor:$GOPATH" \
|
||||
go build -o /usr/local/bin/notary github.com/docker/notary/cmd/notary \
|
||||
&& rm -rf "$GOPATH"
|
||||
|
||||
@@ -186,13 +194,6 @@ RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
||||
&& git checkout -q $DOCKER_PY_COMMIT \
|
||||
&& pip install -r test-requirements.txt
|
||||
|
||||
# Setup s3cmd config
|
||||
RUN { \
|
||||
echo '[default]'; \
|
||||
echo 'access_key=$AWS_ACCESS_KEY'; \
|
||||
echo 'secret_key=$AWS_SECRET_KEY'; \
|
||||
} > ~/.s3cfg
|
||||
|
||||
# Set user.email so crosbymichael's in-container merge commits go smoothly
|
||||
RUN git config --global user.email 'docker-dummy@example.com'
|
||||
|
||||
@@ -247,7 +248,7 @@ RUN set -x \
|
||||
&& rm -rf "$GOPATH"
|
||||
|
||||
# Install runc
|
||||
ENV RUNC_COMMIT bbde9c426ff363d813b8722f0744115c13b408b6
|
||||
ENV RUNC_COMMIT 6c88a526cdd74aab90cc88018368c452c7294a06
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
|
||||
@@ -257,7 +258,7 @@ RUN set -x \
|
||||
&& cp runc /usr/local/bin/docker-runc
|
||||
|
||||
# Install containerd
|
||||
ENV CONTAINERD_COMMIT 142e22a4dce86f3b8ce068a0b043489d21976bb8
|
||||
ENV CONTAINERD_COMMIT d2f03861c91edaafdcb3961461bf82ae83785ed7
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
|
||||
|
||||
@@ -119,12 +119,13 @@ RUN set -x \
|
||||
# Install notary server
|
||||
ENV NOTARY_VERSION docker-v1.11-3
|
||||
RUN set -x \
|
||||
&& export GO15VENDOREXPERIMENT=1 \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \
|
||||
&& (cd "$GOPATH/src/github.com/docker/notary" && git checkout -q "$NOTARY_VERSION") \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH" \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/vendor:$GOPATH" \
|
||||
go build -o /usr/local/bin/notary-server github.com/docker/notary/cmd/notary-server \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH" \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/vendor:$GOPATH" \
|
||||
go build -o /usr/local/bin/notary github.com/docker/notary/cmd/notary \
|
||||
&& rm -rf "$GOPATH"
|
||||
|
||||
@@ -135,13 +136,6 @@ RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
||||
&& git checkout -q $DOCKER_PY_COMMIT \
|
||||
&& pip install -r test-requirements.txt
|
||||
|
||||
# Setup s3cmd config
|
||||
RUN { \
|
||||
echo '[default]'; \
|
||||
echo 'access_key=$AWS_ACCESS_KEY'; \
|
||||
echo 'secret_key=$AWS_SECRET_KEY'; \
|
||||
} > ~/.s3cfg
|
||||
|
||||
# Set user.email so crosbymichael's in-container merge commits go smoothly
|
||||
RUN git config --global user.email 'docker-dummy@example.com'
|
||||
|
||||
@@ -187,7 +181,7 @@ RUN set -x \
|
||||
&& rm -rf "$GOPATH"
|
||||
|
||||
# Install runc
|
||||
ENV RUNC_COMMIT bbde9c426ff363d813b8722f0744115c13b408b6
|
||||
ENV RUNC_COMMIT 6c88a526cdd74aab90cc88018368c452c7294a06
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
|
||||
@@ -197,7 +191,7 @@ RUN set -x \
|
||||
&& cp runc /usr/local/bin/docker-runc
|
||||
|
||||
# Install containerd
|
||||
ENV CONTAINERD_COMMIT 142e22a4dce86f3b8ce068a0b043489d21976bb8
|
||||
ENV CONTAINERD_COMMIT d2f03861c91edaafdcb3961461bf82ae83785ed7
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
|
||||
|
||||
@@ -65,8 +65,8 @@ RUN cd /usr/local/lvm2 \
|
||||
# see https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
|
||||
|
||||
# Install Go
|
||||
ENV GO_VERSION 1.6
|
||||
RUN curl -fsSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-armv6l.tar.gz" \
|
||||
ENV GO_VERSION 1.5.3
|
||||
RUN curl -fsSL "http://dave.cheney.net/paste/go${GO_VERSION}.linux-arm.tar.gz" \
|
||||
| tar -xzC /usr/local
|
||||
ENV PATH /go/bin:/usr/local/go/bin:$PATH
|
||||
ENV GOPATH /go:/go/src/github.com/docker/docker/vendor
|
||||
@@ -128,12 +128,13 @@ RUN set -x \
|
||||
# Install notary server
|
||||
ENV NOTARY_VERSION docker-v1.11-3
|
||||
RUN set -x \
|
||||
&& export GO15VENDOREXPERIMENT=1 \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \
|
||||
&& (cd "$GOPATH/src/github.com/docker/notary" && git checkout -q "$NOTARY_VERSION") \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH" \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/vendor:$GOPATH" \
|
||||
go build -o /usr/local/bin/notary-server github.com/docker/notary/cmd/notary-server \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH" \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/vendor:$GOPATH" \
|
||||
go build -o /usr/local/bin/notary github.com/docker/notary/cmd/notary \
|
||||
&& rm -rf "$GOPATH"
|
||||
|
||||
@@ -197,7 +198,7 @@ RUN set -x \
|
||||
&& rm -rf "$GOPATH"
|
||||
|
||||
# Install runc
|
||||
ENV RUNC_COMMIT bbde9c426ff363d813b8722f0744115c13b408b6
|
||||
ENV RUNC_COMMIT 6c88a526cdd74aab90cc88018368c452c7294a06
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
|
||||
@@ -207,7 +208,7 @@ RUN set -x \
|
||||
&& cp runc /usr/local/bin/docker-runc
|
||||
|
||||
# Install containerd
|
||||
ENV CONTAINERD_COMMIT 142e22a4dce86f3b8ce068a0b043489d21976bb8
|
||||
ENV CONTAINERD_COMMIT d2f03861c91edaafdcb3961461bf82ae83785ed7
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
|
||||
|
||||
@@ -74,7 +74,7 @@ WORKDIR /go/src/github.com/docker/docker
|
||||
ENV DOCKER_BUILDTAGS apparmor seccomp selinux
|
||||
|
||||
# Install runc
|
||||
ENV RUNC_COMMIT bbde9c426ff363d813b8722f0744115c13b408b6
|
||||
ENV RUNC_COMMIT 6c88a526cdd74aab90cc88018368c452c7294a06
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
|
||||
@@ -84,7 +84,7 @@ RUN set -x \
|
||||
&& cp runc /usr/local/bin/docker-runc
|
||||
|
||||
# Install containerd
|
||||
ENV CONTAINERD_COMMIT 142e22a4dce86f3b8ce068a0b043489d21976bb8
|
||||
ENV CONTAINERD_COMMIT d2f03861c91edaafdcb3961461bf82ae83785ed7
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
|
||||
|
||||
@@ -74,8 +74,8 @@ RUN cd /usr/local/lvm2 \
|
||||
# TODO install Go, using gccgo as GOROOT_BOOTSTRAP (Go 1.5+ supports ppc64le properly)
|
||||
# possibly a ppc64le/golang image?
|
||||
|
||||
## BUILD GOLANG 1.6
|
||||
ENV GO_VERSION 1.6
|
||||
## BUILD GOLANG 1.5.3
|
||||
ENV GO_VERSION 1.5.3
|
||||
ENV GO_DOWNLOAD_URL https://golang.org/dl/go${GO_VERSION}.src.tar.gz
|
||||
ENV GO_DOWNLOAD_SHA256 a96cce8ce43a9bf9b2a4c7d470bc7ee0cb00410da815980681c8353218dcf146
|
||||
ENV GOROOT_BOOTSTRAP /usr/local
|
||||
@@ -129,12 +129,13 @@ RUN set -x \
|
||||
# Install notary and notary-server
|
||||
ENV NOTARY_VERSION docker-v1.11-3
|
||||
RUN set -x \
|
||||
&& export GO15VENDOREXPERIMENT=1 \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \
|
||||
&& (cd "$GOPATH/src/github.com/docker/notary" && git checkout -q "$NOTARY_VERSION") \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH" \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/vendor:$GOPATH" \
|
||||
go build -o /usr/local/bin/notary-server github.com/docker/notary/cmd/notary-server \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH" \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/vendor:$GOPATH" \
|
||||
go build -o /usr/local/bin/notary github.com/docker/notary/cmd/notary \
|
||||
&& rm -rf "$GOPATH"
|
||||
|
||||
@@ -198,17 +199,17 @@ RUN set -x \
|
||||
&& rm -rf "$GOPATH"
|
||||
|
||||
# Install runc
|
||||
ENV RUNC_COMMIT bbde9c426ff363d813b8722f0744115c13b408b6
|
||||
ENV RUNC_COMMIT 6c88a526cdd74aab90cc88018368c452c7294a06
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
|
||||
&& cd "$GOPATH/src/github.com/opencontainers/runc" \
|
||||
&& git checkout -q "$RUNC_COMMIT" \
|
||||
&& make static BUILDTAGS="seccomp apparmor selinux" \
|
||||
&& make static BUILDTAGS="apparmor selinux" \
|
||||
&& cp runc /usr/local/bin/docker-runc
|
||||
|
||||
# Install containerd
|
||||
ENV CONTAINERD_COMMIT 142e22a4dce86f3b8ce068a0b043489d21976bb8
|
||||
ENV CONTAINERD_COMMIT d2f03861c91edaafdcb3961461bf82ae83785ed7
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
|
||||
|
||||
@@ -110,11 +110,12 @@ RUN set -x \
|
||||
# Install notary server
|
||||
ENV NOTARY_VERSION docker-v1.11-3
|
||||
RUN set -x \
|
||||
&& export GO15VENDOREXPERIMENT=1 \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \
|
||||
&& (cd "$GOPATH/src/github.com/docker/notary" && git checkout -q "$NOTARY_VERSION") \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH" \
|
||||
go build -gccgoflags=-lpthread -o /usr/local/bin/notary-server github.com/docker/notary/cmd/notary-server \
|
||||
&& GOPATH="$GOPATH/src/github.com/docker/notary/vendor:$GOPATH" \
|
||||
go build -o /usr/local/bin/notary-server github.com/docker/notary/cmd/notary-server \
|
||||
&& rm -rf "$GOPATH"
|
||||
|
||||
# Get the "docker-py" source so we can run their integration tests
|
||||
@@ -177,7 +178,7 @@ RUN set -x \
|
||||
&& rm -rf "$GOPATH"
|
||||
|
||||
# Install runc
|
||||
ENV RUNC_COMMIT bbde9c426ff363d813b8722f0744115c13b408b6
|
||||
ENV RUNC_COMMIT 6c88a526cdd74aab90cc88018368c452c7294a06
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
|
||||
@@ -187,7 +188,7 @@ RUN set -x \
|
||||
&& cp runc /usr/local/bin/docker-runc
|
||||
|
||||
# Install containerd
|
||||
ENV CONTAINERD_COMMIT 142e22a4dce86f3b8ce068a0b043489d21976bb8
|
||||
ENV CONTAINERD_COMMIT d2f03861c91edaafdcb3961461bf82ae83785ed7
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
|
||||
|
||||
@@ -30,7 +30,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install runc
|
||||
ENV RUNC_COMMIT bbde9c426ff363d813b8722f0744115c13b408b6
|
||||
ENV RUNC_COMMIT 6c88a526cdd74aab90cc88018368c452c7294a06
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
|
||||
@@ -40,7 +40,7 @@ RUN set -x \
|
||||
&& cp runc /usr/local/bin/docker-runc
|
||||
|
||||
# Install containerd
|
||||
ENV CONTAINERD_COMMIT 142e22a4dce86f3b8ce068a0b043489d21976bb8
|
||||
ENV CONTAINERD_COMMIT d2f03861c91edaafdcb3961461bf82ae83785ed7
|
||||
RUN set -x \
|
||||
&& export GOPATH="$(mktemp -d)" \
|
||||
&& git clone git://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
|
||||
|
||||
@@ -38,9 +38,9 @@
|
||||
FROM windowsservercore
|
||||
|
||||
# Environment variable notes:
|
||||
# - GOLANG_VERSION must consistent with 'Dockerfile' used by Linux'.
|
||||
# - GO_VERSION must consistent with 'Dockerfile' used by Linux'.
|
||||
# - FROM_DOCKERFILE is used for detection of building within a container.
|
||||
ENV GOLANG_VERSION=1.6 \
|
||||
ENV GO_VERSION=1.5.3 \
|
||||
GIT_LOCATION=https://github.com/git-for-windows/git/releases/download/v2.7.2.windows.1/Git-2.7.2-64-bit.exe \
|
||||
RSRC_COMMIT=ba14da1f827188454a4591717fff29999010887f \
|
||||
GOPATH=C:/go;C:/go/src/github.com/docker/docker/vendor \
|
||||
@@ -63,7 +63,7 @@ RUN \
|
||||
Download-File %GIT_LOCATION% gitsetup.exe; \
|
||||
\
|
||||
Write-Host INFO: Downloading go...; \
|
||||
Download-File https://storage.googleapis.com/golang/go%GOLANG_VERSION%.windows-amd64.msi go.msi; \
|
||||
Download-File https://storage.googleapis.com/golang/go%GO_VERSION%.windows-amd64.msi go.msi; \
|
||||
\
|
||||
Write-Host INFO: Downloading compiler 1 of 3...; \
|
||||
Download-File https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/gcc.zip gcc.zip; \
|
||||
|
||||
3
Makefile
3
Makefile
@@ -69,10 +69,11 @@ bundles:
|
||||
cross: build
|
||||
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary binary cross
|
||||
|
||||
|
||||
win: build
|
||||
$(DOCKER_RUN_DOCKER) hack/make.sh win
|
||||
|
||||
tgz: build
|
||||
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary binary cross tgz
|
||||
|
||||
deb: build
|
||||
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary build-deb
|
||||
|
||||
@@ -252,7 +252,7 @@ func (cli *DockerCli) trustedReference(ref reference.NamedTagged) (reference.Can
|
||||
// Resolve the Auth config relevant for this server
|
||||
authConfig := cli.resolveAuthConfig(repoInfo.Index)
|
||||
|
||||
notaryRepo, err := cli.getNotaryRepository(repoInfo, authConfig)
|
||||
notaryRepo, err := cli.getNotaryRepository(repoInfo, authConfig, "pull")
|
||||
if err != nil {
|
||||
fmt.Fprintf(cli.out, "Error establishing connection to trust repository: %s\n", err)
|
||||
return nil, err
|
||||
|
||||
@@ -55,11 +55,10 @@ func (s *systemRouter) getEvents(ctx context.Context, w http.ResponseWriter, r *
|
||||
return err
|
||||
}
|
||||
|
||||
timer := time.NewTimer(0)
|
||||
timer.Stop()
|
||||
var timeout <-chan time.Time
|
||||
if until > 0 || untilNano > 0 {
|
||||
dur := time.Unix(until, untilNano).Sub(time.Now())
|
||||
timer = time.NewTimer(dur)
|
||||
timeout = time.NewTimer(dur).C
|
||||
}
|
||||
|
||||
ef, err := filters.FromParam(r.Form.Get("filters"))
|
||||
@@ -99,7 +98,7 @@ func (s *systemRouter) getEvents(ctx context.Context, w http.ResponseWriter, r *
|
||||
if err := enc.Encode(jev); err != nil {
|
||||
return err
|
||||
}
|
||||
case <-timer.C:
|
||||
case <-timeout:
|
||||
return nil
|
||||
case <-closeNotify:
|
||||
logrus.Debug("Client disconnected, stop sending events")
|
||||
|
||||
@@ -236,6 +236,17 @@ func (b *Builder) build(config *types.ImageBuildOptions, context builder.Context
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Commit the layer when there are only one children in
|
||||
// the dockerfile, this is only the `FROM` tag, and
|
||||
// build labels. Otherwise, the new image won't be
|
||||
// labeled properly.
|
||||
// Commit here, so the ID of the final image is reported
|
||||
// properly.
|
||||
if len(b.dockerfile.Children) == 1 && len(b.options.Labels) > 0 {
|
||||
b.commit("", b.runConfig.Cmd, "")
|
||||
}
|
||||
|
||||
shortImgID = stringid.TruncateID(b.image)
|
||||
fmt.Fprintf(b.Stdout, " ---> %s\n", shortImgID)
|
||||
if b.options.Remove {
|
||||
|
||||
@@ -413,7 +413,20 @@ func (b *Builder) processImageFrom(img builder.Image) error {
|
||||
b.image = img.ImageID()
|
||||
|
||||
if img.RunConfig() != nil {
|
||||
b.runConfig = img.RunConfig()
|
||||
imgConfig := *img.RunConfig()
|
||||
// inherit runConfig labels from the current
|
||||
// state if they've been set already.
|
||||
// Ensures that images with only a FROM
|
||||
// get the labels populated properly.
|
||||
if b.runConfig.Labels != nil {
|
||||
if imgConfig.Labels == nil {
|
||||
imgConfig.Labels = make(map[string]string)
|
||||
}
|
||||
for k, v := range b.runConfig.Labels {
|
||||
imgConfig.Labels[k] = v
|
||||
}
|
||||
}
|
||||
b.runConfig = &imgConfig
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,3 +13,4 @@ ENV PATH $PATH:/usr/local/go/bin
|
||||
ENV AUTO_GOPATH 1
|
||||
|
||||
ENV DOCKER_BUILDTAGS apparmor selinux
|
||||
ENV RUNC_BUILDTAGS apparmor selinux
|
||||
|
||||
@@ -13,3 +13,4 @@ ENV PATH $PATH:/usr/local/go/bin
|
||||
ENV AUTO_GOPATH 1
|
||||
|
||||
ENV DOCKER_BUILDTAGS apparmor seccomp selinux
|
||||
ENV RUNC_BUILDTAGS apparmor seccomp selinux
|
||||
|
||||
@@ -14,3 +14,4 @@ ENV PATH $PATH:/usr/local/go/bin
|
||||
ENV AUTO_GOPATH 1
|
||||
|
||||
ENV DOCKER_BUILDTAGS apparmor selinux
|
||||
ENV RUNC_BUILDTAGS apparmor selinux
|
||||
|
||||
@@ -42,6 +42,7 @@ for version in "${versions[@]}"; do
|
||||
echo >> "$version/Dockerfile"
|
||||
|
||||
extraBuildTags=
|
||||
runcBuildTags=
|
||||
|
||||
# this list is sorted alphabetically; please keep it that way
|
||||
packages=(
|
||||
@@ -64,7 +65,7 @@ for version in "${versions[@]}"; do
|
||||
# packaging for "sd-journal.h" and libraries varies
|
||||
case "$suite" in
|
||||
precise|wheezy) ;;
|
||||
sid|stretch|wily) packages+=( libsystemd-dev );;
|
||||
sid|stretch|wily|xenial) packages+=( libsystemd-dev );;
|
||||
*) packages+=( libsystemd-journal-dev );;
|
||||
esac
|
||||
|
||||
@@ -73,9 +74,11 @@ for version in "${versions[@]}"; do
|
||||
case "$suite" in
|
||||
precise|wheezy|jessie|trusty)
|
||||
packages=( "${packages[@]/libseccomp-dev}" )
|
||||
runcBuildTags="apparmor selinux"
|
||||
;;
|
||||
*)
|
||||
extraBuildTags+=' seccomp'
|
||||
runcBuildTags="apparmor seccomp selinux"
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -124,4 +127,5 @@ for version in "${versions[@]}"; do
|
||||
buildTags=$( echo "apparmor selinux $extraBuildTags" | xargs -n1 | sort -n | tr '\n' ' ' | sed -e 's/[[:space:]]*$//' )
|
||||
|
||||
echo "ENV DOCKER_BUILDTAGS $buildTags" >> "$version/Dockerfile"
|
||||
echo "ENV RUNC_BUILDTAGS $runcBuildTags" >> "$version/Dockerfile"
|
||||
done
|
||||
|
||||
@@ -13,3 +13,4 @@ ENV PATH $PATH:/usr/local/go/bin
|
||||
ENV AUTO_GOPATH 1
|
||||
|
||||
ENV DOCKER_BUILDTAGS apparmor exclude_graphdriver_btrfs exclude_graphdriver_devicemapper selinux
|
||||
ENV RUNC_BUILDTAGS apparmor selinux
|
||||
|
||||
@@ -13,3 +13,4 @@ ENV PATH $PATH:/usr/local/go/bin
|
||||
ENV AUTO_GOPATH 1
|
||||
|
||||
ENV DOCKER_BUILDTAGS apparmor selinux
|
||||
ENV RUNC_BUILDTAGS apparmor selinux
|
||||
|
||||
@@ -13,3 +13,4 @@ ENV PATH $PATH:/usr/local/go/bin
|
||||
ENV AUTO_GOPATH 1
|
||||
|
||||
ENV DOCKER_BUILDTAGS apparmor seccomp selinux
|
||||
ENV RUNC_BUILDTAGS apparmor seccomp selinux
|
||||
|
||||
16
contrib/builder/deb/amd64/ubuntu-xenial/Dockerfile
Normal file
16
contrib/builder/deb/amd64/ubuntu-xenial/Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# THIS FILE IS AUTOGENERATED; SEE "contrib/builder/deb/amd64/generate.sh"!
|
||||
#
|
||||
|
||||
FROM ubuntu:xenial
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libltdl-dev libseccomp-dev libsqlite3-dev pkg-config libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.5.3
|
||||
RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
ENV AUTO_GOPATH 1
|
||||
|
||||
ENV DOCKER_BUILDTAGS apparmor seccomp selinux
|
||||
ENV RUNC_BUILDTAGS apparmor seccomp selinux
|
||||
@@ -6,7 +6,7 @@ FROM centos:7
|
||||
|
||||
RUN yum groupinstall -y "Development Tools"
|
||||
RUN yum -y swap -- remove systemd-container systemd-container-libs -- install systemd systemd-libs
|
||||
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar
|
||||
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git
|
||||
|
||||
ENV GO_VERSION 1.5.3
|
||||
RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
@@ -15,4 +15,5 @@ ENV PATH $PATH:/usr/local/go/bin
|
||||
ENV AUTO_GOPATH 1
|
||||
|
||||
ENV DOCKER_BUILDTAGS selinux
|
||||
ENV RUNC_BUILDTAGS selinux
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
FROM fedora:22
|
||||
|
||||
RUN dnf install -y @development-tools fedora-packager
|
||||
RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar
|
||||
RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git
|
||||
|
||||
ENV GO_VERSION 1.5.3
|
||||
RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
@@ -14,4 +14,5 @@ ENV PATH $PATH:/usr/local/go/bin
|
||||
ENV AUTO_GOPATH 1
|
||||
|
||||
ENV DOCKER_BUILDTAGS seccomp selinux
|
||||
ENV RUNC_BUILDTAGS seccomp selinux
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
FROM fedora:23
|
||||
|
||||
RUN dnf install -y @development-tools fedora-packager
|
||||
RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar
|
||||
RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git
|
||||
|
||||
ENV GO_VERSION 1.5.3
|
||||
RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
@@ -14,4 +14,5 @@ ENV PATH $PATH:/usr/local/go/bin
|
||||
ENV AUTO_GOPATH 1
|
||||
|
||||
ENV DOCKER_BUILDTAGS seccomp selinux
|
||||
ENV RUNC_BUILDTAGS seccomp selinux
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ for version in "${versions[@]}"; do
|
||||
echo >> "$version/Dockerfile"
|
||||
|
||||
extraBuildTags=
|
||||
runcBuildTags=
|
||||
|
||||
case "$from" in
|
||||
centos:*)
|
||||
@@ -77,6 +78,7 @@ for version in "${versions[@]}"; do
|
||||
sqlite-devel # for "sqlite3.h"
|
||||
systemd-devel # for "sd-journal.h" and libraries
|
||||
tar # older versions of dev-tools do not have tar
|
||||
git # required for containerd and runc clone
|
||||
)
|
||||
|
||||
case "$from" in
|
||||
@@ -98,9 +100,11 @@ for version in "${versions[@]}"; do
|
||||
case "$from" in
|
||||
opensuse:*|oraclelinux:*|centos:7)
|
||||
packages=( "${packages[@]/libseccomp-devel}" )
|
||||
runcBuildTags="selinux"
|
||||
;;
|
||||
*)
|
||||
extraBuildTags+=' seccomp'
|
||||
runcBuildTags="seccomp selinux"
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -148,6 +152,7 @@ for version in "${versions[@]}"; do
|
||||
buildTags=$( echo "selinux $extraBuildTags" | xargs -n1 | sort -n | tr '\n' ' ' | sed -e 's/[[:space:]]*$//' )
|
||||
|
||||
echo "ENV DOCKER_BUILDTAGS $buildTags" >> "$version/Dockerfile"
|
||||
echo "ENV RUNC_BUILDTAGS $runcBuildTags" >> "$version/Dockerfile"
|
||||
echo >> "$version/Dockerfile"
|
||||
|
||||
case "$from" in
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
FROM opensuse:13.2
|
||||
|
||||
RUN zypper --non-interactive install ca-certificates* curl gzip rpm-build
|
||||
RUN zypper --non-interactive install libbtrfs-devel device-mapper-devel glibc-static libselinux-devel libtool-ltdl-devel pkg-config selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar systemd-rpm-macros
|
||||
RUN zypper --non-interactive install libbtrfs-devel device-mapper-devel glibc-static libselinux-devel libtool-ltdl-devel pkg-config selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git systemd-rpm-macros
|
||||
|
||||
ENV GO_VERSION 1.5.3
|
||||
RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
@@ -14,4 +14,5 @@ ENV PATH $PATH:/usr/local/go/bin
|
||||
ENV AUTO_GOPATH 1
|
||||
|
||||
ENV DOCKER_BUILDTAGS selinux
|
||||
ENV RUNC_BUILDTAGS selinux
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
FROM oraclelinux:6
|
||||
|
||||
RUN yum groupinstall -y "Development Tools"
|
||||
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel tar
|
||||
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel tar git
|
||||
|
||||
RUN yum install -y yum-utils && curl -o /etc/yum.repos.d/public-yum-ol6.repo http://yum.oracle.com/public-yum-ol6.repo && yum-config-manager -q --enable ol6_UEKR4
|
||||
RUN yum install -y kernel-uek-devel-4.1.12-32.el6uek
|
||||
@@ -17,6 +17,7 @@ ENV PATH $PATH:/usr/local/go/bin
|
||||
ENV AUTO_GOPATH 1
|
||||
|
||||
ENV DOCKER_BUILDTAGS selinux
|
||||
ENV RUNC_BUILDTAGS selinux
|
||||
|
||||
ENV CGO_CPPFLAGS -D__EXPORTED_HEADERS__ \
|
||||
-I/usr/src/kernels/4.1.12-32.el6uek.x86_64/arch/x86/include/generated/uapi \
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
FROM oraclelinux:7
|
||||
|
||||
RUN yum groupinstall -y "Development Tools"
|
||||
RUN yum install -y --enablerepo=ol7_optional_latest btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar
|
||||
RUN yum install -y --enablerepo=ol7_optional_latest btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git
|
||||
|
||||
ENV GO_VERSION 1.5.3
|
||||
RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
@@ -14,4 +14,5 @@ ENV PATH $PATH:/usr/local/go/bin
|
||||
ENV AUTO_GOPATH 1
|
||||
|
||||
ENV DOCKER_BUILDTAGS selinux
|
||||
ENV RUNC_BUILDTAGS selinux
|
||||
|
||||
|
||||
@@ -410,7 +410,7 @@ __docker_complete_log_drivers() {
|
||||
__docker_complete_log_options() {
|
||||
# see docs/reference/logging/index.md
|
||||
local awslogs_options="awslogs-region awslogs-group awslogs-stream"
|
||||
local fluentd_options="env fluentd-address labels tag"
|
||||
local fluentd_options="env fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries labels tag"
|
||||
local gcplogs_options="env gcp-log-cmd gcp-project labels"
|
||||
local gelf_options="env gelf-address gelf-compression-level gelf-compression-type labels tag"
|
||||
local journald_options="env labels tag"
|
||||
@@ -459,6 +459,10 @@ __docker_complete_log_options() {
|
||||
__docker_complete_log_driver_options() {
|
||||
local key=$(__docker_map_key_of_current_option '--log-opt')
|
||||
case "$key" in
|
||||
fluentd-async-connect)
|
||||
COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
|
||||
return
|
||||
;;
|
||||
gelf-address)
|
||||
COMPREPLY=( $( compgen -W "udp" -S "://" -- "${cur##*=}" ) )
|
||||
__docker_nospace
|
||||
@@ -611,7 +615,7 @@ _docker_attach() {
|
||||
|
||||
case "$cur" in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W "--detach-keys --help --no-stdin --sig-proxy" -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W "--detach-keys --help --no-stdin --sig-proxy=false" -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
local counter=$(__docker_pos_first_nonflag '--detach-keys')
|
||||
@@ -633,6 +637,7 @@ _docker_build() {
|
||||
--cpu-quota
|
||||
--file -f
|
||||
--isolation
|
||||
--label
|
||||
--memory -m
|
||||
--memory-swap
|
||||
--shm-size
|
||||
@@ -697,7 +702,7 @@ _docker_commit() {
|
||||
|
||||
case "$cur" in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W "--author -a --change -c --help --message -m --pause -p" -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W "--author -a --change -c --help --message -m --pause=false -p=false" -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
local counter=$(__docker_pos_first_nonflag '--author|-a|--change|-c|--message|-m')
|
||||
@@ -789,6 +794,7 @@ _docker_daemon() {
|
||||
--cluster-advertise
|
||||
--cluster-store
|
||||
--cluster-store-opt
|
||||
--containerd
|
||||
--default-gateway
|
||||
--default-gateway-v6
|
||||
--default-ulimit
|
||||
@@ -865,7 +871,7 @@ _docker_daemon() {
|
||||
__docker_complete_log_drivers
|
||||
return
|
||||
;;
|
||||
--pidfile|-p|--tlscacert|--tlscert|--tlskey)
|
||||
--containerd|--pidfile|-p|--tlscacert|--tlscert|--tlskey)
|
||||
_filedir
|
||||
return
|
||||
;;
|
||||
@@ -881,6 +887,7 @@ _docker_daemon() {
|
||||
dm.fs
|
||||
dm.loopdatasize
|
||||
dm.loopmetadatasize
|
||||
dm.min_free_space
|
||||
dm.mkfsarg
|
||||
dm.mountopt
|
||||
dm.override_udev_sync_check
|
||||
@@ -1071,7 +1078,7 @@ _docker_help() {
|
||||
_docker_history() {
|
||||
case "$cur" in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W "--help --no-trunc --quiet -q" -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W "--help --human=false -H=false --no-trunc --quiet -q" -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
local counter=$(__docker_pos_first_nonflag)
|
||||
@@ -1211,7 +1218,7 @@ _docker_load() {
|
||||
|
||||
case "$cur" in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W "--help --input -i" -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W "--help --input -i --quiet -q" -- "$cur" ) )
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -1320,11 +1327,14 @@ _docker_network_create() {
|
||||
COMPREPLY=( $(compgen -W "$plugins" -- "$cur") )
|
||||
return
|
||||
;;
|
||||
--label)
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$cur" in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W "--aux-address --driver -d --gateway --help --internal --ip-range --ipam-driver --ipam-opt --ipv6 --opt -o --subnet" -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W "--aux-address --driver -d --gateway --help --internal --ip-range --ipam-driver --ipam-opt --ipv6 --label --opt -o --subnet" -- "$cur" ) )
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -1476,6 +1486,11 @@ _docker_ps() {
|
||||
COMPREPLY=( $( compgen -W "created dead exited paused restarting running" -- "${cur##*=}" ) )
|
||||
return
|
||||
;;
|
||||
volume)
|
||||
cur="${cur##*=}"
|
||||
__docker_complete_volumes
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$prev" in
|
||||
@@ -1483,7 +1498,7 @@ _docker_ps() {
|
||||
__docker_complete_containers_all
|
||||
;;
|
||||
--filter|-f)
|
||||
COMPREPLY=( $( compgen -S = -W "ancestor exited id label name status" -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -S = -W "ancestor exited id label name status volume" -- "$cur" ) )
|
||||
__docker_nospace
|
||||
return
|
||||
;;
|
||||
@@ -1654,6 +1669,7 @@ _docker_run() {
|
||||
--tmpfs
|
||||
--ulimit
|
||||
--user -u
|
||||
--userns
|
||||
--uts
|
||||
--volume-driver
|
||||
--volumes-from
|
||||
@@ -1690,6 +1706,24 @@ _docker_run() {
|
||||
__docker_complete_log_driver_options && return
|
||||
__docker_complete_restart && return
|
||||
|
||||
local key=$(__docker_map_key_of_current_option '--security-opt')
|
||||
case "$key" in
|
||||
label)
|
||||
[[ $cur == *: ]] && return
|
||||
COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "${cur##*=}") )
|
||||
if [ "${COMPREPLY[*]}" != "disable" ] ; then
|
||||
__docker_nospace
|
||||
fi
|
||||
return
|
||||
;;
|
||||
seccomp)
|
||||
local cur=${cur##*=}
|
||||
_filedir
|
||||
COMPREPLY+=( $( compgen -W "unconfined" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$prev" in
|
||||
--add-host)
|
||||
case "$cur" in
|
||||
@@ -1787,32 +1821,20 @@ _docker_run() {
|
||||
return
|
||||
;;
|
||||
--security-opt)
|
||||
case "$cur" in
|
||||
label=*:*)
|
||||
;;
|
||||
label=*)
|
||||
local cur=${cur##*=}
|
||||
COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "$cur") )
|
||||
if [ "${COMPREPLY[*]}" != "disable" ] ; then
|
||||
__docker_nospace
|
||||
fi
|
||||
;;
|
||||
seccomp=*)
|
||||
local cur=${cur##*=}
|
||||
_filedir
|
||||
COMPREPLY+=( $( compgen -W "unconfined" -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=( $( compgen -W "label apparmor seccomp" -S ":" -- "$cur") )
|
||||
__docker_nospace
|
||||
;;
|
||||
esac
|
||||
COMPREPLY=( $( compgen -W "apparmor= label= no-new-privileges seccomp=" -- "$cur") )
|
||||
if [ "${COMPREPLY[*]}" != "no-new-privileges" ] ; then
|
||||
__docker_nospace
|
||||
fi
|
||||
return
|
||||
;;
|
||||
--user|-u)
|
||||
__docker_complete_user_group
|
||||
return
|
||||
;;
|
||||
--userns)
|
||||
COMPREPLY=( $( compgen -W "host" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
--volume-driver)
|
||||
__docker_complete_plugins Volume
|
||||
return
|
||||
@@ -2015,14 +2037,14 @@ _docker_volume_create() {
|
||||
__docker_complete_plugins Volume
|
||||
return
|
||||
;;
|
||||
--name|--opt|-o)
|
||||
--label|--name|--opt|-o)
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$cur" in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W "--driver -d --help --name --opt -o" -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W "--driver -d --help --label --name --opt -o" -- "$cur" ) )
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
@@ -50,11 +50,11 @@ __docker_arguments() {
|
||||
__docker_get_containers() {
|
||||
[[ $PREFIX = -* ]] && return 1
|
||||
integer ret=1
|
||||
local kind
|
||||
declare -a running stopped lines args
|
||||
local kind type line s
|
||||
declare -a running stopped lines args names
|
||||
|
||||
kind=$1
|
||||
shift
|
||||
kind=$1; shift
|
||||
type=$1; shift
|
||||
[[ $kind = (stopped|all) ]] && args=($args -a)
|
||||
|
||||
lines=(${(f)"$(_call_program commands docker $docker_options ps --no-trunc $args)"})
|
||||
@@ -73,39 +73,40 @@ __docker_get_containers() {
|
||||
lines=(${lines[2,-1]})
|
||||
|
||||
# Container ID
|
||||
local line
|
||||
local s
|
||||
for line in $lines; do
|
||||
s="${${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}[0,12]}"
|
||||
s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
|
||||
s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}"
|
||||
if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then
|
||||
stopped=($stopped $s)
|
||||
else
|
||||
running=($running $s)
|
||||
fi
|
||||
done
|
||||
if [[ $type = (ids|all) ]]; then
|
||||
for line in $lines; do
|
||||
s="${${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}[0,12]}"
|
||||
s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
|
||||
s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}"
|
||||
if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then
|
||||
stopped=($stopped $s)
|
||||
else
|
||||
running=($running $s)
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Names: we only display the one without slash. All other names
|
||||
# are generated and may clutter the completion. However, with
|
||||
# Swarm, all names may be prefixed by the swarm node name.
|
||||
local -a names
|
||||
for line in $lines; do
|
||||
names=(${(ps:,:)${${line[${begin[NAMES]},${end[NAMES]}]}%% *}})
|
||||
# First step: find a common prefix and strip it (swarm node case)
|
||||
(( ${#${(u)names%%/*}} == 1 )) && names=${names#${names[1]%%/*}/}
|
||||
# Second step: only keep the first name without a /
|
||||
s=${${names:#*/*}[1]}
|
||||
# If no name, well give up.
|
||||
(( $#s != 0 )) || continue
|
||||
s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
|
||||
s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}"
|
||||
if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then
|
||||
stopped=($stopped $s)
|
||||
else
|
||||
running=($running $s)
|
||||
fi
|
||||
done
|
||||
if [[ $type = (names|all) ]]; then
|
||||
for line in $lines; do
|
||||
names=(${(ps:,:)${${line[${begin[NAMES]},${end[NAMES]}]}%% *}})
|
||||
# First step: find a common prefix and strip it (swarm node case)
|
||||
(( ${#${(u)names%%/*}} == 1 )) && names=${names#${names[1]%%/*}/}
|
||||
# Second step: only keep the first name without a /
|
||||
s=${${names:#*/*}[1]}
|
||||
# If no name, well give up.
|
||||
(( $#s != 0 )) || continue
|
||||
s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
|
||||
s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}"
|
||||
if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then
|
||||
stopped=($stopped $s)
|
||||
else
|
||||
running=($running $s)
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
[[ $kind = (running|all) ]] && _describe -t containers-running "running containers" running "$@" && ret=0
|
||||
[[ $kind = (stopped|all) ]] && _describe -t containers-stopped "stopped containers" stopped "$@" && ret=0
|
||||
@@ -114,17 +115,27 @@ __docker_get_containers() {
|
||||
|
||||
__docker_stoppedcontainers() {
|
||||
[[ $PREFIX = -* ]] && return 1
|
||||
__docker_get_containers stopped "$@"
|
||||
__docker_get_containers stopped all "$@"
|
||||
}
|
||||
|
||||
__docker_runningcontainers() {
|
||||
[[ $PREFIX = -* ]] && return 1
|
||||
__docker_get_containers running "$@"
|
||||
__docker_get_containers running all "$@"
|
||||
}
|
||||
|
||||
__docker_containers() {
|
||||
[[ $PREFIX = -* ]] && return 1
|
||||
__docker_get_containers all "$@"
|
||||
__docker_get_containers all all "$@"
|
||||
}
|
||||
|
||||
__docker_containers_ids() {
|
||||
[[ $PREFIX = -* ]] && return 1
|
||||
__docker_get_containers all ids "$@"
|
||||
}
|
||||
|
||||
__docker_containers_names() {
|
||||
[[ $PREFIX = -* ]] && return 1
|
||||
__docker_get_containers all names "$@"
|
||||
}
|
||||
|
||||
__docker_images() {
|
||||
@@ -200,10 +211,10 @@ __docker_get_log_options() {
|
||||
local -a awslogs_options fluentd_options gelf_options journald_options json_file_options syslog_options splunk_options
|
||||
|
||||
awslogs_options=("awslogs-region" "awslogs-group" "awslogs-stream")
|
||||
fluentd_options=("env" "fluentd-address" "labels" "tag")
|
||||
fluentd_options=("env" "fluentd-address" "fluentd-async-connect" "fluentd-buffer-limit" "fluentd-retry-wait" "fluentd-max-retries" "labels" "tag")
|
||||
gcplogs_options=("env" "gcp-log-cmd" "gcp-project" "labels")
|
||||
gelf_options=("env" "gelf-address" "labels" "tag")
|
||||
journald_options=("env" "labels")
|
||||
gelf_options=("env" "gelf-address" "gelf-compression-level" "gelf-compression-type" "labels" "tag")
|
||||
journald_options=("env" "labels" "tag")
|
||||
json_file_options=("env" "labels" "max-file" "max-size")
|
||||
syslog_options=("syslog-address" "syslog-tls-ca-cert" "syslog-tls-cert" "syslog-tls-key" "syslog-tls-skip-verify" "syslog-facility" "tag")
|
||||
splunk_options=("env" "labels" "splunk-caname" "splunk-capath" "splunk-index" "splunk-insecureskipverify" "splunk-source" "splunk-sourcetype" "splunk-token" "splunk-url" "tag")
|
||||
@@ -244,6 +255,43 @@ __docker_complete_detach_keys() {
|
||||
_describe -t detach_keys-ctrl "'ctrl-' + 'a-z @ [ \\\\ ] ^ _'" ctrl_keys -qS "," && ret=0
|
||||
}
|
||||
|
||||
__docker_complete_ps_filters() {
|
||||
[[ $PREFIX = -* ]] && return 1
|
||||
integer ret=1
|
||||
|
||||
if compset -P '*='; then
|
||||
case "${${words[-1]%=*}#*=}" in
|
||||
(ancestor)
|
||||
__docker_images && ret=0
|
||||
;;
|
||||
(before|since)
|
||||
__docker_containers && ret=0
|
||||
;;
|
||||
(id)
|
||||
__docker_containers_ids && ret=0
|
||||
;;
|
||||
(name)
|
||||
__docker_containers_names && ret=0
|
||||
;;
|
||||
(status)
|
||||
status_opts=('created' 'dead' 'exited' 'paused' 'restarting' 'running')
|
||||
_describe -t status-filter-opts "Status Filter Options" status_opts && ret=0
|
||||
;;
|
||||
(volume)
|
||||
__docker_volumes && ret=0
|
||||
;;
|
||||
*)
|
||||
_message 'value' && ret=0
|
||||
;;
|
||||
esac
|
||||
else
|
||||
opts=('ancestor' 'before' 'exited' 'id' 'label' 'name' 'since' 'status' 'volume')
|
||||
_describe -t filter-opts "Filter Options" opts -qS "=" && ret=0
|
||||
fi
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
__docker_networks() {
|
||||
[[ $PREFIX = -* ]] && return 1
|
||||
integer ret=1
|
||||
@@ -335,6 +383,7 @@ __docker_network_subcommand() {
|
||||
"($help)--ipam-driver=[IP Address Management Driver]:driver:(default)" \
|
||||
"($help)*--ipam-opt=[Custom IPAM plugin options]:opt=value: " \
|
||||
"($help)--ipv6[Enable IPv6 networking]" \
|
||||
"($help)*--label=[Set metadata on a network]:label=value: " \
|
||||
"($help)*"{-o=,--opt=}"[Driver specific options]:opt=value: " \
|
||||
"($help)*--subnet=[Subnet in CIDR format that represents a network segment]:IP/mask: " \
|
||||
"($help -)1:Network Name: " && ret=0
|
||||
@@ -425,6 +474,7 @@ __docker_volume_subcommand() {
|
||||
_arguments $(__docker_arguments) \
|
||||
$opts_help \
|
||||
"($help -d --driver)"{-d=,--driver=}"[Volume driver name]:Driver name:(local)" \
|
||||
"($help)*--label=[Set metadata for a volume]:label=value: " \
|
||||
"($help)--name=[Volume name]" \
|
||||
"($help)*"{-o=,--opt=}"[Driver specific options]:Driver option: " && ret=0
|
||||
;;
|
||||
@@ -489,6 +539,7 @@ __docker_subcommand() {
|
||||
"($help)--isolation=[Container isolation technology]:isolation:(default hyperv process)"
|
||||
"($help)*--shm-size=[Size of '/dev/shm' (format is '<number><unit>')]:shm size: "
|
||||
"($help)*--ulimit=[ulimit options]:ulimit: "
|
||||
"($help)--userns=[Container user namespace]:user namespace:(host)"
|
||||
)
|
||||
opts_build_create_run_update=(
|
||||
"($help)--cpu-shares=[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)"
|
||||
@@ -526,7 +577,7 @@ __docker_subcommand() {
|
||||
"($help)--ipc=[IPC namespace to use]:IPC namespace: "
|
||||
"($help)*--link=[Add link to another container]:link:->link"
|
||||
"($help)*"{-l=,--label=}"[Container metadata]:label: "
|
||||
"($help)--log-driver=[Default driver for container logs]:Logging driver:(json-file syslog journald gelf fluentd awslogs splunk none)"
|
||||
"($help)--log-driver=[Default driver for container logs]:Logging driver:(awslogs etwlogs fluentd gcplogs gelf journald json-file none splunk syslog)"
|
||||
"($help)*--log-opt=[Log driver specific options]:log driver options:__docker_log_options"
|
||||
"($help)--mac-address=[Container MAC address]:MAC address: "
|
||||
"($help)--name=[Container name]:name: "
|
||||
@@ -540,7 +591,6 @@ __docker_subcommand() {
|
||||
"($help)--pid=[PID namespace to use]:PID: "
|
||||
"($help)--privileged[Give extended privileges to this container]"
|
||||
"($help)--read-only[Mount the container's root filesystem as read only]"
|
||||
"($help)--restart=[Restart policy]:restart policy:(no on-failure always unless-stopped)"
|
||||
"($help)*--security-opt=[Security options]:security option: "
|
||||
"($help -t --tty)"{-t,--tty}"[Allocate a pseudo-tty]"
|
||||
"($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users"
|
||||
@@ -554,6 +604,7 @@ __docker_subcommand() {
|
||||
"($help)--blkio-weight=[Block IO (relative weight), between 10 and 1000]:Block IO weight:(10 100 500 1000)"
|
||||
"($help)--kernel-memory=[Kernel memory limit in bytes]:Memory limit: "
|
||||
"($help)--memory-reservation=[Memory soft limit]:Memory limit: "
|
||||
"($help)--restart=[Restart policy]:restart policy:(no on-failure always unless-stopped)"
|
||||
)
|
||||
opts_attach_exec_run_start=(
|
||||
"($help)--detach-keys=[Escape key sequence used to detach a container]:sequence:__docker_complete_detach_keys"
|
||||
@@ -576,6 +627,7 @@ __docker_subcommand() {
|
||||
"($help)*--build-arg[Build-time variables]:<varname>=<value>: " \
|
||||
"($help -f --file)"{-f=,--file=}"[Name of the Dockerfile]:Dockerfile:_files" \
|
||||
"($help)--force-rm[Always remove intermediate containers]" \
|
||||
"($help)*--label=[Set metadata for an image]:label=value: " \
|
||||
"($help)--no-cache[Do not use cache when building the image]" \
|
||||
"($help)--pull[Attempt to pull a newer version of the image]" \
|
||||
"($help -q --quiet)"{-q,--quiet}"[Suppress verbose build output]" \
|
||||
@@ -639,6 +691,7 @@ __docker_subcommand() {
|
||||
"($help -b --bridge)"{-b=,--bridge=}"[Attach containers to a network bridge]:bridge:_net_interfaces" \
|
||||
"($help)--bip=[Network bridge IP]:IP address: " \
|
||||
"($help)--cgroup-parent=[Parent cgroup for all containers]:cgroup: " \
|
||||
"($help)--containerd=[Path to containerd socket]:socket:_files -g \"*.sock\"" \
|
||||
"($help -D --debug)"{-D,--debug}"[Enable debug mode]" \
|
||||
"($help)--default-gateway[Container default gateway IPv4 address]:IPv4 address: " \
|
||||
"($help)--default-gateway-v6[Container default gateway IPv6 address]:IPv6 address: " \
|
||||
@@ -666,7 +719,7 @@ __docker_subcommand() {
|
||||
"($help)--ipv6[Enable IPv6 networking]" \
|
||||
"($help -l --log-level)"{-l=,--log-level=}"[Logging level]:level:(debug info warn error fatal)" \
|
||||
"($help)*--label=[Key=value labels]:label: " \
|
||||
"($help)--log-driver=[Default driver for container logs]:Logging driver:(json-file syslog journald gelf fluentd awslogs splunk none)" \
|
||||
"($help)--log-driver=[Default driver for container logs]:Logging driver:(awslogs etwlogs fluentd gcplogs gelf journald json-file none splunk syslog)" \
|
||||
"($help)*--log-opt=[Log driver specific options]:log driver options:__docker_log_options" \
|
||||
"($help)--mtu=[Network MTU]:mtu:(0 576 1420 1500 9000)" \
|
||||
"($help -p --pidfile)"{-p=,--pidfile=}"[Path to use for daemon PID file]:PID file:_files" \
|
||||
@@ -676,9 +729,9 @@ __docker_subcommand() {
|
||||
"($help)--selinux-enabled[Enable selinux support]" \
|
||||
"($help)*--storage-opt=[Storage driver options]:storage driver options: " \
|
||||
"($help)--tls[Use TLS]" \
|
||||
"($help)--tlscacert=[Trust certs signed only by this CA]:PEM file:_files -g "*.(pem|crt)"" \
|
||||
"($help)--tlscert=[Path to TLS certificate file]:PEM file:_files -g "*.(pem|crt)"" \
|
||||
"($help)--tlskey=[Path to TLS key file]:Key file:_files -g "*.(pem|key)"" \
|
||||
"($help)--tlscacert=[Trust certs signed only by this CA]:PEM file:_files -g \"*.(pem|crt)\"" \
|
||||
"($help)--tlscert=[Path to TLS certificate file]:PEM file:_files -g \"*.(pem|crt)\"" \
|
||||
"($help)--tlskey=[Path to TLS key file]:Key file:_files -g \"*.(pem|key)\"" \
|
||||
"($help)--tlsverify[Use TLS and verify the remote]" \
|
||||
"($help)--userns-remap=[User/Group setting for user namespaces]:user\:group:->users-groups" \
|
||||
"($help)--userland-proxy[Use userland proxy for loopback traffic]" && ret=0
|
||||
@@ -810,7 +863,8 @@ __docker_subcommand() {
|
||||
(load)
|
||||
_arguments $(__docker_arguments) \
|
||||
$opts_help \
|
||||
"($help -i --input)"{-i=,--input=}"[Read from tar archive file]:archive file:_files -g "*.((tar|TAR)(.gz|.GZ|.Z|.bz2|.lzma|.xz|)|(tbz|tgz|txz))(-.)"" && ret=0
|
||||
"($help -i --input)"{-i=,--input=}"[Read from tar archive file]:archive file:_files -g \"*.((tar|TAR)(.gz|.GZ|.Z|.bz2|.lzma|.xz|)|(tbz|tgz|txz))(-.)\"" \
|
||||
"($help -q --quiet)"{-q,--quiet}"[Suppress the load output]" && ret=0
|
||||
;;
|
||||
(login)
|
||||
_arguments $(__docker_arguments) \
|
||||
@@ -866,7 +920,7 @@ __docker_subcommand() {
|
||||
$opts_help \
|
||||
"($help -a --all)"{-a,--all}"[Show all containers]" \
|
||||
"($help)--before=[Show only container created before...]:containers:__docker_containers" \
|
||||
"($help)*"{-f=,--filter=}"[Filter values]:filter: " \
|
||||
"($help)*"{-f=,--filter=}"[Filter values]:filter:->filter-options" \
|
||||
"($help)--format[Pretty-print containers using a Go template]:format: " \
|
||||
"($help -l --latest)"{-l,--latest}"[Show only the latest created container]" \
|
||||
"($help)-n[Show n last created containers, include non-running one]:n:(1 5 10 25 50)" \
|
||||
@@ -874,16 +928,24 @@ __docker_subcommand() {
|
||||
"($help -q --quiet)"{-q,--quiet}"[Only show numeric IDs]" \
|
||||
"($help -s --size)"{-s,--size}"[Display total file sizes]" \
|
||||
"($help)--since=[Show only containers created since...]:containers:__docker_containers" && ret=0
|
||||
|
||||
case $state in
|
||||
(filter-options)
|
||||
__docker_complete_ps_filters && ret=0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
(pull)
|
||||
_arguments $(__docker_arguments) \
|
||||
$opts_help \
|
||||
"($help -a --all-tags)"{-a,--all-tags}"[Download all tagged images]" \
|
||||
"($help)--disable-content-trust[Skip image verification]" \
|
||||
"($help -):name:__docker_search" && ret=0
|
||||
;;
|
||||
(push)
|
||||
_arguments $(__docker_arguments) \
|
||||
$opts_help \
|
||||
"($help)--disable-content-trust[Skip image signing]" \
|
||||
"($help -): :__docker_images" && ret=0
|
||||
;;
|
||||
(rename)
|
||||
|
||||
@@ -222,6 +222,7 @@ func (daemon *Daemon) exportContainerRw(container *container.Container) (archive
|
||||
|
||||
archive, err := container.RWLayer.TarStream()
|
||||
if err != nil {
|
||||
daemon.Unmount(container) // logging is already handled in the `Unmount` function
|
||||
return nil, err
|
||||
}
|
||||
return ioutils.NewReadCloserWrapper(archive, func() error {
|
||||
|
||||
@@ -82,7 +82,7 @@ func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) strin
|
||||
cmd.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", usageFn("Set CORS headers in the remote API"))
|
||||
cmd.StringVar(&config.CgroupParent, []string{"-cgroup-parent"}, "", usageFn("Set parent cgroup for all containers"))
|
||||
cmd.StringVar(&config.RemappedRoot, []string{"-userns-remap"}, "", usageFn("User/Group setting for user namespaces"))
|
||||
cmd.StringVar(&config.ContainerdAddr, []string{"-containerd"}, "", usageFn("Path to containerD socket"))
|
||||
cmd.StringVar(&config.ContainerdAddr, []string{"-containerd"}, "", usageFn("Path to containerd socket"))
|
||||
|
||||
config.attachExperimentalFlags(cmd, usageFn)
|
||||
}
|
||||
|
||||
@@ -720,7 +720,7 @@ func (daemon *Daemon) releaseNetwork(container *container.Container) {
|
||||
|
||||
sb, err := daemon.netController.SandboxByID(sid)
|
||||
if err != nil {
|
||||
logrus.Errorf("error locating sandbox id %s: %v", sid, err)
|
||||
logrus.Warnf("error locating sandbox id %s: %v", sid, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -295,7 +295,18 @@ func specDevice(d *configs.Device) specs.Device {
|
||||
}
|
||||
}
|
||||
|
||||
func getDevicesFromPath(deviceMapping containertypes.DeviceMapping) (devs []specs.Device, err error) {
|
||||
func specDeviceCgroup(d *configs.Device) specs.DeviceCgroup {
|
||||
t := string(d.Type)
|
||||
return specs.DeviceCgroup{
|
||||
Allow: true,
|
||||
Type: &t,
|
||||
Major: &d.Major,
|
||||
Minor: &d.Minor,
|
||||
Access: &d.Permissions,
|
||||
}
|
||||
}
|
||||
|
||||
func getDevicesFromPath(deviceMapping containertypes.DeviceMapping) (devs []specs.Device, devPermissions []specs.DeviceCgroup, err error) {
|
||||
resolvedPathOnHost := deviceMapping.PathOnHost
|
||||
|
||||
// check if it is a symbolic link
|
||||
@@ -309,7 +320,7 @@ func getDevicesFromPath(deviceMapping containertypes.DeviceMapping) (devs []spec
|
||||
// if there was no error, return the device
|
||||
if err == nil {
|
||||
device.Path = deviceMapping.PathInContainer
|
||||
return append(devs, specDevice(device)), nil
|
||||
return append(devs, specDevice(device)), append(devPermissions, specDeviceCgroup(device)), nil
|
||||
}
|
||||
|
||||
// if the device is not a device node
|
||||
@@ -330,6 +341,7 @@ func getDevicesFromPath(deviceMapping containertypes.DeviceMapping) (devs []spec
|
||||
// add the device to userSpecified devices
|
||||
childDevice.Path = strings.Replace(dpath, resolvedPathOnHost, deviceMapping.PathInContainer, 1)
|
||||
devs = append(devs, specDevice(childDevice))
|
||||
devPermissions = append(devPermissions, specDeviceCgroup(childDevice))
|
||||
|
||||
return nil
|
||||
})
|
||||
@@ -337,10 +349,10 @@ func getDevicesFromPath(deviceMapping containertypes.DeviceMapping) (devs []spec
|
||||
}
|
||||
|
||||
if len(devs) > 0 {
|
||||
return devs, nil
|
||||
return devs, devPermissions, nil
|
||||
}
|
||||
|
||||
return devs, fmt.Errorf("error gathering device information while adding custom device %q: %s", deviceMapping.PathOnHost, err)
|
||||
return devs, devPermissions, fmt.Errorf("error gathering device information while adding custom device %q: %s", deviceMapping.PathOnHost, err)
|
||||
}
|
||||
|
||||
func mergeDevices(defaultDevices, userDevices []*configs.Device) []*configs.Device {
|
||||
|
||||
@@ -293,6 +293,11 @@ func (daemon *Daemon) restore() error {
|
||||
go func(c *container.Container) {
|
||||
defer wg.Done()
|
||||
if c.IsRunning() || c.IsPaused() {
|
||||
// Fix activityCount such that graph mounts can be unmounted later
|
||||
if err := daemon.layerStore.ReinitRWLayer(c.RWLayer); err != nil {
|
||||
logrus.Errorf("Failed to ReinitRWLayer for %s due to %s", c.ID, err)
|
||||
return
|
||||
}
|
||||
if err := daemon.containerd.Restore(c.ID, libcontainerd.WithRestartManager(c.RestartManager(true))); err != nil {
|
||||
logrus.Errorf("Failed to restore with containerd: %q", err)
|
||||
return
|
||||
@@ -304,10 +309,6 @@ func (daemon *Daemon) restore() error {
|
||||
mapLock.Lock()
|
||||
restartContainers[c] = make(chan struct{})
|
||||
mapLock.Unlock()
|
||||
} else if !c.IsRunning() && !c.IsPaused() {
|
||||
if mountid, err := daemon.layerStore.GetMountID(c.ID); err == nil {
|
||||
daemon.cleanupMountsByID(mountid)
|
||||
}
|
||||
}
|
||||
|
||||
// if c.hostConfig.Links is nil (not just empty), then it is using the old sqlite links and needs to be migrated
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
@@ -28,91 +28,53 @@ func (daemon *Daemon) cleanupMountsFromReaderByID(reader io.Reader, id string, u
|
||||
return nil
|
||||
}
|
||||
var errors []string
|
||||
mountRoot := ""
|
||||
shmSuffix := "/" + id + "/shm"
|
||||
mergedSuffix := "/" + id + "/merged"
|
||||
|
||||
regexps := getCleanPatterns(id)
|
||||
sc := bufio.NewScanner(reader)
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
fields := strings.Fields(line)
|
||||
if strings.HasPrefix(fields[4], daemon.root) {
|
||||
logrus.Debugf("Mount base: %v", fields[4])
|
||||
mnt := fields[4]
|
||||
if strings.HasSuffix(mnt, shmSuffix) || strings.HasSuffix(mnt, mergedSuffix) {
|
||||
logrus.Debugf("Unmounting %v", mnt)
|
||||
if err := unmount(mnt); err != nil {
|
||||
logrus.Error(err)
|
||||
errors = append(errors, err.Error())
|
||||
if fields := strings.Fields(sc.Text()); len(fields) >= 4 {
|
||||
if mnt := fields[4]; strings.HasPrefix(mnt, daemon.root) {
|
||||
for _, p := range regexps {
|
||||
if p.MatchString(mnt) {
|
||||
if err := unmount(mnt); err != nil {
|
||||
logrus.Error(err)
|
||||
errors = append(errors, err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if mountBase := filepath.Base(mnt); mountBase == id {
|
||||
mountRoot = mnt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if mountRoot != "" {
|
||||
logrus.Debugf("Unmounting %v", mountRoot)
|
||||
if err := unmount(mountRoot); err != nil {
|
||||
logrus.Error(err)
|
||||
errors = append(errors, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if err := sc.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(errors) > 0 {
|
||||
return fmt.Errorf("Error cleaningup mounts:\n%v", strings.Join(errors, "\n"))
|
||||
return fmt.Errorf("Error cleaning up mounts:\n%v", strings.Join(errors, "\n"))
|
||||
}
|
||||
|
||||
logrus.Debugf("Cleaning up old container shm/mqueue/rootfs mounts: done.")
|
||||
logrus.Debugf("Cleaning up old mountid %v: done.", id)
|
||||
return nil
|
||||
}
|
||||
|
||||
// cleanupMounts umounts shm/mqueue mounts for old containers
|
||||
func (daemon *Daemon) cleanupMounts() error {
|
||||
logrus.Debugf("Cleaning up old container shm/mqueue/rootfs mounts: start.")
|
||||
f, err := os.Open("/proc/self/mountinfo")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return daemon.cleanupMountsFromReader(f, mount.Unmount)
|
||||
return daemon.cleanupMountsByID("")
|
||||
}
|
||||
|
||||
func (daemon *Daemon) cleanupMountsFromReader(reader io.Reader, unmount func(target string) error) error {
|
||||
if daemon.root == "" {
|
||||
return nil
|
||||
func getCleanPatterns(id string) (regexps []*regexp.Regexp) {
|
||||
var patterns []string
|
||||
if id == "" {
|
||||
id = "[0-9a-f]{64}"
|
||||
patterns = append(patterns, "containers/"+id+"/shm")
|
||||
}
|
||||
sc := bufio.NewScanner(reader)
|
||||
var errors []string
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
fields := strings.Fields(line)
|
||||
if strings.HasPrefix(fields[4], daemon.root) {
|
||||
logrus.Debugf("Mount base: %v", fields[4])
|
||||
mnt := fields[4]
|
||||
mountBase := filepath.Base(mnt)
|
||||
if mountBase == "shm" || mountBase == "merged" {
|
||||
logrus.Debugf("Unmounting %v", mnt)
|
||||
if err := unmount(mnt); err != nil {
|
||||
logrus.Error(err)
|
||||
errors = append(errors, err.Error())
|
||||
}
|
||||
}
|
||||
patterns = append(patterns, "aufs/mnt/"+id+"$", "overlay/"+id+"/merged$", "zfs/graph/"+id+"$")
|
||||
for _, p := range patterns {
|
||||
r, err := regexp.Compile(p)
|
||||
if err == nil {
|
||||
regexps = append(regexps, r)
|
||||
}
|
||||
}
|
||||
|
||||
if err := sc.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(errors) > 0 {
|
||||
return fmt.Errorf("Error cleaningup mounts:\n%v", strings.Join(errors, "\n"))
|
||||
}
|
||||
|
||||
logrus.Debugf("Cleaning up old container shm/mqueue/rootfs mounts: done.")
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ func TestCleanupMounts(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
|
||||
d.cleanupMountsFromReader(strings.NewReader(mountsFixture), unmount)
|
||||
d.cleanupMountsFromReaderByID(strings.NewReader(mountsFixture), "", unmount)
|
||||
|
||||
if unmounted != 1 {
|
||||
t.Fatalf("Expected to unmount the shm (and the shm only)")
|
||||
@@ -97,7 +97,7 @@ func TestNotCleanupMounts(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
mountInfo := `234 232 0:59 / /dev/shm rw,nosuid,nodev,noexec,relatime - tmpfs shm rw,size=65536k`
|
||||
d.cleanupMountsFromReader(strings.NewReader(mountInfo), unmount)
|
||||
d.cleanupMountsFromReaderByID(strings.NewReader(mountInfo), "", unmount)
|
||||
if unmounted {
|
||||
t.Fatalf("Expected not to clean up /dev/shm")
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ func getBlkioWeightDevices(config containertypes.Resources) ([]specs.WeightDevic
|
||||
weight := weightDevice.Weight
|
||||
d := specs.WeightDevice{Weight: &weight}
|
||||
d.Major = int64(stat.Rdev / 256)
|
||||
d.Major = int64(stat.Rdev % 256)
|
||||
d.Minor = int64(stat.Rdev % 256)
|
||||
blkioWeightDevices = append(blkioWeightDevices, d)
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ func getBlkioReadIOpsDevices(config containertypes.Resources) ([]specs.ThrottleD
|
||||
rate := iopsDevice.Rate
|
||||
d := specs.ThrottleDevice{Rate: &rate}
|
||||
d.Major = int64(stat.Rdev / 256)
|
||||
d.Major = int64(stat.Rdev % 256)
|
||||
d.Minor = int64(stat.Rdev % 256)
|
||||
blkioReadIOpsDevice = append(blkioReadIOpsDevice, d)
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ func getBlkioWriteIOpsDevices(config containertypes.Resources) ([]specs.Throttle
|
||||
rate := iopsDevice.Rate
|
||||
d := specs.ThrottleDevice{Rate: &rate}
|
||||
d.Major = int64(stat.Rdev / 256)
|
||||
d.Major = int64(stat.Rdev % 256)
|
||||
d.Minor = int64(stat.Rdev % 256)
|
||||
blkioWriteIOpsDevice = append(blkioWriteIOpsDevice, d)
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ func getBlkioReadBpsDevices(config containertypes.Resources) ([]specs.ThrottleDe
|
||||
rate := bpsDevice.Rate
|
||||
d := specs.ThrottleDevice{Rate: &rate}
|
||||
d.Major = int64(stat.Rdev / 256)
|
||||
d.Major = int64(stat.Rdev % 256)
|
||||
d.Minor = int64(stat.Rdev % 256)
|
||||
blkioReadBpsDevice = append(blkioReadBpsDevice, d)
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ func getBlkioWriteBpsDevices(config containertypes.Resources) ([]specs.ThrottleD
|
||||
rate := bpsDevice.Rate
|
||||
d := specs.ThrottleDevice{Rate: &rate}
|
||||
d.Major = int64(stat.Rdev / 256)
|
||||
d.Major = int64(stat.Rdev % 256)
|
||||
d.Minor = int64(stat.Rdev % 256)
|
||||
blkioWriteBpsDevice = append(blkioWriteBpsDevice, d)
|
||||
}
|
||||
|
||||
@@ -466,28 +466,36 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
|
||||
func (daemon *Daemon) getCgroupDriver() string {
|
||||
cgroupDriver := cgroupFsDriver
|
||||
|
||||
// No other cgroup drivers are supported at the moment. Warn the
|
||||
// user if they tried to set one other than cgroupfs
|
||||
for _, option := range daemon.configStore.ExecOptions {
|
||||
if UsingSystemd(daemon.configStore) {
|
||||
cgroupDriver = cgroupSystemdDriver
|
||||
}
|
||||
return cgroupDriver
|
||||
}
|
||||
|
||||
// getCD gets the raw value of the native.cgroupdriver option, if set.
|
||||
func getCD(config *Config) string {
|
||||
for _, option := range config.ExecOptions {
|
||||
key, val, err := parsers.ParseKeyValueOpt(option)
|
||||
if err != nil || !strings.EqualFold(key, "native.cgroupdriver") {
|
||||
continue
|
||||
}
|
||||
if val != cgroupFsDriver {
|
||||
logrus.Warnf("cgroupdriver '%s' is not supported", val)
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
return cgroupDriver
|
||||
return ""
|
||||
}
|
||||
|
||||
func usingSystemd(config *Config) bool {
|
||||
// No support for systemd cgroup atm
|
||||
return false
|
||||
// VerifyCgroupDriver validates native.cgroupdriver
|
||||
func VerifyCgroupDriver(config *Config) error {
|
||||
cd := getCD(config)
|
||||
if cd == "" || cd == cgroupFsDriver || cd == cgroupSystemdDriver {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("native.cgroupdriver option %s not supported", cd)
|
||||
}
|
||||
|
||||
func (daemon *Daemon) usingSystemd() bool {
|
||||
return daemon.getCgroupDriver() == cgroupSystemdDriver
|
||||
// UsingSystemd returns true if cli option includes native.cgroupdriver=systemd
|
||||
func UsingSystemd(config *Config) bool {
|
||||
return getCD(config) == cgroupSystemdDriver
|
||||
}
|
||||
|
||||
// verifyPlatformContainerSettings performs platform-specific validation of the
|
||||
@@ -533,7 +541,7 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
|
||||
return warnings, fmt.Errorf("Cannot use the --read-only option when user namespaces are enabled")
|
||||
}
|
||||
}
|
||||
if hostConfig.CgroupParent != "" && daemon.usingSystemd() {
|
||||
if hostConfig.CgroupParent != "" && UsingSystemd(daemon.configStore) {
|
||||
// CgroupParent for systemd cgroup should be named as "xxx.slice"
|
||||
if len(hostConfig.CgroupParent) <= 6 || !strings.HasSuffix(hostConfig.CgroupParent, ".slice") {
|
||||
return warnings, fmt.Errorf("cgroup-parent for systemd cgroup should be a valid slice named as \"xxx.slice\"")
|
||||
@@ -554,7 +562,10 @@ func verifyDaemonSettings(config *Config) error {
|
||||
if !config.bridgeConfig.EnableIPTables && config.bridgeConfig.EnableIPMasq {
|
||||
config.bridgeConfig.EnableIPMasq = false
|
||||
}
|
||||
if config.CgroupParent != "" && usingSystemd(config) {
|
||||
if err := VerifyCgroupDriver(config); err != nil {
|
||||
return err
|
||||
}
|
||||
if config.CgroupParent != "" && UsingSystemd(config) {
|
||||
if len(config.CgroupParent) <= 6 || !strings.HasSuffix(config.CgroupParent, ".slice") {
|
||||
return fmt.Errorf("cgroup-parent for systemd cgroup should be a valid slice named as \"xxx.slice\"")
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ func (daemon *Daemon) cleanupContainer(container *container.Container, forceRemo
|
||||
// Save container state to disk. So that if error happens before
|
||||
// container meta file got removed from disk, then a restart of
|
||||
// docker should not make a dead container alive.
|
||||
if err := container.ToDiskLocking(); err != nil {
|
||||
if err := container.ToDiskLocking(); err != nil && !os.IsNotExist(err) {
|
||||
logrus.Errorf("Error saving dying container to disk: %v", err)
|
||||
}
|
||||
|
||||
@@ -123,10 +123,14 @@ func (daemon *Daemon) cleanupContainer(container *container.Container, forceRemo
|
||||
return fmt.Errorf("Unable to remove filesystem for %v: %v", container.ID, err)
|
||||
}
|
||||
|
||||
metadata, err := daemon.layerStore.ReleaseRWLayer(container.RWLayer)
|
||||
layer.LogReleaseMetadata(metadata)
|
||||
if err != nil && err != layer.ErrMountDoesNotExist {
|
||||
return fmt.Errorf("Driver %s failed to remove root filesystem %s: %s", daemon.GraphDriverName(), container.ID, err)
|
||||
// When container creation fails and `RWLayer` has not been created yet, we
|
||||
// do not call `ReleaseRWLayer`
|
||||
if container.RWLayer != nil {
|
||||
metadata, err := daemon.layerStore.ReleaseRWLayer(container.RWLayer)
|
||||
layer.LogReleaseMetadata(metadata)
|
||||
if err != nil && err != layer.ErrMountDoesNotExist {
|
||||
return fmt.Errorf("Driver %s failed to remove root filesystem %s: %s", daemon.GraphDriverName(), container.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
@@ -64,21 +65,14 @@ func init() {
|
||||
graphdriver.Register("aufs", Init)
|
||||
}
|
||||
|
||||
type data struct {
|
||||
referenceCount int
|
||||
path string
|
||||
}
|
||||
|
||||
// Driver contains information about the filesystem mounted.
|
||||
// root of the filesystem
|
||||
// sync.Mutex to protect against concurrent modifications
|
||||
// active maps mount id to the count
|
||||
type Driver struct {
|
||||
root string
|
||||
uidMaps []idtools.IDMap
|
||||
gidMaps []idtools.IDMap
|
||||
sync.Mutex // Protects concurrent modification to active
|
||||
active map[string]*data
|
||||
sync.Mutex
|
||||
root string
|
||||
uidMaps []idtools.IDMap
|
||||
gidMaps []idtools.IDMap
|
||||
pathCacheLock sync.Mutex
|
||||
pathCache map[string]string
|
||||
}
|
||||
|
||||
// Init returns a new AUFS driver.
|
||||
@@ -111,10 +105,10 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
||||
}
|
||||
|
||||
a := &Driver{
|
||||
root: root,
|
||||
active: make(map[string]*data),
|
||||
uidMaps: uidMaps,
|
||||
gidMaps: gidMaps,
|
||||
root: root,
|
||||
uidMaps: uidMaps,
|
||||
gidMaps: gidMaps,
|
||||
pathCache: make(map[string]string),
|
||||
}
|
||||
|
||||
rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
|
||||
@@ -228,9 +222,7 @@ func (a *Driver) Create(id, parent, mountLabel string) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
a.Lock()
|
||||
a.active[id] = &data{}
|
||||
a.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -259,108 +251,91 @@ func (a *Driver) createDirsFor(id string) error {
|
||||
|
||||
// Remove will unmount and remove the given id.
|
||||
func (a *Driver) Remove(id string) error {
|
||||
// Protect the a.active from concurrent access
|
||||
a.Lock()
|
||||
defer a.Unlock()
|
||||
|
||||
m := a.active[id]
|
||||
if m != nil {
|
||||
if m.referenceCount > 0 {
|
||||
return nil
|
||||
}
|
||||
// Make sure the dir is umounted first
|
||||
if err := a.unmount(m); err != nil {
|
||||
return err
|
||||
}
|
||||
a.pathCacheLock.Lock()
|
||||
mountpoint, exists := a.pathCache[id]
|
||||
a.pathCacheLock.Unlock()
|
||||
if !exists {
|
||||
mountpoint = a.getMountpoint(id)
|
||||
}
|
||||
tmpDirs := []string{
|
||||
"mnt",
|
||||
"diff",
|
||||
if err := a.unmount(mountpoint); err != nil {
|
||||
// no need to return here, we can still try to remove since the `Rename` will fail below if still mounted
|
||||
logrus.Debugf("aufs: error while unmounting %s: %v", mountpoint, err)
|
||||
}
|
||||
|
||||
// Atomically remove each directory in turn by first moving it out of the
|
||||
// way (so that docker doesn't find it anymore) before doing removal of
|
||||
// the whole tree.
|
||||
for _, p := range tmpDirs {
|
||||
realPath := path.Join(a.rootPath(), p, id)
|
||||
tmpPath := path.Join(a.rootPath(), p, fmt.Sprintf("%s-removing", id))
|
||||
if err := os.Rename(realPath, tmpPath); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tmpPath)
|
||||
tmpMntPath := path.Join(a.mntPath(), fmt.Sprintf("%s-removing", id))
|
||||
if err := os.Rename(mountpoint, tmpMntPath); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tmpMntPath)
|
||||
|
||||
tmpDiffpath := path.Join(a.diffPath(), fmt.Sprintf("%s-removing", id))
|
||||
if err := os.Rename(a.getDiffPath(id), tmpDiffpath); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tmpDiffpath)
|
||||
|
||||
// Remove the layers file for the id
|
||||
if err := os.Remove(path.Join(a.rootPath(), "layers", id)); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
if m != nil {
|
||||
delete(a.active, id)
|
||||
}
|
||||
|
||||
a.pathCacheLock.Lock()
|
||||
delete(a.pathCache, id)
|
||||
a.pathCacheLock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the rootfs path for the id.
|
||||
// This will mount the dir at it's given path
|
||||
func (a *Driver) Get(id, mountLabel string) (string, error) {
|
||||
// Protect the a.active from concurrent access
|
||||
a.Lock()
|
||||
defer a.Unlock()
|
||||
|
||||
m := a.active[id]
|
||||
if m == nil {
|
||||
m = &data{}
|
||||
a.active[id] = m
|
||||
}
|
||||
|
||||
parents, err := a.getParentLayerPaths(id)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// If a dir does not have a parent ( no layers )do not try to mount
|
||||
// just return the diff path to the data
|
||||
m.path = path.Join(a.rootPath(), "diff", id)
|
||||
if len(parents) > 0 {
|
||||
m.path = path.Join(a.rootPath(), "mnt", id)
|
||||
if m.referenceCount == 0 {
|
||||
if err := a.mount(id, m, mountLabel, parents); err != nil {
|
||||
return "", err
|
||||
}
|
||||
a.pathCacheLock.Lock()
|
||||
m, exists := a.pathCache[id]
|
||||
a.pathCacheLock.Unlock()
|
||||
|
||||
if !exists {
|
||||
m = a.getDiffPath(id)
|
||||
if len(parents) > 0 {
|
||||
m = a.getMountpoint(id)
|
||||
}
|
||||
}
|
||||
m.referenceCount++
|
||||
return m.path, nil
|
||||
|
||||
// If a dir does not have a parent ( no layers )do not try to mount
|
||||
// just return the diff path to the data
|
||||
if len(parents) > 0 {
|
||||
if err := a.mount(id, m, mountLabel, parents); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
a.pathCacheLock.Lock()
|
||||
a.pathCache[id] = m
|
||||
a.pathCacheLock.Unlock()
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// Put unmounts and updates list of active mounts.
|
||||
func (a *Driver) Put(id string) error {
|
||||
// Protect the a.active from concurrent access
|
||||
a.Lock()
|
||||
defer a.Unlock()
|
||||
a.pathCacheLock.Lock()
|
||||
m, exists := a.pathCache[id]
|
||||
if !exists {
|
||||
m = a.getMountpoint(id)
|
||||
a.pathCache[id] = m
|
||||
}
|
||||
a.pathCacheLock.Unlock()
|
||||
|
||||
m := a.active[id]
|
||||
if m == nil {
|
||||
// but it might be still here
|
||||
if a.Exists(id) {
|
||||
path := path.Join(a.rootPath(), "mnt", id)
|
||||
err := Unmount(path)
|
||||
if err != nil {
|
||||
logrus.Debugf("Failed to unmount %s aufs: %v", id, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
err := a.unmount(m)
|
||||
if err != nil {
|
||||
logrus.Debugf("Failed to unmount %s aufs: %v", id, err)
|
||||
}
|
||||
if count := m.referenceCount; count > 1 {
|
||||
m.referenceCount = count - 1
|
||||
} else {
|
||||
ids, _ := getParentIds(a.rootPath(), id)
|
||||
// We only mounted if there are any parents
|
||||
if ids != nil && len(ids) > 0 {
|
||||
a.unmount(m)
|
||||
}
|
||||
delete(a.active, id)
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// Diff produces an archive of the changes between the specified
|
||||
@@ -443,16 +418,16 @@ func (a *Driver) getParentLayerPaths(id string) ([]string, error) {
|
||||
return layers, nil
|
||||
}
|
||||
|
||||
func (a *Driver) mount(id string, m *data, mountLabel string, layers []string) error {
|
||||
func (a *Driver) mount(id string, target string, mountLabel string, layers []string) error {
|
||||
a.Lock()
|
||||
defer a.Unlock()
|
||||
|
||||
// If the id is mounted or we get an error return
|
||||
if mounted, err := a.mounted(m); err != nil || mounted {
|
||||
if mounted, err := a.mounted(target); err != nil || mounted {
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
target = m.path
|
||||
rw = path.Join(a.rootPath(), "diff", id)
|
||||
)
|
||||
rw := a.getDiffPath(id)
|
||||
|
||||
if err := a.aufsMount(layers, rw, target, mountLabel); err != nil {
|
||||
return fmt.Errorf("error creating aufs mount to %s: %v", target, err)
|
||||
@@ -460,26 +435,42 @@ func (a *Driver) mount(id string, m *data, mountLabel string, layers []string) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Driver) unmount(m *data) error {
|
||||
if mounted, err := a.mounted(m); err != nil || !mounted {
|
||||
func (a *Driver) unmount(mountPath string) error {
|
||||
a.Lock()
|
||||
defer a.Unlock()
|
||||
|
||||
if mounted, err := a.mounted(mountPath); err != nil || !mounted {
|
||||
return err
|
||||
}
|
||||
return Unmount(m.path)
|
||||
if err := Unmount(mountPath); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Driver) mounted(m *data) (bool, error) {
|
||||
var buf syscall.Statfs_t
|
||||
if err := syscall.Statfs(m.path, &buf); err != nil {
|
||||
return false, nil
|
||||
}
|
||||
return graphdriver.FsMagic(buf.Type) == graphdriver.FsMagicAufs, nil
|
||||
func (a *Driver) mounted(mountpoint string) (bool, error) {
|
||||
return graphdriver.Mounted(graphdriver.FsMagicAufs, mountpoint)
|
||||
}
|
||||
|
||||
// Cleanup aufs and unmount all mountpoints
|
||||
func (a *Driver) Cleanup() error {
|
||||
for id, m := range a.active {
|
||||
var dirs []string
|
||||
if err := filepath.Walk(a.mntPath(), func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
dirs = append(dirs, path)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, m := range dirs {
|
||||
if err := a.unmount(m); err != nil {
|
||||
logrus.Errorf("Unmounting %s: %s", stringid.TruncateID(id), err)
|
||||
logrus.Debugf("aufs error unmounting %s: %s", stringid.TruncateID(m), err)
|
||||
}
|
||||
}
|
||||
return mountpk.Unmount(a.root)
|
||||
|
||||
@@ -200,7 +200,7 @@ func TestMountedFalseResponse(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
response, err := d.mounted(d.active["1"])
|
||||
response, err := d.mounted(d.getDiffPath("1"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -227,7 +227,7 @@ func TestMountedTrueReponse(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
response, err := d.mounted(d.active["2"])
|
||||
response, err := d.mounted(d.pathCache["2"])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -293,7 +293,7 @@ func TestRemoveMountedDir(t *testing.T) {
|
||||
t.Fatal("mntPath should not be empty string")
|
||||
}
|
||||
|
||||
mounted, err := d.mounted(d.active["2"])
|
||||
mounted, err := d.mounted(d.pathCache["2"])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -46,3 +46,19 @@ func getParentIds(root, id string) ([]string, error) {
|
||||
}
|
||||
return out, s.Err()
|
||||
}
|
||||
|
||||
func (a *Driver) getMountpoint(id string) string {
|
||||
return path.Join(a.mntPath(), id)
|
||||
}
|
||||
|
||||
func (a *Driver) mntPath() string {
|
||||
return path.Join(a.rootPath(), "mnt")
|
||||
}
|
||||
|
||||
func (a *Driver) getDiffPath(id string) string {
|
||||
return path.Join(a.diffPath(), id)
|
||||
}
|
||||
|
||||
func (a *Driver) diffPath() string {
|
||||
return path.Join(a.rootPath(), "diff")
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@ package btrfs
|
||||
#include <dirent.h>
|
||||
#include <btrfs/ioctl.h>
|
||||
#include <btrfs/ctree.h>
|
||||
|
||||
static void set_name_btrfs_ioctl_vol_args_v2(struct btrfs_ioctl_vol_args_v2* btrfs_struct, const char* value) {
|
||||
snprintf(btrfs_struct->name, BTRFS_SUBVOL_NAME_MAX, "%s", value);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
@@ -159,9 +163,10 @@ func subvolSnapshot(src, dest, name string) error {
|
||||
|
||||
var args C.struct_btrfs_ioctl_vol_args_v2
|
||||
args.fd = C.__s64(getDirFd(srcDir))
|
||||
for i, c := range []byte(name) {
|
||||
args.name[i] = C.char(c)
|
||||
}
|
||||
|
||||
var cs = C.CString(name)
|
||||
C.set_name_btrfs_ioctl_vol_args_v2(&args, cs)
|
||||
C.free(unsafe.Pointer(cs))
|
||||
|
||||
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, getDirFd(destDir), C.BTRFS_IOC_SNAP_CREATE_V2,
|
||||
uintptr(unsafe.Pointer(&args)))
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
|
||||
"github.com/docker/docker/daemon/graphdriver"
|
||||
"github.com/docker/docker/dockerversion"
|
||||
"github.com/docker/docker/pkg/devicemapper"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/loopback"
|
||||
@@ -69,9 +70,6 @@ type devInfo struct {
|
||||
Deleted bool `json:"deleted"`
|
||||
devices *DeviceSet
|
||||
|
||||
mountCount int
|
||||
mountPath string
|
||||
|
||||
// The global DeviceSet lock guarantees that we serialize all
|
||||
// the calls to libdevmapper (which is not threadsafe), but we
|
||||
// sometimes release that lock while sleeping. In that case
|
||||
@@ -1659,7 +1657,12 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error {
|
||||
|
||||
// https://github.com/docker/docker/issues/4036
|
||||
if supported := devicemapper.UdevSetSyncSupport(true); !supported {
|
||||
logrus.Errorf("devmapper: Udev sync is not supported. This will lead to data loss and unexpected behavior. Install a dynamic binary to use devicemapper or select a different storage driver. For more information, see https://docs.docker.com/engine/reference/commandline/daemon/#daemon-storage-driver-option")
|
||||
if dockerversion.IAmStatic == "true" {
|
||||
logrus.Errorf("devmapper: Udev sync is not supported. This will lead to data loss and unexpected behavior. Install a dynamic binary to use devicemapper or select a different storage driver. For more information, see https://docs.docker.com/engine/reference/commandline/daemon/#daemon-storage-driver-option")
|
||||
} else {
|
||||
logrus.Errorf("devmapper: Udev sync is not supported. This will lead to data loss and unexpected behavior. Install a more recent version of libdevmapper or select a different storage driver. For more information, see https://docs.docker.com/engine/reference/commandline/daemon/#daemon-storage-driver-option")
|
||||
}
|
||||
|
||||
if !devices.overrideUdevSyncCheck {
|
||||
return graphdriver.ErrNotSupported
|
||||
}
|
||||
@@ -1991,13 +1994,6 @@ func (devices *DeviceSet) DeleteDevice(hash string, syncDelete bool) error {
|
||||
devices.Lock()
|
||||
defer devices.Unlock()
|
||||
|
||||
// If mountcount is not zero, that means devices is still in use
|
||||
// or has not been Put() properly. Fail device deletion.
|
||||
|
||||
if info.mountCount != 0 {
|
||||
return fmt.Errorf("devmapper: Can't delete device %v as it is still mounted. mntCount=%v", info.Hash, info.mountCount)
|
||||
}
|
||||
|
||||
return devices.deleteDevice(info, syncDelete)
|
||||
}
|
||||
|
||||
@@ -2116,13 +2112,11 @@ func (devices *DeviceSet) cancelDeferredRemoval(info *devInfo) error {
|
||||
}
|
||||
|
||||
// Shutdown shuts down the device by unmounting the root.
|
||||
func (devices *DeviceSet) Shutdown() error {
|
||||
func (devices *DeviceSet) Shutdown(home string) error {
|
||||
logrus.Debugf("devmapper: [deviceset %s] Shutdown()", devices.devicePrefix)
|
||||
logrus.Debugf("devmapper: Shutting down DeviceSet: %s", devices.root)
|
||||
defer logrus.Debugf("devmapper: [deviceset %s] Shutdown() END", devices.devicePrefix)
|
||||
|
||||
var devs []*devInfo
|
||||
|
||||
// Stop deletion worker. This should start delivering new events to
|
||||
// ticker channel. That means no new instance of cleanupDeletedDevice()
|
||||
// will run after this call. If one instance is already running at
|
||||
@@ -2139,30 +2133,46 @@ func (devices *DeviceSet) Shutdown() error {
|
||||
// metadata. Hence save this early before trying to deactivate devices.
|
||||
devices.saveDeviceSetMetaData()
|
||||
|
||||
for _, info := range devices.Devices {
|
||||
devs = append(devs, info)
|
||||
// ignore the error since it's just a best effort to not try to unmount something that's mounted
|
||||
mounts, _ := mount.GetMounts()
|
||||
mounted := make(map[string]bool, len(mounts))
|
||||
for _, mnt := range mounts {
|
||||
mounted[mnt.Mountpoint] = true
|
||||
}
|
||||
devices.Unlock()
|
||||
|
||||
for _, info := range devs {
|
||||
info.lock.Lock()
|
||||
if info.mountCount > 0 {
|
||||
if err := filepath.Walk(path.Join(home, "mnt"), func(p string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if mounted[p] {
|
||||
// We use MNT_DETACH here in case it is still busy in some running
|
||||
// container. This means it'll go away from the global scope directly,
|
||||
// and the device will be released when that container dies.
|
||||
if err := syscall.Unmount(info.mountPath, syscall.MNT_DETACH); err != nil {
|
||||
logrus.Debugf("devmapper: Shutdown unmounting %s, error: %s", info.mountPath, err)
|
||||
if err := syscall.Unmount(p, syscall.MNT_DETACH); err != nil {
|
||||
logrus.Debugf("devmapper: Shutdown unmounting %s, error: %s", p, err)
|
||||
}
|
||||
|
||||
devices.Lock()
|
||||
if err := devices.deactivateDevice(info); err != nil {
|
||||
logrus.Debugf("devmapper: Shutdown deactivate %s , error: %s", info.Hash, err)
|
||||
}
|
||||
devices.Unlock()
|
||||
}
|
||||
info.lock.Unlock()
|
||||
|
||||
if devInfo, err := devices.lookupDevice(path.Base(p)); err != nil {
|
||||
logrus.Debugf("devmapper: Shutdown lookup device %s, error: %s", path.Base(p), err)
|
||||
} else {
|
||||
if err := devices.deactivateDevice(devInfo); err != nil {
|
||||
logrus.Debugf("devmapper: Shutdown deactivate %s , error: %s", devInfo.Hash, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil && !os.IsNotExist(err) {
|
||||
devices.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
devices.Unlock()
|
||||
|
||||
info, _ := devices.lookupDeviceWithLock("")
|
||||
if info != nil {
|
||||
info.lock.Lock()
|
||||
@@ -2202,15 +2212,6 @@ func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error {
|
||||
devices.Lock()
|
||||
defer devices.Unlock()
|
||||
|
||||
if info.mountCount > 0 {
|
||||
if path != info.mountPath {
|
||||
return fmt.Errorf("devmapper: Trying to mount devmapper device in multiple places (%s, %s)", info.mountPath, path)
|
||||
}
|
||||
|
||||
info.mountCount++
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := devices.activateDeviceIfNeeded(info, false); err != nil {
|
||||
return fmt.Errorf("devmapper: Error activating devmapper device for '%s': %s", hash, err)
|
||||
}
|
||||
@@ -2234,9 +2235,6 @@ func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error {
|
||||
return fmt.Errorf("devmapper: Error mounting '%s' on '%s': %s", info.DevName(), path, err)
|
||||
}
|
||||
|
||||
info.mountCount = 1
|
||||
info.mountPath = path
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2256,20 +2254,6 @@ func (devices *DeviceSet) UnmountDevice(hash, mountPath string) error {
|
||||
devices.Lock()
|
||||
defer devices.Unlock()
|
||||
|
||||
// If there are running containers when daemon crashes, during daemon
|
||||
// restarting, it will kill running containers and will finally call
|
||||
// Put() without calling Get(). So info.MountCount may become negative.
|
||||
// if info.mountCount goes negative, we do the unmount and assign
|
||||
// it to 0.
|
||||
|
||||
info.mountCount--
|
||||
if info.mountCount > 0 {
|
||||
return nil
|
||||
} else if info.mountCount < 0 {
|
||||
logrus.Warnf("devmapper: Mount count of device went negative. Put() called without matching Get(). Resetting count to 0")
|
||||
info.mountCount = 0
|
||||
}
|
||||
|
||||
logrus.Debugf("devmapper: Unmount(%s)", mountPath)
|
||||
if err := syscall.Unmount(mountPath, syscall.MNT_DETACH); err != nil {
|
||||
return err
|
||||
@@ -2280,8 +2264,6 @@ func (devices *DeviceSet) UnmountDevice(hash, mountPath string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
info.mountPath = ""
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) {
|
||||
|
||||
// Cleanup unmounts a device.
|
||||
func (d *Driver) Cleanup() error {
|
||||
err := d.DeviceSet.Shutdown()
|
||||
err := d.DeviceSet.Shutdown(d.home)
|
||||
|
||||
if err2 := mount.Unmount(d.home); err == nil {
|
||||
err = err2
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
package graphdriver
|
||||
|
||||
import "syscall"
|
||||
|
||||
var (
|
||||
// Slice of drivers that should be used in an order
|
||||
priority = []string{
|
||||
"zfs",
|
||||
}
|
||||
)
|
||||
|
||||
// Mounted checks if the given path is mounted as the fs type
|
||||
func Mounted(fsType FsMagic, mountPath string) (bool, error) {
|
||||
var buf syscall.Statfs_t
|
||||
if err := syscall.Statfs(mountPath, &buf); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return FsMagic(buf.Type) == fsType, nil
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ const (
|
||||
FsMagicXfs = FsMagic(0x58465342)
|
||||
// FsMagicZfs filesystem id for Zfs
|
||||
FsMagicZfs = FsMagic(0x2fc12fc1)
|
||||
// FsMagicOverlay filesystem id for overlay
|
||||
FsMagicOverlay = FsMagic(0x794C7630)
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -86,3 +88,12 @@ func GetFSMagic(rootpath string) (FsMagic, error) {
|
||||
}
|
||||
return FsMagic(buf.Type), nil
|
||||
}
|
||||
|
||||
// Mounted checks if the given path is mounted as the fs type
|
||||
func Mounted(fsType FsMagic, mountPath string) (bool, error) {
|
||||
var buf syscall.Statfs_t
|
||||
if err := syscall.Statfs(mountPath, &buf); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return FsMagic(buf.Type) == fsType, nil
|
||||
}
|
||||
|
||||
@@ -88,21 +88,13 @@ func (d *naiveDiffDriverWithApply) ApplyDiff(id, parent string, diff archive.Rea
|
||||
// of that. This means all child images share file (but not directory)
|
||||
// data with the parent.
|
||||
|
||||
// ActiveMount contains information about the count, path and whether is mounted or not.
|
||||
// This information is part of the Driver, that contains list of active mounts that are part of this overlay.
|
||||
type ActiveMount struct {
|
||||
count int
|
||||
path string
|
||||
mounted bool
|
||||
}
|
||||
|
||||
// Driver contains information about the home directory and the list of active mounts that are created using this driver.
|
||||
type Driver struct {
|
||||
home string
|
||||
sync.Mutex // Protects concurrent modification to active
|
||||
active map[string]*ActiveMount
|
||||
uidMaps []idtools.IDMap
|
||||
gidMaps []idtools.IDMap
|
||||
home string
|
||||
pathCacheLock sync.Mutex
|
||||
pathCache map[string]string
|
||||
uidMaps []idtools.IDMap
|
||||
gidMaps []idtools.IDMap
|
||||
}
|
||||
|
||||
var backingFs = "<unknown>"
|
||||
@@ -151,10 +143,10 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
||||
}
|
||||
|
||||
d := &Driver{
|
||||
home: home,
|
||||
active: make(map[string]*ActiveMount),
|
||||
uidMaps: uidMaps,
|
||||
gidMaps: gidMaps,
|
||||
home: home,
|
||||
pathCache: make(map[string]string),
|
||||
uidMaps: uidMaps,
|
||||
gidMaps: gidMaps,
|
||||
}
|
||||
|
||||
return NaiveDiffDriverWithApply(d, uidMaps, gidMaps), nil
|
||||
@@ -325,23 +317,14 @@ func (d *Driver) Remove(id string) error {
|
||||
if err := os.RemoveAll(d.dir(id)); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
d.pathCacheLock.Lock()
|
||||
delete(d.pathCache, id)
|
||||
d.pathCacheLock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get creates and mounts the required file system for the given id and returns the mount path.
|
||||
func (d *Driver) Get(id string, mountLabel string) (string, error) {
|
||||
// Protect the d.active from concurrent access
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
|
||||
mount := d.active[id]
|
||||
if mount != nil {
|
||||
mount.count++
|
||||
return mount.path, nil
|
||||
}
|
||||
|
||||
mount = &ActiveMount{count: 1}
|
||||
|
||||
dir := d.dir(id)
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
return "", err
|
||||
@@ -350,9 +333,10 @@ func (d *Driver) Get(id string, mountLabel string) (string, error) {
|
||||
// If id has a root, just return it
|
||||
rootDir := path.Join(dir, "root")
|
||||
if _, err := os.Stat(rootDir); err == nil {
|
||||
mount.path = rootDir
|
||||
d.active[id] = mount
|
||||
return mount.path, nil
|
||||
d.pathCacheLock.Lock()
|
||||
d.pathCache[id] = rootDir
|
||||
d.pathCacheLock.Unlock()
|
||||
return rootDir, nil
|
||||
}
|
||||
|
||||
lowerID, err := ioutil.ReadFile(path.Join(dir, "lower-id"))
|
||||
@@ -365,6 +349,16 @@ func (d *Driver) Get(id string, mountLabel string) (string, error) {
|
||||
mergedDir := path.Join(dir, "merged")
|
||||
|
||||
opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lowerDir, upperDir, workDir)
|
||||
|
||||
// if it's mounted already, just return
|
||||
mounted, err := d.mounted(mergedDir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if mounted {
|
||||
return mergedDir, nil
|
||||
}
|
||||
|
||||
if err := syscall.Mount("overlay", mergedDir, "overlay", 0, label.FormatMountLabel(opts, mountLabel)); err != nil {
|
||||
return "", fmt.Errorf("error creating overlay mount to %s: %v", mergedDir, err)
|
||||
}
|
||||
@@ -378,42 +372,38 @@ func (d *Driver) Get(id string, mountLabel string) (string, error) {
|
||||
if err := os.Chown(path.Join(workDir, "work"), rootUID, rootGID); err != nil {
|
||||
return "", err
|
||||
}
|
||||
mount.path = mergedDir
|
||||
mount.mounted = true
|
||||
d.active[id] = mount
|
||||
|
||||
return mount.path, nil
|
||||
d.pathCacheLock.Lock()
|
||||
d.pathCache[id] = mergedDir
|
||||
d.pathCacheLock.Unlock()
|
||||
|
||||
return mergedDir, nil
|
||||
}
|
||||
|
||||
func (d *Driver) mounted(dir string) (bool, error) {
|
||||
return graphdriver.Mounted(graphdriver.FsMagicOverlay, dir)
|
||||
}
|
||||
|
||||
// Put unmounts the mount path created for the give id.
|
||||
func (d *Driver) Put(id string) error {
|
||||
// Protect the d.active from concurrent access
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
d.pathCacheLock.Lock()
|
||||
mountpoint, exists := d.pathCache[id]
|
||||
d.pathCacheLock.Unlock()
|
||||
|
||||
mount := d.active[id]
|
||||
if mount == nil {
|
||||
if !exists {
|
||||
logrus.Debugf("Put on a non-mounted device %s", id)
|
||||
// but it might be still here
|
||||
if d.Exists(id) {
|
||||
mergedDir := path.Join(d.dir(id), "merged")
|
||||
err := syscall.Unmount(mergedDir, 0)
|
||||
if err != nil {
|
||||
logrus.Debugf("Failed to unmount %s overlay: %v", id, err)
|
||||
}
|
||||
mountpoint = path.Join(d.dir(id), "merged")
|
||||
}
|
||||
return nil
|
||||
|
||||
d.pathCacheLock.Lock()
|
||||
d.pathCache[id] = mountpoint
|
||||
d.pathCacheLock.Unlock()
|
||||
}
|
||||
|
||||
mount.count--
|
||||
if mount.count > 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
defer delete(d.active, id)
|
||||
if mount.mounted {
|
||||
err := syscall.Unmount(mount.path, 0)
|
||||
if err != nil {
|
||||
if mounted, err := d.mounted(mountpoint); mounted || err != nil {
|
||||
if err = syscall.Unmount(mountpoint, 0); err != nil {
|
||||
logrus.Debugf("Failed to unmount %s overlay: %v", id, err)
|
||||
}
|
||||
return err
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@@ -47,10 +46,6 @@ const (
|
||||
type Driver struct {
|
||||
// info stores the shim driver information
|
||||
info hcsshim.DriverInfo
|
||||
// Mutex protects concurrent modification to active
|
||||
sync.Mutex
|
||||
// active stores references to the activated layers
|
||||
active map[string]int
|
||||
}
|
||||
|
||||
var _ graphdriver.DiffGetterDriver = &Driver{}
|
||||
@@ -63,7 +58,6 @@ func InitFilter(home string, options []string, uidMaps, gidMaps []idtools.IDMap)
|
||||
HomeDir: home,
|
||||
Flavour: filterDriver,
|
||||
},
|
||||
active: make(map[string]int),
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
@@ -76,7 +70,6 @@ func InitDiff(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (
|
||||
HomeDir: home,
|
||||
Flavour: diffDriver,
|
||||
},
|
||||
active: make(map[string]int),
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
@@ -189,9 +182,6 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
|
||||
logrus.Debugf("WindowsGraphDriver Get() id %s mountLabel %s", id, mountLabel)
|
||||
var dir string
|
||||
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
|
||||
rID, err := d.resolveID(id)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -203,16 +193,14 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if d.active[rID] == 0 {
|
||||
if err := hcsshim.ActivateLayer(d.info, rID); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := hcsshim.PrepareLayer(d.info, rID, layerChain); err != nil {
|
||||
if err2 := hcsshim.DeactivateLayer(d.info, rID); err2 != nil {
|
||||
logrus.Warnf("Failed to Deactivate %s: %s", id, err)
|
||||
}
|
||||
return "", err
|
||||
if err := hcsshim.ActivateLayer(d.info, rID); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := hcsshim.PrepareLayer(d.info, rID, layerChain); err != nil {
|
||||
if err2 := hcsshim.DeactivateLayer(d.info, rID); err2 != nil {
|
||||
logrus.Warnf("Failed to Deactivate %s: %s", id, err)
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
mountPath, err := hcsshim.GetLayerMountPath(d.info, rID)
|
||||
@@ -223,8 +211,6 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
d.active[rID]++
|
||||
|
||||
// If the layer has a mount path, use that. Otherwise, use the
|
||||
// folder path.
|
||||
if mountPath != "" {
|
||||
@@ -245,22 +231,10 @@ func (d *Driver) Put(id string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
|
||||
if d.active[rID] > 1 {
|
||||
d.active[rID]--
|
||||
} else if d.active[rID] == 1 {
|
||||
if err := hcsshim.UnprepareLayer(d.info, rID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := hcsshim.DeactivateLayer(d.info, rID); err != nil {
|
||||
return err
|
||||
}
|
||||
delete(d.active, rID)
|
||||
if err := hcsshim.UnprepareLayer(d.info, rID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return hcsshim.DeactivateLayer(d.info, rID)
|
||||
}
|
||||
|
||||
// Cleanup ensures the information the driver stores is properly removed.
|
||||
@@ -270,62 +244,40 @@ func (d *Driver) Cleanup() error {
|
||||
|
||||
// Diff produces an archive of the changes between the specified
|
||||
// layer and its parent layer which may be "".
|
||||
// The layer should be mounted when calling this function
|
||||
func (d *Driver) Diff(id, parent string) (_ archive.Archive, err error) {
|
||||
rID, err := d.resolveID(id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Getting the layer paths must be done outside of the lock.
|
||||
layerChain, err := d.getLayerChain(rID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var undo func()
|
||||
|
||||
d.Lock()
|
||||
|
||||
// To support export, a layer must be activated but not prepared.
|
||||
if d.info.Flavour == filterDriver {
|
||||
if d.active[rID] == 0 {
|
||||
if err = hcsshim.ActivateLayer(d.info, rID); err != nil {
|
||||
d.Unlock()
|
||||
return
|
||||
}
|
||||
undo = func() {
|
||||
if err := hcsshim.DeactivateLayer(d.info, rID); err != nil {
|
||||
logrus.Warnf("Failed to Deactivate %s: %s", rID, err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err = hcsshim.UnprepareLayer(d.info, rID); err != nil {
|
||||
d.Unlock()
|
||||
return
|
||||
}
|
||||
undo = func() {
|
||||
if err := hcsshim.PrepareLayer(d.info, rID, layerChain); err != nil {
|
||||
logrus.Warnf("Failed to re-PrepareLayer %s: %s", rID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// this is assuming that the layer is unmounted
|
||||
if err := hcsshim.UnprepareLayer(d.info, rID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d.Unlock()
|
||||
defer func() {
|
||||
if err := hcsshim.PrepareLayer(d.info, rID, layerChain); err != nil {
|
||||
logrus.Warnf("Failed to Deactivate %s: %s", rID, err)
|
||||
}
|
||||
}()
|
||||
|
||||
arch, err := d.exportLayer(rID, layerChain)
|
||||
if err != nil {
|
||||
undo()
|
||||
return
|
||||
}
|
||||
return ioutils.NewReadCloserWrapper(arch, func() error {
|
||||
defer undo()
|
||||
return arch.Close()
|
||||
}), nil
|
||||
}
|
||||
|
||||
// Changes produces a list of changes between the specified layer
|
||||
// and its parent layer. If parent is "", then all changes will be ADD changes.
|
||||
// The layer should be mounted when calling this function
|
||||
func (d *Driver) Changes(id, parent string) ([]archive.Change, error) {
|
||||
rID, err := d.resolveID(id)
|
||||
if err != nil {
|
||||
@@ -336,31 +288,15 @@ func (d *Driver) Changes(id, parent string) ([]archive.Change, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d.Lock()
|
||||
if d.info.Flavour == filterDriver {
|
||||
if d.active[rID] == 0 {
|
||||
if err = hcsshim.ActivateLayer(d.info, rID); err != nil {
|
||||
d.Unlock()
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err := hcsshim.DeactivateLayer(d.info, rID); err != nil {
|
||||
logrus.Warnf("Failed to Deactivate %s: %s", rID, err)
|
||||
}
|
||||
}()
|
||||
} else {
|
||||
if err = hcsshim.UnprepareLayer(d.info, rID); err != nil {
|
||||
d.Unlock()
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err := hcsshim.PrepareLayer(d.info, rID, parentChain); err != nil {
|
||||
logrus.Warnf("Failed to re-PrepareLayer %s: %s", rID, err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
// this is assuming that the layer is unmounted
|
||||
if err := hcsshim.UnprepareLayer(d.info, rID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d.Unlock()
|
||||
defer func() {
|
||||
if err := hcsshim.PrepareLayer(d.info, rID, parentChain); err != nil {
|
||||
logrus.Warnf("Failed to Deactivate %s: %s", rID, err)
|
||||
}
|
||||
}()
|
||||
|
||||
r, err := hcsshim.NewLayerReader(d.info, id, parentChain)
|
||||
if err != nil {
|
||||
@@ -391,6 +327,7 @@ func (d *Driver) Changes(id, parent string) ([]archive.Change, error) {
|
||||
// ApplyDiff extracts the changeset from the given diff into the
|
||||
// layer with the specified id and parent, returning the size of the
|
||||
// new layer in bytes.
|
||||
// The layer should not be mounted when calling this function
|
||||
func (d *Driver) ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error) {
|
||||
rPId, err := d.resolveID(parent)
|
||||
if err != nil {
|
||||
|
||||
@@ -22,12 +22,6 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/label"
|
||||
)
|
||||
|
||||
type activeMount struct {
|
||||
count int
|
||||
path string
|
||||
mounted bool
|
||||
}
|
||||
|
||||
type zfsOptions struct {
|
||||
fsName string
|
||||
mountPath string
|
||||
@@ -109,7 +103,6 @@ func Init(base string, opt []string, uidMaps, gidMaps []idtools.IDMap) (graphdri
|
||||
dataset: rootDataset,
|
||||
options: options,
|
||||
filesystemsCache: filesystemsCache,
|
||||
active: make(map[string]*activeMount),
|
||||
uidMaps: uidMaps,
|
||||
gidMaps: gidMaps,
|
||||
}
|
||||
@@ -166,7 +159,6 @@ type Driver struct {
|
||||
options zfsOptions
|
||||
sync.Mutex // protects filesystem cache against concurrent access
|
||||
filesystemsCache map[string]bool
|
||||
active map[string]*activeMount
|
||||
uidMaps []idtools.IDMap
|
||||
gidMaps []idtools.IDMap
|
||||
}
|
||||
@@ -302,17 +294,6 @@ func (d *Driver) Remove(id string) error {
|
||||
|
||||
// Get returns the mountpoint for the given id after creating the target directories if necessary.
|
||||
func (d *Driver) Get(id, mountLabel string) (string, error) {
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
|
||||
mnt := d.active[id]
|
||||
if mnt != nil {
|
||||
mnt.count++
|
||||
return mnt.path, nil
|
||||
}
|
||||
|
||||
mnt = &activeMount{count: 1}
|
||||
|
||||
mountpoint := d.mountPath(id)
|
||||
filesystem := d.zfsPath(id)
|
||||
options := label.FormatMountLabel("", mountLabel)
|
||||
@@ -335,48 +316,29 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
|
||||
if err := os.Chown(mountpoint, rootUID, rootGID); err != nil {
|
||||
return "", fmt.Errorf("error modifying zfs mountpoint (%s) directory ownership: %v", mountpoint, err)
|
||||
}
|
||||
mnt.path = mountpoint
|
||||
mnt.mounted = true
|
||||
d.active[id] = mnt
|
||||
|
||||
return mountpoint, nil
|
||||
}
|
||||
|
||||
// Put removes the existing mountpoint for the given id if it exists.
|
||||
func (d *Driver) Put(id string) error {
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
|
||||
mnt := d.active[id]
|
||||
if mnt == nil {
|
||||
logrus.Debugf("[zfs] Put on a non-mounted device %s", id)
|
||||
// but it might be still here
|
||||
if d.Exists(id) {
|
||||
err := mount.Unmount(d.mountPath(id))
|
||||
if err != nil {
|
||||
logrus.Debugf("[zfs] Failed to unmount %s zfs fs: %v", id, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
mountpoint := d.mountPath(id)
|
||||
mounted, err := graphdriver.Mounted(graphdriver.FsMagicZfs, mountpoint)
|
||||
if err != nil || !mounted {
|
||||
return err
|
||||
}
|
||||
|
||||
mnt.count--
|
||||
if mnt.count > 0 {
|
||||
return nil
|
||||
}
|
||||
logrus.Debugf(`[zfs] unmount("%s")`, mountpoint)
|
||||
|
||||
defer delete(d.active, id)
|
||||
if mnt.mounted {
|
||||
logrus.Debugf(`[zfs] unmount("%s")`, mnt.path)
|
||||
|
||||
if err := mount.Unmount(mnt.path); err != nil {
|
||||
return fmt.Errorf("error unmounting to %s: %v", mnt.path, err)
|
||||
}
|
||||
if err := mount.Unmount(mountpoint); err != nil {
|
||||
return fmt.Errorf("error unmounting to %s: %v", mountpoint, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Exists checks to see if the cache entry exists for the given id.
|
||||
func (d *Driver) Exists(id string) bool {
|
||||
d.Lock()
|
||||
defer d.Unlock()
|
||||
return d.filesystemsCache[d.zfsPath(id)] == true
|
||||
}
|
||||
|
||||
@@ -63,11 +63,11 @@ package journald
|
||||
// fds[0].events = POLLHUP;
|
||||
// fds[1].fd = sd_journal_get_fd(j);
|
||||
// if (fds[1].fd < 0) {
|
||||
// return -1;
|
||||
// return fds[1].fd;
|
||||
// }
|
||||
// jevents = sd_journal_get_events(j);
|
||||
// if (jevents < 0) {
|
||||
// return -1;
|
||||
// return jevents;
|
||||
// }
|
||||
// fds[1].events = jevents;
|
||||
// sd_journal_get_timeout(j, &when);
|
||||
@@ -81,7 +81,7 @@ package journald
|
||||
// i = poll(fds, 2, timeout);
|
||||
// if ((i == -1) && (errno != EINTR)) {
|
||||
// /* An unexpected error. */
|
||||
// return -1;
|
||||
// return (errno != 0) ? -errno : -EINTR;
|
||||
// }
|
||||
// if (fds[0].revents & POLLHUP) {
|
||||
// /* The close notification pipe was closed. */
|
||||
@@ -101,6 +101,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/coreos/go-systemd/journal"
|
||||
"github.com/docker/docker/daemon/logger"
|
||||
)
|
||||
@@ -177,9 +178,18 @@ func (s *journald) followJournal(logWatcher *logger.LogWatcher, config logger.Re
|
||||
s.readers.readers[logWatcher] = logWatcher
|
||||
s.readers.mu.Unlock()
|
||||
go func() {
|
||||
// Keep copying journal data out until we're notified to stop.
|
||||
for C.wait_for_data_or_close(j, pfd[0]) == 1 {
|
||||
// Keep copying journal data out until we're notified to stop
|
||||
// or we hit an error.
|
||||
status := C.wait_for_data_or_close(j, pfd[0])
|
||||
for status == 1 {
|
||||
cursor = s.drainJournal(logWatcher, config, j, cursor)
|
||||
status = C.wait_for_data_or_close(j, pfd[0])
|
||||
}
|
||||
if status < 0 {
|
||||
cerrstr := C.strerror(C.int(-status))
|
||||
errstr := C.GoString(cerrstr)
|
||||
fmtstr := "error %q while attempting to follow journal for container %q"
|
||||
logrus.Errorf(fmtstr, errstr, s.vars["CONTAINER_ID_FULL"])
|
||||
}
|
||||
// Clean up.
|
||||
C.close(pfd[0])
|
||||
@@ -293,14 +303,21 @@ func (s *journald) readLogs(logWatcher *logger.LogWatcher, config logger.ReadCon
|
||||
}
|
||||
cursor = s.drainJournal(logWatcher, config, j, "")
|
||||
if config.Follow {
|
||||
// Create a pipe that we can poll at the same time as the journald descriptor.
|
||||
if C.pipe(&pipes[0]) == C.int(-1) {
|
||||
logWatcher.Err <- fmt.Errorf("error opening journald close notification pipe")
|
||||
// Allocate a descriptor for following the journal, if we'll
|
||||
// need one. Do it here so that we can report if it fails.
|
||||
if fd := C.sd_journal_get_fd(j); fd < C.int(0) {
|
||||
logWatcher.Err <- fmt.Errorf("error opening journald follow descriptor: %q", C.GoString(C.strerror(-fd)))
|
||||
} else {
|
||||
s.followJournal(logWatcher, config, j, pipes, cursor)
|
||||
// Let followJournal handle freeing the journal context
|
||||
// object and closing the channel.
|
||||
following = true
|
||||
// Create a pipe that we can poll at the same time as
|
||||
// the journald descriptor.
|
||||
if C.pipe(&pipes[0]) == C.int(-1) {
|
||||
logWatcher.Err <- fmt.Errorf("error opening journald close notification pipe")
|
||||
} else {
|
||||
s.followJournal(logWatcher, config, j, pipes, cursor)
|
||||
// Let followJournal handle freeing the journal context
|
||||
// object and closing the channel.
|
||||
following = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/container"
|
||||
"github.com/docker/docker/daemon/caps"
|
||||
"github.com/docker/docker/libcontainerd"
|
||||
@@ -78,6 +79,7 @@ func setResources(s *specs.Spec, r containertypes.Resources) error {
|
||||
func setDevices(s *specs.Spec, c *container.Container) error {
|
||||
// Build lists of devices allowed and created within the container.
|
||||
var devs []specs.Device
|
||||
devPermissions := s.Linux.Resources.Devices
|
||||
if c.HostConfig.Privileged {
|
||||
hostDevices, err := devices.HostDevices()
|
||||
if err != nil {
|
||||
@@ -86,18 +88,26 @@ func setDevices(s *specs.Spec, c *container.Container) error {
|
||||
for _, d := range hostDevices {
|
||||
devs = append(devs, specDevice(d))
|
||||
}
|
||||
rwm := "rwm"
|
||||
devPermissions = []specs.DeviceCgroup{
|
||||
{
|
||||
Allow: true,
|
||||
Access: &rwm,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
for _, deviceMapping := range c.HostConfig.Devices {
|
||||
d, err := getDevicesFromPath(deviceMapping)
|
||||
d, dPermissions, err := getDevicesFromPath(deviceMapping)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
devs = append(devs, d...)
|
||||
devPermissions = append(devPermissions, dPermissions...)
|
||||
}
|
||||
}
|
||||
|
||||
s.Linux.Devices = append(s.Linux.Devices, devs...)
|
||||
s.Linux.Resources.Devices = devPermissions
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -526,6 +536,8 @@ func setMounts(daemon *Daemon, s *specs.Spec, c *container.Container, mounts []c
|
||||
}
|
||||
}
|
||||
}
|
||||
s.Linux.ReadonlyPaths = nil
|
||||
s.Linux.MaskedPaths = nil
|
||||
}
|
||||
|
||||
// TODO: until a kernel/mount solution exists for handling remount in a user namespace,
|
||||
@@ -574,16 +586,24 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e
|
||||
}
|
||||
|
||||
var cgroupsPath string
|
||||
scopePrefix := "docker"
|
||||
parent := "/docker"
|
||||
useSystemd := UsingSystemd(daemon.configStore)
|
||||
if useSystemd {
|
||||
parent = "system.slice"
|
||||
}
|
||||
|
||||
if c.HostConfig.CgroupParent != "" {
|
||||
cgroupsPath = filepath.Join(c.HostConfig.CgroupParent, c.ID)
|
||||
parent = c.HostConfig.CgroupParent
|
||||
} else if daemon.configStore.CgroupParent != "" {
|
||||
parent = daemon.configStore.CgroupParent
|
||||
}
|
||||
|
||||
if useSystemd {
|
||||
cgroupsPath = parent + ":" + scopePrefix + ":" + c.ID
|
||||
logrus.Debugf("createSpec: cgroupsPath: %s", cgroupsPath)
|
||||
} else {
|
||||
defaultCgroupParent := "/docker"
|
||||
if daemon.configStore.CgroupParent != "" {
|
||||
defaultCgroupParent = daemon.configStore.CgroupParent
|
||||
} else if daemon.usingSystemd() {
|
||||
defaultCgroupParent = "system.slice"
|
||||
}
|
||||
cgroupsPath = filepath.Join(defaultCgroupParent, c.ID)
|
||||
cgroupsPath = filepath.Join(parent, c.ID)
|
||||
}
|
||||
s.Linux.CgroupsPath = &cgroupsPath
|
||||
|
||||
@@ -642,10 +662,10 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e
|
||||
|
||||
if apparmor.IsEnabled() {
|
||||
appArmorProfile := "docker-default"
|
||||
if c.HostConfig.Privileged {
|
||||
appArmorProfile = "unconfined"
|
||||
} else if len(c.AppArmorProfile) > 0 {
|
||||
if len(c.AppArmorProfile) > 0 {
|
||||
appArmorProfile = c.AppArmorProfile
|
||||
} else if c.HostConfig.Privileged {
|
||||
appArmorProfile = "unconfined"
|
||||
}
|
||||
s.Process.ApparmorProfile = appArmorProfile
|
||||
}
|
||||
|
||||
@@ -174,8 +174,10 @@ func (daemon *Daemon) Cleanup(container *container.Container) {
|
||||
daemon.unregisterExecCommand(container, eConfig)
|
||||
}
|
||||
|
||||
if err := container.UnmountVolumes(false, daemon.LogVolumeEvent); err != nil {
|
||||
logrus.Warnf("%s cleanup: Failed to umount volumes: %v", container.ID, err)
|
||||
if container.BaseFS != "" {
|
||||
if err := container.UnmountVolumes(false, daemon.LogVolumeEvent); err != nil {
|
||||
logrus.Warnf("%s cleanup: Failed to umount volumes: %v", container.ID, err)
|
||||
}
|
||||
}
|
||||
container.CancelAttachContext()
|
||||
}
|
||||
|
||||
@@ -330,7 +330,20 @@ func (ld *v1LayerDescriptor) Download(ctx context.Context, progressOutput progre
|
||||
logrus.Debugf("Downloaded %s to tempfile %s", ld.ID(), ld.tmpFile.Name())
|
||||
|
||||
ld.tmpFile.Seek(0, 0)
|
||||
return ld.tmpFile, ld.layerSize, nil
|
||||
|
||||
// hand off the temporary file to the download manager, so it will only
|
||||
// be closed once
|
||||
tmpFile := ld.tmpFile
|
||||
ld.tmpFile = nil
|
||||
|
||||
return ioutils.NewReadCloserWrapper(tmpFile, func() error {
|
||||
tmpFile.Close()
|
||||
err := os.RemoveAll(tmpFile.Name())
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to remove temp file: %s", tmpFile.Name())
|
||||
}
|
||||
return err
|
||||
}), ld.layerSize, nil
|
||||
}
|
||||
|
||||
func (ld *v1LayerDescriptor) Close() {
|
||||
|
||||
@@ -278,7 +278,19 @@ func (ld *v2LayerDescriptor) Download(ctx context.Context, progressOutput progre
|
||||
ld.verifier = nil
|
||||
return nil, 0, xfer.DoNotRetry{Err: err}
|
||||
}
|
||||
return tmpFile, size, nil
|
||||
|
||||
// hand off the temporary file to the download manager, so it will only
|
||||
// be closed once
|
||||
ld.tmpFile = nil
|
||||
|
||||
return ioutils.NewReadCloserWrapper(tmpFile, func() error {
|
||||
tmpFile.Close()
|
||||
err := os.RemoveAll(tmpFile.Name())
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to remove temp file: %s", tmpFile.Name())
|
||||
}
|
||||
return err
|
||||
}), size, nil
|
||||
}
|
||||
|
||||
func (ld *v2LayerDescriptor) Close() {
|
||||
|
||||
@@ -121,6 +121,10 @@ func (ls *mockLayerStore) GetMountID(string) (string, error) {
|
||||
return "", errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (ls *mockLayerStore) ReinitRWLayer(layer.RWLayer) error {
|
||||
return errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (ls *mockLayerStore) Cleanup() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -74,5 +74,9 @@ func (cli *DaemonCli) getPlatformRemoteOptions() []libcontainerd.RemoteOption {
|
||||
} else {
|
||||
opts = append(opts, libcontainerd.WithStartDaemon(true))
|
||||
}
|
||||
if daemon.UsingSystemd(cli.Config) {
|
||||
args := []string{"--systemd-cgroup=true"}
|
||||
opts = append(opts, libcontainerd.WithRuntimeArgs(args))
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
@@ -56,14 +56,14 @@ directory including the following:
|
||||
|
||||
To check if the `docker.service` uses an `EnvironmentFile`:
|
||||
|
||||
$ sudo systemctl show docker | grep EnvironmentFile
|
||||
$ systemctl show docker | grep EnvironmentFile
|
||||
EnvironmentFile=-/etc/sysconfig/docker (ignore_errors=yes)
|
||||
|
||||
Alternatively, find out where the service file is located:
|
||||
|
||||
$ sudo systemctl status docker | grep Loaded
|
||||
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled)
|
||||
$ sudo grep EnvironmentFile /usr/lib/systemd/system/docker.service
|
||||
$ systemctl show --property=FragmentPath docker
|
||||
FragmentPath=/usr/lib/systemd/system/docker.service
|
||||
$ grep EnvironmentFile /usr/lib/systemd/system/docker.service
|
||||
EnvironmentFile=-/etc/sysconfig/docker
|
||||
|
||||
You can customize the Docker daemon options using override files as explained in the
|
||||
@@ -143,7 +143,7 @@ Flush changes:
|
||||
|
||||
Verify that the configuration has been loaded:
|
||||
|
||||
$ sudo systemctl show docker --property Environment
|
||||
$ systemctl show --property=Environment docker
|
||||
Environment=HTTP_PROXY=http://proxy.example.com:80/
|
||||
|
||||
Restart Docker:
|
||||
|
||||
@@ -133,17 +133,6 @@ The following double-dash options are deprecated and have no replacement:
|
||||
docker ps --before-id
|
||||
docker search --trusted
|
||||
|
||||
### Auto-creating missing host paths for bind mounts
|
||||
**Deprecated in Release: v1.9**
|
||||
|
||||
**Target for Removal in Release: 1.11**
|
||||
|
||||
When creating a container with a bind-mounted volume-- `docker run -v /host/path:/container/path` --
|
||||
docker was automatically creating the `/host/path` if it didn't already exist.
|
||||
|
||||
This auto-creation of the host path is deprecated and docker will error out if
|
||||
the path does not exist.
|
||||
|
||||
### Interacting with V1 registries
|
||||
|
||||
Version 1.9 adds a flag (`--disable-legacy-registry=false`) which prevents the docker daemon from `pull`, `push`, and `login` operations against v1 registries. Though disabled by default, this signals the intent to deprecate the v1 protocol.
|
||||
|
||||
@@ -169,9 +169,10 @@ Responds with a list of Docker subsystems which this plugin implements.
|
||||
After activation, the plugin will then be sent events from this subsystem.
|
||||
|
||||
Possible values are:
|
||||
- [`authz`](plugins_authorization.md)
|
||||
- [`NetworkDriver`](plugins_network.md)
|
||||
- [`VolumeDriver`](plugins_volume.md)
|
||||
|
||||
* [`authz`](plugins_authorization.md)
|
||||
* [`NetworkDriver`](plugins_network.md)
|
||||
* [`VolumeDriver`](plugins_volume.md)
|
||||
|
||||
|
||||
## Plugin retries
|
||||
|
||||
@@ -14,6 +14,7 @@ weight = -6
|
||||
|
||||
Docker is supported on these Ubuntu operating systems:
|
||||
|
||||
- Ubuntu Xenial 16.04 (LTS)
|
||||
- Ubuntu Wily 15.10
|
||||
- Ubuntu Trusty 14.04 (LTS)
|
||||
- Ubuntu Precise 12.04 (LTS)
|
||||
@@ -85,6 +86,10 @@ packages from the new repository:
|
||||
|
||||
deb https://apt.dockerproject.org/repo ubuntu-wily main
|
||||
|
||||
- Ubuntu Xenial 16.04 (LTS)
|
||||
|
||||
deb https://apt.dockerproject.org/repo ubuntu-xenial main
|
||||
|
||||
> **Note**: Docker does not provide packages for all architectures. You can find
|
||||
> nightly built binaries in https://master.dockerproject.org. To install docker on
|
||||
> a multi-architecture system, add an `[arch=...]` clause to the entry. Refer to the
|
||||
@@ -109,10 +114,11 @@ packages from the new repository:
|
||||
|
||||
### Prerequisites by Ubuntu Version
|
||||
|
||||
- Ubuntu Xenial 16.04 (LTS)
|
||||
- Ubuntu Wily 15.10
|
||||
- Ubuntu Trusty 14.04 (LTS)
|
||||
|
||||
For Ubuntu Trusty and Wily, it's recommended to install the
|
||||
For Ubuntu Trusty, Wily, and Xenial, it's recommended to install the
|
||||
`linux-image-extra` kernel package. The `linux-image-extra` package
|
||||
allows you use the `aufs` storage driver.
|
||||
|
||||
|
||||
@@ -996,7 +996,7 @@ Tag the image `name` into a repository
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
|
||||
Query Parameters:
|
||||
|
||||
|
||||
@@ -1147,7 +1147,7 @@ Tag the image `name` into a repository
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -1644,7 +1644,7 @@ Sets up an exec instance in a running container `id`
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -1685,8 +1685,8 @@ interactive session with the `exec` command.
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
Content-Type: application/json
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/vnd.docker.raw-stream
|
||||
|
||||
{{ STREAM }}
|
||||
|
||||
@@ -1717,7 +1717,7 @@ This API is valid only if `tty` was specified as part of creating and starting t
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: plain/text
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -1095,7 +1095,7 @@ Tag the image `name` into a repository
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -1606,7 +1606,7 @@ Sets up an exec instance in a running container `id`
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -1647,8 +1647,8 @@ interactive session with the `exec` command.
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
Content-Type: application/json
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/vnd.docker.raw-stream
|
||||
|
||||
{{ STREAM }}
|
||||
|
||||
@@ -1679,7 +1679,7 @@ This API is valid only if `tty` was specified as part of creating and starting t
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: plain/text
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -1308,7 +1308,7 @@ Tag the image `name` into a repository
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -1769,7 +1769,7 @@ Sets up an exec instance in a running container `id`
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -1810,8 +1810,8 @@ interactive session with the `exec` command.
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
Content-Type: application/json
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/vnd.docker.raw-stream
|
||||
|
||||
{{ STREAM }}
|
||||
|
||||
@@ -1842,7 +1842,7 @@ This API is valid only if `tty` was specified as part of creating and starting t
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: text/plain
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -1408,7 +1408,7 @@ Tag the image `name` into a repository
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -1887,7 +1887,7 @@ Sets up an exec instance in a running container `id`
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -1929,8 +1929,8 @@ interactive session with the `exec` command.
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
Content-Type: application/json
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/vnd.docker.raw-stream
|
||||
|
||||
{{ STREAM }}
|
||||
|
||||
@@ -1961,7 +1961,7 @@ This API is valid only if `tty` was specified as part of creating and starting t
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: text/plain
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -1477,7 +1477,7 @@ Tag the image `name` into a repository
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -1970,7 +1970,7 @@ Sets up an exec instance in a running container `id`
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -2012,8 +2012,8 @@ interactive session with the `exec` command.
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
Content-Type: application/json
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/vnd.docker.raw-stream
|
||||
|
||||
{{ STREAM }}
|
||||
|
||||
@@ -2044,7 +2044,7 @@ This API is valid only if `tty` was specified as part of creating and starting t
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: text/plain
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -154,14 +154,9 @@ Create a container
|
||||
"com.example.license": "GPL",
|
||||
"com.example.version": "1.0"
|
||||
},
|
||||
"Mounts": [
|
||||
{
|
||||
"Source": "/data",
|
||||
"Destination": "/data",
|
||||
"Mode": "ro,Z",
|
||||
"RW": false
|
||||
}
|
||||
],
|
||||
"Volumes": {
|
||||
"/volumes/data": {}
|
||||
}
|
||||
"WorkingDir": "",
|
||||
"NetworkDisabled": false,
|
||||
"MacAddress": "12:34:56:78:9a:bc",
|
||||
@@ -245,7 +240,8 @@ Json Parameters:
|
||||
- **Entrypoint** - Set the entry point for the container as a string or an array
|
||||
of strings.
|
||||
- **Image** - A string specifying the image name to use for the container.
|
||||
- **Mounts** - An array of mount points in the container.
|
||||
- **Volumes** - An object mapping mount point paths (strings) inside the
|
||||
container to empty objects.
|
||||
- **WorkingDir** - A string specifying the working directory for commands to
|
||||
run in.
|
||||
- **NetworkDisabled** - Boolean value, when true disables networking for the
|
||||
@@ -1622,7 +1618,7 @@ Tag the image `name` into a repository
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -2116,7 +2112,7 @@ Sets up an exec instance in a running container `id`
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -2158,8 +2154,8 @@ interactive session with the `exec` command.
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
Content-Type: application/json
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/vnd.docker.raw-stream
|
||||
|
||||
{{ STREAM }}
|
||||
|
||||
@@ -2190,7 +2186,7 @@ This API is valid only if `tty` was specified as part of creating and starting t
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: text/plain
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -158,14 +158,9 @@ Create a container
|
||||
"com.example.license": "GPL",
|
||||
"com.example.version": "1.0"
|
||||
},
|
||||
"Mounts": [
|
||||
{
|
||||
"Source": "/data",
|
||||
"Destination": "/data",
|
||||
"Mode": "ro,Z",
|
||||
"RW": false
|
||||
}
|
||||
],
|
||||
"Volumes": {
|
||||
"/volumes/data": {}
|
||||
}
|
||||
"WorkingDir": "",
|
||||
"NetworkDisabled": false,
|
||||
"MacAddress": "12:34:56:78:9a:bc",
|
||||
@@ -256,7 +251,8 @@ Json Parameters:
|
||||
- **Entrypoint** - Set the entry point for the container as a string or an array
|
||||
of strings.
|
||||
- **Image** - A string specifying the image name to use for the container.
|
||||
- **Mounts** - An array of mount points in the container.
|
||||
- **Volumes** - An object mapping mount point paths (strings) inside the
|
||||
container to empty objects.
|
||||
- **WorkingDir** - A string specifying the working directory for commands to
|
||||
run in.
|
||||
- **NetworkDisabled** - Boolean value, when true disables networking for the
|
||||
@@ -1773,7 +1769,7 @@ Tag the image `name` into a repository
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -2270,7 +2266,7 @@ Sets up an exec instance in a running container `id`
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -2314,8 +2310,8 @@ interactive session with the `exec` command.
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
Content-Type: application/json
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/vnd.docker.raw-stream
|
||||
|
||||
{{ STREAM }}
|
||||
|
||||
@@ -2347,7 +2343,7 @@ This API is valid only if `tty` was specified as part of creating and starting t
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: text/plain
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -246,17 +246,6 @@ Create a container
|
||||
"com.example.license": "GPL",
|
||||
"com.example.version": "1.0"
|
||||
},
|
||||
"Mounts": [
|
||||
{
|
||||
"Name": "fac362...80535",
|
||||
"Source": "/data",
|
||||
"Destination": "/data",
|
||||
"Driver": "local",
|
||||
"Mode": "ro,Z",
|
||||
"RW": false,
|
||||
"Propagation": ""
|
||||
}
|
||||
],
|
||||
"Volumes": {
|
||||
"/volumes/data": {}
|
||||
}
|
||||
@@ -366,7 +355,8 @@ Json Parameters:
|
||||
- **Entrypoint** - Set the entry point for the container as a string or an array
|
||||
of strings.
|
||||
- **Image** - A string specifying the image name to use for the container.
|
||||
- **Mounts** - An array of mount points in the container.
|
||||
- **Volumes** - An object mapping mount point paths (strings) inside the
|
||||
container to empty objects.
|
||||
- **WorkingDir** - A string specifying the working directory for commands to
|
||||
run in.
|
||||
- **NetworkDisabled** - Boolean value, when true disables networking for the
|
||||
@@ -1984,7 +1974,7 @@ Tag the image `name` into a repository
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -2547,7 +2537,7 @@ Sets up an exec instance in a running container `id`
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -2594,8 +2584,8 @@ interactive session with the `exec` command.
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
Content-Type: application/json
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/vnd.docker.raw-stream
|
||||
|
||||
{{ STREAM }}
|
||||
|
||||
@@ -2627,7 +2617,7 @@ This API is valid only if `tty` was specified as part of creating and starting t
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: text/plain
|
||||
|
||||
Query Parameters:
|
||||
@@ -2653,112 +2643,28 @@ Return low-level information about the `exec` command `id`.
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: plain/text
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"ID" : "11fb006128e8ceb3942e7c58d77750f24210e35f879dd204ac975c184b820b39",
|
||||
"Running" : false,
|
||||
"ExitCode" : 2,
|
||||
"ProcessConfig" : {
|
||||
"privileged" : false,
|
||||
"user" : "",
|
||||
"tty" : false,
|
||||
"entrypoint" : "sh",
|
||||
"arguments" : [
|
||||
"-c",
|
||||
"exit 2"
|
||||
]
|
||||
},
|
||||
"OpenStdin" : false,
|
||||
"OpenStderr" : false,
|
||||
"OpenStdout" : false,
|
||||
"Container" : {
|
||||
"State" : {
|
||||
"Status" : "running",
|
||||
"Running" : true,
|
||||
"Paused" : false,
|
||||
"Restarting" : false,
|
||||
"OOMKilled" : false,
|
||||
"Pid" : 3650,
|
||||
"ExitCode" : 0,
|
||||
"Error" : "",
|
||||
"StartedAt" : "2014-11-17T22:26:03.717657531Z",
|
||||
"FinishedAt" : "0001-01-01T00:00:00Z"
|
||||
"CanRemove": false,
|
||||
"ContainerID": "b53ee82b53a40c7dca428523e34f741f3abc51d9f297a14ff874bf761b995126",
|
||||
"DetachKeys": "",
|
||||
"ExitCode": 2,
|
||||
"ID": "f33bbfb39f5b142420f4759b2348913bd4a8d1a6d7fd56499cb41a1bb91d7b3b",
|
||||
"OpenStderr": true,
|
||||
"OpenStdin": true,
|
||||
"OpenStdout": true,
|
||||
"ProcessConfig": {
|
||||
"arguments": [
|
||||
"-c",
|
||||
"exit 2"
|
||||
],
|
||||
"entrypoint": "sh",
|
||||
"privileged": false,
|
||||
"tty": true,
|
||||
"user": "1000"
|
||||
},
|
||||
"ID" : "8f177a186b977fb451136e0fdf182abff5599a08b3c7f6ef0d36a55aaf89634c",
|
||||
"Created" : "2014-11-17T22:26:03.626304998Z",
|
||||
"Path" : "date",
|
||||
"Args" : [],
|
||||
"Config" : {
|
||||
"Hostname" : "8f177a186b97",
|
||||
"Domainname" : "",
|
||||
"User" : "",
|
||||
"AttachStdin" : false,
|
||||
"AttachStdout" : false,
|
||||
"AttachStderr" : false,
|
||||
"ExposedPorts" : null,
|
||||
"Tty" : false,
|
||||
"OpenStdin" : false,
|
||||
"StdinOnce" : false,
|
||||
"Env" : [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ],
|
||||
"Cmd" : [
|
||||
"date"
|
||||
],
|
||||
"Image" : "ubuntu",
|
||||
"Volumes" : null,
|
||||
"WorkingDir" : "",
|
||||
"Entrypoint" : null,
|
||||
"NetworkDisabled" : false,
|
||||
"MacAddress" : "",
|
||||
"OnBuild" : null,
|
||||
"SecurityOpt" : null
|
||||
},
|
||||
"Image" : "5506de2b643be1e6febbf3b8a240760c6843244c41e12aa2f60ccbb7153d17f5",
|
||||
"NetworkSettings": {
|
||||
"Bridge": "",
|
||||
"SandboxID": "",
|
||||
"HairpinMode": false,
|
||||
"LinkLocalIPv6Address": "",
|
||||
"LinkLocalIPv6PrefixLen": 0,
|
||||
"Ports": null,
|
||||
"SandboxKey": "",
|
||||
"SecondaryIPAddresses": null,
|
||||
"SecondaryIPv6Addresses": null,
|
||||
"EndpointID": "",
|
||||
"Gateway": "",
|
||||
"GlobalIPv6Address": "",
|
||||
"GlobalIPv6PrefixLen": 0,
|
||||
"IPAddress": "",
|
||||
"IPPrefixLen": 0,
|
||||
"IPv6Gateway": "",
|
||||
"MacAddress": "",
|
||||
"Networks": {
|
||||
"bridge": {
|
||||
"NetworkID": "7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812",
|
||||
"EndpointID": "7587b82f0dada3656fda26588aee72630c6fab1536d36e394b2bfbcf898c971d",
|
||||
"Gateway": "172.17.0.1",
|
||||
"IPAddress": "172.17.0.2",
|
||||
"IPPrefixLen": 16,
|
||||
"IPv6Gateway": "",
|
||||
"GlobalIPv6Address": "",
|
||||
"GlobalIPv6PrefixLen": 0,
|
||||
"MacAddress": "02:42:ac:12:00:02"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ResolvConfPath" : "/var/lib/docker/containers/8f177a186b977fb451136e0fdf182abff5599a08b3c7f6ef0d36a55aaf89634c/resolv.conf",
|
||||
"HostnamePath" : "/var/lib/docker/containers/8f177a186b977fb451136e0fdf182abff5599a08b3c7f6ef0d36a55aaf89634c/hostname",
|
||||
"HostsPath" : "/var/lib/docker/containers/8f177a186b977fb451136e0fdf182abff5599a08b3c7f6ef0d36a55aaf89634c/hosts",
|
||||
"LogPath": "/var/lib/docker/containers/1eb5fabf5a03807136561b3c00adcd2992b535d624d5e18b6cdc6a6844d9767b/1eb5fabf5a03807136561b3c00adcd2992b535d624d5e18b6cdc6a6844d9767b-json.log",
|
||||
"Name" : "/test",
|
||||
"Driver" : "aufs",
|
||||
"ExecDriver" : "native-0.2",
|
||||
"MountLabel" : "",
|
||||
"ProcessLabel" : "",
|
||||
"AppArmorProfile" : "",
|
||||
"RestartCount" : 0,
|
||||
"Mounts" : []
|
||||
}
|
||||
"Running": false
|
||||
}
|
||||
|
||||
Status Codes:
|
||||
@@ -2789,7 +2695,8 @@ Status Codes:
|
||||
"Driver": "local",
|
||||
"Mountpoint": "/var/lib/docker/volumes/tardis"
|
||||
}
|
||||
]
|
||||
],
|
||||
"Warnings": []
|
||||
}
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -265,17 +265,6 @@ Create a container
|
||||
"com.example.license": "GPL",
|
||||
"com.example.version": "1.0"
|
||||
},
|
||||
"Mounts": [
|
||||
{
|
||||
"Name": "fac362...80535",
|
||||
"Source": "/data",
|
||||
"Destination": "/data",
|
||||
"Driver": "local",
|
||||
"Mode": "ro,Z",
|
||||
"RW": false,
|
||||
"Propagation": ""
|
||||
}
|
||||
],
|
||||
"Volumes": {
|
||||
"/volumes/data": {}
|
||||
}
|
||||
@@ -386,7 +375,8 @@ Json Parameters:
|
||||
- **Entrypoint** - Set the entry point for the container as a string or an array
|
||||
of strings.
|
||||
- **Image** - A string specifying the image name to use for the container.
|
||||
- **Mounts** - An array of mount points in the container.
|
||||
- **Volumes** - An object mapping mount point paths (strings) inside the
|
||||
container to empty objects.
|
||||
- **WorkingDir** - A string specifying the working directory for commands to
|
||||
run in.
|
||||
- **NetworkDisabled** - Boolean value, when true disables networking for the
|
||||
@@ -2020,7 +2010,7 @@ Tag the image `name` into a repository
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -2590,7 +2580,7 @@ Sets up an exec instance in a running container `id`
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
@@ -2637,8 +2627,8 @@ interactive session with the `exec` command.
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
Content-Type: application/json
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: vnd.docker.raw-stream
|
||||
|
||||
{{ STREAM }}
|
||||
|
||||
@@ -2670,7 +2660,7 @@ This API is valid only if `tty` was specified as part of creating and starting t
|
||||
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 201 OK
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: text/plain
|
||||
|
||||
Query Parameters:
|
||||
@@ -2696,112 +2686,28 @@ Return low-level information about the `exec` command `id`.
|
||||
**Example response**:
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: plain/text
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"ID" : "11fb006128e8ceb3942e7c58d77750f24210e35f879dd204ac975c184b820b39",
|
||||
"Running" : false,
|
||||
"ExitCode" : 2,
|
||||
"ProcessConfig" : {
|
||||
"privileged" : false,
|
||||
"user" : "",
|
||||
"tty" : false,
|
||||
"entrypoint" : "sh",
|
||||
"arguments" : [
|
||||
"-c",
|
||||
"exit 2"
|
||||
]
|
||||
},
|
||||
"OpenStdin" : false,
|
||||
"OpenStderr" : false,
|
||||
"OpenStdout" : false,
|
||||
"Container" : {
|
||||
"State" : {
|
||||
"Status" : "running",
|
||||
"Running" : true,
|
||||
"Paused" : false,
|
||||
"Restarting" : false,
|
||||
"OOMKilled" : false,
|
||||
"Pid" : 3650,
|
||||
"ExitCode" : 0,
|
||||
"Error" : "",
|
||||
"StartedAt" : "2014-11-17T22:26:03.717657531Z",
|
||||
"FinishedAt" : "0001-01-01T00:00:00Z"
|
||||
"CanRemove": false,
|
||||
"ContainerID": "b53ee82b53a40c7dca428523e34f741f3abc51d9f297a14ff874bf761b995126",
|
||||
"DetachKeys": "",
|
||||
"ExitCode": 2,
|
||||
"ID": "f33bbfb39f5b142420f4759b2348913bd4a8d1a6d7fd56499cb41a1bb91d7b3b",
|
||||
"OpenStderr": true,
|
||||
"OpenStdin": true,
|
||||
"OpenStdout": true,
|
||||
"ProcessConfig": {
|
||||
"arguments": [
|
||||
"-c",
|
||||
"exit 2"
|
||||
],
|
||||
"entrypoint": "sh",
|
||||
"privileged": false,
|
||||
"tty": true,
|
||||
"user": "1000"
|
||||
},
|
||||
"ID" : "8f177a186b977fb451136e0fdf182abff5599a08b3c7f6ef0d36a55aaf89634c",
|
||||
"Created" : "2014-11-17T22:26:03.626304998Z",
|
||||
"Path" : "date",
|
||||
"Args" : [],
|
||||
"Config" : {
|
||||
"Hostname" : "8f177a186b97",
|
||||
"Domainname" : "",
|
||||
"User" : "",
|
||||
"AttachStdin" : false,
|
||||
"AttachStdout" : false,
|
||||
"AttachStderr" : false,
|
||||
"ExposedPorts" : null,
|
||||
"Tty" : false,
|
||||
"OpenStdin" : false,
|
||||
"StdinOnce" : false,
|
||||
"Env" : [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ],
|
||||
"Cmd" : [
|
||||
"date"
|
||||
],
|
||||
"Image" : "ubuntu",
|
||||
"Volumes" : null,
|
||||
"WorkingDir" : "",
|
||||
"Entrypoint" : null,
|
||||
"NetworkDisabled" : false,
|
||||
"MacAddress" : "",
|
||||
"OnBuild" : null,
|
||||
"SecurityOpt" : null
|
||||
},
|
||||
"Image" : "5506de2b643be1e6febbf3b8a240760c6843244c41e12aa2f60ccbb7153d17f5",
|
||||
"NetworkSettings": {
|
||||
"Bridge": "",
|
||||
"SandboxID": "",
|
||||
"HairpinMode": false,
|
||||
"LinkLocalIPv6Address": "",
|
||||
"LinkLocalIPv6PrefixLen": 0,
|
||||
"Ports": null,
|
||||
"SandboxKey": "",
|
||||
"SecondaryIPAddresses": null,
|
||||
"SecondaryIPv6Addresses": null,
|
||||
"EndpointID": "",
|
||||
"Gateway": "",
|
||||
"GlobalIPv6Address": "",
|
||||
"GlobalIPv6PrefixLen": 0,
|
||||
"IPAddress": "",
|
||||
"IPPrefixLen": 0,
|
||||
"IPv6Gateway": "",
|
||||
"MacAddress": "",
|
||||
"Networks": {
|
||||
"bridge": {
|
||||
"NetworkID": "7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812",
|
||||
"EndpointID": "7587b82f0dada3656fda26588aee72630c6fab1536d36e394b2bfbcf898c971d",
|
||||
"Gateway": "172.17.0.1",
|
||||
"IPAddress": "172.17.0.2",
|
||||
"IPPrefixLen": 16,
|
||||
"IPv6Gateway": "",
|
||||
"GlobalIPv6Address": "",
|
||||
"GlobalIPv6PrefixLen": 0,
|
||||
"MacAddress": "02:42:ac:12:00:02"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ResolvConfPath" : "/var/lib/docker/containers/8f177a186b977fb451136e0fdf182abff5599a08b3c7f6ef0d36a55aaf89634c/resolv.conf",
|
||||
"HostnamePath" : "/var/lib/docker/containers/8f177a186b977fb451136e0fdf182abff5599a08b3c7f6ef0d36a55aaf89634c/hostname",
|
||||
"HostsPath" : "/var/lib/docker/containers/8f177a186b977fb451136e0fdf182abff5599a08b3c7f6ef0d36a55aaf89634c/hosts",
|
||||
"LogPath": "/var/lib/docker/containers/1eb5fabf5a03807136561b3c00adcd2992b535d624d5e18b6cdc6a6844d9767b/1eb5fabf5a03807136561b3c00adcd2992b535d624d5e18b6cdc6a6844d9767b-json.log",
|
||||
"Name" : "/test",
|
||||
"Driver" : "aufs",
|
||||
"ExecDriver" : "native-0.2",
|
||||
"MountLabel" : "",
|
||||
"ProcessLabel" : "",
|
||||
"AppArmorProfile" : "",
|
||||
"RestartCount" : 0,
|
||||
"Mounts" : []
|
||||
}
|
||||
"Running": false
|
||||
}
|
||||
|
||||
Status Codes:
|
||||
@@ -2832,7 +2738,8 @@ Status Codes:
|
||||
"Driver": "local",
|
||||
"Mountpoint": "/var/lib/docker/volumes/tardis"
|
||||
}
|
||||
]
|
||||
],
|
||||
"Warnings": []
|
||||
}
|
||||
|
||||
Query Parameters:
|
||||
|
||||
@@ -1174,8 +1174,10 @@ To use these, simply pass them on the command line using the `--build-arg
|
||||
`ARG` variables are not persisted into the built image as `ENV` variables are.
|
||||
However, `ARG` variables do impact the build cache in similar ways. If a
|
||||
Dockerfile defines an `ARG` variable whose value is different from a previous
|
||||
build, then a "cache miss" occurs upon its first usage, not its declaration.
|
||||
For example, consider this Dockerfile:
|
||||
build, then a "cache miss" occurs upon first use of the `ARG` variable. The
|
||||
declaration of the `ARG` variable does not count as a use.
|
||||
|
||||
For example, consider these two Dockerfile:
|
||||
|
||||
```
|
||||
1 FROM ubuntu
|
||||
@@ -1183,12 +1185,17 @@ For example, consider this Dockerfile:
|
||||
3 RUN echo $CONT_IMG_VER
|
||||
```
|
||||
|
||||
If you specify `--build-arg CONT_IMG_VER=<value>` on the command line the
|
||||
specification on line 2 does not cause a cache miss; line 3 does cause a cache
|
||||
miss. The definition on line 2 has no impact on the resulting image. The `RUN`
|
||||
on line 3 executes a command and in doing so defines a set of environment
|
||||
variables, including `CONT_IMG_VER`. At that point, the `ARG` variable may
|
||||
impact the resulting image, so a cache miss occurs.
|
||||
```
|
||||
1 FROM ubuntu
|
||||
2 ARG CONT_IMG_VER
|
||||
3 RUN echo hello
|
||||
```
|
||||
|
||||
If you specify `--build-arg CONT_IMG_VER=<value>` on the command line, in both
|
||||
cases, the specification on line 2 does not cause a cache miss; line 3 does
|
||||
cause a cache miss.`ARG CONT_IMG_VER` causes the RUN line to be identified
|
||||
as the same as running `CONT_IMG_VER=<value>` echo hello, so if the `<value>`
|
||||
changes, we get a cache miss.
|
||||
|
||||
Consider another example under the same command line:
|
||||
|
||||
@@ -1203,6 +1210,20 @@ the variable's value in the `ENV` references the `ARG` variable and that
|
||||
variable is changed through the command line. In this example, the `ENV`
|
||||
command causes the image to include the value.
|
||||
|
||||
If an `ENV` instruction overrides an `ARG` instruction of the same name, like
|
||||
this Dockerfile:
|
||||
|
||||
```
|
||||
1 FROM ubuntu
|
||||
2 ARG CONT_IMG_VER
|
||||
3 ENV CONT_IMG_VER hello
|
||||
4 RUN echo $CONT_IMG_VER
|
||||
```
|
||||
|
||||
Line 3 does not cause a cache miss because the value of `CONT_IMG_VER` is a
|
||||
constant (`hello`). As a result, the environment variables and values used on
|
||||
the `RUN` (line 4) doesn't change between builds.
|
||||
|
||||
## ONBUILD
|
||||
|
||||
ONBUILD [INSTRUCTION]
|
||||
|
||||
@@ -26,6 +26,7 @@ parent = "smn_cli"
|
||||
--force-rm Always remove intermediate containers
|
||||
--help Print usage
|
||||
--isolation="" Container isolation technology
|
||||
--label=[] Set metadata for an image
|
||||
-m, --memory="" Memory limit for all build containers
|
||||
--memory-swap="" A positive integer equal to memory plus swap. Specify -1 to enable unlimited swap.
|
||||
--no-cache Do not use cache when building the image
|
||||
|
||||
@@ -21,13 +21,14 @@ weight = -1
|
||||
-b, --bridge="" Attach containers to a network bridge
|
||||
--bip="" Specify network bridge IP
|
||||
--cgroup-parent= Set parent cgroup for all containers
|
||||
-D, --debug Enable debug mode
|
||||
--default-gateway="" Container default gateway IPv4 address
|
||||
--default-gateway-v6="" Container default gateway IPv6 address
|
||||
--cluster-store="" URL of the distributed storage backend
|
||||
--cluster-advertise="" Address of the daemon instance on the cluster
|
||||
--cluster-store-opt=map[] Set cluster options
|
||||
--config-file=/etc/docker/daemon.json Daemon configuration file
|
||||
--containerd Path to containerd socket
|
||||
-D, --debug Enable debug mode
|
||||
--default-gateway="" Container default gateway IPv4 address
|
||||
--default-gateway-v6="" Container default gateway IPv6 address
|
||||
--dns=[] DNS server to use
|
||||
--dns-opt=[] DNS options to use
|
||||
--dns-search=[] DNS search domains to use
|
||||
@@ -462,7 +463,7 @@ options for `zfs` start with `zfs`.
|
||||
|
||||
Example use:
|
||||
|
||||
$ docker daemon --storage-opt dm.min_free_space_percent=10%
|
||||
$ docker daemon --storage-opt dm.min_free_space=10%
|
||||
|
||||
Currently supported options of `zfs`:
|
||||
|
||||
@@ -490,12 +491,13 @@ with the `--exec-opt` flag. All the flag's options have the `native` prefix. A
|
||||
single `native.cgroupdriver` option is available.
|
||||
|
||||
The `native.cgroupdriver` option specifies the management of the container's
|
||||
cgroups. You can specify only specify `cgroupfs` at the moment. If you omit the
|
||||
cgroups. You can specify only specify `cgroupfs` or `systemd`. If you specify
|
||||
`systemd` and it is not available, the system errors out. If you omit the
|
||||
`native.cgroupdriver` option,` cgroupfs` is used.
|
||||
|
||||
This example explicitely sets the `cgroupdriver` to `cgroupfs`:
|
||||
This example sets the `cgroupdriver` to `systemd`:
|
||||
|
||||
$ sudo docker daemon --exec-opt native.cgroupdriver=cgroupfs
|
||||
$ sudo docker daemon --exec-opt native.cgroupdriver=systemd
|
||||
|
||||
Setting this option applies to all containers the daemon launches.
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ parent = "smn_cli"
|
||||
|
||||
--help Print usage
|
||||
-i, --input="" Read from a tar archive file, instead of STDIN. The tarball may be compressed with gzip, bzip, or xz
|
||||
-q, --quiet Suppress the load output. Without this option, a progress bar is displayed.
|
||||
|
||||
Loads a tarred repository from a file or the standard input stream.
|
||||
Restores both images and tags.
|
||||
|
||||
@@ -23,6 +23,7 @@ parent = "smn_cli"
|
||||
--ipam-driver=default IP Address Management Driver
|
||||
--ipam-opt=map[] Set custom IPAM driver specific options
|
||||
--ipv6 Enable IPv6 networking
|
||||
--label=[] Set metadata on a network
|
||||
-o --opt=map[] Set custom driver specific options
|
||||
--subnet=[] Subnet in CIDR format that represents a network segment
|
||||
|
||||
|
||||
@@ -165,6 +165,8 @@ listening on port 5000 (`myregistry.local:5000`):
|
||||
$ docker pull myregistry.local:5000/testing/test-image
|
||||
```
|
||||
|
||||
Registry credentials are managed by [docker login](login.md).
|
||||
|
||||
Docker uses the `https://` protocol to communicate with a registry, unless the
|
||||
registry is allowed to be accessed over an insecure connection. Refer to the
|
||||
[insecure registries](daemon.md#insecure-registries) section for more information.
|
||||
|
||||
@@ -22,3 +22,5 @@ registry or to a self-hosted one.
|
||||
|
||||
Killing the `docker push` process, for example by pressing `CTRL-c` while it is
|
||||
running in a terminal, will terminate the push operation.
|
||||
|
||||
Registry credentials are managed by [docker login](login.md).
|
||||
|
||||
@@ -16,6 +16,7 @@ parent = "smn_cli"
|
||||
|
||||
-d, --driver=local Specify volume driver name
|
||||
--help Print usage
|
||||
--label=[] Set metadata for a volume
|
||||
--name= Specify volume name
|
||||
-o, --opt=map[] Set driver specific options
|
||||
|
||||
|
||||
@@ -1056,7 +1056,7 @@ Both flags take limits in the `<device-path>:<limit>` format. Both read and
|
||||
write rates must be a positive integer.
|
||||
|
||||
## Additional groups
|
||||
--group-add: Add Linux capabilities
|
||||
--group-add: Add additional groups to run as
|
||||
|
||||
By default, the docker container process runs with the supplementary groups looked
|
||||
up for the specified user. If one wants to add more to that list of groups, then
|
||||
@@ -1414,9 +1414,6 @@ The example below mounts an empty tmpfs into the container with the `rw`,
|
||||
|
||||
--volumes-from="": Mount all volumes from the given container(s)
|
||||
|
||||
> **Note**:
|
||||
> The auto-creation of the host path has been [*deprecated*](../deprecated.md#auto-creating-missing-host-paths-for-bind-mounts).
|
||||
|
||||
> **Note**:
|
||||
> When using systemd to manage the Docker daemon's start and stop, in the systemd
|
||||
> unit file there is an option to control mount propagation for the Docker daemon
|
||||
|
||||
@@ -144,7 +144,7 @@ Mounting a host directory can be useful for testing. For example, you can mount
|
||||
source code inside a container. Then, change the source code and see its effect
|
||||
on the application in real time. The directory on the host must be specified as
|
||||
an absolute path and if the directory doesn't exist the Engine daemon automatically
|
||||
creates it for you. This auto-creation of the host path has been [*deprecated*](#auto-creating-missing-host-paths-for-bind-mounts).
|
||||
creates it for you.
|
||||
|
||||
Docker volumes default to mount in read-write mode, but you can also set it to
|
||||
be mounted read-only.
|
||||
|
||||
@@ -87,7 +87,7 @@ specify a single subnet. An `overlay` network supports multiple subnets.
|
||||
> in your infrastructure that is not managed by docker. Such overlaps can cause
|
||||
> connectivity issues or failures when containers are connected to that network.
|
||||
|
||||
In addition to the `--subnetwork` option, you also specify the `--gateway` `--ip-range` and `--aux-address` options.
|
||||
In addition to the `--subnet` option, you also specify the `--gateway` `--ip-range` and `--aux-address` options.
|
||||
|
||||
```bash
|
||||
$ docker network create -d overlay
|
||||
|
||||
@@ -20,7 +20,7 @@ set -e
|
||||
# To update this script on https://get.docker.com,
|
||||
# use hack/release.sh during a normal release,
|
||||
# or the following one-liner for script hotfixes:
|
||||
# s3cmd put --acl-public -P hack/install.sh s3://get.docker.com/index
|
||||
# aws s3 cp --acl public-read hack/install.sh s3://get.docker.com/index
|
||||
#
|
||||
|
||||
url="https://get.docker.com/"
|
||||
|
||||
@@ -81,6 +81,14 @@ if command -v git &> /dev/null && git rev-parse &> /dev/null; then
|
||||
GITCOMMIT=$(git rev-parse --short HEAD)
|
||||
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
|
||||
GITCOMMIT="$GITCOMMIT-unsupported"
|
||||
echo "#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "# GITCOMMIT = $GITCOMMIT"
|
||||
echo "# The version you are building is listed as unsupported because"
|
||||
echo "# there are some files in the git repository that are in an uncommited state."
|
||||
echo "# Commit these changes, or add to .gitignore to remove the -unsupported from the version."
|
||||
echo "# Here is the current list:"
|
||||
git status --porcelain --untracked-files=no
|
||||
echo "#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
fi
|
||||
! BUILDTIME=$(date --rfc-3339 ns | sed -e 's/ /T/') &> /dev/null
|
||||
if [ -z $BUILDTIME ]; then
|
||||
|
||||
@@ -15,8 +15,7 @@ Recommends: aufs-tools,
|
||||
cgroupfs-mount | cgroup-lite,
|
||||
git,
|
||||
xz-utils,
|
||||
${apparmor:Recommends},
|
||||
${yubico:Recommends}
|
||||
${apparmor:Recommends}
|
||||
Conflicts: docker (<< 1.5~), docker.io, lxc-docker, lxc-docker-virtual-package, docker-engine-cs
|
||||
Description: Docker: the open-source application container engine
|
||||
Docker is an open source project to build, ship and run any application as a
|
||||
|
||||
@@ -5,8 +5,6 @@ VERSION = $(shell cat VERSION)
|
||||
override_dh_gencontrol:
|
||||
# if we're on Ubuntu, we need to Recommends: apparmor
|
||||
echo 'apparmor:Recommends=$(shell dpkg-vendor --is Ubuntu && echo apparmor)' >> debian/docker-engine.substvars
|
||||
# recommend yubico-piv-tool since we include pkcs11 by default
|
||||
echo 'yubico:Recommends=yubico-piv-tool (>= 1.1.0~)' >> debian/docker-engine.substvars
|
||||
dh_gencontrol
|
||||
|
||||
override_dh_auto_build:
|
||||
@@ -22,6 +20,10 @@ override_dh_strip:
|
||||
override_dh_auto_install:
|
||||
mkdir -p debian/docker-engine/usr/bin
|
||||
cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary/docker)" debian/docker-engine/usr/bin/docker
|
||||
cp -aT /usr/local/bin/containerd debian/docker-engine/usr/bin/docker-containerd
|
||||
cp -aT /usr/local/bin/containerd-shim debian/docker-engine/usr/bin/docker-containerd-shim
|
||||
cp -aT /usr/local/bin/ctr debian/docker-engine/usr/bin/docker-containerd-ctr
|
||||
cp -aT /usr/local/bin/runc debian/docker-engine/usr/bin/docker-runc
|
||||
mkdir -p debian/docker-engine/usr/lib/docker
|
||||
|
||||
override_dh_installinit:
|
||||
@@ -36,5 +38,8 @@ override_dh_install:
|
||||
dh_install
|
||||
dh_apparmor --profile-name=docker-engine -pdocker-engine
|
||||
|
||||
override_dh_shlibdeps:
|
||||
dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
|
||||
|
||||
%:
|
||||
dh $@ --with=bash-completion $(shell command -v dh_systemd_enable > /dev/null 2>&1 && echo --with=systemd)
|
||||
|
||||
@@ -60,11 +60,6 @@ Requires: device-mapper >= 1.02.90-2
|
||||
%global with_selinux 1
|
||||
%endif
|
||||
|
||||
# yubico-piv-tool recommends
|
||||
%if 0%{?fedora} >= 20 || 0%{?centos} >= 7 || 0%{?rhel} >= 7
|
||||
Requires: yubico-piv-tool >= 1.1.0
|
||||
%endif
|
||||
|
||||
# start if with_selinux
|
||||
%if 0%{?with_selinux}
|
||||
# Version of SELinux we were using
|
||||
@@ -124,6 +119,14 @@ export DOCKER_GITCOMMIT=%{_gitcommit}
|
||||
install -d $RPM_BUILD_ROOT/%{_bindir}
|
||||
install -p -m 755 bundles/%{_origversion}/dynbinary/docker-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/docker
|
||||
|
||||
# install containerd
|
||||
install -p -m 755 /usr/local/bin/containerd $RPM_BUILD_ROOT/%{_bindir}/docker-containerd
|
||||
install -p -m 755 /usr/local/bin/containerd-shim $RPM_BUILD_ROOT/%{_bindir}/docker-containerd-shim
|
||||
install -p -m 755 /usr/local/bin/ctr $RPM_BUILD_ROOT/%{_bindir}/docker-containerd-ctr
|
||||
|
||||
# install runc
|
||||
install -p -m 755 /usr/local/bin/runc $RPM_BUILD_ROOT/%{_bindir}/docker-runc
|
||||
|
||||
# install udev rules
|
||||
install -d $RPM_BUILD_ROOT/%{_sysconfdir}/udev/rules.d
|
||||
install -p -m 644 contrib/udev/80-docker.rules $RPM_BUILD_ROOT/%{_sysconfdir}/udev/rules.d/80-docker.rules
|
||||
@@ -171,6 +174,10 @@ install -p -m 644 contrib/syntax/nano/Dockerfile.nanorc $RPM_BUILD_ROOT/usr/shar
|
||||
%files
|
||||
%doc AUTHORS CHANGELOG.md CONTRIBUTING.md LICENSE MAINTAINERS NOTICE README.md
|
||||
/%{_bindir}/docker
|
||||
/%{_bindir}/docker-containerd
|
||||
/%{_bindir}/docker-containerd-shim
|
||||
/%{_bindir}/docker-containerd-ctr
|
||||
/%{_bindir}/docker-runc
|
||||
/%{_sysconfdir}/udev/rules.d/80-docker.rules
|
||||
%if 0%{?is_systemd}
|
||||
/%{_unitdir}/docker.service
|
||||
|
||||
@@ -9,6 +9,13 @@ if ! command -v docker &> /dev/null; then
|
||||
false
|
||||
fi
|
||||
|
||||
if [ -z "$DOCKER_TEST_HOST" ]; then
|
||||
if docker version &> /dev/null; then
|
||||
echo >&2 'skipping daemon start, since daemon appears to be already started'
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# intentionally open a couple bogus file descriptors to help test that they get scrubbed in containers
|
||||
exec 41>&1 42>&2
|
||||
|
||||
|
||||
@@ -58,14 +58,33 @@ set -e
|
||||
FROM $image
|
||||
WORKDIR /usr/src/docker
|
||||
COPY . /usr/src/docker
|
||||
RUN mkdir -p /go/src/github.com/docker \
|
||||
RUN mkdir -p /go/src/github.com/docker && mkdir -p /go/src/github.com/opencontainers \
|
||||
&& ln -snf /usr/src/docker /go/src/github.com/docker/docker
|
||||
EOF
|
||||
|
||||
# get the RUNC and CONTAINERD commit from the root Dockerfile, this keeps the commits in sync
|
||||
awk '$1 == "ENV" && $2 == "RUNC_COMMIT" { print; exit }' Dockerfile >> "$DEST/$version/Dockerfile.build"
|
||||
awk '$1 == "ENV" && $2 == "CONTAINERD_COMMIT" { print; exit }' Dockerfile >> "$DEST/$version/Dockerfile.build"
|
||||
|
||||
# add runc and containerd compile and install
|
||||
cat >> "$DEST/$version/Dockerfile.build" <<-EOF
|
||||
# Install runc
|
||||
RUN git clone git://github.com/opencontainers/runc.git "/go/src/github.com/opencontainers/runc" \
|
||||
&& cd "/go/src/github.com/opencontainers/runc" \
|
||||
&& git checkout -q "\$RUNC_COMMIT"
|
||||
RUN set -x && export GOPATH="/go" && cd "/go/src/github.com/opencontainers/runc" \
|
||||
&& make BUILDTAGS="\$RUNC_BUILDTAGS" && make install
|
||||
# Install containerd
|
||||
RUN git clone git://github.com/docker/containerd.git "/go/src/github.com/docker/containerd" \
|
||||
&& cd "/go/src/github.com/docker/containerd" \
|
||||
&& git checkout -q "\$CONTAINERD_COMMIT"
|
||||
RUN set -x && export GOPATH="/go" && cd "/go/src/github.com/docker/containerd" && make && make install
|
||||
EOF
|
||||
if [ "$DOCKER_EXPERIMENTAL" ]; then
|
||||
echo 'ENV DOCKER_EXPERIMENTAL 1' >> "$DEST/$version/Dockerfile.build"
|
||||
fi
|
||||
cat >> "$DEST/$version/Dockerfile.build" <<-EOF
|
||||
RUN mv -v hack/make/.build-deb debian
|
||||
RUN cp -aL hack/make/.build-deb debian
|
||||
RUN { echo '$debSource (${debVersion}-0~${suite}) $suite; urgency=low'; echo; echo ' * Version: $VERSION'; echo; echo " -- $debMaintainer $debDate"; } > debian/changelog && cat >&2 debian/changelog
|
||||
RUN dpkg-buildpackage -uc -us
|
||||
EOF
|
||||
|
||||
@@ -87,6 +87,26 @@ set -e
|
||||
cat > "$DEST/$version/Dockerfile.build" <<-EOF
|
||||
FROM $image
|
||||
COPY . /usr/src/${rpmName}
|
||||
RUN mkdir -p /go/src/github.com/docker && mkdir -p /go/src/github.com/opencontainers
|
||||
EOF
|
||||
|
||||
# get the RUNC and CONTAINERD commit from the root Dockerfile, this keeps the commits in sync
|
||||
awk '$1 == "ENV" && $2 == "RUNC_COMMIT" { print; exit }' Dockerfile >> "$DEST/$version/Dockerfile.build"
|
||||
awk '$1 == "ENV" && $2 == "CONTAINERD_COMMIT" { print; exit }' Dockerfile >> "$DEST/$version/Dockerfile.build"
|
||||
|
||||
# add runc and containerd compile and install
|
||||
cat >> "$DEST/$version/Dockerfile.build" <<-EOF
|
||||
# Install runc
|
||||
RUN git clone git://github.com/opencontainers/runc.git "/go/src/github.com/opencontainers/runc" \
|
||||
&& cd "/go/src/github.com/opencontainers/runc" \
|
||||
&& git checkout -q "\$RUNC_COMMIT"
|
||||
RUN set -x && export GOPATH="/go" && cd "/go/src/github.com/opencontainers/runc" \
|
||||
&& make BUILDTAGS="\$RUNC_BUILDTAGS" && make install
|
||||
# Install containerd
|
||||
RUN git clone git://github.com/docker/containerd.git "/go/src/github.com/docker/containerd" \
|
||||
&& cd "/go/src/github.com/docker/containerd" \
|
||||
&& git checkout -q "\$CONTAINERD_COMMIT"
|
||||
RUN set -x && export GOPATH="/go" && cd "/go/src/github.com/docker/containerd" && make && make install
|
||||
EOF
|
||||
if [ "$DOCKER_EXPERIMENTAL" ]; then
|
||||
echo 'ENV DOCKER_EXPERIMENTAL 1' >> "$DEST/$version/Dockerfile.build"
|
||||
@@ -97,7 +117,10 @@ set -e
|
||||
WORKDIR /root/rpmbuild
|
||||
RUN ln -sfv /usr/src/${rpmName}/hack/make/.build-rpm SPECS
|
||||
WORKDIR /root/rpmbuild/SPECS
|
||||
RUN tar -cz -C /usr/src -f /root/rpmbuild/SOURCES/${rpmName}.tar.gz ${rpmName}
|
||||
RUN tar -r -C /usr/src -f /root/rpmbuild/SOURCES/${rpmName}.tar ${rpmName}
|
||||
RUN tar -r -C /go/src/github.com/docker -f /root/rpmbuild/SOURCES/${rpmName}.tar containerd
|
||||
RUN tar -r -C /go/src/github.com/opencontainers -f /root/rpmbuild/SOURCES/${rpmName}.tar runc
|
||||
RUN gzip /root/rpmbuild/SOURCES/${rpmName}.tar
|
||||
RUN { cat /usr/src/${rpmName}/contrib/builder/rpm/${PACKAGE_ARCH}/changelog; } >> ${rpmName}.spec && tail >&2 ${rpmName}.spec
|
||||
RUN rpmbuild -ba \
|
||||
--define '_gitcommit $DOCKER_GITCOMMIT' \
|
||||
|
||||
@@ -14,6 +14,7 @@ set -e
|
||||
#
|
||||
# ... and so on and so forth for the builds created by hack/make/build-deb
|
||||
|
||||
source "$(dirname "$BASH_SOURCE")/.integration-daemon-start"
|
||||
source "$(dirname "$BASH_SOURCE")/.detect-daemon-osarch"
|
||||
|
||||
: ${DOCKER_RELEASE_DIR:=$DEST}
|
||||
|
||||
@@ -14,6 +14,7 @@ set -e
|
||||
#
|
||||
# ... and so on and so forth for the builds created by hack/make/build-rpm
|
||||
|
||||
source "$(dirname "$BASH_SOURCE")/.integration-daemon-start"
|
||||
source "$(dirname "$BASH_SOURCE")/.detect-daemon-osarch"
|
||||
|
||||
: ${DOCKER_RELEASE_DIR:=$DEST}
|
||||
|
||||
@@ -15,21 +15,54 @@ for d in "$CROSS/"*/*; do
|
||||
export GOOS="$(basename "$(dirname "$d")")"
|
||||
BINARY_NAME="docker-$VERSION"
|
||||
BINARY_EXTENSION="$(export GOOS && binary_extension)"
|
||||
if [ "$GOOS" = 'windows' ]; then
|
||||
# if windows use a zip, not tgz
|
||||
BUNDLE_EXTENSION=".zip"
|
||||
IS_TAR="false"
|
||||
else
|
||||
BUNDLE_EXTENSION=".tgz"
|
||||
IS_TAR="true"
|
||||
fi
|
||||
BINARY_FULLNAME="$BINARY_NAME$BINARY_EXTENSION"
|
||||
mkdir -p "$DEST/$GOOS/$GOARCH"
|
||||
TGZ="$DEST/$GOOS/$GOARCH/$BINARY_NAME.tgz"
|
||||
TGZ="$DEST/$GOOS/$GOARCH/$BINARY_NAME$BUNDLE_EXTENSION"
|
||||
|
||||
mkdir -p "$DEST/build"
|
||||
# The staging directory for the files in the tgz
|
||||
BUILD_PATH="$DEST/build"
|
||||
|
||||
mkdir -p "$DEST/build/usr/local/bin"
|
||||
cp -L "$d/$BINARY_FULLNAME" "$DEST/build/usr/local/bin/docker$BINARY_EXTENSION"
|
||||
copy_containerd "$DEST/build/usr/local/bin/"
|
||||
# The directory that is at the root of the tar file
|
||||
TAR_BASE_DIRECTORY="docker"
|
||||
|
||||
tar --numeric-owner --owner 0 -C "$DEST/build" -czf "$TGZ" usr
|
||||
# $DEST/build/docker
|
||||
TAR_PATH="$BUILD_PATH/$TAR_BASE_DIRECTORY"
|
||||
|
||||
# Copy the correct docker binary
|
||||
mkdir -p $TAR_PATH
|
||||
cp -L "$d/$BINARY_FULLNAME" "$TAR_PATH/docker$BINARY_EXTENSION"
|
||||
|
||||
# copy over all the containerd binaries
|
||||
copy_containerd $TAR_PATH
|
||||
|
||||
if [ "$IS_TAR" == "true" ]; then
|
||||
echo "Creating tgz from $BUILD_PATH and naming it $TGZ"
|
||||
tar --numeric-owner --owner 0 -C "$BUILD_PATH" -czf "$TGZ" $TAR_BASE_DIRECTORY
|
||||
else
|
||||
# ZIP needs to full absolute dir path, not the absolute path
|
||||
ZIP=`pwd`"/$TGZ"
|
||||
# keep track of where we are, for later.
|
||||
pushd .
|
||||
# go into the BUILD_PATH since zip does not have a -C equivalent.
|
||||
cd $BUILD_PATH
|
||||
echo "Creating zip from $BUILD_PATH and naming it $ZIP"
|
||||
zip -q -r $ZIP $TAR_BASE_DIRECTORY
|
||||
# go back to where we started
|
||||
popd
|
||||
fi
|
||||
|
||||
hash_files "$TGZ"
|
||||
|
||||
rm -rf "$DEST/build"
|
||||
# cleanup after ourselves
|
||||
rm -rf "$BUILD_PATH"
|
||||
|
||||
echo "Created tgz: $TGZ"
|
||||
done
|
||||
|
||||
@@ -43,7 +43,7 @@ cd /go/src/github.com/docker/docker
|
||||
[ -x hack/make.sh ] || usage
|
||||
|
||||
export AWS_DEFAULT_REGION
|
||||
: ${AWS_DEFAULT_REGION:=us-west-2}
|
||||
: ${AWS_DEFAULT_REGION:=us-west-1}
|
||||
|
||||
RELEASE_BUNDLES=(
|
||||
binary
|
||||
@@ -79,8 +79,6 @@ fi
|
||||
|
||||
setup_s3() {
|
||||
echo "Setting up S3"
|
||||
# TODO: Move to Dockerfile
|
||||
pip install awscli==1.10.15
|
||||
# Try creating the bucket. Ignore errors (it might already exist).
|
||||
aws s3 mb "s3://$BUCKET" 2>/dev/null || true
|
||||
# Check access to the bucket.
|
||||
@@ -104,8 +102,7 @@ s3_url() {
|
||||
echo "https://$BUCKET_PATH"
|
||||
;;
|
||||
*)
|
||||
# TODO: remove s3cmd dependency
|
||||
BASE_URL=$( s3cmd ws-info s3://$BUCKET | awk -v 'FS=: +' '/http:\/\/'$BUCKET'/ { gsub(/\/+$/, "", $2); print $2 }' )
|
||||
BASE_URL="http://${BUCKET}.s3-website-${AWS_DEFAULT_REGION}.amazonaws.com"
|
||||
if [[ -n "$AWS_S3_BUCKET_PATH" ]] ; then
|
||||
echo "$BASE_URL/$AWS_S3_BUCKET_PATH"
|
||||
else
|
||||
@@ -184,7 +181,9 @@ release_build() {
|
||||
binDir=bundles/$VERSION/cross/$GOOS/$GOARCH
|
||||
tgzDir=bundles/$VERSION/tgz/$GOOS/$GOARCH
|
||||
binary=docker-$VERSION
|
||||
tgz=docker-$VERSION.tgz
|
||||
zipExt=".tgz"
|
||||
binaryExt=""
|
||||
tgz=$binary$zipExt
|
||||
|
||||
latestBase=
|
||||
if [ -z "$NOLATEST" ]; then
|
||||
@@ -207,11 +206,12 @@ release_build() {
|
||||
s3Os=Linux
|
||||
;;
|
||||
windows)
|
||||
# this is windows use the .zip and .exe extentions for the files.
|
||||
s3Os=Windows
|
||||
binary+='.exe'
|
||||
if [ "$latestBase" ]; then
|
||||
latestBase+='.exe'
|
||||
fi
|
||||
zipExt=".zip"
|
||||
binaryExt=".exe"
|
||||
tgz=$binary$zipExt
|
||||
binary+=$binaryExt
|
||||
;;
|
||||
*)
|
||||
echo >&2 "error: can't convert $s3Os to an appropriate value for 'uname -s'"
|
||||
@@ -238,11 +238,13 @@ release_build() {
|
||||
esac
|
||||
|
||||
s3Dir="s3://$BUCKET_PATH/builds/$s3Os/$s3Arch"
|
||||
latest=
|
||||
# latest=
|
||||
latestTgz=
|
||||
if [ "$latestBase" ]; then
|
||||
latest="$s3Dir/$latestBase"
|
||||
latestTgz="$s3Dir/$latestBase.tgz"
|
||||
# commented out since we aren't uploading binaries right now.
|
||||
# latest="$s3Dir/$latestBase$binaryExt"
|
||||
# we don't include the $binaryExt because we don't want docker.exe.zip
|
||||
latestTgz="$s3Dir/$latestBase$zipExt"
|
||||
fi
|
||||
|
||||
if [ ! -f "$tgzDir/$tgz" ]; then
|
||||
@@ -311,6 +313,6 @@ echo "We have just pushed $VERSION to $(s3_url). You can download it with the fo
|
||||
echo
|
||||
echo "Darwin/OSX 64bit client tgz: $(s3_url)/builds/Darwin/x86_64/docker-$VERSION.tgz"
|
||||
echo "Linux 64bit tgz: $(s3_url)/builds/Linux/x86_64/docker-$VERSION.tgz"
|
||||
echo "Windows 64bit client tgz: $(s3_url)/builds/Windows/x86_64/docker-$VERSION.tgz"
|
||||
echo "Windows 32bit client tgz: $(s3_url)/builds/Windows/i386/docker-$VERSION.tgz"
|
||||
echo "Windows 64bit client tgz: $(s3_url)/builds/Windows/x86_64/docker-$VERSION.zip"
|
||||
echo "Windows 32bit client tgz: $(s3_url)/builds/Windows/i386/docker-$VERSION.zip"
|
||||
echo
|
||||
|
||||
@@ -24,12 +24,12 @@ clone git golang.org/x/net 47990a1ba55743e6ef1affd3a14e5bac8553615d https://gith
|
||||
clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://github.com/golang/sys.git
|
||||
clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3
|
||||
clone git github.com/docker/go-connections v0.2.0
|
||||
clone git github.com/docker/engine-api v0.3.0
|
||||
clone git github.com/docker/engine-api v0.3.3
|
||||
clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837
|
||||
clone git github.com/imdario/mergo 0.2.1
|
||||
|
||||
#get libnetwork packages
|
||||
clone git github.com/docker/libnetwork v0.7.0-dev.10
|
||||
clone git github.com/docker/libnetwork v0.7.0-rc.4
|
||||
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
||||
clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
|
||||
clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4
|
||||
@@ -44,7 +44,7 @@ clone git github.com/coreos/etcd v2.2.0
|
||||
fix_rewritten_imports github.com/coreos/etcd
|
||||
clone git github.com/ugorji/go 5abd4e96a45c386928ed2ca2a7ef63e2533e18ec
|
||||
clone git github.com/hashicorp/consul v0.5.2
|
||||
clone git github.com/boltdb/bolt v1.1.0
|
||||
clone git github.com/boltdb/bolt v1.2.0
|
||||
clone git github.com/miekg/dns 75e6e86cc601825c5dbcd4e0c209eab180997cd7
|
||||
|
||||
# get graph and distribution packages
|
||||
@@ -60,7 +60,7 @@ clone git github.com/docker/go v1.5.1-1-1-gbaf439e
|
||||
clone git github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c
|
||||
|
||||
clone git github.com/opencontainers/runc 7b6c4c418d5090f4f11eee949fdf49afd15838c9 # libcontainer
|
||||
clone git github.com/opencontainers/specs 3ce138b1934bf227a418e241ead496c383eaba1c # specs
|
||||
clone git github.com/opencontainers/specs 93ca97e83ca7fb4fba6d9e30d5470f99ddc02d11 # specs
|
||||
clone git github.com/seccomp/libseccomp-golang 1b506fc7c24eec5a3693cdcbed40d9c226cfc6a1
|
||||
# libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json)
|
||||
clone git github.com/coreos/go-systemd v4
|
||||
@@ -89,5 +89,5 @@ clone git google.golang.org/api dc6d2353af16e2a2b0ff6986af051d473a4ed468 https:/
|
||||
clone git google.golang.org/cloud dae7e3d993bc3812a2185af60552bb6b847e52a0 https://code.googlesource.com/gocloud
|
||||
|
||||
# containerd
|
||||
clone git github.com/docker/containerd 142e22a4dce86f3b8ce068a0b043489d21976bb8
|
||||
clone git github.com/docker/containerd 07c95162cdcead88dfe4ca0ffb3cea02375ec54d
|
||||
clean
|
||||
|
||||
95
integration-cli/benchmark_test.go
Normal file
95
integration-cli/benchmark_test.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) BenchmarkConcurrentContainerActions(c *check.C) {
|
||||
maxConcurrency := runtime.GOMAXPROCS(0)
|
||||
numIterations := c.N
|
||||
outerGroup := &sync.WaitGroup{}
|
||||
outerGroup.Add(maxConcurrency)
|
||||
chErr := make(chan error, numIterations*2*maxConcurrency)
|
||||
|
||||
for i := 0; i < maxConcurrency; i++ {
|
||||
go func() {
|
||||
defer outerGroup.Done()
|
||||
innerGroup := &sync.WaitGroup{}
|
||||
innerGroup.Add(2)
|
||||
|
||||
go func() {
|
||||
defer innerGroup.Done()
|
||||
for i := 0; i < numIterations; i++ {
|
||||
args := []string{"run", "-d", defaultSleepImage}
|
||||
args = append(args, defaultSleepCommand...)
|
||||
out, _, err := dockerCmdWithError(args...)
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
return
|
||||
}
|
||||
|
||||
id := strings.TrimSpace(out)
|
||||
tmpDir, err := ioutil.TempDir("", "docker-concurrent-test-"+id)
|
||||
if err != nil {
|
||||
chErr <- err
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
out, _, err = dockerCmdWithError("cp", id+":/tmp", tmpDir)
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
return
|
||||
}
|
||||
|
||||
out, _, err = dockerCmdWithError("kill", id)
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
}
|
||||
|
||||
out, _, err = dockerCmdWithError("start", id)
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
}
|
||||
|
||||
out, _, err = dockerCmdWithError("kill", id)
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
}
|
||||
|
||||
// don't do an rm -f here since it can potentially ignore errors from the graphdriver
|
||||
out, _, err = dockerCmdWithError("rm", id)
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer innerGroup.Done()
|
||||
for i := 0; i < numIterations; i++ {
|
||||
out, _, err := dockerCmdWithError("ps")
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
innerGroup.Wait()
|
||||
}()
|
||||
}
|
||||
|
||||
outerGroup.Wait()
|
||||
close(chErr)
|
||||
|
||||
for err := range chErr {
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user