Merge component 'engine' from git@github.com:moby/moby master
This commit is contained in:
@ -20,14 +20,6 @@
|
||||
# # Run tests e.g. integration, py
|
||||
# # hack/make.sh binary test-integration test-docker-py
|
||||
#
|
||||
# # Publish a release:
|
||||
# docker run --privileged \
|
||||
# -e AWS_S3_BUCKET=baz \
|
||||
# -e AWS_ACCESS_KEY=foo \
|
||||
# -e AWS_SECRET_KEY=bar \
|
||||
# -e GPG_PASSPHRASE=gloubiboulga \
|
||||
# docker hack/release.sh
|
||||
#
|
||||
# Note: AppArmor used to mess with privileged mode, but this is no longer
|
||||
# the case. Therefore, you don't have to disable it anymore.
|
||||
#
|
||||
|
||||
@ -126,7 +126,11 @@ func (s *Server) makeHTTPHandler(handler httputils.APIFunc) http.HandlerFunc {
|
||||
// apply to all requests. Data that is specific to the
|
||||
// immediate function being called should still be passed
|
||||
// as 'args' on the function call.
|
||||
ctx := context.WithValue(context.Background(), dockerversion.UAStringKey, r.Header.Get("User-Agent"))
|
||||
|
||||
// use intermediate variable to prevent "should not use basic type
|
||||
// string as key in context.WithValue" golint errors
|
||||
var ki interface{} = dockerversion.UAStringKey
|
||||
ctx := context.WithValue(context.Background(), ki, r.Header.Get("User-Agent"))
|
||||
handlerFunc := s.handlerWithGlobalMiddlewares(handler)
|
||||
|
||||
vars := mux.Vars(r)
|
||||
|
||||
@ -3815,7 +3815,7 @@ definitions:
|
||||
- "process"
|
||||
InitBinary:
|
||||
description: |
|
||||
Name and, optional, path of the the `docker-init` binary.
|
||||
Name and, optional, path of the `docker-init` binary.
|
||||
|
||||
If the path is omitted, the daemon searches the host's `$PATH` for the
|
||||
binary and uses the first result.
|
||||
@ -4033,7 +4033,7 @@ definitions:
|
||||
- "https://registry-3.docker.io/"
|
||||
Secure:
|
||||
description: |
|
||||
Indicates if the the registry is part of the list of insecure
|
||||
Indicates if the registry is part of the list of insecure
|
||||
registries.
|
||||
|
||||
If `false`, the registry is insecure. Insecure registries accept
|
||||
|
||||
@ -11,14 +11,6 @@
|
||||
# # Run the test suite:
|
||||
# docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
|
||||
#
|
||||
# # Publish a release:
|
||||
# docker run --privileged \
|
||||
# -e AWS_S3_BUCKET=baz \
|
||||
# -e AWS_ACCESS_KEY=foo \
|
||||
# -e AWS_SECRET_KEY=bar \
|
||||
# -e GPG_PASSPHRASE=gloubiboulga \
|
||||
# docker hack/release.sh
|
||||
#
|
||||
# Note: AppArmor used to mess with privileged mode, but this is no longer
|
||||
# the case. Therefore, you don't have to disable it anymore.
|
||||
#
|
||||
|
||||
@ -615,7 +615,7 @@ func (s sortableCacheSources) Swap(i, j int) {
|
||||
}
|
||||
|
||||
func newTarsumHash(stat *fsutil.Stat) (hash.Hash, error) {
|
||||
fi := &fsutil.StatInfo{stat}
|
||||
fi := &fsutil.StatInfo{Stat: stat}
|
||||
p := stat.Path
|
||||
if fi.IsDir() {
|
||||
p += string(os.PathSeparator)
|
||||
|
||||
@ -17,7 +17,7 @@ func TestSwarmUnlockError(t *testing.T) {
|
||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
||||
}
|
||||
|
||||
err := client.SwarmUnlock(context.Background(), swarm.UnlockRequest{"SWMKEY-1-y6guTZNTwpQeTL5RhUfOsdBdXoQjiB2GADHSRJvbXeU"})
|
||||
err := client.SwarmUnlock(context.Background(), swarm.UnlockRequest{UnlockKey: "SWMKEY-1-y6guTZNTwpQeTL5RhUfOsdBdXoQjiB2GADHSRJvbXeU"})
|
||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
||||
t.Fatalf("expected a Server Error, got %v", err)
|
||||
}
|
||||
@ -41,7 +41,7 @@ func TestSwarmUnlock(t *testing.T) {
|
||||
}),
|
||||
}
|
||||
|
||||
err := client.SwarmUnlock(context.Background(), swarm.UnlockRequest{"SWMKEY-1-y6guTZNTwpQeTL5RhUfOsdBdXoQjiB2GADHSRJvbXeU"})
|
||||
err := client.SwarmUnlock(context.Background(), swarm.UnlockRequest{UnlockKey: "SWMKEY-1-y6guTZNTwpQeTL5RhUfOsdBdXoQjiB2GADHSRJvbXeU"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -107,10 +107,10 @@ func allocateDaemonPort(addr string) error {
|
||||
func wrapListeners(proto string, ls []net.Listener) []net.Listener {
|
||||
switch proto {
|
||||
case "unix":
|
||||
ls[0] = &hack.MalformedHostHeaderOverride{ls[0]}
|
||||
ls[0] = &hack.MalformedHostHeaderOverride{Listener: ls[0]}
|
||||
case "fd":
|
||||
for i := range ls {
|
||||
ls[i] = &hack.MalformedHostHeaderOverride{ls[i]}
|
||||
ls[i] = &hack.MalformedHostHeaderOverride{Listener: ls[i]}
|
||||
}
|
||||
}
|
||||
return ls
|
||||
|
||||
@ -20,7 +20,7 @@ import (
|
||||
|
||||
// Controller is the controller for the plugin backend.
|
||||
// Plugins are managed as a singleton object with a desired state (different from containers).
|
||||
// With the the plugin controller instead of having a strict create->start->stop->remove
|
||||
// With the plugin controller instead of having a strict create->start->stop->remove
|
||||
// task lifecycle like containers, we manage the desired state of the plugin and let
|
||||
// the plugin manager do what it already does and monitor the plugin.
|
||||
// We'll also end up with many tasks all pointing to the same plugin ID.
|
||||
|
||||
@ -168,7 +168,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
||||
return nil, err
|
||||
}
|
||||
// Create the driver home dir
|
||||
if err := idtools.MkdirAllAndChown(home, 0700, idtools.IDPair{rootUID, rootGID}); err != nil {
|
||||
if err := idtools.MkdirAllAndChown(home, 0700, idtools.IDPair{UID: rootUID, GID: rootGID}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -410,7 +410,7 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, err erro
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := idtools.MkdirAndChown(mergedDir, 0700, idtools.IDPair{rootUID, rootGID}); err != nil {
|
||||
if err := idtools.MkdirAndChown(mergedDir, 0700, idtools.IDPair{UID: rootUID, GID: rootGID}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var (
|
||||
|
||||
@ -200,7 +200,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
||||
return nil, err
|
||||
}
|
||||
// Create the driver home dir
|
||||
if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 0700, idtools.IDPair{rootUID, rootGID}); err != nil {
|
||||
if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 0700, idtools.IDPair{UID: rootUID, GID: rootGID}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -581,7 +581,7 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := idtools.MkdirAndChown(mergedDir, 0700, idtools.IDPair{rootUID, rootGID}); err != nil {
|
||||
if err := idtools.MkdirAndChown(mergedDir, 0700, idtools.IDPair{UID: rootUID, GID: rootGID}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@ -14,6 +14,11 @@ func ErrDTypeNotSupported(driver, backingFs string) error {
|
||||
if backingFs == "xfs" {
|
||||
msg += " Reformat the filesystem with ftype=1 to enable d_type support."
|
||||
}
|
||||
|
||||
if backingFs == "extfs" {
|
||||
msg += " Reformat the filesystem (or use tune2fs) with -O filetype flag to enable d_type support."
|
||||
}
|
||||
|
||||
msg += " Backing filesystems without d_type support are not supported."
|
||||
|
||||
return graphdriver.NotSupportedError(msg)
|
||||
|
||||
@ -106,7 +106,7 @@ func Init(base string, opt []string, uidMaps, gidMaps []idtools.IDMap) (graphdri
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to get root uid/guid: %v", err)
|
||||
}
|
||||
if err := idtools.MkdirAllAndChown(base, 0700, idtools.IDPair{rootUID, rootGID}); err != nil {
|
||||
if err := idtools.MkdirAllAndChown(base, 0700, idtools.IDPair{UID: rootUID, GID: rootGID}); err != nil {
|
||||
return nil, fmt.Errorf("Failed to create '%s': %v", base, err)
|
||||
}
|
||||
|
||||
@ -385,7 +385,7 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e
|
||||
return nil, err
|
||||
}
|
||||
// Create the target directories if they don't exist
|
||||
if err := idtools.MkdirAllAndChown(mountpoint, 0755, idtools.IDPair{rootUID, rootGID}); err != nil {
|
||||
if err := idtools.MkdirAllAndChown(mountpoint, 0755, idtools.IDPair{UID: rootUID, GID: rootGID}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ func (daemon *Daemon) setupMounts(c *container.Container) ([]container.Mount, er
|
||||
if err := daemon.lazyInitializeVolume(c.ID, mount); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s, err := mount.Setup(c.MountLabel, idtools.IDPair{0, 0}, nil)
|
||||
s, err := mount.Setup(c.MountLabel, idtools.IDPair{UID: 0, GID: 0}, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ func IsConflict(err error) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
// IsUnauthorized returns if the the passed in error is an ErrUnauthorized
|
||||
// IsUnauthorized returns if the passed in error is an ErrUnauthorized
|
||||
func IsUnauthorized(err error) bool {
|
||||
_, ok := getImplementer(err).(ErrUnauthorized)
|
||||
return ok
|
||||
|
||||
@ -49,11 +49,6 @@ An example referenced from [Run targets inside a development container](https://
|
||||
refer to
|
||||
[Run tests and test documentation](https://docs.docker.com/opensource/project/test-and-docs/)
|
||||
|
||||
## Release (release.sh)
|
||||
|
||||
Releases any bundles built by `make` on a public AWS S3 bucket.
|
||||
For information regarding configuration, please view `release.sh`.
|
||||
|
||||
## Vendor (vendor.sh)
|
||||
|
||||
A shell script that is a wrapper around Vndr. For information on how to use
|
||||
|
||||
@ -29,7 +29,7 @@ func TestDockerNetworkConnectAlias(t *testing.T) {
|
||||
|
||||
cID1 := container.Create(t, ctx, client, func(c *container.TestContainerConfig) {
|
||||
c.NetworkingConfig = &network.NetworkingConfig{
|
||||
map[string]*network.EndpointSettings{
|
||||
EndpointsConfig: map[string]*network.EndpointSettings{
|
||||
name: {},
|
||||
},
|
||||
}
|
||||
@ -52,7 +52,7 @@ func TestDockerNetworkConnectAlias(t *testing.T) {
|
||||
|
||||
cID2 := container.Create(t, ctx, client, func(c *container.TestContainerConfig) {
|
||||
c.NetworkingConfig = &network.NetworkingConfig{
|
||||
map[string]*network.EndpointSettings{
|
||||
EndpointsConfig: map[string]*network.EndpointSettings{
|
||||
name: {},
|
||||
},
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ func getSpecUser(ociSpec *specs.Spec) (int, int) {
|
||||
func prepareBundleDir(bundleDir string, ociSpec *specs.Spec) (string, error) {
|
||||
uid, gid := getSpecUser(ociSpec)
|
||||
if uid == 0 && gid == 0 {
|
||||
return bundleDir, idtools.MkdirAllAndChownNew(bundleDir, 0755, idtools.IDPair{0, 0})
|
||||
return bundleDir, idtools.MkdirAllAndChownNew(bundleDir, 0755, idtools.IDPair{UID: 0, GID: 0})
|
||||
}
|
||||
|
||||
p := string(filepath.Separator)
|
||||
@ -71,7 +71,7 @@ func prepareBundleDir(bundleDir string, ociSpec *specs.Spec) (string, error) {
|
||||
}
|
||||
if os.IsNotExist(err) || fi.Mode()&1 == 0 {
|
||||
p = fmt.Sprintf("%s.%d.%d", p, uid, gid)
|
||||
if err := idtools.MkdirAndChown(p, 0700, idtools.IDPair{uid, gid}); err != nil && !os.IsExist(err) {
|
||||
if err := idtools.MkdirAndChown(p, 0700, idtools.IDPair{UID: uid, GID: gid}); err != nil && !os.IsExist(err) {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,5 +73,5 @@ func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {
|
||||
|
||||
func getFileUIDGID(stat interface{}) (idtools.IDPair, error) {
|
||||
// no notion of file ownership mapping yet on Windows
|
||||
return idtools.IDPair{0, 0}, nil
|
||||
return idtools.IDPair{UID: 0, GID: 0}, nil
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ const (
|
||||
// Stderr represents standard error steam type.
|
||||
Stderr
|
||||
// Systemerr represents errors originating from the system that make it
|
||||
// into the the multiplexed stream.
|
||||
// into the multiplexed stream.
|
||||
Systemerr
|
||||
|
||||
stdWriterPrefixLen = 8
|
||||
|
||||
@ -53,7 +53,7 @@ func (pm *Manager) enable(p *v2.Plugin, c *controller, force bool) error {
|
||||
}
|
||||
|
||||
rootFS := containerfs.NewLocalContainerFS(filepath.Join(pm.config.Root, p.PluginObj.ID, rootFSFileName))
|
||||
if err := initlayer.Setup(rootFS, idtools.IDPair{0, 0}); err != nil {
|
||||
if err := initlayer.Setup(rootFS, idtools.IDPair{UID: 0, GID: 0}); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
|
||||
@ -257,7 +257,7 @@ func (p *Plugin) Release() {
|
||||
p.AddRefCount(plugingetter.Release)
|
||||
}
|
||||
|
||||
// SetSpecOptModifier sets the function to use to modify the the generated
|
||||
// SetSpecOptModifier sets the function to use to modify the generated
|
||||
// runtime spec.
|
||||
func (p *Plugin) SetSpecOptModifier(f func(*specs.Spec)) {
|
||||
p.mu.Lock()
|
||||
|
||||
@ -1,519 +0,0 @@
|
||||
# Release Checklist
|
||||
## A maintainer's guide to releasing Docker
|
||||
|
||||
So you're in charge of a Docker release? Cool. Here's what to do.
|
||||
|
||||
If your experience deviates from this document, please document the changes
|
||||
to keep it up-to-date.
|
||||
|
||||
It is important to note that this document assumes that the git remote in your
|
||||
repository that corresponds to "https://github.com/docker/docker" is named
|
||||
"origin". If yours is not (for example, if you've chosen to name it "upstream"
|
||||
or something similar instead), be sure to adjust the listed snippets for your
|
||||
local environment accordingly. If you are not sure what your upstream remote is
|
||||
named, use a command like `git remote -v` to find out.
|
||||
|
||||
If you don't have an upstream remote, you can add one easily using something
|
||||
like:
|
||||
|
||||
```bash
|
||||
export GITHUBUSER="YOUR_GITHUB_USER"
|
||||
git remote add origin https://github.com/docker/docker.git
|
||||
git remote add $GITHUBUSER git@github.com:$GITHUBUSER/docker.git
|
||||
```
|
||||
|
||||
### 1. Pull from master and create a release branch
|
||||
|
||||
All releases version numbers will be of the form: vX.Y.Z where X is the major
|
||||
version number, Y is the minor version number and Z is the patch release version number.
|
||||
|
||||
#### Major releases
|
||||
|
||||
The release branch name is just vX.Y because it's going to be the basis for all .Z releases.
|
||||
|
||||
```bash
|
||||
export BASE=vX.Y
|
||||
export VERSION=vX.Y.Z
|
||||
git fetch origin
|
||||
git checkout --track origin/master
|
||||
git checkout -b release/$BASE
|
||||
```
|
||||
|
||||
This new branch is going to be the base for the release. We need to push it to origin so we
|
||||
can track the cherry-picked changes and the version bump:
|
||||
|
||||
```bash
|
||||
git push origin release/$BASE
|
||||
```
|
||||
|
||||
When you have the major release branch in origin, we need to create the bump fork branch
|
||||
that we'll push to our fork:
|
||||
|
||||
```bash
|
||||
git checkout -b bump_$VERSION
|
||||
```
|
||||
|
||||
#### Patch releases
|
||||
|
||||
If we have the release branch in origin, we can create the forked bump branch from it directly:
|
||||
|
||||
```bash
|
||||
export VERSION=vX.Y.Z
|
||||
export PATCH=vX.Y.Z+1
|
||||
git fetch origin
|
||||
git checkout --track origin/release/$BASE
|
||||
git checkout -b bump_$PATCH
|
||||
```
|
||||
|
||||
We cherry-pick only the commits we want into the bump branch:
|
||||
|
||||
```bash
|
||||
# get the commits ids we want to cherry-pick
|
||||
git log
|
||||
# cherry-pick the commits starting from the oldest one, without including merge commits
|
||||
git cherry-pick -s -x <commit-id>
|
||||
git cherry-pick -s -x <commit-id>
|
||||
...
|
||||
```
|
||||
|
||||
### 2. Update the VERSION files and API version on master
|
||||
|
||||
We don't want to stop contributions to master just because we are releasing.
|
||||
So, after the release branch is up, we bump the VERSION and API version to mark
|
||||
the start of the "next" release.
|
||||
|
||||
#### 2.1 Update the VERSION files
|
||||
|
||||
Update the content of the `VERSION` file to be the next minor (incrementing Y)
|
||||
and add the `-dev` suffix. For example, after the release branch for 1.5.0 is
|
||||
created, the `VERSION` file gets updated to `1.6.0-dev` (as in "1.6.0 in the
|
||||
making").
|
||||
|
||||
#### 2.2 Update API version on master
|
||||
|
||||
We don't want API changes to go to the now frozen API version. Create a new
|
||||
entry in `docs/reference/api/` by copying the latest and bumping the version
|
||||
number (in both the file's name and content), and submit this in a PR against
|
||||
master.
|
||||
|
||||
### 3. Update CHANGELOG.md
|
||||
|
||||
You can run this command for reference with git 2.0:
|
||||
|
||||
```bash
|
||||
git fetch --tags
|
||||
LAST_VERSION=$(git tag -l --sort=-version:refname "v*" | grep -E 'v[0-9\.]+$' | head -1)
|
||||
git log --stat $LAST_VERSION..bump_$VERSION
|
||||
```
|
||||
|
||||
If you don't have git 2.0 but have a sort command that supports `-V`:
|
||||
```bash
|
||||
git fetch --tags
|
||||
LAST_VERSION=$(git tag -l | grep -E 'v[0-9\.]+$' | sort -rV | head -1)
|
||||
git log --stat $LAST_VERSION..bump_$VERSION
|
||||
```
|
||||
|
||||
If releasing a major version (X or Y increased in vX.Y.Z), simply listing notable user-facing features is sufficient.
|
||||
```markdown
|
||||
#### Notable features since <last major version>
|
||||
* New docker command to do something useful
|
||||
* Engine API change (deprecating old version)
|
||||
* Performance improvements in some usecases
|
||||
* ...
|
||||
```
|
||||
|
||||
For minor releases (only Z increases in vX.Y.Z), provide a list of user-facing changes.
|
||||
Each change should be listed under a category heading formatted as `#### CATEGORY`.
|
||||
|
||||
`CATEGORY` should describe which part of the project is affected.
|
||||
Valid categories are:
|
||||
* Builder
|
||||
* Documentation
|
||||
* Hack
|
||||
* Packaging
|
||||
* Engine API
|
||||
* Runtime
|
||||
* Other (please use this category sparingly)
|
||||
|
||||
Each change should be formatted as `BULLET DESCRIPTION`, given:
|
||||
|
||||
* BULLET: either `-`, `+` or `*`, to indicate a bugfix, new feature or
|
||||
upgrade, respectively.
|
||||
|
||||
* DESCRIPTION: a concise description of the change that is relevant to the
|
||||
end-user, using the present tense. Changes should be described in terms
|
||||
of how they affect the user, for example "Add new feature X which allows Y",
|
||||
"Fix bug which caused X", "Increase performance of Y".
|
||||
|
||||
EXAMPLES:
|
||||
|
||||
```markdown
|
||||
## 0.3.6 (1995-12-25)
|
||||
|
||||
#### Builder
|
||||
|
||||
+ 'docker build -t FOO .' applies the tag FOO to the newly built image
|
||||
|
||||
#### Engine API
|
||||
|
||||
- Fix a bug in the optional unix socket transport
|
||||
|
||||
#### Runtime
|
||||
|
||||
* Improve detection of kernel version
|
||||
```
|
||||
|
||||
If you need a list of contributors between the last major release and the
|
||||
current bump branch, use something like:
|
||||
```bash
|
||||
git log --format='%aN <%aE>' v0.7.0...bump_v0.8.0 | sort -uf
|
||||
```
|
||||
Obviously, you'll need to adjust version numbers as necessary. If you just need
|
||||
a count, add a simple `| wc -l`.
|
||||
|
||||
### 4. Change the contents of the VERSION file
|
||||
|
||||
Before the big thing, you'll want to make successive release candidates and get
|
||||
people to test. The release candidate number `N` should be part of the version:
|
||||
|
||||
```bash
|
||||
export RC_VERSION=${VERSION}-rcN
|
||||
echo ${RC_VERSION#v} > VERSION
|
||||
```
|
||||
|
||||
### 5. Test the docs
|
||||
|
||||
Make sure that your tree includes documentation for any modified or
|
||||
new features, syntax or semantic changes.
|
||||
|
||||
To test locally:
|
||||
|
||||
```bash
|
||||
make docs
|
||||
```
|
||||
|
||||
To make a shared test at https://beta-docs.docker.io:
|
||||
|
||||
(You will need the `awsconfig` file added to the `docs/` dir)
|
||||
|
||||
```bash
|
||||
make AWS_S3_BUCKET=beta-docs.docker.io BUILD_ROOT=yes docs-release
|
||||
```
|
||||
|
||||
### 6. Commit and create a pull request to the "release" branch
|
||||
|
||||
```bash
|
||||
git add VERSION CHANGELOG.md
|
||||
git commit -m "Bump version to $VERSION"
|
||||
git push $GITHUBUSER bump_$VERSION
|
||||
echo "https://github.com/$GITHUBUSER/docker/compare/docker:release/$BASE...$GITHUBUSER:bump_$VERSION?expand=1"
|
||||
```
|
||||
|
||||
That last command will give you the proper link to visit to ensure that you
|
||||
open the PR against the "release" branch instead of accidentally against
|
||||
"master" (like so many brave souls before you already have).
|
||||
|
||||
### 7. Create a PR to update the AUTHORS file for the release
|
||||
|
||||
Update the AUTHORS file, by running the `hack/generate-authors.sh` on the
|
||||
release branch. To prevent duplicate entries, you may need to update the
|
||||
`.mailmap` file accordingly.
|
||||
|
||||
### 8. Build release candidate rpms and debs
|
||||
|
||||
**NOTE**: It will be a lot faster if you pass a different graphdriver with
|
||||
`DOCKER_GRAPHDRIVER` than `vfs`.
|
||||
|
||||
```bash
|
||||
docker build -t docker .
|
||||
docker run \
|
||||
--rm -t --privileged \
|
||||
-e DOCKER_GRAPHDRIVER=aufs \
|
||||
-v $(pwd)/bundles:/go/src/github.com/docker/docker/bundles \
|
||||
docker \
|
||||
hack/make.sh binary build-deb build-rpm
|
||||
```
|
||||
|
||||
### 9. Publish release candidate rpms and debs
|
||||
|
||||
With the rpms and debs you built from the last step you can release them on the
|
||||
same server, or ideally, move them to a dedicated release box via scp into
|
||||
another docker/docker directory in bundles. This next step assumes you have
|
||||
a checkout of the docker source code at the same commit you used to build, with
|
||||
the artifacts from the last step in `bundles`.
|
||||
|
||||
**NOTE:** If you put a space before the command your `.bash_history` will not
|
||||
save it. (for the `GPG_PASSPHRASE`).
|
||||
|
||||
```bash
|
||||
docker build -t docker .
|
||||
docker run --rm -it --privileged \
|
||||
-v /volumes/repos:/volumes/repos \
|
||||
-v $(pwd)/bundles:/go/src/github.com/docker/docker/bundles \
|
||||
-v $HOME/.gnupg:/root/.gnupg \
|
||||
-e DOCKER_RELEASE_DIR=/volumes/repos \
|
||||
-e GPG_PASSPHRASE \
|
||||
-e KEEPBUNDLE=1 \
|
||||
docker \
|
||||
hack/make.sh release-deb release-rpm sign-repos generate-index-listing
|
||||
```
|
||||
|
||||
### 10. Upload the changed repos to wherever you host
|
||||
|
||||
For example, above we bind mounted `/volumes/repos` as the storage for
|
||||
`DOCKER_RELEASE_DIR`. In this case `/volumes/repos/apt` can be synced with
|
||||
a specific s3 bucket for the apt repo and `/volumes/repos/yum` can be synced with
|
||||
a s3 bucket for the yum repo.
|
||||
|
||||
### 11. Publish release candidate binaries
|
||||
|
||||
To run this you will need access to the release credentials. Get them from the
|
||||
Core maintainers.
|
||||
|
||||
```bash
|
||||
docker build -t docker .
|
||||
|
||||
# static binaries are still pushed to s3
|
||||
docker run \
|
||||
-e AWS_S3_BUCKET=test.docker.com \
|
||||
-e AWS_ACCESS_KEY_ID \
|
||||
-e AWS_SECRET_ACCESS_KEY \
|
||||
-e AWS_DEFAULT_REGION \
|
||||
-i -t --privileged \
|
||||
docker \
|
||||
hack/release.sh
|
||||
```
|
||||
|
||||
It will run the test suite, build the binaries and upload to the specified bucket,
|
||||
so this is a good time to verify that you're running against **test**.docker.com.
|
||||
|
||||
### 12. Purge the cache!
|
||||
|
||||
After the binaries are uploaded to test.docker.com and the packages are on
|
||||
apt.dockerproject.org and yum.dockerproject.org, make sure
|
||||
they get tested in both Ubuntu and Debian for any obvious installation
|
||||
issues or runtime issues.
|
||||
|
||||
If everything looks good, it's time to create a git tag for this candidate:
|
||||
|
||||
```bash
|
||||
git tag -a $RC_VERSION -m $RC_VERSION bump_$VERSION
|
||||
git push origin $RC_VERSION
|
||||
```
|
||||
|
||||
Announcing on multiple medias is the best way to get some help testing! An easy
|
||||
way to get some useful links for sharing:
|
||||
|
||||
```bash
|
||||
echo "Ubuntu/Debian: curl -sSL https://test.docker.com/ | sh"
|
||||
echo "Linux 64bit binary: https://test.docker.com/builds/Linux/x86_64/docker-${VERSION#v}"
|
||||
echo "Darwin/OSX 64bit client binary: https://test.docker.com/builds/Darwin/x86_64/docker-${VERSION#v}"
|
||||
echo "Linux 64bit tgz: https://test.docker.com/builds/Linux/x86_64/docker-${VERSION#v}.tgz"
|
||||
echo "Windows 64bit client binary: https://test.docker.com/builds/Windows/x86_64/docker-${VERSION#v}.exe"
|
||||
echo "Windows 32bit client binary: https://test.docker.com/builds/Windows/i386/docker-${VERSION#v}.exe"
|
||||
```
|
||||
### 13. Announce the release candidate
|
||||
|
||||
The release candidate should be announced on:
|
||||
|
||||
- IRC on #docker, #docker-dev, #docker-maintainers
|
||||
- In a comment on the pull request to notify subscribed people on GitHub
|
||||
- The [docker-dev](https://groups.google.com/forum/#!forum/docker-dev) group
|
||||
- The [docker-maintainers](https://groups.google.com/a/dockerproject.org/forum/#!forum/maintainers) group
|
||||
- (Optional) Any social media that can bring some attention to the release candidate
|
||||
|
||||
### 14. Iterate on successive release candidates
|
||||
|
||||
Spend several days along with the community explicitly investing time and
|
||||
resources to try and break Docker in every possible way, documenting any
|
||||
findings pertinent to the release. This time should be spent testing and
|
||||
finding ways in which the release might have caused various features or upgrade
|
||||
environments to have issues, not coding. During this time, the release is in
|
||||
code freeze, and any additional code changes will be pushed out to the next
|
||||
release.
|
||||
|
||||
It should include various levels of breaking Docker, beyond just using Docker
|
||||
by the book.
|
||||
|
||||
Any issues found may still remain issues for this release, but they should be
|
||||
documented and give appropriate warnings.
|
||||
|
||||
During this phase, the `bump_$VERSION` branch will keep evolving as you will
|
||||
produce new release candidates. The frequency of new candidates is up to the
|
||||
release manager: use your best judgement taking into account the severity of
|
||||
reported issues, testers availability, and time to scheduled release date.
|
||||
|
||||
Each time you'll want to produce a new release candidate, you will start by
|
||||
adding commits to the branch, usually by cherry-picking from master:
|
||||
|
||||
```bash
|
||||
git cherry-pick -s -x -m0 <commit_id>
|
||||
```
|
||||
|
||||
You want your "bump commit" (the one that updates the CHANGELOG and VERSION
|
||||
files) to remain on top, so you'll have to `git rebase -i` to bring it back up.
|
||||
|
||||
Now that your bump commit is back on top, you will need to update the CHANGELOG
|
||||
file (if appropriate for this particular release candidate), and update the
|
||||
VERSION file to increment the RC number:
|
||||
|
||||
```bash
|
||||
export RC_VERSION=$VERSION-rcN
|
||||
echo $RC_VERSION > VERSION
|
||||
```
|
||||
|
||||
You can now amend your last commit and update the bump branch:
|
||||
|
||||
```bash
|
||||
git commit --amend
|
||||
git push -f $GITHUBUSER bump_$VERSION
|
||||
```
|
||||
|
||||
Repeat steps 6 to 14 to tag the code, publish new binaries, announce availability, and
|
||||
get help testing.
|
||||
|
||||
### 15. Finalize the bump branch
|
||||
|
||||
When you're happy with the quality of a release candidate, you can move on and
|
||||
create the real thing.
|
||||
|
||||
You will first have to amend the "bump commit" to drop the release candidate
|
||||
suffix in the VERSION file:
|
||||
|
||||
```bash
|
||||
echo $VERSION > VERSION
|
||||
git add VERSION
|
||||
git commit --amend
|
||||
```
|
||||
|
||||
You will then repeat step 6 to publish the binaries to test
|
||||
|
||||
### 16. Get 2 other maintainers to validate the pull request
|
||||
|
||||
### 17. Build final rpms and debs
|
||||
|
||||
```bash
|
||||
docker build -t docker .
|
||||
docker run \
|
||||
--rm -t --privileged \
|
||||
-v $(pwd)/bundles:/go/src/github.com/docker/docker/bundles \
|
||||
docker \
|
||||
hack/make.sh binary build-deb build-rpm
|
||||
```
|
||||
|
||||
### 18. Publish final rpms and debs
|
||||
|
||||
With the rpms and debs you built from the last step you can release them on the
|
||||
same server, or ideally, move them to a dedicated release box via scp into
|
||||
another docker/docker directory in bundles. This next step assumes you have
|
||||
a checkout of the docker source code at the same commit you used to build, with
|
||||
the artifacts from the last step in `bundles`.
|
||||
|
||||
**NOTE:** If you put a space before the command your `.bash_history` will not
|
||||
save it. (for the `GPG_PASSPHRASE`).
|
||||
|
||||
```bash
|
||||
docker build -t docker .
|
||||
docker run --rm -it --privileged \
|
||||
-v /volumes/repos:/volumes/repos \
|
||||
-v $(pwd)/bundles:/go/src/github.com/docker/docker/bundles \
|
||||
-v $HOME/.gnupg:/root/.gnupg \
|
||||
-e DOCKER_RELEASE_DIR=/volumes/repos \
|
||||
-e GPG_PASSPHRASE \
|
||||
-e KEEPBUNDLE=1 \
|
||||
docker \
|
||||
hack/make.sh release-deb release-rpm sign-repos generate-index-listing
|
||||
```
|
||||
|
||||
### 19. Upload the changed repos to wherever you host
|
||||
|
||||
For example, above we bind mounted `/volumes/repos` as the storage for
|
||||
`DOCKER_RELEASE_DIR`. In this case `/volumes/repos/apt` can be synced with
|
||||
a specific s3 bucket for the apt repo and `/volumes/repos/yum` can be synced with
|
||||
a s3 bucket for the yum repo.
|
||||
|
||||
### 20. Publish final binaries
|
||||
|
||||
Once they're tested and reasonably believed to be working, run against
|
||||
get.docker.com:
|
||||
|
||||
```bash
|
||||
docker build -t docker .
|
||||
# static binaries are still pushed to s3
|
||||
docker run \
|
||||
-e AWS_S3_BUCKET=get.docker.com \
|
||||
-e AWS_ACCESS_KEY_ID \
|
||||
-e AWS_SECRET_ACCESS_KEY \
|
||||
-e AWS_DEFAULT_REGION \
|
||||
-i -t --privileged \
|
||||
docker \
|
||||
hack/release.sh
|
||||
```
|
||||
|
||||
### 21. Purge the cache!
|
||||
|
||||
### 22. Apply tag and create release
|
||||
|
||||
It's very important that we don't make the tag until after the official
|
||||
release is uploaded to get.docker.com!
|
||||
|
||||
```bash
|
||||
git tag -a $VERSION -m $VERSION bump_$VERSION
|
||||
git push origin $VERSION
|
||||
```
|
||||
|
||||
Once the tag is pushed, go to GitHub and create a [new release](https://github.com/docker/docker/releases/new).
|
||||
If the tag is for an RC make sure you check `This is a pre-release` at the bottom of the form.
|
||||
|
||||
Select the tag that you just pushed as the version and paste the changelog in the description of the release.
|
||||
You can see examples in this two links:
|
||||
|
||||
https://github.com/docker/docker/releases/tag/v1.8.0
|
||||
https://github.com/docker/docker/releases/tag/v1.8.0-rc3
|
||||
|
||||
### 23. Go to github to merge the `bump_$VERSION` branch into release
|
||||
|
||||
Don't forget to push that pretty blue button to delete the leftover
|
||||
branch afterwards!
|
||||
|
||||
### 24. Update the docs branch
|
||||
|
||||
You will need to point the docs branch to the newly created release tag:
|
||||
|
||||
```bash
|
||||
git checkout origin/docs
|
||||
git reset --hard origin/$VERSION
|
||||
git push -f origin docs
|
||||
```
|
||||
|
||||
The docs will appear on https://docs.docker.com/ (though there may be cached
|
||||
versions, so its worth checking http://docs.docker.com.s3-website-us-east-1.amazonaws.com/).
|
||||
For more information about documentation releases, see `docs/README.md`.
|
||||
|
||||
Note that the new docs will not appear live on the site until the cache (a complex,
|
||||
distributed CDN system) is flushed. The `make docs-release` command will do this
|
||||
_if_ the `DISTRIBUTION_ID` is set correctly - this will take at least 15 minutes to run
|
||||
and you can check its progress with the CDN Cloudfront Chrome addon.
|
||||
|
||||
### 25. Create a new pull request to merge your bump commit back into master
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
git fetch
|
||||
git reset --hard origin/master
|
||||
git cherry-pick -s -x $VERSION
|
||||
git push $GITHUBUSER merge_release_$VERSION
|
||||
echo "https://github.com/$GITHUBUSER/docker/compare/docker:master...$GITHUBUSER:merge_release_$VERSION?expand=1"
|
||||
```
|
||||
|
||||
Again, get two maintainers to validate, then merge, then push that pretty
|
||||
blue button to delete your branch.
|
||||
|
||||
### 26. Rejoice and Evangelize!
|
||||
|
||||
Congratulations! You're done.
|
||||
|
||||
Go forth and announce the glad tidings of the new release in `#docker`,
|
||||
`#docker-dev`, on the [dev mailing list](https://groups.google.com/forum/#!forum/docker-dev),
|
||||
the [announce mailing list](https://groups.google.com/forum/#!forum/docker-announce),
|
||||
and on Twitter!
|
||||
@ -211,7 +211,7 @@ func (r *Root) Remove(v volume.Volume) error {
|
||||
}
|
||||
|
||||
if !r.scopedPath(realPath) {
|
||||
return errdefs.System(errors.Errorf("Unable to remove a directory of out the Docker root %s: %s", r.scope, realPath))
|
||||
return errdefs.System(errors.Errorf("Unable to remove a directory outside of the local volume root %s: %s", r.scope, realPath))
|
||||
}
|
||||
|
||||
if err := removePath(realPath); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user