4f0d95fa |
package opts // import "github.com/docker/docker/opts" |
9b995910 |
import (
"fmt"
"net"
"net/url" |
ec87479b |
"path/filepath" |
9b995910 |
"strconv"
"strings" |
ec87479b |
"github.com/docker/docker/pkg/homedir" |
9b995910 |
)
var ( |
62cc802f |
// DefaultHTTPPort Default HTTP Port used if only the protocol is provided to -H flag e.g. dockerd -H tcp:// |
9b995910 |
// These are the IANA registered port numbers for use with Docker
// see http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=docker
DefaultHTTPPort = 2375 // Default HTTP Port
// DefaultTLSHTTPPort Default HTTP Port used when TLS enabled
DefaultTLSHTTPPort = 2376 // Default TLS encrypted HTTP Port
// DefaultUnixSocket Path for the unix socket.
// Docker daemon by default always listens on the default unix socket
DefaultUnixSocket = "/var/run/docker.sock"
// DefaultTCPHost constant defines the default host string used by docker on Windows
DefaultTCPHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultHTTPPort)
// DefaultTLSHost constant defines the default host string used by docker for TLS sockets
DefaultTLSHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultTLSHTTPPort) |
0906195f |
// DefaultNamedPipe defines the default named pipe used by docker on Windows
DefaultNamedPipe = `//./pipe/docker_engine` |
9b995910 |
)
// ValidateHost validates that the specified string is a valid host and returns it.
func ValidateHost(val string) (string, error) { |
0906195f |
host := strings.TrimSpace(val) |
de5c80b4 |
// The empty string means default and is not handled by parseDaemonHost |
0906195f |
if host != "" { |
de5c80b4 |
_, err := parseDaemonHost(host) |
0906195f |
if err != nil {
return val, err
} |
9b995910 |
}
// Note: unlike most flag validators, we don't return the mutated value here |
113cae5b |
// we need to know what the user entered later (using ParseHost) to adjust for TLS |
9b995910 |
return val, nil
}
|
ec87479b |
// ParseHost and set defaults for a Daemon host string. |
8493fb18 |
// defaultToTLS is preferred over defaultToUnixXDG.
func ParseHost(defaultToTLS, defaultToUnixXDG bool, val string) (string, error) { |
0906195f |
host := strings.TrimSpace(val)
if host == "" {
if defaultToTLS {
host = DefaultTLSHost |
8493fb18 |
} else if defaultToUnixXDG { |
ec87479b |
runtimeDir, err := homedir.GetRuntimeDir()
if err != nil {
return "", err
}
socket := filepath.Join(runtimeDir, "docker.sock")
host = "unix://" + socket |
0906195f |
} else {
host = DefaultHost
}
} else {
var err error |
de5c80b4 |
host, err = parseDaemonHost(host) |
0906195f |
if err != nil {
return val, err
} |
9b995910 |
}
return host, nil
}
|
de5c80b4 |
// parseDaemonHost parses the specified address and returns an address that will be used as the host. |
0906195f |
// Depending of the address specified, this may return one of the global Default* strings defined in hosts.go. |
de5c80b4 |
func parseDaemonHost(addr string) (string, error) { |
0a4a0d98 |
addrParts := strings.SplitN(addr, "://", 2) |
0906195f |
if len(addrParts) == 1 && addrParts[0] != "" { |
9b995910 |
addrParts = []string{"tcp", addrParts[0]}
}
switch addrParts[0] {
case "tcp": |
fb3eb1c2 |
return ParseTCPAddr(addrParts[1], DefaultTCPHost) |
9b995910 |
case "unix": |
0906195f |
return parseSimpleProtoAddr("unix", addrParts[1], DefaultUnixSocket)
case "npipe":
return parseSimpleProtoAddr("npipe", addrParts[1], DefaultNamedPipe) |
9b995910 |
case "fd":
return addr, nil
default:
return "", fmt.Errorf("Invalid bind address format: %s", addr)
}
}
|
0906195f |
// parseSimpleProtoAddr parses and validates that the specified address is a valid
// socket address for simple protocols like unix and npipe. It returns a formatted
// socket address, either using the address parsed from addr, or the contents of
// defaultAddr if addr is a blank string.
func parseSimpleProtoAddr(proto, addr, defaultAddr string) (string, error) {
addr = strings.TrimPrefix(addr, proto+"://") |
9b995910 |
if strings.Contains(addr, "://") { |
0906195f |
return "", fmt.Errorf("Invalid proto, expected %s: %s", proto, addr) |
9b995910 |
}
if addr == "" {
addr = defaultAddr
} |
0906195f |
return fmt.Sprintf("%s://%s", proto, addr), nil |
9b995910 |
}
|
fb3eb1c2 |
// ParseTCPAddr parses and validates that the specified address is a valid TCP |
9b995910 |
// address. It returns a formatted TCP address, either using the address parsed
// from tryAddr, or the contents of defaultAddr if tryAddr is a blank string.
// tryAddr is expected to have already been Trim()'d
// defaultAddr must be in the full `tcp://host:port` form |
fb3eb1c2 |
func ParseTCPAddr(tryAddr string, defaultAddr string) (string, error) { |
9b995910 |
if tryAddr == "" || tryAddr == "tcp://" {
return defaultAddr, nil
}
addr := strings.TrimPrefix(tryAddr, "tcp://")
if strings.Contains(addr, "://") || addr == "" {
return "", fmt.Errorf("Invalid proto, expected tcp: %s", tryAddr)
}
defaultAddr = strings.TrimPrefix(defaultAddr, "tcp://")
defaultHost, defaultPort, err := net.SplitHostPort(defaultAddr)
if err != nil {
return "", err
}
// url.Parse fails for trailing colon on IPv6 brackets on Go 1.5, but
// not 1.4. See https://github.com/golang/go/issues/12200 and
// https://github.com/golang/go/issues/6530.
if strings.HasSuffix(addr, "]:") {
addr += defaultPort
}
u, err := url.Parse("tcp://" + addr)
if err != nil {
return "", err
}
host, port, err := net.SplitHostPort(u.Host)
if err != nil { |
fb3eb1c2 |
// try port addition once
host, port, err = net.SplitHostPort(net.JoinHostPort(u.Host, defaultPort))
}
if err != nil { |
9b995910 |
return "", fmt.Errorf("Invalid bind address format: %s", tryAddr)
}
if host == "" {
host = defaultHost
}
if port == "" {
port = defaultPort
}
p, err := strconv.Atoi(port)
if err != nil && p == 0 {
return "", fmt.Errorf("Invalid bind address format: %s", tryAddr)
}
return fmt.Sprintf("tcp://%s%s", net.JoinHostPort(host, port), u.Path), nil
} |
c424be21 |
// ValidateExtraHost validates that the specified string is a valid extrahost and returns it.
// ExtraHost is in the form of name:ip where the ip has to be a valid ip (IPv4 or IPv6).
func ValidateExtraHost(val string) (string, error) {
// allow for IPv6 addresses in extra hosts by only splitting on first ":"
arr := strings.SplitN(val, ":", 2)
if len(arr) != 2 || len(arr[0]) == 0 {
return "", fmt.Errorf("bad format for add-host: %q", val)
}
if _, err := ValidateIPAddress(arr[1]); err != nil {
return "", fmt.Errorf("invalid IP address in add-host: %q", arr[1])
}
return val, nil
} |