Browse code

Move some container related methods and structs to smaller files

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2016/05/25 00:49:26
Showing 7 changed files
... ...
@@ -11,5 +11,5 @@ func (daemon *Daemon) ContainerChanges(name string) ([]archive.Change, error) {
11 11
 
12 12
 	container.Lock()
13 13
 	defer container.Unlock()
14
-	return daemon.changes(container)
14
+	return container.RWLayer.Changes()
15 15
 }
16 16
new file mode 100644
... ...
@@ -0,0 +1,145 @@
0
+package daemon
1
+
2
+import (
3
+	"fmt"
4
+	"path/filepath"
5
+	"time"
6
+
7
+	"github.com/docker/docker/container"
8
+	"github.com/docker/docker/daemon/network"
9
+	"github.com/docker/docker/errors"
10
+	"github.com/docker/docker/image"
11
+	"github.com/docker/docker/pkg/truncindex"
12
+	containertypes "github.com/docker/engine-api/types/container"
13
+)
14
+
15
+// GetContainer looks for a container using the provided information, which could be
16
+// one of the following inputs from the caller:
17
+//  - A full container ID, which will exact match a container in daemon's list
18
+//  - A container name, which will only exact match via the GetByName() function
19
+//  - A partial container ID prefix (e.g. short ID) of any length that is
20
+//    unique enough to only return a single container object
21
+//  If none of these searches succeed, an error is returned
22
+func (daemon *Daemon) GetContainer(prefixOrName string) (*container.Container, error) {
23
+	if len(prefixOrName) == 0 {
24
+		return nil, errors.NewBadRequestError(fmt.Errorf("No container name or ID supplied"))
25
+	}
26
+
27
+	if containerByID := daemon.containers.Get(prefixOrName); containerByID != nil {
28
+		// prefix is an exact match to a full container ID
29
+		return containerByID, nil
30
+	}
31
+
32
+	// GetByName will match only an exact name provided; we ignore errors
33
+	if containerByName, _ := daemon.GetByName(prefixOrName); containerByName != nil {
34
+		// prefix is an exact match to a full container Name
35
+		return containerByName, nil
36
+	}
37
+
38
+	containerID, indexError := daemon.idIndex.Get(prefixOrName)
39
+	if indexError != nil {
40
+		// When truncindex defines an error type, use that instead
41
+		if indexError == truncindex.ErrNotExist {
42
+			err := fmt.Errorf("No such container: %s", prefixOrName)
43
+			return nil, errors.NewRequestNotFoundError(err)
44
+		}
45
+		return nil, indexError
46
+	}
47
+	return daemon.containers.Get(containerID), nil
48
+}
49
+
50
+// Exists returns a true if a container of the specified ID or name exists,
51
+// false otherwise.
52
+func (daemon *Daemon) Exists(id string) bool {
53
+	c, _ := daemon.GetContainer(id)
54
+	return c != nil
55
+}
56
+
57
+// IsPaused returns a bool indicating if the specified container is paused.
58
+func (daemon *Daemon) IsPaused(id string) bool {
59
+	c, _ := daemon.GetContainer(id)
60
+	return c.State.IsPaused()
61
+}
62
+
63
+func (daemon *Daemon) containerRoot(id string) string {
64
+	return filepath.Join(daemon.repository, id)
65
+}
66
+
67
+// Load reads the contents of a container from disk
68
+// This is typically done at startup.
69
+func (daemon *Daemon) load(id string) (*container.Container, error) {
70
+	container := daemon.newBaseContainer(id)
71
+
72
+	if err := container.FromDisk(); err != nil {
73
+		return nil, err
74
+	}
75
+
76
+	if container.ID != id {
77
+		return container, fmt.Errorf("Container %s is stored at %s", container.ID, id)
78
+	}
79
+
80
+	return container, nil
81
+}
82
+
83
+// Register makes a container object usable by the daemon as <container.ID>
84
+func (daemon *Daemon) Register(c *container.Container) error {
85
+	// Attach to stdout and stderr
86
+	if c.Config.OpenStdin {
87
+		c.NewInputPipes()
88
+	} else {
89
+		c.NewNopInputPipe()
90
+	}
91
+
92
+	daemon.containers.Add(c.ID, c)
93
+	daemon.idIndex.Add(c.ID)
94
+
95
+	return nil
96
+}
97
+
98
+func (daemon *Daemon) newContainer(name string, config *containertypes.Config, imgID image.ID) (*container.Container, error) {
99
+	var (
100
+		id             string
101
+		err            error
102
+		noExplicitName = name == ""
103
+	)
104
+	id, name, err = daemon.generateIDAndName(name)
105
+	if err != nil {
106
+		return nil, err
107
+	}
108
+
109
+	daemon.generateHostname(id, config)
110
+	entrypoint, args := daemon.getEntrypointAndArgs(config.Entrypoint, config.Cmd)
111
+
112
+	base := daemon.newBaseContainer(id)
113
+	base.Created = time.Now().UTC()
114
+	base.Path = entrypoint
115
+	base.Args = args //FIXME: de-duplicate from config
116
+	base.Config = config
117
+	base.HostConfig = &containertypes.HostConfig{}
118
+	base.ImageID = imgID
119
+	base.NetworkSettings = &network.Settings{IsAnonymousEndpoint: noExplicitName}
120
+	base.Name = name
121
+	base.Driver = daemon.GraphDriverName()
122
+
123
+	return base, err
124
+}
125
+
126
+// GetByName returns a container given a name.
127
+func (daemon *Daemon) GetByName(name string) (*container.Container, error) {
128
+	if len(name) == 0 {
129
+		return nil, fmt.Errorf("No container name supplied")
130
+	}
131
+	fullName := name
132
+	if name[0] != '/' {
133
+		fullName = "/" + name
134
+	}
135
+	id, err := daemon.nameIndex.Get(fullName)
136
+	if err != nil {
137
+		return nil, fmt.Errorf("Could not find entity for %s", name)
138
+	}
139
+	e := daemon.containers.Get(id)
140
+	if e == nil {
141
+		return nil, fmt.Errorf("Could not find container for entity id %s", id)
142
+	}
143
+	return e, nil
144
+}
... ...
@@ -218,3 +218,15 @@ func (daemon *Daemon) VolumeCreate(name, driverName string, opts, labels map[str
218 218
 	apiV.Mountpoint = v.Path()
219 219
 	return apiV, nil
220 220
 }
221
+
222
+func (daemon *Daemon) mergeAndVerifyConfig(config *containertypes.Config, img *image.Image) error {
223
+	if img != nil && img.Config != nil {
224
+		if err := merge(config, img.Config); err != nil {
225
+			return err
226
+		}
227
+	}
228
+	if len(config.Entrypoint) == 0 && len(config.Cmd) == 0 {
229
+		return fmt.Errorf("No command specified")
230
+	}
231
+	return nil
232
+}
... ...
@@ -36,7 +36,6 @@ import (
36 36
 	"github.com/docker/engine-api/types/strslice"
37 37
 	// register graph drivers
38 38
 	_ "github.com/docker/docker/daemon/graphdriver/register"
39
-	"github.com/docker/docker/daemon/network"
40 39
 	dmetadata "github.com/docker/docker/distribution/metadata"
41 40
 	"github.com/docker/docker/distribution/xfer"
42 41
 	"github.com/docker/docker/dockerversion"
... ...
@@ -44,16 +43,13 @@ import (
44 44
 	"github.com/docker/docker/layer"
45 45
 	"github.com/docker/docker/libcontainerd"
46 46
 	"github.com/docker/docker/migrate/v1"
47
-	"github.com/docker/docker/pkg/archive"
48 47
 	"github.com/docker/docker/pkg/fileutils"
49 48
 	"github.com/docker/docker/pkg/graphdb"
50 49
 	"github.com/docker/docker/pkg/idtools"
51
-	"github.com/docker/docker/pkg/namesgenerator"
52 50
 	"github.com/docker/docker/pkg/progress"
53 51
 	"github.com/docker/docker/pkg/registrar"
54 52
 	"github.com/docker/docker/pkg/signal"
55 53
 	"github.com/docker/docker/pkg/streamformatter"
56
-	"github.com/docker/docker/pkg/stringid"
57 54
 	"github.com/docker/docker/pkg/sysinfo"
58 55
 	"github.com/docker/docker/pkg/system"
59 56
 	"github.com/docker/docker/pkg/truncindex"
... ...
@@ -73,9 +69,6 @@ import (
73 73
 )
74 74
 
75 75
 var (
76
-	validContainerNameChars   = utils.RestrictedNameChars
77
-	validContainerNamePattern = utils.RestrictedNamePattern
78
-
79 76
 	errSystemNotSupported = fmt.Errorf("The Docker daemon is not supported on this platform.")
80 77
 )
81 78
 
... ...
@@ -112,110 +105,6 @@ type Daemon struct {
112 112
 	defaultIsolation          containertypes.Isolation // Default isolation mode on Windows
113 113
 }
114 114
 
115
-// GetContainer looks for a container using the provided information, which could be
116
-// one of the following inputs from the caller:
117
-//  - A full container ID, which will exact match a container in daemon's list
118
-//  - A container name, which will only exact match via the GetByName() function
119
-//  - A partial container ID prefix (e.g. short ID) of any length that is
120
-//    unique enough to only return a single container object
121
-//  If none of these searches succeed, an error is returned
122
-func (daemon *Daemon) GetContainer(prefixOrName string) (*container.Container, error) {
123
-	if len(prefixOrName) == 0 {
124
-		return nil, errors.NewBadRequestError(fmt.Errorf("No container name or ID supplied"))
125
-	}
126
-
127
-	if containerByID := daemon.containers.Get(prefixOrName); containerByID != nil {
128
-		// prefix is an exact match to a full container ID
129
-		return containerByID, nil
130
-	}
131
-
132
-	// GetByName will match only an exact name provided; we ignore errors
133
-	if containerByName, _ := daemon.GetByName(prefixOrName); containerByName != nil {
134
-		// prefix is an exact match to a full container Name
135
-		return containerByName, nil
136
-	}
137
-
138
-	containerID, indexError := daemon.idIndex.Get(prefixOrName)
139
-	if indexError != nil {
140
-		// When truncindex defines an error type, use that instead
141
-		if indexError == truncindex.ErrNotExist {
142
-			err := fmt.Errorf("No such container: %s", prefixOrName)
143
-			return nil, errors.NewRequestNotFoundError(err)
144
-		}
145
-		return nil, indexError
146
-	}
147
-	return daemon.containers.Get(containerID), nil
148
-}
149
-
150
-// Exists returns a true if a container of the specified ID or name exists,
151
-// false otherwise.
152
-func (daemon *Daemon) Exists(id string) bool {
153
-	c, _ := daemon.GetContainer(id)
154
-	return c != nil
155
-}
156
-
157
-// IsPaused returns a bool indicating if the specified container is paused.
158
-func (daemon *Daemon) IsPaused(id string) bool {
159
-	c, _ := daemon.GetContainer(id)
160
-	return c.State.IsPaused()
161
-}
162
-
163
-func (daemon *Daemon) containerRoot(id string) string {
164
-	return filepath.Join(daemon.repository, id)
165
-}
166
-
167
-// Load reads the contents of a container from disk
168
-// This is typically done at startup.
169
-func (daemon *Daemon) load(id string) (*container.Container, error) {
170
-	container := daemon.newBaseContainer(id)
171
-
172
-	if err := container.FromDisk(); err != nil {
173
-		return nil, err
174
-	}
175
-
176
-	if container.ID != id {
177
-		return container, fmt.Errorf("Container %s is stored at %s", container.ID, id)
178
-	}
179
-
180
-	return container, nil
181
-}
182
-
183
-func (daemon *Daemon) registerName(container *container.Container) error {
184
-	if daemon.Exists(container.ID) {
185
-		return fmt.Errorf("Container is already loaded")
186
-	}
187
-	if err := validateID(container.ID); err != nil {
188
-		return err
189
-	}
190
-	if container.Name == "" {
191
-		name, err := daemon.generateNewName(container.ID)
192
-		if err != nil {
193
-			return err
194
-		}
195
-		container.Name = name
196
-
197
-		if err := container.ToDiskLocking(); err != nil {
198
-			logrus.Errorf("Error saving container name to disk: %v", err)
199
-		}
200
-	}
201
-	return daemon.nameIndex.Reserve(container.Name, container.ID)
202
-}
203
-
204
-// Register makes a container object usable by the daemon as <container.ID>
205
-func (daemon *Daemon) Register(c *container.Container) error {
206
-	// Attach to stdout and stderr
207
-	if c.Config.OpenStdin {
208
-		c.NewInputPipes()
209
-	} else {
210
-		c.NewNopInputPipe()
211
-	}
212
-
213
-	daemon.containers.Add(c.ID, c)
214
-	daemon.idIndex.Add(c.ID)
215
-
216
-	return nil
217
-}
218
-
219 115
 func (daemon *Daemon) restore() error {
220 116
 	var (
221 117
 		debug         = utils.IsDebugEnabled()
... ...
@@ -431,88 +320,6 @@ func (daemon *Daemon) waitForNetworks(c *container.Container) {
431 431
 	}
432 432
 }
433 433
 
434
-func (daemon *Daemon) mergeAndVerifyConfig(config *containertypes.Config, img *image.Image) error {
435
-	if img != nil && img.Config != nil {
436
-		if err := merge(config, img.Config); err != nil {
437
-			return err
438
-		}
439
-	}
440
-	if len(config.Entrypoint) == 0 && len(config.Cmd) == 0 {
441
-		return fmt.Errorf("No command specified")
442
-	}
443
-	return nil
444
-}
445
-
446
-func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
447
-	var (
448
-		err error
449
-		id  = stringid.GenerateNonCryptoID()
450
-	)
451
-
452
-	if name == "" {
453
-		if name, err = daemon.generateNewName(id); err != nil {
454
-			return "", "", err
455
-		}
456
-		return id, name, nil
457
-	}
458
-
459
-	if name, err = daemon.reserveName(id, name); err != nil {
460
-		return "", "", err
461
-	}
462
-
463
-	return id, name, nil
464
-}
465
-
466
-func (daemon *Daemon) reserveName(id, name string) (string, error) {
467
-	if !validContainerNamePattern.MatchString(name) {
468
-		return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)
469
-	}
470
-	if name[0] != '/' {
471
-		name = "/" + name
472
-	}
473
-
474
-	if err := daemon.nameIndex.Reserve(name, id); err != nil {
475
-		if err == registrar.ErrNameReserved {
476
-			id, err := daemon.nameIndex.Get(name)
477
-			if err != nil {
478
-				logrus.Errorf("got unexpected error while looking up reserved name: %v", err)
479
-				return "", err
480
-			}
481
-			return "", fmt.Errorf("Conflict. The name %q is already in use by container %s. You have to remove (or rename) that container to be able to reuse that name.", name, id)
482
-		}
483
-		return "", fmt.Errorf("error reserving name: %s, error: %v", name, err)
484
-	}
485
-	return name, nil
486
-}
487
-
488
-func (daemon *Daemon) releaseName(name string) {
489
-	daemon.nameIndex.Release(name)
490
-}
491
-
492
-func (daemon *Daemon) generateNewName(id string) (string, error) {
493
-	var name string
494
-	for i := 0; i < 6; i++ {
495
-		name = namesgenerator.GetRandomName(i)
496
-		if name[0] != '/' {
497
-			name = "/" + name
498
-		}
499
-
500
-		if err := daemon.nameIndex.Reserve(name, id); err != nil {
501
-			if err == registrar.ErrNameReserved {
502
-				continue
503
-			}
504
-			return "", err
505
-		}
506
-		return name, nil
507
-	}
508
-
509
-	name = "/" + stringid.TruncateID(id)
510
-	if err := daemon.nameIndex.Reserve(name, id); err != nil {
511
-		return "", err
512
-	}
513
-	return name, nil
514
-}
515
-
516 434
 func (daemon *Daemon) generateHostname(id string, config *containertypes.Config) {
517 435
 	// Generate default hostname
518 436
 	if config.Hostname == "" {
... ...
@@ -527,54 +334,6 @@ func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint strslice.StrSlice, c
527 527
 	return configCmd[0], configCmd[1:]
528 528
 }
529 529
 
530
-func (daemon *Daemon) newContainer(name string, config *containertypes.Config, imgID image.ID) (*container.Container, error) {
531
-	var (
532
-		id             string
533
-		err            error
534
-		noExplicitName = name == ""
535
-	)
536
-	id, name, err = daemon.generateIDAndName(name)
537
-	if err != nil {
538
-		return nil, err
539
-	}
540
-
541
-	daemon.generateHostname(id, config)
542
-	entrypoint, args := daemon.getEntrypointAndArgs(config.Entrypoint, config.Cmd)
543
-
544
-	base := daemon.newBaseContainer(id)
545
-	base.Created = time.Now().UTC()
546
-	base.Path = entrypoint
547
-	base.Args = args //FIXME: de-duplicate from config
548
-	base.Config = config
549
-	base.HostConfig = &containertypes.HostConfig{}
550
-	base.ImageID = imgID
551
-	base.NetworkSettings = &network.Settings{IsAnonymousEndpoint: noExplicitName}
552
-	base.Name = name
553
-	base.Driver = daemon.GraphDriverName()
554
-
555
-	return base, err
556
-}
557
-
558
-// GetByName returns a container given a name.
559
-func (daemon *Daemon) GetByName(name string) (*container.Container, error) {
560
-	if len(name) == 0 {
561
-		return nil, fmt.Errorf("No container name supplied")
562
-	}
563
-	fullName := name
564
-	if name[0] != '/' {
565
-		fullName = "/" + name
566
-	}
567
-	id, err := daemon.nameIndex.Get(fullName)
568
-	if err != nil {
569
-		return nil, fmt.Errorf("Could not find entity for %s", name)
570
-	}
571
-	e := daemon.containers.Get(id)
572
-	if e == nil {
573
-		return nil, fmt.Errorf("Could not find container for entity id %s", id)
574
-	}
575
-	return e, nil
576
-}
577
-
578 530
 // GetLabels for a container or image id
579 531
 func (daemon *Daemon) GetLabels(id string) map[string]string {
580 532
 	// TODO: TestCase
... ...
@@ -947,22 +706,6 @@ func (daemon *Daemon) Unmount(container *container.Container) error {
947 947
 	return nil
948 948
 }
949 949
 
950
-func (daemon *Daemon) kill(c *container.Container, sig int) error {
951
-	return daemon.containerd.Signal(c.ID, sig)
952
-}
953
-
954
-func (daemon *Daemon) subscribeToContainerStats(c *container.Container) chan interface{} {
955
-	return daemon.statsCollector.collect(c)
956
-}
957
-
958
-func (daemon *Daemon) unsubscribeToContainerStats(c *container.Container, ch chan interface{}) {
959
-	daemon.statsCollector.unsubscribe(c, ch)
960
-}
961
-
962
-func (daemon *Daemon) changes(container *container.Container) ([]archive.Change, error) {
963
-	return container.RWLayer.Changes()
964
-}
965
-
966 950
 func writeDistributionProgress(cancelFunc func(), outStream io.Writer, progressChan <-chan progress.Progress) {
967 951
 	progressOutput := streamformatter.NewJSONStreamFormatter().NewProgressOutput(outStream, false)
968 952
 	operationCancelled := false
... ...
@@ -151,3 +151,7 @@ func (daemon *Daemon) killPossiblyDeadProcess(container *container.Container, si
151 151
 	}
152 152
 	return err
153 153
 }
154
+
155
+func (daemon *Daemon) kill(c *container.Container, sig int) error {
156
+	return daemon.containerd.Signal(c.ID, sig)
157
+}
154 158
new file mode 100644
... ...
@@ -0,0 +1,108 @@
0
+package daemon
1
+
2
+import (
3
+	"fmt"
4
+
5
+	"github.com/Sirupsen/logrus"
6
+	"github.com/docker/docker/container"
7
+	"github.com/docker/docker/pkg/namesgenerator"
8
+	"github.com/docker/docker/pkg/registrar"
9
+	"github.com/docker/docker/pkg/stringid"
10
+	"github.com/docker/docker/utils"
11
+)
12
+
13
+var (
14
+	validContainerNameChars   = utils.RestrictedNameChars
15
+	validContainerNamePattern = utils.RestrictedNamePattern
16
+)
17
+
18
+func (daemon *Daemon) registerName(container *container.Container) error {
19
+	if daemon.Exists(container.ID) {
20
+		return fmt.Errorf("Container is already loaded")
21
+	}
22
+	if err := validateID(container.ID); err != nil {
23
+		return err
24
+	}
25
+	if container.Name == "" {
26
+		name, err := daemon.generateNewName(container.ID)
27
+		if err != nil {
28
+			return err
29
+		}
30
+		container.Name = name
31
+
32
+		if err := container.ToDiskLocking(); err != nil {
33
+			logrus.Errorf("Error saving container name to disk: %v", err)
34
+		}
35
+	}
36
+	return daemon.nameIndex.Reserve(container.Name, container.ID)
37
+}
38
+
39
+func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
40
+	var (
41
+		err error
42
+		id  = stringid.GenerateNonCryptoID()
43
+	)
44
+
45
+	if name == "" {
46
+		if name, err = daemon.generateNewName(id); err != nil {
47
+			return "", "", err
48
+		}
49
+		return id, name, nil
50
+	}
51
+
52
+	if name, err = daemon.reserveName(id, name); err != nil {
53
+		return "", "", err
54
+	}
55
+
56
+	return id, name, nil
57
+}
58
+
59
+func (daemon *Daemon) reserveName(id, name string) (string, error) {
60
+	if !validContainerNamePattern.MatchString(name) {
61
+		return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)
62
+	}
63
+	if name[0] != '/' {
64
+		name = "/" + name
65
+	}
66
+
67
+	if err := daemon.nameIndex.Reserve(name, id); err != nil {
68
+		if err == registrar.ErrNameReserved {
69
+			id, err := daemon.nameIndex.Get(name)
70
+			if err != nil {
71
+				logrus.Errorf("got unexpected error while looking up reserved name: %v", err)
72
+				return "", err
73
+			}
74
+			return "", fmt.Errorf("Conflict. The name %q is already in use by container %s. You have to remove (or rename) that container to be able to reuse that name.", name, id)
75
+		}
76
+		return "", fmt.Errorf("error reserving name: %s, error: %v", name, err)
77
+	}
78
+	return name, nil
79
+}
80
+
81
+func (daemon *Daemon) releaseName(name string) {
82
+	daemon.nameIndex.Release(name)
83
+}
84
+
85
+func (daemon *Daemon) generateNewName(id string) (string, error) {
86
+	var name string
87
+	for i := 0; i < 6; i++ {
88
+		name = namesgenerator.GetRandomName(i)
89
+		if name[0] != '/' {
90
+			name = "/" + name
91
+		}
92
+
93
+		if err := daemon.nameIndex.Reserve(name, id); err != nil {
94
+			if err == registrar.ErrNameReserved {
95
+				continue
96
+			}
97
+			return "", err
98
+		}
99
+		return name, nil
100
+	}
101
+
102
+	name = "/" + stringid.TruncateID(id)
103
+	if err := daemon.nameIndex.Reserve(name, id); err != nil {
104
+		return "", err
105
+	}
106
+	return name, nil
107
+}
... ...
@@ -8,6 +8,7 @@ import (
8 8
 	"golang.org/x/net/context"
9 9
 
10 10
 	"github.com/docker/docker/api/types/backend"
11
+	"github.com/docker/docker/container"
11 12
 	"github.com/docker/docker/pkg/ioutils"
12 13
 	"github.com/docker/engine-api/types"
13 14
 	"github.com/docker/engine-api/types/versions"
... ...
@@ -121,3 +122,11 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c
121 121
 		}
122 122
 	}
123 123
 }
124
+
125
+func (daemon *Daemon) subscribeToContainerStats(c *container.Container) chan interface{} {
126
+	return daemon.statsCollector.collect(c)
127
+}
128
+
129
+func (daemon *Daemon) unsubscribeToContainerStats(c *container.Container, ch chan interface{}) {
130
+	daemon.statsCollector.unsubscribe(c, ch)
131
+}