Merge component 'engine' from git@github.com:moby/moby master
This commit is contained in:
19
components/engine/.github/CODEOWNERS
vendored
Normal file
19
components/engine/.github/CODEOWNERS
vendored
Normal 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
|
||||
2
components/engine/.gitignore
vendored
2
components/engine/.gitignore
vendored
@ -4,7 +4,7 @@
|
||||
*.exe
|
||||
*.exe~
|
||||
*.orig
|
||||
*.test
|
||||
test.main
|
||||
.*.swp
|
||||
.DS_Store
|
||||
# a .bashrc may be added to customize the build environment
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
@ -7,7 +7,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -3,7 +3,7 @@ package middleware
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 ""
|
||||
|
||||
@ -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).
|
||||
|
||||
@ -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"`
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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"`
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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"`
|
||||
|
||||
@ -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"`
|
||||
}
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -3,7 +3,7 @@ package debug
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Enable sets the DEBUG env var to true
|
||||
|
||||
@ -4,7 +4,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func TestEnable(t *testing.T) {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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)
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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}))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -3,7 +3,7 @@ package container
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
})
|
||||
}
|
||||
|
||||
@ -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())
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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 }')"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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{
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 (
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
Reference in New Issue
Block a user