Browse code

Moving some more methods away from daemon.go

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

Vincent Demeester authored on 2016/05/27 18:32:26
Showing 6 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,13 @@
0
+package daemon
1
+
2
+import (
3
+	"golang.org/x/net/context"
4
+
5
+	"github.com/docker/docker/dockerversion"
6
+	"github.com/docker/engine-api/types"
7
+)
8
+
9
+// AuthenticateToRegistry checks the validity of credentials in authConfig
10
+func (daemon *Daemon) AuthenticateToRegistry(ctx context.Context, authConfig *types.AuthConfig) (string, string, error) {
11
+	return daemon.RegistryService.Auth(ctx, authConfig, dockerversion.DockerUserAgent(ctx))
12
+}
... ...
@@ -3,14 +3,19 @@ package daemon
3 3
 import (
4 4
 	"fmt"
5 5
 	"path/filepath"
6
+	"regexp"
6 7
 	"time"
7 8
 
8 9
 	"github.com/docker/docker/container"
9 10
 	"github.com/docker/docker/daemon/network"
10 11
 	"github.com/docker/docker/errors"
11 12
 	"github.com/docker/docker/image"
13
+	"github.com/docker/docker/pkg/signal"
14
+	"github.com/docker/docker/pkg/system"
12 15
 	"github.com/docker/docker/pkg/truncindex"
13 16
 	containertypes "github.com/docker/engine-api/types/container"
17
+	"github.com/docker/engine-api/types/strslice"
18
+	"github.com/docker/go-connections/nat"
14 19
 )
15 20
 
16 21
 // GetContainer looks for a container using the provided information, which could be
... ...
@@ -143,3 +148,108 @@ func (daemon *Daemon) GetByName(name string) (*container.Container, error) {
143 143
 	}
144 144
 	return e, nil
145 145
 }
146
+
147
+// newBaseContainer creates a new container with its initial
148
+// configuration based on the root storage from the daemon.
149
+func (daemon *Daemon) newBaseContainer(id string) *container.Container {
150
+	return container.NewBaseContainer(id, daemon.containerRoot(id))
151
+}
152
+
153
+func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint strslice.StrSlice, configCmd strslice.StrSlice) (string, []string) {
154
+	if len(configEntrypoint) != 0 {
155
+		return configEntrypoint[0], append(configEntrypoint[1:], configCmd...)
156
+	}
157
+	return configCmd[0], configCmd[1:]
158
+}
159
+
160
+func (daemon *Daemon) generateHostname(id string, config *containertypes.Config) {
161
+	// Generate default hostname
162
+	if config.Hostname == "" {
163
+		config.Hostname = id[:12]
164
+	}
165
+}
166
+
167
+func (daemon *Daemon) setSecurityOptions(container *container.Container, hostConfig *containertypes.HostConfig) error {
168
+	container.Lock()
169
+	defer container.Unlock()
170
+	return parseSecurityOpt(container, hostConfig)
171
+}
172
+
173
+func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig *containertypes.HostConfig) error {
174
+	// Do not lock while creating volumes since this could be calling out to external plugins
175
+	// Don't want to block other actions, like `docker ps` because we're waiting on an external plugin
176
+	if err := daemon.registerMountPoints(container, hostConfig); err != nil {
177
+		return err
178
+	}
179
+
180
+	container.Lock()
181
+	defer container.Unlock()
182
+
183
+	// Register any links from the host config before starting the container
184
+	if err := daemon.registerLinks(container, hostConfig); err != nil {
185
+		return err
186
+	}
187
+
188
+	// make sure links is not nil
189
+	// this ensures that on the next daemon restart we don't try to migrate from legacy sqlite links
190
+	if hostConfig.Links == nil {
191
+		hostConfig.Links = []string{}
192
+	}
193
+
194
+	container.HostConfig = hostConfig
195
+	return container.ToDisk()
196
+}
197
+
198
+// verifyContainerSettings performs validation of the hostconfig and config
199
+// structures.
200
+func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
201
+
202
+	// First perform verification of settings common across all platforms.
203
+	if config != nil {
204
+		if config.WorkingDir != "" {
205
+			config.WorkingDir = filepath.FromSlash(config.WorkingDir) // Ensure in platform semantics
206
+			if !system.IsAbs(config.WorkingDir) {
207
+				return nil, fmt.Errorf("The working directory '%s' is invalid. It needs to be an absolute path", config.WorkingDir)
208
+			}
209
+		}
210
+
211
+		if len(config.StopSignal) > 0 {
212
+			_, err := signal.ParseSignal(config.StopSignal)
213
+			if err != nil {
214
+				return nil, err
215
+			}
216
+		}
217
+
218
+		// Validate if the given hostname is RFC 1123 (https://tools.ietf.org/html/rfc1123) compliant.
219
+		if len(config.Hostname) > 0 {
220
+			// RFC1123 specifies that 63 bytes is the maximium length
221
+			// Windows has the limitation of 63 bytes in length
222
+			// Linux hostname is limited to HOST_NAME_MAX=64, not not including the terminating null byte.
223
+			// We limit the length to 63 bytes here to match RFC1035 and RFC1123.
224
+			matched, _ := regexp.MatchString("^(([[:alnum:]]|[[:alnum:]][[:alnum:]\\-]*[[:alnum:]])\\.)*([[:alnum:]]|[[:alnum:]][[:alnum:]\\-]*[[:alnum:]])$", config.Hostname)
225
+			if len(config.Hostname) > 63 || !matched {
226
+				return nil, fmt.Errorf("invalid hostname format: %s", config.Hostname)
227
+			}
228
+		}
229
+	}
230
+
231
+	if hostConfig == nil {
232
+		return nil, nil
233
+	}
234
+
235
+	for port := range hostConfig.PortBindings {
236
+		_, portStr := nat.SplitProtoPort(string(port))
237
+		if _, err := nat.ParsePort(portStr); err != nil {
238
+			return nil, fmt.Errorf("Invalid port specification: %q", portStr)
239
+		}
240
+		for _, pb := range hostConfig.PortBindings[port] {
241
+			_, err := nat.NewPort(nat.SplitProtoPort(pb.HostPort))
242
+			if err != nil {
243
+				return nil, fmt.Errorf("Invalid port specification: %q", pb.HostPort)
244
+			}
245
+		}
246
+	}
247
+
248
+	// Now do platform-specific verification
249
+	return verifyPlatformContainerSettings(daemon, hostConfig, config, update)
250
+}
... ...
@@ -2,9 +2,11 @@ package daemon
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"strings"
5 6
 
6 7
 	"github.com/Sirupsen/logrus"
7 8
 	"github.com/docker/docker/container"
9
+	"github.com/docker/docker/errors"
8 10
 	"github.com/docker/docker/image"
9 11
 	"github.com/docker/docker/layer"
10 12
 	"github.com/docker/docker/pkg/idtools"
... ...
@@ -234,3 +236,16 @@ func (daemon *Daemon) mergeAndVerifyConfig(config *containertypes.Config, img *i
234 234
 	}
235 235
 	return nil
236 236
 }
237
+
238
+// Checks if the client set configurations for more than one network while creating a container
239
+func (daemon *Daemon) verifyNetworkingConfig(nwConfig *networktypes.NetworkingConfig) error {
240
+	if nwConfig == nil || len(nwConfig.EndpointsConfig) <= 1 {
241
+		return nil
242
+	}
243
+	l := make([]string, 0, len(nwConfig.EndpointsConfig))
244
+	for k := range nwConfig.EndpointsConfig {
245
+		l = append(l, k)
246
+	}
247
+	err := fmt.Errorf("Container cannot be connected to network endpoints: %s", strings.Join(l, ", "))
248
+	return errors.NewBadRequestError(err)
249
+}
... ...
@@ -14,7 +14,6 @@ import (
14 14
 	"os"
15 15
 	"path"
16 16
 	"path/filepath"
17
-	"regexp"
18 17
 	"runtime"
19 18
 	"strings"
20 19
 	"sync"
... ...
@@ -27,16 +26,12 @@ import (
27 27
 	"github.com/docker/docker/container"
28 28
 	"github.com/docker/docker/daemon/events"
29 29
 	"github.com/docker/docker/daemon/exec"
30
-	"github.com/docker/docker/errors"
31 30
 	"github.com/docker/engine-api/types"
32 31
 	containertypes "github.com/docker/engine-api/types/container"
33
-	networktypes "github.com/docker/engine-api/types/network"
34
-	"github.com/docker/engine-api/types/strslice"
35 32
 	// register graph drivers
36 33
 	_ "github.com/docker/docker/daemon/graphdriver/register"
37 34
 	dmetadata "github.com/docker/docker/distribution/metadata"
38 35
 	"github.com/docker/docker/distribution/xfer"
39
-	"github.com/docker/docker/dockerversion"
40 36
 	"github.com/docker/docker/image"
41 37
 	"github.com/docker/docker/layer"
42 38
 	"github.com/docker/docker/libcontainerd"
... ...
@@ -58,11 +53,9 @@ import (
58 58
 	volumedrivers "github.com/docker/docker/volume/drivers"
59 59
 	"github.com/docker/docker/volume/local"
60 60
 	"github.com/docker/docker/volume/store"
61
-	"github.com/docker/go-connections/nat"
62 61
 	"github.com/docker/libnetwork"
63 62
 	nwconfig "github.com/docker/libnetwork/config"
64 63
 	"github.com/docker/libtrust"
65
-	"golang.org/x/net/context"
66 64
 )
67 65
 
68 66
 var (
... ...
@@ -317,35 +310,6 @@ func (daemon *Daemon) waitForNetworks(c *container.Container) {
317 317
 	}
318 318
 }
319 319
 
320
-func (daemon *Daemon) generateHostname(id string, config *containertypes.Config) {
321
-	// Generate default hostname
322
-	if config.Hostname == "" {
323
-		config.Hostname = id[:12]
324
-	}
325
-}
326
-
327
-func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint strslice.StrSlice, configCmd strslice.StrSlice) (string, []string) {
328
-	if len(configEntrypoint) != 0 {
329
-		return configEntrypoint[0], append(configEntrypoint[1:], configCmd...)
330
-	}
331
-	return configCmd[0], configCmd[1:]
332
-}
333
-
334
-// GetLabels for a container or image id
335
-func (daemon *Daemon) GetLabels(id string) map[string]string {
336
-	// TODO: TestCase
337
-	container := daemon.containers.Get(id)
338
-	if container != nil {
339
-		return container.Config.Labels
340
-	}
341
-
342
-	img, err := daemon.GetImage(id)
343
-	if err == nil {
344
-		return img.ContainerConfig.Labels
345
-	}
346
-	return nil
347
-}
348
-
349 320
 func (daemon *Daemon) children(c *container.Container) map[string]*container.Container {
350 321
 	return daemon.linkIndex.children(c)
351 322
 }
... ...
@@ -762,37 +726,6 @@ func tempDir(rootDir string, rootUID, rootGID int) (string, error) {
762 762
 	return tmpDir, idtools.MkdirAllAs(tmpDir, 0700, rootUID, rootGID)
763 763
 }
764 764
 
765
-func (daemon *Daemon) setSecurityOptions(container *container.Container, hostConfig *containertypes.HostConfig) error {
766
-	container.Lock()
767
-	defer container.Unlock()
768
-	return parseSecurityOpt(container, hostConfig)
769
-}
770
-
771
-func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig *containertypes.HostConfig) error {
772
-	// Do not lock while creating volumes since this could be calling out to external plugins
773
-	// Don't want to block other actions, like `docker ps` because we're waiting on an external plugin
774
-	if err := daemon.registerMountPoints(container, hostConfig); err != nil {
775
-		return err
776
-	}
777
-
778
-	container.Lock()
779
-	defer container.Unlock()
780
-
781
-	// Register any links from the host config before starting the container
782
-	if err := daemon.registerLinks(container, hostConfig); err != nil {
783
-		return err
784
-	}
785
-
786
-	// make sure links is not nil
787
-	// this ensures that on the next daemon restart we don't try to migrate from legacy sqlite links
788
-	if hostConfig.Links == nil {
789
-		hostConfig.Links = []string{}
790
-	}
791
-
792
-	container.HostConfig = hostConfig
793
-	return container.ToDisk()
794
-}
795
-
796 765
 func (daemon *Daemon) setupInitLayer(initPath string) error {
797 766
 	rootUID, rootGID := daemon.GetRemappedUIDGID()
798 767
 	return setupInitLayer(initPath, rootUID, rootGID)
... ...
@@ -806,73 +739,6 @@ func setDefaultMtu(config *Config) {
806 806
 	config.Mtu = defaultNetworkMtu
807 807
 }
808 808
 
809
-// verifyContainerSettings performs validation of the hostconfig and config
810
-// structures.
811
-func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
812
-
813
-	// First perform verification of settings common across all platforms.
814
-	if config != nil {
815
-		if config.WorkingDir != "" {
816
-			config.WorkingDir = filepath.FromSlash(config.WorkingDir) // Ensure in platform semantics
817
-			if !system.IsAbs(config.WorkingDir) {
818
-				return nil, fmt.Errorf("The working directory '%s' is invalid. It needs to be an absolute path", config.WorkingDir)
819
-			}
820
-		}
821
-
822
-		if len(config.StopSignal) > 0 {
823
-			_, err := signal.ParseSignal(config.StopSignal)
824
-			if err != nil {
825
-				return nil, err
826
-			}
827
-		}
828
-
829
-		// Validate if the given hostname is RFC 1123 (https://tools.ietf.org/html/rfc1123) compliant.
830
-		if len(config.Hostname) > 0 {
831
-			// RFC1123 specifies that 63 bytes is the maximium length
832
-			// Windows has the limitation of 63 bytes in length
833
-			// Linux hostname is limited to HOST_NAME_MAX=64, not not including the terminating null byte.
834
-			// We limit the length to 63 bytes here to match RFC1035 and RFC1123.
835
-			matched, _ := regexp.MatchString("^(([[:alnum:]]|[[:alnum:]][[:alnum:]\\-]*[[:alnum:]])\\.)*([[:alnum:]]|[[:alnum:]][[:alnum:]\\-]*[[:alnum:]])$", config.Hostname)
836
-			if len(config.Hostname) > 63 || !matched {
837
-				return nil, fmt.Errorf("invalid hostname format: %s", config.Hostname)
838
-			}
839
-		}
840
-	}
841
-
842
-	if hostConfig == nil {
843
-		return nil, nil
844
-	}
845
-
846
-	for port := range hostConfig.PortBindings {
847
-		_, portStr := nat.SplitProtoPort(string(port))
848
-		if _, err := nat.ParsePort(portStr); err != nil {
849
-			return nil, fmt.Errorf("Invalid port specification: %q", portStr)
850
-		}
851
-		for _, pb := range hostConfig.PortBindings[port] {
852
-			_, err := nat.NewPort(nat.SplitProtoPort(pb.HostPort))
853
-			if err != nil {
854
-				return nil, fmt.Errorf("Invalid port specification: %q", pb.HostPort)
855
-			}
856
-		}
857
-	}
858
-
859
-	// Now do platform-specific verification
860
-	return verifyPlatformContainerSettings(daemon, hostConfig, config, update)
861
-}
862
-
863
-// Checks if the client set configurations for more than one network while creating a container
864
-func (daemon *Daemon) verifyNetworkingConfig(nwConfig *networktypes.NetworkingConfig) error {
865
-	if nwConfig == nil || len(nwConfig.EndpointsConfig) <= 1 {
866
-		return nil
867
-	}
868
-	l := make([]string, 0, len(nwConfig.EndpointsConfig))
869
-	for k := range nwConfig.EndpointsConfig {
870
-		l = append(l, k)
871
-	}
872
-	err := fmt.Errorf("Container cannot be connected to network endpoints: %s", strings.Join(l, ", "))
873
-	return errors.NewBadRequestError(err)
874
-}
875
-
876 809
 func configureVolumes(config *Config, rootUID, rootGID int) (*store.VolumeStore, error) {
877 810
 	volumesDriver, err := local.New(config.Root, rootUID, rootGID)
878 811
 	if err != nil {
... ...
@@ -883,84 +749,11 @@ func configureVolumes(config *Config, rootUID, rootGID int) (*store.VolumeStore,
883 883
 	return store.New(config.Root)
884 884
 }
885 885
 
886
-// AuthenticateToRegistry checks the validity of credentials in authConfig
887
-func (daemon *Daemon) AuthenticateToRegistry(ctx context.Context, authConfig *types.AuthConfig) (string, string, error) {
888
-	return daemon.RegistryService.Auth(ctx, authConfig, dockerversion.DockerUserAgent(ctx))
889
-}
890
-
891 886
 // IsShuttingDown tells whether the daemon is shutting down or not
892 887
 func (daemon *Daemon) IsShuttingDown() bool {
893 888
 	return daemon.shutdown
894 889
 }
895 890
 
896
-// GetContainerStats collects all the stats published by a container
897
-func (daemon *Daemon) GetContainerStats(container *container.Container) (*types.StatsJSON, error) {
898
-	stats, err := daemon.stats(container)
899
-	if err != nil {
900
-		return nil, err
901
-	}
902
-
903
-	if stats.Networks, err = daemon.getNetworkStats(container); err != nil {
904
-		return nil, err
905
-	}
906
-
907
-	return stats, nil
908
-}
909
-
910
-// Resolve Network SandboxID in case the container reuse another container's network stack
911
-func (daemon *Daemon) getNetworkSandboxID(c *container.Container) (string, error) {
912
-	curr := c
913
-	for curr.HostConfig.NetworkMode.IsContainer() {
914
-		containerID := curr.HostConfig.NetworkMode.ConnectedContainer()
915
-		connected, err := daemon.GetContainer(containerID)
916
-		if err != nil {
917
-			return "", fmt.Errorf("Could not get container for %s", containerID)
918
-		}
919
-		curr = connected
920
-	}
921
-	return curr.NetworkSettings.SandboxID, nil
922
-}
923
-
924
-func (daemon *Daemon) getNetworkStats(c *container.Container) (map[string]types.NetworkStats, error) {
925
-	sandboxID, err := daemon.getNetworkSandboxID(c)
926
-	if err != nil {
927
-		return nil, err
928
-	}
929
-
930
-	sb, err := daemon.netController.SandboxByID(sandboxID)
931
-	if err != nil {
932
-		return nil, err
933
-	}
934
-
935
-	lnstats, err := sb.Statistics()
936
-	if err != nil {
937
-		return nil, err
938
-	}
939
-
940
-	stats := make(map[string]types.NetworkStats)
941
-	// Convert libnetwork nw stats into engine-api stats
942
-	for ifName, ifStats := range lnstats {
943
-		stats[ifName] = types.NetworkStats{
944
-			RxBytes:   ifStats.RxBytes,
945
-			RxPackets: ifStats.RxPackets,
946
-			RxErrors:  ifStats.RxErrors,
947
-			RxDropped: ifStats.RxDropped,
948
-			TxBytes:   ifStats.TxBytes,
949
-			TxPackets: ifStats.TxPackets,
950
-			TxErrors:  ifStats.TxErrors,
951
-			TxDropped: ifStats.TxDropped,
952
-		}
953
-	}
954
-
955
-	return stats, nil
956
-}
957
-
958
-// newBaseContainer creates a new container with its initial
959
-// configuration based on the root storage from the daemon.
960
-func (daemon *Daemon) newBaseContainer(id string) *container.Container {
961
-	return container.NewBaseContainer(id, daemon.containerRoot(id))
962
-}
963
-
964 891
 // initDiscovery initializes the discovery watcher for this daemon.
965 892
 func (daemon *Daemon) initDiscovery(config *Config) error {
966 893
 	advertise, err := parseClusterAdvertiseSettings(config.ClusterStore, config.ClusterAdvertise)
... ...
@@ -1112,13 +905,6 @@ func (daemon *Daemon) reloadClusterDiscovery(config *Config) error {
1112 1112
 	return nil
1113 1113
 }
1114 1114
 
1115
-func validateID(id string) error {
1116
-	if id == "" {
1117
-		return fmt.Errorf("Invalid empty id")
1118
-	}
1119
-	return nil
1120
-}
1121
-
1122 1115
 func isBridgeNetworkDisabled(config *Config) bool {
1123 1116
 	return config.bridgeConfig.Iface == disableNetworkBridge
1124 1117
 }
... ...
@@ -106,3 +106,10 @@ func (daemon *Daemon) generateNewName(id string) (string, error) {
106 106
 	}
107 107
 	return name, nil
108 108
 }
109
+
110
+func validateID(id string) error {
111
+	if id == "" {
112
+		return fmt.Errorf("Invalid empty id")
113
+	}
114
+	return nil
115
+}
... ...
@@ -3,6 +3,7 @@ package daemon
3 3
 import (
4 4
 	"encoding/json"
5 5
 	"errors"
6
+	"fmt"
6 7
 	"runtime"
7 8
 
8 9
 	"golang.org/x/net/context"
... ...
@@ -130,3 +131,65 @@ func (daemon *Daemon) subscribeToContainerStats(c *container.Container) chan int
130 130
 func (daemon *Daemon) unsubscribeToContainerStats(c *container.Container, ch chan interface{}) {
131 131
 	daemon.statsCollector.unsubscribe(c, ch)
132 132
 }
133
+
134
+// GetContainerStats collects all the stats published by a container
135
+func (daemon *Daemon) GetContainerStats(container *container.Container) (*types.StatsJSON, error) {
136
+	stats, err := daemon.stats(container)
137
+	if err != nil {
138
+		return nil, err
139
+	}
140
+
141
+	if stats.Networks, err = daemon.getNetworkStats(container); err != nil {
142
+		return nil, err
143
+	}
144
+
145
+	return stats, nil
146
+}
147
+
148
+// Resolve Network SandboxID in case the container reuse another container's network stack
149
+func (daemon *Daemon) getNetworkSandboxID(c *container.Container) (string, error) {
150
+	curr := c
151
+	for curr.HostConfig.NetworkMode.IsContainer() {
152
+		containerID := curr.HostConfig.NetworkMode.ConnectedContainer()
153
+		connected, err := daemon.GetContainer(containerID)
154
+		if err != nil {
155
+			return "", fmt.Errorf("Could not get container for %s", containerID)
156
+		}
157
+		curr = connected
158
+	}
159
+	return curr.NetworkSettings.SandboxID, nil
160
+}
161
+
162
+func (daemon *Daemon) getNetworkStats(c *container.Container) (map[string]types.NetworkStats, error) {
163
+	sandboxID, err := daemon.getNetworkSandboxID(c)
164
+	if err != nil {
165
+		return nil, err
166
+	}
167
+
168
+	sb, err := daemon.netController.SandboxByID(sandboxID)
169
+	if err != nil {
170
+		return nil, err
171
+	}
172
+
173
+	lnstats, err := sb.Statistics()
174
+	if err != nil {
175
+		return nil, err
176
+	}
177
+
178
+	stats := make(map[string]types.NetworkStats)
179
+	// Convert libnetwork nw stats into engine-api stats
180
+	for ifName, ifStats := range lnstats {
181
+		stats[ifName] = types.NetworkStats{
182
+			RxBytes:   ifStats.RxBytes,
183
+			RxPackets: ifStats.RxPackets,
184
+			RxErrors:  ifStats.RxErrors,
185
+			RxDropped: ifStats.RxDropped,
186
+			TxBytes:   ifStats.TxBytes,
187
+			TxPackets: ifStats.TxPackets,
188
+			TxErrors:  ifStats.TxErrors,
189
+			TxDropped: ifStats.TxDropped,
190
+		}
191
+	}
192
+
193
+	return stats, nil
194
+}