Merge component 'engine' from git@github.com:moby/moby master
This commit is contained in:
@ -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/).
|
||||
|
||||
[](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 Relay Chat (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:
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 \
|
||||
|
||||
@ -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 \
|
||||
|
||||
@ -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 \
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1 +0,0 @@
|
||||
17.06.0-dev
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -74,6 +74,7 @@ type ContainerLogsOptions struct {
|
||||
ShowStdout bool
|
||||
ShowStderr bool
|
||||
Since string
|
||||
Until string
|
||||
Timestamps bool
|
||||
Follow bool
|
||||
Tail string
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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"`
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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{}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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(©)
|
||||
}
|
||||
return ©
|
||||
}
|
||||
|
||||
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(©)
|
||||
}
|
||||
return ©
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// +build linux freebsd solaris openbsd darwin
|
||||
// +build linux freebsd openbsd darwin
|
||||
|
||||
package client
|
||||
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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{
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// +build solaris linux freebsd
|
||||
// +build linux freebsd
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// +build linux,!solaris freebsd,!solaris
|
||||
// +build linux freebsd
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// +build linux,!solaris freebsd,!solaris
|
||||
// +build linux freebsd
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// +build !windows,!solaris
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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 != "" {
|
||||
|
||||
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// +build !windows,!solaris
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
// +build !linux,!solaris
|
||||
// +build !linux
|
||||
|
||||
package cluster
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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()
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// +build solaris linux freebsd
|
||||
// +build linux freebsd
|
||||
|
||||
package config
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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
Reference in New Issue
Block a user