Signed-off-by: John Howard <jhoward@microsoft.com>
John Howard authored on 2017/04/26 04:03:45... | ... |
@@ -58,9 +58,8 @@ var ( |
58 | 58 |
errInvalidNetwork = fmt.Errorf("invalid network settings while building port map info") |
59 | 59 |
) |
60 | 60 |
|
61 |
-// CommonContainer holds the fields for a container which are |
|
62 |
-// applicable across all platforms supported by the daemon. |
|
63 |
-type CommonContainer struct { |
|
61 |
+// Container holds the structure defining a container object. |
|
62 |
+type Container struct { |
|
64 | 63 |
StreamConfig *stream.Config |
65 | 64 |
// embed for Container to support states directly. |
66 | 65 |
*State `json:"State"` // Needed for Engine API version <= 1.11 |
... | ... |
@@ -95,21 +94,31 @@ type CommonContainer struct { |
95 | 95 |
LogCopier *logger.Copier `json:"-"` |
96 | 96 |
restartManager restartmanager.RestartManager |
97 | 97 |
attachContext *attachContext |
98 |
+ |
|
99 |
+ // Fields here are specific to Unix platforms |
|
100 |
+ AppArmorProfile string |
|
101 |
+ HostnamePath string |
|
102 |
+ HostsPath string |
|
103 |
+ ShmPath string |
|
104 |
+ ResolvConfPath string |
|
105 |
+ SeccompProfile string |
|
106 |
+ NoNewPrivileges bool |
|
107 |
+ |
|
108 |
+ // Fields here are specific to Windows |
|
109 |
+ NetworkSharedContainerID string |
|
98 | 110 |
} |
99 | 111 |
|
100 | 112 |
// NewBaseContainer creates a new container with its |
101 | 113 |
// basic configuration. |
102 | 114 |
func NewBaseContainer(id, root string) *Container { |
103 | 115 |
return &Container{ |
104 |
- CommonContainer: CommonContainer{ |
|
105 |
- ID: id, |
|
106 |
- State: NewState(), |
|
107 |
- ExecCommands: exec.NewStore(), |
|
108 |
- Root: root, |
|
109 |
- MountPoints: make(map[string]*volume.MountPoint), |
|
110 |
- StreamConfig: stream.NewConfig(), |
|
111 |
- attachContext: &attachContext{}, |
|
112 |
- }, |
|
116 |
+ ID: id, |
|
117 |
+ State: NewState(), |
|
118 |
+ ExecCommands: exec.NewStore(), |
|
119 |
+ Root: root, |
|
120 |
+ MountPoints: make(map[string]*volume.MountPoint), |
|
121 |
+ StreamConfig: stream.NewConfig(), |
|
122 |
+ attachContext: &attachContext{}, |
|
113 | 123 |
} |
114 | 124 |
} |
115 | 125 |
|
... | ... |
@@ -11,9 +11,7 @@ import ( |
11 | 11 |
|
12 | 12 |
func TestContainerStopSignal(t *testing.T) { |
13 | 13 |
c := &Container{ |
14 |
- CommonContainer: CommonContainer{ |
|
15 |
- Config: &container.Config{}, |
|
16 |
- }, |
|
14 |
+ Config: &container.Config{}, |
|
17 | 15 |
} |
18 | 16 |
|
19 | 17 |
def, err := signal.ParseSignal(signal.DefaultStopSignal) |
... | ... |
@@ -27,9 +25,7 @@ func TestContainerStopSignal(t *testing.T) { |
27 | 27 |
} |
28 | 28 |
|
29 | 29 |
c = &Container{ |
30 |
- CommonContainer: CommonContainer{ |
|
31 |
- Config: &container.Config{StopSignal: "SIGKILL"}, |
|
32 |
- }, |
|
30 |
+ Config: &container.Config{StopSignal: "SIGKILL"}, |
|
33 | 31 |
} |
34 | 32 |
s = c.StopSignal() |
35 | 33 |
if s != 9 { |
... | ... |
@@ -39,9 +35,7 @@ func TestContainerStopSignal(t *testing.T) { |
39 | 39 |
|
40 | 40 |
func TestContainerStopTimeout(t *testing.T) { |
41 | 41 |
c := &Container{ |
42 |
- CommonContainer: CommonContainer{ |
|
43 |
- Config: &container.Config{}, |
|
44 |
- }, |
|
42 |
+ Config: &container.Config{}, |
|
45 | 43 |
} |
46 | 44 |
|
47 | 45 |
s := c.StopTimeout() |
... | ... |
@@ -51,9 +45,7 @@ func TestContainerStopTimeout(t *testing.T) { |
51 | 51 |
|
52 | 52 |
stopTimeout := 15 |
53 | 53 |
c = &Container{ |
54 |
- CommonContainer: CommonContainer{ |
|
55 |
- Config: &container.Config{StopTimeout: &stopTimeout}, |
|
56 |
- }, |
|
54 |
+ Config: &container.Config{StopTimeout: &stopTimeout}, |
|
57 | 55 |
} |
58 | 56 |
s = c.StopSignal() |
59 | 57 |
if s != 15 { |
... | ... |
@@ -26,21 +26,6 @@ const ( |
26 | 26 |
containerSecretMountPath = "/run/secrets" |
27 | 27 |
) |
28 | 28 |
|
29 |
-// Container holds the fields specific to unixen implementations. |
|
30 |
-// See CommonContainer for standard fields common to all containers. |
|
31 |
-type Container struct { |
|
32 |
- CommonContainer |
|
33 |
- |
|
34 |
- // Fields below here are platform specific. |
|
35 |
- AppArmorProfile string |
|
36 |
- HostnamePath string |
|
37 |
- HostsPath string |
|
38 |
- ShmPath string |
|
39 |
- ResolvConfPath string |
|
40 |
- SeccompProfile string |
|
41 |
- NoNewPrivileges bool |
|
42 |
-} |
|
43 |
- |
|
44 | 29 |
// ExitStatus provides exit reasons for a container. |
45 | 30 |
type ExitStatus struct { |
46 | 31 |
// The exit code with which the container exited. |
... | ... |
@@ -17,15 +17,6 @@ const ( |
17 | 17 |
containerInternalConfigsDirPath = `C:\ProgramData\Docker\internal\configs` |
18 | 18 |
) |
19 | 19 |
|
20 |
-// Container holds fields specific to the Windows implementation. See |
|
21 |
-// CommonContainer for standard fields common to all containers. |
|
22 |
-type Container struct { |
|
23 |
- CommonContainer |
|
24 |
- |
|
25 |
- // Fields below here are platform specific. |
|
26 |
- NetworkSharedContainerID string |
|
27 |
-} |
|
28 |
- |
|
29 | 20 |
// ExitStatus provides exit reasons for a container. |
30 | 21 |
type ExitStatus struct { |
31 | 22 |
// The exit code with which the container exited. |
... | ... |
@@ -38,14 +38,12 @@ func TestHealthStates(t *testing.T) { |
38 | 38 |
} |
39 | 39 |
|
40 | 40 |
c := &container.Container{ |
41 |
- CommonContainer: container.CommonContainer{ |
|
42 |
- ID: "id", |
|
43 |
- Name: "name", |
|
44 |
- Config: &containertypes.Config{ |
|
45 |
- Image: "image_name", |
|
46 |
- Labels: map[string]string{ |
|
47 |
- "com.docker.swarm.task.id": "id", |
|
48 |
- }, |
|
41 |
+ ID: "id", |
|
42 |
+ Name: "name", |
|
43 |
+ Config: &containertypes.Config{ |
|
44 |
+ Image: "image_name", |
|
45 |
+ Labels: map[string]string{ |
|
46 |
+ "com.docker.swarm.task.id": "id", |
|
49 | 47 |
}, |
50 | 48 |
}, |
51 | 49 |
} |
... | ... |
@@ -27,38 +27,28 @@ import ( |
27 | 27 |
|
28 | 28 |
func TestGetContainer(t *testing.T) { |
29 | 29 |
c1 := &container.Container{ |
30 |
- CommonContainer: container.CommonContainer{ |
|
31 |
- ID: "5a4ff6a163ad4533d22d69a2b8960bf7fafdcba06e72d2febdba229008b0bf57", |
|
32 |
- Name: "tender_bardeen", |
|
33 |
- }, |
|
30 |
+ ID: "5a4ff6a163ad4533d22d69a2b8960bf7fafdcba06e72d2febdba229008b0bf57", |
|
31 |
+ Name: "tender_bardeen", |
|
34 | 32 |
} |
35 | 33 |
|
36 | 34 |
c2 := &container.Container{ |
37 |
- CommonContainer: container.CommonContainer{ |
|
38 |
- ID: "3cdbd1aa394fd68559fd1441d6eff2ab7c1e6363582c82febfaa8045df3bd8de", |
|
39 |
- Name: "drunk_hawking", |
|
40 |
- }, |
|
35 |
+ ID: "3cdbd1aa394fd68559fd1441d6eff2ab7c1e6363582c82febfaa8045df3bd8de", |
|
36 |
+ Name: "drunk_hawking", |
|
41 | 37 |
} |
42 | 38 |
|
43 | 39 |
c3 := &container.Container{ |
44 |
- CommonContainer: container.CommonContainer{ |
|
45 |
- ID: "3cdbd1aa394fd68559fd1441d6eff2abfafdcba06e72d2febdba229008b0bf57", |
|
46 |
- Name: "3cdbd1aa", |
|
47 |
- }, |
|
40 |
+ ID: "3cdbd1aa394fd68559fd1441d6eff2abfafdcba06e72d2febdba229008b0bf57", |
|
41 |
+ Name: "3cdbd1aa", |
|
48 | 42 |
} |
49 | 43 |
|
50 | 44 |
c4 := &container.Container{ |
51 |
- CommonContainer: container.CommonContainer{ |
|
52 |
- ID: "75fb0b800922abdbef2d27e60abcdfaf7fb0698b2a96d22d3354da361a6ff4a5", |
|
53 |
- Name: "5a4ff6a163ad4533d22d69a2b8960bf7fafdcba06e72d2febdba229008b0bf57", |
|
54 |
- }, |
|
45 |
+ ID: "75fb0b800922abdbef2d27e60abcdfaf7fb0698b2a96d22d3354da361a6ff4a5", |
|
46 |
+ Name: "5a4ff6a163ad4533d22d69a2b8960bf7fafdcba06e72d2febdba229008b0bf57", |
|
55 | 47 |
} |
56 | 48 |
|
57 | 49 |
c5 := &container.Container{ |
58 |
- CommonContainer: container.CommonContainer{ |
|
59 |
- ID: "d22d69a2b8960bf7fafdcba06e72d2febdba960bf7fafdcba06e72d2f9008b060b", |
|
60 |
- Name: "d22d69a2b896", |
|
61 |
- }, |
|
50 |
+ ID: "d22d69a2b8960bf7fafdcba06e72d2febdba960bf7fafdcba06e72d2f9008b060b", |
|
51 |
+ Name: "d22d69a2b896", |
|
62 | 52 |
} |
63 | 53 |
|
64 | 54 |
store := container.NewMemoryStore() |
... | ... |
@@ -184,7 +174,7 @@ func TestContainerInitDNS(t *testing.T) { |
184 | 184 |
"UpdateDns":false,"Volumes":{},"VolumesRW":{},"AppliedVolumesFrom":null}` |
185 | 185 |
|
186 | 186 |
// Container struct only used to retrieve path to config file |
187 |
- container := &container.Container{CommonContainer: container.CommonContainer{Root: containerPath}} |
|
187 |
+ container := &container.Container{Root: containerPath} |
|
188 | 188 |
configPath, err := container.ConfigPath() |
189 | 189 |
if err != nil { |
190 | 190 |
t.Fatal(err) |
... | ... |
@@ -26,11 +26,9 @@ func newDaemonWithTmpRoot(t *testing.T) (*Daemon, func()) { |
26 | 26 |
|
27 | 27 |
func newContainerWithState(state *container.State) *container.Container { |
28 | 28 |
return &container.Container{ |
29 |
- CommonContainer: container.CommonContainer{ |
|
30 |
- ID: "test", |
|
31 |
- State: state, |
|
32 |
- Config: &containertypes.Config{}, |
|
33 |
- }, |
|
29 |
+ ID: "test", |
|
30 |
+ State: state, |
|
31 |
+ Config: &containertypes.Config{}, |
|
34 | 32 |
} |
35 | 33 |
|
36 | 34 |
} |
... | ... |
@@ -16,15 +16,13 @@ func TestLogContainerEventCopyLabels(t *testing.T) { |
16 | 16 |
defer e.Evict(l) |
17 | 17 |
|
18 | 18 |
container := &container.Container{ |
19 |
- CommonContainer: container.CommonContainer{ |
|
20 |
- ID: "container_id", |
|
21 |
- Name: "container_name", |
|
22 |
- Config: &containertypes.Config{ |
|
23 |
- Image: "image_name", |
|
24 |
- Labels: map[string]string{ |
|
25 |
- "node": "1", |
|
26 |
- "os": "alpine", |
|
27 |
- }, |
|
19 |
+ ID: "container_id", |
|
20 |
+ Name: "container_name", |
|
21 |
+ Config: &containertypes.Config{ |
|
22 |
+ Image: "image_name", |
|
23 |
+ Labels: map[string]string{ |
|
24 |
+ "node": "1", |
|
25 |
+ "os": "alpine", |
|
28 | 26 |
}, |
29 | 27 |
}, |
30 | 28 |
} |
... | ... |
@@ -49,14 +47,12 @@ func TestLogContainerEventWithAttributes(t *testing.T) { |
49 | 49 |
defer e.Evict(l) |
50 | 50 |
|
51 | 51 |
container := &container.Container{ |
52 |
- CommonContainer: container.CommonContainer{ |
|
53 |
- ID: "container_id", |
|
54 |
- Name: "container_name", |
|
55 |
- Config: &containertypes.Config{ |
|
56 |
- Labels: map[string]string{ |
|
57 |
- "node": "1", |
|
58 |
- "os": "alpine", |
|
59 |
- }, |
|
52 |
+ ID: "container_id", |
|
53 |
+ Name: "container_name", |
|
54 |
+ Config: &containertypes.Config{ |
|
55 |
+ Labels: map[string]string{ |
|
56 |
+ "node": "1", |
|
57 |
+ "os": "alpine", |
|
60 | 58 |
}, |
61 | 59 |
}, |
62 | 60 |
} |
... | ... |
@@ -19,17 +19,15 @@ func reset(c *container.Container) { |
19 | 19 |
|
20 | 20 |
func TestNoneHealthcheck(t *testing.T) { |
21 | 21 |
c := &container.Container{ |
22 |
- CommonContainer: container.CommonContainer{ |
|
23 |
- ID: "container_id", |
|
24 |
- Name: "container_name", |
|
25 |
- Config: &containertypes.Config{ |
|
26 |
- Image: "image_name", |
|
27 |
- Healthcheck: &containertypes.HealthConfig{ |
|
28 |
- Test: []string{"NONE"}, |
|
29 |
- }, |
|
22 |
+ ID: "container_id", |
|
23 |
+ Name: "container_name", |
|
24 |
+ Config: &containertypes.Config{ |
|
25 |
+ Image: "image_name", |
|
26 |
+ Healthcheck: &containertypes.HealthConfig{ |
|
27 |
+ Test: []string{"NONE"}, |
|
30 | 28 |
}, |
31 |
- State: &container.State{}, |
|
32 | 29 |
}, |
30 |
+ State: &container.State{}, |
|
33 | 31 |
} |
34 | 32 |
daemon := &Daemon{} |
35 | 33 |
|
... | ... |
@@ -58,12 +56,10 @@ func TestHealthStates(t *testing.T) { |
58 | 58 |
} |
59 | 59 |
|
60 | 60 |
c := &container.Container{ |
61 |
- CommonContainer: container.CommonContainer{ |
|
62 |
- ID: "container_id", |
|
63 |
- Name: "container_name", |
|
64 |
- Config: &containertypes.Config{ |
|
65 |
- Image: "image_name", |
|
66 |
- }, |
|
61 |
+ ID: "container_id", |
|
62 |
+ Name: "container_name", |
|
63 |
+ Config: &containertypes.Config{ |
|
64 |
+ Image: "image_name", |
|
67 | 65 |
}, |
68 | 66 |
} |
69 | 67 |
daemon := &Daemon{ |
... | ... |
@@ -18,70 +18,67 @@ func TestBackportMountSpec(t *testing.T) { |
18 | 18 |
d := Daemon{containers: container.NewMemoryStore()} |
19 | 19 |
|
20 | 20 |
c := &container.Container{ |
21 |
- CommonContainer: container.CommonContainer{ |
|
22 |
- State: &container.State{}, |
|
23 |
- MountPoints: map[string]*volume.MountPoint{ |
|
24 |
- "/apple": {Destination: "/apple", Source: "/var/lib/docker/volumes/12345678", Name: "12345678", RW: true, CopyData: true}, // anonymous volume |
|
25 |
- "/banana": {Destination: "/banana", Source: "/var/lib/docker/volumes/data", Name: "data", RW: true, CopyData: true}, // named volume |
|
26 |
- "/cherry": {Destination: "/cherry", Source: "/var/lib/docker/volumes/data", Name: "data", CopyData: true}, // RO named volume |
|
27 |
- "/dates": {Destination: "/dates", Source: "/var/lib/docker/volumes/data", Name: "data"}, // named volume nocopy |
|
28 |
- "/elderberry": {Destination: "/elderberry", Source: "/var/lib/docker/volumes/data", Name: "data"}, // masks anon vol |
|
29 |
- "/fig": {Destination: "/fig", Source: "/data", RW: true}, // RW bind |
|
30 |
- "/guava": {Destination: "/guava", Source: "/data", RW: false, Propagation: "shared"}, // RO bind + propagation |
|
31 |
- "/kumquat": {Destination: "/kumquat", Name: "data", RW: false, CopyData: true}, // volumes-from |
|
21 |
+ State: &container.State{}, |
|
22 |
+ MountPoints: map[string]*volume.MountPoint{ |
|
23 |
+ "/apple": {Destination: "/apple", Source: "/var/lib/docker/volumes/12345678", Name: "12345678", RW: true, CopyData: true}, // anonymous volume |
|
24 |
+ "/banana": {Destination: "/banana", Source: "/var/lib/docker/volumes/data", Name: "data", RW: true, CopyData: true}, // named volume |
|
25 |
+ "/cherry": {Destination: "/cherry", Source: "/var/lib/docker/volumes/data", Name: "data", CopyData: true}, // RO named volume |
|
26 |
+ "/dates": {Destination: "/dates", Source: "/var/lib/docker/volumes/data", Name: "data"}, // named volume nocopy |
|
27 |
+ "/elderberry": {Destination: "/elderberry", Source: "/var/lib/docker/volumes/data", Name: "data"}, // masks anon vol |
|
28 |
+ "/fig": {Destination: "/fig", Source: "/data", RW: true}, // RW bind |
|
29 |
+ "/guava": {Destination: "/guava", Source: "/data", RW: false, Propagation: "shared"}, // RO bind + propagation |
|
30 |
+ "/kumquat": {Destination: "/kumquat", Name: "data", RW: false, CopyData: true}, // volumes-from |
|
32 | 31 |
|
33 |
- // partially configured mountpoint due to #32613 |
|
34 |
- // specifically, `mp.Spec.Source` is not set |
|
35 |
- "/honeydew": { |
|
36 |
- Type: mounttypes.TypeVolume, |
|
37 |
- Destination: "/honeydew", |
|
38 |
- Name: "data", |
|
39 |
- Source: "/var/lib/docker/volumes/data", |
|
40 |
- Spec: mounttypes.Mount{Type: mounttypes.TypeVolume, Target: "/honeydew", VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true}}, |
|
41 |
- }, |
|
32 |
+ // partially configured mountpoint due to #32613 |
|
33 |
+ // specifically, `mp.Spec.Source` is not set |
|
34 |
+ "/honeydew": { |
|
35 |
+ Type: mounttypes.TypeVolume, |
|
36 |
+ Destination: "/honeydew", |
|
37 |
+ Name: "data", |
|
38 |
+ Source: "/var/lib/docker/volumes/data", |
|
39 |
+ Spec: mounttypes.Mount{Type: mounttypes.TypeVolume, Target: "/honeydew", VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true}}, |
|
40 |
+ }, |
|
42 | 41 |
|
43 |
- // from hostconfig.Mounts |
|
44 |
- "/jambolan": { |
|
45 |
- Type: mounttypes.TypeVolume, |
|
46 |
- Destination: "/jambolan", |
|
47 |
- Source: "/var/lib/docker/volumes/data", |
|
48 |
- RW: true, |
|
49 |
- Name: "data", |
|
50 |
- Spec: mounttypes.Mount{Type: mounttypes.TypeVolume, Target: "/jambolan", Source: "data"}, |
|
51 |
- }, |
|
42 |
+ // from hostconfig.Mounts |
|
43 |
+ "/jambolan": { |
|
44 |
+ Type: mounttypes.TypeVolume, |
|
45 |
+ Destination: "/jambolan", |
|
46 |
+ Source: "/var/lib/docker/volumes/data", |
|
47 |
+ RW: true, |
|
48 |
+ Name: "data", |
|
49 |
+ Spec: mounttypes.Mount{Type: mounttypes.TypeVolume, Target: "/jambolan", Source: "data"}, |
|
52 | 50 |
}, |
53 |
- HostConfig: &containertypes.HostConfig{ |
|
54 |
- Binds: []string{ |
|
55 |
- "data:/banana", |
|
56 |
- "data:/cherry:ro", |
|
57 |
- "data:/dates:ro,nocopy", |
|
58 |
- "data:/elderberry:ro,nocopy", |
|
59 |
- "/data:/fig", |
|
60 |
- "/data:/guava:ro,shared", |
|
61 |
- "data:/honeydew:nocopy", |
|
62 |
- }, |
|
63 |
- VolumesFrom: []string{"1:ro"}, |
|
64 |
- Mounts: []mounttypes.Mount{ |
|
65 |
- {Type: mounttypes.TypeVolume, Target: "/jambolan"}, |
|
66 |
- }, |
|
51 |
+ }, |
|
52 |
+ HostConfig: &containertypes.HostConfig{ |
|
53 |
+ Binds: []string{ |
|
54 |
+ "data:/banana", |
|
55 |
+ "data:/cherry:ro", |
|
56 |
+ "data:/dates:ro,nocopy", |
|
57 |
+ "data:/elderberry:ro,nocopy", |
|
58 |
+ "/data:/fig", |
|
59 |
+ "/data:/guava:ro,shared", |
|
60 |
+ "data:/honeydew:nocopy", |
|
61 |
+ }, |
|
62 |
+ VolumesFrom: []string{"1:ro"}, |
|
63 |
+ Mounts: []mounttypes.Mount{ |
|
64 |
+ {Type: mounttypes.TypeVolume, Target: "/jambolan"}, |
|
67 | 65 |
}, |
68 |
- Config: &containertypes.Config{Volumes: map[string]struct{}{ |
|
69 |
- "/apple": {}, |
|
70 |
- "/elderberry": {}, |
|
71 |
- }}, |
|
72 |
- }} |
|
66 |
+ }, |
|
67 |
+ Config: &containertypes.Config{Volumes: map[string]struct{}{ |
|
68 |
+ "/apple": {}, |
|
69 |
+ "/elderberry": {}, |
|
70 |
+ }}, |
|
71 |
+ } |
|
73 | 72 |
|
74 | 73 |
d.containers.Add("1", &container.Container{ |
75 |
- CommonContainer: container.CommonContainer{ |
|
76 |
- State: &container.State{}, |
|
77 |
- ID: "1", |
|
78 |
- MountPoints: map[string]*volume.MountPoint{ |
|
79 |
- "/kumquat": {Destination: "/kumquat", Name: "data", RW: false, CopyData: true}, |
|
80 |
- }, |
|
81 |
- HostConfig: &containertypes.HostConfig{ |
|
82 |
- Binds: []string{ |
|
83 |
- "data:/kumquat:ro", |
|
84 |
- }, |
|
74 |
+ State: &container.State{}, |
|
75 |
+ ID: "1", |
|
76 |
+ MountPoints: map[string]*volume.MountPoint{ |
|
77 |
+ "/kumquat": {Destination: "/kumquat", Name: "data", RW: false, CopyData: true}, |
|
78 |
+ }, |
|
79 |
+ HostConfig: &containertypes.HostConfig{ |
|
80 |
+ Binds: []string{ |
|
81 |
+ "data:/kumquat:ro", |
|
85 | 82 |
}, |
86 | 83 |
}, |
87 | 84 |
}) |