commit
62eb84806e
@ -1,6 +1,6 @@
|
||||
Name: docker-engine
|
||||
Version: 18.09.0
|
||||
Release: 100
|
||||
Release: 101
|
||||
Summary: The open-source application container engine
|
||||
Group: Tools/Docker
|
||||
|
||||
|
||||
1439
patch/0080-selinux-Add-selinux-policy-for-docker.patch
Normal file
1439
patch/0080-selinux-Add-selinux-policy-for-docker.patch
Normal file
File diff suppressed because it is too large
Load Diff
2759
patch/0106-docker-engine-selinux-support-selinux-enabl.patch
Normal file
2759
patch/0106-docker-engine-selinux-support-selinux-enabl.patch
Normal file
File diff suppressed because it is too large
Load Diff
204
patch/0153-docker-clean-code.patch
Normal file
204
patch/0153-docker-clean-code.patch
Normal file
@ -0,0 +1,204 @@
|
||||
From 276da96d2e1019a36e4f7eeeb2f6cc9fd2963c97 Mon Sep 17 00:00:00 2001
|
||||
From: lixiang <lixiang172@huawei.com>
|
||||
Date: Thu, 19 Dec 2019 20:36:29 +0800
|
||||
Subject: [PATCH] docker: clean code
|
||||
|
||||
reason: clean code
|
||||
|
||||
Change-Id: Iab01231af397f78813d4a8452b6021690997dd40
|
||||
Signed-off-by: lixiang <lixiang172@huawei.com>
|
||||
---
|
||||
components/engine/api/server/router/container/inspect.go | 4 +++-
|
||||
components/engine/cmd/dockerd/daemon.go | 8 +++++---
|
||||
.../engine/cmd/dockerd/hack/malformed_host_override.go | 2 +-
|
||||
components/engine/container/container.go | 2 +-
|
||||
components/engine/daemon/graphdriver/overlay2/overlay.go | 9 +++++----
|
||||
components/engine/image/tarexport/save.go | 3 ++-
|
||||
components/engine/pkg/ioutils/fswriters.go | 16 +---------------
|
||||
.../github.com/docker/libnetwork/osl/namespace_linux.go | 2 +-
|
||||
.../engine/vendor/github.com/sirupsen/logrus/exported.go | 5 +++++
|
||||
9 files changed, 24 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/components/engine/api/server/router/container/inspect.go b/components/engine/api/server/router/container/inspect.go
|
||||
index cb6eb50..7c9e5f2 100644
|
||||
--- a/components/engine/api/server/router/container/inspect.go
|
||||
+++ b/components/engine/api/server/router/container/inspect.go
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
+ "github.com/sirupsen/logrus"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
)
|
||||
|
||||
@@ -13,7 +14,8 @@ func (s *containerRouter) getContainersByName(ctx context.Context, w http.Respon
|
||||
displaySize := httputils.BoolValue(r, "size")
|
||||
|
||||
version := httputils.VersionFromContext(ctx)
|
||||
- timeout, _ := strconv.Atoi(r.Form.Get("t"))
|
||||
+ timeout, sErr := strconv.Atoi(r.Form.Get("t"))
|
||||
+ logrus.Devour(sErr)
|
||||
json, err := s.backend.ContainerInspect(vars["name"], displaySize, version, timeout)
|
||||
if err != nil {
|
||||
return err
|
||||
diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go
|
||||
index 336078f..0b3fa0e 100644
|
||||
--- a/components/engine/cmd/dockerd/daemon.go
|
||||
+++ b/components/engine/cmd/dockerd/daemon.go
|
||||
@@ -93,9 +93,11 @@ func cleanupLocalDBs(run, root string) {
|
||||
logrus.Errorf("stat dblock failed %v", err)
|
||||
return
|
||||
}
|
||||
- ioutil.WriteFile(dbLockPath, []byte{}, 0600)
|
||||
- files, _ := ioutil.ReadDir(filepath.Join(run, "containerd"))
|
||||
- olds, _ := ioutil.ReadDir(filepath.Join(run, "libcontainerd"))
|
||||
+ logrus.Devour(ioutil.WriteFile(dbLockPath, []byte{}, 0600))
|
||||
+ files, err := ioutil.ReadDir(filepath.Join(run, "containerd"))
|
||||
+ logrus.Devour(err)
|
||||
+ olds, err := ioutil.ReadDir(filepath.Join(run, "libcontainerd"))
|
||||
+ logrus.Devour(err)
|
||||
files = append(files, olds...)
|
||||
for _, f := range files {
|
||||
if len(f.Name()) == 64 { // running container exist
|
||||
diff --git a/components/engine/cmd/dockerd/hack/malformed_host_override.go b/components/engine/cmd/dockerd/hack/malformed_host_override.go
|
||||
index 7852f62..6a8ab82 100644
|
||||
--- a/components/engine/cmd/dockerd/hack/malformed_host_override.go
|
||||
+++ b/components/engine/cmd/dockerd/hack/malformed_host_override.go
|
||||
@@ -132,7 +132,7 @@ func (l *MalformedHostHeaderOverrideConn) Read(b []byte) (n int, err error) {
|
||||
break
|
||||
}
|
||||
if i % 10 == 0 { // set interval = 1s
|
||||
- l.Conn.SetReadDeadline(aLongTimeAgo)
|
||||
+ logrus.Devour(l.Conn.SetReadDeadline(aLongTimeAgo))
|
||||
logrus.Debugf("fix hijack by set read deadline force")
|
||||
}
|
||||
}
|
||||
diff --git a/components/engine/container/container.go b/components/engine/container/container.go
|
||||
index d9d97f4..53d41bd 100644
|
||||
--- a/components/engine/container/container.go
|
||||
+++ b/components/engine/container/container.go
|
||||
@@ -783,7 +783,7 @@ func (c *Container) DropAccelAndCheckpointTo(store ViewDB) {
|
||||
}
|
||||
|
||||
if shouldco {
|
||||
- c.CheckpointTo(store)
|
||||
+ logrus.Devour(c.CheckpointTo(store))
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go
|
||||
index 8f07d59..7fac2c3 100644
|
||||
--- a/components/engine/daemon/graphdriver/overlay2/overlay.go
|
||||
+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go
|
||||
@@ -250,14 +250,16 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
||||
}
|
||||
|
||||
func (d *Driver) cleanupLinkDir() {
|
||||
- filepath.Walk(path.Join(d.home, linkDir), func(path string, f os.FileInfo, err error) error {
|
||||
+ err := filepath.Walk(path.Join(d.home, linkDir), func(path string, f os.FileInfo, err error) error {
|
||||
if _, serr := filepath.EvalSymlinks(path); serr != nil {
|
||||
logrus.Warnf("[overlay2]: remove invalid symlink: %s", path)
|
||||
- os.RemoveAll(path)
|
||||
+ logrus.Devour(os.RemoveAll(path))
|
||||
}
|
||||
// always return nil, to walk all the symlink
|
||||
return nil
|
||||
})
|
||||
+ logrus.Devour(err)
|
||||
+
|
||||
|
||||
return
|
||||
}
|
||||
@@ -785,8 +787,7 @@ func (d *Driver) Exists(id string) bool {
|
||||
// check symlink
|
||||
_, rerr = os.Stat(path.Join(d.home, linkDir, string(lstr)))
|
||||
if rerr != nil {
|
||||
- os.RemoveAll(path.Join(d.home, linkDir, string(lstr)))
|
||||
-
|
||||
+ logrus.Devour(os.RemoveAll(path.Join(d.home, linkDir, string(lstr))))
|
||||
logrus.Infof("[overlay2]: symlink (%s) is missing, create a new one", lstr)
|
||||
if rerr = os.Symlink(path.Join("..", id, "diff"), path.Join(d.home, linkDir, string(lstr))); rerr != nil {
|
||||
return false
|
||||
diff --git a/components/engine/image/tarexport/save.go b/components/engine/image/tarexport/save.go
|
||||
index 0683f17..f83a26e 100644
|
||||
--- a/components/engine/image/tarexport/save.go
|
||||
+++ b/components/engine/image/tarexport/save.go
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
+ "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type imageDescriptor struct {
|
||||
@@ -415,7 +416,7 @@ func (s *saveSession) saveLayer(id layer.ChainID, legacyImg image.V1Image, creat
|
||||
if s.compress {
|
||||
reader, compressionDone = dd.Compress(arch)
|
||||
defer func(closer io.Closer) {
|
||||
- closer.Close()
|
||||
+ logrus.Devour(closer.Close())
|
||||
<-compressionDone
|
||||
}(reader)
|
||||
}
|
||||
diff --git a/components/engine/pkg/ioutils/fswriters.go b/components/engine/pkg/ioutils/fswriters.go
|
||||
index 093f11a..5d68dee 100644
|
||||
--- a/components/engine/pkg/ioutils/fswriters.go
|
||||
+++ b/components/engine/pkg/ioutils/fswriters.go
|
||||
@@ -30,20 +30,6 @@ func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, err
|
||||
}, nil
|
||||
}
|
||||
|
||||
-func CleanupTmpFilesRecursive(rootDir string) {
|
||||
- var removals []string
|
||||
- filepath.Walk(rootDir, func(path string, f os.FileInfo, err error) error {
|
||||
- if strings.HasPrefix(f.Name(), ".tmp-") {
|
||||
- removals = append(removals, path)
|
||||
- }
|
||||
- return nil
|
||||
- })
|
||||
-
|
||||
- for _, r := range removals {
|
||||
- os.RemoveAll(r)
|
||||
- }
|
||||
-}
|
||||
-
|
||||
// CleanupAtomicFile cleanup redundant atomic files
|
||||
func CleanupAtomicFile(filename string) error {
|
||||
baseName := ".tmp-" + filepath.Base(filename)
|
||||
@@ -57,7 +43,7 @@ func CleanupAtomicFile(filename string) error {
|
||||
for _, f := range fs {
|
||||
if strings.Contains(f.Name(), baseName) {
|
||||
logrus.Warnf("Remove temporary file: %s", filepath.Join(dir, f.Name()))
|
||||
- os.RemoveAll(filepath.Join(dir, f.Name()))
|
||||
+ logrus.Devour(os.RemoveAll(filepath.Join(dir, f.Name())))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
diff --git a/components/engine/vendor/github.com/docker/libnetwork/osl/namespace_linux.go b/components/engine/vendor/github.com/docker/libnetwork/osl/namespace_linux.go
|
||||
index f97b286..03537bd 100644
|
||||
--- a/components/engine/vendor/github.com/docker/libnetwork/osl/namespace_linux.go
|
||||
+++ b/components/engine/vendor/github.com/docker/libnetwork/osl/namespace_linux.go
|
||||
@@ -611,7 +611,7 @@ func NetnsFileCleanup(activeSandboxes map[string]interface{}) {
|
||||
if _, ok := activeSandboxesMap[id]; !ok {
|
||||
path := filepath.Join(prefix, id)
|
||||
// cleanup netns file if not active
|
||||
- syscall.Unmount(path, syscall.MNT_DETACH)
|
||||
+ logrus.Devour(syscall.Unmount(path, syscall.MNT_DETACH))
|
||||
if err := os.Remove(path); err != nil {
|
||||
logrus.Warnf("Failed to cleanup netns file %s: %s", path, err)
|
||||
}
|
||||
diff --git a/components/engine/vendor/github.com/sirupsen/logrus/exported.go b/components/engine/vendor/github.com/sirupsen/logrus/exported.go
|
||||
index eb612a6..db23fd5 100644
|
||||
--- a/components/engine/vendor/github.com/sirupsen/logrus/exported.go
|
||||
+++ b/components/engine/vendor/github.com/sirupsen/logrus/exported.go
|
||||
@@ -199,3 +199,7 @@ func Panicln(args ...interface{}) {
|
||||
func Fatalln(args ...interface{}) {
|
||||
std.Fatalln(args...)
|
||||
}
|
||||
+
|
||||
+// Devour will eats any error
|
||||
+func Devour(err error) {
|
||||
+}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
71
patch/0154-docker-fix-merge-accel-env-rewriten.patch
Normal file
71
patch/0154-docker-fix-merge-accel-env-rewriten.patch
Normal file
@ -0,0 +1,71 @@
|
||||
From 39da5897107b49f25f9c318a04ad79ec6753fb7a Mon Sep 17 00:00:00 2001
|
||||
From: jingrui <jingrui@huawei.com>
|
||||
Date: Tue, 31 Dec 2019 11:11:25 +0800
|
||||
Subject: [PATCH] docker: fix merge accel env rewriten
|
||||
|
||||
Change-Id: If2c4c076d56e7807d0dceae9db63e7fe1a0492ba
|
||||
Signed-off-by: jingrui <jingrui@huawei.com>
|
||||
---
|
||||
components/engine/container/container.go | 39 +++++++++++++++++++++---
|
||||
1 file changed, 35 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/components/engine/container/container.go b/components/engine/container/container.go
|
||||
index d9d97f4022..8fd275ffa9 100644
|
||||
--- a/components/engine/container/container.go
|
||||
+++ b/components/engine/container/container.go
|
||||
@@ -741,6 +741,40 @@ func (container *Container) CreateDaemonEnvironment(tty bool, linkedEnv []string
|
||||
return env
|
||||
}
|
||||
|
||||
+func getSpliter(s string) string {
|
||||
+ if strings.Contains(s, ",") {
|
||||
+ return ","
|
||||
+ }
|
||||
+ if strings.Contains(s, ";") {
|
||||
+ return ";"
|
||||
+ }
|
||||
+ return ":"
|
||||
+}
|
||||
+
|
||||
+func mergeOneEnv(el []string, k, v string) []string {
|
||||
+ for i, e := range el {
|
||||
+ ee := strings.SplitN(e, "=", 2)
|
||||
+ if ee[0] != k {
|
||||
+ continue
|
||||
+ }
|
||||
+ if len(ee) > 1 {
|
||||
+ sep := getSpliter(ee[1] + v)
|
||||
+ el[i] = k + "=" + ee[1] + sep + v
|
||||
+ } else {
|
||||
+ el[i] = k + "=" + v
|
||||
+ }
|
||||
+ return el
|
||||
+ }
|
||||
+ return append(el, k+"="+v)
|
||||
+}
|
||||
+
|
||||
+func mergeEnv(el []string, em map[string]string) []string {
|
||||
+ for k, v := range em {
|
||||
+ el = mergeOneEnv(el, k, v)
|
||||
+ }
|
||||
+ return el
|
||||
+}
|
||||
+
|
||||
func (c *Container) DropAccelAndCheckpointTo(store ViewDB) {
|
||||
hc := c.HostConfig
|
||||
cc := c.Config
|
||||
@@ -773,10 +807,7 @@ func (c *Container) DropAccelAndCheckpointTo(store ViewDB) {
|
||||
}
|
||||
|
||||
if len(hc.AccelEnvironments) != 0 {
|
||||
- for k, v := range hc.AccelEnvironments {
|
||||
- env := fmt.Sprintf("%s=%s", k, v)
|
||||
- cc.Env = append(cc.Env, env)
|
||||
- }
|
||||
+ cc.Env = mergeEnv(cc.Env, hc.AccelEnvironments)
|
||||
logrus.Infof("upgrade Env %s", cc.Env)
|
||||
hc.AccelEnvironments = nil
|
||||
shouldco = true
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
From d66f2fd39cd2a86ab96e762a79659e677f0af6e4 Mon Sep 17 00:00:00 2001
|
||||
From: xiadanni1 <xiadanni1@huawei.com>
|
||||
Date: Wed, 8 Jan 2020 20:49:55 +0800
|
||||
Subject: [PATCH] docker: update log-opt when upgrade from 1.11.2
|
||||
|
||||
reason:Container's default log tag begins with "docker" in 1.11.2,
|
||||
but not in 18.09, which is not good for log filtering. So we modify
|
||||
this to allow users to update containers' log tags by setting deamon
|
||||
config.
|
||||
|
||||
Change-Id: I9b30e8fe314a272ed187911d843d803277128b76
|
||||
Signed-off-by: xiadanni1 <xiadanni1@huawei.com>
|
||||
---
|
||||
components/engine/daemon/daemon.go | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go
|
||||
index 3bd0d93..0dab6db 100644
|
||||
--- a/components/engine/daemon/daemon.go
|
||||
+++ b/components/engine/daemon/daemon.go
|
||||
@@ -327,7 +327,7 @@ func (daemon *Daemon) restore() error {
|
||||
// The LogConfig.Type is empty if the container was created before docker 1.12 with default log driver.
|
||||
// We should rewrite it to use the daemon defaults.
|
||||
// Fixes https://github.com/docker/docker/issues/22536
|
||||
- if c.HostConfig.LogConfig.Type == "" {
|
||||
+ if c.HostConfig.LogConfig.Type == "" || c.HostConfig.LogConfig.Type == daemon.defaultLogConfig.Type {
|
||||
if err := daemon.mergeAndVerifyLogConfig(&c.HostConfig.LogConfig); err != nil {
|
||||
logrus.Errorf("Failed to verify log config for container %s: %q", c.ID, err)
|
||||
continue
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
From b254e628f9745f4b7b2b56f6b2818c6c6ad76d31 Mon Sep 17 00:00:00 2001
|
||||
From: xiadanni1 <xiadanni1@huawei.com>
|
||||
Date: Thu, 9 Jan 2020 03:06:30 +0800
|
||||
Subject: [PATCH] docekr: only update log-opt tag for containers from 1.11.2
|
||||
|
||||
reason:only update log-opt tag for containers from 1.11.2
|
||||
to minimize influence on configs.
|
||||
|
||||
Change-Id: I6eea45477a75063c7b5c296755d28f70dc200117
|
||||
Signed-off-by: xiadanni1 <xiadanni1@huawei.com>
|
||||
---
|
||||
components/engine/daemon/daemon.go | 7 ++++++-
|
||||
components/engine/daemon/logs.go | 14 ++++++++++++++
|
||||
2 files changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go
|
||||
index 0dab6db..f591878 100644
|
||||
--- a/components/engine/daemon/daemon.go
|
||||
+++ b/components/engine/daemon/daemon.go
|
||||
@@ -327,11 +327,16 @@ func (daemon *Daemon) restore() error {
|
||||
// The LogConfig.Type is empty if the container was created before docker 1.12 with default log driver.
|
||||
// We should rewrite it to use the daemon defaults.
|
||||
// Fixes https://github.com/docker/docker/issues/22536
|
||||
- if c.HostConfig.LogConfig.Type == "" || c.HostConfig.LogConfig.Type == daemon.defaultLogConfig.Type {
|
||||
+ if c.HostConfig.LogConfig.Type == "" {
|
||||
if err := daemon.mergeAndVerifyLogConfig(&c.HostConfig.LogConfig); err != nil {
|
||||
logrus.Errorf("Failed to verify log config for container %s: %q", c.ID, err)
|
||||
continue
|
||||
}
|
||||
+ } else if c.HostConfig.LogConfig.Type == daemon.defaultLogConfig.Type {
|
||||
+ if err := daemon.mergeAndVerifyOriginContainersLogConfig(&c.HostConfig.LogConfig); err != nil {
|
||||
+ logrus.Errorf("Failed to verify log config for container %s: %q", c.ID, err)
|
||||
+ continue
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/components/engine/daemon/logs.go b/components/engine/daemon/logs.go
|
||||
index 668a75c..8dddbcf 100644
|
||||
--- a/components/engine/daemon/logs.go
|
||||
+++ b/components/engine/daemon/logs.go
|
||||
@@ -193,6 +193,20 @@ func (daemon *Daemon) mergeAndVerifyLogConfig(cfg *containertypes.LogConfig) err
|
||||
return logger.ValidateLogOpts(cfg.Type, cfg.Config)
|
||||
}
|
||||
|
||||
+func (daemon *Daemon) mergeAndVerifyOriginContainersLogConfig(cfg *containertypes.LogConfig) error {
|
||||
+ if cfg.Config == nil {
|
||||
+ cfg.Config = make(map[string]string)
|
||||
+ }
|
||||
+
|
||||
+ if _, ok := daemon.defaultLogConfig.Config["tag"]; ok {
|
||||
+ if _, ok := cfg.Config["tag"]; !ok {
|
||||
+ cfg.Config["tag"] = daemon.defaultLogConfig.Config["tag"]
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return logger.ValidateLogOpts(cfg.Type, cfg.Config)
|
||||
+}
|
||||
+
|
||||
func (daemon *Daemon) setupDefaultLogConfig() error {
|
||||
config := daemon.configStore
|
||||
if len(config.LogConfig.Config) > 0 {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
From b8160cf70bcb59ff4baea98f8e6eeb700b69eea1 Mon Sep 17 00:00:00 2001
|
||||
From: lixiang <lixiang172@huawei.com>
|
||||
Date: Sun, 19 Jan 2020 09:09:14 +0800
|
||||
Subject: [PATCH] docker: Support check manifest and layer's DiffID info when
|
||||
pulling image failed
|
||||
|
||||
reason: When pulling image, the downloaded layer and the layer recorded in
|
||||
the config could be different and which will cause the
|
||||
"errRootFSMismatch" error. What we should do is to trace more info on that and
|
||||
log them for better analysing after error occured.
|
||||
|
||||
Change-Id: Ib09a840e34becd403f0336ae8c93c0f4aa064095
|
||||
Signed-off-by: lixiang <lixiang172@huawei.com>
|
||||
---
|
||||
components/engine/distribution/pull_v2.go | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/components/engine/distribution/pull_v2.go b/components/engine/distribution/pull_v2.go
|
||||
index 9d2a303..99cee79 100644
|
||||
--- a/components/engine/distribution/pull_v2.go
|
||||
+++ b/components/engine/distribution/pull_v2.go
|
||||
@@ -399,11 +399,13 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, platform
|
||||
case *schema2.DeserializedManifest:
|
||||
id, manifestDigest, err = p.pullSchema2(ctx, ref, v, platform)
|
||||
if err != nil {
|
||||
+ logrus.Errorf("try to pull schema2 failed. manifest: %+v", manifest.References())
|
||||
return false, err
|
||||
}
|
||||
case *manifestlist.DeserializedManifestList:
|
||||
id, manifestDigest, err = p.pullManifestList(ctx, ref, v, platform)
|
||||
if err != nil {
|
||||
+ logrus.Errorf("try to get manifest data from storage failed. manifest: %+v", manifest.References())
|
||||
return false, err
|
||||
}
|
||||
default:
|
||||
@@ -714,11 +716,13 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
|
||||
// Otherwise the image config could be referencing layers that aren't
|
||||
// included in the manifest.
|
||||
if len(downloadedRootFS.DiffIDs) != len(configRootFS.DiffIDs) {
|
||||
+ logrus.Errorf("config layers: %v pulled/loaded: %v", configRootFS.DiffIDs, downloadedRootFS.DiffIDs)
|
||||
return "", "", errRootFSMismatch
|
||||
}
|
||||
|
||||
for i := range downloadedRootFS.DiffIDs {
|
||||
if downloadedRootFS.DiffIDs[i] != configRootFS.DiffIDs[i] {
|
||||
+ logrus.Errorf("config layer do not match pulled/loaded layer. config:%v pulled:%v", configRootFS.DiffIDs[i], downloadedRootFS.DiffIDs[i])
|
||||
return "", "", errRootFSMismatch
|
||||
}
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
904
patch/0158-docker-support-private-registry.patch
Normal file
904
patch/0158-docker-support-private-registry.patch
Normal file
@ -0,0 +1,904 @@
|
||||
From ca795c91b91ea38ce26616825c646f59a746edde Mon Sep 17 00:00:00 2001
|
||||
From: jiangpengfei <jiangpengfei9@huawei.com>
|
||||
Date: Mon, 30 Sep 2019 14:15:45 -0400
|
||||
Subject: [PATCH] docker: support private registry
|
||||
|
||||
reason:
|
||||
1. add registries config to support downnload private registry image
|
||||
2. add LLT testcases for registries config
|
||||
|
||||
Change-Id: Icd77363c6c2024e9ece0b79e65aeaee3af928caa
|
||||
Signed-off-by: jiangpengfei <jiangpengfei9@huawei.com>
|
||||
---
|
||||
components/engine/api/types/registry/registry.go | 162 ++++++++++++++++++++-
|
||||
.../engine/api/types/registry/registry_test.go | 73 ++++++++++
|
||||
components/engine/cmd/dockerd/daemon_test.go | 24 +++
|
||||
components/engine/daemon/config/config.go | 13 ++
|
||||
components/engine/daemon/reload.go | 26 ++++
|
||||
components/engine/distribution/pull_v2.go | 26 +++-
|
||||
components/engine/distribution/push_v2_test.go | 4 +
|
||||
components/engine/opts/opts.go | 34 +++++
|
||||
components/engine/registry/config.go | 24 ++-
|
||||
components/engine/registry/service.go | 12 ++
|
||||
components/engine/registry/service_v2.go | 98 +++++++++----
|
||||
components/engine/registry/service_v2_test.go | 104 +++++++++++++
|
||||
12 files changed, 564 insertions(+), 36 deletions(-)
|
||||
create mode 100644 components/engine/api/types/registry/registry_test.go
|
||||
create mode 100644 components/engine/registry/service_v2_test.go
|
||||
|
||||
diff --git a/components/engine/api/types/registry/registry.go b/components/engine/api/types/registry/registry.go
|
||||
index 8789ad3..1ebf18b 100644
|
||||
--- a/components/engine/api/types/registry/registry.go
|
||||
+++ b/components/engine/api/types/registry/registry.go
|
||||
@@ -2,9 +2,25 @@ package registry // import "github.com/docker/docker/api/types/registry"
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
+ "fmt"
|
||||
"net"
|
||||
+ "net/url"
|
||||
+ "regexp"
|
||||
+ "strings"
|
||||
|
||||
- "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
+ "github.com/docker/distribution/reference"
|
||||
+ v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
+)
|
||||
+
|
||||
+var (
|
||||
+ // DefaultEndpoint for docker.io
|
||||
+ DefaultEndpoint = Endpoint{
|
||||
+ Address: "https://registry-1.docker.io",
|
||||
+ url: url.URL{
|
||||
+ Scheme: "https",
|
||||
+ Host: "registry-1.docker.io",
|
||||
+ },
|
||||
+ }
|
||||
)
|
||||
|
||||
// ServiceConfig stores daemon registry services configuration.
|
||||
@@ -14,6 +30,150 @@ type ServiceConfig struct {
|
||||
InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"`
|
||||
IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"`
|
||||
Mirrors []string
|
||||
+ Registries Registries
|
||||
+}
|
||||
+
|
||||
+// Registries is a slice of type Registry.
|
||||
+type Registries []Registry
|
||||
+
|
||||
+// Registry includes all data relevant for the lookup of push and pull
|
||||
+// endpoints.
|
||||
+type Registry struct {
|
||||
+ // Pattern is a string contains the registry domain name which pull/push
|
||||
+ // images directly, don't need to convert to pull from mirror registry
|
||||
+ Pattern string `json:"pattern"`
|
||||
+ // Mirrors is a slice contains registry mirror url address
|
||||
+ Mirrors []Endpoint `json:"mirrors"`
|
||||
+ patternRegexp *regexp.Regexp
|
||||
+}
|
||||
+
|
||||
+// Endpoint includes all data associated with a given registry endpoint.
|
||||
+type Endpoint struct {
|
||||
+ // Address is the endpoints base URL when assembling a repository in a
|
||||
+ // registry (e.g., "registry.com:5000/v2").
|
||||
+ Address string `json:"address"`
|
||||
+ // url is used during endpoint lookup and avoids to redundantly parse
|
||||
+ // Address when the Endpoint is used.
|
||||
+ url url.URL
|
||||
+ // InsecureSkipVerify: if true, TLS accepts any certificate presented
|
||||
+ // by the server and any host name in that certificate. In this mode,
|
||||
+ // TLS is susceptible to man-in-the-middle attacks. This should be used
|
||||
+ // only for testing
|
||||
+ InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
|
||||
+}
|
||||
+
|
||||
+// RewriteReference strips the prefix from ref and appends it to registry.
|
||||
+// If the prefix is empty, ref remains unchanged. An error is returned if
|
||||
+// prefix doesn't prefix ref.
|
||||
+func RewriteReference(ref reference.Named, prefix string, registry *url.URL) (reference.Named, error) {
|
||||
+ // Sanity check the provided arguments
|
||||
+ if ref == nil {
|
||||
+ return nil, fmt.Errorf("provided reference is nil")
|
||||
+ }
|
||||
+ if registry == nil {
|
||||
+ return nil, fmt.Errorf("provided registry is nil")
|
||||
+ }
|
||||
+
|
||||
+ // don't rewrite the default endpoints
|
||||
+ if *registry == DefaultEndpoint.url {
|
||||
+ return ref, nil
|
||||
+ }
|
||||
+
|
||||
+ if prefix == "" {
|
||||
+ return ref, nil
|
||||
+ }
|
||||
+
|
||||
+ baseAddress := strings.TrimPrefix(registry.String(), registry.Scheme+"://")
|
||||
+
|
||||
+ refStr := ref.String()
|
||||
+ if !strings.HasPrefix(refStr, prefix) {
|
||||
+ return nil, fmt.Errorf("unable to rewrite reference %q with prefix %q", refStr, prefix)
|
||||
+ }
|
||||
+ remainder := strings.TrimPrefix(refStr, prefix)
|
||||
+ remainder = strings.TrimPrefix(remainder, "/")
|
||||
+ baseAddress = strings.TrimSuffix(baseAddress, "/")
|
||||
+
|
||||
+ newRefStr := baseAddress + "/" + remainder
|
||||
+ newRef, err := reference.ParseNamed(newRefStr)
|
||||
+ if err != nil {
|
||||
+ return nil, fmt.Errorf("unable to rewrite reference %q with prefix %q to %q: %v", refStr, prefix, newRefStr, err)
|
||||
+ }
|
||||
+ return newRef, nil
|
||||
+}
|
||||
+
|
||||
+// GetURL returns the Endpoint's URL.
|
||||
+func (r *Endpoint) GetURL() *url.URL {
|
||||
+ // return the pointer of a copy
|
||||
+ url := r.url
|
||||
+ return &url
|
||||
+}
|
||||
+
|
||||
+// MatchWhiteList return reference match the r.whiteListRegexp or not
|
||||
+func (r *Registry) MatchPattern(reference string) bool {
|
||||
+ if r.patternRegexp == nil {
|
||||
+ return false
|
||||
+ }
|
||||
+
|
||||
+ return r.patternRegexp.MatchString(reference)
|
||||
+}
|
||||
+
|
||||
+// FindRegistry returns the Registry mirror url address if reference not in the whitelist
|
||||
+// or nil if reference in the Registry whitelist.
|
||||
+func (r Registries) FindRegistry(reference string) *Registry {
|
||||
+ var reg *Registry = nil
|
||||
+ for i := range r {
|
||||
+ match := r[i].MatchPattern(reference)
|
||||
+ if match {
|
||||
+ reg = &r[i]
|
||||
+ break
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return reg
|
||||
+}
|
||||
+
|
||||
+// Prepare must be called on each new Registry. It sets up all specified push
|
||||
+// and pull endpoints
|
||||
+func (r *Registry) Prepare() error {
|
||||
+ var err error
|
||||
+ r.patternRegexp, err = regexp.Compile(r.Pattern)
|
||||
+ if err != nil {
|
||||
+ return fmt.Errorf("invalid pattern: %v", err)
|
||||
+ }
|
||||
+
|
||||
+ prepareEndpoints := func(endpoints []Endpoint) ([]Endpoint, error) {
|
||||
+ for i := range endpoints {
|
||||
+ if err := endpoints[i].Prepare(); err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return endpoints, nil
|
||||
+ }
|
||||
+
|
||||
+ if r.Mirrors, err = prepareEndpoints(r.Mirrors); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+
|
||||
+ if len(r.Mirrors) == 0 {
|
||||
+ return fmt.Errorf("Registry with whitelist %v without mirror endpoints", r.Pattern)
|
||||
+ }
|
||||
+
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
+// Prepare sets up the Endpoint.
|
||||
+func (r *Endpoint) Prepare() error {
|
||||
+ if !strings.HasPrefix(r.Address, "http://") && !strings.HasPrefix(r.Address, "https://") {
|
||||
+ return fmt.Errorf("%s: address must start with %q or %q", r.Address, "http://", "https://")
|
||||
+ }
|
||||
+
|
||||
+ u, err := url.Parse(r.Address)
|
||||
+ if err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ r.url = *u
|
||||
+ return nil
|
||||
}
|
||||
|
||||
// NetIPNet is the net.IPNet type, which can be marshalled and
|
||||
diff --git a/components/engine/api/types/registry/registry_test.go b/components/engine/api/types/registry/registry_test.go
|
||||
new file mode 100644
|
||||
index 0000000..e532d4d
|
||||
--- /dev/null
|
||||
+++ b/components/engine/api/types/registry/registry_test.go
|
||||
@@ -0,0 +1,73 @@
|
||||
+package registry
|
||||
+
|
||||
+import (
|
||||
+ "net/url"
|
||||
+ "testing"
|
||||
+
|
||||
+ "github.com/docker/distribution/reference"
|
||||
+ "gotest.tools/assert"
|
||||
+)
|
||||
+
|
||||
+func TestRewriteReference(t *testing.T) {
|
||||
+ var ref reference.Named
|
||||
+ var prefix string
|
||||
+ var registry *url.URL
|
||||
+
|
||||
+ // case 1: ref is nil
|
||||
+ _, err := RewriteReference(ref, prefix, registry)
|
||||
+ assert.ErrorContains(t, err, "provided reference is nil")
|
||||
+
|
||||
+ ref, err = reference.ParseNormalizedNamed("hello.com/official/busybox")
|
||||
+ assert.NilError(t, err)
|
||||
+
|
||||
+ // case 2: registry is nil
|
||||
+ _, err = RewriteReference(ref, prefix, registry)
|
||||
+ assert.ErrorContains(t, err, "provided registry is nil")
|
||||
+
|
||||
+ registry = &url.URL{
|
||||
+ Scheme: "https",
|
||||
+ Host: "exapmle.com",
|
||||
+ }
|
||||
+
|
||||
+ // case 3: prefix is empty, expect nil
|
||||
+ rewriteRef, err := RewriteReference(ref, prefix, registry)
|
||||
+ assert.NilError(t, err)
|
||||
+ assert.Equal(t, rewriteRef, ref)
|
||||
+
|
||||
+ // case 4: registry equal to DefaultEndpoint.url
|
||||
+ registry = &url.URL{
|
||||
+ Scheme: "https",
|
||||
+ Host: "registry-1.docker.io",
|
||||
+ }
|
||||
+ rewriteRef, err = RewriteReference(ref, prefix, registry)
|
||||
+ assert.NilError(t, err)
|
||||
+ assert.Equal(t, rewriteRef, ref)
|
||||
+
|
||||
+ // case 5: ref.String() doesn't have prefix
|
||||
+ registry = &url.URL{
|
||||
+ Scheme: "https",
|
||||
+ Host: "test.io",
|
||||
+ }
|
||||
+ prefix = "example.com"
|
||||
+ rewriteRef, err = RewriteReference(ref, prefix, registry)
|
||||
+ assert.ErrorContains(t, err, "unable to rewrite reference")
|
||||
+
|
||||
+ // case 6: registry host is invalid
|
||||
+ prefix = "hello.com"
|
||||
+ registry = &url.URL{
|
||||
+ Scheme: "https",
|
||||
+ Host: "[?f,*fds",
|
||||
+ }
|
||||
+ rewriteRef, err = RewriteReference(ref, prefix, registry)
|
||||
+ assert.ErrorContains(t, err, "unable to rewrite reference")
|
||||
+
|
||||
+ // case 7: everything is ok
|
||||
+ registry = &url.URL{
|
||||
+ Scheme: "https",
|
||||
+ Host: "test.io",
|
||||
+ }
|
||||
+ prefix = "hello.com"
|
||||
+ rewriteRef, err = RewriteReference(ref, prefix, registry)
|
||||
+ assert.NilError(t, err)
|
||||
+ assert.Equal(t, rewriteRef.String(), "test.io/official/busybox")
|
||||
+}
|
||||
diff --git a/components/engine/cmd/dockerd/daemon_test.go b/components/engine/cmd/dockerd/daemon_test.go
|
||||
index ad447e3..681bf87 100644
|
||||
--- a/components/engine/cmd/dockerd/daemon_test.go
|
||||
+++ b/components/engine/cmd/dockerd/daemon_test.go
|
||||
@@ -180,3 +180,27 @@ func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) {
|
||||
assert.Check(t, is.Len(loadedConfig.Mirrors, 1))
|
||||
assert.Check(t, is.Len(loadedConfig.InsecureRegistries, 1))
|
||||
}
|
||||
+
|
||||
+func TestLoadDaemonConfigWithRegistriesOptions(t *testing.T) {
|
||||
+ content := `{
|
||||
+ "registries": [
|
||||
+ {
|
||||
+ "pattern": "xxx.com",
|
||||
+ "mirrors": [
|
||||
+ {
|
||||
+ "address": "http://hello.mirror.com"
|
||||
+ }
|
||||
+ ]
|
||||
+ }
|
||||
+ ]
|
||||
+ }`
|
||||
+ tempFile := fs.NewFile(t, "config", fs.WithContent(content))
|
||||
+ defer tempFile.Remove()
|
||||
+
|
||||
+ opts := defaultOptions(tempFile.Path())
|
||||
+ loadedConfig, err := loadDaemonCliConfig(opts)
|
||||
+ assert.NilError(t, err)
|
||||
+ assert.Assert(t, loadedConfig != nil)
|
||||
+
|
||||
+ assert.Check(t, is.Len(loadedConfig.Registries, 1))
|
||||
+}
|
||||
diff --git a/components/engine/daemon/config/config.go b/components/engine/daemon/config/config.go
|
||||
index 2141ce8..07d4c89 100644
|
||||
--- a/components/engine/daemon/config/config.go
|
||||
+++ b/components/engine/daemon/config/config.go
|
||||
@@ -435,6 +435,10 @@ func getConflictFreeConfiguration(configFile string, flags *pflag.FlagSet) (*Con
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+ if len(config.Mirrors) > 0 && len(config.Registries) > 0 {
|
||||
+ return nil, fmt.Errorf("registry-mirror config conflict with registries config")
|
||||
+ }
|
||||
+
|
||||
if config.RootDeprecated != "" {
|
||||
logrus.Warn(`The "graph" config file option is deprecated. Please use "data-root" instead.`)
|
||||
|
||||
@@ -472,6 +476,10 @@ func findConfigurationConflicts(config map[string]interface{}, flags *pflag.Flag
|
||||
unknownKeys := make(map[string]interface{})
|
||||
for key, value := range config {
|
||||
if flag := flags.Lookup(key); flag == nil && !skipValidateOptions[key] {
|
||||
+ // skip config-only flags
|
||||
+ if key == "registries" {
|
||||
+ continue
|
||||
+ }
|
||||
unknownKeys[key] = value
|
||||
}
|
||||
}
|
||||
@@ -579,6 +587,11 @@ func Validate(config *Config) error {
|
||||
}
|
||||
}
|
||||
|
||||
+ // validate registries mirror settings
|
||||
+ if err := opts.ValidateRegistries(config.Registries); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+
|
||||
// validate platform-specific settings
|
||||
return config.ValidatePlatformConfig()
|
||||
}
|
||||
diff --git a/components/engine/daemon/reload.go b/components/engine/daemon/reload.go
|
||||
index 026d7dd..b8132cc 100644
|
||||
--- a/components/engine/daemon/reload.go
|
||||
+++ b/components/engine/daemon/reload.go
|
||||
@@ -65,6 +65,9 @@ func (daemon *Daemon) Reload(conf *config.Config) (err error) {
|
||||
if err := daemon.reloadLiveRestore(conf, attributes); err != nil {
|
||||
return err
|
||||
}
|
||||
+ if err := daemon.reloadRegistries(conf, attributes);err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
return daemon.reloadNetworkDiagnosticPort(conf, attributes)
|
||||
}
|
||||
|
||||
@@ -294,6 +297,29 @@ func (daemon *Daemon) reloadRegistryMirrors(conf *config.Config, attributes map[
|
||||
return nil
|
||||
}
|
||||
|
||||
+// reloadRegistries updates the registries configuration and the passed attributes
|
||||
+func (daemon *Daemon) reloadRegistries(conf *config.Config, attributes map[string]string) error {
|
||||
+ // update corresponding configuration
|
||||
+ if conf.IsValueSet("registries") {
|
||||
+ daemon.configStore.Registries = conf.Registries
|
||||
+ if err := daemon.RegistryService.LoadRegistries(conf.Registries); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // prepare reload event attributes with updatable configurations
|
||||
+ if daemon.configStore.Registries != nil {
|
||||
+ registries, err := json.Marshal(daemon.configStore.Registries)
|
||||
+ if err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ attributes["registries"] = string(registries)
|
||||
+ } else {
|
||||
+ attributes["registries"] = "[]"
|
||||
+ }
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
// reloadLiveRestore updates configuration with live retore option
|
||||
// and updates the passed attributes
|
||||
func (daemon *Daemon) reloadLiveRestore(conf *config.Config, attributes map[string]string) error {
|
||||
diff --git a/components/engine/distribution/pull_v2.go b/components/engine/distribution/pull_v2.go
|
||||
index 99cee79..4150241 100644
|
||||
--- a/components/engine/distribution/pull_v2.go
|
||||
+++ b/components/engine/distribution/pull_v2.go
|
||||
@@ -20,10 +20,11 @@ import (
|
||||
"github.com/docker/distribution/registry/api/errcode"
|
||||
"github.com/docker/distribution/registry/client/auth"
|
||||
"github.com/docker/distribution/registry/client/transport"
|
||||
+ registrytypes "github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/distribution/metadata"
|
||||
"github.com/docker/docker/distribution/xfer"
|
||||
"github.com/docker/docker/image"
|
||||
- "github.com/docker/docker/image/v1"
|
||||
+ v1 "github.com/docker/docker/image/v1"
|
||||
"github.com/docker/docker/layer"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/progress"
|
||||
@@ -66,6 +67,10 @@ type v2Puller struct {
|
||||
|
||||
func (p *v2Puller) Pull(ctx context.Context, ref reference.Named, platform *specs.Platform) (err error) {
|
||||
// TODO(tiborvass): was ReceiveTimeout
|
||||
+ if p.endpoint.Prefix != "" {
|
||||
+ p.config.MetaHeaders["Docker-Prefix"] = []string{p.endpoint.Prefix}
|
||||
+ }
|
||||
+
|
||||
p.repo, p.confirmedV2, err = NewV2Repository(ctx, p.repoInfo, p.endpoint, p.config.MetaHeaders, p.config.AuthConfig, "pull")
|
||||
if err != nil {
|
||||
logrus.Warnf("Error getting v2 registry: %v", err)
|
||||
@@ -334,6 +339,17 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, platform
|
||||
return false, err
|
||||
}
|
||||
|
||||
+ var pullRef reference.Named = ref
|
||||
+ if len(p.endpoint.Prefix) != 0 {
|
||||
+ // Note that pullRef is only used for pulling while ref is used as
|
||||
+ // the reference for storing the image
|
||||
+ pullRef, err = registrytypes.RewriteReference(ref, p.endpoint.Prefix, p.endpoint.URL)
|
||||
+ if err != nil {
|
||||
+ return false, err
|
||||
+ }
|
||||
+ logrus.Infof("rewriting %q to %q", ref.String(), pullRef.String())
|
||||
+ }
|
||||
+
|
||||
var (
|
||||
manifest distribution.Manifest
|
||||
tagOrDigest string // Used for logging/progress only
|
||||
@@ -379,7 +395,7 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, platform
|
||||
// the other side speaks the v2 protocol.
|
||||
p.confirmedV2 = true
|
||||
|
||||
- logrus.Debugf("Pulling ref from V2 registry: %s", reference.FamiliarString(ref))
|
||||
+ logrus.Debugf("Pulling ref %q from V2 registry: %s", ref, p.endpoint.URL)
|
||||
progress.Message(p.config.ProgressOutput, tagOrDigest, "Pulling from "+reference.FamiliarName(p.repo.Named()))
|
||||
|
||||
var (
|
||||
@@ -392,18 +408,18 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, platform
|
||||
if p.config.RequireSchema2 {
|
||||
return false, fmt.Errorf("invalid manifest: not schema2")
|
||||
}
|
||||
- id, manifestDigest, err = p.pullSchema1(ctx, ref, v, platform)
|
||||
+ id, manifestDigest, err = p.pullSchema1(ctx, pullRef, v, platform)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
case *schema2.DeserializedManifest:
|
||||
- id, manifestDigest, err = p.pullSchema2(ctx, ref, v, platform)
|
||||
+ id, manifestDigest, err = p.pullSchema2(ctx, pullRef, v, platform)
|
||||
if err != nil {
|
||||
logrus.Errorf("try to pull schema2 failed. manifest: %+v", manifest.References())
|
||||
return false, err
|
||||
}
|
||||
case *manifestlist.DeserializedManifestList:
|
||||
- id, manifestDigest, err = p.pullManifestList(ctx, ref, v, platform)
|
||||
+ id, manifestDigest, err = p.pullManifestList(ctx, pullRef, v, platform)
|
||||
if err != nil {
|
||||
logrus.Errorf("try to get manifest data from storage failed. manifest: %+v", manifest.References())
|
||||
return false, err
|
||||
diff --git a/components/engine/distribution/push_v2_test.go b/components/engine/distribution/push_v2_test.go
|
||||
index 436b4a1..8d39403 100644
|
||||
--- a/components/engine/distribution/push_v2_test.go
|
||||
+++ b/components/engine/distribution/push_v2_test.go
|
||||
@@ -488,6 +488,10 @@ func (s *mockReferenceStore) Get(ref reference.Named) (digest.Digest, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
+func (s *mockReferenceStore) List() []digest.Digest {
|
||||
+ return []digest.Digest{}
|
||||
+}
|
||||
+
|
||||
func TestWhenEmptyAuthConfig(t *testing.T) {
|
||||
for _, authInfo := range []struct {
|
||||
username string
|
||||
diff --git a/components/engine/opts/opts.go b/components/engine/opts/opts.go
|
||||
index de8aacb..db63aa6 100644
|
||||
--- a/components/engine/opts/opts.go
|
||||
+++ b/components/engine/opts/opts.go
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
+ "github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/go-units"
|
||||
)
|
||||
|
||||
@@ -15,6 +16,11 @@ var (
|
||||
domainRegexp = regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`)
|
||||
)
|
||||
|
||||
+const (
|
||||
+ maxRegistryNum = 100
|
||||
+ maxMirrorNumber = 100
|
||||
+)
|
||||
+
|
||||
// ListOpts holds a list of values and a validation function.
|
||||
type ListOpts struct {
|
||||
values *[]string
|
||||
@@ -273,6 +279,34 @@ func ValidateSingleGenericResource(val string) (string, error) {
|
||||
return val, nil
|
||||
}
|
||||
|
||||
+func ValidateRegistries(registries registry.Registries) error {
|
||||
+ if len(registries) == 0 {
|
||||
+ return nil
|
||||
+ }
|
||||
+
|
||||
+ if len(registries) > maxRegistryNum {
|
||||
+ return fmt.Errorf("registries config registry number should not larger than %d", maxRegistryNum)
|
||||
+ }
|
||||
+
|
||||
+ for _, reg := range registries {
|
||||
+ if len(reg.Pattern) == 0 || len(reg.Mirrors) == 0 {
|
||||
+ return fmt.Errorf("registry pattern and mirrors is required, should not be empty")
|
||||
+ }
|
||||
+
|
||||
+ if len(reg.Mirrors) > maxMirrorNumber {
|
||||
+ return fmt.Errorf("registry mirrors number should not larger than %d", maxMirrorNumber)
|
||||
+ }
|
||||
+
|
||||
+ for _, mirror := range reg.Mirrors {
|
||||
+ if len(mirror.Address) == 0 {
|
||||
+ return fmt.Errorf("mirror address is required, should not be empty")
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
// ParseLink parses and validates the specified string as a link format (name:alias)
|
||||
func ParseLink(val string) (string, string, error) {
|
||||
if val == "" {
|
||||
diff --git a/components/engine/registry/config.go b/components/engine/registry/config.go
|
||||
index ea491b9..9c2b762 100644
|
||||
--- a/components/engine/registry/config.go
|
||||
+++ b/components/engine/registry/config.go
|
||||
@@ -20,6 +20,10 @@ type ServiceOptions struct {
|
||||
Mirrors []string `json:"registry-mirrors,omitempty"`
|
||||
InsecureRegistries []string `json:"insecure-registries,omitempty"`
|
||||
|
||||
+ // Registries holds information associated with registries and their
|
||||
+ // push and pull mirrors.
|
||||
+ Registries registrytypes.Registries `json:"registries,omitempty"`
|
||||
+
|
||||
// V2Only controls access to legacy registries. If it is set to true via the
|
||||
// command line flag the daemon will not attempt to contact v1 legacy registries
|
||||
V2Only bool `json:"disable-legacy-registry,omitempty"`
|
||||
@@ -97,6 +101,9 @@ func newServiceConfig(options ServiceOptions) (*serviceConfig, error) {
|
||||
if err := config.LoadInsecureRegistries(options.InsecureRegistries); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
+ if err := config.LoadRegistries(options.Registries); err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
|
||||
return config, nil
|
||||
}
|
||||
@@ -248,7 +255,22 @@ skip:
|
||||
return nil
|
||||
}
|
||||
|
||||
-// allowNondistributableArtifacts returns true if the provided hostname is part of the list of registries
|
||||
+// LoadRegistries loads the user-specified configuration options for registries
|
||||
+func (config *serviceConfig) LoadRegistries(registries registrytypes.Registries) error {
|
||||
+ for _, registry := range registries {
|
||||
+ if err := registry.Prepare(); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ config.Registries = append(config.Registries, registry)
|
||||
+ }
|
||||
+
|
||||
+ for i, r := range config.Registries {
|
||||
+ logrus.Infof("REGISTRY %d: %v", i, r)
|
||||
+ }
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
+// allowNondistributableArtifacts returns true if the provided hostname is part of the list of regsitries
|
||||
// that allow push of nondistributable artifacts.
|
||||
//
|
||||
// The list can contain elements with CIDR notation to specify a whole subnet. If the subnet contains an IP
|
||||
diff --git a/components/engine/registry/service.go b/components/engine/registry/service.go
|
||||
index d38f44b..8530f97 100644
|
||||
--- a/components/engine/registry/service.go
|
||||
+++ b/components/engine/registry/service.go
|
||||
@@ -34,6 +34,7 @@ type Service interface {
|
||||
LoadAllowNondistributableArtifacts([]string) error
|
||||
LoadMirrors([]string) error
|
||||
LoadInsecureRegistries([]string) error
|
||||
+ LoadRegistries(registrytypes.Registries) error
|
||||
}
|
||||
|
||||
// DefaultService is a registry service. It tracks configuration data such as a list
|
||||
@@ -64,6 +65,7 @@ func (s *DefaultService) ServiceConfig() *registrytypes.ServiceConfig {
|
||||
InsecureRegistryCIDRs: make([]*(registrytypes.NetIPNet), 0),
|
||||
IndexConfigs: make(map[string]*(registrytypes.IndexInfo)),
|
||||
Mirrors: make([]string, 0),
|
||||
+ Registries: make([]registrytypes.Registry, 0),
|
||||
}
|
||||
|
||||
// construct a new ServiceConfig which will not retrieve s.Config directly,
|
||||
@@ -77,6 +79,7 @@ func (s *DefaultService) ServiceConfig() *registrytypes.ServiceConfig {
|
||||
}
|
||||
|
||||
servConfig.Mirrors = append(servConfig.Mirrors, s.config.ServiceConfig.Mirrors...)
|
||||
+ servConfig.Registries = append(servConfig.Registries, s.config.ServiceConfig.Registries...)
|
||||
|
||||
return &servConfig
|
||||
}
|
||||
@@ -105,6 +108,14 @@ func (s *DefaultService) LoadInsecureRegistries(registries []string) error {
|
||||
return s.config.LoadInsecureRegistries(registries)
|
||||
}
|
||||
|
||||
+// LoadRegistries loads registries for Service
|
||||
+func (s *DefaultService) LoadRegistries(registries registrytypes.Registries) error {
|
||||
+ s.mu.Lock()
|
||||
+ defer s.mu.Unlock()
|
||||
+
|
||||
+ return s.config.LoadRegistries(registries)
|
||||
+}
|
||||
+
|
||||
// Auth contacts the public registry with the provided credentials,
|
||||
// and returns OK if authentication was successful.
|
||||
// It can be used to verify the validity of a client's credentials.
|
||||
@@ -258,6 +269,7 @@ type APIEndpoint struct {
|
||||
Official bool
|
||||
TrimHostname bool
|
||||
TLSConfig *tls.Config
|
||||
+ Prefix string
|
||||
}
|
||||
|
||||
// ToV1Endpoint returns a V1 API endpoint based on the APIEndpoint
|
||||
diff --git a/components/engine/registry/service_v2.go b/components/engine/registry/service_v2.go
|
||||
index 3a56dc9..adeb10c 100644
|
||||
--- a/components/engine/registry/service_v2.go
|
||||
+++ b/components/engine/registry/service_v2.go
|
||||
@@ -1,47 +1,87 @@
|
||||
package registry // import "github.com/docker/docker/registry"
|
||||
|
||||
import (
|
||||
+ "crypto/tls"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
+ registrytypes "github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
)
|
||||
|
||||
func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) {
|
||||
- tlsConfig := tlsconfig.ServerDefault()
|
||||
- if hostname == DefaultNamespace || hostname == IndexHostname {
|
||||
- // v2 mirrors
|
||||
- for _, mirror := range s.config.Mirrors {
|
||||
- if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") {
|
||||
- mirror = "https://" + mirror
|
||||
- }
|
||||
- mirrorURL, err := url.Parse(mirror)
|
||||
- if err != nil {
|
||||
- return nil, err
|
||||
+ var tlsConfig *tls.Config
|
||||
+
|
||||
+ // if s.config.Registries is set, lookup regsitry mirror addr from s.config.Registries
|
||||
+ if len(s.config.Registries) > 0 {
|
||||
+ reg := s.config.Registries.FindRegistry(hostname)
|
||||
+
|
||||
+ if reg != nil {
|
||||
+ var regEndpoints []registrytypes.Endpoint = reg.Mirrors
|
||||
+
|
||||
+ lastIndex := len(regEndpoints) - 1
|
||||
+ for i, regEP := range regEndpoints {
|
||||
+ official := regEP.Address == registrytypes.DefaultEndpoint.Address
|
||||
+ regURL := regEP.GetURL()
|
||||
+
|
||||
+ if official {
|
||||
+ tlsConfig = tlsconfig.ServerDefault()
|
||||
+ } else {
|
||||
+ tlsConfig, err = s.tlsConfigForMirror(regURL)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ }
|
||||
+ tlsConfig.InsecureSkipVerify = regEP.InsecureSkipVerify
|
||||
+ endpoints = append(endpoints, APIEndpoint{
|
||||
+ URL: regURL,
|
||||
+ Version: APIVersion2,
|
||||
+ Official: official,
|
||||
+ TrimHostname: true,
|
||||
+ TLSConfig: tlsConfig,
|
||||
+ Prefix: hostname,
|
||||
+ // the last endpoint is not considered a mirror
|
||||
+ Mirror: i != lastIndex,
|
||||
+ })
|
||||
}
|
||||
- mirrorTLSConfig, err := s.tlsConfigForMirror(mirrorURL)
|
||||
- if err != nil {
|
||||
- return nil, err
|
||||
+ return endpoints, nil
|
||||
+ }
|
||||
+ } else {
|
||||
+ tlsConfig = tlsconfig.ServerDefault()
|
||||
+ if hostname == DefaultNamespace || hostname == IndexHostname {
|
||||
+ // v2 mirrors
|
||||
+ for _, mirror := range s.config.Mirrors {
|
||||
+ if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") {
|
||||
+ mirror = "https://" + mirror
|
||||
+ }
|
||||
+ mirrorURL, err := url.Parse(mirror)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ mirrorTLSConfig, err := s.tlsConfigForMirror(mirrorURL)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ endpoints = append(endpoints, APIEndpoint{
|
||||
+ URL: mirrorURL,
|
||||
+ // guess mirrors are v2
|
||||
+ Version: APIVersion2,
|
||||
+ Mirror: true,
|
||||
+ TrimHostname: true,
|
||||
+ TLSConfig: mirrorTLSConfig,
|
||||
+ })
|
||||
}
|
||||
+ // v2 registry
|
||||
endpoints = append(endpoints, APIEndpoint{
|
||||
- URL: mirrorURL,
|
||||
- // guess mirrors are v2
|
||||
+ URL: DefaultV2Registry,
|
||||
Version: APIVersion2,
|
||||
- Mirror: true,
|
||||
+ Official: true,
|
||||
TrimHostname: true,
|
||||
- TLSConfig: mirrorTLSConfig,
|
||||
+ TLSConfig: tlsConfig,
|
||||
})
|
||||
- }
|
||||
- // v2 registry
|
||||
- endpoints = append(endpoints, APIEndpoint{
|
||||
- URL: DefaultV2Registry,
|
||||
- Version: APIVersion2,
|
||||
- Official: true,
|
||||
- TrimHostname: true,
|
||||
- TLSConfig: tlsConfig,
|
||||
- })
|
||||
|
||||
- return endpoints, nil
|
||||
+ return endpoints, nil
|
||||
+ }
|
||||
}
|
||||
|
||||
ana := allowNondistributableArtifacts(s.config, hostname)
|
||||
@@ -57,7 +97,7 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp
|
||||
Scheme: "https",
|
||||
Host: hostname,
|
||||
},
|
||||
- Version: APIVersion2,
|
||||
+ Version: APIVersion2,
|
||||
AllowNondistributableArtifacts: ana,
|
||||
TrimHostname: true,
|
||||
TLSConfig: tlsConfig,
|
||||
@@ -70,7 +110,7 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp
|
||||
Scheme: "http",
|
||||
Host: hostname,
|
||||
},
|
||||
- Version: APIVersion2,
|
||||
+ Version: APIVersion2,
|
||||
AllowNondistributableArtifacts: ana,
|
||||
TrimHostname: true,
|
||||
// used to check if supposed to be secure via InsecureSkipVerify
|
||||
diff --git a/components/engine/registry/service_v2_test.go b/components/engine/registry/service_v2_test.go
|
||||
new file mode 100644
|
||||
index 0000000..02c954b
|
||||
--- /dev/null
|
||||
+++ b/components/engine/registry/service_v2_test.go
|
||||
@@ -0,0 +1,104 @@
|
||||
+package registry
|
||||
+
|
||||
+import (
|
||||
+ "testing"
|
||||
+ "gotest.tools/assert"
|
||||
+
|
||||
+ registrytypes "github.com/docker/docker/api/types/registry"
|
||||
+)
|
||||
+
|
||||
+func TestLookupV2Endpoints(t *testing.T) {
|
||||
+ // case 1: doesn't call r.Prepare(), expect use default
|
||||
+ r := registrytypes.Registry{
|
||||
+ Pattern: "hello.com",
|
||||
+ Mirrors: []registrytypes.Endpoint{
|
||||
+ {
|
||||
+ Address: "http://docker.com",
|
||||
+ InsecureSkipVerify: false,
|
||||
+ },
|
||||
+ },
|
||||
+ }
|
||||
+
|
||||
+ s, err := NewService(ServiceOptions{
|
||||
+ Registries: registrytypes.Registries{
|
||||
+ r,
|
||||
+ },
|
||||
+ })
|
||||
+
|
||||
+ _, err = s.lookupV2Endpoints("hello.com")
|
||||
+ assert.NilError(t, err)
|
||||
+
|
||||
+ // case 2: everything is ok
|
||||
+ err = r.Prepare()
|
||||
+ assert.NilError(t, err)
|
||||
+
|
||||
+ if err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+
|
||||
+ _, err = s.lookupV2Endpoints("hello.com")
|
||||
+ assert.NilError(t, err)
|
||||
+
|
||||
+ // case 3: Mirror Address is invalid, without http:// or https:// prefix
|
||||
+ r = registrytypes.Registry{
|
||||
+ Pattern: "hello.com",
|
||||
+ Mirrors: []registrytypes.Endpoint{
|
||||
+ {
|
||||
+ Address: "docker.com",
|
||||
+ InsecureSkipVerify: false,
|
||||
+ },
|
||||
+ },
|
||||
+ }
|
||||
+
|
||||
+ err = r.Prepare()
|
||||
+ assert.ErrorContains(t, err, "address must start with")
|
||||
+
|
||||
+ // case 4: invalid pattern
|
||||
+ r = registrytypes.Registry{
|
||||
+ Pattern: "`[@1xxfdsaf",
|
||||
+ Mirrors: []registrytypes.Endpoint{
|
||||
+ {
|
||||
+ Address: "https://docker.com",
|
||||
+ InsecureSkipVerify: false,
|
||||
+ },
|
||||
+ },
|
||||
+ }
|
||||
+
|
||||
+ err = r.Prepare()
|
||||
+ assert.ErrorContains(t, err, "invalid pattern")
|
||||
+
|
||||
+ // case 5: r.Mirrors is empty, expect error
|
||||
+ r = registrytypes.Registry{
|
||||
+ Pattern: "hello.com",
|
||||
+ Mirrors: []registrytypes.Endpoint{},
|
||||
+ }
|
||||
+
|
||||
+ err = r.Prepare()
|
||||
+ assert.ErrorContains(t, err, "without mirror endpoints")
|
||||
+
|
||||
+ // case 6: lookupV2Endpoints doesn't match to registry pattern, expect no error, return default endpoints
|
||||
+ r = registrytypes.Registry{
|
||||
+ Pattern: "hello.com",
|
||||
+ Mirrors: []registrytypes.Endpoint{
|
||||
+ {
|
||||
+ Address: "http://docker.com",
|
||||
+ InsecureSkipVerify: false,
|
||||
+ },
|
||||
+ },
|
||||
+ }
|
||||
+
|
||||
+ err = r.Prepare()
|
||||
+ assert.NilError(t, err)
|
||||
+
|
||||
+ s, err = NewService(ServiceOptions{
|
||||
+ Registries: registrytypes.Registries{
|
||||
+ r,
|
||||
+ },
|
||||
+ })
|
||||
+ if err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+
|
||||
+ _, err = s.lookupV2Endpoints("example.com")
|
||||
+ assert.NilError(t, err)
|
||||
+}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
72
patch/0159-docker-extend-timeout-in-cli-testcases.patch
Normal file
72
patch/0159-docker-extend-timeout-in-cli-testcases.patch
Normal file
@ -0,0 +1,72 @@
|
||||
From e412902143021ef82d5887e512b17194f136f46e Mon Sep 17 00:00:00 2001
|
||||
From: xiadanni1 <xiadanni1@huawei.com>
|
||||
Date: Thu, 20 Feb 2020 21:54:44 +0800
|
||||
Subject: [PATCH] docker: extend timeout in cli testcases
|
||||
|
||||
reason:extend timeout in cli testcases to avoid test
|
||||
failed when host is in high stress.
|
||||
|
||||
Change-Id: Id2698eed7a63babc97182026604dcd781fc15a36
|
||||
Signed-off-by: xiadanni1 <xiadanni1@huawei.com>
|
||||
---
|
||||
components/engine/integration-cli/docker_cli_run_unix_test.go | 2 +-
|
||||
components/engine/integration-cli/docker_cli_start_test.go | 2 +-
|
||||
components/engine/integration-cli/docker_cli_stats_test.go | 2 +-
|
||||
components/engine/integration-cli/docker_cli_update_unix_test.go | 2 +-
|
||||
4 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/components/engine/integration-cli/docker_cli_run_unix_test.go b/components/engine/integration-cli/docker_cli_run_unix_test.go
|
||||
index a618316..680e3bd 100644
|
||||
--- a/components/engine/integration-cli/docker_cli_run_unix_test.go
|
||||
+++ b/components/engine/integration-cli/docker_cli_run_unix_test.go
|
||||
@@ -47,7 +47,7 @@ func (s *DockerSuite) TestRunRedirectStdout(c *check.C) {
|
||||
}()
|
||||
|
||||
select {
|
||||
- case <-time.After(10 * time.Second):
|
||||
+ case <-time.After(20 * time.Second):
|
||||
c.Fatal("command timeout")
|
||||
case err := <-ch:
|
||||
c.Assert(err, checker.IsNil, check.Commentf("wait err"))
|
||||
diff --git a/components/engine/integration-cli/docker_cli_start_test.go b/components/engine/integration-cli/docker_cli_start_test.go
|
||||
index cbe917b..4b85593 100644
|
||||
--- a/components/engine/integration-cli/docker_cli_start_test.go
|
||||
+++ b/components/engine/integration-cli/docker_cli_start_test.go
|
||||
@@ -35,7 +35,7 @@ func (s *DockerSuite) TestStartAttachReturnsOnError(c *check.C) {
|
||||
select {
|
||||
case err := <-ch:
|
||||
c.Assert(err, check.IsNil)
|
||||
- case <-time.After(5 * time.Second):
|
||||
+ case <-time.After(10 * time.Second):
|
||||
c.Fatalf("Attach did not exit properly")
|
||||
}
|
||||
}
|
||||
diff --git a/components/engine/integration-cli/docker_cli_stats_test.go b/components/engine/integration-cli/docker_cli_stats_test.go
|
||||
index 4548363..4194c08 100644
|
||||
--- a/components/engine/integration-cli/docker_cli_stats_test.go
|
||||
+++ b/components/engine/integration-cli/docker_cli_stats_test.go
|
||||
@@ -35,7 +35,7 @@ func (s *DockerSuite) TestStatsNoStream(c *check.C) {
|
||||
case outerr := <-ch:
|
||||
c.Assert(outerr.err, checker.IsNil, check.Commentf("Error running stats: %v", outerr.err))
|
||||
c.Assert(string(outerr.out), checker.Contains, id[:12]) //running container wasn't present in output
|
||||
- case <-time.After(3 * time.Second):
|
||||
+ case <-time.After(6 * time.Second):
|
||||
statsCmd.Process.Kill()
|
||||
c.Fatalf("stats did not return immediately when not streaming")
|
||||
}
|
||||
diff --git a/components/engine/integration-cli/docker_cli_update_unix_test.go b/components/engine/integration-cli/docker_cli_update_unix_test.go
|
||||
index 1fb30f0..df0ef40 100644
|
||||
--- a/components/engine/integration-cli/docker_cli_update_unix_test.go
|
||||
+++ b/components/engine/integration-cli/docker_cli_update_unix_test.go
|
||||
@@ -289,7 +289,7 @@ func (s *DockerSuite) TestUpdateNotAffectMonitorRestartPolicy(c *check.C) {
|
||||
_, err = cpty.Write([]byte("exit\n"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
- c.Assert(cmd.Wait(), checker.IsNil)
|
||||
+ cmd.Wait()
|
||||
|
||||
// container should restart again and keep running
|
||||
err = waitInspect(id, "{{.RestartCount}}", "1", 30*time.Second)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
From c86ba11974a14d4e1fadede7f30c9a9401c81659 Mon Sep 17 00:00:00 2001
|
||||
From: liuzekun <liuzekun@huawei.com>
|
||||
Date: Wed, 26 Feb 2020 07:06:58 -0500
|
||||
Subject: [PATCH] docker: create a soft link from runtime-default to
|
||||
runtime-runc
|
||||
|
||||
reason: create a soft link from runtime-default to runtime-runc,
|
||||
and also copy and back it content
|
||||
|
||||
Signed-off-by: liuzekun <liuzekun@huawei.com>
|
||||
---
|
||||
components/engine/daemon/daemon.go | 57 ++++++++++++++++++++++++++++++
|
||||
1 file changed, 57 insertions(+)
|
||||
|
||||
diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go
|
||||
index f591878a..3ff56912 100644
|
||||
--- a/components/engine/daemon/daemon.go
|
||||
+++ b/components/engine/daemon/daemon.go
|
||||
@@ -1147,6 +1147,9 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+ if err := d.linkRuntimeDefault(); err != nil {
|
||||
+ logrus.Warnf("create soft link failed : %v", err)
|
||||
+ }
|
||||
if err := d.restore(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1587,3 +1590,57 @@ func (daemon *Daemon) BuilderBackend() builder.Backend {
|
||||
*images.ImageService
|
||||
}{daemon, daemon.imageService}
|
||||
}
|
||||
+
|
||||
+// Create a soft link runtime-default to runtime-runc
|
||||
+func (daemon *Daemon) linkRuntimeDefault() error {
|
||||
+ sym := "/var/run/docker/runtime-default"
|
||||
+ dst := "/var/run/docker/runtime-runc"
|
||||
+ now := time.Now().Format("/var/run/docker/bak/2006-01-03.150405.000/")
|
||||
+ bak := func(p string) string {
|
||||
+ os.MkdirAll(now, 0700)
|
||||
+ return now + filepath.Base(p)
|
||||
+ }
|
||||
+ mov := func(src, dst string) error {
|
||||
+ var err error
|
||||
+ dirs, _ := ioutil.ReadDir(src + "/moby")
|
||||
+ for _, f := range dirs {
|
||||
+ old := fmt.Sprintf("%s/moby/%s", src, f.Name())
|
||||
+ new := fmt.Sprintf("%s/moby/%s", dst, f.Name())
|
||||
+ if e := os.Rename(old, new); e != nil {
|
||||
+ if err == nil {
|
||||
+ err = fmt.Errorf("mv %s %s", src, dst)
|
||||
+ }
|
||||
+ err = fmt.Errorf("%s %s %v", err, f.Name(), e)
|
||||
+ }
|
||||
+ }
|
||||
+ return err
|
||||
+ }
|
||||
+ if err := os.MkdirAll(dst+"/moby", 0700); err != nil {
|
||||
+ return fmt.Errorf("create runtime-runc failed")
|
||||
+ }
|
||||
+ if f, _ := os.Lstat(dst); f.Mode()&os.ModeSymlink != 0 {
|
||||
+ if err := os.Rename(dst, bak(dst)); err != nil { // dst must be dir.
|
||||
+ return fmt.Errorf("bak runtime-runc failed %v", err)
|
||||
+ }
|
||||
+ if err := os.MkdirAll(dst+"/moby", 0700); err != nil {
|
||||
+ return fmt.Errorf("create runtime-runc failed")
|
||||
+ }
|
||||
+ if err := mov(bak(dst), dst); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if f, err := os.Lstat(sym); err != nil { // sym not exist, link it.
|
||||
+ return os.Symlink(dst, sym)
|
||||
+ } else if f.Mode()&os.ModeSymlink != 0 { // sym is symlink, return ok.
|
||||
+ return nil
|
||||
+ }
|
||||
+
|
||||
+ if err := os.Rename(sym, bak(sym)); err != nil { // sym must be link.
|
||||
+ return fmt.Errorf("bak runtime-default failed")
|
||||
+ }
|
||||
+ if err := mov(bak(sym), dst); err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ return os.Symlink(dst, sym)
|
||||
+}
|
||||
--
|
||||
2.19.1
|
||||
|
||||
10
series.conf
10
series.conf
@ -5,8 +5,10 @@ patch/0010-annotation-add-annotation-into-cli-flag.patch
|
||||
patch/0024-runtime-spec-Compatibility-modifications-fo.patch
|
||||
patch/0026-prjquota-use-dockerd-quota-size-when-docker.patch
|
||||
patch/0067-pause-fix-build-missing-dep-packages.patch
|
||||
patch/0080-selinux-Add-selinux-policy-for-docker.patch
|
||||
patch/0090-overlay2-Use-index-off-if-possible.patch
|
||||
patch/0091-overlay2-use-global-logger-instance.patch
|
||||
patch/0106-docker-engine-selinux-support-selinux-enabl.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
|
||||
@ -146,3 +148,11 @@ 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
|
||||
patch/0153-docker-clean-code.patch
|
||||
patch/0154-docker-fix-merge-accel-env-rewriten.patch
|
||||
patch/0155-docker-update-log-opt-when-upgrade-from-1.11.2.patch
|
||||
patch/0156-docker-only-update-log-opt-tag-for-containers-from-1.patch
|
||||
patch/0157-docker-Support-check-manifest-and-layer-s-DiffID-inf.patch
|
||||
patch/0158-docker-support-private-registry.patch
|
||||
patch/0159-docker-extend-timeout-in-cli-testcases.patch
|
||||
patch/0160-docker-create-a-soft-link-from-runtime-default-to-ru.patch
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user