Merge component 'engine' from git@github.com:moby/moby master

This commit is contained in:
Andrew Hsu
2017-08-14 16:37:05 +00:00
566 changed files with 6830 additions and 3585 deletions

19
components/engine/.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1,19 @@
# Github code owners
# See https://help.github.com/articles/about-codeowners/
#
# KEEP THIS FILE SORTED. Order is important. Last match takes precedence.
builder/** @dnephin @tonistiigi
client/** @dnephin
contrib/mkimage/** @tianon
daemon/graphdriver/devmapper/** @rhvgoyal
daemon/graphdriver/lcow/** @johnstep @jhowardmsft
daemon/graphdriver/overlay/** @dmcgowan
daemon/graphdriver/overlay2/** @dmcgowan
daemon/graphdriver/windows/** @johnstep @jhowardmsft
daemon/logger/awslogs/** @samuelkarp
hack/** @dnephin @tianon
hack/integration-cli-on-swarm/** @AkihiroSuda
pkg/testutil/** @dnephin
plugin/** @cpuguy83
project/** @thaJeztah

View File

@ -4,7 +4,7 @@
*.exe
*.exe~
*.orig
*.test
test.main
.*.swp
.DS_Store
# a .bashrc may be added to customize the build environment

View File

@ -160,6 +160,10 @@ it! Take a look at existing tests for inspiration. [Run the full test
suite](https://docs.docker.com/opensource/project/test-and-docs/) on your branch before
submitting a pull request.
If your changes need integration tests, write them against the API. The `cli`
integration tests are slowly either migrated to API tests or moved away as unit
tests in `docker/cli` and end-to-end tests for docker.
Update the documentation when creating or modifying features. Test your
documentation changes for clarity, concision, and correctness, as well as a
clean documentation build. See our contributors guide for [our style

View File

@ -9,7 +9,7 @@
# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
#
# # Run the test suite:
# docker run -e DOCKER_GITCOMMIT=foo --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py
# docker run -e DOCKER_GITCOMMIT=foo --privileged docker hack/make.sh test-unit test-integration test-docker-py
#
# # Publish a release:
# docker run --privileged \
@ -72,21 +72,21 @@ RUN apt-get update && apt-get install -y \
zip \
--no-install-recommends \
&& pip install awscli==1.10.15
# Get lvm2 source for compiling statically
ENV LVM2_VERSION 2.02.103
# Get lvm2 sources to build statically linked devmapper library
ENV LVM2_VERSION 2.02.173
RUN mkdir -p /usr/local/lvm2 \
&& curl -fsSL "https://mirrors.kernel.org/sourceware/lvm2/LVM2.${LVM2_VERSION}.tgz" \
| tar -xzC /usr/local/lvm2 --strip-components=1
# See https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags
# Compile and install lvm2
# Compile and install (only the needed library)
RUN cd /usr/local/lvm2 \
&& ./configure \
--build="$(gcc -print-multiarch)" \
--enable-static_link \
&& make device-mapper \
&& make install_device-mapper
# See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
--enable-pkgconfig \
&& make -C include \
&& make -C libdm install_device-mapper
# Install seccomp: the version shipped upstream is too old
ENV SECCOMP_VERSION 2.3.2

View File

@ -9,7 +9,7 @@
# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
#
# # Run the test suite:
# docker run --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py
# docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
#
# Note: AppArmor used to mess with privileged mode, but this is no longer
# the case. Therefore, you don't have to disable it anymore.
@ -54,28 +54,20 @@ RUN apt-get update && apt-get install -y \
vim-common \
--no-install-recommends
# Get lvm2 source for compiling statically
ENV LVM2_VERSION 2.02.103
# Get lvm2 sources to build statically linked devmapper library
ENV LVM2_VERSION 2.02.173
RUN mkdir -p /usr/local/lvm2 \
&& curl -fsSL "https://mirrors.kernel.org/sourceware/lvm2/LVM2.${LVM2_VERSION}.tgz" \
| tar -xzC /usr/local/lvm2 --strip-components=1
# See https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags
# Fix platform enablement in lvm2 to support aarch64 properly
RUN set -e \
&& for f in config.guess config.sub; do \
curl -fsSL -o "/usr/local/lvm2/autoconf/$f" "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=$f;hb=HEAD"; \
done
# "arch.c:78:2: error: #error the arch code needs to know about your machine type"
# Compile and install lvm2
# Compile and install (only the needed library)
RUN cd /usr/local/lvm2 \
&& ./configure \
--build="$(gcc -print-multiarch)" \
--enable-static_link \
&& make device-mapper \
&& make install_device-mapper
# See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
--enable-pkgconfig \
&& make -C include \
&& make -C libdm install_device-mapper
# Install seccomp: the version shipped upstream is too old
ENV SECCOMP_VERSION 2.3.2

View File

@ -9,7 +9,7 @@
# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
#
# # Run the test suite:
# docker run --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py
# docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
#
# Note: AppArmor used to mess with privileged mode, but this is no longer
# the case. Therefore, you don't have to disable it anymore.
@ -53,21 +53,21 @@ RUN apt-get update && apt-get install -y \
--no-install-recommends \
&& pip install awscli==1.10.15
# Get lvm2 source for compiling statically
ENV LVM2_VERSION 2.02.103
# Get lvm2 sources to build statically linked devmapper library
ENV LVM2_VERSION 2.02.173
RUN mkdir -p /usr/local/lvm2 \
&& curl -fsSL "https://mirrors.kernel.org/sourceware/lvm2/LVM2.${LVM2_VERSION}.tgz" \
| tar -xzC /usr/local/lvm2 --strip-components=1
# See https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags
# Compile and install lvm2
# Compile and install (only the needed library)
RUN cd /usr/local/lvm2 \
&& ./configure \
--build="$(gcc -print-multiarch)" \
--enable-static_link \
&& make device-mapper \
&& make install_device-mapper
# See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
--enable-pkgconfig \
&& make -C include \
&& make -C libdm install_device-mapper
# Install Go
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored

View File

@ -9,7 +9,7 @@
# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
#
# # Run the test suite:
# docker run --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py
# docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
#
# Note: AppArmor used to mess with privileged mode, but this is no longer
# the case. Therefore, you don't have to disable it anymore.
@ -53,28 +53,20 @@ RUN apt-get update && apt-get install -y \
vim-common \
--no-install-recommends
# Get lvm2 source for compiling statically
ENV LVM2_VERSION 2.02.103
# Get lvm2 sources to build statically linked devmapper library
ENV LVM2_VERSION 2.02.173
RUN mkdir -p /usr/local/lvm2 \
&& curl -fsSL "https://mirrors.kernel.org/sourceware/lvm2/LVM2.${LVM2_VERSION}.tgz" \
| tar -xzC /usr/local/lvm2 --strip-components=1
# See https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags
# Fix platform enablement in lvm2 to support ppc64le properly
RUN set -e \
&& for f in config.guess config.sub; do \
curl -fsSL -o "/usr/local/lvm2/autoconf/$f" "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=$f;hb=HEAD"; \
done
# "arch.c:78:2: error: #error the arch code needs to know about your machine type"
# Compile and install lvm2
# Compile and install (only the needed library)
RUN cd /usr/local/lvm2 \
&& ./configure \
--build="$(gcc -print-multiarch)" \
--enable-static_link \
&& make device-mapper \
&& make install_device-mapper
# See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
--enable-pkgconfig \
&& make -C include \
&& make -C libdm install_device-mapper
# Install seccomp: the version shipped upstream is too old
ENV SECCOMP_VERSION 2.3.2

View File

@ -9,7 +9,7 @@
# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
#
# # Run the test suite:
# docker run --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py
# docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
#
# Note: AppArmor used to mess with privileged mode, but this is no longer
# the case. Therefore, you don't have to disable it anymore.
@ -64,28 +64,20 @@ RUN set -x \
) \
&& rm -rf "$SECCOMP_PATH"
# Get lvm2 source for compiling statically
ENV LVM2_VERSION 2.02.103
# Get lvm2 sources to build statically linked devmapper library
ENV LVM2_VERSION 2.02.173
RUN mkdir -p /usr/local/lvm2 \
&& curl -fsSL "https://mirrors.kernel.org/sourceware/lvm2/LVM2.${LVM2_VERSION}.tgz" \
| tar -xzC /usr/local/lvm2 --strip-components=1
# See https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags
# Fix platform enablement in lvm2 to support s390x properly
RUN set -e \
&& for f in config.guess config.sub; do \
curl -fsSL -o "/usr/local/lvm2/autoconf/$f" "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=$f;hb=HEAD"; \
done
# "arch.c:78:2: error: #error the arch code needs to know about your machine type"
# Compile and install lvm2
# Compile and install (only the needed library)
RUN cd /usr/local/lvm2 \
&& ./configure \
--build="$(gcc -print-multiarch)" \
--enable-static_link \
&& make device-mapper \
&& make install_device-mapper
# See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
--enable-pkgconfig \
&& make -C include \
&& make -C libdm install_device-mapper
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
ENV GO_VERSION 1.8.3

View File

@ -1,7 +1,7 @@
# docker build -t docker:simple -f Dockerfile.simple .
# docker run --rm docker:simple hack/make.sh dynbinary
# docker run --rm --privileged docker:simple hack/dind hack/make.sh test-unit
# docker run --rm --privileged -v /var/lib/docker docker:simple hack/dind hack/make.sh dynbinary test-integration-cli
# docker run --rm --privileged -v /var/lib/docker docker:simple hack/dind hack/make.sh dynbinary test-integration
# This represents the bare minimum required to build and test Docker.

View File

@ -90,6 +90,7 @@
"mgoelzer",
"programmerq",
"rheinwein",
"ripcurld0",
"thajeztah"
]
@ -390,6 +391,11 @@
Email = "laura@codeship.com"
GitHub = "rheinwein"
[people.ripcurld0]
Name = "Boaz Shuster"
Email = "ripcurld.github@gmail.com"
GitHub = "ripcurld0"
[people.runcom]
Name = "Antonio Murdaca"
Email = "runcom@redhat.com"

View File

@ -1,4 +1,4 @@
.PHONY: all binary dynbinary build cross deb help init-go-pkg-cache install manpages rpm run shell test test-docker-py test-integration-cli test-unit tgz validate win
.PHONY: all binary dynbinary build cross deb help init-go-pkg-cache install manpages rpm run shell test test-docker-py test-integration test-unit tgz validate win
# set the graph driver as the current graphdriver if not set
DOCKER_GRAPHDRIVER := $(if $(DOCKER_GRAPHDRIVER),$(DOCKER_GRAPHDRIVER),$(shell docker info 2>&1 | grep "Storage Driver" | sed 's/.*: //'))
@ -149,13 +149,15 @@ shell: build ## start a shell inside the build env
$(DOCKER_RUN_DOCKER) bash
test: build ## run the unit, integration and docker-py tests
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary cross test-unit test-integration-cli test-docker-py
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary cross test-unit test-integration test-docker-py
test-docker-py: build ## run the docker-py tests
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary test-docker-py
test-integration-cli: build ## run the integration tests
$(DOCKER_RUN_DOCKER) hack/make.sh build-integration-test-binary dynbinary test-integration-cli
test-integration-cli: test-integration ## (DEPRECATED) use test-integration
test-integration: build ## run the integration tests
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary test-integration
test-unit: build ## run the unit tests
$(DOCKER_RUN_DOCKER) hack/make.sh test-unit

View File

@ -15,7 +15,7 @@ import (
// Common constants for daemon and client.
const (
// DefaultVersion of Current REST API
DefaultVersion string = "1.31"
DefaultVersion string = "1.32"
// NoBaseImageSpecifier is the symbol used by the FROM
// command to specify that no base image is to be used.

View File

@ -4,10 +4,10 @@ import (
"net/http"
"strings"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/versions"
"github.com/gorilla/mux"
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
)

View File

@ -7,7 +7,7 @@ import (
"net/http"
"strings"
"github.com/Sirupsen/logrus"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -5,7 +5,6 @@ import (
"io"
"net/url"
"sort"
"strings"
"golang.org/x/net/context"
@ -53,7 +52,8 @@ func WriteLogStream(ctx context.Context, w io.Writer, msgs <-chan *backend.LogMe
}
logLine := msg.Line
if config.Details {
logLine = append([]byte(stringAttrs(msg.Attrs)+" "), logLine...)
logLine = append(attrsByteSlice(msg.Attrs), ' ')
logLine = append(logLine, msg.Line...)
}
if config.Timestamps {
// TODO(dperny) the format is defined in
@ -71,24 +71,26 @@ func WriteLogStream(ctx context.Context, w io.Writer, msgs <-chan *backend.LogMe
}
}
type byKey []string
type byKey []backend.LogAttr
func (s byKey) Len() int { return len(s) }
func (s byKey) Less(i, j int) bool {
keyI := strings.Split(s[i], "=")
keyJ := strings.Split(s[j], "=")
return keyI[0] < keyJ[0]
}
func (s byKey) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (b byKey) Len() int { return len(b) }
func (b byKey) Less(i, j int) bool { return b[i].Key < b[j].Key }
func (b byKey) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
func stringAttrs(a backend.LogAttributes) string {
var ss byKey
for k, v := range a {
k, v := url.QueryEscape(k), url.QueryEscape(v)
ss = append(ss, k+"="+v)
func attrsByteSlice(a []backend.LogAttr) []byte {
// Note this sorts "a" in-place. That is fine here - nothing else is
// going to use Attrs or care about the order.
sort.Sort(byKey(a))
var ret []byte
for i, pair := range a {
k, v := url.QueryEscape(pair.Key), url.QueryEscape(pair.Value)
ret = append(ret, []byte(k)...)
ret = append(ret, '=')
ret = append(ret, []byte(v)...)
if i != len(a)-1 {
ret = append(ret, ',')
}
}
sort.Sort(ss)
return strings.Join(ss, ",")
return ret
}

View File

@ -1,9 +1,9 @@
package server
import (
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/server/middleware"
"github.com/sirupsen/logrus"
)
// handlerWithGlobalMiddlewares wraps the handler function for a request with

View File

@ -3,7 +3,7 @@ package middleware
import (
"net/http"
"github.com/Sirupsen/logrus"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -7,9 +7,9 @@ import (
"net/http"
"strings"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/pkg/ioutils"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -12,7 +12,6 @@ import (
"strings"
"sync"
"github.com/Sirupsen/logrus"
apierrors "github.com/docker/docker/api/errors"
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types"
@ -24,6 +23,7 @@ import (
"github.com/docker/docker/pkg/streamformatter"
units "github.com/docker/go-units"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -8,7 +8,6 @@ import (
"strconv"
"syscall"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api"
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types"
@ -19,6 +18,7 @@ import (
containerpkg "github.com/docker/docker/container"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/signal"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
"golang.org/x/net/websocket"
)

View File

@ -7,11 +7,11 @@ import (
"net/http"
"strconv"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/pkg/stdcopy"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -16,6 +16,7 @@ import (
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/versions"
"github.com/docker/libnetwork"
netconst "github.com/docker/libnetwork/datastore"
"github.com/docker/libnetwork/networkdb"
)
@ -135,6 +136,17 @@ func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r
}
}
nwk, err := n.cluster.GetNetwork(term)
if err == nil {
// If the get network is passed with a specific network ID / partial network ID
// or if the get network was passed with a network name and scope as swarm
// 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) {
return httputils.WriteJSON(w, http.StatusOK, nwk)
}
}
nr, _ := n.cluster.GetNetworks()
for _, network := range nr {
if network.ID == term && isMatchingScope(network.Scope, scope) {
@ -397,7 +409,9 @@ func buildIpamResources(r *types.NetworkResource, nwInfo libnetwork.NetworkInfo)
for _, ip4Info := range ipv4Info {
iData := network.IPAMConfig{}
iData.Subnet = ip4Info.IPAMData.Pool.String()
iData.Gateway = ip4Info.IPAMData.Gateway.IP.String()
if ip4Info.IPAMData.Gateway != nil {
iData.Gateway = ip4Info.IPAMData.Gateway.IP.String()
}
r.IPAM.Config = append(r.IPAM.Config, iData)
}
}

View File

@ -6,7 +6,6 @@ import (
"net/http"
"strconv"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/errors"
"github.com/docker/docker/api/server/httputils"
basictypes "github.com/docker/docker/api/types"
@ -14,6 +13,7 @@ import (
"github.com/docker/docker/api/types/filters"
types "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/versions"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -6,7 +6,6 @@ import (
"net/http"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api"
"github.com/docker/docker/api/errors"
"github.com/docker/docker/api/server/httputils"
@ -18,6 +17,7 @@ import (
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/pkg/ioutils"
pkgerrors "github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -7,7 +7,6 @@ import (
"net/http"
"strings"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/errors"
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/server/middleware"
@ -15,6 +14,7 @@ import (
"github.com/docker/docker/api/server/router/debug"
"github.com/docker/docker/dockerversion"
"github.com/gorilla/mux"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -19,10 +19,10 @@ produces:
consumes:
- "application/json"
- "text/plain"
basePath: "/v1.31"
basePath: "/v1.32"
info:
title: "Docker Engine API"
version: "1.31"
version: "1.32"
x-logo:
url: "https://docs.docker.com/images/logo-docker-main.png"
description: |
@ -44,7 +44,7 @@ info:
The API is usually changed in each release of Docker, so API calls are versioned to ensure that clients don't break.
For Docker Engine 17.06, the API version is 1.30. To lock to this version, you prefix the URL with `/v1.30`. For example, calling `/info` is the same as calling `/v1.30/info`.
For Docker Engine 17.07, the API version is 1.31. To lock to this version, you prefix the URL with `/v1.31`. For example, calling `/info` is the same as calling `/v1.31/info`.
Engine releases in the near future should support this version of the API, so your client will continue to work even if it is talking to a newer Engine.
@ -52,10 +52,11 @@ info:
The API uses an open schema model, which means server may add extra properties to responses. Likewise, the server will ignore any extra query parameters and request body properties. When you write clients, you need to ignore additional properties in responses to ensure they do not break when talking to newer Docker daemons.
This documentation is for version 1.31 of the API. Use this table to find documentation for previous versions of the API:
This documentation is for version 1.32 of the API. Use this table to find documentation for previous versions of the API:
Docker version | API version | Changes
----------------|-------------|---------
17.07.x | [1.31](https://docs.docker.com/engine/api/v1.31/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-31-api-changes)
17.06.x | [1.30](https://docs.docker.com/engine/api/v1.30/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-30-api-changes)
17.05.x | [1.29](https://docs.docker.com/engine/api/v1.29/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-29-api-changes)
17.04.x | [1.28](https://docs.docker.com/engine/api/v1.28/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-28-api-changes)
@ -322,7 +323,6 @@ definitions:
MaximumRetryCount:
type: "integer"
description: "If `on-failure` is used, the number of times to retry before giving up"
default: {}
Resources:
description: "A container's resources (cgroups config, ulimits, etc)"
@ -487,6 +487,41 @@ definitions:
type: "integer"
format: "int64"
ResourceObject:
description: "An object describing the resources which can be advertised by a node and requested by a task"
type: "object"
properties:
NanoCPUs:
type: "integer"
format: "int64"
MemoryBytes:
type: "integer"
format: "int64"
GenericResources:
$ref: "#/definitions/GenericResources"
GenericResources:
description: "User defined Resources, can be either Integer resources (e.g: SSD=3) or String resources (e.g: GPU={UUID1, UUID2})"
type: "array"
items:
type: "object"
properties:
NamedResourceSpec:
type: "object"
properties:
Kind:
type: "string"
Value:
type: "string"
DiscreteResourceSpec:
type: "object"
properties:
Kind:
type: "string"
Value:
type: "integer"
format: "int64"
HealthConfig:
description: "A test to perform to check that the container is healthy."
type: "object"
@ -630,7 +665,17 @@ definitions:
type: "string"
IpcMode:
type: "string"
description: "IPC namespace to use for the container."
description: |
IPC sharing mode for the container. Possible values are:
- `"none"`: own private IPC namespace, with /dev/shm not mounted
- `"private"`: own private IPC namespace
- `"shareable"`: own private IPC namespace, with a possibility to share it with other containers
- `"container:<name|id>"`: join another (shareable) container's IPC namespace
- `"host"`: use the host system's IPC namespace
If not specified, daemon default is used, which can either be `"private"`
or `"shareable"`, depending on daemon version and configuration.
Cgroup:
type: "string"
description: "Cgroup to use for the container."
@ -1089,17 +1134,27 @@ definitions:
type: "string"
UsageData:
type: "object"
x-nullable: true
required: [Size, RefCount]
description: |
Usage details about the volume. This information is used by the
`GET /system/df` endpoint, and omitted in other endpoints.
properties:
Size:
type: "integer"
description: "The disk space used by the volume (local driver only)"
default: -1
description: |
Amount of disk space used by the volume (in bytes). This information
is only available for volumes created with the `"local"` volume
driver. For volumes created with other volume drivers, this field
is set to `-1` ("not available")
x-nullable: false
RefCount:
type: "integer"
default: -1
description: "The number of containers referencing this volume."
description: |
The number of containers referencing this volume. This field
is set to `-1` if the reference-count is not available.
x-nullable: false
example:
@ -1349,26 +1404,33 @@ definitions:
Name:
type: "string"
x-nullable: false
example: "some-mount"
Description:
type: "string"
x-nullable: false
example: "This is a mount that's used by the plugin."
Settable:
type: "array"
items:
type: "string"
Source:
type: "string"
example: "/var/lib/docker/plugins/"
Destination:
type: "string"
x-nullable: false
example: "/mnt/state"
Type:
type: "string"
x-nullable: false
example: "bind"
Options:
type: "array"
items:
type: "string"
example:
- "rbind"
- "rw"
PluginDevice:
type: "object"
required: [Name, Description, Settable, Path]
@ -1386,6 +1448,7 @@ definitions:
type: "string"
Path:
type: "string"
example: "/dev/fuse"
PluginEnv:
type: "object"
@ -1427,13 +1490,16 @@ definitions:
properties:
Id:
type: "string"
example: "5724e2c8652da337ab2eedd19fc6fc0ec908e4bd907c7421bf6a8dfc70c4c078"
Name:
type: "string"
x-nullable: false
example: "tiborvass/sample-volume-plugin"
Enabled:
description: "True when the plugin is running. False when the plugin is not running, only installed."
description: "True if the plugin is running. False if the plugin is not running, only installed."
type: "boolean"
x-nullable: false
example: true
Settings:
description: "Settings that can be modified by users."
type: "object"
@ -1448,6 +1514,8 @@ definitions:
type: "array"
items:
type: "string"
example:
- "DEBUG=0"
Args:
type: "array"
items:
@ -1460,6 +1528,7 @@ definitions:
description: "plugin remote reference used to push/pull the plugin"
type: "string"
x-nullable: false
example: "localhost:5000/tiborvass/sample-volume-plugin:latest"
Config:
description: "The config of a plugin."
type: "object"
@ -1483,12 +1552,15 @@ definitions:
description: "Docker Version used to create the plugin"
type: "string"
x-nullable: false
example: "17.06.0-ce"
Description:
type: "string"
x-nullable: false
example: "A sample volume plugin for Docker"
Documentation:
type: "string"
x-nullable: false
example: "https://docs.docker.com/engine/extend/plugins/"
Interface:
description: "The interface between Docker and the plugin"
x-nullable: false
@ -1499,16 +1571,23 @@ definitions:
type: "array"
items:
$ref: "#/definitions/PluginInterfaceType"
example:
- "docker.volumedriver/1.0"
Socket:
type: "string"
x-nullable: false
example: "plugins.sock"
Entrypoint:
type: "array"
items:
type: "string"
example:
- "/usr/bin/sample-volume-plugin"
- "/data"
WorkDir:
type: "string"
x-nullable: false
example: "/bin/"
User:
type: "object"
x-nullable: false
@ -1516,9 +1595,11 @@ definitions:
UID:
type: "integer"
format: "uint32"
example: 1000
GID:
type: "integer"
format: "uint32"
example: 1000
Network:
type: "object"
x-nullable: false
@ -1527,6 +1608,7 @@ definitions:
Type:
x-nullable: false
type: "string"
example: "host"
Linux:
type: "object"
x-nullable: false
@ -1536,9 +1618,13 @@ definitions:
type: "array"
items:
type: "string"
example:
- "CAP_SYS_ADMIN"
- "CAP_SYSLOG"
AllowAllDevices:
type: "boolean"
x-nullable: false
example: false
Devices:
type: "array"
items:
@ -1546,12 +1632,15 @@ definitions:
PropagatedMount:
type: "string"
x-nullable: false
example: "/mnt/volumes"
IpcHost:
type: "boolean"
x-nullable: false
example: false
PidHost:
type: "boolean"
x-nullable: false
example: false
Mounts:
type: "array"
items:
@ -1560,6 +1649,11 @@ definitions:
type: "array"
items:
$ref: "#/definitions/PluginEnv"
example:
- Name: "DEBUG"
Description: "If set, prints debug messages"
Settable: null
Value: "0"
Args:
type: "object"
x-nullable: false
@ -1568,9 +1662,11 @@ definitions:
Name:
x-nullable: false
type: "string"
example: "args"
Description:
x-nullable: false
type: "string"
example: "command line arguments"
Settable:
type: "array"
items:
@ -1584,50 +1680,14 @@ definitions:
properties:
type:
type: "string"
example: "layers"
diff_ids:
type: "array"
items:
type: "string"
example:
Id: "5724e2c8652da337ab2eedd19fc6fc0ec908e4bd907c7421bf6a8dfc70c4c078"
Name: "tiborvass/sample-volume-plugin"
Tag: "latest"
Active: true
Settings:
Env:
- "DEBUG=0"
Args: null
Devices: null
Config:
Description: "A sample volume plugin for Docker"
Documentation: "https://docs.docker.com/engine/extend/plugins/"
Interface:
Types:
- "docker.volumedriver/1.0"
Socket: "plugins.sock"
Entrypoint:
- "/usr/bin/sample-volume-plugin"
- "/data"
WorkDir: ""
User: {}
Network:
Type: ""
Linux:
Capabilities: null
AllowAllDevices: false
Devices: null
Mounts: null
PropagatedMount: "/data"
Env:
- Name: "DEBUG"
Description: "If set, prints debug messages"
Settable: null
Value: "0"
Args:
Name: "args"
Description: "command line arguments"
Settable: null
Value: []
example:
- "sha256:675532206fbf3030b8458f88d6e26d4eb1577688a25efec97154c94e8b6b4887"
- "sha256:e216a057b1cb1efc11f8a268f37ef62083e70b1b38323ba252e25ac88904a7e8"
ObjectVersion:
description: |
@ -1702,14 +1762,7 @@ definitions:
OS:
type: "string"
Resources:
type: "object"
properties:
NanoCPUs:
type: "integer"
format: "int64"
MemoryBytes:
type: "integer"
format: "int64"
$ref: "#/definitions/ResourceObject"
Engine:
type: "object"
properties:
@ -1750,6 +1803,16 @@ definitions:
Resources:
NanoCPUs: 4000000000
MemoryBytes: 8272408576
GenericResources:
- DiscreteResourceSpec:
Kind: "SSD"
Value: 3
- NamedResourceSpec:
Kind: "GPU"
Value: "UUID1"
- NamedResourceSpec:
Kind: "GPU"
Value: "UUID2"
Engine:
EngineVersion: "17.04.0"
Labels:
@ -1977,7 +2040,7 @@ definitions:
properties:
PluginSpec:
type: "object"
description: "Invalid when specified with `ContainerSpec`."
description: "Invalid when specified with `ContainerSpec`. *(Experimental release only.)*"
properties:
Name:
description: "The name or 'alias' to use for the plugin."
@ -2214,27 +2277,10 @@ definitions:
properties:
Limits:
description: "Define resources limits."
type: "object"
properties:
NanoCPUs:
description: "CPU limit in units of 10<sup>-9</sup> CPU shares."
type: "integer"
format: "int64"
MemoryBytes:
description: "Memory limit in Bytes."
type: "integer"
format: "int64"
$ref: "#/definitions/ResourceObject"
Reservation:
description: "Define resources reservation."
properties:
NanoCPUs:
description: "CPU reservation in units of 10<sup>-9</sup> CPU shares."
type: "integer"
format: "int64"
MemoryBytes:
description: "Memory reservation in Bytes."
type: "integer"
format: "int64"
$ref: "#/definitions/ResourceObject"
RestartPolicy:
description: "Specification for the restart policy which applies to containers created as part of this service."
type: "object"
@ -2365,6 +2411,8 @@ definitions:
NodeID:
description: "The ID of the node that this task is on."
type: "string"
AssignedGenericResources:
$ref: "#/definitions/GenericResources"
Status:
type: "object"
properties:
@ -2444,6 +2492,16 @@ definitions:
Gateway: "10.255.0.1"
Addresses:
- "10.255.0.10/16"
AssignedGenericResources:
- DiscreteResourceSpec:
Kind: "SSD"
Value: 3
- NamedResourceSpec:
Kind: "GPU"
Value: "UUID1"
- NamedResourceSpec:
Kind: "GPU"
Value: "UUID2"
ServiceSpec:
description: "User modifiable configuration for a service."
properties:
@ -2780,6 +2838,27 @@ definitions:
type: "array"
items:
$ref: "#/definitions/Mount"
Driver:
description: "Driver represents a driver (network, logging, secrets)."
type: "object"
required: [Name]
properties:
Name:
description: "Name of the driver."
type: "string"
x-nullable: false
example: "some-driver"
Options:
description: "Key/value map of driver-specific options."
type: "object"
x-nullable: false
additionalProperties:
type: "string"
example:
OptionA: "value for driver-specific option A"
OptionB: "value for driver-specific option B"
SecretSpec:
type: "object"
properties:
@ -2791,24 +2870,38 @@ definitions:
type: "object"
additionalProperties:
type: "string"
example:
com.example.some-label: "some-value"
com.example.some-other-label: "some-other-value"
Data:
description: "Base64-url-safe-encoded secret data"
type: "array"
items:
type: "string"
description: |
Base64-url-safe-encoded ([RFC 4648](https://tools.ietf.org/html/rfc4648#section-3.2))
data to store as secret.
This field is only used to _create_ a secret, and is not returned by
other endpoints.
type: "string"
example: ""
Driver:
description: "Name of the secrets driver used to fetch the secret's value from an external secret store"
$ref: "#/definitions/Driver"
Secret:
type: "object"
properties:
ID:
type: "string"
example: "blt1owaxmitz71s9v5zh81zun"
Version:
$ref: "#/definitions/ObjectVersion"
CreatedAt:
type: "string"
format: "dateTime"
example: "2017-07-20T13:55:28.678958722Z"
UpdatedAt:
type: "string"
format: "dateTime"
example: "2017-07-20T13:55:28.678958722Z"
Spec:
$ref: "#/definitions/SecretSpec"
ConfigSpec:
@ -2823,10 +2916,10 @@ definitions:
additionalProperties:
type: "string"
Data:
description: "Base64-url-safe-encoded config data"
type: "array"
items:
type: "string"
description: |
Base64-url-safe-encoded ([RFC 4648](https://tools.ietf.org/html/rfc4648#section-3.2))
config data.
type: "string"
Config:
type: "object"
properties:
@ -5506,6 +5599,8 @@ paths:
type: "string"
MemTotal:
type: "integer"
GenericResources:
$ref: "#/definitions/GenericResources"
MemoryLimit:
type: "boolean"
NCPU:
@ -5949,13 +6044,13 @@ paths:
-
Name: "my-volume"
Driver: "local"
Mountpoint: ""
Mountpoint: "/var/lib/docker/volumes/my-volume/_data"
Labels: null
Scope: ""
Scope: "local"
Options: null
UsageData:
Size: 0
RefCount: 0
Size: 10920104
RefCount: 2
500:
description: "server error"
schema:
@ -6887,46 +6982,6 @@ paths:
type: "array"
items:
$ref: "#/definitions/Plugin"
example:
- Id: "5724e2c8652da337ab2eedd19fc6fc0ec908e4bd907c7421bf6a8dfc70c4c078"
Name: "tiborvass/sample-volume-plugin"
Tag: "latest"
Active: true
Settings:
Env:
- "DEBUG=0"
Args: null
Devices: null
Config:
Description: "A sample volume plugin for Docker"
Documentation: "https://docs.docker.com/engine/extend/plugins/"
Interface:
Types:
- "docker.volumedriver/1.0"
Socket: "plugins.sock"
Entrypoint:
- "/usr/bin/sample-volume-plugin"
- "/data"
WorkDir: ""
User: {}
Network:
Type: ""
Linux:
Capabilities: null
AllowAllDevices: false
Devices: null
Mounts: null
PropagatedMount: "/data"
Env:
- Name: "DEBUG"
Description: "If set, prints debug messages"
Settable: null
Value: "0"
Args:
Name: "args"
Description: "command line arguments"
Settable: null
Value: []
500:
description: "Server error"
schema:
@ -8416,6 +8471,20 @@ paths:
items:
$ref: "#/definitions/Secret"
example:
- ID: "blt1owaxmitz71s9v5zh81zun"
Version:
Index: 85
CreatedAt: "2017-07-20T13:55:28.678958722Z"
UpdatedAt: "2017-07-20T13:55:28.678958722Z"
Spec:
Name: "mysql-passwd"
Labels:
some.label: "some.value"
Driver:
Name: "secret-bucket"
Options:
OptionA: "value for driver option A"
OptionB: "value for driver option B"
- ID: "ktnbjxoalbkvbvedmg1urrz8h"
Version:
Index: 11
@ -8423,6 +8492,8 @@ paths:
UpdatedAt: "2016-11-05T01:20:17.327670065Z"
Spec:
Name: "app-dev.crt"
Labels:
foo: "bar"
500:
description: "server error"
schema:
@ -8486,6 +8557,11 @@ paths:
Labels:
foo: "bar"
Data: "VEhJUyBJUyBOT1QgQSBSRUFMIENFUlRJRklDQVRFCg=="
Driver:
Name: "secret-bucket"
Options:
OptionA: "value for driver option A"
OptionB: "value for driver option B"
tags: ["Secret"]
/secrets/{id}:
get:
@ -8507,6 +8583,14 @@ paths:
UpdatedAt: "2016-11-05T01:20:17.327670065Z"
Spec:
Name: "app-dev.crt"
Labels:
foo: "bar"
Driver:
Name: "secret-bucket"
Options:
OptionA: "value for driver option A"
OptionB: "value for driver option B"
404:
description: "secret not found"
schema:

View File

@ -35,7 +35,7 @@ type LogMessage struct {
Line []byte
Source string
Timestamp time.Time
Attrs LogAttributes
Attrs []LogAttr
Partial bool
// Err is an error associated with a message. Completeness of a message
@ -44,9 +44,11 @@ type LogMessage struct {
Err error
}
// LogAttributes is used to hold the extra attributes available in the log message
// Primarily used for converting the map type to string and sorting.
type LogAttributes map[string]string
// LogAttr is used to hold the extra attributes available in the log message.
type LogAttr struct {
Key string
Value string
}
// LogSelector is a list of services and tasks that should be returned as part
// of a log stream. It is similar to swarmapi.LogSelector, with the difference

View File

@ -23,41 +23,46 @@ func (i Isolation) IsDefault() bool {
// IpcMode represents the container ipc stack.
type IpcMode string
// IsPrivate indicates whether the container uses its private ipc stack.
// IsPrivate indicates whether the container uses its own private ipc namespace which can not be shared.
func (n IpcMode) IsPrivate() bool {
return !(n.IsHost() || n.IsContainer())
return n == "private"
}
// IsHost indicates whether the container uses the host's ipc stack.
// IsHost indicates whether the container shares the host's ipc namespace.
func (n IpcMode) IsHost() bool {
return n == "host"
}
// IsContainer indicates whether the container uses a container's ipc stack.
// IsShareable indicates whether the container's ipc namespace can be shared with another container.
func (n IpcMode) IsShareable() bool {
return n == "shareable"
}
// IsContainer indicates whether the container uses another container's ipc namespace.
func (n IpcMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
return len(parts) > 1 && parts[0] == "container"
}
// Valid indicates whether the ipc stack is valid.
// IsNone indicates whether container IpcMode is set to "none".
func (n IpcMode) IsNone() bool {
return n == "none"
}
// IsEmpty indicates whether container IpcMode is empty
func (n IpcMode) IsEmpty() bool {
return n == ""
}
// Valid indicates whether the ipc mode is valid.
func (n IpcMode) Valid() bool {
parts := strings.Split(string(n), ":")
switch mode := parts[0]; mode {
case "", "host":
case "container":
if len(parts) != 2 || parts[1] == "" {
return false
}
default:
return false
}
return true
return n.IsEmpty() || n.IsNone() || n.IsPrivate() || n.IsHost() || n.IsShareable() || n.IsContainer()
}
// Container returns the name of the container ipc stack is going to be used.
func (n IpcMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
if len(parts) > 1 {
if len(parts) > 1 && parts[0] == "container" {
return parts[1]
}
return ""

View File

@ -15,6 +15,8 @@ const (
TypeVolume Type = "volume"
// TypeTmpfs is the type for mounting tmpfs
TypeTmpfs Type = "tmpfs"
// TypeNamedPipe is the type for mounting Windows named pipes
TypeNamedPipe Type = "npipe"
)
// Mount represents a mount (volume).

View File

@ -11,7 +11,7 @@ type Plugin struct {
// Required: true
Config PluginConfig `json:"Config"`
// True when the plugin is running. False when the plugin is not running, only installed.
// True if the plugin is running. False if the plugin is not running, only installed.
// Required: true
Enabled bool `json:"Enabled"`

View File

@ -9,14 +9,6 @@ import (
// PluginsListResponse contains the response for the Engine API
type PluginsListResponse []*Plugin
const (
authzDriver = "AuthzDriver"
graphDriver = "GraphDriver"
ipamDriver = "IpamDriver"
networkDriver = "NetworkDriver"
volumeDriver = "VolumeDriver"
)
// UnmarshalJSON implements json.Unmarshaler for PluginInterfaceType
func (t *PluginInterfaceType) UnmarshalJSON(p []byte) error {
versionIndex := len(p)

View File

@ -20,7 +20,7 @@ type Annotations struct {
Labels map[string]string `json:"Labels"`
}
// Driver represents a driver (network, logging).
// Driver represents a driver (network, logging, secrets backend).
type Driver struct {
Name string `json:",omitempty"`
Options map[string]string `json:",omitempty"`

View File

@ -51,6 +51,7 @@ type Task struct {
Status TaskStatus `json:",omitempty"`
DesiredState TaskState `json:",omitempty"`
NetworksAttachments []NetworkAttachment `json:",omitempty"`
GenericResources []GenericResource `json:",omitempty"`
}
// TaskSpec represents the spec of a task.
@ -79,8 +80,34 @@ type TaskSpec struct {
// Resources represents resources (CPU/Memory).
type Resources struct {
NanoCPUs int64 `json:",omitempty"`
MemoryBytes int64 `json:",omitempty"`
NanoCPUs int64 `json:",omitempty"`
MemoryBytes int64 `json:",omitempty"`
GenericResources []GenericResource `json:",omitempty"`
}
// GenericResource represents a "user defined" resource which can
// be either an integer (e.g: SSD=3) or a string (e.g: SSD=sda1)
type GenericResource struct {
NamedResourceSpec *NamedGenericResource `json:",omitempty"`
DiscreteResourceSpec *DiscreteGenericResource `json:",omitempty"`
}
// NamedGenericResource represents a "user defined" resource which is defined
// as a string.
// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...)
// Value is used to identify the resource (GPU="UUID-1", FPGA="/dev/sdb5", ...)
type NamedGenericResource struct {
Kind string `json:",omitempty"`
Value string `json:",omitempty"`
}
// DiscreteGenericResource represents a "user defined" resource which is defined
// as an integer
// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...)
// Value is used to count the resource (SSD=5, HDD=3, ...)
type DiscreteGenericResource struct {
Kind string `json:",omitempty"`
Value int64 `json:",omitempty"`
}
// ResourceRequirements represents resources requirements.

View File

@ -168,6 +168,7 @@ type Info struct {
RegistryConfig *registry.ServiceConfig
NCPU int
MemTotal int64
GenericResources []swarm.GenericResource
DockerRootDir string
HTTPProxy string `json:"HttpProxy"`
HTTPSProxy string `json:"HttpsProxy"`

View File

@ -47,15 +47,23 @@ type Volume struct {
UsageData *VolumeUsageData `json:"UsageData,omitempty"`
}
// VolumeUsageData volume usage data
// VolumeUsageData Usage details about the volume. This information is used by the
// `GET /system/df` endpoint, and omitted in other endpoints.
//
// swagger:model VolumeUsageData
type VolumeUsageData struct {
// The number of containers referencing this volume.
// The number of containers referencing this volume. This field
// is set to `-1` if the reference-count is not available.
//
// Required: true
RefCount int64 `json:"RefCount"`
// The disk space used by the volume (local driver only)
// Amount of disk space used by the volume (in bytes). This information
// is only available for volumes created with the `"local"` volume
// driver. For volumes created with other volume drivers, this field
// is set to `-1` ("not available")
//
// Required: true
Size int64 `json:"Size"`
}

View File

@ -9,7 +9,6 @@ import (
"strings"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/container"
@ -18,14 +17,15 @@ import (
"github.com/docker/docker/builder/dockerfile/parser"
"github.com/docker/docker/builder/fscache"
"github.com/docker/docker/builder/remotecontext"
"github.com/docker/docker/client/session"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/chrootarchive"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/system"
"github.com/moby/buildkit/session"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
"golang.org/x/sync/syncmap"
)

View File

@ -5,8 +5,8 @@ import (
"github.com/docker/docker/builder/fscache"
"github.com/docker/docker/builder/remotecontext"
"github.com/docker/docker/client/session"
"github.com/docker/docker/client/session/filesync"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/filesync"
"github.com/pkg/errors"
"golang.org/x/net/context"
)

View File

@ -4,13 +4,13 @@ import (
"fmt"
"io"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/builder"
containerpkg "github.com/docker/docker/container"
"github.com/docker/docker/pkg/stringid"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -17,7 +17,6 @@ import (
"strings"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/strslice"
@ -29,6 +28,7 @@ import (
"github.com/docker/docker/pkg/system"
"github.com/docker/go-connections/nat"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// ENV foo bar

View File

@ -4,12 +4,12 @@ import (
"strconv"
"strings"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/builder"
"github.com/docker/docker/builder/remotecontext"
dockerimage "github.com/docker/docker/image"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -1,9 +1,9 @@
package dockerfile
import (
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/builder"
"github.com/sirupsen/logrus"
)
// ImageProber exposes an Image cache to the Builder. It supports resetting a

View File

@ -8,14 +8,14 @@ import (
"sync"
"time"
"github.com/Sirupsen/logrus"
"github.com/boltdb/bolt"
"github.com/docker/docker/builder"
"github.com/docker/docker/builder/remotecontext"
"github.com/docker/docker/client/session/filesync"
"github.com/docker/docker/pkg/directory"
"github.com/docker/docker/pkg/stringid"
"github.com/moby/buildkit/session/filesync"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/tonistiigi/fsutil"
"golang.org/x/net/context"
"golang.org/x/sync/singleflight"

View File

@ -7,7 +7,7 @@ import (
"testing"
"time"
"github.com/docker/docker/client/session/filesync"
"github.com/moby/buildkit/session/filesync"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
)

View File

@ -8,7 +8,6 @@ import (
"path/filepath"
"strings"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/builder"
"github.com/docker/docker/builder/dockerfile/parser"
@ -17,6 +16,7 @@ import (
"github.com/docker/docker/pkg/symlink"
"github.com/docker/docker/pkg/urlutil"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// ClientSessionRemote is identifier for client-session context transport

View File

@ -1,7 +1,6 @@
package git
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
@ -98,22 +97,46 @@ func getRefAndSubdir(fragment string) (ref string, subdir string) {
func fetchArgs(remoteURL string, ref string) []string {
args := []string{"fetch", "--recurse-submodules=yes"}
shallow := true
if urlutil.IsURL(remoteURL) {
res, err := http.Head(fmt.Sprintf("%s/info/refs?service=git-upload-pack", remoteURL))
if err != nil || res.Header.Get("Content-Type") != "application/x-git-upload-pack-advertisement" {
shallow = false
}
}
if shallow {
if supportsShallowClone(remoteURL) {
args = append(args, "--depth", "1")
}
return append(args, "origin", ref)
}
// Check if a given git URL supports a shallow git clone,
// i.e. it is a non-HTTP server or a smart HTTP server.
func supportsShallowClone(remoteURL string) bool {
if urlutil.IsURL(remoteURL) {
// Check if the HTTP server is smart
// Smart servers must correctly respond to a query for the git-upload-pack service
serviceURL := remoteURL + "/info/refs?service=git-upload-pack"
// Try a HEAD request and fallback to a Get request on error
res, err := http.Head(serviceURL)
if err != nil || res.StatusCode != http.StatusOK {
res, err = http.Get(serviceURL)
if err == nil {
res.Body.Close()
}
if err != nil || res.StatusCode != http.StatusOK {
// request failed
return false
}
}
if res.Header.Get("Content-Type") != "application/x-git-upload-pack-advertisement" {
// Fallback, not a smart server
return false
}
return true
}
// Non-HTTP protocols always support shallow clones
return true
}
func checkoutGit(root, ref, subdir string) (string, error) {
// Try checking out by ref name first. This will work on branches and sets
// .git/HEAD to the current branch name

View File

@ -3,7 +3,7 @@ package debug
import (
"os"
"github.com/Sirupsen/logrus"
"github.com/sirupsen/logrus"
)
// Enable sets the DEBUG env var to true

View File

@ -4,7 +4,7 @@ import (
"os"
"testing"
"github.com/Sirupsen/logrus"
"github.com/sirupsen/logrus"
)
func TestEnable(t *testing.T) {

View File

@ -165,7 +165,7 @@ func NewClient(host string, version string, client *http.Client, httpHeaders map
}
if client != nil {
if _, ok := client.Transport.(*http.Transport); !ok {
if _, ok := client.Transport.(http.RoundTripper); !ok {
return nil, fmt.Errorf("unable to verify TLS configuration, invalid transport %v", client.Transport)
}
} else {

View File

@ -177,12 +177,14 @@ func (cli *Client) setupHijackConn(req *http.Request, proto string) (net.Conn, e
// Server hijacks the connection, error 'connection closed' expected
resp, err := clientconn.Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusSwitchingProtocols {
resp.Body.Close()
return nil, fmt.Errorf("unable to upgrade to %s, received %d", proto, resp.StatusCode)
if err != httputil.ErrPersistEOF {
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusSwitchingProtocols {
resp.Body.Close()
return nil, fmt.Errorf("unable to upgrade to %s, received %d", proto, resp.StatusCode)
}
}
c, br := clientconn.Hijack()

View File

@ -1,71 +0,0 @@
package filesync
import (
"context"
"io/ioutil"
"path/filepath"
"testing"
"github.com/docker/docker/client/session"
"github.com/docker/docker/client/session/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup"
)
func TestFileSyncIncludePatterns(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "fsynctest")
require.NoError(t, err)
destDir, err := ioutil.TempDir("", "fsynctest")
require.NoError(t, err)
err = ioutil.WriteFile(filepath.Join(tmpDir, "foo"), []byte("content1"), 0600)
require.NoError(t, err)
err = ioutil.WriteFile(filepath.Join(tmpDir, "bar"), []byte("content2"), 0600)
require.NoError(t, err)
s, err := session.NewSession("foo", "bar")
require.NoError(t, err)
m, err := session.NewManager()
require.NoError(t, err)
fs := NewFSSyncProvider(tmpDir, nil)
s.Allow(fs)
dialer := session.Dialer(testutil.TestStream(testutil.Handler(m.HandleConn)))
g, ctx := errgroup.WithContext(context.Background())
g.Go(func() error {
return s.Run(ctx, dialer)
})
g.Go(func() (reterr error) {
c, err := m.Get(ctx, s.UUID())
if err != nil {
return err
}
if err := FSSync(ctx, c, FSSendRequestOpt{
DestDir: destDir,
IncludePatterns: []string{"ba*"},
}); err != nil {
return err
}
_, err = ioutil.ReadFile(filepath.Join(destDir, "foo"))
assert.Error(t, err)
dt, err := ioutil.ReadFile(filepath.Join(destDir, "bar"))
if err != nil {
return err
}
assert.Equal(t, "content2", string(dt))
return s.Close()
})
err = g.Wait()
require.NoError(t, err)
}

View File

@ -1,70 +0,0 @@
package testutil
import (
"io"
"net"
"time"
"github.com/Sirupsen/logrus"
"golang.org/x/net/context"
)
// Handler is function called to handle incoming connection
type Handler func(ctx context.Context, conn net.Conn, meta map[string][]string) error
// Dialer is a function for dialing an outgoing connection
type Dialer func(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error)
// TestStream creates an in memory session dialer for a handler function
func TestStream(handler Handler) Dialer {
s1, s2 := sockPair()
return func(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error) {
go func() {
err := handler(context.TODO(), s1, meta)
if err != nil {
logrus.Error(err)
}
s1.Close()
}()
return s2, nil
}
}
func sockPair() (*sock, *sock) {
pr1, pw1 := io.Pipe()
pr2, pw2 := io.Pipe()
return &sock{pw1, pr2, pw1}, &sock{pw2, pr1, pw2}
}
type sock struct {
io.Writer
io.Reader
io.Closer
}
func (s *sock) LocalAddr() net.Addr {
return dummyAddr{}
}
func (s *sock) RemoteAddr() net.Addr {
return dummyAddr{}
}
func (s *sock) SetDeadline(t time.Time) error {
return nil
}
func (s *sock) SetReadDeadline(t time.Time) error {
return nil
}
func (s *sock) SetWriteDeadline(t time.Time) error {
return nil
}
type dummyAddr struct {
}
func (d dummyAddr) Network() string {
return "tcp"
}
func (d dummyAddr) String() string {
return "localhost"
}

View File

@ -62,6 +62,9 @@ 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.StringVar(&conf.NodeGenericResources, "node-generic-resources", "", "user defined resources (e.g. fpga=2;gpu={UUID1,UUID2,UUID3})")
flags.IntVar(&conf.NetworkControlPlaneMTU, "network-control-plane-mtu", config.DefaultNetworkMtu, "Network Control plane MTU")
// "--deprecated-key-path" is to allow configuration of the key used
// for the daemon ID and the deprecated image signing. It was never
// exposed as a command line option but is added here to allow

View File

@ -47,6 +47,7 @@ func installConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
flags.StringVar(&conf.SeccompProfile, "seccomp-profile", "", "Path to seccomp profile")
flags.Var(&conf.ShmSize, "default-shm-size", "Default shm size for containers")
flags.BoolVar(&conf.NoNewPrivileges, "no-new-privileges", false, "Set no-new-privileges by default for new containers")
flags.StringVar(&conf.IpcMode, "default-ipc-mode", config.DefaultIpcMode, `Default mode for containers ipc ("shareable" | "private")`)
attachExperimentalFlags(conf, flags)
}

View File

@ -9,7 +9,6 @@ import (
"strings"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/uuid"
"github.com/docker/docker/api"
apiserver "github.com/docker/docker/api/server"
@ -30,17 +29,16 @@ import (
"github.com/docker/docker/builder/dockerfile"
"github.com/docker/docker/builder/fscache"
"github.com/docker/docker/cli/debug"
"github.com/docker/docker/client/session"
"github.com/docker/docker/daemon"
"github.com/docker/docker/daemon/cluster"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/daemon/listeners"
"github.com/docker/docker/daemon/logger"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/libcontainerd"
dopts "github.com/docker/docker/opts"
"github.com/docker/docker/pkg/authorization"
"github.com/docker/docker/pkg/jsonlog"
"github.com/docker/docker/pkg/listeners"
"github.com/docker/docker/pkg/pidfile"
"github.com/docker/docker/pkg/plugingetter"
"github.com/docker/docker/pkg/signal"
@ -50,7 +48,9 @@ import (
"github.com/docker/docker/runconfig"
"github.com/docker/go-connections/tlsconfig"
swarmapi "github.com/docker/swarmkit/api"
"github.com/moby/buildkit/session"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
)
@ -96,6 +96,7 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) {
logrus.SetFormatter(&logrus.TextFormatter{
TimestampFormat: jsonlog.RFC3339NanoFixed,
DisableColors: cli.Config.RawLogs,
FullTimestamp: true,
})
if err := setDefaultUmask(); err != nil {
@ -205,7 +206,7 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) {
signal.Trap(func() {
cli.stop()
<-stopc // wait for daemonCli.start() to return
})
}, logrus.StandardLogger())
// Notify that the API is active, but before daemon is set up.
preNotifySystem()

View File

@ -3,10 +3,10 @@ package main
import (
"testing"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/pkg/testutil"
"github.com/docker/docker/pkg/testutil/tempfile"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

View File

@ -6,9 +6,9 @@ import (
"os"
"path/filepath"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/libcontainerd"
"github.com/docker/docker/pkg/system"
"github.com/sirupsen/logrus"
"golang.org/x/sys/windows"
)

View File

@ -6,12 +6,12 @@ import (
"path/filepath"
"runtime"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/cli"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/pkg/reexec"
"github.com/docker/docker/pkg/term"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

View File

@ -4,8 +4,8 @@ import (
"net"
"net/http"
"github.com/Sirupsen/logrus"
metrics "github.com/docker/go-metrics"
"github.com/sirupsen/logrus"
)
func startMetricsServer(addr string) error {

View File

@ -5,11 +5,11 @@ import (
"os"
"path/filepath"
"github.com/Sirupsen/logrus"
cliconfig "github.com/docker/docker/cli/config"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/opts"
"github.com/docker/go-connections/tlsconfig"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
)

View File

@ -12,8 +12,8 @@ import (
"time"
"unsafe"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/system"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/svc"

View File

@ -15,7 +15,6 @@ import (
"syscall"
"time"
"github.com/Sirupsen/logrus"
containertypes "github.com/docker/docker/api/types/container"
mounttypes "github.com/docker/docker/api/types/mount"
networktypes "github.com/docker/docker/api/types/network"
@ -44,6 +43,7 @@ import (
"github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/types"
agentexec "github.com/docker/swarmkit/agent/exec"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)
@ -167,7 +167,7 @@ func (container *Container) toDisk() (*Container, error) {
}
// Save container settings
f, err := ioutils.NewAtomicFileWriter(pth, 0644)
f, err := ioutils.NewAtomicFileWriter(pth, 0600)
if err != nil {
return nil, err
}
@ -745,6 +745,9 @@ func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epC
for _, alias := range epConfig.Aliases {
createOptions = append(createOptions, libnetwork.CreateOptionMyAlias(alias))
}
for k, v := range epConfig.DriverOpts {
createOptions = append(createOptions, libnetwork.EndpointOptionGeneric(options.Generic{k: v}))
}
}
if container.NetworkSettings.Service != nil {
@ -790,9 +793,6 @@ func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epC
createOptions = append(createOptions, libnetwork.EndpointOptionGeneric(genericOption))
}
for k, v := range epConfig.DriverOpts {
createOptions = append(createOptions, libnetwork.EndpointOptionGeneric(options.Generic{k: v}))
}
}

View File

@ -7,9 +7,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types"
containertypes "github.com/docker/docker/api/types/container"
mounttypes "github.com/docker/docker/api/types/mount"
@ -20,6 +18,8 @@ import (
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/volume"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
@ -171,47 +171,47 @@ func (container *Container) HasMountFor(path string) bool {
return exists
}
// UnmountIpcMounts uses the provided unmount function to unmount shm and mqueue if they were mounted
func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
if container.HostConfig.IpcMode.IsContainer() || container.HostConfig.IpcMode.IsHost() {
return
// UnmountIpcMount uses the provided unmount function to unmount shm if it was mounted
func (container *Container) UnmountIpcMount(unmount func(pth string) error) error {
if container.HasMountFor("/dev/shm") {
return nil
}
var warnings []string
if !container.HasMountFor("/dev/shm") {
shmPath, err := container.ShmResourcePath()
if err != nil {
logrus.Error(err)
warnings = append(warnings, err.Error())
} else if shmPath != "" {
if err := unmount(shmPath); err != nil && !os.IsNotExist(err) {
if mounted, mErr := mount.Mounted(shmPath); mounted || mErr != nil {
warnings = append(warnings, fmt.Sprintf("failed to umount %s: %v", shmPath, err))
}
}
// container.ShmPath should not be used here as it may point
// to the host's or other container's /dev/shm
shmPath, err := container.ShmResourcePath()
if err != nil {
return err
}
if shmPath == "" {
return nil
}
if err = unmount(shmPath); err != nil && !os.IsNotExist(err) {
if mounted, mErr := mount.Mounted(shmPath); mounted || mErr != nil {
return errors.Wrapf(err, "umount %s", shmPath)
}
}
if len(warnings) > 0 {
logrus.Warnf("failed to cleanup ipc mounts:\n%v", strings.Join(warnings, "\n"))
}
return nil
}
// IpcMounts returns the list of IPC mounts
func (container *Container) IpcMounts() []Mount {
var mounts []Mount
if !container.HasMountFor("/dev/shm") {
label.SetFileLabel(container.ShmPath, container.MountLabel)
mounts = append(mounts, Mount{
Source: container.ShmPath,
Destination: "/dev/shm",
Writable: true,
Propagation: string(volume.DefaultPropagationMode),
})
if container.HasMountFor("/dev/shm") {
return mounts
}
if container.ShmPath == "" {
return mounts
}
label.SetFileLabel(container.ShmPath, container.MountLabel)
mounts = append(mounts, Mount{
Source: container.ShmPath,
Destination: "/dev/shm",
Writable: true,
Propagation: string(volume.DefaultPropagationMode),
})
return mounts
}

View File

@ -24,9 +24,10 @@ type ExitStatus struct {
ExitCode int
}
// UnmountIpcMounts unmounts Ipc related mounts.
// UnmountIpcMount unmounts Ipc related mounts.
// This is a NOOP on windows.
func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
func (container *Container) UnmountIpcMount(unmount func(pth string) error) error {
return nil
}
// IpcMounts returns the list of Ipc related mounts.

View File

@ -1,8 +1,8 @@
package container
import (
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types"
"github.com/sirupsen/logrus"
)
// Health holds the current container health-check state

View File

@ -3,7 +3,7 @@ package container
import (
"time"
"github.com/Sirupsen/logrus"
"github.com/sirupsen/logrus"
)
const (

View File

@ -6,10 +6,10 @@ import (
"golang.org/x/net/context"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/pools"
"github.com/docker/docker/pkg/promise"
"github.com/docker/docker/pkg/term"
"github.com/sirupsen/logrus"
)
var defaultEscapeSequence = []byte{16, 17} // ctrl-p, ctrl-q

View File

@ -7,11 +7,11 @@ import (
"strings"
"sync"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/libcontainerd"
"github.com/docker/docker/pkg/broadcaster"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/pools"
"github.com/sirupsen/logrus"
)
// Config holds information about I/O streams managed together.

View File

@ -6,11 +6,11 @@ import (
"strings"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/network"
"github.com/docker/go-connections/nat"
"github.com/hashicorp/go-memdb"
"github.com/sirupsen/logrus"
)
const (
@ -168,9 +168,9 @@ func (db *memDB) Delete(c *Container) error {
txn.Delete(memdbNamesTable, nameAssociation{name: name})
}
if err := txn.Delete(memdbContainersTable, NewBaseContainer(c.ID, c.Root)); err != nil {
return err
}
// Ignore error - the container may not actually exist in the
// db, but we still need to clean up associated names.
txn.Delete(memdbContainersTable, NewBaseContainer(c.ID, c.Root))
return nil
})
}

View File

@ -150,4 +150,12 @@ func TestNames(t *testing.T) {
view = db.Snapshot()
assert.Equal(t, map[string][]string{"containerid1": {"name1", "name3", "name4"}, "containerid4": {"name2"}}, view.GetAllNames())
// Release containerid1's names with Delete even though no container exists
assert.NoError(t, db.Delete(&Container{ID: "containerid1"}))
// Reusing one of those names should work
assert.NoError(t, db.ReserveName("name1", "containerid4"))
view = db.Snapshot()
assert.Equal(t, map[string][]string{"containerid4": {"name1", "name2"}}, view.GetAllNames())
}

View File

@ -11,9 +11,9 @@ import (
"strconv"
"strings"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/daemon/graphdriver/devmapper"
"github.com/docker/docker/pkg/devicemapper"
"github.com/sirupsen/logrus"
)
func usage() {

View File

@ -64,7 +64,7 @@ fetch_blob() {
-D-
)"
curlHeaders="$(echo "$curlHeaders" | tr -d '\r')"
if [ "$(echo "$curlHeaders" | awk 'NR == 1 { print $2; exit }')" != '200' ]; then
if echo "$curlHeaders" | grep -qE "^HTTP/[0-9].[0-9] 3"; then
rm -f "$targetFile"
local blobRedirect="$(echo "$curlHeaders" | awk -F ': ' 'tolower($1) == "location" { print $2; exit }')"

View File

@ -81,13 +81,13 @@ fi
if [[ -n "$install_groups" ]];
then
yum -c "$yum_config" --installroot="$target" --releasever=/ --setopt=tsflags=nodocs \
--setopt=group_package_types=mandatory -y groupinstall $install_groups
--setopt=group_package_types=mandatory -y groupinstall "$install_groups"
fi
if [[ -n "$install_packages" ]];
then
yum -c "$yum_config" --installroot="$target" --releasever=/ --setopt=tsflags=nodocs \
--setopt=group_package_types=mandatory -y install $install_packages
--setopt=group_package_types=mandatory -y install "$install_packages"
fi
yum -c "$yum_config" --installroot="$target" -y clean all

View File

@ -25,7 +25,7 @@
</dict>
</dict>
<key>match</key>
<string>^\s*\b(FROM)\b.*?\b(AS)\b</string>
<string>^\s*\b(?i:(FROM))\b.*?\b(?i:(AS))\b</string>
</dict>
<dict>
<key>captures</key>
@ -42,7 +42,7 @@
</dict>
</dict>
<key>match</key>
<string>^\s*(?:(ONBUILD)\s+)?(ADD|ARG|CMD|COPY|ENTRYPOINT|ENV|EXPOSE|FROM|HEALTHCHECK|LABEL|MAINTAINER|RUN|SHELL|STOPSIGNAL|USER|VOLUME|WORKDIR)\s</string>
<string>^\s*(?i:(ONBUILD)\s+)?(?i:(ADD|ARG|CMD|COPY|ENTRYPOINT|ENV|EXPOSE|FROM|HEALTHCHECK|LABEL|MAINTAINER|RUN|SHELL|STOPSIGNAL|USER|VOLUME|WORKDIR))\s</string>
</dict>
<dict>
<key>captures</key>
@ -59,7 +59,7 @@
</dict>
</dict>
<key>match</key>
<string>^\s*(?:(ONBUILD)\s+)?(CMD|ENTRYPOINT)\s</string>
<string>^\s*(?i:(ONBUILD)\s+)?(?i:(CMD|ENTRYPOINT))\s</string>
</dict>
<dict>
<key>begin</key>

View File

@ -5,7 +5,6 @@ import (
"fmt"
"io"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/errors"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/container"
@ -13,6 +12,7 @@ import (
"github.com/docker/docker/daemon/logger"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/docker/pkg/term"
"github.com/sirupsen/logrus"
)
// ContainerAttach attaches to logs according to the config passed in. See ContainerAttachConfig.

View File

@ -4,7 +4,6 @@ import (
"io"
"runtime"
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
@ -15,6 +14,7 @@ import (
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/registry"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)
@ -27,6 +27,7 @@ type releaseableLayer struct {
func (rl *releaseableLayer) Mount() (string, error) {
var err error
var mountPath string
var chainID layer.ChainID
if rl.roLayer != nil {
chainID = rl.roLayer.ChainID()
@ -38,7 +39,19 @@ func (rl *releaseableLayer) Mount() (string, error) {
return "", errors.Wrap(err, "failed to create rwlayer")
}
return rl.rwLayer.Mount("")
mountPath, err = rl.rwLayer.Mount("")
if err != nil {
// Clean up the layer if we fail to mount it here.
metadata, err := rl.layerStore.ReleaseRWLayer(rl.rwLayer)
layer.LogReleaseMetadata(metadata)
if err != nil {
logrus.Errorf("Failed to release RWLayer: %s", err)
}
rl.rwLayer = nil
return "", err
}
return mountPath, nil
}
func (rl *releaseableLayer) Commit(platform string) (builder.ReleaseableLayer, error) {
@ -51,6 +64,7 @@ func (rl *releaseableLayer) Commit(platform string) (builder.ReleaseableLayer, e
if err != nil {
return nil, err
}
defer stream.Close()
newLayer, err := rl.layerStore.Register(stream, chainID, layer.Platform(platform))
if err != nil {
@ -75,20 +89,32 @@ func (rl *releaseableLayer) Release() error {
if rl.released {
return nil
}
if err := rl.releaseRWLayer(); err != nil {
// Best effort attempt at releasing read-only layer before returning original error.
rl.releaseROLayer()
return err
}
if err := rl.releaseROLayer(); err != nil {
return err
}
rl.released = true
rl.releaseRWLayer()
return rl.releaseROLayer()
return nil
}
func (rl *releaseableLayer) releaseRWLayer() error {
if rl.rwLayer == nil {
return nil
}
if err := rl.rwLayer.Unmount(); err != nil {
logrus.Errorf("Failed to unmount RWLayer: %s", err)
return err
}
metadata, err := rl.layerStore.ReleaseRWLayer(rl.rwLayer)
layer.LogReleaseMetadata(metadata)
if err != nil {
logrus.Errorf("Failed to release RWLayer: %s", err)
}
rl.rwLayer = nil
return err
}
@ -98,6 +124,10 @@ func (rl *releaseableLayer) releaseROLayer() error {
}
metadata, err := rl.layerStore.Release(rl.roLayer)
layer.LogReleaseMetadata(metadata)
if err != nil {
logrus.Errorf("Failed to release ROLayer: %s", err)
}
rl.roLayer = nil
return err
}

View File

@ -1,9 +1,9 @@
package daemon
import (
"github.com/Sirupsen/logrus"
"github.com/docker/docker/builder"
"github.com/docker/docker/image/cache"
"github.com/sirupsen/logrus"
)
// MakeImageCache creates a stateful image cache.

View File

@ -46,7 +46,6 @@ import (
"sync"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types/network"
types "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/daemon/cluster/controllers/plugin"
@ -56,6 +55,7 @@ import (
swarmapi "github.com/docker/swarmkit/api"
swarmnode "github.com/docker/swarmkit/node"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -5,7 +5,6 @@ import (
"io/ioutil"
"net/http"
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/reference"
enginetypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm/runtime"
@ -14,6 +13,7 @@ import (
"github.com/docker/swarmkit/api"
"github.com/gogo/protobuf/proto"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -9,13 +9,13 @@ import (
"testing"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/reference"
enginetypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm/runtime"
"github.com/docker/docker/pkg/pubsub"
"github.com/docker/docker/plugin"
"github.com/docker/docker/plugin/v2"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -5,12 +5,12 @@ import (
"fmt"
"strings"
"github.com/Sirupsen/logrus"
container "github.com/docker/docker/api/types/container"
mounttypes "github.com/docker/docker/api/types/mount"
types "github.com/docker/docker/api/types/swarm"
swarmapi "github.com/docker/swarmkit/api"
gogotypes "github.com/gogo/protobuf/types"
"github.com/sirupsen/logrus"
)
func containerSpecFromGRPC(c *swarmapi.ContainerSpec) *types.ContainerSpec {

View File

@ -42,6 +42,7 @@ func NodeFromGRPC(n swarmapi.Node) types.Node {
if n.Description.Resources != nil {
node.Description.Resources.NanoCPUs = n.Description.Resources.NanoCPUs
node.Description.Resources.MemoryBytes = n.Description.Resources.MemoryBytes
node.Description.Resources.GenericResources = GenericResourcesFromGRPC(n.Description.Resources.Generic)
}
if n.Description.Engine != nil {
node.Description.Engine.EngineVersion = n.Description.Engine.EngineVersion

View File

@ -8,6 +8,7 @@ import (
"github.com/docker/docker/api/types/swarm/runtime"
"github.com/docker/docker/pkg/namesgenerator"
swarmapi "github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/api/genericresource"
"github.com/gogo/protobuf/proto"
gogotypes "github.com/gogo/protobuf/types"
"github.com/pkg/errors"
@ -301,6 +302,31 @@ func annotationsFromGRPC(ann swarmapi.Annotations) types.Annotations {
return a
}
// GenericResourcesFromGRPC converts a GRPC GenericResource to a GenericResource
func GenericResourcesFromGRPC(genericRes []*swarmapi.GenericResource) []types.GenericResource {
var generic []types.GenericResource
for _, res := range genericRes {
var current types.GenericResource
switch r := res.Resource.(type) {
case *swarmapi.GenericResource_DiscreteResourceSpec:
current.DiscreteResourceSpec = &types.DiscreteGenericResource{
Kind: r.DiscreteResourceSpec.Kind,
Value: r.DiscreteResourceSpec.Value,
}
case *swarmapi.GenericResource_NamedResourceSpec:
current.NamedResourceSpec = &types.NamedGenericResource{
Kind: r.NamedResourceSpec.Kind,
Value: r.NamedResourceSpec.Value,
}
}
generic = append(generic, current)
}
return generic
}
func resourcesFromGRPC(res *swarmapi.ResourceRequirements) *types.ResourceRequirements {
var resources *types.ResourceRequirements
if res != nil {
@ -313,8 +339,9 @@ func resourcesFromGRPC(res *swarmapi.ResourceRequirements) *types.ResourceRequir
}
if res.Reservations != nil {
resources.Reservations = &types.Resources{
NanoCPUs: res.Reservations.NanoCPUs,
MemoryBytes: res.Reservations.MemoryBytes,
NanoCPUs: res.Reservations.NanoCPUs,
MemoryBytes: res.Reservations.MemoryBytes,
GenericResources: GenericResourcesFromGRPC(res.Reservations.Generic),
}
}
}
@ -322,6 +349,24 @@ func resourcesFromGRPC(res *swarmapi.ResourceRequirements) *types.ResourceRequir
return resources
}
// GenericResourcesToGRPC converts a GenericResource to a GRPC GenericResource
func GenericResourcesToGRPC(genericRes []types.GenericResource) []*swarmapi.GenericResource {
var generic []*swarmapi.GenericResource
for _, res := range genericRes {
var r *swarmapi.GenericResource
if res.DiscreteResourceSpec != nil {
r = genericresource.NewDiscrete(res.DiscreteResourceSpec.Kind, res.DiscreteResourceSpec.Value)
} else if res.NamedResourceSpec != nil {
r = genericresource.NewString(res.NamedResourceSpec.Kind, res.NamedResourceSpec.Value)
}
generic = append(generic, r)
}
return generic
}
func resourcesToGRPC(res *types.ResourceRequirements) *swarmapi.ResourceRequirements {
var reqs *swarmapi.ResourceRequirements
if res != nil {
@ -336,6 +381,7 @@ func resourcesToGRPC(res *types.ResourceRequirements) *swarmapi.ResourceRequirem
reqs.Reservations = &swarmapi.Resources{
NanoCPUs: res.Reservations.NanoCPUs,
MemoryBytes: res.Reservations.MemoryBytes,
Generic: GenericResourcesToGRPC(res.Reservations.GenericResources),
}
}

View File

@ -30,7 +30,8 @@ func TaskFromGRPC(t swarmapi.Task) (types.Task, error) {
Message: t.Status.Message,
Err: t.Status.Err,
},
DesiredState: types.TaskState(strings.ToLower(t.DesiredState.String())),
DesiredState: types.TaskState(strings.ToLower(t.DesiredState.String())),
GenericResources: GenericResourcesFromGRPC(t.AssignedGenericResources),
}
// Meta

View File

@ -12,7 +12,6 @@ import (
"syscall"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
@ -28,6 +27,7 @@ import (
"github.com/docker/swarmkit/log"
gogotypes "github.com/gogo/protobuf/types"
"github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
"golang.org/x/time/rate"
)

View File

@ -8,7 +8,7 @@ import (
"strings"
"time"
"github.com/Sirupsen/logrus"
"github.com/sirupsen/logrus"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
@ -25,6 +25,7 @@ import (
netconst "github.com/docker/libnetwork/datastore"
"github.com/docker/swarmkit/agent/exec"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/api/genericresource"
"github.com/docker/swarmkit/template"
gogotypes "github.com/gogo/protobuf/types"
)
@ -186,13 +187,16 @@ func (c *containerConfig) exposedPorts() map[nat.Port]struct{} {
}
func (c *containerConfig) config() *enginecontainer.Config {
genericEnvs := genericresource.EnvFormat(c.task.AssignedGenericResources, "DOCKER_RESOURCE")
env := append(c.spec().Env, genericEnvs...)
config := &enginecontainer.Config{
Labels: c.labels(),
StopSignal: c.spec().StopSignal,
Tty: c.spec().TTY,
OpenStdin: c.spec().OpenStdin,
User: c.spec().User,
Env: c.spec().Env,
Env: env,
Hostname: c.spec().Hostname,
WorkingDir: c.spec().Dir,
Image: c.image(),

View File

@ -524,10 +524,12 @@ func (r *controller) Logs(ctx context.Context, publisher exec.LogPublisher, opti
}
// parse the details out of the Attrs map
attrs := []api.LogAttr{}
for k, v := range msg.Attrs {
attr := api.LogAttr{Key: k, Value: v}
attrs = append(attrs, attr)
var attrs []api.LogAttr
if len(msg.Attrs) != 0 {
attrs = make([]api.LogAttr, 0, len(msg.Attrs))
for _, attr := range msg.Attrs {
attrs = append(attrs, api.LogAttr{Key: attr.Key, Value: attr.Value})
}
}
if err := publisher.Publish(ctx, api.LogMessage{

View File

@ -5,12 +5,12 @@ import (
"sort"
"strings"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/network"
swarmtypes "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/daemon/cluster/controllers/plugin"
"github.com/docker/docker/daemon/cluster/convert"
executorpkg "github.com/docker/docker/daemon/cluster/executor"
clustertypes "github.com/docker/docker/daemon/cluster/provider"
networktypes "github.com/docker/libnetwork/types"
@ -18,6 +18,7 @@ import (
"github.com/docker/swarmkit/agent/exec"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/api/naming"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)
@ -119,6 +120,7 @@ func (e *executor) Describe(ctx context.Context) (*api.NodeDescription, error) {
Resources: &api.Resources{
NanoCPUs: int64(info.NCPU) * 1e9,
MemoryBytes: info.MemTotal,
Generic: convert.GenericResourcesToGRPC(info.GenericResources),
},
}
@ -183,13 +185,17 @@ func (e *executor) Controller(t *api.Task) (exec.Controller, error) {
}
switch runtimeKind {
case string(swarmtypes.RuntimePlugin):
info, _ := e.backend.SystemInfo()
if !info.ExperimentalBuild {
return ctlr, fmt.Errorf("runtime type %q only supported in experimental", swarmtypes.RuntimePlugin)
}
c, err := plugin.NewController(e.pluginBackend, t)
if err != nil {
return ctlr, err
}
ctlr = c
default:
return ctlr, fmt.Errorf("unsupported runtime type: %q", r.Generic.Kind)
return ctlr, fmt.Errorf("unsupported runtime type: %q", runtimeKind)
}
case *api.TaskSpec_Container:
c, err := newController(e.backend, t, dependencyGetter)

View File

@ -3,7 +3,6 @@ package cluster
import (
"fmt"
"github.com/Sirupsen/logrus"
apierrors "github.com/docker/docker/api/errors"
apitypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/network"
@ -12,6 +11,7 @@ import (
"github.com/docker/docker/runconfig"
swarmapi "github.com/docker/swarmkit/api"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -8,13 +8,13 @@ import (
"sync"
"time"
"github.com/Sirupsen/logrus"
types "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/daemon/cluster/executor/container"
lncluster "github.com/docker/libnetwork/cluster"
swarmapi "github.com/docker/swarmkit/api"
swarmnode "github.com/docker/swarmkit/node"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
"google.golang.org/grpc"
)

View File

@ -10,7 +10,6 @@ import (
"strings"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/reference"
apierrors "github.com/docker/docker/api/errors"
apitypes "github.com/docker/docker/api/types"
@ -22,6 +21,7 @@ import (
swarmapi "github.com/docker/swarmkit/api"
gogotypes "github.com/gogo/protobuf/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)
@ -139,9 +139,16 @@ func (c *Cluster) CreateService(s types.ServiceSpec, encodedAuth string, queryRe
case *swarmapi.TaskSpec_Generic:
switch serviceSpec.Task.GetGeneric().Kind {
case string(types.RuntimePlugin):
info, _ := c.config.Backend.SystemInfo()
if !info.ExperimentalBuild {
return fmt.Errorf("runtime type %q only supported in experimental", types.RuntimePlugin)
}
if s.TaskTemplate.PluginSpec == nil {
return errors.New("plugin spec must be set")
}
default:
return fmt.Errorf("unsupported runtime type: %q", serviceSpec.Task.GetGeneric().Kind)
}
r, err := state.controlClient.CreateService(ctx, &swarmapi.CreateServiceRequest{Spec: &serviceSpec})
@ -458,22 +465,33 @@ func (c *Cluster) ServiceLogs(ctx context.Context, selector *backend.LogSelector
for _, msg := range subscribeMsg.Messages {
// make a new message
m := new(backend.LogMessage)
m.Attrs = make(backend.LogAttributes)
m.Attrs = make([]backend.LogAttr, 0, len(msg.Attrs)+3)
// add the timestamp, adding the error if it fails
m.Timestamp, err = gogotypes.TimestampFromProto(msg.Timestamp)
if err != nil {
m.Err = err
}
nodeKey := contextPrefix + ".node.id"
serviceKey := contextPrefix + ".service.id"
taskKey := contextPrefix + ".task.id"
// copy over all of the details
for _, d := range msg.Attrs {
m.Attrs[d.Key] = d.Value
switch d.Key {
case nodeKey, serviceKey, taskKey:
// we have the final say over context details (in case there
// is a conflict (if the user added a detail with a context's
// key for some reason))
default:
m.Attrs = append(m.Attrs, backend.LogAttr{Key: d.Key, Value: d.Value})
}
}
// we have the final say over context details (in case there
// is a conflict (if the user added a detail with a context's
// key for some reason))
m.Attrs[contextPrefix+".node.id"] = msg.Context.NodeID
m.Attrs[contextPrefix+".service.id"] = msg.Context.ServiceID
m.Attrs[contextPrefix+".task.id"] = msg.Context.TaskID
m.Attrs = append(m.Attrs,
backend.LogAttr{Key: nodeKey, Value: msg.Context.NodeID},
backend.LogAttr{Key: serviceKey, Value: msg.Context.ServiceID},
backend.LogAttr{Key: taskKey, Value: msg.Context.TaskID},
)
switch msg.Stream {
case swarmapi.LogStreamStdout:

View File

@ -6,7 +6,6 @@ import (
"strings"
"time"
"github.com/Sirupsen/logrus"
apierrors "github.com/docker/docker/api/errors"
apitypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
@ -18,6 +17,7 @@ import (
"github.com/docker/swarmkit/manager/encryption"
swarmnode "github.com/docker/swarmkit/node"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
)

View File

@ -11,57 +11,50 @@ import (
// GetTasks returns a list of tasks matching the filter options.
func (c *Cluster) GetTasks(options apitypes.TaskListOptions) ([]types.Task, error) {
c.mu.RLock()
defer c.mu.RUnlock()
var r *swarmapi.ListTasksResponse
state := c.currentNodeState()
if !state.IsActiveManager() {
return nil, c.errNoManager(state)
}
filterTransform := func(filter filters.Args) error {
if filter.Include("service") {
serviceFilters := filter.Get("service")
for _, serviceFilter := range serviceFilters {
service, err := c.GetService(serviceFilter, false)
if err != nil {
return err
if err := c.lockedManagerAction(func(ctx context.Context, state nodeState) error {
filterTransform := func(filter filters.Args) error {
if filter.Include("service") {
serviceFilters := filter.Get("service")
for _, serviceFilter := range serviceFilters {
service, err := getService(ctx, state.controlClient, serviceFilter, false)
if err != nil {
return err
}
filter.Del("service", serviceFilter)
filter.Add("service", service.ID)
}
filter.Del("service", serviceFilter)
filter.Add("service", service.ID)
}
}
if filter.Include("node") {
nodeFilters := filter.Get("node")
for _, nodeFilter := range nodeFilters {
node, err := c.GetNode(nodeFilter)
if err != nil {
return err
if filter.Include("node") {
nodeFilters := filter.Get("node")
for _, nodeFilter := range nodeFilters {
node, err := getNode(ctx, state.controlClient, nodeFilter)
if err != nil {
return err
}
filter.Del("node", nodeFilter)
filter.Add("node", node.ID)
}
filter.Del("node", nodeFilter)
filter.Add("node", node.ID)
}
if !filter.Include("runtime") {
// default to only showing container tasks
filter.Add("runtime", "container")
filter.Add("runtime", "")
}
return nil
}
if !filter.Include("runtime") {
// default to only showing container tasks
filter.Add("runtime", "container")
filter.Add("runtime", "")
filters, err := newListTasksFilters(options.Filters, filterTransform)
if err != nil {
return err
}
return nil
}
filters, err := newListTasksFilters(options.Filters, filterTransform)
if err != nil {
return nil, err
}
ctx, cancel := c.getRequestContext()
defer cancel()
r, err := state.controlClient.ListTasks(
ctx,
&swarmapi.ListTasksRequest{Filters: filters})
if err != nil {
r, err = state.controlClient.ListTasks(
ctx,
&swarmapi.ListTasksRequest{Filters: filters})
return err
}); err != nil {
return nil, err
}

View File

@ -12,13 +12,13 @@ import (
"strings"
"sync"
"github.com/Sirupsen/logrus"
daemondiscovery "github.com/docker/docker/daemon/discovery"
"github.com/docker/docker/opts"
"github.com/docker/docker/pkg/authorization"
"github.com/docker/docker/pkg/discovery"
"github.com/docker/docker/registry"
"github.com/imdario/mergo"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
)
@ -168,6 +168,11 @@ type CommonConfig struct {
ValuesSet map[string]interface{}
Experimental bool `json:"experimental"` // Experimental indicates whether experimental features should be exposed or not
// Exposed node Generic Resources
NodeGenericResources string `json:"node-generic-resources,omitempty"`
// NetworkControlPlaneMTU allows to specify the control plane MTU, this will allow to optimize the network use in some components
NetworkControlPlaneMTU int `json:"network-control-plane-mtu,omitempty"`
}
// IsValueSet returns true if a configuration value
@ -497,6 +502,10 @@ func Validate(config *Config) error {
}
}
if _, err := opts.ParseGenericResources(config.NodeGenericResources); err != nil {
return err
}
if defaultRuntime := config.GetDefaultRuntimeName(); defaultRuntime != "" && defaultRuntime != StockRuntimeName {
runtimes := config.GetAllRuntimes()
if _, ok := runtimes[defaultRuntime]; !ok {
@ -504,6 +513,11 @@ func Validate(config *Config) error {
}
}
// validate platform-specific settings
if err := config.ValidatePlatformConfig(); err != nil {
return err
}
return nil
}

View File

@ -27,3 +27,8 @@ type BridgeConfig struct {
func (conf *Config) IsSwarmCompatible() error {
return nil
}
// ValidatePlatformConfig checks if any platform-specific configuration settings are invalid.
func (conf *Config) ValidatePlatformConfig() error {
return nil
}

View File

@ -5,10 +5,16 @@ package config
import (
"fmt"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/opts"
units "github.com/docker/go-units"
)
const (
// DefaultIpcMode is default for container's IpcMode, if not set otherwise
DefaultIpcMode = "shareable" // TODO: change to private
)
// Config defines the configuration of a docker daemon.
// It includes json tags to deserialize configuration from a file
// using the same names that the flags in the command line uses.
@ -31,6 +37,7 @@ type Config struct {
SeccompProfile string `json:"seccomp-profile,omitempty"`
ShmSize opts.MemBytes `json:"default-shm-size,omitempty"`
NoNewPrivileges bool `json:"no-new-privileges,omitempty"`
IpcMode string `json:"default-ipc-mode,omitempty"`
}
// BridgeConfig stores all the bridge driver specific
@ -61,3 +68,21 @@ func (conf *Config) IsSwarmCompatible() error {
}
return nil
}
func verifyDefaultIpcMode(mode string) error {
const hint = "Use \"shareable\" or \"private\"."
dm := containertypes.IpcMode(mode)
if !dm.Valid() {
return fmt.Errorf("Default IPC mode setting (%v) is invalid. "+hint, dm)
}
if dm != "" && !dm.IsPrivate() && !dm.IsShareable() {
return fmt.Errorf("IPC mode \"%v\" is not supported as default value. "+hint, dm)
}
return nil
}
// ValidatePlatformConfig checks if any platform-specific configuration settings are invalid.
func (conf *Config) ValidatePlatformConfig() error {
return verifyDefaultIpcMode(conf.IpcMode)
}

View File

@ -50,3 +50,8 @@ func (conf *Config) GetExecRoot() string {
func (conf *Config) IsSwarmCompatible() error {
return nil
}
// ValidatePlatformConfig checks if any platform-specific configuration settings are invalid.
func (conf *Config) ValidatePlatformConfig() error {
return nil
}

View File

@ -1,8 +1,8 @@
package daemon
import (
"github.com/Sirupsen/logrus"
swarmtypes "github.com/docker/docker/api/types/swarm"
"github.com/sirupsen/logrus"
)
// SetContainerConfigReferences sets the container config references needed

View File

@ -10,7 +10,6 @@ import (
"strings"
"time"
"github.com/Sirupsen/logrus"
derr "github.com/docker/docker/api/errors"
containertypes "github.com/docker/docker/api/types/container"
networktypes "github.com/docker/docker/api/types/network"
@ -24,6 +23,7 @@ import (
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/types"
"github.com/sirupsen/logrus"
)
var (

View File

@ -11,7 +11,6 @@ import (
"strconv"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/container"
"github.com/docker/docker/daemon/links"
"github.com/docker/docker/pkg/idtools"
@ -21,6 +20,7 @@ import (
"github.com/docker/libnetwork"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
@ -57,13 +57,27 @@ func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]s
return env, nil
}
func (daemon *Daemon) getIpcContainer(container *container.Container) (*container.Container, error) {
containerID := container.HostConfig.IpcMode.Container()
container, err := daemon.GetContainer(containerID)
func (daemon *Daemon) getIpcContainer(id string) (*container.Container, error) {
errMsg := "can't join IPC of container " + id
// Check the container exists
container, err := daemon.GetContainer(id)
if err != nil {
return nil, errors.Wrapf(err, "cannot join IPC of a non running container: %s", container.ID)
return nil, errors.Wrap(err, errMsg)
}
return container, daemon.checkContainer(container, containerIsRunning, containerIsNotRestarting)
// Check the container is running and not restarting
if err := daemon.checkContainer(container, containerIsRunning, containerIsNotRestarting); err != nil {
return nil, errors.Wrap(err, errMsg)
}
// Check the container ipc is shareable
if st, err := os.Stat(container.ShmPath); err != nil || !st.IsDir() {
if err == nil || os.IsNotExist(err) {
return nil, errors.New(errMsg + ": non-shareable IPC")
}
// stat() failed?
return nil, errors.Wrap(err, errMsg+": unexpected error from stat "+container.ShmPath)
}
return container, nil
}
func (daemon *Daemon) getPidContainer(container *container.Container) (*container.Container, error) {
@ -90,25 +104,33 @@ func containerIsNotRestarting(c *container.Container) error {
}
func (daemon *Daemon) setupIpcDirs(c *container.Container) error {
var err error
ipcMode := c.HostConfig.IpcMode
c.ShmPath, err = c.ShmResourcePath()
if err != nil {
return err
}
if c.HostConfig.IpcMode.IsContainer() {
ic, err := daemon.getIpcContainer(c)
switch {
case ipcMode.IsContainer():
ic, err := daemon.getIpcContainer(ipcMode.Container())
if err != nil {
return err
}
c.ShmPath = ic.ShmPath
} else if c.HostConfig.IpcMode.IsHost() {
case ipcMode.IsHost():
if _, err := os.Stat("/dev/shm"); err != nil {
return fmt.Errorf("/dev/shm is not mounted, but must be for --ipc=host")
}
c.ShmPath = "/dev/shm"
} else {
case ipcMode.IsPrivate(), ipcMode.IsNone():
// c.ShmPath will/should not be used, so make it empty.
// Container's /dev/shm mount comes from OCI spec.
c.ShmPath = ""
case ipcMode.IsEmpty():
// A container was created by an older version of the daemon.
// The default behavior used to be what is now called "shareable".
fallthrough
case ipcMode.IsShareable():
rootIDs := daemon.idMappings.RootPair()
if !c.HasMountFor("/dev/shm") {
shmPath, err := c.ShmResourcePath()
@ -120,19 +142,18 @@ func (daemon *Daemon) setupIpcDirs(c *container.Container) error {
return err
}
shmSize := int64(daemon.configStore.ShmSize)
if c.HostConfig.ShmSize != 0 {
shmSize = c.HostConfig.ShmSize
}
shmproperty := "mode=1777,size=" + strconv.FormatInt(shmSize, 10)
shmproperty := "mode=1777,size=" + strconv.FormatInt(c.HostConfig.ShmSize, 10)
if err := unix.Mount("shm", shmPath, "tmpfs", uintptr(unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV), label.FormatMountLabel(shmproperty, c.GetMountLabel())); err != nil {
return fmt.Errorf("mounting shm tmpfs: %s", err)
}
if err := os.Chown(shmPath, rootIDs.UID, rootIDs.GID); err != nil {
return err
}
c.ShmPath = shmPath
}
default:
return fmt.Errorf("invalid IPC mode: %v", ipcMode)
}
return nil

View File

@ -5,11 +5,11 @@ import (
"io/ioutil"
"os"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/container"
"github.com/docker/docker/pkg/system"
"github.com/docker/libnetwork"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]string, error) {

Some files were not shown because too many files have changed in this diff Show More