github.com/rajnmithun/docker@v1.6.0-rc2/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|digest 66 // The tag can be confusing because of a port in a repository name. 67 // Ex: localhost.localdomain:5000/samalba/hipache:latest 68 // Digest ex: localhost:5000/foo/bar@sha256:bc8813ea7b3603864987522f02a76101c17ad122e1c46d790efc0fca78ca7bfb 69 func ParseRepositoryTag(repos string) (string, string) { 70 n := strings.Index(repos, "@") 71 if n >= 0 { 72 parts := strings.Split(repos, "@") 73 return parts[0], parts[1] 74 } 75 n = strings.LastIndex(repos, ":") 76 if n < 0 { 77 return repos, "" 78 } 79 if tag := repos[n+1:]; !strings.Contains(tag, "/") { 80 return repos[:n], tag 81 } 82 return repos, "" 83 } 84 85 func PartParser(template, data string) (map[string]string, error) { 86 // ip:public:private 87 var ( 88 templateParts = strings.Split(template, ":") 89 parts = strings.Split(data, ":") 90 out = make(map[string]string, len(templateParts)) 91 ) 92 if len(parts) != len(templateParts) { 93 return nil, fmt.Errorf("Invalid format to parse. %s should match template %s", data, template) 94 } 95 96 for i, t := range templateParts { 97 value := "" 98 if len(parts) > i { 99 value = parts[i] 100 } 101 out[t] = value 102 } 103 return out, nil 104 } 105 106 func ParseKeyValueOpt(opt string) (string, string, error) { 107 parts := strings.SplitN(opt, "=", 2) 108 if len(parts) != 2 { 109 return "", "", fmt.Errorf("Unable to parse key/value option: %s", opt) 110 } 111 return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil 112 } 113 114 func ParsePortRange(ports string) (uint64, uint64, error) { 115 if ports == "" { 116 return 0, 0, fmt.Errorf("Empty string specified for ports.") 117 } 118 if !strings.Contains(ports, "-") { 119 start, err := strconv.ParseUint(ports, 10, 16) 120 end := start 121 return start, end, err 122 } 123 124 parts := strings.Split(ports, "-") 125 start, err := strconv.ParseUint(parts[0], 10, 16) 126 if err != nil { 127 return 0, 0, err 128 } 129 end, err := strconv.ParseUint(parts[1], 10, 16) 130 if err != nil { 131 return 0, 0, err 132 } 133 if end < start { 134 return 0, 0, fmt.Errorf("Invalid range specified for the Port: %s", ports) 135 } 136 return start, end, nil 137 }