Compare commits
113 Commits
v18.03.1-c
...
v17.12.1-c
| Author | SHA1 | Date | |
|---|---|---|---|
| feff709de8 | |||
| 36e98850f2 | |||
| 675493e24d | |||
| 602216ce56 | |||
| 7ec8b355f2 | |||
| f5152d8714 | |||
| 3869e4896d | |||
| e9f1a359d7 | |||
| 8d3d4fa90a | |||
| 831e67711b | |||
| 0a43e1edf9 | |||
| d70d9c910a | |||
| 3cfc217709 | |||
| fa49979990 | |||
| 62a24759f6 | |||
| 2d24bc5e5f | |||
| d852c51a7d | |||
| c85f7d7628 | |||
| 0d1f2df861 | |||
| bd3930dfb1 | |||
| f312cb1bb1 | |||
| 69b85c633e | |||
| 84d4132c8d | |||
| dbf4d3a8ca | |||
| 092f60f9eb | |||
| 1c517bd52c | |||
| 7a399f3d9a | |||
| ea3ea188f6 | |||
| f0cfc346fd | |||
| f5829ca5cf | |||
| 1d1bcb2fca | |||
| 8c22dc2e68 | |||
| 09d84539fa | |||
| 67d4bb5888 | |||
| 5507d73275 | |||
| 1e67593a37 | |||
| 25c4322a30 | |||
| 5f1c192c19 | |||
| 276c2ad6a4 | |||
| ae80c6aedf | |||
| 6da2ecc95c | |||
| a7ee159424 | |||
| 092e59ef76 | |||
| bf9d7adabe | |||
| 88f57f81f9 | |||
| c97c6d62c2 | |||
| 2861174d81 | |||
| 8673a4245b | |||
| 5dee703312 | |||
| 6a2c058cd8 | |||
| 6819d0ec05 | |||
| 740d71bf6a | |||
| b6799f808c | |||
| f8b1976d4c | |||
| aad5f42ada | |||
| 351bf41f51 | |||
| 59c59ce2f5 | |||
| 65b3c804b5 | |||
| fcbcbec6b1 | |||
| ee3330bc06 | |||
| ddc114ea2b | |||
| 52f2c25c69 | |||
| 7f829d4736 | |||
| 332e30b02e | |||
| 0a4c60553a | |||
| b827146463 | |||
| 2802af349a | |||
| 0ba5b1beec | |||
| e4e75fe503 | |||
| b63dd43fb3 | |||
| c01b9b9177 | |||
| 03845511e3 | |||
| 13ce294474 | |||
| 80c8033ede | |||
| 5a77b12973 | |||
| df19150f28 | |||
| 3083961ff0 | |||
| b18ab30d0e | |||
| c69b9c5296 | |||
| 6eb0519584 | |||
| a6dd5c1211 | |||
| 0b9f58dd38 | |||
| d191b0309f | |||
| a8731dffeb | |||
| a77efd829e | |||
| 7b688ab54a | |||
| 228adfcd40 | |||
| 02f4c4289a | |||
| f4f23ddb6b | |||
| ae0095d51f | |||
| 0d895d041d | |||
| 29cb745e30 | |||
| f9cde631a2 | |||
| 264ab31364 | |||
| 5d7e8f3778 | |||
| 74e076ab06 | |||
| 184c27d785 | |||
| 33d771ed94 | |||
| 50e759c017 | |||
| bde1eb8281 | |||
| fb8384a555 | |||
| 86127edfd5 | |||
| d2b3575a03 | |||
| d256539bf4 | |||
| fbfecebc0a | |||
| f73a0ff35c | |||
| 5f5c42593a | |||
| fcde1eb2b7 | |||
| b52085fc2e | |||
| ee2f9437b6 | |||
| 8e51e59c8a | |||
| a4b9862912 | |||
| 718cc1a071 |
137
CHANGELOG.md
137
CHANGELOG.md
@ -1 +1,138 @@
|
||||
# Changelog
|
||||
|
||||
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/engine/deprecated/ where target removal dates can also
|
||||
be found.
|
||||
|
||||
**IMPORTANT**: You must stop all containers and plugins **BEFORE** upgrading to Docker CE 17.12.
|
||||
See related PR: [moby/moby#35812](https://github.com/moby/moby/pull/35812)
|
||||
|
||||
## 17.12.1-ce (2017-02-DD)
|
||||
|
||||
### Client
|
||||
- Fix `node-generic-resource` typo [moby/moby#35970](https://github.com/moby/moby/pull/35970) and [moby/moby#36125](https://github.com/moby/moby/pull/36125)
|
||||
* Return errors from daemon on stack deploy configs create/update [docker/cli#757](https://github.com/docker/cli/pull/757)
|
||||
|
||||
### Logging
|
||||
- awslogs: fix batch size calculation for large logs [moby/moby#35726](https://github.com/moby/moby/pull/35726)
|
||||
|
||||
### Networking
|
||||
- Fix ingress network when upgrading from 17.09 to 17.12 [moby/moby#36003](https://github.com/moby/moby/pull/36003)
|
||||
* Add verbose info to partial overlay ID [moby/moby#35989](https://github.com/moby/moby/pull/35989)
|
||||
|
||||
### Packaging
|
||||
- Set TasksMax in docker.service [docker/docker-ce-packaging#78](https://github.com/docker/docker-ce-packaging/pull/78)
|
||||
|
||||
### Runtime
|
||||
* Bump Golang to 1.9.4
|
||||
* Bump containerd to 1.0.1
|
||||
- Fix dockerd not being able to reconnect to containerd when it is restarted [moby/moby#36173](https://github.com/moby/moby/pull/36173)
|
||||
- Fix containerd events from being processed twice [moby/moby#35891](https://github.com/moby/moby/issues/35891)
|
||||
- Fix vfs graph driver failure to initialize because of failure to setup fs quota [moby/moby#35827](https://github.com/moby/moby/pull/35827)
|
||||
- Fix regression of health check not using container's working directory [moby/moby#35845](https://github.com/moby/moby/pull/35845)
|
||||
- Honor `DOCKER_RAMDISK` with containerd 1.0 [moby/moby#35957](https://github.com/moby/moby/pull/35957)
|
||||
- Update runc to fix hang during start and exec [moby/moby#36097](https://github.com/moby/moby/pull/36097)
|
||||
- Windows: Vendor of Microsoft/hcsshim @v.0.6.8 partial fix for import layer failing [moby/moby#35924](https://github.com/moby/moby/pull/35924)
|
||||
|
||||
## 17.12.0-ce (2017-12-27)
|
||||
|
||||
## Known Issues
|
||||
* AWS logs batch size calculation [moby/moby#35726](https://github.com/moby/moby/pull/35726)
|
||||
* Health check no longer uses the container's working directory [moby/moby#35843](https://github.com/moby/moby/issues/35843)
|
||||
* Errors not returned from client in stack deploy configs [moby/moby#757](https://github.com/docker/cli/pull/757)
|
||||
* Daemon aborts when project quota fails [moby/moby#35827](https://github.com/moby/moby/pull/35827)
|
||||
* Docker cannot use memory limit when using systemd options [moby/moby#35123](https://github.com/moby/moby/issues/35123)
|
||||
|
||||
### Builder
|
||||
|
||||
- Fix build cache hash for broken symlink [moby/moby#34271](https://github.com/moby/moby/pull/34271)
|
||||
- Fix long stream sync [moby/moby#35404](https://github.com/moby/moby/pull/35404)
|
||||
- Fix dockerfile parser failing silently on long tokens [moby/moby#35429](https://github.com/moby/moby/pull/35429)
|
||||
|
||||
### Client
|
||||
|
||||
* Remove secret/config duplication in cli/compose [docker/cli#671](https://github.com/docker/cli/pull/671)
|
||||
* Add `--local` flag to `docker trust sign` [docker/cli#575](https://github.com/docker/cli/pull/575)
|
||||
* Add `docker trust inspect` [docker/cli#694](https://github.com/docker/cli/pull/694)
|
||||
+ Add `name` field to secrets and configs to allow interpolation in Compose files [docker/cli#668](https://github.com/docker/cli/pull/668)
|
||||
+ Add `--isolation` for setting swarm service isolation mode [docker/cli#426](https://github.com/docker/cli/pull/426)
|
||||
* Remove deprecated "daemon" subcommand [docker/cli#689](https://github.com/docker/cli/pull/689)
|
||||
- Fix behaviour of `rmi -f` with unexpected errors [docker/cli#654](https://github.com/docker/cli/pull/654)
|
||||
* Integrated Generic resource in service create [docker/cli#429](https://github.com/docker/cli/pull/429)
|
||||
- Fix external networks in stacks [docker/cli#743](https://github.com/docker/cli/pull/743)
|
||||
* Remove support for referencing images by image shortid [docker/cli#753](https://github.com/docker/cli/pull/753) and [moby/moby#35790](https://github.com/moby/moby/pull/35790)
|
||||
* Use commit-sha instead of tag for containerd [moby/moby#35770](https://github.com/moby/moby/pull/35770)
|
||||
|
||||
### Documentation
|
||||
|
||||
* Update API version history for 1.35 [moby/moby#35724](https://github.com/moby/moby/pull/35724)
|
||||
|
||||
### Logging
|
||||
|
||||
* Logentries driver line-only=true []byte output fix [moby/moby#35612](https://github.com/moby/moby/pull/35612)
|
||||
* Logentries line-only logopt fix to maintain backwards compatibility [moby/moby#35628](https://github.com/moby/moby/pull/35628)
|
||||
+ Add `--until` flag for docker logs [moby/moby#32914](https://github.com/moby/moby/pull/32914)
|
||||
+ Add gelf log driver plugin to Windows build [moby/moby#35073](https://github.com/moby/moby/pull/35073)
|
||||
* Set timeout on splunk batch send [moby/moby#35496](https://github.com/moby/moby/pull/35496)
|
||||
* Update Graylog2/go-gelf [moby/moby#35765](https://github.com/moby/moby/pull/35765)
|
||||
|
||||
### Networking
|
||||
|
||||
* Move load balancer sandbox creation/deletion into libnetwork [moby/moby#35422](https://github.com/moby/moby/pull/35422)
|
||||
* Only chown network files within container metadata [moby/moby#34224](https://github.com/moby/moby/pull/34224)
|
||||
* Restore error type in FindNetwork [moby/moby#35634](https://github.com/moby/moby/pull/35634)
|
||||
- Fix consumes MIME type for NetworkConnect [moby/moby#35542](https://github.com/moby/moby/pull/35542)
|
||||
+ Added support for persisting Windows network driver specific options [moby/moby#35563](https://github.com/moby/moby/pull/35563)
|
||||
- Fix timeout on netlink sockets and watchmiss leak [moby/moby#35677](https://github.com/moby/moby/pull/35677)
|
||||
+ New daemon config for networking diagnosis [moby/moby#35677](https://github.com/moby/moby/pull/35677)
|
||||
- Clean up node management logic [docker/libnetwork#2036](https://github.com/docker/libnetwork/pull/2036)
|
||||
- Allocate VIPs when endpoints are restored [docker/swarmkit#2474](https://github.com/docker/swarmkit/pull/2474)
|
||||
|
||||
### Runtime
|
||||
|
||||
* Update to containerd v1.0.0 [moby/moby#35707](https://github.com/moby/moby/pull/35707)
|
||||
* Have VFS graphdriver use accelerated in-kernel copy [moby/moby#35537](https://github.com/moby/moby/pull/35537)
|
||||
* Introduce `workingdir` option for docker exec [moby/moby#35661](https://github.com/moby/moby/pull/35661)
|
||||
* Bump Go to 1.9.2 [moby/moby#33892](https://github.com/moby/moby/pull/33892) [docker/cli#716](https://github.com/docker/cli/pull/716)
|
||||
* `/dev` should not be readonly with `--readonly` flag [moby/moby#35344](https://github.com/moby/moby/pull/35344)
|
||||
+ Add custom build-time Graphdrivers priority list [moby/moby#35522](https://github.com/moby/moby/pull/35522)
|
||||
* LCOW: CLI changes to add platform flag - pull, run, create and build [docker/cli#474](https://github.com/docker/cli/pull/474)
|
||||
* Fix width/height on Windoes for `docker exec` [moby/moby#35631](https://github.com/moby/moby/pull/35631)
|
||||
* Detect overlay2 support on pre-4.0 kernels [moby/moby#35527](https://github.com/moby/moby/pull/35527)
|
||||
* Devicemapper: remove container rootfs mountPath after umount [moby/moby#34573](https://github.com/moby/moby/pull/34573)
|
||||
* Disallow overlay/overlay2 on top of NFS [moby/moby#35483](https://github.com/moby/moby/pull/35483)
|
||||
- Fix potential panic during plugin set. [moby/moby#35632](https://github.com/moby/moby/pull/35632)
|
||||
- Fix some issues with locking on the container [moby/moby#35501](https://github.com/moby/moby/pull/35501)
|
||||
- Fixup some issues with plugin refcounting [moby/moby#35265](https://github.com/moby/moby/pull/35265)
|
||||
+ Add missing lock in ProcessEvent [moby/moby#35516](https://github.com/moby/moby/pull/35516)
|
||||
+ Add vfs quota support [moby/moby#35231](https://github.com/moby/moby/pull/35231)
|
||||
* Skip empty directories on prior graphdriver detection [moby/moby#35528](https://github.com/moby/moby/pull/35528)
|
||||
* Skip xfs quota tests when running in user namespace [moby/moby#35526](https://github.com/moby/moby/pull/35526)
|
||||
+ Added SubSecondPrecision to config option. [moby/moby#35529](https://github.com/moby/moby/pull/35529)
|
||||
* Update fsnotify to fix deadlock in removing watch [moby/moby#35453](https://github.com/moby/moby/pull/35453)
|
||||
- Fix "duplicate mount point" when `--tmpfs /dev/shm` is used [moby/moby#35467](https://github.com/moby/moby/pull/35467)
|
||||
- Fix honoring tmpfs-size for user `/dev/shm` mount [moby/moby#35316](https://github.com/moby/moby/pull/35316)
|
||||
- Fix EBUSY errors under overlayfs and v4.13+ kernels [moby/moby#34948](https://github.com/moby/moby/pull/34948)
|
||||
* Container: protect health monitor channel [moby/moby#35482](https://github.com/moby/moby/pull/35482)
|
||||
* Container: protect the health status with mutex [moby/moby#35517](https://github.com/moby/moby/pull/35517)
|
||||
* Container: update real-time resources [moby/moby#33731](https://github.com/moby/moby/pull/33731)
|
||||
* Create labels when volume exists only remotely [moby/moby#34896](https://github.com/moby/moby/pull/34896)
|
||||
- Fix leaking container/exec state [moby/moby#35484](https://github.com/moby/moby/pull/35484)
|
||||
* Disallow using legacy (v1) registries [moby/moby#35751](https://github.com/moby/moby/pull/35751) and [docker/cli#747](https://github.com/docker/cli/pull/747)
|
||||
- Windows: Fix case insensitive filename matching against builder cache [moby/moby#35793](https://github.com/moby/moby/pull/35793)
|
||||
- Fix race conditions around process handling and error checks [moby/moby#35809](https://github.com/moby/moby/pull/35809)
|
||||
* Ensure containers are stopped on daemon startup [moby/moby#35805](https://github.com/moby/moby/pull/35805)
|
||||
* Follow containerd namespace conventions [moby/moby#35812](https://github.com/moby/moby/pull/35812)
|
||||
|
||||
### Swarm Mode
|
||||
|
||||
+ Added support for swarm service isolation mode [moby/moby#34424](https://github.com/moby/moby/pull/34424)
|
||||
- Fix task clean up for tasks that are complete [docker/swarmkit#2477](https://github.com/docker/swarmkit/pull/2477)
|
||||
|
||||
### Packaging
|
||||
|
||||
+ Add Packaging for Fedora 27 [docker/docker-ce-packaging#59](https://github.com/docker/docker-ce-packaging/pull/59)
|
||||
* Change default versioning scheme to 0.0.0-dev unless specified for packaging [docker/docker-ce-packaging#67](https://github.com/docker/docker-ce-packaging/pull/67)
|
||||
* Pass Version to engine static builds [docker/docker-ce-packaging#70](https://github.com/docker/docker-ce-packaging/pull/70)
|
||||
+ Added support for aarch64 on Debian (stretch/jessie) and Ubuntu Zesty or newer [docker/docker-ce-packaging#35](https://github.com/docker/docker-ce-packaging/pull/35)
|
||||
|
||||
@ -1 +1 @@
|
||||
17.12.0-dev
|
||||
17.12.1-ce-rc1
|
||||
|
||||
@ -248,13 +248,13 @@ func createConfigs(
|
||||
case err == nil:
|
||||
// config already exists, then we update that
|
||||
if err := client.ConfigUpdate(ctx, config.ID, config.Meta.Version, configSpec); err != nil {
|
||||
errors.Wrapf(err, "failed to update config %s", configSpec.Name)
|
||||
return errors.Wrapf(err, "failed to update config %s", configSpec.Name)
|
||||
}
|
||||
case apiclient.IsErrNotFound(err):
|
||||
// config does not exist, then we create a new one.
|
||||
fmt.Fprintf(dockerCli.Out(), "Creating config %s\n", configSpec.Name)
|
||||
if _, err := client.ConfigCreate(ctx, configSpec); err != nil {
|
||||
errors.Wrapf(err, "failed to create config %s", configSpec.Name)
|
||||
return errors.Wrapf(err, "failed to create config %s", configSpec.Name)
|
||||
}
|
||||
default:
|
||||
return err
|
||||
|
||||
@ -62,7 +62,7 @@ func Networks(namespace Namespace, networks networkMap, servicesNetworks map[str
|
||||
for internalName := range servicesNetworks {
|
||||
network := networks[internalName]
|
||||
if network.External.External {
|
||||
externalNetworks = append(externalNetworks, network.External.Name)
|
||||
externalNetworks = append(externalNetworks, network.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@ -55,10 +55,8 @@ func TestNetworks(t *testing.T) {
|
||||
},
|
||||
},
|
||||
"outside": composetypes.NetworkConfig{
|
||||
External: composetypes.External{
|
||||
External: true,
|
||||
Name: "special",
|
||||
},
|
||||
External: composetypes.External{External: true},
|
||||
Name: "special",
|
||||
},
|
||||
"attachablenet": composetypes.NetworkConfig{
|
||||
Driver: "overlay",
|
||||
|
||||
@ -230,7 +230,7 @@ func convertServiceNetworks(
|
||||
}
|
||||
target := namespace.Scope(networkName)
|
||||
if networkConfig.External.External {
|
||||
target = networkConfig.External.Name
|
||||
target = networkConfig.Name
|
||||
}
|
||||
netAttachConfig := swarm.NetworkAttachmentConfig{
|
||||
Target: target,
|
||||
|
||||
@ -219,10 +219,8 @@ func TestConvertServiceNetworksOnlyDefault(t *testing.T) {
|
||||
func TestConvertServiceNetworks(t *testing.T) {
|
||||
networkConfigs := networkMap{
|
||||
"front": composetypes.NetworkConfig{
|
||||
External: composetypes.External{
|
||||
External: true,
|
||||
Name: "fronttier",
|
||||
},
|
||||
External: composetypes.External{External: true},
|
||||
Name: "fronttier",
|
||||
},
|
||||
"back": composetypes.NetworkConfig{},
|
||||
}
|
||||
@ -259,10 +257,8 @@ func TestConvertServiceNetworks(t *testing.T) {
|
||||
func TestConvertServiceNetworksCustomDefault(t *testing.T) {
|
||||
networkConfigs := networkMap{
|
||||
"default": composetypes.NetworkConfig{
|
||||
External: composetypes.External{
|
||||
External: true,
|
||||
Name: "custom",
|
||||
},
|
||||
External: composetypes.External{External: true},
|
||||
Name: "custom",
|
||||
},
|
||||
}
|
||||
networks := map[string]*composetypes.ServiceNetworkConfig{}
|
||||
|
||||
@ -2164,7 +2164,6 @@ _docker_create() {
|
||||
_docker_daemon() {
|
||||
local boolean_options="
|
||||
$global_boolean_options
|
||||
--disable-legacy-registry
|
||||
--experimental
|
||||
--help
|
||||
--icc=false
|
||||
@ -2221,6 +2220,7 @@ _docker_daemon() {
|
||||
--metrics-addr
|
||||
--mtu
|
||||
--network-control-plane-mtu
|
||||
--node-generic-resource
|
||||
--oom-score-adjust
|
||||
--pidfile -p
|
||||
--registry-mirror
|
||||
@ -2866,6 +2866,7 @@ _docker_inspect() {
|
||||
$(__docker_services)
|
||||
$(__docker_volumes)
|
||||
" -- "$cur" ) )
|
||||
__ltrim_colon_completions "$cur"
|
||||
;;
|
||||
container)
|
||||
__docker_complete_containers_all
|
||||
@ -3396,6 +3397,7 @@ _docker_service_update_and_create() {
|
||||
--dns-option
|
||||
--dns-search
|
||||
--env-file
|
||||
--generic-resource
|
||||
--group
|
||||
--host
|
||||
--mode
|
||||
@ -3457,6 +3459,8 @@ _docker_service_update_and_create() {
|
||||
--dns-rm
|
||||
--dns-search-add
|
||||
--dns-search-rm
|
||||
--generic-resource-add
|
||||
--generic-resource-rm
|
||||
--group-add
|
||||
--group-rm
|
||||
--host-add
|
||||
|
||||
@ -745,7 +745,7 @@ __docker_container_subcommand() {
|
||||
"($help)--privileged[Give extended Linux capabilities to the command]" \
|
||||
"($help -t --tty)"{-t,--tty}"[Allocate a pseudo-tty]" \
|
||||
"($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users" \
|
||||
"($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories"
|
||||
"($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories" \
|
||||
"($help -):containers:__docker_complete_running_containers" \
|
||||
"($help -)*::command:->anycommand" && ret=0
|
||||
case $state in
|
||||
@ -2633,7 +2633,6 @@ __docker_subcommand() {
|
||||
"($help)--default-gateway-v6[Container default gateway IPv6 address]:IPv6 address: " \
|
||||
"($help)--default-shm-size=[Default shm size for containers]:size:" \
|
||||
"($help)*--default-ulimit=[Default ulimits for containers]:ulimit: " \
|
||||
"($help)--disable-legacy-registry[Disable contacting legacy registries (default true)]" \
|
||||
"($help)*--dns=[DNS server to use]:DNS: " \
|
||||
"($help)*--dns-opt=[DNS options to use]:DNS option: " \
|
||||
"($help)*--dns-search=[DNS search domains to use]:DNS search: " \
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
FROM dockercore/golang-cross@sha256:2e843a0e4d82b6bab34d2cb7abe26d1a6cda23226ecc3869100c8db553603f9b
|
||||
FROM dockercore/golang-cross:1.9.4@sha256:b8d43ef11ccaa15bec63a1f1fd0c28a0e729074aa62fcfa51f0a5888f3571315
|
||||
ENV DISABLE_WARN_OUTSIDE_CONTAINER=1
|
||||
WORKDIR /go/src/github.com/docker/cli
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
FROM golang:1.9.2-alpine3.6
|
||||
FROM golang:1.9.4-alpine3.6
|
||||
|
||||
RUN apk add -U git make bash coreutils ca-certificates
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
FROM golang:1.9.2-alpine3.6
|
||||
FROM golang:1.9.4-alpine3.6
|
||||
|
||||
RUN apk add -U git
|
||||
|
||||
|
||||
@ -74,9 +74,13 @@ The `filter` param to filter the list of image by reference (name or name:tag) i
|
||||
### `repository:shortid` image references
|
||||
**Deprecated In Release: [v1.13.0](https://github.com/docker/docker/releases/tag/v1.13.0)**
|
||||
|
||||
**Target For Removal In Release: v17.12**
|
||||
**Removed In Release: v17.12**
|
||||
|
||||
`repository:shortid` syntax for referencing images is very little used, collides with tag references can be confused with digest references.
|
||||
The `repository:shortid` syntax for referencing images is very little used,
|
||||
collides with tag references, and can be confused with digest references.
|
||||
|
||||
Support for the `repository:shortid` notation to reference images was removed
|
||||
in Docker 17.12.
|
||||
|
||||
### `docker daemon` subcommand
|
||||
**Deprecated In Release: [v1.13.0](https://github.com/docker/docker/releases/tag/v1.13.0)**
|
||||
@ -88,10 +92,10 @@ The daemon is moved to a separate binary (`dockerd`), and should be used instead
|
||||
### Duplicate keys with conflicting values in engine labels
|
||||
**Deprecated In Release: [v1.13.0](https://github.com/docker/docker/releases/tag/v1.13.0)**
|
||||
|
||||
**Target For Removal In Release: v17.12**
|
||||
**Removed In Release: v17.12**
|
||||
|
||||
Duplicate keys with conflicting values have been deprecated. A warning is displayed
|
||||
in the output, and an error will be returned in the future.
|
||||
When setting duplicate keys with conflicting values, an error will be produced, and the daemon
|
||||
will fail to start.
|
||||
|
||||
### `MAINTAINER` in Dockerfile
|
||||
**Deprecated In Release: [v1.13.0](https://github.com/docker/docker/releases/tag/v1.13.0)**
|
||||
@ -110,12 +114,16 @@ future Engine versions. Instead of just requesting, for example, the URL
|
||||
### Backing filesystem without `d_type` support for overlay/overlay2
|
||||
**Deprecated In Release: [v1.13.0](https://github.com/docker/docker/releases/tag/v1.13.0)**
|
||||
|
||||
**Target For Removal In Release: v17.12**
|
||||
**Removed In Release: v17.12**
|
||||
|
||||
The overlay and overlay2 storage driver does not work as expected if the backing
|
||||
filesystem does not support `d_type`. For example, XFS does not support `d_type`
|
||||
if it is formatted with the `ftype=0` option.
|
||||
|
||||
Starting with Docker 17.12, new installations will not support running overlay2 on
|
||||
a backing filesystem without `d_type` support. For existing installations that upgrade
|
||||
to 17.12, a warning will be printed.
|
||||
|
||||
Please also refer to [#27358](https://github.com/docker/docker/issues/27358) for
|
||||
further information.
|
||||
|
||||
@ -292,7 +300,7 @@ of the `--changes` flag that allows to pass `Dockerfile` commands.
|
||||
|
||||
**Disabled By Default In Release: v17.06**
|
||||
|
||||
**Target For Removal In Release: v17.12**
|
||||
**Removed In Release: v17.12**
|
||||
|
||||
Version 1.8.3 added a flag (`--disable-legacy-registry=false`) which prevents the
|
||||
docker daemon from `pull`, `push`, and `login` operations against v1
|
||||
@ -303,6 +311,21 @@ Support for the v1 protocol to the public registry was removed in 1.13. Any
|
||||
mirror configurations using v1 should be updated to use a
|
||||
[v2 registry mirror](https://docs.docker.com/registry/recipes/mirror/).
|
||||
|
||||
Starting with Docker 17.12, support for V1 registries has been removed, and the
|
||||
`--disable-legacy-registry` flag can no longer be used, and `dockerd` will fail to
|
||||
start when set.
|
||||
|
||||
### `--disable-legacy-registry` override daemon option
|
||||
|
||||
**Disabled In Release: v17.12**
|
||||
|
||||
**Target For Removal In Release: v18.03**
|
||||
|
||||
The `--disable-legacy-registry` flag was disabled in Docker 17.12 and will print
|
||||
an error when used. For this error to be printed, the flag itself is still present,
|
||||
but hidden. The flag will be removed in Docker 18.03.
|
||||
|
||||
|
||||
### Docker Content Trust ENV passphrase variables name change
|
||||
**Deprecated In Release: [v1.9.0](https://github.com/docker/docker/releases/tag/v1.9.0)**
|
||||
|
||||
|
||||
@ -42,7 +42,6 @@ Options:
|
||||
--default-gateway-v6 ip Container default gateway IPv6 address
|
||||
--default-runtime string Default OCI runtime for containers (default "runc")
|
||||
--default-ulimit ulimit Default ulimits for containers (default [])
|
||||
--disable-legacy-registry Disable contacting legacy registries (default true)
|
||||
--dns list DNS server to use (default [])
|
||||
--dns-opt list DNS options to use (default [])
|
||||
--dns-search list DNS search domains to use (default [])
|
||||
@ -263,7 +262,7 @@ snapshots. For each devicemapper graph location – typically
|
||||
`/var/lib/docker/devicemapper` – a thin pool is created based on two block
|
||||
devices, one for data and one for metadata. By default, these block devices
|
||||
are created automatically by using loopback mounts of automatically created
|
||||
sparse files. Refer to [Storage driver options](#storage-driver-options) below
|
||||
sparse files. Refer to [Devicemapper options](#devicemapper-options) below
|
||||
for a way how to customize this setup.
|
||||
[~jpetazzo/Resizing Docker containers with the Device Mapper plugin](http://jpetazzo.github.io/2014/01/29/docker-device-mapper-resize/)
|
||||
article explains how to tune your existing setup without the use of options.
|
||||
@ -275,7 +274,7 @@ does not share executable memory between devices. Use
|
||||
The `zfs` driver is probably not as fast as `btrfs` but has a longer track record
|
||||
on stability. Thanks to `Single Copy ARC` shared blocks between clones will be
|
||||
cached only once. Use `dockerd -s zfs`. To select a different zfs filesystem
|
||||
set `zfs.fsname` option as described in [Storage driver options](#storage-driver-options).
|
||||
set `zfs.fsname` option as described in [ZFS options](#zfs-options).
|
||||
|
||||
The `overlay` is a very fast union filesystem. It is now merged in the main
|
||||
Linux kernel as of [3.18.0](https://lkml.org/lkml/2014/10/26/137). `overlay`
|
||||
@ -1054,18 +1053,14 @@ system's list of trusted CAs instead of enabling `--insecure-registry`.
|
||||
|
||||
#### Legacy Registries
|
||||
|
||||
Operations against registries supporting only the legacy v1 protocol are
|
||||
disabled by default. Specifically, the daemon will not attempt `push`,
|
||||
`pull` and `login` to v1 registries. The exception to this is `search`
|
||||
which can still be performed on v1 registries.
|
||||
Starting with Docker 17.12, operations against registries supporting only the
|
||||
legacy v1 protocol are no longer supported. Specifically, the daemon will not
|
||||
attempt `push`, `pull` and `login` to v1 registries. The exception to this is
|
||||
`search` which can still be performed on v1 registries.
|
||||
|
||||
Add `"disable-legacy-registry":false` to the [daemon configuration
|
||||
file](#daemon-configuration-file), or set the
|
||||
`--disable-legacy-registry=false` flag, if you need to interact with
|
||||
registries that have not yet migrated to the v2 protocol.
|
||||
The `disable-legacy-registry` configuration option has been removed and, when
|
||||
used, will produce an error on daemon startup.
|
||||
|
||||
Interaction v1 registries will no longer be supported in Docker v17.12,
|
||||
and the `disable-legacy-registry` configuration option will be removed.
|
||||
|
||||
### Running a Docker daemon behind an HTTPS_PROXY
|
||||
|
||||
@ -1339,7 +1334,6 @@ This is a full example of the allowed configuration options on Linux:
|
||||
"registry-mirrors": [],
|
||||
"seccomp-profile": "",
|
||||
"insecure-registries": [],
|
||||
"disable-legacy-registry": false,
|
||||
"no-new-privileges": false,
|
||||
"default-runtime": "runc",
|
||||
"oom-score-adjust": -500,
|
||||
@ -1408,8 +1402,7 @@ This is a full example of the allowed configuration options on Windows:
|
||||
"raw-logs": false,
|
||||
"allow-nondistributable-artifacts": [],
|
||||
"registry-mirrors": [],
|
||||
"insecure-registries": [],
|
||||
"disable-legacy-registry": false
|
||||
"insecure-registries": []
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -588,11 +588,11 @@ Use Docker's `--restart` to specify a container's *restart policy*. A restart
|
||||
policy controls whether the Docker daemon restarts a container after exit.
|
||||
Docker supports the following restart policies:
|
||||
|
||||
| Policy | Result |
|
||||
|:----------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `no` | Do not automatically restart the container when it exits. This is the default. |
|
||||
| `failure` | Restart only if the container exits with a non-zero exit status. Optionally, limit the number of restart retries the Docker daemon attempts. |
|
||||
| `always` | Always restart the container regardless of the exit status. When you specify always, the Docker daemon will try to restart the container indefinitely. The container will also always start on daemon startup, regardless of the current state of the container. |
|
||||
| Policy | Result |
|
||||
|:---------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `no` | Do not automatically restart the container when it exits. This is the default. |
|
||||
| `on-failure[:max-retries]` | Restart only if the container exits with a non-zero exit status. Optionally, limit the number of restart retries the Docker daemon attempts. |
|
||||
| `always` | Always restart the container regardless of the exit status. When you specify always, the Docker daemon will try to restart the container indefinitely. The container will also always start on daemon startup, regardless of the current state of the container. |
|
||||
|
||||
```bash
|
||||
$ docker run --restart=always redis
|
||||
|
||||
@ -739,7 +739,7 @@ Containers on the same network can access each other using
|
||||
You can publish service ports to make them available externally to the swarm
|
||||
using the `--publish` flag. The `--publish` flag can take two different styles
|
||||
of arguments. The short version is positional, and allows you to specify the
|
||||
target port and container port separated by a colon.
|
||||
published port and target port separated by a colon.
|
||||
|
||||
```bash
|
||||
$ docker service create --name my_web --replicas 3 --publish 8080:80 nginx
|
||||
@ -751,7 +751,7 @@ mode when using the short format. Here is an example of using the long format
|
||||
for the same service as above:
|
||||
|
||||
```bash
|
||||
$ docker service create --name my_web --replicas 3 --publish target=8080,port=80 nginx
|
||||
$ docker service create --name my_web --replicas 3 --publish published=8080,target=80 nginx
|
||||
```
|
||||
|
||||
The options you can specify are:
|
||||
@ -765,7 +765,7 @@ The options you can specify are:
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>target and container port </td>
|
||||
<td>published and target port </td>
|
||||
<td><tt></tt></td>
|
||||
<td><tt></tt></td>
|
||||
<td></td>
|
||||
@ -773,16 +773,16 @@ The options you can specify are:
|
||||
<tr>
|
||||
<td>protocol</td>
|
||||
<td><tt>--publish 8080:80</tt></td>
|
||||
<td><tt>--publish target=8080,port=80</tt></td>
|
||||
<td><tt>--publish published=8080,target=80</tt></td>
|
||||
<td><p>
|
||||
The container port to publish and the target port to bind it to on the
|
||||
routing mesh or directly on the node.
|
||||
The port to publish the service to on the routing mesh or directly on
|
||||
the node, and the target port on the container.
|
||||
</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>mode</td>
|
||||
<td>Not possible to set using short syntax.</td>
|
||||
<td><tt>--publish target=8080,port=80,mode=host</tt></td>
|
||||
<td><tt>--publish published=8080,target=80,mode=host</tt></td>
|
||||
<td><p>
|
||||
The mode to use for binding the port, either `ingress` or `host`. Defaults
|
||||
to `ingress` to use the routing mesh.
|
||||
@ -791,7 +791,7 @@ The options you can specify are:
|
||||
<tr>
|
||||
<td>protocol</td>
|
||||
<td><tt>--publish 8080:80/tcp</tt></td>
|
||||
<td><tt>--publish target=8080,port=80,protocol=tcp</tt></td>
|
||||
<td><tt>--publish published=8080,target=80,protocol=tcp</tt></td>
|
||||
<td><p>
|
||||
The protocol to use, either `tcp` or `udp`. Defaults to `tcp`. To bind a
|
||||
port for both protocols, specify the `-p` or `--publish` flag twice.
|
||||
@ -800,7 +800,7 @@ The options you can specify are:
|
||||
</table>
|
||||
|
||||
When you publish a service port using `ingres` mode, the swarm routing mesh
|
||||
makes the service accessible at the target port on every node regardless if
|
||||
makes the service accessible at the published port on every node regardless if
|
||||
there is a task for the service running on the node. If you use `host` mode,
|
||||
the port is only bound on nodes where the service is running, and a given port
|
||||
on a node can only be bound once. You can only set the publication mode using
|
||||
|
||||
@ -177,18 +177,18 @@ $ docker service update --mount-rm /somewhere myservice
|
||||
myservice
|
||||
```
|
||||
|
||||
### Add or remove port mappings
|
||||
### Add or remove published service ports
|
||||
|
||||
Use the `--port-add` or `--port-rm` flags to add or remove port mappings to or
|
||||
from a service. You can use the short or long syntax discussed in the
|
||||
[docker service update](service_create/#attach-a-service-to-an-existing-network-network)
|
||||
Use the `--publish-add` or `--publish-rm` flags to add or remove a published
|
||||
port for a service. You can use the short or long syntax discussed in the
|
||||
[docker service create](service_create/#attach-a-service-to-an-existing-network-network)
|
||||
reference.
|
||||
|
||||
The following example adds a port mapping to an existing service.
|
||||
The following example adds a published service port to an existing service.
|
||||
|
||||
```bash
|
||||
$ docker service update \
|
||||
--port-add port=80,target=8080 \
|
||||
--publish-add published=8080,target=80 \
|
||||
myservice
|
||||
```
|
||||
|
||||
|
||||
@ -26,7 +26,6 @@ dockerd - Enable daemon mode
|
||||
[**--default-ipc-mode**=*MODE*]
|
||||
[**--default-shm-size**[=*64MiB*]]
|
||||
[**--default-ulimit**[=*[]*]]
|
||||
[**--disable-legacy-registry**]
|
||||
[**--dns**[=*[]*]]
|
||||
[**--dns-opt**[=*[]*]]
|
||||
[**--dns-search**[=*[]*]]
|
||||
@ -197,9 +196,6 @@ $ sudo dockerd --add-runtime runc=runc --add-runtime custom=/usr/local/bin/my-ru
|
||||
**--default-ulimit**=[]
|
||||
Default ulimits for containers.
|
||||
|
||||
**--disable-legacy-registry**=*true*|*false*
|
||||
Disable contacting legacy registries. Default is `true`.
|
||||
|
||||
**--dns**=""
|
||||
Force Docker to use specific DNS servers
|
||||
|
||||
|
||||
@ -87,7 +87,7 @@ RUN apt-get update && apt-get install -y \
|
||||
# will need updating, to avoid errors. Ping #docker-maintainers on IRC
|
||||
# with a heads-up.
|
||||
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
|
||||
| tar -xzC /usr/local
|
||||
|
||||
|
||||
@ -73,7 +73,7 @@ RUN apt-get update && apt-get install -y \
|
||||
|
||||
# Install Go
|
||||
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" \
|
||||
| tar -xzC /usr/local
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ RUN apt-get update && apt-get install -y \
|
||||
|
||||
# Install Go
|
||||
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" \
|
||||
| tar -xzC /usr/local
|
||||
ENV PATH /go/bin:/usr/local/go/bin:$PATH
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
## Step 1: Build tests
|
||||
FROM golang:1.9.2-alpine3.6 as builder
|
||||
FROM golang:1.9.4-alpine3.6 as builder
|
||||
|
||||
RUN apk add --update \
|
||||
bash \
|
||||
|
||||
@ -64,7 +64,7 @@ RUN apt-get update && apt-get install -y \
|
||||
# Install Go
|
||||
# NOTE: official ppc64le go binaries weren't available until go 1.6.4 and 1.7.4
|
||||
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" \
|
||||
| tar -xzC /usr/local
|
||||
|
||||
|
||||
@ -58,7 +58,7 @@ RUN apt-get update && apt-get install -y \
|
||||
--no-install-recommends
|
||||
|
||||
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" \
|
||||
| tar -xzC /usr/local
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
# will need updating, to avoid errors. Ping #docker-maintainers on IRC
|
||||
# with a heads-up.
|
||||
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
|
||||
| tar -xzC /usr/local
|
||||
ENV PATH /go/bin:/usr/local/go/bin:$PATH
|
||||
|
||||
@ -161,7 +161,7 @@ SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPref
|
||||
# Environment variable notes:
|
||||
# - GO_VERSION must be consistent with 'Dockerfile' used by Linux.
|
||||
# - FROM_DOCKERFILE is used for detection of building within a container.
|
||||
ENV GO_VERSION=1.9.2 `
|
||||
ENV GO_VERSION=1.9.4 `
|
||||
GIT_VERSION=2.11.1 `
|
||||
GOPATH=C:\go `
|
||||
FROM_DOCKERFILE=1
|
||||
|
||||
@ -177,6 +177,13 @@ func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r
|
||||
// return the network. Skipped using isMatchingScope because it is true if the scope
|
||||
// is not set which would be case if the client API v1.30
|
||||
if strings.HasPrefix(nwk.ID, term) || (netconst.SwarmScope == scope) {
|
||||
// If we have a previous match "backend", return it, we need verbose when enabled
|
||||
// ex: overlay/partial_ID or name/swarm_scope
|
||||
if nwv, ok := listByPartialID[nwk.ID]; ok {
|
||||
nwk = nwv
|
||||
} else if nwv, ok := listByFullName[nwk.ID]; ok {
|
||||
nwk = nwv
|
||||
}
|
||||
return httputils.WriteJSON(w, http.StatusOK, nwk)
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,6 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
@ -23,10 +22,8 @@ import (
|
||||
"github.com/docker/docker/pkg/containerfs"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/pkg/symlink"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/docker/go-connections/nat"
|
||||
lcUser "github.com/opencontainers/runc/libcontainer/user"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@ -216,82 +213,6 @@ func (b *Builder) performCopy(state *dispatchState, inst copyInstruction) error
|
||||
return b.exportImage(state, imageMount, runConfigWithCommentCmd)
|
||||
}
|
||||
|
||||
func parseChownFlag(chown, ctrRootPath string, idMappings *idtools.IDMappings) (idtools.IDPair, error) {
|
||||
var userStr, grpStr string
|
||||
parts := strings.Split(chown, ":")
|
||||
if len(parts) > 2 {
|
||||
return idtools.IDPair{}, errors.New("invalid chown string format: " + chown)
|
||||
}
|
||||
if len(parts) == 1 {
|
||||
// if no group specified, use the user spec as group as well
|
||||
userStr, grpStr = parts[0], parts[0]
|
||||
} else {
|
||||
userStr, grpStr = parts[0], parts[1]
|
||||
}
|
||||
|
||||
passwdPath, err := symlink.FollowSymlinkInScope(filepath.Join(ctrRootPath, "etc", "passwd"), ctrRootPath)
|
||||
if err != nil {
|
||||
return idtools.IDPair{}, errors.Wrapf(err, "can't resolve /etc/passwd path in container rootfs")
|
||||
}
|
||||
groupPath, err := symlink.FollowSymlinkInScope(filepath.Join(ctrRootPath, "etc", "group"), ctrRootPath)
|
||||
if err != nil {
|
||||
return idtools.IDPair{}, errors.Wrapf(err, "can't resolve /etc/group path in container rootfs")
|
||||
}
|
||||
uid, err := lookupUser(userStr, passwdPath)
|
||||
if err != nil {
|
||||
return idtools.IDPair{}, errors.Wrapf(err, "can't find uid for user "+userStr)
|
||||
}
|
||||
gid, err := lookupGroup(grpStr, groupPath)
|
||||
if err != nil {
|
||||
return idtools.IDPair{}, errors.Wrapf(err, "can't find gid for group "+grpStr)
|
||||
}
|
||||
|
||||
// convert as necessary because of user namespaces
|
||||
chownPair, err := idMappings.ToHost(idtools.IDPair{UID: uid, GID: gid})
|
||||
if err != nil {
|
||||
return idtools.IDPair{}, errors.Wrapf(err, "unable to convert uid/gid to host mapping")
|
||||
}
|
||||
return chownPair, nil
|
||||
}
|
||||
|
||||
func lookupUser(userStr, filepath string) (int, error) {
|
||||
// if the string is actually a uid integer, parse to int and return
|
||||
// as we don't need to translate with the help of files
|
||||
uid, err := strconv.Atoi(userStr)
|
||||
if err == nil {
|
||||
return uid, nil
|
||||
}
|
||||
users, err := lcUser.ParsePasswdFileFilter(filepath, func(u lcUser.User) bool {
|
||||
return u.Name == userStr
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(users) == 0 {
|
||||
return 0, errors.New("no such user: " + userStr)
|
||||
}
|
||||
return users[0].Uid, nil
|
||||
}
|
||||
|
||||
func lookupGroup(groupStr, filepath string) (int, error) {
|
||||
// if the string is actually a gid integer, parse to int and return
|
||||
// as we don't need to translate with the help of files
|
||||
gid, err := strconv.Atoi(groupStr)
|
||||
if err == nil {
|
||||
return gid, nil
|
||||
}
|
||||
groups, err := lcUser.ParseGroupFileFilter(filepath, func(g lcUser.Group) bool {
|
||||
return g.Name == groupStr
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(groups) == 0 {
|
||||
return 0, errors.New("no such group: " + groupStr)
|
||||
}
|
||||
return groups[0].Gid, nil
|
||||
}
|
||||
|
||||
func createDestInfo(workingDir string, inst copyInstruction, imageMount *imageMount, platform string) (copyInfo, error) {
|
||||
// Twiddle the destination when it's a relative path - meaning, make it
|
||||
// relative to the WORKINGDIR
|
||||
|
||||
88
components/engine/builder/dockerfile/internals_linux.go
Normal file
88
components/engine/builder/dockerfile/internals_linux.go
Normal file
@ -0,0 +1,88 @@
|
||||
package dockerfile
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/symlink"
|
||||
lcUser "github.com/opencontainers/runc/libcontainer/user"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func parseChownFlag(chown, ctrRootPath string, idMappings *idtools.IDMappings) (idtools.IDPair, error) {
|
||||
var userStr, grpStr string
|
||||
parts := strings.Split(chown, ":")
|
||||
if len(parts) > 2 {
|
||||
return idtools.IDPair{}, errors.New("invalid chown string format: " + chown)
|
||||
}
|
||||
if len(parts) == 1 {
|
||||
// if no group specified, use the user spec as group as well
|
||||
userStr, grpStr = parts[0], parts[0]
|
||||
} else {
|
||||
userStr, grpStr = parts[0], parts[1]
|
||||
}
|
||||
|
||||
passwdPath, err := symlink.FollowSymlinkInScope(filepath.Join(ctrRootPath, "etc", "passwd"), ctrRootPath)
|
||||
if err != nil {
|
||||
return idtools.IDPair{}, errors.Wrapf(err, "can't resolve /etc/passwd path in container rootfs")
|
||||
}
|
||||
groupPath, err := symlink.FollowSymlinkInScope(filepath.Join(ctrRootPath, "etc", "group"), ctrRootPath)
|
||||
if err != nil {
|
||||
return idtools.IDPair{}, errors.Wrapf(err, "can't resolve /etc/group path in container rootfs")
|
||||
}
|
||||
uid, err := lookupUser(userStr, passwdPath)
|
||||
if err != nil {
|
||||
return idtools.IDPair{}, errors.Wrapf(err, "can't find uid for user "+userStr)
|
||||
}
|
||||
gid, err := lookupGroup(grpStr, groupPath)
|
||||
if err != nil {
|
||||
return idtools.IDPair{}, errors.Wrapf(err, "can't find gid for group "+grpStr)
|
||||
}
|
||||
|
||||
// convert as necessary because of user namespaces
|
||||
chownPair, err := idMappings.ToHost(idtools.IDPair{UID: uid, GID: gid})
|
||||
if err != nil {
|
||||
return idtools.IDPair{}, errors.Wrapf(err, "unable to convert uid/gid to host mapping")
|
||||
}
|
||||
return chownPair, nil
|
||||
}
|
||||
|
||||
func lookupUser(userStr, filepath string) (int, error) {
|
||||
// if the string is actually a uid integer, parse to int and return
|
||||
// as we don't need to translate with the help of files
|
||||
uid, err := strconv.Atoi(userStr)
|
||||
if err == nil {
|
||||
return uid, nil
|
||||
}
|
||||
users, err := lcUser.ParsePasswdFileFilter(filepath, func(u lcUser.User) bool {
|
||||
return u.Name == userStr
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(users) == 0 {
|
||||
return 0, errors.New("no such user: " + userStr)
|
||||
}
|
||||
return users[0].Uid, nil
|
||||
}
|
||||
|
||||
func lookupGroup(groupStr, filepath string) (int, error) {
|
||||
// if the string is actually a gid integer, parse to int and return
|
||||
// as we don't need to translate with the help of files
|
||||
gid, err := strconv.Atoi(groupStr)
|
||||
if err == nil {
|
||||
return gid, nil
|
||||
}
|
||||
groups, err := lcUser.ParseGroupFileFilter(filepath, func(g lcUser.Group) bool {
|
||||
return g.Name == groupStr
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(groups) == 0 {
|
||||
return 0, errors.New("no such group: " + groupStr)
|
||||
}
|
||||
return groups[0].Gid, nil
|
||||
}
|
||||
138
components/engine/builder/dockerfile/internals_linux_test.go
Normal file
138
components/engine/builder/dockerfile/internals_linux_test.go
Normal file
@ -0,0 +1,138 @@
|
||||
package dockerfile
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestChownFlagParsing(t *testing.T) {
|
||||
testFiles := map[string]string{
|
||||
"passwd": `root:x:0:0::/bin:/bin/false
|
||||
bin:x:1:1::/bin:/bin/false
|
||||
wwwwww:x:21:33::/bin:/bin/false
|
||||
unicorn:x:1001:1002::/bin:/bin/false
|
||||
`,
|
||||
"group": `root:x:0:
|
||||
bin:x:1:
|
||||
wwwwww:x:33:
|
||||
unicorn:x:1002:
|
||||
somegrp:x:5555:
|
||||
othergrp:x:6666:
|
||||
`,
|
||||
}
|
||||
// test mappings for validating use of maps
|
||||
idMaps := []idtools.IDMap{
|
||||
{
|
||||
ContainerID: 0,
|
||||
HostID: 100000,
|
||||
Size: 65536,
|
||||
},
|
||||
}
|
||||
remapped := idtools.NewIDMappingsFromMaps(idMaps, idMaps)
|
||||
unmapped := &idtools.IDMappings{}
|
||||
|
||||
contextDir, cleanup := createTestTempDir(t, "", "builder-chown-parse-test")
|
||||
defer cleanup()
|
||||
|
||||
if err := os.Mkdir(filepath.Join(contextDir, "etc"), 0755); err != nil {
|
||||
t.Fatalf("error creating test directory: %v", err)
|
||||
}
|
||||
|
||||
for filename, content := range testFiles {
|
||||
createTestTempFile(t, filepath.Join(contextDir, "etc"), filename, content, 0644)
|
||||
}
|
||||
|
||||
// positive tests
|
||||
for _, testcase := range []struct {
|
||||
name string
|
||||
chownStr string
|
||||
idMapping *idtools.IDMappings
|
||||
expected idtools.IDPair
|
||||
}{
|
||||
{
|
||||
name: "UIDNoMap",
|
||||
chownStr: "1",
|
||||
idMapping: unmapped,
|
||||
expected: idtools.IDPair{UID: 1, GID: 1},
|
||||
},
|
||||
{
|
||||
name: "UIDGIDNoMap",
|
||||
chownStr: "0:1",
|
||||
idMapping: unmapped,
|
||||
expected: idtools.IDPair{UID: 0, GID: 1},
|
||||
},
|
||||
{
|
||||
name: "UIDWithMap",
|
||||
chownStr: "0",
|
||||
idMapping: remapped,
|
||||
expected: idtools.IDPair{UID: 100000, GID: 100000},
|
||||
},
|
||||
{
|
||||
name: "UIDGIDWithMap",
|
||||
chownStr: "1:33",
|
||||
idMapping: remapped,
|
||||
expected: idtools.IDPair{UID: 100001, GID: 100033},
|
||||
},
|
||||
{
|
||||
name: "UserNoMap",
|
||||
chownStr: "bin:5555",
|
||||
idMapping: unmapped,
|
||||
expected: idtools.IDPair{UID: 1, GID: 5555},
|
||||
},
|
||||
{
|
||||
name: "GroupWithMap",
|
||||
chownStr: "0:unicorn",
|
||||
idMapping: remapped,
|
||||
expected: idtools.IDPair{UID: 100000, GID: 101002},
|
||||
},
|
||||
{
|
||||
name: "UserOnlyWithMap",
|
||||
chownStr: "unicorn",
|
||||
idMapping: remapped,
|
||||
expected: idtools.IDPair{UID: 101001, GID: 101002},
|
||||
},
|
||||
} {
|
||||
t.Run(testcase.name, func(t *testing.T) {
|
||||
idPair, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping)
|
||||
require.NoError(t, err, "Failed to parse chown flag: %q", testcase.chownStr)
|
||||
assert.Equal(t, testcase.expected, idPair, "chown flag mapping failure")
|
||||
})
|
||||
}
|
||||
|
||||
// error tests
|
||||
for _, testcase := range []struct {
|
||||
name string
|
||||
chownStr string
|
||||
idMapping *idtools.IDMappings
|
||||
descr string
|
||||
}{
|
||||
{
|
||||
name: "BadChownFlagFormat",
|
||||
chownStr: "bob:1:555",
|
||||
idMapping: unmapped,
|
||||
descr: "invalid chown string format: bob:1:555",
|
||||
},
|
||||
{
|
||||
name: "UserNoExist",
|
||||
chownStr: "bob",
|
||||
idMapping: unmapped,
|
||||
descr: "can't find uid for user bob: no such user: bob",
|
||||
},
|
||||
{
|
||||
name: "GroupNoExist",
|
||||
chownStr: "root:bob",
|
||||
idMapping: unmapped,
|
||||
descr: "can't find gid for group bob: no such group: bob",
|
||||
},
|
||||
} {
|
||||
t.Run(testcase.name, func(t *testing.T) {
|
||||
_, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping)
|
||||
assert.EqualError(t, err, testcase.descr, "Expected error string doesn't match")
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -2,8 +2,6 @@ package dockerfile
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
@ -13,7 +11,6 @@ import (
|
||||
"github.com/docker/docker/builder"
|
||||
"github.com/docker/docker/builder/remotecontext"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -171,130 +168,3 @@ func TestDeepCopyRunConfig(t *testing.T) {
|
||||
copy.Shell[0] = "sh"
|
||||
assert.Equal(t, fullMutableRunConfig(), runConfig)
|
||||
}
|
||||
|
||||
func TestChownFlagParsing(t *testing.T) {
|
||||
testFiles := map[string]string{
|
||||
"passwd": `root:x:0:0::/bin:/bin/false
|
||||
bin:x:1:1::/bin:/bin/false
|
||||
wwwwww:x:21:33::/bin:/bin/false
|
||||
unicorn:x:1001:1002::/bin:/bin/false
|
||||
`,
|
||||
"group": `root:x:0:
|
||||
bin:x:1:
|
||||
wwwwww:x:33:
|
||||
unicorn:x:1002:
|
||||
somegrp:x:5555:
|
||||
othergrp:x:6666:
|
||||
`,
|
||||
}
|
||||
// test mappings for validating use of maps
|
||||
idMaps := []idtools.IDMap{
|
||||
{
|
||||
ContainerID: 0,
|
||||
HostID: 100000,
|
||||
Size: 65536,
|
||||
},
|
||||
}
|
||||
remapped := idtools.NewIDMappingsFromMaps(idMaps, idMaps)
|
||||
unmapped := &idtools.IDMappings{}
|
||||
|
||||
contextDir, cleanup := createTestTempDir(t, "", "builder-chown-parse-test")
|
||||
defer cleanup()
|
||||
|
||||
if err := os.Mkdir(filepath.Join(contextDir, "etc"), 0755); err != nil {
|
||||
t.Fatalf("error creating test directory: %v", err)
|
||||
}
|
||||
|
||||
for filename, content := range testFiles {
|
||||
createTestTempFile(t, filepath.Join(contextDir, "etc"), filename, content, 0644)
|
||||
}
|
||||
|
||||
// positive tests
|
||||
for _, testcase := range []struct {
|
||||
name string
|
||||
chownStr string
|
||||
idMapping *idtools.IDMappings
|
||||
expected idtools.IDPair
|
||||
}{
|
||||
{
|
||||
name: "UIDNoMap",
|
||||
chownStr: "1",
|
||||
idMapping: unmapped,
|
||||
expected: idtools.IDPair{UID: 1, GID: 1},
|
||||
},
|
||||
{
|
||||
name: "UIDGIDNoMap",
|
||||
chownStr: "0:1",
|
||||
idMapping: unmapped,
|
||||
expected: idtools.IDPair{UID: 0, GID: 1},
|
||||
},
|
||||
{
|
||||
name: "UIDWithMap",
|
||||
chownStr: "0",
|
||||
idMapping: remapped,
|
||||
expected: idtools.IDPair{UID: 100000, GID: 100000},
|
||||
},
|
||||
{
|
||||
name: "UIDGIDWithMap",
|
||||
chownStr: "1:33",
|
||||
idMapping: remapped,
|
||||
expected: idtools.IDPair{UID: 100001, GID: 100033},
|
||||
},
|
||||
{
|
||||
name: "UserNoMap",
|
||||
chownStr: "bin:5555",
|
||||
idMapping: unmapped,
|
||||
expected: idtools.IDPair{UID: 1, GID: 5555},
|
||||
},
|
||||
{
|
||||
name: "GroupWithMap",
|
||||
chownStr: "0:unicorn",
|
||||
idMapping: remapped,
|
||||
expected: idtools.IDPair{UID: 100000, GID: 101002},
|
||||
},
|
||||
{
|
||||
name: "UserOnlyWithMap",
|
||||
chownStr: "unicorn",
|
||||
idMapping: remapped,
|
||||
expected: idtools.IDPair{UID: 101001, GID: 101002},
|
||||
},
|
||||
} {
|
||||
t.Run(testcase.name, func(t *testing.T) {
|
||||
idPair, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping)
|
||||
require.NoError(t, err, "Failed to parse chown flag: %q", testcase.chownStr)
|
||||
assert.Equal(t, testcase.expected, idPair, "chown flag mapping failure")
|
||||
})
|
||||
}
|
||||
|
||||
// error tests
|
||||
for _, testcase := range []struct {
|
||||
name string
|
||||
chownStr string
|
||||
idMapping *idtools.IDMappings
|
||||
descr string
|
||||
}{
|
||||
{
|
||||
name: "BadChownFlagFormat",
|
||||
chownStr: "bob:1:555",
|
||||
idMapping: unmapped,
|
||||
descr: "invalid chown string format: bob:1:555",
|
||||
},
|
||||
{
|
||||
name: "UserNoExist",
|
||||
chownStr: "bob",
|
||||
idMapping: unmapped,
|
||||
descr: "can't find uid for user bob: no such user: bob",
|
||||
},
|
||||
{
|
||||
name: "GroupNoExist",
|
||||
chownStr: "root:bob",
|
||||
idMapping: unmapped,
|
||||
descr: "can't find gid for group bob: no such group: bob",
|
||||
},
|
||||
} {
|
||||
t.Run(testcase.name, func(t *testing.T) {
|
||||
_, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping)
|
||||
assert.EqualError(t, err, testcase.descr, "Expected error string doesn't match")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
package dockerfile
|
||||
|
||||
import "github.com/docker/docker/pkg/idtools"
|
||||
|
||||
func parseChownFlag(chown, ctrRootPath string, idMappings *idtools.IDMappings) (idtools.IDPair, error) {
|
||||
return idMappings.RootPair(), nil
|
||||
}
|
||||
@ -67,7 +67,7 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
|
||||
|
||||
flags.StringVar(&conf.MetricsAddress, "metrics-addr", "", "Set default address and port to serve the metrics api on")
|
||||
|
||||
flags.Var(opts.NewListOptsRef(&conf.NodeGenericResources, opts.ValidateSingleGenericResource), "node-generic-resource", "Advertise user-defined resource")
|
||||
flags.Var(opts.NewNamedListOptsRef("node-generic-resources", &conf.NodeGenericResources, opts.ValidateSingleGenericResource), "node-generic-resource", "Advertise user-defined resource")
|
||||
|
||||
flags.IntVar(&conf.NetworkControlPlaneMTU, "network-control-plane-mtu", config.DefaultNetworkMtu, "Network Control plane MTU")
|
||||
|
||||
@ -92,6 +92,8 @@ func installRegistryServiceFlags(options *registry.ServiceOptions, flags *pflag.
|
||||
flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication")
|
||||
|
||||
if runtime.GOOS != "windows" {
|
||||
// TODO: Remove this flag after 3 release cycles (18.03)
|
||||
flags.BoolVar(&options.V2Only, "disable-legacy-registry", true, "Disable contacting legacy registries")
|
||||
flags.MarkHidden("disable-legacy-registry")
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -472,8 +473,15 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !conf.V2Only {
|
||||
logrus.Warnf(`The "disable-legacy-registry" option is deprecated and wil be removed in Docker v17.12. Interacting with legacy (v1) registries will no longer be supported in Docker v17.12"`)
|
||||
if runtime.GOOS != "windows" {
|
||||
if flags.Changed("disable-legacy-registry") {
|
||||
// TODO: Remove this error after 3 release cycles (18.03)
|
||||
return nil, errors.New("ERROR: The '--disable-legacy-registry' flag has been removed. Interacting with legacy (v1) registries is no longer supported")
|
||||
}
|
||||
if !conf.V2Only {
|
||||
// TODO: Remove this error after 3 release cycles (18.03)
|
||||
return nil, errors.New("ERROR: The 'disable-legacy-registry' configuration option has been removed. Interacting with legacy (v1) registries is no longer supported")
|
||||
}
|
||||
}
|
||||
|
||||
if flags.Changed("graph") {
|
||||
|
||||
@ -61,6 +61,22 @@ func TestLoadDaemonCliConfigWithConflicts(t *testing.T) {
|
||||
testutil.ErrorContains(t, err, "as a flag and in the configuration file: labels")
|
||||
}
|
||||
|
||||
func TestLoadDaemonCliWithConflictingNodeGenericResources(t *testing.T) {
|
||||
tempFile := fs.NewFile(t, "config", fs.WithContent(`{"node-generic-resources": ["foo=bar", "bar=baz"]}`))
|
||||
defer tempFile.Remove()
|
||||
configFile := tempFile.Path()
|
||||
|
||||
opts := defaultOptions(configFile)
|
||||
flags := opts.flags
|
||||
|
||||
assert.NoError(t, flags.Set("config-file", configFile))
|
||||
assert.NoError(t, flags.Set("node-generic-resource", "r1=bar"))
|
||||
assert.NoError(t, flags.Set("node-generic-resource", "r2=baz"))
|
||||
|
||||
_, err := loadDaemonCliConfig(opts)
|
||||
testutil.ErrorContains(t, err, "as a flag and in the configuration file: node-generic-resources")
|
||||
}
|
||||
|
||||
func TestLoadDaemonCliWithConflictingLabels(t *testing.T) {
|
||||
opts := defaultOptions("")
|
||||
flags := opts.flags
|
||||
|
||||
@ -97,15 +97,3 @@ func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) {
|
||||
|
||||
assert.True(t, loadedConfig.EnableUserlandProxy)
|
||||
}
|
||||
|
||||
func TestLoadDaemonConfigWithLegacyRegistryOptions(t *testing.T) {
|
||||
content := `{"disable-legacy-registry": false}`
|
||||
tempFile := fs.NewFile(t, "config", fs.WithContent(content))
|
||||
defer tempFile.Remove()
|
||||
|
||||
opts := defaultOptions(tempFile.Path())
|
||||
loadedConfig, err := loadDaemonCliConfig(opts)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, loadedConfig)
|
||||
assert.False(t, loadedConfig.V2Only)
|
||||
}
|
||||
|
||||
@ -1,18 +1,5 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
_ "github.com/docker/docker/autogen/winresources/dockerd"
|
||||
)
|
||||
|
||||
//go:cgo_import_dynamic main.dummy CommandLineToArgvW%2 "shell32.dll"
|
||||
|
||||
var dummy uintptr
|
||||
|
||||
func init() {
|
||||
// Ensure that this import is not removed by the linker. This is used to
|
||||
// ensure that shell32.dll is loaded by the system loader, preventing
|
||||
// go#15286 from triggering on Nano Server TP5.
|
||||
atomic.LoadUintptr(&dummy)
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ FROM aarch64/debian:jessie
|
||||
RUN echo deb http://ftp.debian.org/debian jessie-backports main > /etc/apt/sources.list.d/backports.list
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev libseccomp-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM aarch64/debian:stretch
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-dev libseccomp-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM aarch64/ubuntu:trusty
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM aarch64/ubuntu:xenial
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-dev libseccomp-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list.d
|
||||
RUN apt-get update && apt-get install -y -t wheezy-backports btrfs-tools --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM ubuntu:trusty
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM ubuntu:xenial
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM ubuntu:yakkety
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM ubuntu:zesty
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
# GOARM is the ARM architecture version which is unrelated to the above Golang version
|
||||
ENV GOARM 6
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
|
||||
|
||||
@ -6,7 +6,7 @@ FROM armhf/ubuntu:trusty
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM armhf/ubuntu:xenial
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM armhf/ubuntu:yakkety
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM ppc64le/ubuntu:trusty
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM ppc64le/ubuntu:xenial
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libseccomp-dev libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM ppc64le/ubuntu:yakkety
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libseccomp-dev libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM s390x/ubuntu:xenial
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config libsystemd-dev vim-common --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ FROM s390x/ubuntu:yakkety
|
||||
|
||||
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config libsystemd-dev vim-common --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ FROM amazonlinux:latest
|
||||
RUN yum groupinstall -y "Development Tools"
|
||||
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel tar git cmake vim-common
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -8,7 +8,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 libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ RUN dnf -y upgrade
|
||||
RUN dnf install -y @development-tools fedora-packager
|
||||
RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ RUN dnf -y upgrade
|
||||
RUN dnf install -y @development-tools fedora-packager
|
||||
RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -7,7 +7,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 pkg-config selinux-policy selinux-policy-devel systemd-devel tar git cmake vim systemd-rpm-macros
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ RUN yum install -y kernel-uek-devel-4.1.12-32.el6uek
|
||||
RUN yum groupinstall -y "Development Tools"
|
||||
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel pkgconfig selinux-policy selinux-policy-devel tar git cmake vim-common
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -7,7 +7,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 libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ FROM photon:1.0
|
||||
RUN tdnf install -y wget curl ca-certificates gzip make rpm-build sed gcc linux-api-headers glibc-devel binutils libseccomp elfutils
|
||||
RUN tdnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkg-config selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ RUN yum groupinstall --skip-broken -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 libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -8,7 +8,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 libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ RUN dnf -y upgrade
|
||||
RUN dnf install -y @development-tools fedora-packager
|
||||
RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ RUN zypper addrepo -n ppc64le-updates -f https://download.opensuse.org/ports/upd
|
||||
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 pkg-config selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ FROM sinenomine/clefos-base-s390x
|
||||
RUN touch /var/lib/rpm/* && yum groupinstall -y "Development Tools"
|
||||
RUN touch /var/lib/rpm/* && yum install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ RUN zypper ar https://download.opensuse.org/ports/zsystems/tumbleweed/repo/oss/
|
||||
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 pkg-config selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim systemd-rpm-macros
|
||||
|
||||
ENV GO_VERSION 1.9.2
|
||||
ENV GO_VERSION 1.9.4
|
||||
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" | tar xzC /usr/local
|
||||
ENV PATH $PATH:/usr/local/go/bin
|
||||
|
||||
|
||||
@ -146,6 +146,11 @@ func (e *executor) Configure(ctx context.Context, node *api.Node) error {
|
||||
attachments[na.Network.ID] = na.Addresses[0]
|
||||
}
|
||||
|
||||
if (ingressNA == nil) && (node.Attachment != nil) {
|
||||
ingressNA = node.Attachment
|
||||
attachments[ingressNA.Network.ID] = ingressNA.Addresses[0]
|
||||
}
|
||||
|
||||
if ingressNA == nil {
|
||||
e.backend.ReleaseIngress()
|
||||
return e.backend.GetAttachmentStore().ResetAttachments(attachments)
|
||||
|
||||
@ -62,8 +62,8 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// MainNamespace is the name of the namespace used for users containers
|
||||
const MainNamespace = "moby"
|
||||
// ContainersNamespace is the name of the namespace used for users containers
|
||||
const ContainersNamespace = "moby"
|
||||
|
||||
var (
|
||||
errSystemNotSupported = errors.New("the Docker daemon is not supported on this platform")
|
||||
@ -247,6 +247,11 @@ func (daemon *Daemon) restore() error {
|
||||
logrus.WithError(err).Errorf("Failed to delete container %s from containerd", c.ID)
|
||||
return
|
||||
}
|
||||
} else if !daemon.configStore.LiveRestoreEnabled {
|
||||
if err := daemon.kill(c, c.StopSignal()); err != nil && !errdefs.IsNotFound(err) {
|
||||
logrus.WithError(err).WithField("container", c.ID).Error("error shutting down container")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if c.IsRunning() || c.IsPaused() {
|
||||
@ -317,24 +322,24 @@ func (daemon *Daemon) restore() error {
|
||||
activeSandboxes[c.NetworkSettings.SandboxID] = options
|
||||
mapLock.Unlock()
|
||||
}
|
||||
} else {
|
||||
// get list of containers we need to restart
|
||||
}
|
||||
|
||||
// Do not autostart containers which
|
||||
// has endpoints in a swarm scope
|
||||
// network yet since the cluster is
|
||||
// not initialized yet. We will start
|
||||
// it after the cluster is
|
||||
// initialized.
|
||||
if daemon.configStore.AutoRestart && c.ShouldRestart() && !c.NetworkSettings.HasSwarmEndpoint {
|
||||
mapLock.Lock()
|
||||
restartContainers[c] = make(chan struct{})
|
||||
mapLock.Unlock()
|
||||
} else if c.HostConfig != nil && c.HostConfig.AutoRemove {
|
||||
mapLock.Lock()
|
||||
removeContainers[c.ID] = c
|
||||
mapLock.Unlock()
|
||||
}
|
||||
// get list of containers we need to restart
|
||||
|
||||
// Do not autostart containers which
|
||||
// has endpoints in a swarm scope
|
||||
// network yet since the cluster is
|
||||
// not initialized yet. We will start
|
||||
// it after the cluster is
|
||||
// initialized.
|
||||
if daemon.configStore.AutoRestart && c.ShouldRestart() && !c.NetworkSettings.HasSwarmEndpoint {
|
||||
mapLock.Lock()
|
||||
restartContainers[c] = make(chan struct{})
|
||||
mapLock.Unlock()
|
||||
} else if c.HostConfig != nil && c.HostConfig.AutoRemove {
|
||||
mapLock.Lock()
|
||||
removeContainers[c.ID] = c
|
||||
mapLock.Unlock()
|
||||
}
|
||||
|
||||
c.Lock()
|
||||
@ -890,7 +895,7 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
|
||||
|
||||
go d.execCommandGC()
|
||||
|
||||
d.containerd, err = containerdRemote.NewClient(MainNamespace, d)
|
||||
d.containerd, err = containerdRemote.NewClient(ContainersNamespace, d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -350,11 +350,17 @@ func makeBackingFsDev(home string) (string, error) {
|
||||
backingFsBlockDev := path.Join(home, "backingFsBlockDev")
|
||||
// Re-create just in case someone copied the home directory over to a new device
|
||||
unix.Unlink(backingFsBlockDev)
|
||||
if err := unix.Mknod(backingFsBlockDev, unix.S_IFBLK|0600, int(stat.Dev)); err != nil {
|
||||
err := unix.Mknod(backingFsBlockDev, unix.S_IFBLK|0600, int(stat.Dev))
|
||||
switch err {
|
||||
case nil:
|
||||
return backingFsBlockDev, nil
|
||||
|
||||
case unix.ENOSYS:
|
||||
return "", ErrQuotaNotSupported
|
||||
|
||||
default:
|
||||
return "", fmt.Errorf("Failed to mknod %s: %v", backingFsBlockDev, err)
|
||||
}
|
||||
|
||||
return backingFsBlockDev, nil
|
||||
}
|
||||
|
||||
func hasQuotaSupport(backingFsBlockDev string) (bool, error) {
|
||||
|
||||
@ -35,9 +35,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := setupDriverQuota(d); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
setupDriverQuota(d)
|
||||
|
||||
return graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps), nil
|
||||
}
|
||||
|
||||
@ -2,20 +2,21 @@
|
||||
|
||||
package vfs
|
||||
|
||||
import "github.com/docker/docker/daemon/graphdriver/quota"
|
||||
import (
|
||||
"github.com/docker/docker/daemon/graphdriver/quota"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type driverQuota struct {
|
||||
quotaCtl *quota.Control
|
||||
}
|
||||
|
||||
func setupDriverQuota(driver *Driver) error {
|
||||
func setupDriverQuota(driver *Driver) {
|
||||
if quotaCtl, err := quota.NewControl(driver.home); err == nil {
|
||||
driver.quotaCtl = quotaCtl
|
||||
} else if err != quota.ErrQuotaNotSupported {
|
||||
return err
|
||||
logrus.Warnf("Unable to setup quota: %v\n", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Driver) setupQuota(dir string, size uint64) error {
|
||||
|
||||
@ -80,6 +80,7 @@ func (p *cmdProbe) run(ctx context.Context, d *Daemon, cntr *container.Container
|
||||
execConfig.Tty = false
|
||||
execConfig.Privileged = false
|
||||
execConfig.User = cntr.Config.User
|
||||
execConfig.WorkingDir = cntr.Config.WorkingDir
|
||||
|
||||
linkedEnv, err := d.setupLinkedContainers(cntr)
|
||||
if err != nil {
|
||||
|
||||
@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
)
|
||||
|
||||
// errImageDoesNotExist is error returned when no image can be found for a reference.
|
||||
@ -59,21 +58,6 @@ func (daemon *Daemon) GetImageIDAndOS(refOrID string) (image.ID, string, error)
|
||||
return id, imageOS, nil
|
||||
}
|
||||
|
||||
// deprecated: repo:shortid https://github.com/docker/docker/pull/799
|
||||
if tagged, ok := namedRef.(reference.Tagged); ok {
|
||||
if tag := tagged.Tag(); stringid.IsShortID(stringid.TruncateID(tag)) {
|
||||
for platform := range daemon.stores {
|
||||
if id, err := daemon.stores[platform].imageStore.Search(tag); err == nil {
|
||||
for _, storeRef := range daemon.referenceStore.References(id.Digest()) {
|
||||
if storeRef.Name() == namedRef.Name() {
|
||||
return id, platform, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search based on ID
|
||||
for os := range daemon.stores {
|
||||
if id, err := daemon.stores[os].imageStore.Search(refOrID); err == nil {
|
||||
|
||||
@ -4,10 +4,10 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/errdefs"
|
||||
containerpkg "github.com/docker/docker/container"
|
||||
"github.com/docker/docker/libcontainerd"
|
||||
"github.com/docker/docker/pkg/signal"
|
||||
@ -97,15 +97,11 @@ func (daemon *Daemon) killWithSignal(container *containerpkg.Container, sig int)
|
||||
}
|
||||
|
||||
if err := daemon.kill(container, sig); err != nil {
|
||||
err = errors.Wrapf(err, "Cannot kill container %s", container.ID)
|
||||
// if container or process not exists, ignore the error
|
||||
// TODO: we shouldn't have to parse error strings from containerd
|
||||
if strings.Contains(err.Error(), "container not found") ||
|
||||
strings.Contains(err.Error(), "no such process") {
|
||||
logrus.Warnf("container kill failed because of 'container not found' or 'no such process': %s", err.Error())
|
||||
if errdefs.IsNotFound(err) {
|
||||
unpause = false
|
||||
logrus.WithError(err).WithField("container", container.ID).WithField("action", "kill").Debug("container kill failed because of 'container not found' or 'no such process'")
|
||||
} else {
|
||||
return err
|
||||
return errors.Wrapf(err, "Cannot kill container %s", container.ID)
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,7 +167,7 @@ func (daemon *Daemon) Kill(container *containerpkg.Container) error {
|
||||
// killPossibleDeadProcess is a wrapper around killSig() suppressing "no such process" error.
|
||||
func (daemon *Daemon) killPossiblyDeadProcess(container *containerpkg.Container, sig int) error {
|
||||
err := daemon.killWithSignal(container, sig)
|
||||
if err == syscall.ESRCH {
|
||||
if errdefs.IsNotFound(err) {
|
||||
e := errNoSuchProcess{container.GetPID(), sig}
|
||||
logrus.Debug(e)
|
||||
return e
|
||||
|
||||
@ -95,6 +95,17 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// eventBatch holds the events that are batched for submission and the
|
||||
// associated data about it.
|
||||
//
|
||||
// Warning: this type is not threadsafe and must not be used
|
||||
// concurrently. This type is expected to be consumed in a single go
|
||||
// routine and never concurrently.
|
||||
type eventBatch struct {
|
||||
batch []wrappedEvent
|
||||
bytes int
|
||||
}
|
||||
|
||||
// New creates an awslogs logger using the configuration passed in on the
|
||||
// context. Supported context configuration variables are awslogs-region,
|
||||
// awslogs-group, awslogs-stream, awslogs-create-group, awslogs-multiline-pattern
|
||||
@ -389,32 +400,32 @@ var newTicker = func(freq time.Duration) *time.Ticker {
|
||||
// Logs, the processEvents method is called. If a multiline pattern is not
|
||||
// configured, log events are submitted to the processEvents method immediately.
|
||||
func (l *logStream) collectBatch() {
|
||||
timer := newTicker(batchPublishFrequency)
|
||||
var events []wrappedEvent
|
||||
ticker := newTicker(batchPublishFrequency)
|
||||
var eventBuffer []byte
|
||||
var eventBufferTimestamp int64
|
||||
var batch = newEventBatch()
|
||||
for {
|
||||
select {
|
||||
case t := <-timer.C:
|
||||
case t := <-ticker.C:
|
||||
// If event buffer is older than batch publish frequency flush the event buffer
|
||||
if eventBufferTimestamp > 0 && len(eventBuffer) > 0 {
|
||||
eventBufferAge := t.UnixNano()/int64(time.Millisecond) - eventBufferTimestamp
|
||||
eventBufferExpired := eventBufferAge > int64(batchPublishFrequency)/int64(time.Millisecond)
|
||||
eventBufferNegative := eventBufferAge < 0
|
||||
if eventBufferExpired || eventBufferNegative {
|
||||
events = l.processEvent(events, eventBuffer, eventBufferTimestamp)
|
||||
l.processEvent(batch, eventBuffer, eventBufferTimestamp)
|
||||
eventBuffer = eventBuffer[:0]
|
||||
}
|
||||
}
|
||||
l.publishBatch(events)
|
||||
events = events[:0]
|
||||
l.publishBatch(batch)
|
||||
batch.reset()
|
||||
case msg, more := <-l.messages:
|
||||
if !more {
|
||||
// Flush event buffer and release resources
|
||||
events = l.processEvent(events, eventBuffer, eventBufferTimestamp)
|
||||
l.processEvent(batch, eventBuffer, eventBufferTimestamp)
|
||||
eventBuffer = eventBuffer[:0]
|
||||
l.publishBatch(events)
|
||||
events = events[:0]
|
||||
l.publishBatch(batch)
|
||||
batch.reset()
|
||||
return
|
||||
}
|
||||
if eventBufferTimestamp == 0 {
|
||||
@ -425,7 +436,7 @@ func (l *logStream) collectBatch() {
|
||||
if l.multilinePattern.Match(unprocessedLine) || len(eventBuffer)+len(unprocessedLine) > maximumBytesPerEvent {
|
||||
// This is a new log event or we will exceed max bytes per event
|
||||
// so flush the current eventBuffer to events and reset timestamp
|
||||
events = l.processEvent(events, eventBuffer, eventBufferTimestamp)
|
||||
l.processEvent(batch, eventBuffer, eventBufferTimestamp)
|
||||
eventBufferTimestamp = msg.Timestamp.UnixNano() / int64(time.Millisecond)
|
||||
eventBuffer = eventBuffer[:0]
|
||||
}
|
||||
@ -434,7 +445,7 @@ func (l *logStream) collectBatch() {
|
||||
eventBuffer = append(eventBuffer, processedLine...)
|
||||
logger.PutMessage(msg)
|
||||
} else {
|
||||
events = l.processEvent(events, unprocessedLine, msg.Timestamp.UnixNano()/int64(time.Millisecond))
|
||||
l.processEvent(batch, unprocessedLine, msg.Timestamp.UnixNano()/int64(time.Millisecond))
|
||||
logger.PutMessage(msg)
|
||||
}
|
||||
}
|
||||
@ -450,8 +461,7 @@ func (l *logStream) collectBatch() {
|
||||
// bytes per event (defined in maximumBytesPerEvent). There is a fixed per-event
|
||||
// byte overhead (defined in perEventBytes) which is accounted for in split- and
|
||||
// batch-calculations.
|
||||
func (l *logStream) processEvent(events []wrappedEvent, unprocessedLine []byte, timestamp int64) []wrappedEvent {
|
||||
bytes := 0
|
||||
func (l *logStream) processEvent(batch *eventBatch, unprocessedLine []byte, timestamp int64) {
|
||||
for len(unprocessedLine) > 0 {
|
||||
// Split line length so it does not exceed the maximum
|
||||
lineBytes := len(unprocessedLine)
|
||||
@ -459,38 +469,33 @@ func (l *logStream) processEvent(events []wrappedEvent, unprocessedLine []byte,
|
||||
lineBytes = maximumBytesPerEvent
|
||||
}
|
||||
line := unprocessedLine[:lineBytes]
|
||||
unprocessedLine = unprocessedLine[lineBytes:]
|
||||
if (len(events) >= maximumLogEventsPerPut) || (bytes+lineBytes+perEventBytes > maximumBytesPerPut) {
|
||||
// Publish an existing batch if it's already over the maximum number of events or if adding this
|
||||
// event would push it over the maximum number of total bytes.
|
||||
l.publishBatch(events)
|
||||
events = events[:0]
|
||||
bytes = 0
|
||||
}
|
||||
events = append(events, wrappedEvent{
|
||||
|
||||
event := wrappedEvent{
|
||||
inputLogEvent: &cloudwatchlogs.InputLogEvent{
|
||||
Message: aws.String(string(line)),
|
||||
Timestamp: aws.Int64(timestamp),
|
||||
},
|
||||
insertOrder: len(events),
|
||||
})
|
||||
bytes += (lineBytes + perEventBytes)
|
||||
insertOrder: batch.count(),
|
||||
}
|
||||
|
||||
added := batch.add(event, lineBytes)
|
||||
if added {
|
||||
unprocessedLine = unprocessedLine[lineBytes:]
|
||||
} else {
|
||||
l.publishBatch(batch)
|
||||
batch.reset()
|
||||
}
|
||||
}
|
||||
return events
|
||||
}
|
||||
|
||||
// publishBatch calls PutLogEvents for a given set of InputLogEvents,
|
||||
// accounting for sequencing requirements (each request must reference the
|
||||
// sequence token returned by the previous request).
|
||||
func (l *logStream) publishBatch(events []wrappedEvent) {
|
||||
if len(events) == 0 {
|
||||
func (l *logStream) publishBatch(batch *eventBatch) {
|
||||
if batch.isEmpty() {
|
||||
return
|
||||
}
|
||||
|
||||
// events in a batch must be sorted by timestamp
|
||||
// see http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html
|
||||
sort.Sort(byTimestamp(events))
|
||||
cwEvents := unwrapEvents(events)
|
||||
cwEvents := unwrapEvents(batch.events())
|
||||
|
||||
nextSequenceToken, err := l.putLogEvents(cwEvents, l.sequenceToken)
|
||||
|
||||
@ -615,3 +620,70 @@ func unwrapEvents(events []wrappedEvent) []*cloudwatchlogs.InputLogEvent {
|
||||
}
|
||||
return cwEvents
|
||||
}
|
||||
|
||||
func newEventBatch() *eventBatch {
|
||||
return &eventBatch{
|
||||
batch: make([]wrappedEvent, 0),
|
||||
bytes: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// events returns a slice of wrappedEvents sorted in order of their
|
||||
// timestamps and then by their insertion order (see `byTimestamp`).
|
||||
//
|
||||
// Warning: this method is not threadsafe and must not be used
|
||||
// concurrently.
|
||||
func (b *eventBatch) events() []wrappedEvent {
|
||||
sort.Sort(byTimestamp(b.batch))
|
||||
return b.batch
|
||||
}
|
||||
|
||||
// add adds an event to the batch of events accounting for the
|
||||
// necessary overhead for an event to be logged. An error will be
|
||||
// returned if the event cannot be added to the batch due to service
|
||||
// limits.
|
||||
//
|
||||
// Warning: this method is not threadsafe and must not be used
|
||||
// concurrently.
|
||||
func (b *eventBatch) add(event wrappedEvent, size int) bool {
|
||||
addBytes := size + perEventBytes
|
||||
|
||||
// verify we are still within service limits
|
||||
switch {
|
||||
case len(b.batch)+1 > maximumLogEventsPerPut:
|
||||
return false
|
||||
case b.bytes+addBytes > maximumBytesPerPut:
|
||||
return false
|
||||
}
|
||||
|
||||
b.bytes += addBytes
|
||||
b.batch = append(b.batch, event)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// count is the number of batched events. Warning: this method
|
||||
// is not threadsafe and must not be used concurrently.
|
||||
func (b *eventBatch) count() int {
|
||||
return len(b.batch)
|
||||
}
|
||||
|
||||
// size is the total number of bytes that the batch represents.
|
||||
//
|
||||
// Warning: this method is not threadsafe and must not be used
|
||||
// concurrently.
|
||||
func (b *eventBatch) size() int {
|
||||
return b.bytes
|
||||
}
|
||||
|
||||
func (b *eventBatch) isEmpty() bool {
|
||||
zeroEvents := b.count() == 0
|
||||
zeroSize := b.size() == 0
|
||||
return zeroEvents && zeroSize
|
||||
}
|
||||
|
||||
// reset prepares the batch for reuse.
|
||||
func (b *eventBatch) reset() {
|
||||
b.bytes = 0
|
||||
b.batch = b.batch[:0]
|
||||
}
|
||||
|
||||
@ -49,6 +49,15 @@ func (l *logStream) logGenerator(lineCount int, multilineCount int) {
|
||||
}
|
||||
}
|
||||
|
||||
func testEventBatch(events []wrappedEvent) *eventBatch {
|
||||
batch := newEventBatch()
|
||||
for _, event := range events {
|
||||
eventlen := len([]byte(*event.inputLogEvent.Message))
|
||||
batch.add(event, eventlen)
|
||||
}
|
||||
return batch
|
||||
}
|
||||
|
||||
func TestNewAWSLogsClientUserAgentHandler(t *testing.T) {
|
||||
info := logger.Info{
|
||||
Config: map[string]string{
|
||||
@ -212,7 +221,7 @@ func TestPublishBatchSuccess(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
stream.publishBatch(events)
|
||||
stream.publishBatch(testEventBatch(events))
|
||||
if stream.sequenceToken == nil {
|
||||
t.Fatal("Expected non-nil sequenceToken")
|
||||
}
|
||||
@ -257,7 +266,7 @@ func TestPublishBatchError(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
stream.publishBatch(events)
|
||||
stream.publishBatch(testEventBatch(events))
|
||||
if stream.sequenceToken == nil {
|
||||
t.Fatal("Expected non-nil sequenceToken")
|
||||
}
|
||||
@ -291,7 +300,7 @@ func TestPublishBatchInvalidSeqSuccess(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
stream.publishBatch(events)
|
||||
stream.publishBatch(testEventBatch(events))
|
||||
if stream.sequenceToken == nil {
|
||||
t.Fatal("Expected non-nil sequenceToken")
|
||||
}
|
||||
@ -354,7 +363,7 @@ func TestPublishBatchAlreadyAccepted(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
stream.publishBatch(events)
|
||||
stream.publishBatch(testEventBatch(events))
|
||||
if stream.sequenceToken == nil {
|
||||
t.Fatal("Expected non-nil sequenceToken")
|
||||
}
|
||||
@ -859,7 +868,8 @@ func TestCollectBatchMaxEvents(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCollectBatchMaxTotalBytes(t *testing.T) {
|
||||
mockClient := newMockClientBuffered(1)
|
||||
expectedPuts := 2
|
||||
mockClient := newMockClientBuffered(expectedPuts)
|
||||
stream := &logStream{
|
||||
client: mockClient,
|
||||
logGroupName: groupName,
|
||||
@ -867,11 +877,14 @@ func TestCollectBatchMaxTotalBytes(t *testing.T) {
|
||||
sequenceToken: aws.String(sequenceToken),
|
||||
messages: make(chan *logger.Message),
|
||||
}
|
||||
mockClient.putLogEventsResult <- &putLogEventsResult{
|
||||
successResult: &cloudwatchlogs.PutLogEventsOutput{
|
||||
NextSequenceToken: aws.String(nextSequenceToken),
|
||||
},
|
||||
for i := 0; i < expectedPuts; i++ {
|
||||
mockClient.putLogEventsResult <- &putLogEventsResult{
|
||||
successResult: &cloudwatchlogs.PutLogEventsOutput{
|
||||
NextSequenceToken: aws.String(nextSequenceToken),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
var ticks = make(chan time.Time)
|
||||
newTicker = func(_ time.Duration) *time.Ticker {
|
||||
return &time.Ticker{
|
||||
@ -881,32 +894,57 @@ func TestCollectBatchMaxTotalBytes(t *testing.T) {
|
||||
|
||||
go stream.collectBatch()
|
||||
|
||||
longline := strings.Repeat("A", maximumBytesPerPut)
|
||||
numPayloads := maximumBytesPerPut / (maximumBytesPerEvent + perEventBytes)
|
||||
// maxline is the maximum line that could be submitted after
|
||||
// accounting for its overhead.
|
||||
maxline := strings.Repeat("A", maximumBytesPerPut-(perEventBytes*numPayloads))
|
||||
// This will be split and batched up to the `maximumBytesPerPut'
|
||||
// (+/- `maximumBytesPerEvent'). This /should/ be aligned, but
|
||||
// should also tolerate an offset within that range.
|
||||
stream.Log(&logger.Message{
|
||||
Line: []byte(longline + "B"),
|
||||
Line: []byte(maxline[:len(maxline)/2]),
|
||||
Timestamp: time.Time{},
|
||||
})
|
||||
stream.Log(&logger.Message{
|
||||
Line: []byte(maxline[len(maxline)/2:]),
|
||||
Timestamp: time.Time{},
|
||||
})
|
||||
stream.Log(&logger.Message{
|
||||
Line: []byte("B"),
|
||||
Timestamp: time.Time{},
|
||||
})
|
||||
|
||||
// no ticks
|
||||
// no ticks, guarantee batch by size (and chan close)
|
||||
stream.Close()
|
||||
|
||||
argument := <-mockClient.putLogEventsArgument
|
||||
if argument == nil {
|
||||
t.Fatal("Expected non-nil PutLogEventsInput")
|
||||
}
|
||||
bytes := 0
|
||||
|
||||
// Should total to the maximum allowed bytes.
|
||||
eventBytes := 0
|
||||
for _, event := range argument.LogEvents {
|
||||
bytes += len(*event.Message)
|
||||
eventBytes += len(*event.Message)
|
||||
}
|
||||
if bytes > maximumBytesPerPut {
|
||||
t.Errorf("Expected <= %d bytes but was %d", maximumBytesPerPut, bytes)
|
||||
eventsOverhead := len(argument.LogEvents) * perEventBytes
|
||||
payloadTotal := eventBytes + eventsOverhead
|
||||
// lowestMaxBatch allows the payload to be offset if the messages
|
||||
// don't lend themselves to align with the maximum event size.
|
||||
lowestMaxBatch := maximumBytesPerPut - maximumBytesPerEvent
|
||||
|
||||
if payloadTotal > maximumBytesPerPut {
|
||||
t.Errorf("Expected <= %d bytes but was %d", maximumBytesPerPut, payloadTotal)
|
||||
}
|
||||
if payloadTotal < lowestMaxBatch {
|
||||
t.Errorf("Batch to be no less than %d but was %d", lowestMaxBatch, payloadTotal)
|
||||
}
|
||||
|
||||
argument = <-mockClient.putLogEventsArgument
|
||||
if len(argument.LogEvents) != 1 {
|
||||
t.Errorf("Expected LogEvents to contain 1 elements, but contains %d", len(argument.LogEvents))
|
||||
}
|
||||
message := *argument.LogEvents[0].Message
|
||||
message := *argument.LogEvents[len(argument.LogEvents)-1].Message
|
||||
if message[len(message)-1:] != "B" {
|
||||
t.Errorf("Expected message to be %s but was %s", "B", message[len(message)-1:])
|
||||
}
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
package awslogs
|
||||
|
||||
import "github.com/aws/aws-sdk-go/service/cloudwatchlogs"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
|
||||
)
|
||||
|
||||
type mockcwlogsclient struct {
|
||||
createLogGroupArgument chan *cloudwatchlogs.CreateLogGroupInput
|
||||
@ -67,7 +71,30 @@ func (m *mockcwlogsclient) PutLogEvents(input *cloudwatchlogs.PutLogEventsInput)
|
||||
LogGroupName: input.LogGroupName,
|
||||
LogStreamName: input.LogStreamName,
|
||||
}
|
||||
|
||||
// Intended mock output
|
||||
output := <-m.putLogEventsResult
|
||||
|
||||
// Checked enforced limits in mock
|
||||
totalBytes := 0
|
||||
for _, evt := range events {
|
||||
if evt.Message == nil {
|
||||
continue
|
||||
}
|
||||
eventBytes := len([]byte(*evt.Message))
|
||||
if eventBytes > maximumBytesPerEvent {
|
||||
// exceeded per event message size limits
|
||||
return nil, fmt.Errorf("maximum bytes per event exceeded: Event too large %d, max allowed: %d", eventBytes, maximumBytesPerEvent)
|
||||
}
|
||||
// total event bytes including overhead
|
||||
totalBytes += eventBytes + perEventBytes
|
||||
}
|
||||
|
||||
if totalBytes > maximumBytesPerPut {
|
||||
// exceeded per put maximum size limit
|
||||
return nil, fmt.Errorf("maximum bytes per put exceeded: Upload too large %d, max allowed: %d", totalBytes, maximumBytesPerPut)
|
||||
}
|
||||
|
||||
return output.successResult, output.errorResult
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +23,18 @@ keywords: "API, Docker, rcli, REST, documentation"
|
||||
configuration is only used for Windows containers.
|
||||
* `GET /containers/(name)/logs` now supports an additional query parameter: `until`,
|
||||
which returns log lines that occurred before the specified timestamp.
|
||||
* `POST /containers/{id}/exec` now accepts a `WorkingDir` property to set the
|
||||
work-dir for the exec process, independent of the container's work-dir.
|
||||
* `Get /version` now returns a `Platform.Name` field, which can be used by products
|
||||
using Moby as a foundation to return information about the platform.
|
||||
* `Get /version` now returns a `Components` field, which can be used to return
|
||||
information about the components used. Information about the engine itself is
|
||||
now included as a "Component" version, and contains all information from the
|
||||
top-level `Version`, `GitCommit`, `APIVersion`, `MinAPIVersion`, `GoVersion`,
|
||||
`Os`, `Arch`, `BuildTime`, `KernelVersion`, and `Experimental` fields. Going
|
||||
forward, the information from the `Components` section is preferred over their
|
||||
top-level counterparts.
|
||||
|
||||
|
||||
## v1.34 API changes
|
||||
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
TOMLV_COMMIT=9baf8a8a9f2ed20a8e54160840c492f937eeaf9a
|
||||
|
||||
# When updating RUNC_COMMIT, also update runc in vendor.conf accordingly
|
||||
RUNC_COMMIT=b2567b37d7b75eb4cf325b77297b140ea686ce8f
|
||||
CONTAINERD_COMMIT=v1.0.0
|
||||
RUNC_COMMIT=9f9c96235cc97674e935002fc3d78361b696a69e
|
||||
CONTAINERD_COMMIT=9b55aab90508bd389d7654c4baf173a981477d55 # v1.0.1
|
||||
TINI_COMMIT=949e6facb77383876aeff8a6944dde66b3089574
|
||||
LIBNETWORK_COMMIT=7b2b1feb1de4817d522cc372af149ff48d25028e
|
||||
VNDR_COMMIT=a6e196d8b4b0cbbdc29aebdb20c59ac6926bb384
|
||||
|
||||
@ -1,13 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/integration-cli/request"
|
||||
@ -48,25 +45,6 @@ func (s *DockerSuite) TestInfoAPI(c *check.C) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestInfoAPIRuncCommit tests that dockerd is able to obtain RunC version
|
||||
// information, and that the version matches the expected version
|
||||
func (s *DockerSuite) TestInfoAPIRuncCommit(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux) // Windows does not have RunC version information
|
||||
|
||||
res, body, err := request.Get("/v1.30/info")
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
b, err := request.ReadBody(body)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
var i types.Info
|
||||
|
||||
c.Assert(json.Unmarshal(b, &i), checker.IsNil)
|
||||
c.Assert(i.RuncCommit.ID, checker.Not(checker.Equals), "N/A")
|
||||
c.Assert(i.RuncCommit.ID, checker.Equals, i.RuncCommit.Expected)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestInfoAPIVersioned(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux) // Windows only supports 1.25 or later
|
||||
|
||||
|
||||
@ -4211,6 +4211,7 @@ func (s *DockerTrustSuite) TestBuildContextDirIsSymlink(c *check.C) {
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedBuildTagFromReleasesRole(c *check.C) {
|
||||
c.Skip("Blacklisting for Docker CE")
|
||||
testRequires(c, NotaryHosting)
|
||||
|
||||
latestTag := s.setupTrustedImage(c, "trusted-build-releases-role")
|
||||
@ -4242,6 +4243,7 @@ func (s *DockerTrustSuite) TestTrustedBuildTagFromReleasesRole(c *check.C) {
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedBuildTagIgnoresOtherDelegationRoles(c *check.C) {
|
||||
c.Skip("Blacklisting for Docker CE")
|
||||
testRequires(c, NotaryHosting)
|
||||
|
||||
latestTag := s.setupTrustedImage(c, "trusted-build-releases-role")
|
||||
|
||||
@ -268,7 +268,6 @@ func (s *DockerSuite) TestCreateByImageID(c *check.C) {
|
||||
|
||||
dockerCmd(c, "create", imageID)
|
||||
dockerCmd(c, "create", truncatedImageID)
|
||||
dockerCmd(c, "create", fmt.Sprintf("%s:%s", imageName, truncatedImageID))
|
||||
|
||||
// Ensure this fails
|
||||
out, exit, _ := dockerCmdWithError("create", fmt.Sprintf("%s:%s", imageName, imageID))
|
||||
@ -280,7 +279,10 @@ func (s *DockerSuite) TestCreateByImageID(c *check.C) {
|
||||
c.Fatalf(`Expected %q in output; got: %s`, expected, out)
|
||||
}
|
||||
|
||||
out, exit, _ = dockerCmdWithError("create", fmt.Sprintf("%s:%s", "wrongimage", truncatedImageID))
|
||||
if i := strings.IndexRune(imageID, ':'); i >= 0 {
|
||||
imageID = imageID[i+1:]
|
||||
}
|
||||
out, exit, _ = dockerCmdWithError("create", fmt.Sprintf("%s:%s", "wrongimage", imageID))
|
||||
if exit == 0 {
|
||||
c.Fatalf("expected non-zero exit code; received %d", exit)
|
||||
}
|
||||
|
||||
@ -1451,7 +1451,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonAndContainerKill(c *chec
|
||||
|
||||
// kill the container
|
||||
icmd.RunCommand(ctrBinary, "--address", "/var/run/docker/containerd/docker-containerd.sock",
|
||||
"--namespace", moby_daemon.MainNamespace, "tasks", "kill", id).Assert(c, icmd.Success)
|
||||
"--namespace", moby_daemon.ContainersNamespace, "tasks", "kill", id).Assert(c, icmd.Success)
|
||||
|
||||
// restart daemon.
|
||||
d.Restart(c)
|
||||
@ -2011,7 +2011,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithKilledRunningContainer(t *check
|
||||
|
||||
// kill the container
|
||||
icmd.RunCommand(ctrBinary, "--address", "/var/run/docker/containerd/docker-containerd.sock",
|
||||
"--namespace", moby_daemon.MainNamespace, "tasks", "kill", cid).Assert(t, icmd.Success)
|
||||
"--namespace", moby_daemon.ContainersNamespace, "tasks", "kill", cid).Assert(t, icmd.Success)
|
||||
|
||||
// Give time to containerd to process the command if we don't
|
||||
// the exit event might be received after we do the inspect
|
||||
@ -2106,7 +2106,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithUnpausedRunningContainer(t *che
|
||||
result := icmd.RunCommand(
|
||||
ctrBinary,
|
||||
"--address", "/var/run/docker/containerd/docker-containerd.sock",
|
||||
"--namespace", moby_daemon.MainNamespace,
|
||||
"--namespace", moby_daemon.ContainersNamespace,
|
||||
"tasks", "resume", cid)
|
||||
result.Assert(t, icmd.Success)
|
||||
|
||||
|
||||
@ -13,9 +13,7 @@ import (
|
||||
)
|
||||
|
||||
func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithExternalAuth(c *check.C) {
|
||||
|
||||
// @TODO TestLogoutWithExternalAuth expects docker to fall back to a v1 registry, so has to be updated for v17.12, when v1 registries are no longer supported
|
||||
s.d.StartWithBusybox(c, "--disable-legacy-registry=false")
|
||||
s.d.StartWithBusybox(c)
|
||||
|
||||
osPath := os.Getenv("PATH")
|
||||
defer os.Setenv("PATH", osPath)
|
||||
@ -62,7 +60,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithExternalAuth(c *check.C)
|
||||
// check I cannot pull anymore
|
||||
out, err := s.d.Cmd("--config", tmp, "pull", repoName)
|
||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
c.Assert(out, checker.Contains, "Error: image dockercli/busybox:authtest not found")
|
||||
c.Assert(out, checker.Contains, "no basic auth credentials")
|
||||
}
|
||||
|
||||
// #23100
|
||||
|
||||
@ -259,18 +259,6 @@ func (s *DockerHubPullSuite) TestPullClientDisconnect(c *check.C) {
|
||||
c.Assert(err, checker.NotNil, check.Commentf("image was pulled after client disconnected"))
|
||||
}
|
||||
|
||||
func (s *DockerRegistryAuthHtpasswdSuite) TestPullNoCredentialsNotFound(c *check.C) {
|
||||
// @TODO TestPullNoCredentialsNotFound expects docker to fall back to a v1 registry, so has to be updated for v17.12, when v1 registries are no longer supported
|
||||
s.d.StartWithBusybox(c, "--disable-legacy-registry=false")
|
||||
|
||||
// we don't care about the actual image, we just want to see image not found
|
||||
// because that means v2 call returned 401 and we fell back to v1 which usually
|
||||
// gives a 404 (in this case the test registry doesn't handle v1 at all)
|
||||
out, err := s.d.Cmd("pull", privateRegistryURL+"/busybox")
|
||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
c.Assert(out, checker.Contains, "Error: image busybox:latest not found")
|
||||
}
|
||||
|
||||
// Regression test for https://github.com/docker/docker/issues/26429
|
||||
func (s *DockerSuite) TestPullLinuxImageFailsOnWindows(c *check.C) {
|
||||
testRequires(c, DaemonIsWindows, Network)
|
||||
|
||||
@ -133,6 +133,7 @@ func (s *DockerTrustSuite) TestTrustedPullDelete(c *check.C) {
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPullReadsFromReleasesRole(c *check.C) {
|
||||
c.Skip("Blacklisting for Docker CE")
|
||||
testRequires(c, NotaryHosting)
|
||||
repoName := fmt.Sprintf("%v/dockerclireleasesdelegationpulling/trusted", privateRegistryURL)
|
||||
targetName := fmt.Sprintf("%s:latest", repoName)
|
||||
@ -188,6 +189,7 @@ func (s *DockerTrustSuite) TestTrustedPullReadsFromReleasesRole(c *check.C) {
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPullIgnoresOtherDelegationRoles(c *check.C) {
|
||||
c.Skip("Blacklisting for Docker CE")
|
||||
testRequires(c, NotaryHosting)
|
||||
repoName := fmt.Sprintf("%v/dockerclipullotherdelegation/trusted", privateRegistryURL)
|
||||
targetName := fmt.Sprintf("%s:latest", repoName)
|
||||
|
||||
@ -282,6 +282,7 @@ func (s *DockerSchema1RegistrySuite) TestCrossRepositoryLayerPushNotSupported(c
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPush(c *check.C) {
|
||||
c.Skip("Blacklisting for Docker CE")
|
||||
repoName := fmt.Sprintf("%v/dockerclitrusted/pushtest:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
cli.DockerCmd(c, "tag", "busybox", repoName)
|
||||
@ -366,6 +367,7 @@ func (s *DockerTrustSuite) TestTrustedPushWithExistingSignedTag(c *check.C) {
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPushWithIncorrectPassphraseForNonRoot(c *check.C) {
|
||||
c.Skip("Blacklisting for Docker CE")
|
||||
repoName := fmt.Sprintf("%v/dockercliincorretpwd/trusted:latest", privateRegistryURL)
|
||||
// tag the image and upload it to the private registry
|
||||
cli.DockerCmd(c, "tag", "busybox", repoName)
|
||||
|
||||
@ -36,7 +36,6 @@ import (
|
||||
"github.com/docker/libnetwork/types"
|
||||
"github.com/go-check/check"
|
||||
"github.com/gotestyourself/gotestyourself/icmd"
|
||||
libcontainerUser "github.com/opencontainers/runc/libcontainer/user"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
@ -751,7 +750,7 @@ func (s *DockerSuite) TestRunUserByIDBig(c *check.C) {
|
||||
if err == nil {
|
||||
c.Fatal("No error, but must be.", out)
|
||||
}
|
||||
if !strings.Contains(strings.ToUpper(out), strings.ToUpper(libcontainerUser.ErrRange.Error())) {
|
||||
if !strings.Contains(strings.ToLower(out), "uids and gids must be in range") {
|
||||
c.Fatalf("expected error about uids range, got %s", out)
|
||||
}
|
||||
}
|
||||
@ -764,7 +763,7 @@ func (s *DockerSuite) TestRunUserByIDNegative(c *check.C) {
|
||||
if err == nil {
|
||||
c.Fatal("No error, but must be.", out)
|
||||
}
|
||||
if !strings.Contains(strings.ToUpper(out), strings.ToUpper(libcontainerUser.ErrRange.Error())) {
|
||||
if !strings.Contains(strings.ToLower(out), "uids and gids must be in range") {
|
||||
c.Fatalf("expected error about uids range, got %s", out)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/integration-cli/cli/build"
|
||||
"github.com/docker/docker/internal/testutil"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
@ -140,29 +137,3 @@ func (s *DockerSuite) TestTagInvalidRepoName(c *check.C) {
|
||||
c.Fatal("tagging with image named \"sha256\" should have failed")
|
||||
}
|
||||
}
|
||||
|
||||
// ensure tags cannot create ambiguity with image ids
|
||||
func (s *DockerSuite) TestTagTruncationAmbiguity(c *check.C) {
|
||||
buildImageSuccessfully(c, "notbusybox:latest", build.WithDockerfile(`FROM busybox
|
||||
MAINTAINER dockerio`))
|
||||
imageID := getIDByName(c, "notbusybox:latest")
|
||||
truncatedImageID := stringid.TruncateID(imageID)
|
||||
truncatedTag := fmt.Sprintf("notbusybox:%s", truncatedImageID)
|
||||
|
||||
id := inspectField(c, truncatedTag, "Id")
|
||||
|
||||
// Ensure inspect by image id returns image for image id
|
||||
c.Assert(id, checker.Equals, imageID)
|
||||
c.Logf("Built image: %s", imageID)
|
||||
|
||||
// test setting tag fails
|
||||
_, _, err := dockerCmdWithError("tag", "busybox:latest", truncatedTag)
|
||||
if err != nil {
|
||||
c.Fatalf("Error tagging with an image id: %s", err)
|
||||
}
|
||||
|
||||
id = inspectField(c, truncatedTag, "Id")
|
||||
|
||||
// Ensure id is imageID and not busybox:latest
|
||||
c.Assert(id, checker.Not(checker.Equals), imageID)
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ func makefile(path string, contents string) (string, error) {
|
||||
return f.Name(), nil
|
||||
}
|
||||
|
||||
// TestV2Only ensures that a daemon by default does not
|
||||
// TestV2Only ensures that a daemon does not
|
||||
// attempt to contact any v1 registry endpoints.
|
||||
func (s *DockerRegistrySuite) TestV2Only(c *check.C) {
|
||||
reg, err := registry.NewMock(c)
|
||||
@ -56,65 +56,3 @@ func (s *DockerRegistrySuite) TestV2Only(c *check.C) {
|
||||
s.d.Cmd("push", repoName)
|
||||
s.d.Cmd("pull", repoName)
|
||||
}
|
||||
|
||||
// TestV1 starts a daemon with legacy registries enabled
|
||||
// and ensure v1 endpoints are hit for the following operations:
|
||||
// login, push, pull, build & run
|
||||
func (s *DockerRegistrySuite) TestV1(c *check.C) {
|
||||
reg, err := registry.NewMock(c)
|
||||
defer reg.Close()
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
v2Pings := 0
|
||||
reg.RegisterHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
|
||||
v2Pings++
|
||||
// V2 ping 404 causes fallback to v1
|
||||
w.WriteHeader(404)
|
||||
})
|
||||
|
||||
v1Pings := 0
|
||||
reg.RegisterHandler("/v1/_ping", func(w http.ResponseWriter, r *http.Request) {
|
||||
v1Pings++
|
||||
})
|
||||
|
||||
v1Logins := 0
|
||||
reg.RegisterHandler("/v1/users/", func(w http.ResponseWriter, r *http.Request) {
|
||||
v1Logins++
|
||||
})
|
||||
|
||||
v1Repo := 0
|
||||
reg.RegisterHandler("/v1/repositories/busybox/", func(w http.ResponseWriter, r *http.Request) {
|
||||
v1Repo++
|
||||
})
|
||||
|
||||
reg.RegisterHandler("/v1/repositories/busybox/images", func(w http.ResponseWriter, r *http.Request) {
|
||||
v1Repo++
|
||||
})
|
||||
|
||||
s.d.Start(c, "--insecure-registry", reg.URL(), "--disable-legacy-registry=false")
|
||||
|
||||
tmp, err := ioutil.TempDir("", "integration-cli-")
|
||||
c.Assert(err, check.IsNil)
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
dockerfileName, err := makefile(tmp, fmt.Sprintf("FROM %s/busybox", reg.URL()))
|
||||
c.Assert(err, check.IsNil, check.Commentf("Unable to create test dockerfile"))
|
||||
|
||||
s.d.Cmd("build", "--file", dockerfileName, tmp)
|
||||
c.Assert(v1Repo, check.Equals, 1, check.Commentf("Expected v1 repository access after build"))
|
||||
|
||||
repoName := fmt.Sprintf("%s/busybox", reg.URL())
|
||||
s.d.Cmd("run", repoName)
|
||||
c.Assert(v1Repo, check.Equals, 2, check.Commentf("Expected v1 repository access after run"))
|
||||
|
||||
s.d.Cmd("login", "-u", "richard", "-p", "testtest", reg.URL())
|
||||
c.Assert(v1Logins, check.Equals, 1, check.Commentf("Expected v1 login attempt"))
|
||||
|
||||
s.d.Cmd("tag", "busybox", repoName)
|
||||
s.d.Cmd("push", repoName)
|
||||
|
||||
c.Assert(v1Repo, check.Equals, 2)
|
||||
|
||||
s.d.Cmd("pull", repoName)
|
||||
c.Assert(v1Repo, check.Equals, 3, check.Commentf("Expected v1 repository access after pull"))
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ const notaryHost = "localhost:4443"
|
||||
const notaryURL = "https://" + notaryHost
|
||||
|
||||
var SuccessTagging = icmd.Expected{
|
||||
Out: "Tagging",
|
||||
Err: "Tagging",
|
||||
}
|
||||
|
||||
var SuccessSigningAndPushing = icmd.Expected{
|
||||
|
||||
61
components/engine/integration/container/health_test.go
Normal file
61
components/engine/integration/container/health_test.go
Normal file
@ -0,0 +1,61 @@
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/integration/util/request"
|
||||
"github.com/gotestyourself/gotestyourself/poll"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestHealthCheckWorkdir verifies that health-checks inherit the containers'
|
||||
// working-dir.
|
||||
func TestHealthCheckWorkdir(t *testing.T) {
|
||||
defer setupTest(t)()
|
||||
ctx := context.Background()
|
||||
client := request.NewAPIClient(t)
|
||||
|
||||
c, err := client.ContainerCreate(ctx,
|
||||
&container.Config{
|
||||
Image: "busybox",
|
||||
Tty: true,
|
||||
WorkingDir: "/foo",
|
||||
Cmd: strslice.StrSlice([]string{"top"}),
|
||||
Healthcheck: &container.HealthConfig{
|
||||
Test: []string{"CMD-SHELL", "if [ \"$PWD\" = \"/foo\" ]; then exit 0; else exit 1; fi;"},
|
||||
Interval: 50 * time.Millisecond,
|
||||
Retries: 3,
|
||||
},
|
||||
},
|
||||
&container.HostConfig{},
|
||||
&network.NetworkingConfig{},
|
||||
"healthtest",
|
||||
)
|
||||
require.NoError(t, err)
|
||||
err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
poll.WaitOn(t, pollForHealthStatus(ctx, client, c.ID, types.Healthy), poll.WithDelay(100*time.Millisecond))
|
||||
}
|
||||
|
||||
func pollForHealthStatus(ctx context.Context, client client.APIClient, containerID string, healthStatus string) func(log poll.LogT) poll.Result {
|
||||
return func(log poll.LogT) poll.Result {
|
||||
inspect, err := client.ContainerInspect(ctx, containerID)
|
||||
|
||||
switch {
|
||||
case err != nil:
|
||||
return poll.Error(err)
|
||||
case inspect.State.Health.Status == healthStatus:
|
||||
return poll.Success()
|
||||
default:
|
||||
return poll.Continue("waiting for container to become %s", healthStatus)
|
||||
}
|
||||
}
|
||||
}
|
||||
112
components/engine/integration/container/restart_test.go
Normal file
112
components/engine/integration/container/restart_test.go
Normal file
@ -0,0 +1,112 @@
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/integration-cli/daemon"
|
||||
)
|
||||
|
||||
func TestDaemonRestartKillContainers(t *testing.T) {
|
||||
type testCase struct {
|
||||
desc string
|
||||
config *container.Config
|
||||
hostConfig *container.HostConfig
|
||||
|
||||
xRunning bool
|
||||
xRunningLiveRestore bool
|
||||
}
|
||||
|
||||
for _, c := range []testCase{
|
||||
{
|
||||
desc: "container without restart policy",
|
||||
config: &container.Config{Image: "busybox", Cmd: []string{"top"}},
|
||||
xRunningLiveRestore: true,
|
||||
},
|
||||
{
|
||||
desc: "container with restart=always",
|
||||
config: &container.Config{Image: "busybox", Cmd: []string{"top"}},
|
||||
hostConfig: &container.HostConfig{RestartPolicy: container.RestartPolicy{Name: "always"}},
|
||||
xRunning: true,
|
||||
xRunningLiveRestore: true,
|
||||
},
|
||||
} {
|
||||
for _, liveRestoreEnabled := range []bool{false, true} {
|
||||
for fnName, stopDaemon := range map[string]func(*testing.T, *daemon.Daemon){
|
||||
"kill-daemon": func(t *testing.T, d *daemon.Daemon) {
|
||||
if err := d.Kill(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
},
|
||||
"stop-daemon": func(t *testing.T, d *daemon.Daemon) {
|
||||
d.Stop(t)
|
||||
},
|
||||
} {
|
||||
t.Run(fmt.Sprintf("live-restore=%v/%s/%s", liveRestoreEnabled, c.desc, fnName), func(t *testing.T) {
|
||||
c := c
|
||||
liveRestoreEnabled := liveRestoreEnabled
|
||||
stopDaemon := stopDaemon
|
||||
|
||||
t.Parallel()
|
||||
|
||||
d := daemon.New(t, "", "dockerd", daemon.Config{})
|
||||
client, err := d.NewClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var args []string
|
||||
if liveRestoreEnabled {
|
||||
args = []string{"--live-restore"}
|
||||
}
|
||||
|
||||
d.StartWithBusybox(t, args...)
|
||||
defer d.Stop(t)
|
||||
ctx := context.Background()
|
||||
|
||||
resp, err := client.ContainerCreate(ctx, c.config, c.hostConfig, nil, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer client.ContainerRemove(ctx, resp.ID, types.ContainerRemoveOptions{Force: true})
|
||||
|
||||
if err := client.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
stopDaemon(t, d)
|
||||
d.Start(t, args...)
|
||||
|
||||
expected := c.xRunning
|
||||
if liveRestoreEnabled {
|
||||
expected = c.xRunningLiveRestore
|
||||
}
|
||||
|
||||
var running bool
|
||||
for i := 0; i < 30; i++ {
|
||||
inspect, err := client.ContainerInspect(ctx, resp.ID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
running = inspect.State.Running
|
||||
if running == expected {
|
||||
break
|
||||
}
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
}
|
||||
|
||||
if running != expected {
|
||||
t.Fatalf("got unexpected running state, expected %v, got: %v", expected, running)
|
||||
}
|
||||
// TODO(cpuguy83): test pause states... this seems to be rather undefined currently
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user