Skip to content
This repository was archived by the owner on Feb 27, 2018. It is now read-only.

Commit 3cbe794

Browse files
Sven DowideitSven Dowideit
authored andcommitted
Merge pull request #218 from SvenDowideit/get-client-certs
Get client certs from vm, and set up the DOCKER_HOST with the real connection string
2 parents ddde716 + 05b9c61 commit 3cbe794

7 files changed

Lines changed: 209 additions & 87 deletions

File tree

cmds.go

Lines changed: 40 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"fmt"
66
"os"
77
"runtime"
8-
"strings"
98
"time"
109

1110
_ "github.com/boot2docker/boot2docker-cli/dummy"
@@ -61,44 +60,50 @@ func cmdUp() error {
6160
}
6261
print("\n")
6362

64-
fmt.Printf("Started.")
63+
fmt.Printf("Started.\n")
6564

6665
if IP == "" {
6766
// lets try one more time
6867
time.Sleep(600 * time.Millisecond)
69-
fmt.Printf(" Trying to get IP one more time")
68+
fmt.Printf(" Trying to get IP one more time\n")
7069

7170
IP = RequestIPFromSSH(m)
7271
}
72+
// Copying the certs here - someone might have have written a Windows API client.
73+
certPath := RequestCertsUsingSSH(m)
7374
switch runtime.GOOS {
7475
case "windows":
75-
fmt.Printf("Docker client does not run on Windows for now. Please use")
76-
fmt.Printf(" \"%s\" ssh", os.Args[0])
77-
fmt.Printf("to SSH into the VM instead.")
76+
fmt.Printf("Docker client does not run on Windows for now. Please use\n")
77+
fmt.Printf(" \"%s\" ssh\n", os.Args[0])
78+
fmt.Printf("to SSH into the VM instead.\n")
7879
default:
7980
if IP == "" {
80-
fmt.Fprintf(os.Stderr, "Auto detection of the VM's IP address failed.")
81-
fmt.Fprintf(os.Stderr, "Please run `boot2docker -v up` to diagnose.")
81+
fmt.Fprintf(os.Stderr, "Auto detection of the VM's IP address failed.\n")
82+
fmt.Fprintf(os.Stderr, "Please run `boot2docker -v up` to diagnose.\n")
8283
} else {
8384
// Check if $DOCKER_HOST ENV var is properly configured.
84-
if os.Getenv("DOCKER_HOST") != fmt.Sprintf("tcp://%s:%d", IP, driver.DockerPort) {
85-
fmt.Printf("To connect the Docker client to the Docker daemon, please set:")
86-
fmt.Printf(" export DOCKER_HOST=tcp://%s:%d", IP, driver.DockerPort)
85+
socket := RequestSocketFromSSH(m)
86+
if os.Getenv("DOCKER_HOST") != socket || os.Getenv("DOCKER_CERT_PATH") != certPath {
87+
fmt.Printf("\nTo connect the Docker client to the Docker daemon, please set:\n")
88+
fmt.Printf(" export DOCKER_HOST=%s\n", socket)
89+
// Assume Docker 1.2.0 with TLS on...
90+
fmt.Printf(" export DOCKER_CERT_PATH=%s\n", certPath)
8791
} else {
88-
fmt.Printf("Your DOCKER_HOST env variable is already set correctly.")
92+
fmt.Printf("Your DOCKER_HOST env variable is already set correctly.\n")
8993
}
9094
}
9195
}
96+
fmt.Printf("\n")
9297
return nil
9398
}
9499

95100
// Tell the user the config (and later let them set it?)
96101
func cmdConfig() error {
97-
dir, err := getCfgDir(".boot2docker")
102+
dir, err := cfgDir(".boot2docker")
98103
if err != nil {
99104
return fmt.Errorf("Error working out Profile file location: %s", err)
100105
}
101-
filename := getCfgFilename(dir)
106+
filename := cfgFilename(dir)
102107
fmt.Printf("boot2docker profile filename: %s", filename)
103108
fmt.Println(printConfig())
104109
return nil
@@ -217,6 +222,26 @@ func cmdStatus() error {
217222
return nil
218223
}
219224

225+
// tell the User the Docker socket to connect to
226+
func cmdSocket() error {
227+
m, err := driver.GetMachine(&B2D)
228+
if err != nil {
229+
return fmt.Errorf("Failed to get machine %q: %s", B2D.VM, err)
230+
}
231+
232+
if m.GetState() != driver.Running {
233+
return fmt.Errorf("VM %q is not running.", B2D.VM)
234+
}
235+
236+
Socket := RequestSocketFromSSH(m)
237+
238+
fmt.Fprintf(os.Stderr, "\n\t export DOCKER_HOST=")
239+
fmt.Printf("%s", Socket)
240+
fmt.Fprintf(os.Stderr, "\n\n")
241+
242+
return nil
243+
}
244+
220245
// Call the external SSH command to login into boot2docker VM.
221246
func cmdSSH() error {
222247
m, err := driver.GetMachine(&B2D)
@@ -236,17 +261,7 @@ func cmdSSH() error {
236261
i++
237262
}
238263

239-
sshArgs := append([]string{
240-
"-o", "IdentitiesOnly=yes",
241-
"-o", "StrictHostKeyChecking=no",
242-
"-o", "UserKnownHostsFile=/dev/null",
243-
"-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts."
244-
"-p", fmt.Sprintf("%d", m.GetSSHPort()),
245-
"-i", B2D.SSHKey,
246-
"docker@localhost",
247-
}, os.Args[i:]...)
248-
249-
if err := cmdInteractive(B2D.SSH, sshArgs...); err != nil {
264+
if err := cmdInteractive(m, os.Args[i:]...); err != nil {
250265
return fmt.Errorf("%s", err)
251266
}
252267
return nil
@@ -287,38 +302,6 @@ func cmdIP() error {
287302
return nil
288303
}
289304

290-
func RequestIPFromSSH(m driver.Machine) string {
291-
// fall back to using the NAT port forwarded ssh
292-
out, err := cmd(B2D.SSH,
293-
"-v", // please leave in - this seems to improve the chance of success
294-
"-o", "IdentitiesOnly=yes",
295-
"-o", "StrictHostKeyChecking=no",
296-
"-o", "UserKnownHostsFile=/dev/null",
297-
"-p", fmt.Sprintf("%d", m.GetSSHPort()),
298-
"-i", B2D.SSHKey,
299-
"docker@localhost",
300-
"ip addr show dev eth1",
301-
)
302-
IP := ""
303-
if err != nil {
304-
fmt.Fprintf(os.Stderr, "request ip from ssh error: %v", err)
305-
} else {
306-
if B2D.Verbose {
307-
fmt.Printf("SSH returned: %s\nEND SSH\n", out)
308-
}
309-
// parse to find: inet 192.168.59.103/24 brd 192.168.59.255 scope global eth1
310-
lines := strings.Split(out, "\n")
311-
for _, line := range lines {
312-
vals := strings.Split(strings.TrimSpace(line), " ")
313-
if len(vals) >= 2 && vals[0] == "inet" {
314-
IP = vals[1][:strings.Index(vals[1], "/")]
315-
break
316-
}
317-
}
318-
}
319-
return IP
320-
}
321-
322305
// Download the boot2docker ISO image.
323306
func cmdDownload() error {
324307
fmt.Printf("Downloading boot2docker ISO image...")

config.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,7 @@ var (
2020
B2D = driver.MachineConfig{}
2121
)
2222

23-
func getCfgDir(name string) (string, error) {
24-
if b2dDir := os.Getenv("BOOT2DOCKER_DIR"); b2dDir != "" {
25-
return b2dDir, nil
26-
}
27-
23+
func homeDir() (string, error) {
2824
dir := ""
2925

3026
// *nix and MSYS Windows
@@ -35,14 +31,29 @@ func getCfgDir(name string) (string, error) {
3531
if _, err := os.Stat(dir); err != nil {
3632
return "", err
3733
}
34+
35+
return dir, nil
36+
}
37+
38+
func cfgDir(name string) (string, error) {
39+
if name == ".boot2docker" {
40+
if b2dDir := os.Getenv("BOOT2DOCKER_DIR"); b2dDir != "" {
41+
return b2dDir, nil
42+
}
43+
}
44+
45+
dir, err := homeDir()
46+
if err != nil {
47+
return "", err
48+
}
3849
dir = filepath.Join(dir, name)
3950
if err := os.MkdirAll(dir, 0755); err != nil {
4051
return "", err
4152
}
4253
return dir, nil
4354
}
4455

45-
func getCfgFilename(dir string) string {
56+
func cfgFilename(dir string) string {
4657
filename := os.Getenv("BOOT2DOCKER_PROFILE")
4758
if filename == "" {
4859
filename = filepath.Join(dir, "profile")
@@ -64,7 +75,7 @@ func printConfig() string {
6475

6576
// Read configuration from both profile and flags. Flags override profile.
6677
func config() (*flag.FlagSet, error) {
67-
dir, err := getCfgDir(".boot2docker")
78+
dir, err := cfgDir(".boot2docker")
6879
if err != nil {
6980
return nil, fmt.Errorf("failed to get boot2docker directory: %s", err)
7081
}
@@ -95,7 +106,7 @@ func config() (*flag.FlagSet, error) {
95106
flags.StringVar(&B2D.SSH, "ssh", "ssh", "path to SSH client utility.")
96107
flags.StringVar(&B2D.SSHGen, "ssh-keygen", "ssh-keygen", "path to ssh-keygen utility.")
97108

98-
sshdir, _ := getCfgDir(".ssh")
109+
sshdir, _ := cfgDir(".ssh")
99110
flags.StringVar(&B2D.SSHKey, "sshkey", filepath.Join(sshdir, "id_boot2docker"), "path to SSH key to use.")
100111
flags.UintVarP(&B2D.DiskSize, "disksize", "s", 20000, "boot2docker disk image size (in MB).")
101112
flags.UintVarP(&B2D.Memory, "memory", "m", 2048, "virtual machine memory size (in MB).")
@@ -121,7 +132,7 @@ func config() (*flag.FlagSet, error) {
121132
return nil, err
122133
}
123134
// Over-ride from the profile file
124-
filename := getCfgFilename(B2D.Dir)
135+
filename := cfgFilename(B2D.Dir)
125136
if _, err := os.Lstat(filename); err == nil {
126137
if _, err := toml.DecodeFile(filename, &B2D); err != nil {
127138
return nil, err
@@ -153,7 +164,7 @@ func config() (*flag.FlagSet, error) {
153164
}
154165

155166
func usageShort() {
156-
fmt.Fprintf(os.Stderr, "Usage: %s [<options>] {help|init|up|ssh|save|down|poweroff|reset|restart|config|status|info|ip|delete|destroy|download|version} [<args>]\n", os.Args[0])
167+
fmt.Fprintf(os.Stderr, "Usage: %s [<options>] {help|init|up|ssh|save|down|poweroff|reset|restart|config|status|info|ip|socket|delete|destroy|download|version} [<args>]\n", os.Args[0])
157168
}
158169

159170
func usageLong(flags *flag.FlagSet) {
@@ -175,6 +186,7 @@ Commands:
175186
config|cfg Show selected profile file settings.
176187
info Display detailed information of VM.
177188
ip Display the IP address of the VM's Host-only network.
189+
socket Display the DOCKER_HOST socket to connect to.
178190
status Display current state of VM.
179191
download Download boot2docker ISO image.
180192
upgrade Upgrade the boot2docker ISO image (if vm is running it will be stopped and started).

driver/driver.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type Machine interface {
4141
DelStorageCtl(name string) error
4242
AttachStorage(ctlName string, medium StorageMedium) error
4343
GetState() MachineState
44+
GetName() string
4445
GetSerialFile() string
4546
GetDockerPort() uint
4647
GetSSHPort() uint

dummy/machine.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ func (m *Machine) Reset() error {
9292
return nil
9393
}
9494

95+
// Get current name
96+
func (m *Machine) GetName() string {
97+
return m.Name
98+
}
99+
95100
// Get current state
96101
func (m *Machine) GetState() driver.MachineState {
97102
return m.State

main.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package main
22

33
import (
4-
"os"
54
"fmt"
5+
"os"
66
)
77

88
// The following vars will be injected during the build process.
@@ -65,6 +65,8 @@ func run() error {
6565
return cmdDelete()
6666
case "info":
6767
return cmdInfo()
68+
case "socket":
69+
return cmdSocket()
6870
case "status":
6971
return cmdStatus()
7072
case "ssh":

0 commit comments

Comments
 (0)