// IP returns the IP address of the Docker machine func IP(name string) (string, error) { output, _, err := localcmd.New(dockerMachineBinary()).Args("ip", name).Output() if err != nil { return "", ErrDockerMachineExec("ip", err) } return strings.TrimSpace(output), nil }
// Start starts up an existing Docker machine func Start(name string) error { err := localcmd.New(dockerMachineBinary()).Args("start", name).Run() if err != nil { return ErrDockerMachineExec("start", err) } return nil }
// determineMachineProcs determines a reasonable default for machine processors // TODO: implement linux & windows func determineMachineProcessors() int { if runtime.GOOS == "darwin" { output, _, err := localcmd.New("sysctl").Args("-n", "hw.ncpus").Output() if err == nil { ncpus, aerr := strconv.Atoi(strings.TrimSpace(output)) if aerr == nil { return ncpus // use all cpus } } } return defaultMachineProcessors }
// determineMachineMemory determines a reasonable default for machine memory // TODO: implement linux & windows func determineMachineMemory() int { if runtime.GOOS == "darwin" { output, _, err := localcmd.New("sysctl").Args("-n", "hw.memsize").Output() if err == nil { mem, perr := strconv.ParseInt(strings.TrimSpace(output), 10, 64) if perr == nil { return int(mem / (1024 * 1024 * 2)) // half of available megs } } } return defaultMachineMemory }
// Client returns a Docker client for the given Docker machine func Client(name string) (*docker.Client, error) { output, _, err := localcmd.New(dockerMachineBinary()).Args("env", name).Output() if err != nil { return nil, ErrDockerMachineExec("env", err) } scanner := bufio.NewScanner(bytes.NewBufferString(output)) var ( dockerHost, certPath string tlsVerify bool ) prefix := "export " if runtime.GOOS == "windows" { prefix = "SET " } for scanner.Scan() { line := scanner.Text() if strings.HasPrefix(line, prefix) { line = strings.TrimPrefix(line, prefix) parts := strings.SplitN(line, "=", 2) if len(parts) != 2 { continue } switch strings.ToUpper(parts[0]) { case "DOCKER_HOST": dockerHost = strings.Trim(parts[1], "\"") case "DOCKER_CERT_PATH": certPath = strings.Trim(parts[1], "\"") case "DOCKER_TLS_VERIFY": tlsVerify = len(parts[1]) > 0 } } } var client *docker.Client if tlsVerify { cert := filepath.Join(certPath, "cert.pem") key := filepath.Join(certPath, "key.pem") ca := filepath.Join(certPath, "ca.pem") client, err = docker.NewVersionedTLSClient(dockerHost, cert, key, ca, "") } else { client, err = docker.NewVersionedClient(dockerHost, "") } if err != nil { return nil, errors.NewError("could not get Docker client for machine %s", name).WithCause(err) } client.SkipServerVersionCheck = true return client, nil }
// Create creates a new Docker machine func (b *Builder) Create() error { if Exists(b.name) { return ErrDockerMachineExists } if IsAvailable() { return ErrDockerMachineNotAvailable } mem := b.memory if mem == 0 { mem = determineMachineMemory() } proc := b.processors if proc == 0 { proc = determineMachineProcessors() } return localcmd.New(dockerMachineBinary()).Args( "create", "--driver", "virtualbox", "--virtualbox-cpu-count", strconv.Itoa(proc), "--virtualbox-memory", strconv.Itoa(mem), "--engine-insecure-registry", "172.30.0.0/16", b.name).Run() }
// Exists returns true if a Docker machine exists func Exists(name string) bool { err := localcmd.New(dockerMachineBinary()).Args("inspect", name).Run() return err == nil }
// IsRunning returns true if a Docker machine is running func IsRunning(name string) bool { err := localcmd.New(dockerMachineBinary()).Args("ip", name).Run() return err == nil }
// Client returns a Docker client for the given Docker machine func Client(name string) (*docker.Client, *dockerclient.Client, error) { output, _, err := localcmd.New(dockerMachineBinary()).Args("env", name).Output() if err != nil { return nil, nil, ErrDockerMachineExec("env", err) } scanner := bufio.NewScanner(bytes.NewBufferString(output)) var ( dockerHost, certPath string tlsVerify bool ) prefix := "export " if runtime.GOOS == "windows" { prefix = "SET " } for scanner.Scan() { line := scanner.Text() if strings.HasPrefix(line, prefix) { line = strings.TrimPrefix(line, prefix) parts := strings.SplitN(line, "=", 2) if len(parts) != 2 { continue } switch strings.ToUpper(parts[0]) { case "DOCKER_HOST": dockerHost = strings.Trim(parts[1], "\"") case "DOCKER_CERT_PATH": certPath = strings.Trim(parts[1], "\"") case "DOCKER_TLS_VERIFY": tlsVerify = len(parts[1]) > 0 } } } var client *docker.Client if len(certPath) > 0 { cert := filepath.Join(certPath, "cert.pem") key := filepath.Join(certPath, "key.pem") ca := filepath.Join(certPath, "ca.pem") client, err = docker.NewVersionedTLSClient(dockerHost, cert, key, ca, "") } else { client, err = docker.NewVersionedClient(dockerHost, "") } if err != nil { return nil, nil, errors.NewError("could not get Docker client for machine %s", name).WithCause(err) } client.SkipServerVersionCheck = true var httpClient *http.Client if len(certPath) > 0 { tlscOptions := tlsconfig.Options{ CAFile: filepath.Join(certPath, "ca.pem"), CertFile: filepath.Join(certPath, "cert.pem"), KeyFile: filepath.Join(certPath, "key.pem"), InsecureSkipVerify: !tlsVerify, } tlsc, tlsErr := tlsconfig.Client(tlscOptions) if tlsErr != nil { return nil, nil, errors.NewError("could not create TLS config client for machine %s", name).WithCause(tlsErr) } httpClient = &http.Client{ Transport: net.SetTransportDefaults(&http.Transport{ TLSClientConfig: tlsc, }), } } engineAPIClient, err := dockerclient.NewClient(dockerHost, "", httpClient, nil) if err != nil { return nil, nil, errors.NewError("cannot create Docker engine API client").WithCause(err) } return client, engineAPIClient, nil }