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

This commit is contained in:
Andrew Hsu
2017-11-28 18:03:40 -08:00
519 changed files with 8797 additions and 5125 deletions

View File

@ -1,8 +1,8 @@
# Contributing to Docker
# Contribute to the Moby Project
Want to hack on Docker? Awesome! We have a contributor's guide that explains
[setting up a Docker development environment and the contribution
process](https://docs.docker.com/opensource/project/who-written-for/).
Want to hack on the Moby Project? Awesome! We have a contributor's guide that explains
[setting up a development environment and the contribution
process](docs/contributing/).
[![Contributors guide](docs/static_files/contributors.png)](https://docs.docker.com/opensource/project/who-written-for/)
@ -21,14 +21,14 @@ start participating.
## Reporting security issues
The Docker maintainers take security seriously. If you discover a security
The Moby maintainers take security seriously. If you discover a security
issue, please bring it to their attention right away!
Please **DO NOT** file a public issue, instead send your report privately to
[security@docker.com](mailto:security@docker.com).
Security reports are greatly appreciated and we will publicly thank you for it.
We also like to send gifts—if you're into Docker schwag, make sure to let
We also like to send gifts—if you're into schwag, make sure to let
us know. We currently do not offer a paid security bounty program, but are not
ruling it out in the future.
@ -83,11 +83,7 @@ contributions, see [the advanced contribution
section](https://docs.docker.com/opensource/workflow/advanced-contributing/) in
the contributors guide.
We try hard to keep Docker lean and focused. Docker can't do everything for
everybody. This means that we might decide against incorporating a new feature.
However, there might be a way to implement that feature *on top of* Docker.
### Talking to other Docker users and contributors
### Connect with other Moby Project contributors
<table class="tg">
<col width="45%">
@ -96,52 +92,29 @@ However, there might be a way to implement that feature *on top of* Docker.
<td>Forums</td>
<td>
A public forum for users to discuss questions and explore current design patterns and
best practices about Docker and related projects in the Docker Ecosystem. To participate,
just log in with your Docker Hub account on <a href="https://forums.docker.com" target="_blank">https://forums.docker.com</a>.
best practices about all the Moby projects. To participate, log in with your Github
account or create an account at <a href="https://forums.mobyproject.org" target="_blank">https://forums.mobyproject.org</a>.
</td>
</tr>
<tr>
<td>Internet&nbsp;Relay&nbsp;Chat&nbsp;(IRC)</td>
<td>Slack</td>
<td>
<p>
IRC a direct line to our most knowledgeable Docker users; we have
both the <code>#docker</code> and <code>#docker-dev</code> group on
<strong>irc.freenode.net</strong>.
IRC is a rich chat protocol but it can overwhelm new users. You can search
<a href="https://botbot.me/freenode/docker/#" target="_blank">our chat archives</a>.
Register for the Docker Community Slack at
<a href="https://community.docker.com/registrations/groups/4316" target="_blank">https://community.docker.com/registrations/groups/4316</a>.
We use the #moby-project channel for general discussion, and there are seperate channels for other Moby projects such as #containerd.
Archives are available at <a href="https://dockercommunity.slackarchive.io/" target="_blank">https://dockercommunity.slackarchive.io/</a>.
</p>
<p>
Read our <a href="https://docs.docker.com/opensource/get-help/#irc-quickstart" target="_blank">IRC quickstart guide</a>
for an easy way to get started.
</p>
</td>
</tr>
<tr>
<td>Google Group</td>
<td>
The <a href="https://groups.google.com/forum/#!forum/docker-dev" target="_blank">docker-dev</a>
group is for contributors and other people contributing to the Docker project.
You can join them without a google account by sending an email to
<a href="mailto:docker-dev+subscribe@googlegroups.com">docker-dev+subscribe@googlegroups.com</a>.
After receiving the join-request message, you can simply reply to that to confirm the subscription.
</td>
</tr>
<tr>
<td>Twitter</td>
<td>
You can follow <a href="https://twitter.com/docker/" target="_blank">Docker's Twitter feed</a>
You can follow <a href="https://twitter.com/moby/" target="_blank">Moby Project Twitter feed</a>
to get updates on our products. You can also tweet us questions or just
share blogs or stories.
</td>
</tr>
<tr>
<td>Stack Overflow</td>
<td>
Stack Overflow has thousands of Docker questions listed. We regularly
monitor <a href="https://stackoverflow.com/search?tab=newest&q=docker" target="_blank">Docker questions</a>
and so do many other knowledgeable Docker users.
</td>
</tr>
</table>
@ -159,7 +132,7 @@ Submit tests for your changes. See [TESTING.md](./TESTING.md) for details.
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.
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
@ -266,15 +239,11 @@ Please see the [Coding Style](#coding-style) for further guidelines.
### Merge approval
Docker maintainers use LGTM (Looks Good To Me) in comments on the code review to
indicate acceptance.
Moby maintainers use LGTM (Looks Good To Me) in comments on the code review to
indicate acceptance, or use the Github review approval feature.
A change requires LGTMs from an absolute majority of the maintainers of each
component affected. For example, if a change affects `docs/` and `registry/`, it
needs an absolute majority from the maintainers of `docs/` AND, separately, an
absolute majority of the maintainers of `registry/`.
For more details, see the [MAINTAINERS](MAINTAINERS) page.
For an explanation of the review and approval process see the
[REVIEWING](project/REVIEWING.md) page.
### Sign your work
@ -342,9 +311,9 @@ Don't forget: being a maintainer is a time investment. Make sure you
will have time to make yourself available. You don't have to be a
maintainer to make a difference on the project!
## Docker community guidelines
## Moby community guidelines
We want to keep the Docker community awesome, growing and collaborative. We need
We want to keep the Moby community awesome, growing and collaborative. We need
your help to keep it that way. To help with this we've come up with some general
guidelines for the community as a whole:

View File

@ -86,7 +86,7 @@ RUN apt-get update && apt-get install -y \
# will need updating, to avoid errors. Ping #docker-maintainers on IRC
# with a heads-up.
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
| tar -xzC /usr/local
@ -133,7 +133,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Get the "docker-py" source so we can run their integration tests
ENV DOCKER_PY_COMMIT a962578e515185cf06506050b2200c0b81aa84ef
ENV DOCKER_PY_COMMIT 1d6b5b203222ba5df7dedfcd1ee061a452f99c8a
# To run integration tests docker-pycreds is required.
RUN git clone https://github.com/docker/docker-py.git /docker-py \
&& cd /docker-py \
@ -189,8 +189,9 @@ RUN ln -s /usr/local/completion/bash/docker /etc/bash_completion.d/docker
# Wrap all commands in the "docker-in-docker" script to allow nested containers
ENTRYPOINT ["hack/dind"]
# Options for hack/validate/gometalinter
ENV GOMETALINTER_OPTS="--deadline 2m"
# Upload docker source
COPY . /go/src/github.com/docker/docker
# Options for hack/validate/gometalinter
ENV GOMETALINTER_OPTS="--deadline 2m"

View File

@ -73,7 +73,7 @@ RUN apt-get update && apt-get install -y \
# Install Go
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" \
| tar -xzC /usr/local
@ -105,7 +105,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Get the "docker-py" source so we can run their integration tests
ENV DOCKER_PY_COMMIT a962578e515185cf06506050b2200c0b81aa84ef
ENV DOCKER_PY_COMMIT 1d6b5b203222ba5df7dedfcd1ee061a452f99c8a
# To run integration tests docker-pycreds is required.
RUN git clone https://github.com/docker/docker-py.git /docker-py \
&& cd /docker-py \
@ -158,8 +158,8 @@ ENV PATH=/usr/local/cli:$PATH
# Wrap all commands in the "docker-in-docker" script to allow nested containers
ENTRYPOINT ["hack/dind"]
# Upload docker source
COPY . /go/src/github.com/docker/docker
# Options for hack/validate/gometalinter
ENV GOMETALINTER_OPTS="--deadline 4m -j2"
# Upload docker source
COPY . /go/src/github.com/docker/docker

View File

@ -63,7 +63,7 @@ RUN apt-get update && apt-get install -y \
# Install Go
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" \
| tar -xzC /usr/local
ENV PATH /go/bin:/usr/local/go/bin:$PATH
@ -103,7 +103,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Get the "docker-py" source so we can run their integration tests
ENV DOCKER_PY_COMMIT a962578e515185cf06506050b2200c0b81aa84ef
ENV DOCKER_PY_COMMIT 1d6b5b203222ba5df7dedfcd1ee061a452f99c8a
# To run integration tests docker-pycreds is required.
RUN git clone https://github.com/docker/docker-py.git /docker-py \
&& cd /docker-py \
@ -146,8 +146,8 @@ ENV PATH=/usr/local/cli:$PATH
ENTRYPOINT ["hack/dind"]
# Upload docker source
COPY . /go/src/github.com/docker/docker
# Options for hack/validate/gometalinter
ENV GOMETALINTER_OPTS="--deadline 10m -j2"
# Upload docker source
COPY . /go/src/github.com/docker/docker

View File

@ -1,8 +1,9 @@
## Step 1: Build tests
FROM golang:1.8.5-alpine3.6 as builder
FROM golang:1.9.2-alpine3.6 as builder
RUN apk add --update \
bash \
btrfs-progs-dev \
build-base \
curl \
lvm2-dev \

View File

@ -64,7 +64,7 @@ RUN apt-get update && apt-get install -y \
# Install Go
# NOTE: official ppc64le go binaries weren't available until go 1.6.4 and 1.7.4
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" \
| tar -xzC /usr/local
@ -101,7 +101,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Get the "docker-py" source so we can run their integration tests
ENV DOCKER_PY_COMMIT a962578e515185cf06506050b2200c0b81aa84ef
ENV DOCKER_PY_COMMIT 1d6b5b203222ba5df7dedfcd1ee061a452f99c8a
# To run integration tests docker-pycreds is required.
RUN git clone https://github.com/docker/docker-py.git /docker-py \
&& cd /docker-py \

View File

@ -58,7 +58,7 @@ RUN apt-get update && apt-get install -y \
--no-install-recommends
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" \
| tar -xzC /usr/local
@ -95,7 +95,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Get the "docker-py" source so we can run their integration tests
ENV DOCKER_PY_COMMIT a962578e515185cf06506050b2200c0b81aa84ef
ENV DOCKER_PY_COMMIT 1d6b5b203222ba5df7dedfcd1ee061a452f99c8a
# To run integration tests docker-pycreds is required.
RUN git clone https://github.com/docker/docker-py.git /docker-py \
&& cd /docker-py \

View File

@ -40,7 +40,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
# will need updating, to avoid errors. Ping #docker-maintainers on IRC
# with a heads-up.
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
| tar -xzC /usr/local
ENV PATH /go/bin:/usr/local/go/bin:$PATH

View File

@ -161,7 +161,7 @@ SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPref
# Environment variable notes:
# - GO_VERSION must be consistent with 'Dockerfile' used by Linux.
# - FROM_DOCKERFILE is used for detection of building within a container.
ENV GO_VERSION=1.8.5 `
ENV GO_VERSION=1.9.2 `
GIT_VERSION=2.11.1 `
GOPATH=C:\go `
FROM_DOCKERFILE=1

View File

@ -364,7 +364,7 @@
[people.misty]
Name = "Misty Stanley-Jones"
Email = "misty@docker.com"
GitHub = "mstanleyjones"
GitHub = "mistyhacks"
[people.mlaventure]
Name = "Kenfe-Mickaël Laventure"

View File

@ -16,6 +16,13 @@ export DOCKER_GITCOMMIT
# env vars passed through directly to Docker's build scripts
# to allow things like `make KEEPBUNDLE=1 binary` easily
# `project/PACKAGERS.md` have some limited documentation of some of these
#
# DOCKER_LDFLAGS can be used to pass additional parameters to -ldflags
# option of "go build". For example, a built-in graphdriver priority list
# can be changed during build time like this:
#
# make DOCKER_LDFLAGS="-X github.com/docker/docker/daemon/graphdriver.priority=overlay2,devicemapper" dynbinary
#
DOCKER_ENVS := \
-e DOCKER_CROSSPLATFORMS \
-e BUILD_APT_MIRROR \
@ -31,6 +38,7 @@ DOCKER_ENVS := \
-e DOCKER_GITCOMMIT \
-e DOCKER_GRAPHDRIVER \
-e DOCKER_INCREMENTAL_BINARY \
-e DOCKER_LDFLAGS \
-e DOCKER_PORT \
-e DOCKER_REMAP_ROOT \
-e DOCKER_STORAGE_OPTS \
@ -150,8 +158,8 @@ run: build ## run the docker daemon in a container
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 test-docker-py
test: build test-unit ## run the unit, integration and docker-py tests
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary cross test-integration test-docker-py
test-docker-py: build ## run the docker-py tests
$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary test-docker-py

View File

@ -1 +0,0 @@
17.06.0-dev

View File

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

View File

@ -25,7 +25,7 @@ func getImplementer(err error) error {
}
}
// IsNotFound returns if the passed in error is a ErrNotFound
// IsNotFound returns if the passed in error is an ErrNotFound
func IsNotFound(err error) bool {
_, ok := getImplementer(err).(ErrNotFound)
return ok
@ -37,7 +37,7 @@ func IsInvalidParameter(err error) bool {
return ok
}
// IsConflict returns if the passed in error is a ErrConflict
// IsConflict returns if the passed in error is an ErrConflict
func IsConflict(err error) bool {
_, ok := getImplementer(err).(ErrConflict)
return ok
@ -55,13 +55,13 @@ func IsUnavailable(err error) bool {
return ok
}
// IsForbidden returns if the passed in error is a ErrForbidden
// IsForbidden returns if the passed in error is an ErrForbidden
func IsForbidden(err error) bool {
_, ok := getImplementer(err).(ErrForbidden)
return ok
}
// IsSystem returns if the passed in error is a ErrSystem
// IsSystem returns if the passed in error is an ErrSystem
func IsSystem(err error) bool {
_, ok := getImplementer(err).(ErrSystem)
return ok
@ -73,7 +73,7 @@ func IsNotModified(err error) bool {
return ok
}
// IsNotImplemented returns if the passed in error is a ErrNotImplemented
// IsNotImplemented returns if the passed in error is an ErrNotImplemented
func IsNotImplemented(err error) bool {
_, ok := getImplementer(err).(ErrNotImplemented)
return ok

View File

@ -96,6 +96,7 @@ func (s *containerRouter) getContainersLogs(ctx context.Context, w http.Response
Follow: httputils.BoolValue(r, "follow"),
Timestamps: httputils.BoolValue(r, "timestamps"),
Since: r.Form.Get("since"),
Until: r.Form.Get("until"),
Tail: r.Form.Get("tail"),
ShowStdout: stdout,
ShowStderr: stderr,

View File

@ -19,10 +19,10 @@ produces:
consumes:
- "application/json"
- "text/plain"
basePath: "/v1.34"
basePath: "/v1.35"
info:
title: "Docker Engine API"
version: "1.34"
version: "1.35"
x-logo:
url: "https://docs.docker.com/images/logo-docker-main.png"
description: |
@ -42,38 +42,26 @@ info:
# Versioning
The API is usually changed in each release of Docker, so API calls are versioned to ensure that clients don't break.
The API is usually changed in each release, so API calls are versioned to
ensure that clients don't break. To lock to a specific version of the API,
you prefix the URL with its version, for example, call `/v1.30/info` to use
the v1.30 version of the `/info` endpoint. If the API version specified in
the URL is not supported by the daemon, a HTTP `400 Bad Request` error message
is returned.
For Docker Engine 17.10, the API version is 1.33. To lock to this version, you prefix the URL with `/v1.33`. For example, calling `/info` is the same as calling `/v1.33/info`.
If you omit the version-prefix, the current version of the API (v1.35) is used.
For example, calling `/info` is the same as calling `/v1.35/info`. Using the
API without a version-prefix is deprecated and will be removed in a future release.
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.
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.
In previous versions of Docker, it was possible to access the API without providing a version. This behaviour is now deprecated will be removed in a future version of Docker.
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
daemons.
If the API version specified in the URL is not supported by the daemon, a HTTP `400 Bad Request` error message is returned.
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.34 of the API. Use this table to find documentation for previous versions of the API:
Docker version | API version | Changes
----------------|-------------|---------
17.10.x | [1.33](https://docs.docker.com/engine/api/v1.33/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-33-api-changes)
17.09.x | [1.32](https://docs.docker.com/engine/api/v1.32/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-32-api-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)
17.03.1 | [1.27](https://docs.docker.com/engine/api/v1.27/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-27-api-changes)
1.13.1 & 17.03.0 | [1.26](https://docs.docker.com/engine/api/v1.26/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-26-api-changes)
1.13.0 | [1.25](https://docs.docker.com/engine/api/v1.25/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-25-api-changes)
1.12.x | [1.24](https://docs.docker.com/engine/api/v1.24/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-24-api-changes)
1.11.x | [1.23](https://docs.docker.com/engine/api/v1.23/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-23-api-changes)
1.10.x | [1.22](https://docs.docker.com/engine/api/v1.22/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-22-api-changes)
1.9.x | [1.21](https://docs.docker.com/engine/api/v1.21/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-21-api-changes)
1.8.x | [1.20](https://docs.docker.com/engine/api/v1.20/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-20-api-changes)
1.7.x | [1.19](https://docs.docker.com/engine/api/v1.19/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-19-api-changes)
1.6.x | [1.18](https://docs.docker.com/engine/api/v1.18/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-18-api-changes)
# Authentication
@ -344,6 +332,7 @@ definitions:
Memory:
description: "Memory limit in bytes."
type: "integer"
format: "int64"
default: 0
# Applicable to UNIX platforms
CgroupParent:
@ -2688,7 +2677,13 @@ definitions:
ConfigName is the name of the config that this references, but this is just provided for
lookup/display purposes. The config in the reference will be identified by its ID.
type: "string"
Isolation:
type: "string"
description: "Isolation technology of the containers running the service. (Windows only)"
enum:
- "default"
- "process"
- "hyperv"
Resources:
description: "Resource requirements which apply to each individual container created as part of the service."
type: "object"
@ -4963,6 +4958,11 @@ paths:
description: "Only return logs since this time, as a UNIX timestamp"
type: "integer"
default: 0
- name: "until"
in: "query"
description: "Only return logs before this time, as a UNIX timestamp"
type: "integer"
default: 0
- name: "timestamps"
in: "query"
description: "Add timestamps to every log line"
@ -6996,7 +6996,7 @@ paths:
- `network=<string>` network name or ID
- `node=<string>` node ID
- `plugin`=<string> plugin name or ID
- `scope`<string> local or swarm
- `scope`=<string> local or swarm
- `secret=<string>` secret name or ID
- `service=<string>` service name or ID
- `type=<string>` object to filter by, one of `container`, `image`, `volume`, `network`, `daemon`, `plugin`, `node`, `service`, `secret` or `config`
@ -7892,7 +7892,7 @@ paths:
summary: "Connect a container to a network"
operationId: "NetworkConnect"
consumes:
- "application/octet-stream"
- "application/json"
responses:
200:
description: "No error"

View File

@ -74,6 +74,7 @@ type ContainerLogsOptions struct {
ShowStdout bool
ShowStderr bool
Since string
Until string
Timestamps bool
Follow bool
Tail string

View File

@ -20,6 +20,27 @@ func (i Isolation) IsDefault() bool {
return strings.ToLower(string(i)) == "default" || string(i) == ""
}
// IsHyperV indicates the use of a Hyper-V partition for isolation
func (i Isolation) IsHyperV() bool {
return strings.ToLower(string(i)) == "hyperv"
}
// IsProcess indicates the use of process isolation
func (i Isolation) IsProcess() bool {
return strings.ToLower(string(i)) == "process"
}
const (
// IsolationEmpty is unspecified (same behavior as default)
IsolationEmpty = Isolation("")
// IsolationDefault is the default isolation mode on current daemon
IsolationDefault = Isolation("default")
// IsolationProcess is process isolation mode
IsolationProcess = Isolation("process")
// IsolationHyperV is HyperV isolation mode
IsolationHyperV = Isolation("hyperv")
)
// IpcMode represents the container ipc stack.
type IpcMode string

View File

@ -1,9 +1,5 @@
package container
import (
"strings"
)
// IsBridge indicates whether container uses the bridge network stack
// in windows it is given the name NAT
func (n NetworkMode) IsBridge() bool {
@ -21,16 +17,6 @@ func (n NetworkMode) IsUserDefined() bool {
return !n.IsDefault() && !n.IsNone() && !n.IsBridge() && !n.IsContainer()
}
// IsHyperV indicates the use of a Hyper-V partition for isolation
func (i Isolation) IsHyperV() bool {
return strings.ToLower(string(i)) == "hyperv"
}
// IsProcess indicates the use of process isolation
func (i Isolation) IsProcess() bool {
return strings.ToLower(string(i)) == "process"
}
// IsValid indicates if an isolation technology is valid
func (i Isolation) IsValid() bool {
return i.IsDefault() || i.IsHyperV() || i.IsProcess()

View File

@ -65,8 +65,9 @@ type ContainerSpec struct {
// The format of extra hosts on swarmkit is specified in:
// http://man7.org/linux/man-pages/man5/hosts.5.html
// IP_address canonical_hostname [aliases...]
Hosts []string `json:",omitempty"`
DNSConfig *DNSConfig `json:",omitempty"`
Secrets []*SecretReference `json:",omitempty"`
Configs []*ConfigReference `json:",omitempty"`
Hosts []string `json:",omitempty"`
DNSConfig *DNSConfig `json:",omitempty"`
Secrets []*SecretReference `json:",omitempty"`
Configs []*ConfigReference `json:",omitempty"`
Isolation container.Isolation `json:",omitempty"`
}

View File

@ -131,10 +131,10 @@ func (bm *BuildManager) initializeClientSession(ctx context.Context, cancel func
}
logrus.Debug("client is session enabled")
ctx, cancelCtx := context.WithTimeout(ctx, sessionConnectTimeout)
connectCtx, cancelCtx := context.WithTimeout(ctx, sessionConnectTimeout)
defer cancelCtx()
c, err := bm.sg.Get(ctx, options.SessionID)
c, err := bm.sg.Get(connectCtx, options.SessionID)
if err != nil {
return nil, err
}

View File

@ -214,7 +214,8 @@ func (s *dispatchState) beginStage(stageName string, image builder.Image) {
s.imageID = image.ImageID()
if image.RunConfig() != nil {
s.runConfig = copyRunConfig(image.RunConfig()) // copy avoids referencing the same instance when 2 stages have the same base
// copy avoids referencing the same instance when 2 stages have the same base
s.runConfig = copyRunConfig(image.RunConfig())
} else {
s.runConfig = &container.Config{}
}

View File

@ -1,6 +1,8 @@
package dockerfile
import (
"runtime"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/builder"
"github.com/docker/docker/builder/remotecontext"
@ -73,7 +75,13 @@ func (m *imageSources) Unmount() (retErr error) {
func (m *imageSources) Add(im *imageMount) {
switch im.image {
case nil:
im.image = &dockerimage.Image{}
// set the OS for scratch images
os := runtime.GOOS
// Windows does not support scratch except for LCOW
if runtime.GOOS == "windows" {
os = "linux"
}
im.image = &dockerimage.Image{V1Image: dockerimage.V1Image{OS: os}}
default:
m.byImageID[im.image.ImageID()] = im
}

View File

@ -25,6 +25,7 @@ import (
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/symlink"
"github.com/docker/docker/pkg/system"
"github.com/docker/go-connections/nat"
lcUser "github.com/opencontainers/runc/libcontainer/user"
"github.com/pkg/errors"
)
@ -385,14 +386,6 @@ func hashStringSlice(prefix string, slice []string) string {
type runConfigModifier func(*container.Config)
func copyRunConfig(runConfig *container.Config, modifiers ...runConfigModifier) *container.Config {
copy := *runConfig
for _, modifier := range modifiers {
modifier(&copy)
}
return &copy
}
func withCmd(cmd []string) runConfigModifier {
return func(runConfig *container.Config) {
runConfig.Cmd = cmd
@ -438,6 +431,48 @@ func withEntrypointOverride(cmd []string, entrypoint []string) runConfigModifier
}
}
func copyRunConfig(runConfig *container.Config, modifiers ...runConfigModifier) *container.Config {
copy := *runConfig
copy.Cmd = copyStringSlice(runConfig.Cmd)
copy.Env = copyStringSlice(runConfig.Env)
copy.Entrypoint = copyStringSlice(runConfig.Entrypoint)
copy.OnBuild = copyStringSlice(runConfig.OnBuild)
copy.Shell = copyStringSlice(runConfig.Shell)
if copy.Volumes != nil {
copy.Volumes = make(map[string]struct{}, len(runConfig.Volumes))
for k, v := range runConfig.Volumes {
copy.Volumes[k] = v
}
}
if copy.ExposedPorts != nil {
copy.ExposedPorts = make(nat.PortSet, len(runConfig.ExposedPorts))
for k, v := range runConfig.ExposedPorts {
copy.ExposedPorts[k] = v
}
}
if copy.Labels != nil {
copy.Labels = make(map[string]string, len(runConfig.Labels))
for k, v := range runConfig.Labels {
copy.Labels[k] = v
}
}
for _, modifier := range modifiers {
modifier(&copy)
}
return &copy
}
func copyStringSlice(orig []string) []string {
if orig == nil {
return nil
}
return append([]string{}, orig...)
}
// getShell is a helper function which gets the right shell for prefixing the
// shell-form of RUN, ENTRYPOINT and CMD instructions
func getShell(c *container.Config, os string) []string {

View File

@ -14,6 +14,7 @@ import (
"github.com/docker/docker/builder/remotecontext"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/go-connections/nat"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -133,6 +134,44 @@ func TestCopyRunConfig(t *testing.T) {
}
func fullMutableRunConfig() *container.Config {
return &container.Config{
Cmd: []string{"command", "arg1"},
Env: []string{"env1=foo", "env2=bar"},
ExposedPorts: nat.PortSet{
"1000/tcp": {},
"1001/tcp": {},
},
Volumes: map[string]struct{}{
"one": {},
"two": {},
},
Entrypoint: []string{"entry", "arg1"},
OnBuild: []string{"first", "next"},
Labels: map[string]string{
"label1": "value1",
"label2": "value2",
},
Shell: []string{"shell", "-c"},
}
}
func TestDeepCopyRunConfig(t *testing.T) {
runConfig := fullMutableRunConfig()
copy := copyRunConfig(runConfig)
assert.Equal(t, fullMutableRunConfig(), copy)
copy.Cmd[1] = "arg2"
copy.Env[1] = "env2=new"
copy.ExposedPorts["10002"] = struct{}{}
copy.Volumes["three"] = struct{}{}
copy.Entrypoint[1] = "arg2"
copy.OnBuild[0] = "start"
copy.Labels["label3"] = "value3"
copy.Shell[0] = "sh"
assert.Equal(t, fullMutableRunConfig(), runConfig)
}
func TestChownFlagParsing(t *testing.T) {
testFiles := map[string]string{
"passwd": `root:x:0:0::/bin:/bin/false

View File

@ -321,7 +321,7 @@ func Parse(rwc io.Reader) (*Result, error) {
Warnings: warnings,
EscapeToken: d.escapeToken,
OS: d.platformToken,
}, nil
}, handleScannerError(scanner.Err())
}
func trimComments(src []byte) []byte {
@ -358,3 +358,12 @@ func processLine(d *Directive, token []byte, stripLeftWhitespace bool) ([]byte,
}
return trimComments(token), d.possibleParserDirective(string(token))
}
func handleScannerError(err error) error {
switch err {
case bufio.ErrTooLong:
return errors.Errorf("dockerfile line greater than max allowed size of %d", bufio.MaxScanTokenSize-1)
default:
return err
}
}

View File

@ -1,12 +1,14 @@
package parser
import (
"bufio"
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"github.com/stretchr/testify/assert"
@ -159,3 +161,14 @@ RUN indented \
assert.Contains(t, warnings[1], "RUN another thing")
assert.Contains(t, warnings[2], "will become errors in a future release")
}
func TestParseReturnsScannerErrors(t *testing.T) {
label := strings.Repeat("a", bufio.MaxScanTokenSize)
dockerfile := strings.NewReader(fmt.Sprintf(`
FROM image
LABEL test=%s
`, label))
_, err := Parse(dockerfile)
assert.EqualError(t, err, "dockerfile line greater than max allowed size of 65535")
}

View File

@ -79,7 +79,6 @@ func FromArchive(tarStream io.Reader) (builder.Source, error) {
}
tsc.sums = sum.GetSums()
return tsc, nil
}
@ -122,8 +121,5 @@ func normalize(path string, root containerfs.ContainerFS) (cleanPath, fullPath s
if err != nil {
return "", "", errors.Wrapf(err, "forbidden path outside the build context: %s (%s)", path, cleanPath)
}
if _, err := root.Lstat(fullPath); err != nil {
return "", "", errors.WithStack(convertPathError(err, path))
}
return
}

View File

@ -97,26 +97,23 @@ func newGitRemote(gitURL string, dockerfilePath string) (builder.Source, *parser
}
func newURLRemote(url string, dockerfilePath string, progressReader func(in io.ReadCloser) io.ReadCloser) (builder.Source, *parser.Result, error) {
var dockerfile io.ReadCloser
dockerfileFoundErr := errors.New("found-dockerfile")
c, err := MakeRemoteContext(url, map[string]func(io.ReadCloser) (io.ReadCloser, error){
mimeTypes.TextPlain: func(rc io.ReadCloser) (io.ReadCloser, error) {
dockerfile = rc
return nil, dockerfileFoundErr
},
// fallback handler (tar context)
"": func(rc io.ReadCloser) (io.ReadCloser, error) {
return progressReader(rc), nil
},
})
switch {
case err == dockerfileFoundErr:
res, err := parser.Parse(dockerfile)
return nil, res, err
case err != nil:
contentType, content, err := downloadRemote(url)
if err != nil {
return nil, nil, err
}
return withDockerfileFromContext(c.(modifiableContext), dockerfilePath)
defer content.Close()
switch contentType {
case mimeTypes.TextPlain:
res, err := parser.Parse(progressReader(content))
return nil, res, err
default:
source, err := FromArchive(progressReader(content))
if err != nil {
return nil, nil, err
}
return withDockerfileFromContext(source.(modifiableContext), dockerfilePath)
}
}
func removeDockerfile(c modifiableContext, filesToRemove ...string) error {

View File

@ -6,6 +6,7 @@ import (
"github.com/docker/docker/builder"
"github.com/docker/docker/builder/remotecontext/git"
"github.com/docker/docker/pkg/archive"
"github.com/sirupsen/logrus"
)
// MakeGitContext returns a Context from gitURL that is cloned in a temporary directory.
@ -21,9 +22,14 @@ func MakeGitContext(gitURL string) (builder.Source, error) {
}
defer func() {
// TODO: print errors?
c.Close()
os.RemoveAll(root)
err := c.Close()
if err != nil {
logrus.WithField("action", "MakeGitContext").WithField("module", "builder").WithField("url", gitURL).WithError(err).Error("error while closing git context")
}
err = os.RemoveAll(root)
if err != nil {
logrus.WithField("action", "MakeGitContext").WithField("module", "builder").WithField("url", gitURL).WithError(err).Error("error while removing path and children of root")
}
}()
return FromArchive(c)
}

View File

@ -40,16 +40,18 @@ func (c *lazySource) Hash(path string) (string, error) {
return "", err
}
fi, err := c.root.Lstat(fullPath)
if err != nil {
return "", errors.WithStack(err)
}
relPath, err := Rel(c.root, fullPath)
if err != nil {
return "", errors.WithStack(convertPathError(err, cleanPath))
}
fi, err := os.Lstat(fullPath)
if err != nil {
// Backwards compatibility: a missing file returns a path as hash.
// This is reached in the case of a broken symlink.
return relPath, nil
}
sum, ok := c.sums[relPath]
if !ok {
sum, err = c.prepareHash(relPath, fi)

View File

@ -10,7 +10,7 @@ import (
"net/url"
"regexp"
"github.com/docker/docker/builder"
"github.com/docker/docker/pkg/ioutils"
"github.com/pkg/errors"
)
@ -22,50 +22,23 @@ const acceptableRemoteMIME = `(?:application/(?:(?:x\-)?tar|octet\-stream|((?:x\
var mimeRe = regexp.MustCompile(acceptableRemoteMIME)
// MakeRemoteContext downloads a context from remoteURL and returns it.
//
// If contentTypeHandlers is non-nil, then the Content-Type header is read along with a maximum of
// maxPreambleLength bytes from the body to help detecting the MIME type.
// Look at acceptableRemoteMIME for more details.
//
// If a match is found, then the body is sent to the contentType handler and a (potentially compressed) tar stream is expected
// to be returned. If no match is found, it is assumed the body is a tar stream (compressed or not).
// In either case, an (assumed) tar stream is passed to FromArchive whose result is returned.
func MakeRemoteContext(remoteURL string, contentTypeHandlers map[string]func(io.ReadCloser) (io.ReadCloser, error)) (builder.Source, error) {
f, err := GetWithStatusError(remoteURL)
// downloadRemote context from a url and returns it, along with the parsed content type
func downloadRemote(remoteURL string) (string, io.ReadCloser, error) {
response, err := GetWithStatusError(remoteURL)
if err != nil {
return nil, fmt.Errorf("error downloading remote context %s: %v", remoteURL, err)
}
defer f.Body.Close()
var contextReader io.ReadCloser
if contentTypeHandlers != nil {
contentType := f.Header.Get("Content-Type")
clen := f.ContentLength
contentType, contextReader, err = inspectResponse(contentType, f.Body, clen)
if err != nil {
return nil, fmt.Errorf("error detecting content type for remote %s: %v", remoteURL, err)
}
defer contextReader.Close()
// This loop tries to find a content-type handler for the detected content-type.
// If it could not find one from the caller-supplied map, it tries the empty content-type `""`
// which is interpreted as a fallback handler (usually used for raw tar contexts).
for _, ct := range []string{contentType, ""} {
if fn, ok := contentTypeHandlers[ct]; ok {
defer contextReader.Close()
if contextReader, err = fn(contextReader); err != nil {
return nil, err
}
break
}
}
return "", nil, fmt.Errorf("error downloading remote context %s: %v", remoteURL, err)
}
// Pass through - this is a pre-packaged context, presumably
// with a Dockerfile with the right name inside it.
return FromArchive(contextReader)
contentType, contextReader, err := inspectResponse(
response.Header.Get("Content-Type"),
response.Body,
response.ContentLength)
if err != nil {
response.Body.Close()
return "", nil, fmt.Errorf("error detecting content type for remote %s: %v", remoteURL, err)
}
return contentType, ioutils.NewReadCloserWrapper(contextReader, response.Body.Close), nil
}
// GetWithStatusError does an http.Get() and returns an error if the
@ -110,7 +83,7 @@ func GetWithStatusError(address string) (resp *http.Response, err error) {
// - an io.Reader for the response body
// - an error value which will be non-nil either when something goes wrong while
// reading bytes from r or when the detected content-type is not acceptable.
func inspectResponse(ct string, r io.Reader, clen int64) (string, io.ReadCloser, error) {
func inspectResponse(ct string, r io.Reader, clen int64) (string, io.Reader, error) {
plen := clen
if plen <= 0 || plen > maxPreambleLength {
plen = maxPreambleLength
@ -119,14 +92,14 @@ func inspectResponse(ct string, r io.Reader, clen int64) (string, io.ReadCloser,
preamble := make([]byte, plen)
rlen, err := r.Read(preamble)
if rlen == 0 {
return ct, ioutil.NopCloser(r), errors.New("empty response")
return ct, r, errors.New("empty response")
}
if err != nil && err != io.EOF {
return ct, ioutil.NopCloser(r), err
return ct, r, err
}
preambleR := bytes.NewReader(preamble[:rlen])
bodyReader := ioutil.NopCloser(io.MultiReader(preambleR, r))
bodyReader := io.MultiReader(preambleR, r)
// Some web servers will use application/octet-stream as the default
// content type for files without an extension (e.g. 'Dockerfile')
// so if we receive this value we better check for text content

View File

@ -11,7 +11,7 @@ import (
"github.com/docker/docker/builder"
"github.com/docker/docker/internal/testutil"
"github.com/docker/docker/pkg/archive"
"github.com/gotestyourself/gotestyourself/fs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -174,11 +174,10 @@ func TestUnknownContentLength(t *testing.T) {
}
}
func TestMakeRemoteContext(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-tarsum-test")
defer cleanup()
createTestTempFile(t, contextDir, builder.DefaultDockerfileName, dockerfileContents, 0777)
func TestDownloadRemote(t *testing.T) {
contextDir := fs.NewDir(t, "test-builder-download-remote",
fs.WithFile(builder.DefaultDockerfileName, dockerfileContents))
defer contextDir.Remove()
mux := http.NewServeMux()
server := httptest.NewServer(mux)
@ -187,39 +186,15 @@ func TestMakeRemoteContext(t *testing.T) {
serverURL.Path = "/" + builder.DefaultDockerfileName
remoteURL := serverURL.String()
mux.Handle("/", http.FileServer(http.Dir(contextDir)))
mux.Handle("/", http.FileServer(http.Dir(contextDir.Path())))
remoteContext, err := MakeRemoteContext(remoteURL, map[string]func(io.ReadCloser) (io.ReadCloser, error){
mimeTypes.TextPlain: func(rc io.ReadCloser) (io.ReadCloser, error) {
dockerfile, err := ioutil.ReadAll(rc)
if err != nil {
return nil, err
}
contentType, content, err := downloadRemote(remoteURL)
require.NoError(t, err)
r, err := archive.Generate(builder.DefaultDockerfileName, string(dockerfile))
if err != nil {
return nil, err
}
return ioutil.NopCloser(r), nil
},
})
if err != nil {
t.Fatalf("Error when executing DetectContextFromRemoteURL: %s", err)
}
if remoteContext == nil {
t.Fatal("Remote context should not be nil")
}
h, err := remoteContext.Hash(builder.DefaultDockerfileName)
if err != nil {
t.Fatalf("failed to compute hash %s", err)
}
if expected, actual := "7b6b6b66bee9e2102fbdc2228be6c980a2a23adf371962a37286a49f7de0f7cc", h; expected != actual {
t.Fatalf("There should be file named %s %s in fileInfoSums", expected, actual)
}
assert.Equal(t, mimeTypes.TextPlain, contentType)
raw, err := ioutil.ReadAll(content)
require.NoError(t, err)
assert.Equal(t, dockerfileContents, string(raw))
}
func TestGetWithStatusError(t *testing.T) {

View File

@ -104,17 +104,6 @@ func TestHashSubdir(t *testing.T) {
}
}
func TestStatNotExisting(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-tarsum-test")
defer cleanup()
src := makeTestArchiveContext(t, contextDir)
_, err := src.Hash("not-existing")
if !os.IsNotExist(errors.Cause(err)) {
t.Fatalf("This file should not exist: %s", err)
}
}
func TestRemoveDirectory(t *testing.T) {
contextDir, cleanup := createTestTempDir(t, "", "builder-tarsum-test")
defer cleanup()
@ -129,17 +118,20 @@ func TestRemoveDirectory(t *testing.T) {
src := makeTestArchiveContext(t, contextDir)
tarSum := src.(modifiableContext)
_, err = src.Root().Stat(src.Root().Join(src.Root().Path(), relativePath))
if err != nil {
t.Fatalf("Statting %s shouldn't fail: %+v", relativePath, err)
}
tarSum := src.(modifiableContext)
err = tarSum.Remove(relativePath)
if err != nil {
t.Fatalf("Error when executing Remove: %s", err)
}
_, err = src.Hash(contextSubdir)
_, err = src.Root().Stat(src.Root().Join(src.Root().Path(), relativePath))
if !os.IsNotExist(errors.Cause(err)) {
t.Fatal("Directory should not exist at this point")
t.Fatalf("Directory should not exist at this point: %+v ", err)
}
}

View File

@ -1,4 +1,4 @@
// +build linux freebsd solaris openbsd darwin
// +build linux freebsd openbsd darwin
package client

View File

@ -51,6 +51,14 @@ func (cli *Client) ContainerLogs(ctx context.Context, container string, options
query.Set("since", ts)
}
if options.Until != "" {
ts, err := timetypes.GetTimestamp(options.Until, time.Now())
if err != nil {
return nil, err
}
query.Set("until", ts)
}
if options.Timestamps {
query.Set("timestamps", "1")
}

View File

@ -13,6 +13,7 @@ import (
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/internal/testutil"
"golang.org/x/net/context"
)
@ -28,9 +29,11 @@ func TestContainerLogsError(t *testing.T) {
_, err = client.ContainerLogs(context.Background(), "container_id", types.ContainerLogsOptions{
Since: "2006-01-02TZ",
})
if err == nil || !strings.Contains(err.Error(), `parsing time "2006-01-02TZ"`) {
t.Fatalf("expected a 'parsing time' error, got %v", err)
}
testutil.ErrorContains(t, err, `parsing time "2006-01-02TZ"`)
_, err = client.ContainerLogs(context.Background(), "container_id", types.ContainerLogsOptions{
Until: "2006-01-02TZ",
})
testutil.ErrorContains(t, err, `parsing time "2006-01-02TZ"`)
}
func TestContainerLogs(t *testing.T) {
@ -80,6 +83,17 @@ func TestContainerLogs(t *testing.T) {
"since": "invalid but valid",
},
},
{
options: types.ContainerLogsOptions{
// An complete invalid date, timestamp or go duration will be
// passed as is
Until: "invalid but valid",
},
expectedQueryParams: map[string]string{
"tail": "",
"until": "invalid but valid",
},
},
}
for _, logCase := range cases {
client := &Client{

View File

@ -65,7 +65,8 @@ 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.Var(opts.NewListOptsRef(&conf.NodeGenericResources, opts.ValidateSingleGenericResource), "node-generic-resource", "Advertise user-defined resource")
flags.IntVar(&conf.NetworkControlPlaneMTU, "network-control-plane-mtu", config.DefaultNetworkMtu, "Network Control plane MTU")
// "--deprecated-key-path" is to allow configuration of the key used

View File

@ -1,4 +1,4 @@
// +build solaris linux freebsd
// +build linux freebsd
package main

View File

@ -1,4 +1,4 @@
// +build linux,!solaris freebsd,!solaris
// +build linux freebsd
package main

View File

@ -1,4 +1,4 @@
// +build linux,!solaris freebsd,!solaris
// +build linux freebsd
package main

View File

@ -480,22 +480,12 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
logrus.Warnf(`The "-g / --graph" flag is deprecated. Please use "--data-root" instead`)
}
// Labels of the docker engine used to allow multiple values associated with the same key.
// This is deprecated in 1.13, and, be removed after 3 release cycles.
// The following will check the conflict of labels, and report a warning for deprecation.
//
// TODO: After 3 release cycles (17.12) an error will be returned, and labels will be
// sanitized to consolidate duplicate key-value pairs (config.Labels = newLabels):
//
// newLabels, err := daemon.GetConflictFreeLabels(config.Labels)
// if err != nil {
// return nil, err
// }
// config.Labels = newLabels
//
if _, err := config.GetConflictFreeLabels(conf.Labels); err != nil {
logrus.Warnf("Engine labels with duplicate keys and conflicting values have been deprecated: %s", err)
// Check if duplicate label-keys with different values are found
newLabels, err := config.GetConflictFreeLabels(conf.Labels)
if err != nil {
return nil, err
}
conf.Labels = newLabels
// Regardless of whether the user sets it to true or false, if they
// specify TLSVerify at all then we need to turn on TLS

View File

@ -61,6 +61,28 @@ func TestLoadDaemonCliConfigWithConflicts(t *testing.T) {
testutil.ErrorContains(t, err, "as a flag and in the configuration file: labels")
}
func TestLoadDaemonCliWithConflictingLabels(t *testing.T) {
opts := defaultOptions("")
flags := opts.flags
assert.NoError(t, flags.Set("label", "foo=bar"))
assert.NoError(t, flags.Set("label", "foo=baz"))
_, err := loadDaemonCliConfig(opts)
assert.EqualError(t, err, "conflict labels for foo=baz and foo=bar")
}
func TestLoadDaemonCliWithDuplicateLabels(t *testing.T) {
opts := defaultOptions("")
flags := opts.flags
assert.NoError(t, flags.Set("label", "foo=the-same"))
assert.NoError(t, flags.Set("label", "foo=the-same"))
_, err := loadDaemonCliConfig(opts)
assert.NoError(t, err)
}
func TestLoadDaemonCliConfigWithTLSVerify(t *testing.T) {
tempFile := fs.NewFile(t, "config", fs.WithContent(`{"tlsverify": true}`))
defer tempFile.Remove()

View File

@ -1,4 +1,4 @@
// +build !windows,!solaris
// +build !windows
package main

View File

@ -1,7 +1,4 @@
// +build !windows,!solaris
// TODO: Create new file for Solaris which tests config parameters
// as described in daemon/config_solaris.go
// +build !windows
package main

View File

@ -1,4 +1,4 @@
// +build solaris freebsd
// +build freebsd
package container
@ -7,7 +7,7 @@ import (
)
func detachMounted(path string) error {
//Solaris and FreeBSD do not support the lazy unmount or MNT_DETACH feature.
// FreeBSD do not support the lazy unmount or MNT_DETACH feature.
// Therefore there are separate definitions for this.
return unix.Unmount(path, 0)
}

View File

@ -1,4 +1,4 @@
// +build linux freebsd solaris
// +build linux freebsd
package container
@ -65,12 +65,11 @@ func (container *Container) NetworkMounts() []Mount {
if _, err := os.Stat(container.ResolvConfPath); err != nil {
logrus.Warnf("ResolvConfPath set to %q, but can't stat this filename (err = %v); skipping", container.ResolvConfPath, err)
} else {
if !container.HasMountFor("/etc/resolv.conf") {
label.Relabel(container.ResolvConfPath, container.MountLabel, shared)
}
writable := !container.HostConfig.ReadonlyRootfs
if m, exists := container.MountPoints["/etc/resolv.conf"]; exists {
writable = m.RW
} else {
label.Relabel(container.ResolvConfPath, container.MountLabel, shared)
}
mounts = append(mounts, Mount{
Source: container.ResolvConfPath,
@ -84,12 +83,11 @@ func (container *Container) NetworkMounts() []Mount {
if _, err := os.Stat(container.HostnamePath); err != nil {
logrus.Warnf("HostnamePath set to %q, but can't stat this filename (err = %v); skipping", container.HostnamePath, err)
} else {
if !container.HasMountFor("/etc/hostname") {
label.Relabel(container.HostnamePath, container.MountLabel, shared)
}
writable := !container.HostConfig.ReadonlyRootfs
if m, exists := container.MountPoints["/etc/hostname"]; exists {
writable = m.RW
} else {
label.Relabel(container.HostnamePath, container.MountLabel, shared)
}
mounts = append(mounts, Mount{
Source: container.HostnamePath,
@ -103,12 +101,11 @@ func (container *Container) NetworkMounts() []Mount {
if _, err := os.Stat(container.HostsPath); err != nil {
logrus.Warnf("HostsPath set to %q, but can't stat this filename (err = %v); skipping", container.HostsPath, err)
} else {
if !container.HasMountFor("/etc/hosts") {
label.Relabel(container.HostsPath, container.MountLabel, shared)
}
writable := !container.HostConfig.ReadonlyRootfs
if m, exists := container.MountPoints["/etc/hosts"]; exists {
writable = m.RW
} else {
label.Relabel(container.HostsPath, container.MountLabel, shared)
}
mounts = append(mounts, Mount{
Source: container.HostsPath,
@ -160,7 +157,18 @@ func (container *Container) ShmResourcePath() (string, error) {
// HasMountFor checks if path is a mountpoint
func (container *Container) HasMountFor(path string) bool {
_, exists := container.MountPoints[path]
return exists
if exists {
return true
}
// Also search among the tmpfs mounts
for dest := range container.HostConfig.Tmpfs {
if dest == path {
return true
}
}
return false
}
// UnmountIpcMount uses the provided unmount function to unmount shm if it was mounted
@ -324,6 +332,12 @@ func (container *Container) UpdateContainer(hostConfig *containertypes.HostConfi
if resources.KernelMemory != 0 {
cResources.KernelMemory = resources.KernelMemory
}
if resources.CPURealtimePeriod != 0 {
cResources.CPURealtimePeriod = resources.CPURealtimePeriod
}
if resources.CPURealtimeRuntime != 0 {
cResources.CPURealtimeRuntime = resources.CPURealtimeRuntime
}
// update HostConfig of container
if hostConfig.RestartPolicy.Name != "" {

View File

@ -1,6 +1,8 @@
package container
import (
"sync"
"github.com/docker/docker/api/types"
"github.com/sirupsen/logrus"
)
@ -9,26 +11,53 @@ import (
type Health struct {
types.Health
stop chan struct{} // Write struct{} to stop the monitor
mu sync.Mutex
}
// String returns a human-readable description of the health-check state
func (s *Health) String() string {
// This happens when the monitor has yet to be setup.
if s.Status == "" {
return types.Unhealthy
}
status := s.Status()
switch s.Status {
switch status {
case types.Starting:
return "health: starting"
default: // Healthy and Unhealthy are clear on their own
return s.Status
return s.Health.Status
}
}
// OpenMonitorChannel creates and returns a new monitor channel. If there already is one,
// it returns nil.
// Status returns the current health status.
//
// Note that this takes a lock and the value may change after being read.
func (s *Health) Status() string {
s.mu.Lock()
defer s.mu.Unlock()
// This happens when the monitor has yet to be setup.
if s.Health.Status == "" {
return types.Unhealthy
}
return s.Health.Status
}
// SetStatus writes the current status to the underlying health structure,
// obeying the locking semantics.
//
// Status may be set directly if another lock is used.
func (s *Health) SetStatus(new string) {
s.mu.Lock()
defer s.mu.Unlock()
s.Health.Status = new
}
// OpenMonitorChannel creates and returns a new monitor channel. If there
// already is one, it returns nil.
func (s *Health) OpenMonitorChannel() chan struct{} {
s.mu.Lock()
defer s.mu.Unlock()
if s.stop == nil {
logrus.Debug("OpenMonitorChannel")
s.stop = make(chan struct{})
@ -39,12 +68,15 @@ func (s *Health) OpenMonitorChannel() chan struct{} {
// CloseMonitorChannel closes any existing monitor channel.
func (s *Health) CloseMonitorChannel() {
s.mu.Lock()
defer s.mu.Unlock()
if s.stop != nil {
logrus.Debug("CloseMonitorChannel: waiting for probe to stop")
close(s.stop)
s.stop = nil
// unhealthy when the monitor has stopped for compatibility reasons
s.Status = types.Unhealthy
s.Health.Status = types.Unhealthy
logrus.Debug("CloseMonitorChannel done")
}
}

View File

@ -7,7 +7,7 @@ FROM aarch64/debian:jessie
RUN echo deb http://ftp.debian.org/debian jessie-backports main > /etc/apt/sources.list.d/backports.list
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev libseccomp-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM aarch64/debian:stretch
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-dev libseccomp-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM aarch64/ubuntu:trusty
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM aarch64/ubuntu:xenial
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-dev libseccomp-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -12,7 +12,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list.d
RUN apt-get update && apt-get install -y -t wheezy-backports btrfs-tools --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y apparmor bash-completion build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM ubuntu:trusty
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM ubuntu:xenial
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM ubuntu:yakkety
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM ubuntu:zesty
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
# GOARM is the ARM architecture version which is unrelated to the above Golang version
ENV GOARM 6
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local

View File

@ -6,7 +6,7 @@ FROM armhf/ubuntu:trusty
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM armhf/ubuntu:xenial
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM armhf/ubuntu:yakkety
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM ppc64le/ubuntu:trusty
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM ppc64le/ubuntu:xenial
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libseccomp-dev libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM ppc64le/ubuntu:yakkety
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libseccomp-dev libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM s390x/ubuntu:xenial
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config libsystemd-dev vim-common --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,7 +6,7 @@ FROM s390x/ubuntu:yakkety
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config libsystemd-dev vim-common --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -5,9 +5,9 @@
FROM amazonlinux:latest
RUN yum groupinstall -y "Development Tools"
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel tar git cmake vim-common
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel tar git cmake vim-common
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,9 +6,9 @@ FROM centos:7
RUN yum groupinstall -y "Development Tools"
RUN yum -y swap -- remove systemd-container systemd-container-libs -- install systemd systemd-libs
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,9 +6,9 @@ FROM fedora:24
RUN dnf -y upgrade
RUN dnf install -y @development-tools fedora-packager
RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,9 +6,9 @@ FROM fedora:25
RUN dnf -y upgrade
RUN dnf install -y @development-tools fedora-packager
RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -5,9 +5,9 @@
FROM opensuse:13.2
RUN zypper --non-interactive install ca-certificates* curl gzip rpm-build
RUN zypper --non-interactive install libbtrfs-devel device-mapper-devel glibc-static libselinux-devel libtool-ltdl-devel pkg-config selinux-policy selinux-policy-devel systemd-devel tar git cmake vim systemd-rpm-macros
RUN zypper --non-interactive install libbtrfs-devel device-mapper-devel glibc-static libselinux-devel pkg-config selinux-policy selinux-policy-devel systemd-devel tar git cmake vim systemd-rpm-macros
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -8,9 +8,9 @@ RUN yum install -y yum-utils && curl -o /etc/yum.repos.d/public-yum-ol6.repo htt
RUN yum install -y kernel-uek-devel-4.1.12-32.el6uek
RUN yum groupinstall -y "Development Tools"
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel tar git cmake vim-common
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel pkgconfig selinux-policy selinux-policy-devel tar git cmake vim-common
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -5,9 +5,9 @@
FROM oraclelinux:7
RUN yum groupinstall -y "Development Tools"
RUN yum install -y --enablerepo=ol7_optional_latest btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
RUN yum install -y --enablerepo=ol7_optional_latest btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -5,9 +5,9 @@
FROM photon:1.0
RUN tdnf install -y wget curl ca-certificates gzip make rpm-build sed gcc linux-api-headers glibc-devel binutils libseccomp elfutils
RUN tdnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkg-config selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
RUN tdnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkg-config selinux-policy selinux-policy-devel systemd-devel tar git cmake vim-common
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -7,9 +7,9 @@ FROM multiarch/centos:7.2.1511-armhfp-clean
RUN yum install -y yum-plugin-ovl
RUN yum groupinstall --skip-broken -y "Development Tools"
RUN yum -y swap -- remove systemd-container systemd-container-libs -- install systemd systemd-libs
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -6,10 +6,10 @@ FROM ppc64le/centos:7
RUN yum groupinstall -y "Development Tools"
RUN yum -y swap -- remove systemd-container systemd-container-libs -- install systemd systemd-libs
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
ENV GO_VERSION 1.8.5
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin
ENV AUTO_GOPATH 1

View File

@ -6,9 +6,9 @@ FROM ppc64le/fedora:24
RUN dnf -y upgrade
RUN dnf install -y @development-tools fedora-packager
RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel systemd-devel tar git cmake
RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -7,10 +7,10 @@ FROM ppc64le/opensuse:42.1
RUN zypper addrepo -n ppc64le-oss -f https://download.opensuse.org/ports/ppc/distribution/leap/42.1/repo/oss/ ppc64le-oss
RUN zypper addrepo -n ppc64le-updates -f https://download.opensuse.org/ports/update/42.1/ ppc64le-updates
RUN zypper --non-interactive install ca-certificates* curl gzip rpm-build
RUN zypper --non-interactive install libbtrfs-devel device-mapper-devel glibc-static libselinux-devel libtool-ltdl-devel pkg-config selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim
RUN zypper --non-interactive install libbtrfs-devel device-mapper-devel glibc-static libselinux-devel pkg-config selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim
ENV GO_VERSION 1.8.5
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin
ENV AUTO_GOPATH 1

View File

@ -6,9 +6,9 @@ FROM sinenomine/clefos-base-s390x
RUN touch /var/lib/rpm/* && yum groupinstall -y "Development Tools"
RUN touch /var/lib/rpm/* && yum install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
RUN touch /var/lib/rpm/* && yum install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim-common
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -7,9 +7,9 @@ FROM opensuse/s390x:tumbleweed
RUN zypper ar https://download.opensuse.org/ports/zsystems/tumbleweed/repo/oss/ tumbleweed
RUN zypper --non-interactive install ca-certificates* curl gzip rpm-build
RUN zypper --non-interactive install libbtrfs-devel device-mapper-devel glibc-static libselinux-devel libtool-ltdl-devel pkg-config selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim systemd-rpm-macros
RUN zypper --non-interactive install libbtrfs-devel device-mapper-devel glibc-static libselinux-devel pkg-config selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git cmake vim systemd-rpm-macros
ENV GO_VERSION 1.8.5
ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin

View File

@ -1,4 +1,4 @@
// +build !windows,!solaris
// +build !windows
package main

View File

@ -11,7 +11,6 @@ usage() {
echo >&2 " $mkimg -t someuser/centos:5 rinse --distribution centos-5"
echo >&2 " $mkimg -t someuser/mageia:4 mageia-urpmi --version=4"
echo >&2 " $mkimg -t someuser/mageia:4 mageia-urpmi --version=4 --mirror=http://somemirror/"
echo >&2 " $mkimg -t someuser/solaris solaris"
exit 1
}
@ -20,13 +19,6 @@ scriptDir="$(dirname "$(readlink -f "$BASH_SOURCE")")/mkimage"
os=
os=$(uname -o)
# set up path to gnu tools if solaris
[[ $os == "Solaris" ]] && export PATH=/usr/gnu/bin:$PATH
# TODO check for gnu-tar, gnu-getopt
# TODO requires root/sudo due to some pkg operations. sigh.
[[ $os == "Solaris" && $EUID != "0" ]] && echo >&2 "image create on Solaris requires superuser privilege"
optTemp=$(getopt --options '+d:t:c:hC' --longoptions 'dir:,tag:,compression:,no-compression,help' --name "$mkimg" -- "$@")
eval set -- "$optTemp"
unset optTemp

View File

@ -1,89 +0,0 @@
#!/usr/bin/env bash
#
# Solaris 12 base image build script.
#
set -e
# TODO add optional package publisher origin
rootfsDir="$1"
shift
# base install
(
set -x
pkg image-create --full --zone \
--facet facet.locale.*=false \
--facet facet.locale.POSIX=true \
--facet facet.doc=false \
--facet facet.doc.*=false \
"$rootfsDir"
pkg -R "$rootfsDir" set-property use-system-repo true
pkg -R "$rootfsDir" set-property flush-content-cache-on-success true
pkg -R "$rootfsDir" install core-os
)
# Lay in stock configuration, set up milestone
# XXX This all may become optional in a base image
(
# faster to build repository database on tmpfs
REPO_DB=/system/volatile/repository.$$
export SVCCFG_REPOSITORY=${REPO_DB}
export SVCCFG_DOOR_PATH=$rootfsDir/system/volatile/tmp_repo_door
# Import base manifests. NOTE These are a combination of basic requirement
# and gleaned from container milestone manifest. They may change.
for m in $rootfsDir/lib/svc/manifest/system/environment.xml \
$rootfsDir/lib/svc/manifest/system/svc/global.xml \
$rootfsDir/lib/svc/manifest/system/svc/restarter.xml \
$rootfsDir/lib/svc/manifest/network/dns/client.xml \
$rootfsDir/lib/svc/manifest/system/name-service/switch.xml \
$rootfsDir/lib/svc/manifest/system/name-service/cache.xml \
$rootfsDir/lib/svc/manifest/milestone/container.xml ; do
svccfg import $m
done
# Apply system layer profile, deleting unnecessary dependencies
svccfg apply $rootfsDir/etc/svc/profile/generic_container.xml
# XXX Even if we keep a repo in the base image, this is definitely optional
svccfg apply $rootfsDir/etc/svc/profile/sysconfig/container_sc.xml
for s in svc:/system/svc/restarter \
svc:/system/environment \
svc:/network/dns/client \
svc:/system/name-service/switch \
svc:/system/name-service/cache \
svc:/system/svc/global \
svc:/milestone/container ;do
svccfg -s $s refresh
done
# now copy the built up repository into the base rootfs
mv $REPO_DB $rootfsDir/etc/svc/repository.db
)
# pkg(1) needs the zoneproxy-client running in the container.
# use a simple wrapper to run it as needed.
# XXX maybe we go back to running this in SMF?
mv "$rootfsDir/usr/bin/pkg" "$rootfsDir/usr/bin/wrapped_pkg"
cat > "$rootfsDir/usr/bin/pkg" <<-'EOF'
#!/bin/sh
#
# THIS FILE CREATED DURING DOCKER BASE IMAGE CREATION
#
# The Solaris base image uses the sysrepo proxy mechanism. The
# IPS client pkg(1) requires the zoneproxy-client to reach the
# remote publisher origins through the host. This wrapper script
# enables and disables the proxy client as needed. This is a
# temporary solution.
/usr/lib/zones/zoneproxy-client -s localhost:1008
PKG_SYSREPO_URL=http://localhost:1008 /usr/bin/wrapped_pkg "$@"
pkill -9 zoneproxy-client
EOF
chmod +x "$rootfsDir/usr/bin/pkg"

View File

@ -71,11 +71,7 @@ func (rl *releaseableLayer) Commit(os string) (builder.ReleaseableLayer, error)
if err != nil {
return nil, err
}
if layer.IsEmpty(newLayer.DiffID()) {
_, err := rl.layerStore.Release(newLayer)
return &releaseableLayer{layerStore: rl.layerStore}, err
}
// TODO: An optimization woudld be to handle empty layers before returning
return &releaseableLayer{layerStore: rl.layerStore, roLayer: newLayer}, nil
}

View File

@ -6,7 +6,6 @@ import (
"fmt"
"strings"
"github.com/docker/docker/pkg/stringutils"
"github.com/syndtr/gocapability/capability"
)
@ -69,6 +68,17 @@ func GetAllCapabilities() []string {
return output
}
// inSlice tests whether a string is contained in a slice of strings or not.
// Comparison is case insensitive
func inSlice(slice []string, s string) bool {
for _, ss := range slice {
if strings.ToLower(s) == strings.ToLower(ss) {
return true
}
}
return false
}
// TweakCapabilities can tweak capabilities by adding or dropping capabilities
// based on the basics capabilities.
func TweakCapabilities(basics, adds, drops []string) ([]string, error) {
@ -86,17 +96,17 @@ func TweakCapabilities(basics, adds, drops []string) ([]string, error) {
continue
}
if !stringutils.InSlice(allCaps, "CAP_"+cap) {
if !inSlice(allCaps, "CAP_"+cap) {
return nil, fmt.Errorf("Unknown capability drop: %q", cap)
}
}
// handle --cap-add=all
if stringutils.InSlice(adds, "all") {
if inSlice(adds, "all") {
basics = allCaps
}
if !stringutils.InSlice(drops, "all") {
if !inSlice(drops, "all") {
for _, cap := range basics {
// skip `all` already handled above
if strings.ToLower(cap) == "all" {
@ -104,7 +114,7 @@ func TweakCapabilities(basics, adds, drops []string) ([]string, error) {
}
// if we don't drop `all`, add back all the non-dropped caps
if !stringutils.InSlice(drops, cap[4:]) {
if !inSlice(drops, cap[4:]) {
newCaps = append(newCaps, strings.ToUpper(cap))
}
}
@ -118,12 +128,12 @@ func TweakCapabilities(basics, adds, drops []string) ([]string, error) {
cap = "CAP_" + cap
if !stringutils.InSlice(allCaps, cap) {
if !inSlice(allCaps, cap) {
return nil, fmt.Errorf("Unknown capability to add: %q", cap)
}
// add cap if not already in the list
if !stringutils.InSlice(newCaps, cap) {
if !inSlice(newCaps, cap) {
newCaps = append(newCaps, strings.ToUpper(cap))
}
}

View File

@ -34,6 +34,7 @@ func containerSpecFromGRPC(c *swarmapi.ContainerSpec) *types.ContainerSpec {
Hosts: c.Hosts,
Secrets: secretReferencesFromGRPC(c.Secrets),
Configs: configReferencesFromGRPC(c.Configs),
Isolation: IsolationFromGRPC(c.Isolation),
}
if c.DNSConfig != nil {
@ -232,6 +233,7 @@ func containerToGRPC(c *types.ContainerSpec) (*swarmapi.ContainerSpec, error) {
Hosts: c.Hosts,
Secrets: secretReferencesToGRPC(c.Secrets),
Configs: configReferencesToGRPC(c.Configs),
Isolation: isolationToGRPC(c.Isolation),
}
if c.DNSConfig != nil {
@ -354,3 +356,26 @@ func healthConfigToGRPC(h *container.HealthConfig) *swarmapi.HealthConfig {
StartPeriod: gogotypes.DurationProto(h.StartPeriod),
}
}
// IsolationFromGRPC converts a swarm api container isolation to a moby isolation representation
func IsolationFromGRPC(i swarmapi.ContainerSpec_Isolation) container.Isolation {
switch i {
case swarmapi.ContainerIsolationHyperV:
return container.IsolationHyperV
case swarmapi.ContainerIsolationProcess:
return container.IsolationProcess
case swarmapi.ContainerIsolationDefault:
return container.IsolationDefault
}
return container.IsolationEmpty
}
func isolationToGRPC(i container.Isolation) swarmapi.ContainerSpec_Isolation {
if i.IsHyperV() {
return swarmapi.ContainerIsolationHyperV
}
if i.IsProcess() {
return swarmapi.ContainerIsolationProcess
}
return swarmapi.ContainerIsolationDefault
}

View File

@ -3,10 +3,12 @@ package convert
import (
"testing"
containertypes "github.com/docker/docker/api/types/container"
swarmtypes "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/swarm/runtime"
swarmapi "github.com/docker/swarmkit/api"
google_protobuf3 "github.com/gogo/protobuf/types"
"github.com/stretchr/testify/require"
)
func TestServiceConvertFromGRPCRuntimeContainer(t *testing.T) {
@ -148,3 +150,85 @@ func TestServiceConvertToGRPCGenericRuntimeCustom(t *testing.T) {
t.Fatal(err)
}
}
func TestServiceConvertToGRPCIsolation(t *testing.T) {
cases := []struct {
name string
from containertypes.Isolation
to swarmapi.ContainerSpec_Isolation
}{
{name: "empty", from: containertypes.IsolationEmpty, to: swarmapi.ContainerIsolationDefault},
{name: "default", from: containertypes.IsolationDefault, to: swarmapi.ContainerIsolationDefault},
{name: "process", from: containertypes.IsolationProcess, to: swarmapi.ContainerIsolationProcess},
{name: "hyperv", from: containertypes.IsolationHyperV, to: swarmapi.ContainerIsolationHyperV},
{name: "proCess", from: containertypes.Isolation("proCess"), to: swarmapi.ContainerIsolationProcess},
{name: "hypErv", from: containertypes.Isolation("hypErv"), to: swarmapi.ContainerIsolationHyperV},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
s := swarmtypes.ServiceSpec{
TaskTemplate: swarmtypes.TaskSpec{
ContainerSpec: &swarmtypes.ContainerSpec{
Image: "alpine:latest",
Isolation: c.from,
},
},
Mode: swarmtypes.ServiceMode{
Global: &swarmtypes.GlobalService{},
},
}
res, err := ServiceSpecToGRPC(s)
require.NoError(t, err)
v, ok := res.Task.Runtime.(*swarmapi.TaskSpec_Container)
if !ok {
t.Fatal("expected type swarmapi.TaskSpec_Container")
}
require.Equal(t, c.to, v.Container.Isolation)
})
}
}
func TestServiceConvertFromGRPCIsolation(t *testing.T) {
cases := []struct {
name string
from swarmapi.ContainerSpec_Isolation
to containertypes.Isolation
}{
{name: "default", to: containertypes.IsolationDefault, from: swarmapi.ContainerIsolationDefault},
{name: "process", to: containertypes.IsolationProcess, from: swarmapi.ContainerIsolationProcess},
{name: "hyperv", to: containertypes.IsolationHyperV, from: swarmapi.ContainerIsolationHyperV},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
gs := swarmapi.Service{
Meta: swarmapi.Meta{
Version: swarmapi.Version{
Index: 1,
},
CreatedAt: nil,
UpdatedAt: nil,
},
SpecVersion: &swarmapi.Version{
Index: 1,
},
Spec: swarmapi.ServiceSpec{
Task: swarmapi.TaskSpec{
Runtime: &swarmapi.TaskSpec_Container{
Container: &swarmapi.ContainerSpec{
Image: "alpine:latest",
Isolation: c.from,
},
},
},
},
}
svc, err := ServiceFromGRPC(gs)
if err != nil {
t.Fatal(err)
}
require.Equal(t, c.to, svc.Spec.TaskTemplate.ContainerSpec.Isolation)
})
}
}

View File

@ -168,6 +168,10 @@ func (c *containerConfig) portBindings() nat.PortMap {
return portBindings
}
func (c *containerConfig) isolation() enginecontainer.Isolation {
return convert.IsolationFromGRPC(c.spec().Isolation)
}
func (c *containerConfig) exposedPorts() map[nat.Port]struct{} {
exposedPorts := make(map[nat.Port]struct{})
if c.task.Endpoint == nil {
@ -350,6 +354,7 @@ func (c *containerConfig) hostConfig() *enginecontainer.HostConfig {
PortBindings: c.portBindings(),
Mounts: c.mounts(),
ReadonlyRootfs: c.spec().ReadOnly,
Isolation: c.isolation(),
}
if c.spec().DNSConfig != nil {

View File

@ -0,0 +1,37 @@
package container
import (
"testing"
container "github.com/docker/docker/api/types/container"
swarmapi "github.com/docker/swarmkit/api"
"github.com/stretchr/testify/require"
)
func TestIsolationConversion(t *testing.T) {
cases := []struct {
name string
from swarmapi.ContainerSpec_Isolation
to container.Isolation
}{
{name: "default", from: swarmapi.ContainerIsolationDefault, to: container.IsolationDefault},
{name: "process", from: swarmapi.ContainerIsolationProcess, to: container.IsolationProcess},
{name: "hyperv", from: swarmapi.ContainerIsolationHyperV, to: container.IsolationHyperV},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
task := swarmapi.Task{
Spec: swarmapi.TaskSpec{
Runtime: &swarmapi.TaskSpec_Container{
Container: &swarmapi.ContainerSpec{
Image: "alpine:latest",
Isolation: c.from,
},
},
},
}
config := containerConfig{task: &task}
require.Equal(t, c.to, config.hostConfig().Isolation)
})
}
}

View File

@ -1,4 +1,4 @@
// +build !linux,!solaris
// +build !linux
package cluster

View File

@ -17,6 +17,8 @@ import (
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// nodeRunner implements a manager for continuously running swarmkit node, restarting them with backoff delays if needed.
@ -217,7 +219,10 @@ func (n *nodeRunner) watchClusterEvents(ctx context.Context, conn *grpc.ClientCo
msg, err := watch.Recv()
if err != nil {
// store watch is broken
logrus.WithError(err).Error("failed to receive changes from store watch API")
errStatus, ok := status.FromError(err)
if !ok || errStatus.Code() != codes.Canceled {
logrus.WithError(err).Error("failed to receive changes from store watch API")
}
return
}
select {

View File

@ -198,9 +198,9 @@ func (c *Cluster) Join(req types.JoinRequest) error {
// Inspect retrieves the configuration properties of a managed swarm cluster.
func (c *Cluster) Inspect() (types.Swarm, error) {
var swarm *swarmapi.Cluster
var swarm types.Swarm
if err := c.lockedManagerAction(func(ctx context.Context, state nodeState) error {
s, err := getSwarm(ctx, state.controlClient)
s, err := c.inspect(ctx, state)
if err != nil {
return err
}
@ -209,7 +209,15 @@ func (c *Cluster) Inspect() (types.Swarm, error) {
}); err != nil {
return types.Swarm{}, err
}
return convert.SwarmFromGRPC(*swarm), nil
return swarm, nil
}
func (c *Cluster) inspect(ctx context.Context, state nodeState) (types.Swarm, error) {
s, err := getSwarm(ctx, state.controlClient)
if err != nil {
return types.Swarm{}, err
}
return convert.SwarmFromGRPC(*s), nil
}
// Update updates configuration of a managed swarm cluster.
@ -413,7 +421,7 @@ func (c *Cluster) Info() types.Info {
if state.IsActiveManager() {
info.ControlAvailable = true
swarm, err := c.Inspect()
swarm, err := c.inspect(ctx, state)
if err != nil {
info.Error = err.Error()
}

View File

@ -171,7 +171,8 @@ type CommonConfig struct {
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"`
// e.g: ["orange=red", "orange=green", "orange=blue", "apple=3"]
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"`
@ -257,22 +258,12 @@ func Reload(configFile string, flags *pflag.FlagSet, reload func(*Config)) error
return fmt.Errorf("file configuration validation failed (%v)", err)
}
// Labels of the docker engine used to allow multiple values associated with the same key.
// This is deprecated in 1.13, and, be removed after 3 release cycles.
// The following will check the conflict of labels, and report a warning for deprecation.
//
// TODO: After 3 release cycles (17.12) an error will be returned, and labels will be
// sanitized to consolidate duplicate key-value pairs (config.Labels = newLabels):
//
// newLabels, err := GetConflictFreeLabels(newConfig.Labels)
// if err != nil {
// return err
// }
// newConfig.Labels = newLabels
//
if _, err := GetConflictFreeLabels(newConfig.Labels); err != nil {
logrus.Warnf("Engine labels with duplicate keys and conflicting values have been deprecated: %s", err)
// Check if duplicate label-keys with different values are found
newLabels, err := GetConflictFreeLabels(newConfig.Labels)
if err != nil {
return err
}
newConfig.Labels = newLabels
reload(newConfig)
return nil

View File

@ -1,4 +1,4 @@
// +build solaris linux freebsd
// +build linux freebsd
package config

View File

@ -9,6 +9,7 @@ import (
"github.com/docker/docker/daemon/discovery"
"github.com/docker/docker/internal/testutil"
"github.com/docker/docker/opts"
"github.com/gotestyourself/gotestyourself/fs"
"github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
)
@ -259,6 +260,20 @@ func TestValidateConfigurationErrors(t *testing.T) {
},
},
},
{
config: &Config{
CommonConfig: CommonConfig{
NodeGenericResources: []string{"foo"},
},
},
},
{
config: &Config{
CommonConfig: CommonConfig{
NodeGenericResources: []string{"foo=bar", "foo=1"},
},
},
},
}
for _, tc := range testCases {
err := Validate(tc.config)
@ -316,6 +331,20 @@ func TestValidateConfiguration(t *testing.T) {
},
},
},
{
config: &Config{
CommonConfig: CommonConfig{
NodeGenericResources: []string{"foo=bar", "foo=baz"},
},
},
},
{
config: &Config{
CommonConfig: CommonConfig{
NodeGenericResources: []string{"foo=1"},
},
},
},
}
for _, tc := range testCases {
err := Validate(tc.config)
@ -431,3 +460,29 @@ func TestReloadBadDefaultConfig(t *testing.T) {
assert.Error(t, err)
testutil.ErrorContains(t, err, "unable to configure the Docker daemon with file")
}
func TestReloadWithConflictingLabels(t *testing.T) {
tempFile := fs.NewFile(t, "config", fs.WithContent(`{"labels":["foo=bar","foo=baz"]}`))
defer tempFile.Remove()
configFile := tempFile.Path()
var lbls []string
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
flags.String("config-file", configFile, "")
flags.StringSlice("labels", lbls, "")
err := Reload(configFile, flags, func(c *Config) {})
testutil.ErrorContains(t, err, "conflict labels for foo=baz and foo=bar")
}
func TestReloadWithDuplicateLabels(t *testing.T) {
tempFile := fs.NewFile(t, "config", fs.WithContent(`{"labels":["foo=the-same","foo=the-same"]}`))
defer tempFile.Remove()
configFile := tempFile.Path()
var lbls []string
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
flags.String("config-file", configFile, "")
flags.StringSlice("labels", lbls, "")
err := Reload(configFile, flags, func(c *Config) {})
assert.NoError(t, err)
}

View File

@ -7,8 +7,8 @@ import (
)
// ParseGenericResources parses and validates the specified string as a list of GenericResource
func ParseGenericResources(value string) ([]swarm.GenericResource, error) {
if value == "" {
func ParseGenericResources(value []string) ([]swarm.GenericResource, error) {
if len(value) == 0 {
return nil, nil
}

View File

@ -329,6 +329,10 @@ func (daemon *Daemon) verifyContainerSettings(platform string, hostConfig *conta
return nil, errors.Errorf("invalid restart policy '%s'", p.Name)
}
if !hostConfig.Isolation.IsValid() {
return nil, errors.Errorf("invalid isolation '%s' on %s", hostConfig.Isolation, runtime.GOOS)
}
// Now do platform-specific verification
return verifyPlatformContainerSettings(daemon, hostConfig, config, update)
}

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