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