Fix: https://github.com/moby/moby/issues/34307
Signed-off-by: Chen Min <chenmin46@huawei.com>
| ... | ... |
@@ -64,6 +64,10 @@ const ( |
| 64 | 64 |
cgroupSystemdDriver = "systemd" |
| 65 | 65 |
) |
| 66 | 66 |
|
| 67 |
+type containerGetter interface {
|
|
| 68 |
+ GetContainer(string) (*container.Container, error) |
|
| 69 |
+} |
|
| 70 |
+ |
|
| 67 | 71 |
func getMemoryResources(config containertypes.Resources) *specs.LinuxMemory {
|
| 68 | 72 |
memory := specs.LinuxMemory{}
|
| 69 | 73 |
|
| ... | ... |
@@ -285,6 +289,8 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf |
| 285 | 285 |
hostConfig.IpcMode = containertypes.IpcMode(m) |
| 286 | 286 |
} |
| 287 | 287 |
|
| 288 |
+ adaptSharedNamespaceContainer(daemon, hostConfig) |
|
| 289 |
+ |
|
| 288 | 290 |
var err error |
| 289 | 291 |
opts, err := daemon.generateSecurityOpt(hostConfig) |
| 290 | 292 |
if err != nil {
|
| ... | ... |
@@ -299,6 +305,36 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf |
| 299 | 299 |
return nil |
| 300 | 300 |
} |
| 301 | 301 |
|
| 302 |
+// adaptSharedNamespaceContainer replaces container name with its ID in hostConfig. |
|
| 303 |
+// To be more precisely, it modifies `container:name` to `container:ID` of PidMode, IpcMode |
|
| 304 |
+// and NetworkMode. |
|
| 305 |
+// |
|
| 306 |
+// When a container shares its namespace with another container, use ID can keep the namespace |
|
| 307 |
+// sharing connection between the two containers even the another container is renamed. |
|
| 308 |
+func adaptSharedNamespaceContainer(daemon containerGetter, hostConfig *containertypes.HostConfig) {
|
|
| 309 |
+ containerPrefix := "container:" |
|
| 310 |
+ if hostConfig.PidMode.IsContainer() {
|
|
| 311 |
+ pidContainer := hostConfig.PidMode.Container() |
|
| 312 |
+ // if there is any error returned here, we just ignore it and leave it to be |
|
| 313 |
+ // handled in the following logic |
|
| 314 |
+ if c, err := daemon.GetContainer(pidContainer); err == nil {
|
|
| 315 |
+ hostConfig.PidMode = containertypes.PidMode(containerPrefix + c.ID) |
|
| 316 |
+ } |
|
| 317 |
+ } |
|
| 318 |
+ if hostConfig.IpcMode.IsContainer() {
|
|
| 319 |
+ ipcContainer := hostConfig.IpcMode.Container() |
|
| 320 |
+ if c, err := daemon.GetContainer(ipcContainer); err == nil {
|
|
| 321 |
+ hostConfig.IpcMode = containertypes.IpcMode(containerPrefix + c.ID) |
|
| 322 |
+ } |
|
| 323 |
+ } |
|
| 324 |
+ if hostConfig.NetworkMode.IsContainer() {
|
|
| 325 |
+ netContainer := hostConfig.NetworkMode.ConnectedContainer() |
|
| 326 |
+ if c, err := daemon.GetContainer(netContainer); err == nil {
|
|
| 327 |
+ hostConfig.NetworkMode = containertypes.NetworkMode(containerPrefix + c.ID) |
|
| 328 |
+ } |
|
| 329 |
+ } |
|
| 330 |
+} |
|
| 331 |
+ |
|
| 302 | 332 |
func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysinfo.SysInfo, update bool) ([]string, error) {
|
| 303 | 333 |
warnings := []string{}
|
| 304 | 334 |
fixMemorySwappiness(resources) |
| ... | ... |
@@ -3,6 +3,7 @@ |
| 3 | 3 |
package daemon |
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 |
+ "errors" |
|
| 6 | 7 |
"io/ioutil" |
| 7 | 8 |
"os" |
| 8 | 9 |
"path/filepath" |
| ... | ... |
@@ -18,6 +19,44 @@ import ( |
| 18 | 18 |
"github.com/docker/docker/volume/store" |
| 19 | 19 |
) |
| 20 | 20 |
|
| 21 |
+type fakeContainerGetter struct {
|
|
| 22 |
+ containers map[string]*container.Container |
|
| 23 |
+} |
|
| 24 |
+ |
|
| 25 |
+func (f *fakeContainerGetter) GetContainer(cid string) (*container.Container, error) {
|
|
| 26 |
+ container, ok := f.containers[cid] |
|
| 27 |
+ if !ok {
|
|
| 28 |
+ return nil, errors.New("container not found")
|
|
| 29 |
+ } |
|
| 30 |
+ return container, nil |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+// Unix test as uses settings which are not available on Windows |
|
| 34 |
+func TestAdjustSharedNamespaceContainerName(t *testing.T) {
|
|
| 35 |
+ fakeID := "abcdef1234567890" |
|
| 36 |
+ hostConfig := &containertypes.HostConfig{
|
|
| 37 |
+ IpcMode: containertypes.IpcMode("container:base"),
|
|
| 38 |
+ PidMode: containertypes.PidMode("container:base"),
|
|
| 39 |
+ NetworkMode: containertypes.NetworkMode("container:base"),
|
|
| 40 |
+ } |
|
| 41 |
+ containerStore := &fakeContainerGetter{}
|
|
| 42 |
+ containerStore.containers = make(map[string]*container.Container) |
|
| 43 |
+ containerStore.containers["base"] = &container.Container{
|
|
| 44 |
+ ID: fakeID, |
|
| 45 |
+ } |
|
| 46 |
+ |
|
| 47 |
+ adaptSharedNamespaceContainer(containerStore, hostConfig) |
|
| 48 |
+ if hostConfig.IpcMode != containertypes.IpcMode("container:"+fakeID) {
|
|
| 49 |
+ t.Errorf("Expected IpcMode to be container:%s", fakeID)
|
|
| 50 |
+ } |
|
| 51 |
+ if hostConfig.PidMode != containertypes.PidMode("container:"+fakeID) {
|
|
| 52 |
+ t.Errorf("Expected PidMode to be container:%s", fakeID)
|
|
| 53 |
+ } |
|
| 54 |
+ if hostConfig.NetworkMode != containertypes.NetworkMode("container:"+fakeID) {
|
|
| 55 |
+ t.Errorf("Expected NetworkMode to be container:%s", fakeID)
|
|
| 56 |
+ } |
|
| 57 |
+} |
|
| 58 |
+ |
|
| 21 | 59 |
// Unix test as uses settings which are not available on Windows |
| 22 | 60 |
func TestAdjustCPUShares(t *testing.T) {
|
| 23 | 61 |
tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-")
|