From be56a4fe892367aa2a047df27363a6e3854fd93a Mon Sep 17 00:00:00 2001 From: dogsheng <960055655@qq.com> Date: Wed, 25 Dec 2019 19:10:46 +0800 Subject: [PATCH] Package init --- patch/0128-docker-fix-CVE-2019-13509.patch | 84 +++++++++ ...dd-validation-for-ref-CVE-2019-13139.patch | 92 ++++++++++ ...Handle-blocked-I-O-of-exec-d-process.patch | 148 ++++++++++++++++ ...1-docker-fix-mount-loop-on-docker-cp.patch | 138 +++++++++++++++ ...p-when-container-source-path-is-root.patch | 41 +++++ ...x-updateUnpauseStats-wrong-path-erro.patch | 34 ++++ patch/0142-docker-fix-fd-leak-on-reboot.patch | 164 ++++++++++++++++++ ...t-on-unhealthy-flag-for-health-check.patch | 40 +++++ ...x-testcase-TestAttachClosedOnContain.patch | 31 ++++ ...-hot-upgrade-support-default-runtime.patch | 55 ++++++ ...er-hot-upgrade-support-accel-plugins.patch | 123 +++++++++++++ ...t-upgrade-treat-empty-storage-opt-as.patch | 33 ++++ ...ocker-ignore-warning-for-docker-info.patch | 34 ++++ ...eck-running-containers-before-del-db.patch | 33 ++++ ...ocker-fix-set-read-deadline-not-work.patch | 75 ++++++++ ...tting-env-variable-to-disable-db-del.patch | 31 ++++ ...ble-disable-legacy-registry-function.patch | 53 ++++++ series.conf | 18 +- 18 files changed, 1226 insertions(+), 1 deletion(-) create mode 100644 patch/0128-docker-fix-CVE-2019-13509.patch create mode 100644 patch/0129-docker-add-validation-for-ref-CVE-2019-13139.patch create mode 100644 patch/0130-docker-Handle-blocked-I-O-of-exec-d-process.patch create mode 100644 patch/0131-docker-fix-mount-loop-on-docker-cp.patch create mode 100644 patch/0132-docker-fix-docker-cp-when-container-source-path-is-root.patch create mode 100644 patch/0141-docker-fix-updateUnpauseStats-wrong-path-erro.patch create mode 100644 patch/0142-docker-fix-fd-leak-on-reboot.patch create mode 100644 patch/0143-docker-add-exit-on-unhealthy-flag-for-health-check.patch create mode 100644 patch/0144-docker-fix-testcase-TestAttachClosedOnContain.patch create mode 100644 patch/0145-docker-hot-upgrade-support-default-runtime.patch create mode 100644 patch/0146-docker-hot-upgrade-support-accel-plugins.patch create mode 100644 patch/0147-docker-hot-upgrade-treat-empty-storage-opt-as.patch create mode 100644 patch/0148-docker-ignore-warning-for-docker-info.patch create mode 100644 patch/0149-docker-check-running-containers-before-del-db.patch create mode 100644 patch/0150-docker-fix-set-read-deadline-not-work.patch create mode 100644 patch/0151-docker-enable-setting-env-variable-to-disable-db-del.patch create mode 100644 patch/0152-docker-Enable-disable-legacy-registry-function.patch diff --git a/patch/0128-docker-fix-CVE-2019-13509.patch b/patch/0128-docker-fix-CVE-2019-13509.patch new file mode 100644 index 0000000..23c8513 --- /dev/null +++ b/patch/0128-docker-fix-CVE-2019-13509.patch @@ -0,0 +1,84 @@ +From 0593b8b0e4279cf015140229795a09df6e3ca8f1 Mon Sep 17 00:00:00 2001 +From: jingrui +Date: Mon, 12 Aug 2019 19:13:00 +0800 +Subject: [PATCH] docker: [backport] fix CVE-2019-13509 + +ref: +https://github.com/moby/moby/commit/e4b9edd31fdba3adf1e39fb9874f73d391f0ff34 + +Commit 77b8465d7e68ca102d7aae839c7b3fe0ecd28398 added a secret update +endpoint to allow updating labels on existing secrets. However, when +implementing the endpoint, the DebugRequestMiddleware was not updated +to scrub the Data field (as is being done when creating a secret). + +When updating a secret (to set labels), the Data field should be either +`nil` (not set), or contain the same value as the existing secret. In +situations where the Data field is set, and the `dockerd` daemon is +running with debugging enabled / log-level debug, the base64-encoded +value of the secret is printed to the daemon logs. + +The docker cli does not have a `docker secret update` command, but +when using `docker stack deploy`, the docker cli sends the secret +data both when _creating_ a stack, and when _updating_ a stack, thus +leaking the secret data if the daemon runs with debug enabled: +... + +Signed-off-by: Sebastiaan van Stijn +(cherry picked from commit c7ce4be93ae8edd2da62a588e01c67313a4aba0c) +Signed-off-by: Tibor Vass +(cherry picked from commit 73db8c77bfb2d0cbdf71ce491f3d3e66c9dd5be6) +Signed-off-by: Sebastiaan van Stijn +Upstream-commit: 32b40c53662e733b4627b0b303c71b52484a31f4 + +Change-Id: If571264d227f41cbdcf7dceaa56d7b10ec2a3ee7 +Signed-off-by: jingrui +--- + .../engine/api/server/middleware/debug.go | 24 +++++++++++-------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +diff --git a/components/engine/api/server/middleware/debug.go b/components/engine/api/server/middleware/debug.go +index 2cef1d46c3..31165bf918 100644 +--- a/components/engine/api/server/middleware/debug.go ++++ b/components/engine/api/server/middleware/debug.go +@@ -71,9 +71,22 @@ func maskSecretKeys(inp interface{}, path string) { + } + + if form, ok := inp.(map[string]interface{}); ok { ++ scrub := []string{ ++ // Note: The Data field contains the base64-encoded secret in 'secret' ++ // and 'config' create and update requests. Currently, no other POST ++ // API endpoints use a data field, so we scrub this field unconditionally. ++ // Change this handling to be conditional if a new endpoint is added ++ // in future where this field should not be scrubbed. ++ "data", ++ "jointoken", ++ "password", ++ "secret", ++ "signingcakey", ++ "unlockkey", ++ } + loop0: + for k, v := range form { +- for _, m := range []string{"password", "secret", "jointoken", "unlockkey", "signingcakey"} { ++ for _, m := range scrub { + if strings.EqualFold(m, k) { + form[k] = "*****" + continue loop0 +@@ -81,14 +94,5 @@ func maskSecretKeys(inp interface{}, path string) { + } + maskSecretKeys(v, path) + } +- +- // Route-specific redactions +- if strings.HasSuffix(path, "/secrets/create") { +- for k := range form { +- if k == "Data" { +- form[k] = "*****" +- } +- } +- } + } + } +-- +2.17.1 + diff --git a/patch/0129-docker-add-validation-for-ref-CVE-2019-13139.patch b/patch/0129-docker-add-validation-for-ref-CVE-2019-13139.patch new file mode 100644 index 0000000..a8ad5f6 --- /dev/null +++ b/patch/0129-docker-add-validation-for-ref-CVE-2019-13139.patch @@ -0,0 +1,92 @@ +From b4361679c96219e6f1805cd802ba47a9c9f86f4d Mon Sep 17 00:00:00 2001 +From: build +Date: Mon, 9 Sep 2019 03:13:51 -0400 +Subject: [PATCH] docker: add validation for ref (CVE-2019-13139) + +reason: add validation for ref (CVE-2019-13139) + +Reference from https://github.com/moby/moby/pull/38944 + +Signed-off-by: Tonis Tiigi +Cherry-pick from commit 723b107ca4fba14580a6cd971e63d8af2e7d2bbe +Signed-off-by: Andrew Hsu +--- + .../builder/remotecontext/git/gitutils.go | 6 +++++- + .../remotecontext/git/gitutils_test.go | 21 ++++++++++++++++--- + 2 files changed, 23 insertions(+), 4 deletions(-) + +diff --git a/components/engine/builder/remotecontext/git/gitutils.go b/components/engine/builder/remotecontext/git/gitutils.go +index 77a45be..a907915 100644 +--- a/components/engine/builder/remotecontext/git/gitutils.go ++++ b/components/engine/builder/remotecontext/git/gitutils.go +@@ -102,6 +102,10 @@ func parseRemoteURL(remoteURL string) (gitRepo, error) { + u.Fragment = "" + repo.remote = u.String() + } ++ ++ if strings.HasPrefix(repo.ref, "-") { ++ return gitRepo{}, errors.Errorf("invalid refspec: %s", repo.ref) ++ } + return repo, nil + } + +@@ -124,7 +128,7 @@ func fetchArgs(remoteURL string, ref string) []string { + args = append(args, "--depth", "1") + } + +- return append(args, "origin", ref) ++ return append(args, "origin", "--", ref) + } + + // Check if a given git URL supports a shallow git clone, +diff --git a/components/engine/builder/remotecontext/git/gitutils_test.go b/components/engine/builder/remotecontext/git/gitutils_test.go +index 8c39679..34dd495 100644 +--- a/components/engine/builder/remotecontext/git/gitutils_test.go ++++ b/components/engine/builder/remotecontext/git/gitutils_test.go +@@ -59,7 +59,7 @@ func TestCloneArgsSmartHttp(t *testing.T) { + }) + + args := fetchArgs(serverURL.String(), "master") +- exp := []string{"fetch", "--depth", "1", "origin", "master"} ++ exp := []string{"fetch", "--depth", "1", "origin", "--", "master"} + assert.Check(t, is.DeepEqual(exp, args)) + } + +@@ -75,13 +75,13 @@ func TestCloneArgsDumbHttp(t *testing.T) { + }) + + args := fetchArgs(serverURL.String(), "master") +- exp := []string{"fetch", "origin", "master"} ++ exp := []string{"fetch", "origin", "--", "master"} + assert.Check(t, is.DeepEqual(exp, args)) + } + + func TestCloneArgsGit(t *testing.T) { + args := fetchArgs("git://github.com/docker/docker", "master") +- exp := []string{"fetch", "--depth", "1", "origin", "master"} ++ exp := []string{"fetch", "--depth", "1", "origin", "--", "master"} + assert.Check(t, is.DeepEqual(exp, args)) + } + +@@ -276,3 +276,18 @@ func TestValidGitTransport(t *testing.T) { + } + } + } ++ ++func TestGitInvalidRef(t *testing.T) { ++ gitUrls := []string{ ++ "git://github.com/moby/moby#--foo bar", ++ "git@github.com/moby/moby#--upload-pack=sleep;:", ++ "git@g.com:a/b.git#-B", ++ "git@g.com:a/b.git#with space", ++ } ++ ++ for _, url := range gitUrls { ++ _, err := Clone(url) ++ assert.Assert(t, err != nil) ++ assert.Check(t, is.Contains(strings.ToLower(err.Error()), "invalid refspec")) ++ } ++} +-- +2.20.1 + diff --git a/patch/0130-docker-Handle-blocked-I-O-of-exec-d-process.patch b/patch/0130-docker-Handle-blocked-I-O-of-exec-d-process.patch new file mode 100644 index 0000000..6bec743 --- /dev/null +++ b/patch/0130-docker-Handle-blocked-I-O-of-exec-d-process.patch @@ -0,0 +1,148 @@ +From cd5b236a64426aa7059795afc102110a866df8f0 Mon Sep 17 00:00:00 2001 +From: xiadanni1 +Date: Tue, 5 Nov 2019 03:52:02 +0800 +Subject: [PATCH] docker: [backport] Handle blocked I/O of exec'd processes + +reason: help process delete not block forever when the process exists but the I/O was +inherited by a subprocess that lives on. + +Cherry-pick from upstream https://github.com/moby/moby/pull/39383 + +Change-Id: Ibf8afe3fbfb068a6308565ec1059fc9ef5d6d2e2 +Signed-off-by: xiadanni1 +--- + components/engine/container/container.go | 2 +- + components/engine/container/stream/streams.go | 29 ++++++++++++++++++++++++--- + components/engine/daemon/exec/exec.go | 3 ++- + components/engine/daemon/monitor.go | 6 ++++-- + 4 files changed, 33 insertions(+), 7 deletions(-) + +diff --git a/components/engine/container/container.go b/components/engine/container/container.go +index c194220..81119a0 100644 +--- a/components/engine/container/container.go ++++ b/components/engine/container/container.go +@@ -754,7 +754,7 @@ func (i *rio) Close() error { + } + + func (i *rio) Wait() { +- i.sc.Wait() ++ i.sc.Wait(context.Background()) + + i.IO.Wait() + } +diff --git a/components/engine/container/stream/streams.go b/components/engine/container/stream/streams.go +index d81867c..585f9e8 100644 +--- a/components/engine/container/stream/streams.go ++++ b/components/engine/container/stream/streams.go +@@ -1,6 +1,7 @@ + package stream // import "github.com/docker/docker/container/stream" + + import ( ++ "context" + "fmt" + "io" + "io/ioutil" +@@ -24,11 +25,12 @@ import ( + // copied and delivered to all StdoutPipe and StderrPipe consumers, using + // a kind of "broadcaster". + type Config struct { +- sync.WaitGroup ++ wg sync.WaitGroup + stdout *broadcaster.Unbuffered + stderr *broadcaster.Unbuffered + stdin io.ReadCloser + stdinPipe io.WriteCloser ++ dio *cio.DirectIO + } + + // NewConfig creates a stream config and initializes +@@ -115,14 +117,15 @@ func (c *Config) CloseStreams() error { + + // CopyToPipe connects streamconfig with a libcontainerd.IOPipe + func (c *Config) CopyToPipe(iop *cio.DirectIO) { ++ c.dio = iop + copyFunc := func(w io.Writer, r io.ReadCloser) { +- c.Add(1) ++ c.wg.Add(1) + go func() { + if _, err := pools.Copy(w, r); err != nil { + logrus.Errorf("stream copy error: %v", err) + } + r.Close() +- c.Done() ++ c.wg.Done() + }() + } + +@@ -144,3 +147,23 @@ func (c *Config) CopyToPipe(iop *cio.DirectIO) { + } + } + } ++ ++// Wait for the stream to close ++// Wait supports timeouts via the context to unblock and forcefully ++// close the io streams ++func (c *Config) Wait(ctx context.Context) { ++ done := make(chan struct{}, 1) ++ go func() { ++ c.wg.Wait() ++ close(done) ++ }() ++ select { ++ case <-done: ++ case <-ctx.Done(): ++ if c.dio != nil { ++ c.dio.Cancel() ++ c.dio.Wait() ++ c.dio.Close() ++ } ++ } ++} +diff --git a/components/engine/daemon/exec/exec.go b/components/engine/daemon/exec/exec.go +index c036c46..08fc87c 100644 +--- a/components/engine/daemon/exec/exec.go ++++ b/components/engine/daemon/exec/exec.go +@@ -1,6 +1,7 @@ + package exec // import "github.com/docker/docker/daemon/exec" + + import ( ++ "context" + "runtime" + "sync" + +@@ -58,7 +59,7 @@ func (i *rio) Close() error { + } + + func (i *rio) Wait() { +- i.sc.Wait() ++ i.sc.Wait(context.Background()) + + i.IO.Wait() + } +diff --git a/components/engine/daemon/monitor.go b/components/engine/daemon/monitor.go +index 7ae85f5..e041bd5 100644 +--- a/components/engine/daemon/monitor.go ++++ b/components/engine/daemon/monitor.go +@@ -56,7 +56,8 @@ func (daemon *Daemon) ProcessEvent(id string, e libcontainerd.EventType, ei libc + logrus.WithError(err).Warnf("failed to delete container %s from containerd", c.ID) + } + +- c.StreamConfig.Wait() ++ ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) ++ c.StreamConfig.Wait(ctx) + c.Reset(false) + + exitStatus := container.ExitStatus{ +@@ -121,7 +122,8 @@ func (daemon *Daemon) ProcessEvent(id string, e libcontainerd.EventType, ei libc + defer execConfig.Unlock() + execConfig.ExitCode = &ec + execConfig.Running = false +- execConfig.StreamConfig.Wait() ++ ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) ++ execConfig.StreamConfig.Wait(ctx) + if err := execConfig.CloseStreams(); err != nil { + logrus.Errorf("failed to cleanup exec %s streams: %s", c.ID, err) + } +-- +1.8.3.1 + diff --git a/patch/0131-docker-fix-mount-loop-on-docker-cp.patch b/patch/0131-docker-fix-mount-loop-on-docker-cp.patch new file mode 100644 index 0000000..1631a14 --- /dev/null +++ b/patch/0131-docker-fix-mount-loop-on-docker-cp.patch @@ -0,0 +1,138 @@ +From cdcaf9f39ebde63ed3fce4d062224e4198589368 Mon Sep 17 00:00:00 2001 +From: liuzekun +Date: Mon, 9 Dec 2019 04:02:10 -0500 +Subject: [PATCH] docker: fix mount loop on "docker cp" + +reason: fix mount loop on "docker cp" +Cherry-pick from upstream: https://github.com/moby/moby/pull/38993 +--- + components/engine/container/container_unix.go | 9 ++++++++- + components/engine/daemon/archive.go | 15 +++++++++++++-- + components/engine/daemon/volumes_unix.go | 9 +++++++++ + components/engine/pkg/mount/mount.go | 5 +++++ + 4 files changed, 35 insertions(+), 3 deletions(-) + +diff --git a/components/engine/container/container_unix.go b/components/engine/container/container_unix.go +index 5a21b8c..43dd759 100644 +--- a/components/engine/container/container_unix.go ++++ b/components/engine/container/container_unix.go +@@ -385,7 +385,14 @@ func (container *Container) DetachAndUnmount(volumeEventLog func(name, action st + logrus.Warnf("%s unmountVolumes: Failed to do lazy umount fo volume '%s': %v", container.ID, mountPath, err) + } + } +- return container.UnmountVolumes(volumeEventLog) ++ err := container.UnmountVolumes(volumeEventLog) ++ // (daemon *).mountVolumes() calls mount.MakeMountAndRUnbindable() for ++ // container root, which results in an extra bind mount, unmount it. ++ if root, err := container.GetResourcePath(""); err == nil { ++ mount.Unmount(root) ++ } ++ ++ return err + } + + // copyExistingContents copies from the source to the destination and +diff --git a/components/engine/daemon/archive.go b/components/engine/daemon/archive.go +index 0053e53..0bac763 100644 +--- a/components/engine/daemon/archive.go ++++ b/components/engine/daemon/archive.go +@@ -12,6 +12,7 @@ import ( + "github.com/docker/docker/pkg/archive" + "github.com/docker/docker/pkg/chrootarchive" + "github.com/docker/docker/pkg/ioutils" ++ "github.com/docker/docker/pkg/mount" + "github.com/docker/docker/pkg/system" + "github.com/pkg/errors" + ) +@@ -172,6 +173,9 @@ func (daemon *Daemon) containerStatPath(container *container.Container, path str + defer daemon.Unmount(container) + + err = daemon.mountVolumes(container) ++ if err == mount.ErrMountAndRUnbindFailed { ++ return nil, err ++ } + defer container.DetachAndUnmount(daemon.LogVolumeEvent) + if err != nil { + return nil, err +@@ -208,9 +212,11 @@ func (daemon *Daemon) containerArchivePath(container *container.Container, path + } + + defer func() { +- if err != nil { ++ if err != nil && err != mount.ErrMountAndRUnbindFailed { + // unmount any volumes + container.DetachAndUnmount(daemon.LogVolumeEvent) ++ } ++ if err != nil { + // unmount the container's rootfs + daemon.Unmount(container) + } +@@ -286,6 +292,9 @@ func (daemon *Daemon) containerExtractToDir(container *container.Container, path + defer daemon.Unmount(container) + + err = daemon.mountVolumes(container) ++ if err == mount.ErrMountAndRUnbindFailed { ++ return err ++ } + defer container.DetachAndUnmount(daemon.LogVolumeEvent) + if err != nil { + return err +@@ -410,9 +419,11 @@ func (daemon *Daemon) containerCopy(container *container.Container, resource str + } + + defer func() { +- if err != nil { ++ if err != nil && err != mount.ErrMountAndRUnbindFailed { + // unmount any volumes + container.DetachAndUnmount(daemon.LogVolumeEvent) ++ } ++ if err != nil { + // unmount the container's rootfs + daemon.Unmount(container) + } +diff --git a/components/engine/daemon/volumes_unix.go b/components/engine/daemon/volumes_unix.go +index 5ddb926..e9a6d37 100644 +--- a/components/engine/daemon/volumes_unix.go ++++ b/components/engine/daemon/volumes_unix.go +@@ -109,6 +109,15 @@ func setBindModeIfNull(bind *volumemounts.MountPoint) { + } + + func (daemon *Daemon) mountVolumes(container *container.Container) error { ++ if root, err := container.GetResourcePath(""); err == nil { ++ err = mount.ForceMount(root, root, "none", "bind") ++ if err != nil { ++ return mount.ErrMountAndRUnbindFailed ++ } else { ++ mount.ForceMount("", root, "none", "runbindable") ++ } ++ } ++ + mounts, err := daemon.setupMounts(container) + if err != nil { + return err +diff --git a/components/engine/pkg/mount/mount.go b/components/engine/pkg/mount/mount.go +index 874aff6..a784e0d 100644 +--- a/components/engine/pkg/mount/mount.go ++++ b/components/engine/pkg/mount/mount.go +@@ -1,6 +1,7 @@ + package mount // import "github.com/docker/docker/pkg/mount" + + import ( ++ "errors" + "sort" + "strings" + "syscall" +@@ -8,6 +9,10 @@ import ( + "github.com/sirupsen/logrus" + ) + ++var ( ++ ErrMountAndRUnbindFailed = errors.New("make mount and runbind failed") ++) ++ + // FilterFunc is a type defining a callback function + // to filter out unwanted entries. It takes a pointer + // to an Info struct (not fully populated, currently +-- +2.20.1 + diff --git a/patch/0132-docker-fix-docker-cp-when-container-source-path-is-root.patch b/patch/0132-docker-fix-docker-cp-when-container-source-path-is-root.patch new file mode 100644 index 0000000..7a51ce3 --- /dev/null +++ b/patch/0132-docker-fix-docker-cp-when-container-source-path-is-root.patch @@ -0,0 +1,41 @@ +From 10fedb9c9814c584ceabfd966fa9cdbeb98ba587 Mon Sep 17 00:00:00 2001 +From: liuzekun +Date: Tue, 10 Dec 2019 03:44:18 -0500 +Subject: [PATCH] docker: fix docker cp when container source path is / + +reason: fix docker cp when container source path is / +Cherry-pick from upstream: https://github.com/moby/moby/pull/39357 +--- + components/engine/daemon/archive.go | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/components/engine/daemon/archive.go b/components/engine/daemon/archive.go +index 0bac763..f9c6fc7 100644 +--- a/components/engine/daemon/archive.go ++++ b/components/engine/daemon/archive.go +@@ -255,7 +255,11 @@ func (daemon *Daemon) containerArchivePath(container *container.Container, path + if driver.Base(resolvedPath) == "." { + resolvedPath += string(driver.Separator()) + "." + } +- sourceDir, sourceBase := driver.Dir(resolvedPath), driver.Base(resolvedPath) ++ sourceDir := resolvedPath ++ sourceBase := "." ++ if stat.Mode&os.ModeDir == 0 { // not dir ++ sourceDir, sourceBase = driver.Split(resolvedPath) ++ } + opts := archive.TarResourceRebaseOpts(sourceBase, driver.Base(absPath)) + + data, err := archivePath(driver, sourceDir, opts, container.BaseFS.Path()) +@@ -450,9 +454,6 @@ func (daemon *Daemon) containerCopy(container *container.Container, resource str + d, f := driver.Split(basePath) + basePath = d + filter = []string{f} +- } else { +- filter = []string{driver.Base(basePath)} +- basePath = driver.Dir(basePath) + } + archive, err := archivePath(driver, basePath, &archive.TarOptions{ + Compression: archive.Uncompressed, +-- +2.20.1 + diff --git a/patch/0141-docker-fix-updateUnpauseStats-wrong-path-erro.patch b/patch/0141-docker-fix-updateUnpauseStats-wrong-path-erro.patch new file mode 100644 index 0000000..3618b6e --- /dev/null +++ b/patch/0141-docker-fix-updateUnpauseStats-wrong-path-erro.patch @@ -0,0 +1,34 @@ +From d9b610a415b59f330ca151009434fa83e59cc5e5 Mon Sep 17 00:00:00 2001 +From: lixiang172 +Date: Mon, 12 Aug 2019 09:35:56 +0800 +Subject: [PATCH] docker: fix updateUnpauseStats wrong path error + +reason: The container stats path has changed but the updatePauseStatus +still use old path, so we need to update it in case the error occur + +Change-Id: I309ae2e351eb3b945a23b85841029770b7855da4 +--- + components/engine/daemon/daemon.go | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go +index 6c5eafd..01351cc 100644 +--- a/components/engine/daemon/daemon.go ++++ b/components/engine/daemon/daemon.go +@@ -209,7 +209,12 @@ func (daemon *Daemon) updatePauseStatus(c *container.Container) error { + // update docker pause status. + // for old container, CgroupParent may be empty. + if c.CgroupParent == "" { +- spec, err := libcontainerd.LoadContainerSpec(filepath.Join(daemon.configStore.ExecRoot, "libcontainerd"), c.ID) ++ // for container just be created, the moby path is empty, so just return nil ++ if c.State.StateString() == "created" { ++ return nil ++ } ++ mobyPath := "containerd/daemon/io.containerd.runtime.v1.linux/moby" ++ spec, err := libcontainerd.LoadContainerSpec(filepath.Join(daemon.configStore.ExecRoot, mobyPath), c.ID) + if err != nil { + return err + } +-- +1.8.3.1 + diff --git a/patch/0142-docker-fix-fd-leak-on-reboot.patch b/patch/0142-docker-fix-fd-leak-on-reboot.patch new file mode 100644 index 0000000..95ddaef --- /dev/null +++ b/patch/0142-docker-fix-fd-leak-on-reboot.patch @@ -0,0 +1,164 @@ +From 7a175514804e423257225a33fd7788ddd621e567 Mon Sep 17 00:00:00 2001 +From: jingrui +Date: Tue, 3 Sep 2019 16:10:19 +0800 +Subject: [PATCH] docker: fix fd leak on reboot + +The original db cleanup is too late, because docker has opened the db +files. Move it to dockerd start entry. + +Change-Id: I462c6b2fe44a0447fd5cc111f25b2e26b7488dc2 +Signed-off-by: jingrui +--- + components/engine/cmd/dockerd/daemon.go | 35 ++++++++++++- + components/engine/daemon/daemon.go | 68 ------------------------- + 2 files changed, 34 insertions(+), 69 deletions(-) + +diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go +index 78cd41ac59..1981175a4a 100644 +--- a/components/engine/cmd/dockerd/daemon.go ++++ b/components/engine/cmd/dockerd/daemon.go +@@ -4,6 +4,7 @@ import ( + "context" + "crypto/tls" + "fmt" ++ "io/ioutil" + "os" + "path/filepath" + "runtime" +@@ -71,6 +72,38 @@ func NewDaemonCli() *DaemonCli { + return &DaemonCli{} + } + ++func cleanupLocalDB(db string) { ++ _, err := os.Stat(db) ++ if err == nil { ++ err = os.Remove(db) ++ logrus.Infof("cleanup DB %s error=%v", db, err) ++ } ++} ++ ++// DB files may corrupted on exception poweroff but can be rebuild at run time, ++// so we can remove DB files on OS starts avoid daemon can not startup. ++func cleanupLocalDBs(run, root string) { ++ // check db lock is exist, do nothing if file is existed ++ dbLockPath := filepath.Join(run, "dblock") ++ _, err := os.Stat(dbLockPath) ++ if err == nil { ++ return ++ } ++ if !os.IsNotExist(err) { ++ logrus.Errorf("stat dblock failed %v", err) ++ return ++ } ++ ioutil.WriteFile(dbLockPath, []byte{}, 0600) ++ cleanupLocalDB(filepath.Join(root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) ++ cleanupLocalDB(filepath.Join(root, "builder/fscache.db")) ++ cleanupLocalDB(filepath.Join(root, "volumes/metadata.db")) ++ cleanupLocalDB(filepath.Join(root, "network/files/local-kv.db")) ++ cleanupLocalDB(filepath.Join(root, "accelerator/accel.db")) ++ cleanupLocalDB(filepath.Join(root, "buildkit/metadata.db")) ++ cleanupLocalDB(filepath.Join(root, "buildkit/cache.db")) ++ cleanupLocalDB(filepath.Join(root, "buildkit/snapshots.db")) ++} ++ + func (cli *DaemonCli) start(opts *daemonOptions) (err error) { + stopc := make(chan bool) + defer close(stopc) +@@ -151,7 +184,7 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { + return fmt.Errorf("Failed to generate containerd options: %v", err) + } + +- daemon.CleanupContainerdDBs(cli.Config.ExecRoot, cli.Config.Root) ++ cleanupLocalDBs(cli.Config.ExecRoot, cli.Config.Root) + r, err := supervisor.Start(ctx, filepath.Join(cli.Config.Root, "containerd"), filepath.Join(cli.Config.ExecRoot, "containerd"), opts...) + if err != nil { + cancel() +diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go +index 01351cc544..b9af915ef8 100644 +--- a/components/engine/daemon/daemon.go ++++ b/components/engine/daemon/daemon.go +@@ -514,8 +514,6 @@ func (daemon *Daemon) restore() error { + logrus.Errorf("removeRedundantMounts failed %v", err) + } + +- daemon.cleanupLocalDBs(daemon.configStore.ExecRoot, daemon.configStore.Root) +- + containerIDs := make(map[string]struct{}) + for cid, _ := range containers { + containerIDs[cid] = struct{}{} +@@ -616,72 +614,6 @@ func (daemon *Daemon) restore() error { + return nil + } + +-func cleanupLocalDB(db string) { +- _, err := os.Stat(db) +- if err == nil { +- err = os.Remove(db) +- logrus.Infof("cleanup DB %s error=%v", db, err) +- } +-} +- +-func CleanupContainerdDBs(run, root string) { +- // check db lock is exist, do nothing if file is existed +- dbLockPath := filepath.Join(run, "dblock") +- _, err := os.Stat(dbLockPath) +- if err == nil { +- return +- } +- if !os.IsNotExist(err) { +- logrus.Errorf("stat DB dblock failed %v", err) +- return +- } +- cleanupLocalDB(filepath.Join(root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) +-} +- +-// DB files may corrupted on exception poweroff but can be rebuild at run time, +-// so we can remove DB files on OS starts avoid daemon can not startup. +-func (daemon *Daemon) cleanupLocalDBs(run, root string) { +- // check db lock is exist, do nothing if file is existed +- dbLockPath := filepath.Join(run, "dblock") +- _, err := os.Stat(dbLockPath) +- if err == nil { +- return +- } +- if !os.IsNotExist(err) { +- logrus.Errorf("stat dblock failed %v", err) +- return +- } +- ioutil.WriteFile(dbLockPath, []byte{}, 0600) +- +- removeAllDB := func() { +- cleanupLocalDB(filepath.Join(root, "builder/fscache.db")) +- cleanupLocalDB(filepath.Join(root, "volumes/metadata.db")) +- cleanupLocalDB(filepath.Join(root, "network/files/local-kv.db")) +- cleanupLocalDB(filepath.Join(root, "accelerator/accel.db")) +- cleanupLocalDB(filepath.Join(root, "buildkit/metadata.db")) +- cleanupLocalDB(filepath.Join(root, "buildkit/cache.db")) +- cleanupLocalDB(filepath.Join(root, "buildkit/snapshots.db")) +- } +- +- if daemon.containers == nil { +- logrus.Warnf("nil containers, cleanup local DB after OS start ...") +- removeAllDB() +- return +- } +- +- ls, err := daemon.Containers(&types.ContainerListOptions{}) +- if err != nil { +- logrus.Errorf("list containers failed %v", err) +- return +- } +- +- if len(ls) == 0 { +- logrus.Warnf("no running containers, cleanup local DB after OS start ...") +- removeAllDB() +- return +- } +-} +- + // RestartSwarmContainers restarts any autostart container which has a + // swarm endpoint. + func (daemon *Daemon) RestartSwarmContainers() { +-- +2.17.1 + diff --git a/patch/0143-docker-add-exit-on-unhealthy-flag-for-health-check.patch b/patch/0143-docker-add-exit-on-unhealthy-flag-for-health-check.patch new file mode 100644 index 0000000..ad3a26f --- /dev/null +++ b/patch/0143-docker-add-exit-on-unhealthy-flag-for-health-check.patch @@ -0,0 +1,40 @@ +From d22a96d286265462f82db6329a555cc4dcf3a99c Mon Sep 17 00:00:00 2001 +From: liuzekun +Date: Mon, 14 Oct 2019 23:09:29 -0400 +Subject: [PATCH] docker: add 'exit-on-unhealthy' flag for docker build parse Dockerfile + +reason: add 'exit-on-unhealthy' flag for docker build parse + +Signed-off-by: liuzekun +--- + .../buildkit/frontend/dockerfile/instructions/parse.go | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go +index 0ce076a5..acfd669b 100644 +--- a/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go ++++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go +@@ -449,6 +449,7 @@ func parseHealthcheck(req parseRequest) (*HealthCheckCommand, error) { + flTimeout := req.flags.AddString("timeout", "") + flStartPeriod := req.flags.AddString("start-period", "") + flRetries := req.flags.AddString("retries", "") ++ flExitOnUnhealthy := req.flags.AddBool("exit-on-unhealthy", false) + + if err := req.flags.Parse(); err != nil { + return nil, err +@@ -501,6 +502,12 @@ func parseHealthcheck(req parseRequest) (*HealthCheckCommand, error) { + healthcheck.Retries = 0 + } + ++ exitonunhealthy, err := strconv.ParseBool(flExitOnUnhealthy.Value) ++ if err != nil { ++ return nil, err ++ } ++ healthcheck.ExitOnUnhealthy = exitonunhealthy ++ + cmd.Health = &healthcheck + } + return cmd, nil +-- +2.20.1 + diff --git a/patch/0144-docker-fix-testcase-TestAttachClosedOnContain.patch b/patch/0144-docker-fix-testcase-TestAttachClosedOnContain.patch new file mode 100644 index 0000000..780ca9a --- /dev/null +++ b/patch/0144-docker-fix-testcase-TestAttachClosedOnContain.patch @@ -0,0 +1,31 @@ +From 1b8ccbb863368258645e76a85fca202050a9c636 Mon Sep 17 00:00:00 2001 +From: xiadanni1 +Date: Thu, 31 Oct 2019 02:35:33 +0800 +Subject: [PATCH] docker: fix testcase TestAttachClosedOnContainerStop + +reason:testcase TestAttachClosedOnContainerStop will fail because we add timeout +for attach when container stops, in this case we just ignore err. + +Change-Id: I5db1e76535d7a39d3782b488025e27b09e341d3b +Signed-off-by: xiadanni1 +--- + components/engine/integration-cli/docker_cli_attach_unix_test.go | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/components/engine/integration-cli/docker_cli_attach_unix_test.go b/components/engine/integration-cli/docker_cli_attach_unix_test.go +index 9affb94..906bf07 100644 +--- a/components/engine/integration-cli/docker_cli_attach_unix_test.go ++++ b/components/engine/integration-cli/docker_cli_attach_unix_test.go +@@ -52,6 +52,9 @@ func (s *DockerSuite) TestAttachClosedOnContainerStop(c *check.C) { + case err := <-errChan: + tty.Close() + out, _ := ioutil.ReadAll(pty) ++ if strings.Contains(string(out), "Wait container status timeout") { ++ err = nil ++ } + c.Assert(err, check.IsNil, check.Commentf("out: %v", string(out))) + case <-time.After(attachWait): + c.Fatal("timed out without attach returning") +-- +1.8.3.1 + diff --git a/patch/0145-docker-hot-upgrade-support-default-runtime.patch b/patch/0145-docker-hot-upgrade-support-default-runtime.patch new file mode 100644 index 0000000..4da8757 --- /dev/null +++ b/patch/0145-docker-hot-upgrade-support-default-runtime.patch @@ -0,0 +1,55 @@ +From 1479fdcf8c162cb9b0c54673fedba2a2ee2dbf36 Mon Sep 17 00:00:00 2001 +From: jingrui +Date: Wed, 14 Aug 2019 10:35:30 +0800 +Subject: [PATCH 1/3] docker: hot-upgrade support default runtime + +When hot-upgrade from docker-1.11.2, old version docker using +default runtime for runc. We need support start container created from +old version docker. + +Change-Id: I1287c5a6798be57c8d0446230806dc87c98ab787 +Signed-off-by: jingrui +--- + components/engine/daemon/config/config_common_unix.go | 5 +++++ + components/engine/daemon/daemon.go | 5 ++--- + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/components/engine/daemon/config/config_common_unix.go b/components/engine/daemon/config/config_common_unix.go +index 0a862d3b50..e2dfec91bb 100644 +--- a/components/engine/daemon/config/config_common_unix.go ++++ b/components/engine/daemon/config/config_common_unix.go +@@ -32,6 +32,11 @@ func (conf *Config) GetRuntime(name string) *types.Runtime { + if rt, ok := conf.Runtimes[name]; ok { + return &rt + } ++ if name == "default" { // legacy docker reserved default for runc. ++ if rt, ok := conf.Runtimes["runc"]; ok { ++ return &rt ++ } ++ } + return nil + } + +diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go +index b9af915ef8..3bd0d93a52 100644 +--- a/components/engine/daemon/daemon.go ++++ b/components/engine/daemon/daemon.go +@@ -357,13 +357,12 @@ func (daemon *Daemon) restore() error { + }).Debug("restoring container") + + var ( +- err error +- alive bool + ec uint32 + exitedAt time.Time + ) + +- alive, _, err = daemon.containerd.Restore(context.Background(), c.ID, c.InitializeStdio) ++ alive, pid, err := daemon.containerd.Restore(context.Background(), c.ID, c.InitializeStdio) ++ logrus.Infof("restored %s from containerd alive=%t pid=%d error=%v", c.ID, alive, pid, err) + if err != nil && !errdefs.IsNotFound(err) { + logrus.Errorf("Failed to restore container %s with containerd: %s", c.ID, err) + return +-- +2.17.1 + diff --git a/patch/0146-docker-hot-upgrade-support-accel-plugins.patch b/patch/0146-docker-hot-upgrade-support-accel-plugins.patch new file mode 100644 index 0000000..7e9d08a --- /dev/null +++ b/patch/0146-docker-hot-upgrade-support-accel-plugins.patch @@ -0,0 +1,123 @@ +From 475f02ed158e1339114f34fed98aa766e630351b Mon Sep 17 00:00:00 2001 +From: jingrui +Date: Mon, 23 Sep 2019 13:43:44 +0800 +Subject: [PATCH 2/3] docker: hot-upgrade support accel plugins + +docker-18.09 do not support accel management, so we should convert accel data +into env/bind/devices when restore container that started by docker-1.11.2. + +Change-Id: I19131123735e3f03c50d314ed5a22ab2fb7908b9 +Signed-off-by: jingrui +--- + .../engine/api/types/container/host_config.go | 17 +++++++ + components/engine/container/container.go | 46 +++++++++++++++++++ + components/engine/daemon/container.go | 1 + + 3 files changed, 64 insertions(+) + +diff --git a/components/engine/api/types/container/host_config.go b/components/engine/api/types/container/host_config.go +index 6989b2bbf9..f5930b92c1 100644 +--- a/components/engine/api/types/container/host_config.go ++++ b/components/engine/api/types/container/host_config.go +@@ -360,6 +360,18 @@ type UpdateConfig struct { + RestartPolicy RestartPolicy + } + ++// AccelMount holds the attribultes of accelerator volume mounts ++// Accelerator need to mount one or more volumes into container to provide lib and binary ++// These volume or directories may need to be merged ++type AccelMount struct { ++ Source string `json:"source"` ++ Destination string `json:"destination"` ++ RW bool `json:"writable"` ++ Propagation string `json:"mountpropagation"` ++ Mode string ++ Cover bool `json:"cover"` ++} ++ + // HostConfig the non-portable Config structure of a container. + // Here, "non-portable" means "dependent of the host we are running on". + // Portable information *should* appear in Config. +@@ -405,6 +417,11 @@ type HostConfig struct { + Isolation Isolation // Isolation technology of the container (e.g. default, hyperv) + HookSpec string // specification file containing custom hook definition + ++ // support plugin created by docker-1.11.2 with accel plugins. ++ AccelBindings map[string]AccelMount `json:",omitempty"` // Bind mount for accelerator ++ AccelDevices map[string]string `json:",omitempty"` // Devices for accelerator ++ AccelEnvironments map[string]string `json:",omitempty"` // Envs for accelerator ++ + // Contains container's resources (cgroups, ulimits) + Resources + +diff --git a/components/engine/container/container.go b/components/engine/container/container.go +index c19422061d..687df0c71a 100644 +--- a/components/engine/container/container.go ++++ b/components/engine/container/container.go +@@ -741,6 +741,52 @@ func (container *Container) CreateDaemonEnvironment(tty bool, linkedEnv []string + return env + } + ++func (c *Container) DropAccelAndCheckpointTo(store ViewDB) { ++ hc := c.HostConfig ++ cc := c.Config ++ shouldco := false ++ if len(hc.AccelBindings) != 0 { ++ for dst, ab := range hc.AccelBindings { ++ bind := fmt.Sprintf("%s:%s", ab.Source, dst) ++ if !ab.RW { ++ bind += ":ro" ++ } ++ hc.Binds = append(hc.Binds, bind) ++ } ++ logrus.Infof("upgrade Binds %v", hc.Binds) ++ hc.AccelBindings = nil ++ shouldco = true ++ } ++ ++ if len(hc.AccelDevices) != 0 { ++ for dest, hostPath := range hc.AccelDevices { ++ dev := containertypes.DeviceMapping{ ++ PathOnHost: hostPath, ++ PathInContainer: dest, ++ CgroupPermissions: "rwm", ++ } ++ hc.Devices = append(hc.Devices, dev) ++ } ++ logrus.Infof("upgrade Devices %v", hc.Devices) ++ hc.AccelDevices = nil ++ shouldco = true ++ } ++ ++ if len(hc.AccelEnvironments) != 0 { ++ for k, v := range hc.AccelEnvironments { ++ env := fmt.Sprintf("%s=%s", k, v) ++ cc.Env = append(cc.Env, env) ++ } ++ logrus.Infof("upgrade Env %s", cc.Env) ++ hc.AccelEnvironments = nil ++ shouldco = true ++ } ++ ++ if shouldco { ++ c.CheckpointTo(store) ++ } ++} ++ + type rio struct { + cio.IO + +diff --git a/components/engine/daemon/container.go b/components/engine/daemon/container.go +index 1cf67c4b5a..bf4574087d 100644 +--- a/components/engine/daemon/container.go ++++ b/components/engine/daemon/container.go +@@ -112,6 +112,7 @@ func (daemon *Daemon) load(id string) (*container.Container, error) { + return container, fmt.Errorf("Container %s is stored at %s", container.ID, id) + } + ++ container.DropAccelAndCheckpointTo(daemon.containersReplica) + return container, nil + } + +-- +2.17.1 + diff --git a/patch/0147-docker-hot-upgrade-treat-empty-storage-opt-as.patch b/patch/0147-docker-hot-upgrade-treat-empty-storage-opt-as.patch new file mode 100644 index 0000000..063f4c1 --- /dev/null +++ b/patch/0147-docker-hot-upgrade-treat-empty-storage-opt-as.patch @@ -0,0 +1,33 @@ +From f408e6c5b7bbf3eb4588e9b25165c7b959562189 Mon Sep 17 00:00:00 2001 +From: jingrui +Date: Thu, 26 Sep 2019 19:35:57 +0800 +Subject: [PATCH 3/3] docker: hot-upgrade treat empty storage-opt as + nil + +treat empty storage-opt as nil, fix error when rest api pass "StorageOpt": {} + +Error response from daemon: --storage-opt is supported only for overlay over xfs or ext4 with 'pquota' mount option. + +Change-Id: I21597b08493ed90aba466f6dcdf977ee46a2dbea +Signed-off-by: jingrui +--- + components/engine/daemon/create.go | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/components/engine/daemon/create.go b/components/engine/daemon/create.go +index b57b01eacc..7733d7b80b 100644 +--- a/components/engine/daemon/create.go ++++ b/components/engine/daemon/create.go +@@ -158,6 +158,9 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig, managed bool) ( + } + + container.HostConfig.StorageOpt = params.HostConfig.StorageOpt ++ if len(container.HostConfig.StorageOpt) == 0 { ++ container.HostConfig.StorageOpt = nil ++ } + + // Fixes: https://github.com/moby/moby/issues/34074 and + // https://github.com/docker/for-win/issues/999. +-- +2.17.1 + diff --git a/patch/0148-docker-ignore-warning-for-docker-info.patch b/patch/0148-docker-ignore-warning-for-docker-info.patch new file mode 100644 index 0000000..f8f6986 --- /dev/null +++ b/patch/0148-docker-ignore-warning-for-docker-info.patch @@ -0,0 +1,34 @@ +From 50b18098c37050f9cc55b4affa3fc8f1f73c93fb Mon Sep 17 00:00:00 2001 +From: jingrui +Date: Tue, 5 Nov 2019 09:32:40 +0800 +Subject: [PATCH 1/2] docker: ignore warning for docker info + +Change-Id: I7835830560068fc0ad135807c0d41f6757a02dd3 +Signed-off-by: jingrui +--- + components/engine/daemon/info_unix.go | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/components/engine/daemon/info_unix.go b/components/engine/daemon/info_unix.go +index c53804edec..131f877485 100644 +--- a/components/engine/daemon/info_unix.go ++++ b/components/engine/daemon/info_unix.go +@@ -40,7 +40,6 @@ func (daemon *Daemon) fillPlatformInfo(v *types.Info, sysInfo *sysinfo.SysInfo) + } + + if v.RuncCommit.ID == "" { +- logrus.Warnf("failed to retrieve %s version: unknown output format: %s", defaultRuntimeBinary, string(rv)) + v.RuncCommit.ID = "N/A" + } + } else { +@@ -72,7 +71,6 @@ func (daemon *Daemon) fillPlatformInfo(v *types.Info, sysInfo *sysinfo.SysInfo) + } + v.InitCommit = ver + } else { +- logrus.Warnf("failed to retrieve %s version: %s", defaultInitBinary, err) + v.InitCommit.ID = "N/A" + } + +-- +2.17.1 + diff --git a/patch/0149-docker-check-running-containers-before-del-db.patch b/patch/0149-docker-check-running-containers-before-del-db.patch new file mode 100644 index 0000000..c3e40d4 --- /dev/null +++ b/patch/0149-docker-check-running-containers-before-del-db.patch @@ -0,0 +1,33 @@ +From b3a721be343ac3183ab3cd5f52183b25a05e2f8d Mon Sep 17 00:00:00 2001 +From: jingrui +Date: Tue, 5 Nov 2019 11:43:07 +0800 +Subject: [PATCH] docker: check running containers before del db + +Change-Id: I2ea6a0c5f4b7c7f859e415231d67e8e219846bd7 +Signed-off-by: jingrui +--- + components/engine/cmd/dockerd/daemon.go | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go +index 1981175a4a..918012a334 100644 +--- a/components/engine/cmd/dockerd/daemon.go ++++ b/components/engine/cmd/dockerd/daemon.go +@@ -94,6 +94,14 @@ func cleanupLocalDBs(run, root string) { + return + } + ioutil.WriteFile(dbLockPath, []byte{}, 0600) ++ files, _ := ioutil.ReadDir(filepath.Join(run, "containerd")) ++ olds, _ := ioutil.ReadDir(filepath.Join(run, "libcontainerd")) ++ files = append(files, olds...) ++ for _, f := range files { ++ if len(f.Name()) == 64 { // running container exist ++ return ++ } ++ } + cleanupLocalDB(filepath.Join(root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) + cleanupLocalDB(filepath.Join(root, "builder/fscache.db")) + cleanupLocalDB(filepath.Join(root, "volumes/metadata.db")) +-- +2.17.1 + diff --git a/patch/0150-docker-fix-set-read-deadline-not-work.patch b/patch/0150-docker-fix-set-read-deadline-not-work.patch new file mode 100644 index 0000000..9f1305e --- /dev/null +++ b/patch/0150-docker-fix-set-read-deadline-not-work.patch @@ -0,0 +1,75 @@ +From 2b830a56e558697de18b821aebed4afb205e073b Mon Sep 17 00:00:00 2001 +From: jingrui +Date: Tue, 19 Nov 2019 17:35:58 +0800 +Subject: [PATCH] docker: fix set read deadline not work + +Change-Id: I494ff5b18c3d06bfc0064bf6da1eb83b66540cf4 +Signed-off-by: jingrui +--- + .../dockerd/hack/malformed_host_override.go | 37 ++++++++++++++++++- + 1 file changed, 35 insertions(+), 2 deletions(-) + +diff --git a/components/engine/cmd/dockerd/hack/malformed_host_override.go b/components/engine/cmd/dockerd/hack/malformed_host_override.go +index ddd5eb9d8b..b42b6f0e3a 100644 +--- a/components/engine/cmd/dockerd/hack/malformed_host_override.go ++++ b/components/engine/cmd/dockerd/hack/malformed_host_override.go +@@ -2,7 +2,12 @@ + + package hack // import "github.com/docker/docker/cmd/dockerd/hack" + +-import "net" ++import ( ++ "net" ++ "time" ++ "sync/atomic" ++ "github.com/sirupsen/logrus" ++) + + // MalformedHostHeaderOverride is a wrapper to be able + // to overcome the 400 Bad request coming from old docker +@@ -20,6 +26,18 @@ type MalformedHostHeaderOverrideConn struct { + } + + var closeConnHeader = []byte("\r\nConnection: close\r") ++var aLongTimeAgo = time.Unix(1, 0) ++var longTimeAgo int32 ++ ++// fix hijack hang ++func (l *MalformedHostHeaderOverrideConn) SetReadDeadline(t time.Time) error { ++ if t.Equal(aLongTimeAgo) { ++ atomic.StoreInt32(&longTimeAgo, 1) ++ } else { ++ atomic.StoreInt32(&longTimeAgo, 0) ++ } ++ return l.Conn.SetReadDeadline(t) ++} + + // Read reads the first *read* request from http.Server to inspect + // the Host header. If the Host starts with / then we're talking to +@@ -107,7 +125,22 @@ func (l *MalformedHostHeaderOverrideConn) Read(b []byte) (n int, err error) { + } + return len(buf), nil + } +- return l.Conn.Read(b) ++ var done int32 ++ go func() { ++ for i := 1; i < 300; i++ { // wait max = 30s ++ time.Sleep(100*time.Millisecond) // check interval = 0.1s ++ if atomic.LoadInt32(&longTimeAgo) == 0 || atomic.LoadInt32(&done) == 1 { ++ break ++ } ++ if i % 10 == 0 { // set interval = 1s ++ l.Conn.SetReadDeadline(aLongTimeAgo) ++ logrus.Debugf("fix hijack by set read deadline force") ++ } ++ } ++ }() ++ num, err := l.Conn.Read(b) ++ atomic.StoreInt32(&done, 1) ++ return num, err + } + + // Accept makes the listener accepts connections and wraps the connection +-- +2.17.1 + diff --git a/patch/0151-docker-enable-setting-env-variable-to-disable-db-del.patch b/patch/0151-docker-enable-setting-env-variable-to-disable-db-del.patch new file mode 100644 index 0000000..6970eb8 --- /dev/null +++ b/patch/0151-docker-enable-setting-env-variable-to-disable-db-del.patch @@ -0,0 +1,31 @@ +From e6f33061b2c9c6ce3676ec9be79d0bc99455bac6 Mon Sep 17 00:00:00 2001 +From: xiadanni1 +Date: Thu, 21 Nov 2019 02:04:28 +0800 +Subject: [PATCH] docker: enable setting env variable to disable db delete + +reason: crash files will be cleaned up when daemon restart, this patch allows +users to set env variable to disable db files delete if they need. + +Change-Id: Ibfc1ee02c8cd49dc05a1c0aa087af27cb0848c79 +Signed-off-by: xiadanni1 +--- + components/engine/cmd/dockerd/daemon.go | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go +index 744ec45..5fb8811 100644 +--- a/components/engine/cmd/dockerd/daemon.go ++++ b/components/engine/cmd/dockerd/daemon.go +@@ -102,6 +102,9 @@ func cleanupLocalDBs(run, root string) { + return + } + } ++ if os.Getenv("DISABLE_CRASH_FILES_DELETE") == "true" { ++ return ++ } + cleanupLocalDB(filepath.Join(root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) + cleanupLocalDB(filepath.Join(root, "builder/fscache.db")) + cleanupLocalDB(filepath.Join(root, "volumes/metadata.db")) +-- +1.8.3.1 + diff --git a/patch/0152-docker-Enable-disable-legacy-registry-function.patch b/patch/0152-docker-Enable-disable-legacy-registry-function.patch new file mode 100644 index 0000000..aaab0ee --- /dev/null +++ b/patch/0152-docker-Enable-disable-legacy-registry-function.patch @@ -0,0 +1,53 @@ +From a42b2ba938d30e05fd15502a3dc6d3cb6a7d1b25 Mon Sep 17 00:00:00 2001 +From: lixiang +Date: Thu, 28 Nov 2019 17:37:40 +0800 +Subject: [PATCH] docker:Enable "disable-legacy-registry" function + +reason:Enable "disable-legacy-registry" function which is used for +docker hot upgrade. + +Change-Id: I33dbb865d96d60ee2f758d204dea1a7f441d1a97 +Signed-off-by: lixiang +--- + components/engine/cmd/dockerd/config.go | 2 -- + components/engine/cmd/dockerd/daemon.go | 11 ----------- + 2 files changed, 13 deletions(-) + +diff --git a/components/engine/cmd/dockerd/config.go b/components/engine/cmd/dockerd/config.go +index 6f62b97..257b87f 100644 +--- a/components/engine/cmd/dockerd/config.go ++++ b/components/engine/cmd/dockerd/config.go +@@ -93,8 +93,6 @@ func installRegistryServiceFlags(options *registry.ServiceOptions, flags *pflag. + flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication") + + if runtime.GOOS != "windows" { +- // TODO: Remove this flag after 3 release cycles (18.03) + flags.BoolVar(&options.V2Only, "disable-legacy-registry", true, "Disable contacting legacy registries") +- flags.MarkHidden("disable-legacy-registry") + } + } +diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go +index 5fb8811..336078f 100644 +--- a/components/engine/cmd/dockerd/daemon.go ++++ b/components/engine/cmd/dockerd/daemon.go +@@ -479,17 +479,6 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) { + return nil, err + } + +- if runtime.GOOS != "windows" { +- if flags.Changed("disable-legacy-registry") { +- // TODO: Remove this error after 3 release cycles (18.03) +- return nil, errors.New("ERROR: The '--disable-legacy-registry' flag has been removed. Interacting with legacy (v1) registries is no longer supported") +- } +- if !conf.V2Only { +- // TODO: Remove this error after 3 release cycles (18.03) +- return nil, errors.New("ERROR: The 'disable-legacy-registry' configuration option has been removed. Interacting with legacy (v1) registries is no longer supported") +- } +- } +- + if flags.Changed("graph") { + logrus.Warnf(`The "-g / --graph" flag is deprecated. Please use "--data-root" instead`) + } +-- +1.8.3.1 + diff --git a/series.conf b/series.conf index 8bb8dcb..b5c19f6 100644 --- a/series.conf +++ b/series.conf @@ -9,7 +9,11 @@ patch/0090-overlay2-Use-index-off-if-possible.patch patch/0091-overlay2-use-global-logger-instance.patch patch/0126-docker-pass-root-to-chroot-to-for-chroot-ta.patch patch/0127-docker-support-docker-cli-using-syslog.patch - +patch/0128-docker-fix-CVE-2019-13509.patch +patch/0129-docker-add-validation-for-ref-CVE-2019-13139.patch +patch/0130-docker-Handle-blocked-I-O-of-exec-d-process.patch +patch/0131-docker-fix-mount-loop-on-docker-cp.patch +patch/0132-docker-fix-docker-cp-when-container-source-path-is-root.patch patch/0003-pause-fix-integration-testing-faile-about-doc.patch patch/0005-prjquota-fix-few-overlay2-quota-problems.patch @@ -130,3 +134,15 @@ patch/0141-docker-remove-logo-info.patch patch/0142-docker-add-copyright.patch patch/0143-docker-add-license.patch patch/0144-docker-hide-some-path-in-container.patch +patch/0141-docker-fix-updateUnpauseStats-wrong-path-erro.patch +patch/0142-docker-fix-fd-leak-on-reboot.patch +patch/0143-docker-add-exit-on-unhealthy-flag-for-health-check.patch +patch/0144-docker-fix-testcase-TestAttachClosedOnContain.patch +patch/0145-docker-hot-upgrade-support-default-runtime.patch +patch/0146-docker-hot-upgrade-support-accel-plugins.patch +patch/0147-docker-hot-upgrade-treat-empty-storage-opt-as.patch +patch/0148-docker-ignore-warning-for-docker-info.patch +patch/0149-docker-check-running-containers-before-del-db.patch +patch/0150-docker-fix-set-read-deadline-not-work.patch +patch/0151-docker-enable-setting-env-variable-to-disable-db-del.patch +patch/0152-docker-Enable-disable-legacy-registry-function.patch