Browse code

Add a "daemon" build tag and toggle it with the already-existing "DOCKER_CLIENTONLY" build variable

This works mostly by refactoring our "main" package to be careful about what it imports based on the daemon build tag. :)

Also, I've updated Travis to test "client-only" compilation after it tests the daemon version.

Docker-DCO-1.1-Signed-off-by: Andrew Page <admwiggin@gmail.com> (github: tianon)

Tianon Gravi authored on 2014/08/02 02:34:06
Showing 6 changed files
... ...
@@ -16,6 +16,7 @@ sudo: false
16 16
 # Disable the normal go build.
17 17
 install:
18 18
   - export DOCKER_BUILDTAGS='exclude_graphdriver_btrfs exclude_graphdriver_devicemapper' # btrfs and devicemapper fail to compile thanks to a couple missing headers (which we can't install thanks to "sudo: false")
19
+  - export AUTO_GOPATH=1
19 20
 
20 21
 before_script:
21 22
   - env | sort
... ...
@@ -23,6 +24,7 @@ before_script:
23 23
 script:
24 24
   - hack/make.sh validate-dco
25 25
   - hack/make.sh validate-gofmt
26
-  - AUTO_GOPATH=1 ./hack/make.sh dynbinary
26
+  - ./hack/make.sh dynbinary
27
+  - DOCKER_CLIENTONLY=1 ./hack/make.sh dynbinary
27 28
 
28 29
 # vim:set sw=2 ts=2:
29 30
new file mode 100644
... ...
@@ -0,0 +1,17 @@
0
+// +build !daemon
1
+
2
+package main
3
+
4
+import (
5
+	"log"
6
+)
7
+
8
+const CanDaemon = false
9
+
10
+func mainSysinit() {
11
+	log.Fatal("This is a client-only binary - running it as 'dockerinit' is not supported.")
12
+}
13
+
14
+func mainDaemon() {
15
+	log.Fatal("This is a client-only binary - running the Docker daemon is not supported.")
16
+}
0 17
new file mode 100644
... ...
@@ -0,0 +1,112 @@
0
+// +build daemon
1
+
2
+package main
3
+
4
+import (
5
+	"log"
6
+	"net"
7
+
8
+	"github.com/docker/docker/builtins"
9
+	"github.com/docker/docker/dockerversion"
10
+	"github.com/docker/docker/engine"
11
+	flag "github.com/docker/docker/pkg/mflag"
12
+	"github.com/docker/docker/sysinit"
13
+)
14
+
15
+const CanDaemon = true
16
+
17
+func mainSysinit() {
18
+	// Running in init mode
19
+	sysinit.SysInit()
20
+}
21
+
22
+func mainDaemon() {
23
+	if flag.NArg() != 0 {
24
+		flag.Usage()
25
+		return
26
+	}
27
+
28
+	if *bridgeName != "" && *bridgeIp != "" {
29
+		log.Fatal("You specified -b & --bip, mutually exclusive options. Please specify only one.")
30
+	}
31
+
32
+	if !*flEnableIptables && !*flInterContainerComm {
33
+		log.Fatal("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.")
34
+	}
35
+
36
+	if net.ParseIP(*flDefaultIp) == nil {
37
+		log.Fatalf("Specified --ip=%s is not in correct format \"0.0.0.0\".", *flDefaultIp)
38
+	}
39
+
40
+	eng := engine.New()
41
+	// Load builtins
42
+	if err := builtins.Register(eng); err != nil {
43
+		log.Fatal(err)
44
+	}
45
+
46
+	// handle the pidfile early. https://github.com/docker/docker/issues/6973
47
+	if len(*pidfile) > 0 {
48
+		job := eng.Job("initserverpidfile", *pidfile)
49
+		if err := job.Run(); err != nil {
50
+			log.Fatal(err)
51
+		}
52
+	}
53
+
54
+	// load the daemon in the background so we can immediately start
55
+	// the http api so that connections don't fail while the daemon
56
+	// is booting
57
+	go func() {
58
+		// Load plugin: httpapi
59
+		job := eng.Job("initserver")
60
+		// include the variable here too, for the server config
61
+		job.Setenv("Pidfile", *pidfile)
62
+		job.Setenv("Root", *flRoot)
63
+		job.SetenvBool("AutoRestart", *flAutoRestart)
64
+		job.SetenvList("Dns", flDns.GetAll())
65
+		job.SetenvList("DnsSearch", flDnsSearch.GetAll())
66
+		job.SetenvBool("EnableIptables", *flEnableIptables)
67
+		job.SetenvBool("EnableIpForward", *flEnableIpForward)
68
+		job.Setenv("BridgeIface", *bridgeName)
69
+		job.Setenv("BridgeIP", *bridgeIp)
70
+		job.Setenv("DefaultIp", *flDefaultIp)
71
+		job.SetenvBool("InterContainerCommunication", *flInterContainerComm)
72
+		job.Setenv("GraphDriver", *flGraphDriver)
73
+		job.SetenvList("GraphOptions", flGraphOpts.GetAll())
74
+		job.Setenv("ExecDriver", *flExecDriver)
75
+		job.SetenvInt("Mtu", *flMtu)
76
+		job.SetenvBool("EnableSelinuxSupport", *flSelinuxEnabled)
77
+		job.SetenvList("Sockets", flHosts.GetAll())
78
+		if err := job.Run(); err != nil {
79
+			log.Fatal(err)
80
+		}
81
+		// after the daemon is done setting up we can tell the api to start
82
+		// accepting connections
83
+		if err := eng.Job("acceptconnections").Run(); err != nil {
84
+			log.Fatal(err)
85
+		}
86
+	}()
87
+
88
+	// TODO actually have a resolved graphdriver to show?
89
+	log.Printf("docker daemon: %s %s; execdriver: %s; graphdriver: %s",
90
+		dockerversion.VERSION,
91
+		dockerversion.GITCOMMIT,
92
+		*flExecDriver,
93
+		*flGraphDriver)
94
+
95
+	// Serve api
96
+	job := eng.Job("serveapi", flHosts.GetAll()...)
97
+	job.SetenvBool("Logging", true)
98
+	job.SetenvBool("EnableCors", *flEnableCors)
99
+	job.Setenv("Version", dockerversion.VERSION)
100
+	job.Setenv("SocketGroup", *flSocketGroup)
101
+
102
+	job.SetenvBool("Tls", *flTls)
103
+	job.SetenvBool("TlsVerify", *flTlsVerify)
104
+	job.Setenv("TlsCa", *flCa)
105
+	job.Setenv("TlsCert", *flCert)
106
+	job.Setenv("TlsKey", *flKey)
107
+	job.SetenvBool("BufferRequests", true)
108
+	if err := job.Run(); err != nil {
109
+		log.Fatal(err)
110
+	}
111
+}
... ...
@@ -6,19 +6,13 @@ import (
6 6
 	"fmt"
7 7
 	"io/ioutil"
8 8
 	"log"
9
-	"net"
10 9
 	"os"
11
-	"path/filepath"
12 10
 	"strings"
13 11
 
14 12
 	"github.com/docker/docker/api"
15 13
 	"github.com/docker/docker/api/client"
16
-	"github.com/docker/docker/builtins"
17 14
 	"github.com/docker/docker/dockerversion"
18
-	"github.com/docker/docker/engine"
19
-	"github.com/docker/docker/opts"
20 15
 	flag "github.com/docker/docker/pkg/mflag"
21
-	"github.com/docker/docker/sysinit"
22 16
 	"github.com/docker/docker/utils"
23 17
 )
24 18
 
... ...
@@ -28,63 +22,24 @@ const (
28 28
 	defaultCertFile = "cert.pem"
29 29
 )
30 30
 
31
-var (
32
-	dockerConfDir = os.Getenv("DOCKER_CONFIG")
33
-)
34
-
35 31
 func main() {
36
-	if len(dockerConfDir) == 0 {
37
-		dockerConfDir = filepath.Join(os.Getenv("HOME"), ".docker")
38
-	}
39 32
 	if selfPath := utils.SelfPath(); strings.Contains(selfPath, ".dockerinit") {
40
-		// Running in init mode
41
-		sysinit.SysInit()
33
+		mainSysinit()
42 34
 		return
43 35
 	}
44 36
 
45
-	var (
46
-		flVersion            = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit")
47
-		flDaemon             = flag.Bool([]string{"d", "-daemon"}, false, "Enable daemon mode")
48
-		flGraphOpts          opts.ListOpts
49
-		flDebug              = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode")
50
-		flAutoRestart        = flag.Bool([]string{"r", "-restart"}, true, "Restart previously running containers")
51
-		bridgeName           = flag.String([]string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking")
52
-		bridgeIp             = flag.String([]string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b")
53
-		pidfile              = flag.String([]string{"p", "-pidfile"}, "/var/run/docker.pid", "Path to use for daemon PID file")
54
-		flRoot               = flag.String([]string{"g", "-graph"}, "/var/lib/docker", "Path to use as the root of the Docker runtime")
55
-		flSocketGroup        = flag.String([]string{"G", "-group"}, "docker", "Group to assign the unix socket specified by -H when running in daemon mode\nuse '' (the empty string) to disable setting of a group")
56
-		flEnableCors         = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API")
57
-		flDns                = opts.NewListOpts(opts.ValidateIPAddress)
58
-		flDnsSearch          = opts.NewListOpts(opts.ValidateDnsSearch)
59
-		flEnableIptables     = flag.Bool([]string{"#iptables", "-iptables"}, true, "Enable Docker's addition of iptables rules")
60
-		flEnableIpForward    = flag.Bool([]string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
61
-		flDefaultIp          = flag.String([]string{"#ip", "-ip"}, "0.0.0.0", "Default IP address to use when binding container ports")
62
-		flInterContainerComm = flag.Bool([]string{"#icc", "-icc"}, true, "Enable inter-container communication")
63
-		flGraphDriver        = flag.String([]string{"s", "-storage-driver"}, "", "Force the Docker runtime to use a specific storage driver")
64
-		flExecDriver         = flag.String([]string{"e", "-exec-driver"}, "native", "Force the Docker runtime to use a specific exec driver")
65
-		flHosts              = opts.NewListOpts(api.ValidateHost)
66
-		flMtu                = flag.Int([]string{"#mtu", "-mtu"}, 0, "Set the containers network MTU\nif no value is provided: default to the default route MTU or 1500 if no default route is available")
67
-		flTls                = flag.Bool([]string{"-tls"}, false, "Use TLS; implied by tls-verify flags")
68
-		flTlsVerify          = flag.Bool([]string{"-tlsverify"}, false, "Use TLS and verify the remote (daemon: verify client, client: verify daemon)")
69
-		flCa                 = flag.String([]string{"-tlscacert"}, filepath.Join(dockerConfDir, defaultCaFile), "Trust only remotes providing a certificate signed by the CA given here")
70
-		flCert               = flag.String([]string{"-tlscert"}, filepath.Join(dockerConfDir, defaultCertFile), "Path to TLS certificate file")
71
-		flKey                = flag.String([]string{"-tlskey"}, filepath.Join(dockerConfDir, defaultKeyFile), "Path to TLS key file")
72
-		flSelinuxEnabled     = flag.Bool([]string{"-selinux-enabled"}, false, "Enable selinux support. SELinux does not presently support the BTRFS storage driver")
73
-	)
74
-	flag.Var(&flDns, []string{"#dns", "-dns"}, "Force Docker to use specific DNS servers")
75
-	flag.Var(&flDnsSearch, []string{"-dns-search"}, "Force Docker to use specific DNS search domains")
76
-	flag.Var(&flHosts, []string{"H", "-host"}, "The socket(s) to bind to in daemon mode\nspecified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.")
77
-	flag.Var(&flGraphOpts, []string{"-storage-opt"}, "Set storage driver options")
78
-
79 37
 	flag.Parse()
80 38
 
81 39
 	if *flVersion {
82 40
 		showVersion()
83 41
 		return
84 42
 	}
43
+	if *flDebug {
44
+		os.Setenv("DEBUG", "1")
45
+	}
46
+
85 47
 	if flHosts.Len() == 0 {
86 48
 		defaultHost := os.Getenv("DOCKER_HOST")
87
-
88 49
 		if defaultHost == "" || *flDaemon {
89 50
 			// If we do not have a host, default to unix socket
90 51
 			defaultHost = fmt.Sprintf("unix://%s", api.DEFAULTUNIXSOCKET)
... ...
@@ -95,152 +50,63 @@ func main() {
95 95
 		flHosts.Set(defaultHost)
96 96
 	}
97 97
 
98
-	if *bridgeName != "" && *bridgeIp != "" {
99
-		log.Fatal("You specified -b & --bip, mutually exclusive options. Please specify only one.")
100
-	}
101
-
102
-	if !*flEnableIptables && !*flInterContainerComm {
103
-		log.Fatal("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.")
104
-	}
105
-
106
-	if net.ParseIP(*flDefaultIp) == nil {
107
-		log.Fatalf("Specified --ip=%s is not in correct format \"0.0.0.0\".", *flDefaultIp)
98
+	if *flDaemon {
99
+		mainDaemon()
100
+		return
108 101
 	}
109 102
 
110
-	if *flDebug {
111
-		os.Setenv("DEBUG", "1")
103
+	if flHosts.Len() > 1 {
104
+		log.Fatal("Please specify only one -H")
112 105
 	}
106
+	protoAddrParts := strings.SplitN(flHosts.GetAll()[0], "://", 2)
113 107
 
114
-	if *flDaemon {
115
-		if flag.NArg() != 0 {
116
-			flag.Usage()
117
-			return
118
-		}
119
-		eng := engine.New()
120
-		// Load builtins
121
-		if err := builtins.Register(eng); err != nil {
122
-			log.Fatal(err)
123
-		}
124
-
125
-		// handle the pidfile early. https://github.com/docker/docker/issues/6973
126
-		if len(*pidfile) > 0 {
127
-			job := eng.Job("initserverpidfile", *pidfile)
128
-			if err := job.Run(); err != nil {
129
-				log.Fatal(err)
130
-			}
131
-		}
132
-
133
-		// load the daemon in the background so we can immediately start
134
-		// the http api so that connections don't fail while the daemon
135
-		// is booting
136
-		go func() {
137
-			// Load plugin: httpapi
138
-			job := eng.Job("initserver")
139
-			// include the variable here too, for the server config
140
-			job.Setenv("Pidfile", *pidfile)
141
-			job.Setenv("Root", *flRoot)
142
-			job.SetenvBool("AutoRestart", *flAutoRestart)
143
-			job.SetenvList("Dns", flDns.GetAll())
144
-			job.SetenvList("DnsSearch", flDnsSearch.GetAll())
145
-			job.SetenvBool("EnableIptables", *flEnableIptables)
146
-			job.SetenvBool("EnableIpForward", *flEnableIpForward)
147
-			job.Setenv("BridgeIface", *bridgeName)
148
-			job.Setenv("BridgeIP", *bridgeIp)
149
-			job.Setenv("DefaultIp", *flDefaultIp)
150
-			job.SetenvBool("InterContainerCommunication", *flInterContainerComm)
151
-			job.Setenv("GraphDriver", *flGraphDriver)
152
-			job.SetenvList("GraphOptions", flGraphOpts.GetAll())
153
-			job.Setenv("ExecDriver", *flExecDriver)
154
-			job.SetenvInt("Mtu", *flMtu)
155
-			job.SetenvBool("EnableSelinuxSupport", *flSelinuxEnabled)
156
-			job.SetenvList("Sockets", flHosts.GetAll())
157
-			if err := job.Run(); err != nil {
158
-				log.Fatal(err)
159
-			}
160
-			// after the daemon is done setting up we can tell the api to start
161
-			// accepting connections
162
-			if err := eng.Job("acceptconnections").Run(); err != nil {
163
-				log.Fatal(err)
164
-			}
165
-		}()
166
-
167
-		// TODO actually have a resolved graphdriver to show?
168
-		log.Printf("docker daemon: %s %s; execdriver: %s; graphdriver: %s",
169
-			dockerversion.VERSION,
170
-			dockerversion.GITCOMMIT,
171
-			*flExecDriver,
172
-			*flGraphDriver)
173
-
174
-		// Serve api
175
-		job := eng.Job("serveapi", flHosts.GetAll()...)
176
-		job.SetenvBool("Logging", true)
177
-		job.SetenvBool("EnableCors", *flEnableCors)
178
-		job.Setenv("Version", dockerversion.VERSION)
179
-		job.Setenv("SocketGroup", *flSocketGroup)
180
-
181
-		job.SetenvBool("Tls", *flTls)
182
-		job.SetenvBool("TlsVerify", *flTlsVerify)
183
-		job.Setenv("TlsCa", *flCa)
184
-		job.Setenv("TlsCert", *flCert)
185
-		job.Setenv("TlsKey", *flKey)
186
-		job.SetenvBool("BufferRequests", true)
187
-		if err := job.Run(); err != nil {
188
-			log.Fatal(err)
189
-		}
190
-	} else {
191
-		if flHosts.Len() > 1 {
192
-			log.Fatal("Please specify only one -H")
108
+	var (
109
+		cli       *client.DockerCli
110
+		tlsConfig tls.Config
111
+	)
112
+	tlsConfig.InsecureSkipVerify = true
113
+
114
+	// If we should verify the server, we need to load a trusted ca
115
+	if *flTlsVerify {
116
+		*flTls = true
117
+		certPool := x509.NewCertPool()
118
+		file, err := ioutil.ReadFile(*flCa)
119
+		if err != nil {
120
+			log.Fatalf("Couldn't read ca cert %s: %s", *flCa, err)
193 121
 		}
194
-		protoAddrParts := strings.SplitN(flHosts.GetAll()[0], "://", 2)
195
-
196
-		var (
197
-			cli       *client.DockerCli
198
-			tlsConfig tls.Config
199
-		)
200
-		tlsConfig.InsecureSkipVerify = true
122
+		certPool.AppendCertsFromPEM(file)
123
+		tlsConfig.RootCAs = certPool
124
+		tlsConfig.InsecureSkipVerify = false
125
+	}
201 126
 
202
-		// If we should verify the server, we need to load a trusted ca
203
-		if *flTlsVerify {
127
+	// If tls is enabled, try to load and send client certificates
128
+	if *flTls || *flTlsVerify {
129
+		_, errCert := os.Stat(*flCert)
130
+		_, errKey := os.Stat(*flKey)
131
+		if errCert == nil && errKey == nil {
204 132
 			*flTls = true
205
-			certPool := x509.NewCertPool()
206
-			file, err := ioutil.ReadFile(*flCa)
133
+			cert, err := tls.LoadX509KeyPair(*flCert, *flKey)
207 134
 			if err != nil {
208
-				log.Fatalf("Couldn't read ca cert %s: %s", *flCa, err)
209
-			}
210
-			certPool.AppendCertsFromPEM(file)
211
-			tlsConfig.RootCAs = certPool
212
-			tlsConfig.InsecureSkipVerify = false
213
-		}
214
-
215
-		// If tls is enabled, try to load and send client certificates
216
-		if *flTls || *flTlsVerify {
217
-			_, errCert := os.Stat(*flCert)
218
-			_, errKey := os.Stat(*flKey)
219
-			if errCert == nil && errKey == nil {
220
-				*flTls = true
221
-				cert, err := tls.LoadX509KeyPair(*flCert, *flKey)
222
-				if err != nil {
223
-					log.Fatalf("Couldn't load X509 key pair: %s. Key encrypted?", err)
224
-				}
225
-				tlsConfig.Certificates = []tls.Certificate{cert}
135
+				log.Fatalf("Couldn't load X509 key pair: %s. Key encrypted?", err)
226 136
 			}
137
+			tlsConfig.Certificates = []tls.Certificate{cert}
227 138
 		}
139
+	}
228 140
 
229
-		if *flTls || *flTlsVerify {
230
-			cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, protoAddrParts[0], protoAddrParts[1], &tlsConfig)
231
-		} else {
232
-			cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, protoAddrParts[0], protoAddrParts[1], nil)
233
-		}
141
+	if *flTls || *flTlsVerify {
142
+		cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, protoAddrParts[0], protoAddrParts[1], &tlsConfig)
143
+	} else {
144
+		cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, protoAddrParts[0], protoAddrParts[1], nil)
145
+	}
234 146
 
235
-		if err := cli.ParseCommands(flag.Args()...); err != nil {
236
-			if sterr, ok := err.(*utils.StatusError); ok {
237
-				if sterr.Status != "" {
238
-					log.Println(sterr.Status)
239
-				}
240
-				os.Exit(sterr.StatusCode)
147
+	if err := cli.ParseCommands(flag.Args()...); err != nil {
148
+		if sterr, ok := err.(*utils.StatusError); ok {
149
+			if sterr.Status != "" {
150
+				log.Println(sterr.Status)
241 151
 			}
242
-			log.Fatal(err)
152
+			os.Exit(sterr.StatusCode)
243 153
 		}
154
+		log.Fatal(err)
244 155
 	}
245 156
 }
246 157
 
247 158
new file mode 100644
... ...
@@ -0,0 +1,63 @@
0
+package main
1
+
2
+import (
3
+	"os"
4
+	"path/filepath"
5
+
6
+	"github.com/docker/docker/api"
7
+	"github.com/docker/docker/opts"
8
+	flag "github.com/docker/docker/pkg/mflag"
9
+)
10
+
11
+var (
12
+	dockerConfDir = os.Getenv("DOCKER_CONFIG")
13
+)
14
+
15
+func init() {
16
+	if dockerConfDir == "" {
17
+		dockerConfDir = filepath.Join(os.Getenv("HOME"), ".docker")
18
+	}
19
+}
20
+
21
+var (
22
+	flVersion            = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit")
23
+	flDaemon             = flag.Bool([]string{"d", "-daemon"}, false, "Enable daemon mode")
24
+	flGraphOpts          opts.ListOpts
25
+	flDebug              = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode")
26
+	flAutoRestart        = flag.Bool([]string{"r", "-restart"}, true, "Restart previously running containers")
27
+	bridgeName           = flag.String([]string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking")
28
+	bridgeIp             = flag.String([]string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b")
29
+	pidfile              = flag.String([]string{"p", "-pidfile"}, "/var/run/docker.pid", "Path to use for daemon PID file")
30
+	flRoot               = flag.String([]string{"g", "-graph"}, "/var/lib/docker", "Path to use as the root of the Docker runtime")
31
+	flSocketGroup        = flag.String([]string{"G", "-group"}, "docker", "Group to assign the unix socket specified by -H when running in daemon mode\nuse '' (the empty string) to disable setting of a group")
32
+	flEnableCors         = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API")
33
+	flDns                = opts.NewListOpts(opts.ValidateIPAddress)
34
+	flDnsSearch          = opts.NewListOpts(opts.ValidateDnsSearch)
35
+	flEnableIptables     = flag.Bool([]string{"#iptables", "-iptables"}, true, "Enable Docker's addition of iptables rules")
36
+	flEnableIpForward    = flag.Bool([]string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
37
+	flDefaultIp          = flag.String([]string{"#ip", "-ip"}, "0.0.0.0", "Default IP address to use when binding container ports")
38
+	flInterContainerComm = flag.Bool([]string{"#icc", "-icc"}, true, "Enable inter-container communication")
39
+	flGraphDriver        = flag.String([]string{"s", "-storage-driver"}, "", "Force the Docker runtime to use a specific storage driver")
40
+	flExecDriver         = flag.String([]string{"e", "-exec-driver"}, "native", "Force the Docker runtime to use a specific exec driver")
41
+	flHosts              = opts.NewListOpts(api.ValidateHost)
42
+	flMtu                = flag.Int([]string{"#mtu", "-mtu"}, 0, "Set the containers network MTU\nif no value is provided: default to the default route MTU or 1500 if no default route is available")
43
+	flTls                = flag.Bool([]string{"-tls"}, false, "Use TLS; implied by tls-verify flags")
44
+	flTlsVerify          = flag.Bool([]string{"-tlsverify"}, false, "Use TLS and verify the remote (daemon: verify client, client: verify daemon)")
45
+	flSelinuxEnabled     = flag.Bool([]string{"-selinux-enabled"}, false, "Enable selinux support. SELinux does not presently support the BTRFS storage driver")
46
+
47
+	// these are initialized in init() below since their default values depend on dockerConfDir which isn't fully initialized until init() runs
48
+	flCa   *string
49
+	flCert *string
50
+	flKey  *string
51
+)
52
+
53
+func init() {
54
+	flCa = flag.String([]string{"-tlscacert"}, filepath.Join(dockerConfDir, defaultCaFile), "Trust only remotes providing a certificate signed by the CA given here")
55
+	flCert = flag.String([]string{"-tlscert"}, filepath.Join(dockerConfDir, defaultCertFile), "Path to TLS certificate file")
56
+	flKey = flag.String([]string{"-tlskey"}, filepath.Join(dockerConfDir, defaultKeyFile), "Path to TLS key file")
57
+
58
+	flag.Var(&flDns, []string{"#dns", "-dns"}, "Force Docker to use specific DNS servers")
59
+	flag.Var(&flDnsSearch, []string{"-dns-search"}, "Force Docker to use specific DNS search domains")
60
+	flag.Var(&flHosts, []string{"H", "-host"}, "The socket(s) to bind to in daemon mode\nspecified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.")
61
+	flag.Var(&flGraphOpts, []string{"-storage-opt"}, "Set storage driver options")
62
+}
... ...
@@ -90,6 +90,10 @@ if [ ! "$GOPATH" ]; then
90 90
 	exit 1
91 91
 fi
92 92
 
93
+if [ -z "$DOCKER_CLIENTONLY" ]; then
94
+	DOCKER_BUILDTAGS+=" daemon"
95
+fi
96
+
93 97
 # Use these flags when compiling the tests and final binary
94 98
 LDFLAGS='
95 99
 	-w