1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #31754 from vieux/bump_17.03.1

bump to 17.03.1-rc1
This commit is contained in:
Victor Vieux 2017-03-13 23:25:41 -07:00 committed by GitHub
commit 59c6eb8c2f
22 changed files with 453 additions and 107 deletions

View file

@ -5,6 +5,38 @@ 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.
## 17.03.1-ce (2017-03-20)
### Remote API (v1.27) & Client
* Fix autoremove on older api [#31692](https://github.com/docker/docker/pull/31692)
* Fix default network customization for a stack [#31258](https://github.com/docker/docker/pull/31258/)
* Correct CPU usage calculation in presence of offline CPUs and newer Linux [#31802](https://github.com/docker/docker/pull/31802)
* Fix issue where service healthcheck is `{}` in remote API [#30197](https://github.com/docker/docker/pull/30197)
### Runtime
* Update runc to 54296cf40ad8143b62dbcaa1d90e520a2136ddfe [#3166](https://github.com/docker/docker/pull/31666)
* Ignore cgroup2 mountpoints [opencontainers/runc#1266](https://github.com/opencontainers/runc/pull/1266)
* Update containerd to 595e75c212d19a81d2b808a518fe1afc1391dad5 [#31662](https://github.com/docker/docker/pull/31662)
* Register healtcheck service before calling restore() [docker/containerd#609](https://github.com/docker/containerd/pull/609)
* Fix `docker exec` not working after unattended upgrades that reload apparmor profiles [#31773](https://github.com/docker/docker/pull/31773)
* Fix unmounting layer without merge dir with Overlay2 [#31069](https://github.com/docker/docker/pull/31069)
* Do not ignore "volume in use" errors when force-delete [#31450](https://github.com/docker/docker/pull/31450)
### Swarm Mode
* Update swarmkit to 17756457ad6dc4d8a639a1f0b7a85d1b65a617bb [#31807](https://github.com/docker/docker/pull/31807)
* Scheduler now correctly considers tasks which have been assigned to a node but aren't yet running [docker/swarmkit#1980](https://github.com/docker/swarmkit/pull/1980)
* Allow removal of a network when only dead tasks reference it [docker/swarmkit#2018](https://github.com/docker/swarmkit/pull/2018)
* Retry failed network allocations less aggressively [docker/swarmkit#2021](https://github.com/docker/swarmkit/pull/2021)
* Avoid network allocation for tasks that are no longer running [docker/swarmkit#2017](https://github.com/docker/swarmkit/pull/2017)
* Bookkeeping fixes inside network allocator allocator [docker/swarmkit#2019](https://github.com/docker/swarmkit/pull/2019) [docker/swarmkit#2020](https://github.com/docker/swarmkit/pull/2020)
### Windows
* Cleanup HCS on restore [#31503](https://github.com/docker/docker/pull/31503)
## 17.03.0-ce (2017-03-01)
**IMPORTANT**: Starting with this release, Docker is on a monthly release cycle and uses a
@ -45,9 +77,6 @@ Upgrading from Docker 1.13.1 to 17.03.0 is expected to be simple and low-risk.
### Swarm Mode
* Shutdown leaks an error when the container was never started [#31279](https://github.com/docker/docker/pull/31279)
### Swarm Mode
* Fix possibility of tasks getting stuck in the "NEW" state during a leader failover [docker/swarmkit#1938](https://github.com/docker/swarmkit/pull/1938)
* Fix extraneous task creations for global services that led to confusing replica counts in `docker service ls` [docker/swarmkit#1957](https://github.com/docker/swarmkit/pull/1957)
* Fix problem that made rolling updates slow when `task-history-limit` was set to 1 [docker/swarmkit#1948](https://github.com/docker/swarmkit/pull/1948)

View file

@ -1 +1 @@
17.03.0-ce
17.03.1-ce-rc1

View file

@ -118,8 +118,6 @@ tags:
Run new commands inside running containers. See the [command-line reference](https://docs.docker.com/engine/reference/commandline/exec/) for more information.
To exec a command in a container, you first need to create an exec instance, then start it. These two API endpoints are wrapped up in a single command-line command, `docker exec`.
- name: "Secret"
x-displayName: "Secrets"
# Swarm things
- name: "Swarm"
x-displayName: "Swarm"
@ -137,6 +135,10 @@ tags:
x-displayName: "Tasks"
description: |
A task is a container running on a swarm. It is the atomic scheduling unit of swarm. Swarm mode must be enabled for these endpoints to work.
- name: "Secret"
x-displayName: "Secrets"
description: |
Secrets are sensitive data that can be used by services. Swarm mode must be enabled for these endpoints to work.
# System things
- name: "Plugin"
x-displayName: "Plugins"

View file

@ -271,7 +271,7 @@ func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error {
fmt.Fprintf(dockerCli.Out(), " %s\n", attribute)
}
// TODO: Engine labels with duplicate keys has been deprecated in 1.13 and will be error out
// after 3 release cycles (1.16). For now, a WARNING will be generated. The following will
// after 3 release cycles (17.12). For now, a WARNING will be generated. The following will
// be removed eventually.
labelMap := map[string]string{}
for _, label := range info.Labels {

View file

@ -17,6 +17,8 @@ import (
"github.com/docker/go-connections/nat"
)
const defaultNetwork = "default"
// Services from compose-file types to engine API types
// TODO: fix secrets API so that SecretAPIClient is not required here
func Services(
@ -157,18 +159,15 @@ func convertServiceNetworks(
name string,
) ([]swarm.NetworkAttachmentConfig, error) {
if len(networks) == 0 {
return []swarm.NetworkAttachmentConfig{
{
Target: namespace.Scope("default"),
Aliases: []string{name},
},
}, nil
networks = map[string]*composetypes.ServiceNetworkConfig{
defaultNetwork: {},
}
}
nets := []swarm.NetworkAttachmentConfig{}
for networkName, network := range networks {
networkConfig, ok := networkConfigs[networkName]
if !ok {
if !ok && networkName != defaultNetwork {
return []swarm.NetworkAttachmentConfig{}, fmt.Errorf(
"service %q references network %q, which is not declared", name, networkName)
}

View file

@ -145,10 +145,9 @@ func TestConvertHealthcheckDisableWithTest(t *testing.T) {
func TestConvertServiceNetworksOnlyDefault(t *testing.T) {
networkConfigs := networkMap{}
networks := map[string]*composetypes.ServiceNetworkConfig{}
configs, err := convertServiceNetworks(
networks, networkConfigs, NewNamespace("foo"), "service")
nil, networkConfigs, NewNamespace("foo"), "service")
expected := []swarm.NetworkAttachmentConfig{
{
@ -201,6 +200,31 @@ func TestConvertServiceNetworks(t *testing.T) {
assert.DeepEqual(t, []swarm.NetworkAttachmentConfig(sortedConfigs), expected)
}
func TestConvertServiceNetworksCustomDefault(t *testing.T) {
networkConfigs := networkMap{
"default": composetypes.NetworkConfig{
External: composetypes.External{
External: true,
Name: "custom",
},
},
}
networks := map[string]*composetypes.ServiceNetworkConfig{}
configs, err := convertServiceNetworks(
networks, networkConfigs, NewNamespace("foo"), "service")
expected := []swarm.NetworkAttachmentConfig{
{
Target: "custom",
Aliases: []string{"service"},
},
}
assert.NilError(t, err)
assert.DeepEqual(t, []swarm.NetworkAttachmentConfig(configs), expected)
}
type byTargetSort []swarm.NetworkAttachmentConfig
func (s byTargetSort) Len() int {

View file

@ -433,7 +433,7 @@ func loadDaemonCliConfig(opts daemonOptions) (*daemon.Config, error) {
// This is deprecated in 1.13, and, be removed after 3 release cycles.
// The following will check the conflict of labels, and report a warning for deprecation.
//
// TODO: After 3 release cycles (1.16) an error will be returned, and labels will be
// TODO: After 3 release cycles (17.12) an error will be returned, and labels will be
// sanitized to consolidate duplicate key-value pairs (config.Labels = newLabels):
//
// newLabels, err := daemon.GetConflictFreeLabels(config.Labels)

View file

@ -570,7 +570,7 @@ __docker_subcommands() {
$(__docker_to_extglob "$subcommands") )
subcommand_pos=$counter
local subcommand=${words[$counter]}
local completions_func=_docker_${command}_${subcommand}
local completions_func=_docker_${command}_${subcommand//-/_}
declare -F $completions_func >/dev/null && $completions_func
return 0
;;
@ -605,38 +605,25 @@ __docker_complete_local_interfaces() {
COMPREPLY=( $( compgen -W "$(__docker_local_interfaces) $additional_interface" -- "$cur" ) )
}
__docker_complete_capabilities() {
# The list of capabilities is defined in types.go, ALL was added manually.
# __docker_complete_capabilities_addable completes Linux capabilities which are
# not granted by default and may be added.
# see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities
__docker_complete_capabilities_addable() {
COMPREPLY=( $( compgen -W "
ALL
AUDIT_CONTROL
AUDIT_WRITE
AUDIT_READ
BLOCK_SUSPEND
CHOWN
DAC_OVERRIDE
DAC_READ_SEARCH
FOWNER
FSETID
IPC_LOCK
IPC_OWNER
KILL
LEASE
LINUX_IMMUTABLE
MAC_ADMIN
MAC_OVERRIDE
MKNOD
NET_ADMIN
NET_BIND_SERVICE
NET_BROADCAST
NET_RAW
SETFCAP
SETGID
SETPCAP
SETUID
SYS_ADMIN
SYS_BOOT
SYS_CHROOT
SYSLOG
SYS_MODULE
SYS_NICE
@ -650,7 +637,30 @@ __docker_complete_capabilities() {
" -- "$cur" ) )
}
__docker_complete_detach-keys() {
# __docker_complete_capabilities_droppable completes Linux capability options which are
# allowed by default and can be dropped.
# see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities
__docker_complete_capabilities_droppable() {
COMPREPLY=( $( compgen -W "
ALL
AUDIT_WRITE
CHOWN
DAC_OVERRIDE
FOWNER
FSETID
KILL
MKNOD
NET_BIND_SERVICE
NET_RAW
SETFCAP
SETGID
SETPCAP
SETUID
SYS_CHROOT
" -- "$cur" ) )
}
__docker_complete_detach_keys() {
case "$prev" in
--detach-keys)
case "$cur" in
@ -1047,7 +1057,7 @@ _docker_container() {
}
_docker_container_attach() {
__docker_complete_detach-keys && return
__docker_complete_detach_keys && return
case "$cur" in
-*)
@ -1154,7 +1164,7 @@ _docker_container_diff() {
}
_docker_container_exec() {
__docker_complete_detach-keys && return
__docker_complete_detach_keys && return
case "$prev" in
--env|-e)
@ -1498,7 +1508,7 @@ _docker_container_run() {
--rm
--sig-proxy=false
"
__docker_complete_detach-keys && return
__docker_complete_detach_keys && return
fi
local all_options="$options_with_args $boolean_options"
@ -1538,8 +1548,12 @@ _docker_container_run() {
COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) )
return
;;
--cap-add|--cap-drop)
__docker_complete_capabilities
--cap-add)
__docker_complete_capabilities_addable
return
;;
--cap-drop)
__docker_complete_capabilities_droppable
return
;;
--cidfile|--env-file|--init-path|--label-file)
@ -1686,7 +1700,7 @@ _docker_container_run() {
}
_docker_container_start() {
__docker_complete_detach-keys && return
__docker_complete_detach_keys && return
case "$prev" in
--checkpoint)
@ -3141,7 +3155,7 @@ _docker_swarm_join() {
esac
}
_docker_swarm_join-token() {
_docker_swarm_join_token() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) )
@ -3171,7 +3185,7 @@ _docker_swarm_unlock() {
esac
}
_docker_swarm_unlock-key() {
_docker_swarm_unlock_key() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) )
@ -4289,7 +4303,7 @@ _docker() {
command_pos=0
fi
local completions_func=_docker_${command}
local completions_func=_docker_${command//-/_}
declare -F $completions_func >/dev/null && $completions_func
eval "$previous_extglob_setting"

View file

@ -205,7 +205,7 @@ func (r *controller) Start(ctx context.Context) error {
}
// no health check
if ctnr.Config == nil || ctnr.Config.Healthcheck == nil {
if ctnr.Config == nil || ctnr.Config.Healthcheck == nil || len(ctnr.Config.Healthcheck.Test) == 0 || ctnr.Config.Healthcheck.Test[0] == "NONE" {
if err := r.adapter.activateServiceBinding(); err != nil {
log.G(ctx).WithError(err).Errorf("failed to activate service binding for container %s which has no healthcheck config", r.adapter.container.name())
return err
@ -213,12 +213,6 @@ func (r *controller) Start(ctx context.Context) error {
return nil
}
healthCmd := ctnr.Config.Healthcheck.Test
if len(healthCmd) == 0 || healthCmd[0] == "NONE" {
return nil
}
// wait for container to be healthy
eventq := r.adapter.events(ctx)

View file

@ -279,7 +279,7 @@ func ReloadConfiguration(configFile string, flags *pflag.FlagSet, reload func(*C
// This is deprecated in 1.13, and, be removed after 3 release cycles.
// The following will check the conflict of labels, and report a warning for deprecation.
//
// TODO: After 3 release cycles (1.16) an error will be returned, and labels will be
// TODO: After 3 release cycles (17.12) an error will be returned, and labels will be
// sanitized to consolidate duplicate key-value pairs (config.Labels = newLabels):
//
// newLabels, err := GetConflictFreeLabels(newConfig.Labels)

View file

@ -8,11 +8,12 @@ import (
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/errors"
apierrors "github.com/docker/docker/api/errors"
"github.com/docker/docker/api/types"
"github.com/docker/docker/container"
"github.com/docker/docker/layer"
volumestore "github.com/docker/docker/volume/store"
"github.com/pkg/errors"
)
// ContainerRm removes the container id from the filesystem. An error
@ -29,7 +30,7 @@ func (daemon *Daemon) ContainerRm(name string, config *types.ContainerRmConfig)
// Container state RemovalInProgress should be used to avoid races.
if inProgress := container.SetRemovalInProgress(); inProgress {
err := fmt.Errorf("removal of container %s is already in progress", name)
return errors.NewBadRequestError(err)
return apierrors.NewBadRequestError(err)
}
defer container.ResetRemovalInProgress()
@ -80,7 +81,7 @@ func (daemon *Daemon) cleanupContainer(container *container.Container, forceRemo
if container.IsRunning() {
if !forceRemove {
err := fmt.Errorf("You cannot remove a running container %s. Stop the container before attempting removal or use -f", container.ID)
return errors.NewRequestConflictError(err)
return apierrors.NewRequestConflictError(err)
}
if err := daemon.Kill(container); err != nil {
return fmt.Errorf("Could not kill running container %s, cannot remove - %v", container.ID, err)
@ -143,6 +144,9 @@ func (daemon *Daemon) cleanupContainer(container *container.Container, forceRemo
// This is called directly from the Engine API
func (daemon *Daemon) VolumeRm(name string, force bool) error {
err := daemon.volumeRm(name)
if err != nil && volumestore.IsInUse(err) {
return apierrors.NewRequestConflictError(err)
}
if err == nil || force {
daemon.volumes.Purge(name)
return nil
@ -157,11 +161,7 @@ func (daemon *Daemon) volumeRm(name string) error {
}
if err := daemon.volumes.Remove(v); err != nil {
if volumestore.IsInUse(err) {
err := fmt.Errorf("Unable to remove volume, volume still in use: %v", err)
return errors.NewRequestConflictError(err)
}
return fmt.Errorf("Error while removing volume %s: %v", name, err)
return errors.Wrap(err, "unable to remove volume")
}
daemon.LogVolumeEvent(v.Name(), "destroy", map[string]string{"driver": v.DriverName()})
return nil

View file

@ -5,6 +5,7 @@ import (
"github.com/docker/docker/daemon/caps"
"github.com/docker/docker/daemon/exec"
"github.com/docker/docker/libcontainerd"
"github.com/opencontainers/runc/libcontainer/apparmor"
"github.com/opencontainers/runtime-spec/specs-go"
)
@ -23,5 +24,27 @@ func execSetPlatformOpt(c *container.Container, ec *exec.Config, p *libcontainer
if ec.Privileged {
p.Capabilities = caps.GetAllCapabilities()
}
if apparmor.IsEnabled() {
var appArmorProfile string
if c.AppArmorProfile != "" {
appArmorProfile = c.AppArmorProfile
} else if c.HostConfig.Privileged {
appArmorProfile = "unconfined"
} else {
appArmorProfile = "docker-default"
}
if appArmorProfile == "docker-default" {
// Unattended upgrades and other fun services can unload AppArmor
// profiles inadvertently. Since we cannot store our profile in
// /etc/apparmor.d, nor can we practically add other ways of
// telling the system to keep our profile loaded, in order to make
// sure that we keep the default profile enabled we dynamically
// reload it if necessary.
if err := ensureDefaultAppArmorProfile(); err != nil {
return err
}
}
}
return nil
}

View file

@ -144,7 +144,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, err
}
if !supportsDType {
// not a fatal error until v1.16 (#27443)
// not a fatal error until v17.12 (#27443)
logrus.Warn(overlayutils.ErrDTypeNotSupported("overlay", backingFs))
}

View file

@ -30,7 +30,7 @@ import (
"github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/go-units"
units "github.com/docker/go-units"
"github.com/opencontainers/runc/libcontainer/label"
)
@ -170,7 +170,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, err
}
if !supportsDType {
// not a fatal error until v1.16 (#27443)
// not a fatal error until v17.12 (#27443)
logrus.Warn(overlayutils.ErrDTypeNotSupported("overlay2", backingFs))
}
@ -553,7 +553,17 @@ func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
// Put unmounts the mount path created for the give id.
func (d *Driver) Put(id string) error {
mountpoint := path.Join(d.dir(id), "merged")
dir := d.dir(id)
_, err := ioutil.ReadFile(path.Join(dir, lowerFile))
if err != nil {
// If no lower, no mount happened and just return directly
if os.IsNotExist(err) {
return nil
}
return err
}
mountpoint := path.Join(dir, "merged")
if count := d.ctr.Decrement(mountpoint); count > 0 {
return nil
}

View file

@ -13,6 +13,6 @@ func ErrDTypeNotSupported(driver, backingFs string) error {
if backingFs == "xfs" {
msg += " Reformat the filesystem with ftype=1 to enable d_type support."
}
msg += " Running without d_type support will no longer be supported in Docker 1.16."
msg += " Running without d_type support will no longer be supported in Docker 17.12."
return errors.New(msg)
}

View file

@ -74,7 +74,7 @@ The currently supported filters are:
* id (network's id)
* label (`label=<key>` or `label=<key>=<value>`)
* name (network's name)
* type (custom|builtin)
* type (`custom|builtin`)
#### Driver

View file

@ -35,7 +35,7 @@ Options:
- name=<string> a container's name
- network=(<network-id>|<network-name>)
- since=(<container-name>|<container-id>)
- status=(created|restarting|removing|running|paused|exited)
- status=(created|restarting|removing|running|paused|exited)
- volume=(<volume name>|<mount point destination>)
--format string Pretty-print containers using a Go template
--help Print usage
@ -84,11 +84,11 @@ The currently supported filters are:
* label (`label=<key>` or `label=<key>=<value>`)
* name (container's name)
* exited (int - the code of exited containers. Only useful with `--all`)
* status (created|restarting|running|removing|paused|exited|dead)
* status (`created|restarting|running|removing|paused|exited|dead`)
* ancestor (`<image-name>[:<tag>]`, `<image id>` or `<image@digest>`) - filters containers that were created from the given image or a descendant.
* before (container's id or name) - filters containers created before given id or name
* since (container's id or name) - filters containers created since given id or name
* isolation (default|process|hyperv) (Windows daemon only)
* isolation (`default|process|hyperv`) (Windows daemon only)
* volume (volume name or mount point) - filters containers that mount volumes.
* network (network id or name) - filters containers connected to the provided network
* health (starting|healthy|unhealthy|none) - filters containers based on healthcheck status

View file

@ -249,12 +249,69 @@ For more information about named volumes, see
The following table describes options which apply to both bind-mounts and named
volumes in a service:
| Option | Required | Description
|:-----------------------------------------|:--------------------------|:-----------------------------------------------------------------------------------------
| **type** | | The type of mount, can be either `volume`, `bind`, or `tmpfs`. Defaults to `volume` if no type is specified.<ul><li>`volume`: mounts a [managed volume](volume_create.md) into the container.</li><li>`bind`: bind-mounts a directory or file from the host into the container.</li><li>`tmpfs`: mount a tmpfs in the container</li></ul>
| **src** or **source** | for `type=bind`&nbsp;only | <ul><li>`type=volume`: `src` is an optional way to specify the name of the volume (for example, `src=my-volume`). If the named volume does not exist, it is automatically created. If no `src` is specified, the volume is assigned a random name which is guaranteed to be unique on the host, but may not be unique cluster-wide. A randomly-named volume has the same lifecycle as its container and is destroyed when the *container* is destroyed (which is upon `service update`, or when scaling or re-balancing the service).</li><li>`type=bind`: `src` is required, and specifies an absolute path to the file or directory to bind-mount (for example, `src=/path/on/host/`). An error is produced if the file or directory does not exist.</li><li>`type=tmpfs`: `src` is not supported.</li></ul>
| **dst** or **destination** or **target** | yes | Mount path inside the container, for example `/some/path/in/container/`. If the path does not exist in the container's filesystem, the Engine creates a directory at the specified location before mounting the volume or bind-mount.
| **readonly** or **ro** | | The Engine mounts binds and volumes `read-write` unless `readonly` option is given when mounting the bind or volume.<br /><br /><ul><li>`true` or `1` or no value: Mounts the bind or volume read-only.</li><li>`false` or `0`: Mounts the bind or volume read-write.</li></ul>
<table>
<tr>
<th>Option</th>
<th>Required</th>
<th>Description</th>
</tr>
<tr>
<td><b>types</b></td>
<td></td>
<td>
<p>The type of mount, can be either <tt>volume</tt>, <tt>bind</tt>, or <tt>tmpfs</tt>. Defaults to <tt>volume</tt> if no type is specified.
<ul>
<li><tt>volume</tt>: mounts a [managed volume](volume_create.md) into the container.</li>
<li><tt>bind</tt>: bind-mounts a directory or file from the host into the container.</li>
<li><tt>tmpfs</tt>: mount a tmpfs in the container</li>
</ul></p>
</td>
</tr>
<tr>
<td><b>src</b> or <b>source</b></td>
<td>for <tt>type=bind</tt> only></td>
<td>
<ul>
<li>
<tt>type=volume</tt>: <tt>src</tt> is an optional way to specify the name of the volume (for example, <tt>src=my-volume</tt>).
If the named volume does not exist, it is automatically created. If no <tt>src</tt> is specified, the volume is
assigned a random name which is guaranteed to be unique on the host, but may not be unique cluster-wide.
A randomly-named volume has the same lifecycle as its container and is destroyed when the <i>container</i>
is destroyed (which is upon <tt>service update</tt>, or when scaling or re-balancing the service)
</li>
<li>
<tt>type=bind</tt>: <tt>src</tt> is required, and specifies an absolute path to the file or directory to bind-mount
(for example, <tt>src=/path/on/host/</tt>). An error is produced if the file or directory does not exist.
</li>
<li>
<tt>type=tmpfs</tt>: <tt>src</tt> is not supported.
</li>
</ul>
</td>
</tr>
<tr>
<td><p><b>dst</b> or <b>destination</b> or <b>target</b></p></td>
<td>yes</td>
<td>
<p>Mount path inside the container, for example <tt>/some/path/in/container/</tt>.
If the path does not exist in the container's filesystem, the Engine creates
a directory at the specified location before mounting the volume or bind-mount.</p>
</td>
</tr>
<tr>
<td><p><b>readonly</b> or <b>ro</b></p></td>
<td></td>
<td>
<p>The Engine mounts binds and volumes <tt>read-write</tt> unless <tt>readonly</tt> option
is given when mounting the bind or volume.
<ul>
<li><tt>true</tt> or <tt>1</tt> or no value: Mounts the bind or volume read-only.</li>
<li><tt>false</tt> or <tt>0</tt>: Mounts the bind or volume read-write.</li>
</ul></p>
</td>
</tr>
</table>
#### Bind Propagation
@ -294,22 +351,84 @@ For more information about bind propagation, see the
[Linux kernel documentation for shared subtree](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt).
#### Options for Named Volumes
The following options can only be used for named volumes (`type=volume`);
| Option | Description
|:----------------------|:--------------------------------------------------------------------------------------------------------------------
| **volume-driver** | Name of the volume-driver plugin to use for the volume. Defaults to ``"local"``, to use the local volume driver to create the volume if the volume does not exist.
| **volume-label** | One or more custom metadata ("labels") to apply to the volume upon creation. For example, `volume-label=mylabel=hello-world,my-other-label=hello-mars`. For more information about labels, refer to [apply custom metadata](https://docs.docker.com/engine/userguide/labels-custom-metadata/).
| **volume-nocopy** | By default, if you attach an empty volume to a container, and files or directories already existed at the mount-path in the container (`dst`), the Engine copies those files and directories into the volume, allowing the host to access them. Set `volume-nocopy` to disables copying files from the container's filesystem to the volume and mount the empty volume.<br /><br />A value is optional:<ul><li>`true` or `1`: Default if you do not provide a value. Disables copying.</li><li>`false` or `0`: Enables copying.</li></ul>
| **volume-opt** | Options specific to a given volume driver, which will be passed to the driver when creating the volume. Options are provided as a comma-separated list of key/value pairs, for example, `volume-opt=some-option=some-value,some-other-option=some-other-value`. For available options for a given driver, refer to that driver's documentation.
<table>
<tr>
<th>Option</th>
<th>Description</th>
</tr>
<tr>
<td><b>volume-driver</b></td>
<td>
<p>Name of the volume-driver plugin to use for the volume. Defaults to
<tt>"local"</tt>, to use the local volume driver to create the volume if the
volume does not exist.</p>
</td>
</tr>
<tr>
<td><b>volume-label</b></td>
<td>
One or more custom metadata ("labels") to apply to the volume upon
creation. For example,
`volume-label=mylabel=hello-world,my-other-label=hello-mars`. For more
information about labels, refer to
<a href="https://docs.docker.com/engine/userguide/labels-custom-metadata/">apply custom metadata</a>.
</td>
</tr>
<tr>
<td><b>volume-nocopy</b></td>
<td>
By default, if you attach an empty volume to a container, and files or
directories already existed at the mount-path in the container (<tt>dst</tt>),
the Engine copies those files and directories into the volume, allowing
the host to access them. Set `volume-nocopy` to disables copying files
from the container's filesystem to the volume and mount the empty volume.
A value is optional:
<ul>
<li><tt>true</tt> or <tt>1</tt>: Default if you do not provide a value. Disables copying.</li>
<li><tt>false</tt> or <tt>0</tt>: Enables copying.</li>
</ul>
</td>
</tr>
<tr>
<td><b>volume-opt</b></td>
<td>
Options specific to a given volume driver, which will be passed to the
driver when creating the volume. Options are provided as a comma-separated
list of key/value pairs, for example,
<tt>volume-opt=some-option=some-value,some-other-option=some-other-value</tt>.
For available options for a given driver, refer to that driver's
documentation.
</td>
</tr>
</table>
#### Options for tmpfs
The following options can only be used for tmpfs mounts (`type=tmpfs`);
| Option | Description
|:----------------------|:--------------------------------------------------------------------------------------------------------------------
| **tmpfs-size** | Size of the tmpfs mount in bytes. Unlimited by default in Linux.
| **tmpfs-mode** | File mode of the tmpfs in octal. (e.g. `"700"` or `"0700"`.) Defaults to ``"1777"`` in Linux.
<table>
<tr>
<th>Option</th>
<th>Description</th>
</tr>
<tr>
<td><b>tmpfs-size</b></td>
<td>Size of the tmpfs mount in bytes. Unlimited by default in Linux.</td>
</tr>
<tr>
<td><b>tmpfs-mode</b></td>
<td>File mode of the tmpfs in octal. (e.g. <tt>"700"</tt> or <tt>"0700"</tt>.) Defaults to <tt>"1777"</tt> in Linux.</td>
</tr>
</table>
#### Differences between "--mount" and "--volume"
@ -412,13 +531,40 @@ constraint expressions. Multiple constraints find nodes that satisfy every
expression (AND match). Constraints can match node or Docker Engine labels as
follows:
| node attribute | matches | example |
|:----------------|:--------------------------|:------------------------------------------------|
| node.id | node ID | `node.id == 2ivku8v2gvtg4` |
| node.hostname | node hostname | `node.hostname != node-2` |
| node.role | node role: manager | `node.role == manager` |
| node.labels | user defined node labels | `node.labels.security == high` |
| engine.labels | Docker Engine's labels | `engine.labels.operatingsystem == ubuntu 14.04` |
<table>
<tr>
<th>node attribute</th>
<th>matches</th>
<th>example</th>
</tr>
<tr>
<td><tt>node.id</tt></td>
<td>Node ID</td>
<td><tt>node.id == 2ivku8v2gvtg4</tt></td>
</tr>
<tr>
<td><tt>node.hostname</tt></td>
<td>Node hostname</td>
<td><tt>node.hostname != node-2</tt></td>
</tr>
<tr>
<td<tt>node.role</tt></td>
<td><tt>node role: manager</tt></td>
<td><tt>node.role == manager</tt></td>
</tr>
<tr>
<td><tt>node.labels</tt></td>
<td>user defined node labels</td>
<td><tt>node.labels.security == high</tt></td>
</tr>
<tr>
<td><tt>engine.labels</tt></td>
<td>Docker Engine's labels</td>
<td><tt>engine.labels.operatingsystem == ubuntu 14.04</tt></td>
</tr>
</table>
`engine.labels` apply to Docker Engine labels like operating system,
drivers, etc. Swarm administrators add `node.labels` for operational purposes by
@ -530,15 +676,42 @@ The supported flags are the following :
Valid placeholders for the Go template are listed below:
Placeholder | Description
----------------- | --------------------------------------------
`.Service.ID` | Service ID
`.Service.Name` | Service name
`.Service.Labels` | Service labels
`.Node.ID` | Node ID
`.Task.ID` | Task ID
`.Task.Name` | Task name
`.Task.Slot` | Task slot
<table>
<tr>
<th>Placeholder</th>
<th>Description</th>
</tr>
<tr>
<td><tt>.Service.ID</tt></td>
<td>Service ID</td>
</tr>
<tr>
<td><tt>.Service.Name</tt></td>
<td>Service name</td>
</tr>
<tr>
<td><tt>.Service.Labels</tt></td>
<td>Service labels</td>
</tr>
<tr>
<td><tt>.Node.ID</tt></td>
<td>Node ID</td>
</tr>
<tr>
<td><tt>.Task.ID</tt></td>
<td>Task ID</td>
</tr>
<tr>
<td><tt>.Task.Name</tt></td>
<td>Task name</td>
</tr>
<tr>
<td><tt>.Task.Slot</tt></td>
<td>Task slot</td>
</tr>
</table>
#### Template example

View file

@ -27,12 +27,12 @@ Options:
-q, --quiet Only display IDs
```
### Description
## Description
Lists the services that are running as part of the specified stack. This
command has to be run targeting a manager node.
### Examples
## Examples
The following command shows all services in the `myapp` stack:

View file

@ -15,6 +15,7 @@ import (
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/pkg/integration/checker"
"github.com/go-check/check"
@ -1365,3 +1366,26 @@ func (s *DockerSwarmSuite) TestAPIDuplicateNetworks(c *check.C) {
c.Assert(r2.Scope, checker.Equals, "swarm")
}
// Test case for 30178
func (s *DockerSwarmSuite) TestAPISwarmHealthcheckNone(c *check.C) {
d := s.AddDaemon(c, true, true)
out, err := d.Cmd("network", "create", "-d", "overlay", "lb")
c.Assert(err, checker.IsNil, check.Commentf(out))
instances := 1
d.createService(c, simpleTestService, setInstances(instances), func(s *swarm.Service) {
s.Spec.TaskTemplate.ContainerSpec.Healthcheck = &container.HealthConfig{}
s.Spec.TaskTemplate.Networks = []swarm.NetworkAttachmentConfig{
{Target: "lb"},
}
})
waitAndAssert(c, defaultReconciliationTimeout, d.checkActiveContainerCount, checker.Equals, instances)
containers := d.activeContainers()
out, err = d.Cmd("exec", containers[0], "ping", "-c1", "-W3", "top")
c.Assert(err, checker.IsNil, check.Commentf(out))
}

View file

@ -398,14 +398,54 @@ func (s *DockerSuite) TestVolumeCLIRmForce(c *check.C) {
out, _, err := runCommandWithOutput(exec.Command("rm", "-rf", path))
c.Assert(err, check.IsNil)
dockerCmd(c, "volume", "rm", "-f", "test")
dockerCmd(c, "volume", "rm", "-f", name)
out, _ = dockerCmd(c, "volume", "ls")
c.Assert(out, checker.Not(checker.Contains), name)
dockerCmd(c, "volume", "create", "test")
dockerCmd(c, "volume", "create", name)
out, _ = dockerCmd(c, "volume", "ls")
c.Assert(out, checker.Contains, name)
}
// TestVolumeCLIRmForceInUse verifies that repeated `docker volume rm -f` calls does not remove a volume
// if it is in use. Test case for https://github.com/docker/docker/issues/31446
func (s *DockerSuite) TestVolumeCLIRmForceInUse(c *check.C) {
name := "testvolume"
out, _ := dockerCmd(c, "volume", "create", name)
id := strings.TrimSpace(out)
c.Assert(id, checker.Equals, name)
prefix, slash := getPrefixAndSlashFromDaemonPlatform()
out, e := dockerCmd(c, "create", "-v", "testvolume:"+prefix+slash+"foo", "busybox")
cid := strings.TrimSpace(out)
_, _, err := dockerCmdWithError("volume", "rm", "-f", name)
c.Assert(err, check.NotNil)
c.Assert(err.Error(), checker.Contains, "volume is in use")
out, _ = dockerCmd(c, "volume", "ls")
c.Assert(out, checker.Contains, name)
// The original issue did not _remove_ the volume from the list
// the first time. But a second call to `volume rm` removed it.
// Calling `volume rm` a second time to confirm it's not removed
// when calling twice.
_, _, err = dockerCmdWithError("volume", "rm", "-f", name)
c.Assert(err, check.NotNil)
c.Assert(err.Error(), checker.Contains, "volume is in use")
out, _ = dockerCmd(c, "volume", "ls")
c.Assert(out, checker.Contains, name)
// Verify removing the volume after the container is removed works
_, e = dockerCmd(c, "rm", cid)
c.Assert(e, check.Equals, 0)
_, e = dockerCmd(c, "volume", "rm", "-f", name)
c.Assert(e, check.Equals, 0)
out, e = dockerCmd(c, "volume", "ls")
c.Assert(e, check.Equals, 0)
c.Assert(out, checker.Not(checker.Contains), name)
}
func (s *DockerSuite) TestVolumeCliInspectWithVolumeOpts(c *check.C) {
testRequires(c, DaemonIsLinux)

View file

@ -552,8 +552,22 @@ func (clnt *client) Stats(containerID string) (*Stats, error) {
// Restore is the handler for restoring a container
func (clnt *client) Restore(containerID string, _ StdioCallback, unusedOnWindows ...CreateOption) error {
// TODO Windows: Implement this. For now, just tell the backend the container exited.
logrus.Debugf("libcontainerd: Restore(%s)", containerID)
// TODO Windows: On RS1, a re-attach isn't possible.
// However, there is a scenario in which there is an issue.
// Consider a background container. The daemon dies unexpectedly.
// HCS will still have the compute service alive and running.
// For consistence, we call in to shoot it regardless if HCS knows about it
// We explicitly just log a warning if the terminate fails.
// Then we tell the backend the container exited.
if hc, err := hcsshim.OpenContainer(containerID); err == nil {
if err := hc.Terminate(); err != nil {
if !hcsshim.IsPending(err) {
logrus.Warnf("libcontainerd: failed to terminate %s on restore - %q", containerID, err)
}
}
}
return clnt.backend.StateChanged(containerID, StateInfo{
CommonStateInfo: CommonStateInfo{
State: StateExit,