@@ -45,7 +45,7 @@ import (
45
45
"k8s.io/minikube/pkg/minikube/sysinit"
46
46
)
47
47
48
- var dockerSetEnvTmpl = fmt .Sprintf (
48
+ var dockerEnvTCPTmpl = fmt .Sprintf (
49
49
"{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerTLSVerify }}{{ .Suffix }}" +
50
50
"{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerHost }}{{ .Suffix }}" +
51
51
"{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerCertPath }}{{ .Suffix }}" +
@@ -70,6 +70,12 @@ var dockerSetEnvTmpl = fmt.Sprintf(
70
70
constants .ExistingDockerHostEnv ,
71
71
constants .ExistingDockerCertPathEnv ,
72
72
constants .MinikubeActiveDockerdEnv )
73
+ var dockerEnvSSHTmpl = fmt .Sprintf (
74
+ "{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerHost }}{{ .Suffix }}" +
75
+ "{{ .Prefix }}%s{{ .Delimiter }}{{ .MinikubeDockerdProfile }}{{ .Suffix }}" +
76
+ "{{ .UsageHint }}" ,
77
+ constants .DockerHostEnv ,
78
+ constants .MinikubeActiveDockerdEnv )
73
79
74
80
// DockerShellConfig represents the shell config for Docker
75
81
type DockerShellConfig struct {
@@ -88,6 +94,8 @@ type DockerShellConfig struct {
88
94
89
95
var (
90
96
noProxy bool
97
+ sshHost bool
98
+ sshAdd bool
91
99
dockerUnset bool
92
100
defaultNoProxyGetter NoProxyGetter
93
101
)
@@ -105,12 +113,19 @@ func dockerShellCfgSet(ec DockerEnvConfig, envMap map[string]string) *DockerShel
105
113
profile := ec .profile
106
114
const usgPlz = "To point your shell to minikube's docker-daemon, run:"
107
115
usgCmd := fmt .Sprintf ("minikube -p %s docker-env" , profile )
116
+ if ec .ssh {
117
+ usgCmd += " --ssh-host"
118
+ }
108
119
s := & DockerShellConfig {
109
120
Config : * shell .CfgSet (ec .EnvConfig , usgPlz , usgCmd ),
110
121
}
111
- s .DockerCertPath = envMap [constants .DockerCertPathEnv ]
122
+ if ! ec .ssh {
123
+ s .DockerCertPath = envMap [constants .DockerCertPathEnv ]
124
+ }
112
125
s .DockerHost = envMap [constants .DockerHostEnv ]
113
- s .DockerTLSVerify = envMap [constants .DockerTLSVerifyEnv ]
126
+ if ! ec .ssh {
127
+ s .DockerTLSVerify = envMap [constants .DockerTLSVerifyEnv ]
128
+ }
114
129
115
130
s .ExistingDockerCertPath = envMap [constants .ExistingDockerCertPathEnv ]
116
131
s .ExistingDockerHost = envMap [constants .ExistingDockerHostEnv ]
@@ -226,8 +241,10 @@ var dockerEnvCmd = &cobra.Command{
226
241
out.V {"runtime" : co .Config .KubernetesConfig .ContainerRuntime })
227
242
}
228
243
229
- ensureDockerd (cname , co .CP .Runner )
244
+ r := co .CP .Runner
245
+ ensureDockerd (cname , r )
230
246
247
+ d := co .CP .Host .Driver
231
248
port := constants .DockerDaemonPort
232
249
if driver .NeedsPortForward (driverName ) {
233
250
port , err = oci .ForwardedPort (driverName , cname , port )
@@ -236,14 +253,30 @@ var dockerEnvCmd = &cobra.Command{
236
253
}
237
254
}
238
255
256
+ hostname , err := d .GetSSHHostname ()
257
+ if err != nil {
258
+ exit .Error (reason .IfSSHClient , "Error getting ssh client" , err )
259
+ }
260
+
261
+ sshport , err := d .GetSSHPort ()
262
+ if err != nil {
263
+ exit .Error (reason .IfSSHClient , "Error getting ssh client" , err )
264
+ }
265
+
266
+ hostIP := co .CP .IP .String ()
239
267
ec := DockerEnvConfig {
240
268
EnvConfig : sh ,
241
269
profile : cname ,
242
270
driver : driverName ,
243
- hostIP : co .CP .IP .String (),
271
+ ssh : sshHost ,
272
+ hostIP : hostIP ,
244
273
port : port ,
245
274
certsDir : localpath .MakeMiniPath ("certs" ),
246
275
noProxy : noProxy ,
276
+ username : d .GetSSHUsername (),
277
+ hostname : hostname ,
278
+ sshport : sshport ,
279
+ keypath : d .GetSSHKeyPath (),
247
280
}
248
281
249
282
dockerPath , err := exec .LookPath ("docker" )
@@ -265,6 +298,22 @@ var dockerEnvCmd = &cobra.Command{
265
298
if err := dockerSetScript (ec , os .Stdout ); err != nil {
266
299
exit .Error (reason .InternalDockerScript , "Error generating set output" , err )
267
300
}
301
+
302
+ if sshAdd {
303
+ klog .Infof ("Adding %v" , d .GetSSHKeyPath ())
304
+
305
+ path , err := exec .LookPath ("ssh-add" )
306
+ if err != nil {
307
+ exit .Error (reason .IfSSHClient , "Error with ssh-add" , err )
308
+ }
309
+
310
+ cmd := exec .Command (path , d .GetSSHKeyPath ())
311
+ cmd .Stderr = os .Stderr
312
+ err = cmd .Run ()
313
+ if err != nil {
314
+ exit .Error (reason .IfSSHClient , "Error with ssh-add" , err )
315
+ }
316
+ }
268
317
},
269
318
}
270
319
@@ -273,33 +322,32 @@ type DockerEnvConfig struct {
273
322
shell.EnvConfig
274
323
profile string
275
324
driver string
325
+ ssh bool
276
326
hostIP string
277
327
port int
278
328
certsDir string
279
329
noProxy bool
330
+ username string
331
+ hostname string
332
+ sshport int
333
+ keypath string
280
334
}
281
335
282
336
// dockerSetScript writes out a shell-compatible 'docker-env' script
283
337
func dockerSetScript (ec DockerEnvConfig , w io.Writer ) error {
338
+ var dockerSetEnvTmpl string
339
+ if ec .ssh {
340
+ dockerSetEnvTmpl = dockerEnvSSHTmpl
341
+ } else {
342
+ dockerSetEnvTmpl = dockerEnvTCPTmpl
343
+ }
284
344
envVars := dockerEnvVars (ec )
285
345
return shell .SetScript (ec .EnvConfig , w , dockerSetEnvTmpl , dockerShellCfgSet (ec , envVars ))
286
346
}
287
347
288
348
// dockerSetScript writes out a shell-compatible 'docker-env unset' script
289
349
func dockerUnsetScript (ec DockerEnvConfig , w io.Writer ) error {
290
- vars := []string {
291
- constants .DockerTLSVerifyEnv ,
292
- constants .DockerHostEnv ,
293
- constants .DockerCertPathEnv ,
294
- constants .MinikubeActiveDockerdEnv ,
295
- }
296
-
297
- if ec .noProxy {
298
- k , _ := defaultNoProxyGetter .GetNoProxyVar ()
299
- if k != "" {
300
- vars = append (vars , k )
301
- }
302
- }
350
+ vars := dockerEnvNames (ec )
303
351
return shell .UnsetScript (ec .EnvConfig , w , vars )
304
352
}
305
353
@@ -308,14 +356,31 @@ func dockerURL(ip string, port int) string {
308
356
return fmt .Sprintf ("tcp://%s" , net .JoinHostPort (ip , strconv .Itoa (port )))
309
357
}
310
358
359
+ // sshURL returns the docker endpoint URL when using socket over ssh.
360
+ func sshURL (username string , hostname string , port int ) string {
361
+ // assumes standard /var/run/docker.sock as the path (not possible to set it at the moment)
362
+ return fmt .Sprintf ("ssh://%s@%s" , username , net .JoinHostPort (hostname , strconv .Itoa (port )))
363
+ }
364
+
311
365
// dockerEnvVars gets the necessary docker env variables to allow the use of minikube's docker daemon
312
366
func dockerEnvVars (ec DockerEnvConfig ) map [string ]string {
313
- rt := map [string ]string {
367
+ envTCP := map [string ]string {
314
368
constants .DockerTLSVerifyEnv : "1" ,
315
369
constants .DockerHostEnv : dockerURL (ec .hostIP , ec .port ),
316
370
constants .DockerCertPathEnv : ec .certsDir ,
317
371
constants .MinikubeActiveDockerdEnv : ec .profile ,
318
372
}
373
+ envSSH := map [string ]string {
374
+ constants .DockerHostEnv : sshURL (ec .username , ec .hostname , ec .sshport ),
375
+ constants .MinikubeActiveDockerdEnv : ec .profile ,
376
+ }
377
+
378
+ var rt map [string ]string
379
+ if ec .ssh {
380
+ rt = envSSH
381
+ } else {
382
+ rt = envTCP
383
+ }
319
384
if os .Getenv (constants .MinikubeActiveDockerdEnv ) == "" {
320
385
for _ , env := range constants .DockerDaemonEnvs {
321
386
if v := oci .InitialEnv (env ); v != "" {
@@ -327,6 +392,24 @@ func dockerEnvVars(ec DockerEnvConfig) map[string]string {
327
392
return rt
328
393
}
329
394
395
+ // dockerEnvNames gets the necessary docker env variables to reset after using minikube's docker daemon
396
+ func dockerEnvNames (ec DockerEnvConfig ) []string {
397
+ vars := []string {
398
+ constants .DockerTLSVerifyEnv ,
399
+ constants .DockerHostEnv ,
400
+ constants .DockerCertPathEnv ,
401
+ constants .MinikubeActiveDockerdEnv ,
402
+ }
403
+
404
+ if ec .noProxy {
405
+ k , _ := defaultNoProxyGetter .GetNoProxyVar ()
406
+ if k != "" {
407
+ vars = append (vars , k )
408
+ }
409
+ }
410
+ return vars
411
+ }
412
+
330
413
// dockerEnvVarsList gets the necessary docker env variables to allow the use of minikube's docker daemon to be used in a exec.Command
331
414
func dockerEnvVarsList (ec DockerEnvConfig ) []string {
332
415
return []string {
@@ -348,6 +431,8 @@ func tryDockerConnectivity(bin string, ec DockerEnvConfig) ([]byte, error) {
348
431
func init () {
349
432
defaultNoProxyGetter = & EnvNoProxyGetter {}
350
433
dockerEnvCmd .Flags ().BoolVar (& noProxy , "no-proxy" , false , "Add machine IP to NO_PROXY environment variable" )
434
+ dockerEnvCmd .Flags ().BoolVar (& sshHost , "ssh-host" , false , "Use SSH connection instead of HTTPS (port 2376)" )
435
+ dockerEnvCmd .Flags ().BoolVar (& sshAdd , "ssh-add" , false , "Add SSH identity key to SSH authentication agent" )
351
436
dockerEnvCmd .Flags ().StringVar (& shell .ForceShell , "shell" , "" , "Force environment to be configured for a specified shell: [fish, cmd, powershell, tcsh, bash, zsh], default is auto-detect" )
352
437
dockerEnvCmd .Flags ().BoolVarP (& dockerUnset , "unset" , "u" , false , "Unset variables instead of setting them" )
353
438
}
0 commit comments