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  }