/
machine.go
122 lines (105 loc) · 3.19 KB
/
machine.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package machine
import (
"fmt"
"os"
"os/exec"
"regexp"
"strings"
"github.com/justincarter/docker-workbench/run"
)
// Machine represents a docker machine
type Machine struct {
Name string
}
// Create the docker machine
func (m *Machine) Create() {
// default configuration using docker-machine environment variables
env := map[string]string{
"VIRTUALBOX_CPU_COUNT": "2",
"VIRTUALBOX_DISK_SIZE": "60000",
"VIRTUALBOX_MEMORY_SIZE": "2048",
"VIRTUALBOX_NO_SHARE": "true",
}
for k, v := range env {
// set defaults only if the variable is currently unset
if os.Getenv(k) == "" {
os.Setenv(k, v)
}
}
// create the machine
args := fmt.Sprintf("create --driver virtualbox %s", m.Name)
cmd := exec.Command("docker-machine", strings.Fields(args)...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Printf("docker-workbench: docker-machine create failed.")
os.Exit(1)
}
}
// EvalEnv sets docker environment variables
func (m *Machine) EvalEnv() {
out, _ := run.Output("docker-machine", "env", m.Name, "--shell=bash")
env := parseEnvOutput(out)
for k, v := range env {
os.Setenv(k, v)
}
}
// PrintEvalHint shows a hint about running docker env if required
func (m *Machine) PrintEvalHint(checkenv bool) {
showhint := true
if checkenv == true && os.Getenv("DOCKER_MACHINE_NAME") == m.Name {
showhint = false
}
if showhint == true {
fmt.Println("\nRun the following command to set this machine as your default:")
fmt.Printf("eval \"$(docker-machine env %s)\"\n", m.Name)
}
}
// Exists checks if a VM exists
func (m *Machine) Exists() bool {
out, _ := run.Output(run.VBoxManagePath(), "list", "vms")
re := regexp.MustCompile("(?mi)^\"" + m.Name + "\"")
return re.Match(out)
}
// IP returns the IP address of the docker machine
func (m *Machine) IP() (ip string, success bool) {
out, _ := run.Output("docker-machine", "ip", m.Name)
ip = strings.Split(string(out), "\n")[0]
success = ValidIPv4(ip)
return
}
// ShareFolder adds a /workbench shared folder to the VM
func (m *Machine) ShareFolder(folder string) {
args := []string{"sharedfolder", "add", m.Name, "--name", "workbench", "--hostpath", folder}
run.Run(run.VBoxManagePath(), args...)
}
// SSH into the docker machine to run a command
func (m *Machine) SSH(command string) {
run.Run("docker-machine", "ssh", m.Name, command)
}
// Start the docker machine
func (m *Machine) Start() {
run.Run("docker-machine", "start", m.Name)
}
// Stop the docker machine
func (m *Machine) Stop() {
run.Run("docker-machine", "stop", m.Name)
}
// ValidIPv4 returns true for valid IPv4 addresses
func ValidIPv4(ip string) bool {
// validate IP address
re, _ := regexp.Compile(`^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$`)
return re.Match([]byte(ip))
}
// parseEnvOutput parses the output from `docker-machine env` and returns a map
func parseEnvOutput(output []byte) map[string]string {
env := make(map[string]string)
for _, line := range strings.Split(string(output), "\n") {
re, _ := regexp.Compile(`export (.*?)="(.*)"`)
matches := re.FindStringSubmatch(line)
if len(matches) == 3 {
env[matches[1]] = matches[2]
}
}
return env
}