github.com/dougm/docker@v1.5.0/pkg/parsers/parsers.go (about) 1 package parsers 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 ) 8 9 // FIXME: Change this not to receive default value as parameter 10 func ParseHost(defaultTCPAddr, defaultUnixAddr, addr string) (string, error) { 11 addr = strings.TrimSpace(addr) 12 if addr == "" { 13 addr = fmt.Sprintf("unix://%s", defaultUnixAddr) 14 } 15 addrParts := strings.Split(addr, "://") 16 if len(addrParts) == 1 { 17 addrParts = []string{"tcp", addrParts[0]} 18 } 19 20 switch addrParts[0] { 21 case "tcp": 22 return ParseTCPAddr(addrParts[1], defaultTCPAddr) 23 case "unix": 24 return ParseUnixAddr(addrParts[1], defaultUnixAddr) 25 case "fd": 26 return addr, nil 27 default: 28 return "", fmt.Errorf("Invalid bind address format: %s", addr) 29 } 30 } 31 32 func ParseUnixAddr(addr string, defaultAddr string) (string, error) { 33 addr = strings.TrimPrefix(addr, "unix://") 34 if strings.Contains(addr, "://") { 35 return "", fmt.Errorf("Invalid proto, expected unix: %s", addr) 36 } 37 if addr == "" { 38 addr = defaultAddr 39 } 40 return fmt.Sprintf("unix://%s", addr), nil 41 } 42 43 func ParseTCPAddr(addr string, defaultAddr string) (string, error) { 44 addr = strings.TrimPrefix(addr, "tcp://") 45 if strings.Contains(addr, "://") || addr == "" { 46 return "", fmt.Errorf("Invalid proto, expected tcp: %s", addr) 47 } 48 49 hostParts := strings.Split(addr, ":") 50 if len(hostParts) != 2 { 51 return "", fmt.Errorf("Invalid bind address format: %s", addr) 52 } 53 host := hostParts[0] 54 if host == "" { 55 host = defaultAddr 56 } 57 58 p, err := strconv.Atoi(hostParts[1]) 59 if err != nil && p == 0 { 60 return "", fmt.Errorf("Invalid bind address format: %s", addr) 61 } 62 return fmt.Sprintf("tcp://%s:%d", host, p), nil 63 } 64 65 // Get a repos name and returns the right reposName + tag 66 // The tag can be confusing because of a port in a repository name. 67 // Ex: localhost.localdomain:5000/samalba/hipache:latest 68 func ParseRepositoryTag(repos string) (string, string) { 69 n := strings.LastIndex(repos, ":") 70 if n < 0 { 71 return repos, "" 72 } 73 if tag := repos[n+1:]; !strings.Contains(tag, "/") { 74 return repos[:n], tag 75 } 76 return repos, "" 77 } 78 79 func PartParser(template, data string) (map[string]string, error) { 80 // ip:public:private 81 var ( 82 templateParts = strings.Split(template, ":") 83 parts = strings.Split(data, ":") 84 out = make(map[string]string, len(templateParts)) 85 ) 86 if len(parts) != len(templateParts) { 87 return nil, fmt.Errorf("Invalid format to parse. %s should match template %s", data, template) 88 } 89 90 for i, t := range templateParts { 91 value := "" 92 if len(parts) > i { 93 value = parts[i] 94 } 95 out[t] = value 96 } 97 return out, nil 98 } 99 100 func ParseKeyValueOpt(opt string) (string, string, error) { 101 parts := strings.SplitN(opt, "=", 2) 102 if len(parts) != 2 { 103 return "", "", fmt.Errorf("Unable to parse key/value option: %s", opt) 104 } 105 return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil 106 } 107 108 func ParsePortRange(ports string) (uint64, uint64, error) { 109 if ports == "" { 110 return 0, 0, fmt.Errorf("Empty string specified for ports.") 111 } 112 if !strings.Contains(ports, "-") { 113 start, err := strconv.ParseUint(ports, 10, 16) 114 end := start 115 return start, end, err 116 } 117 118 parts := strings.Split(ports, "-") 119 start, err := strconv.ParseUint(parts[0], 10, 16) 120 if err != nil { 121 return 0, 0, err 122 } 123 end, err := strconv.ParseUint(parts[1], 10, 16) 124 if err != nil { 125 return 0, 0, err 126 } 127 if end < start { 128 return 0, 0, fmt.Errorf("Invalid range specified for the Port: %s", ports) 129 } 130 return start, end, nil 131 }