github.com/rsampaio/docker@v0.7.2-0.20150827203920-fdc73cc3fc31/api/common.go (about)

     1  package api
     2  
     3  import (
     4  	"fmt"
     5  	"mime"
     6  	"path/filepath"
     7  	"sort"
     8  	"strings"
     9  
    10  	"github.com/Sirupsen/logrus"
    11  	"github.com/docker/docker/api/types"
    12  	"github.com/docker/docker/pkg/system"
    13  	"github.com/docker/docker/pkg/version"
    14  	"github.com/docker/libtrust"
    15  )
    16  
    17  // Common constants for daemon and client.
    18  const (
    19  	// Version of Current REST API
    20  	Version version.Version = "1.21"
    21  
    22  	// MinVersion represents Minimun REST API version supported
    23  	MinVersion version.Version = "1.12"
    24  
    25  	// DefaultDockerfileName is the Default filename with Docker commands, read by docker build
    26  	DefaultDockerfileName string = "Dockerfile"
    27  )
    28  
    29  // byPrivatePort is temporary type used to sort types.Port by PrivatePort
    30  type byPrivatePort []types.Port
    31  
    32  func (r byPrivatePort) Len() int           { return len(r) }
    33  func (r byPrivatePort) Swap(i, j int)      { r[i], r[j] = r[j], r[i] }
    34  func (r byPrivatePort) Less(i, j int) bool { return r[i].PrivatePort < r[j].PrivatePort }
    35  
    36  // DisplayablePorts returns formatted string representing open ports of container
    37  // e.g. "0.0.0.0:80->9090/tcp, 9988/tcp"
    38  // it's used by command 'docker ps'
    39  func DisplayablePorts(ports []types.Port) string {
    40  	var (
    41  		result          = []string{}
    42  		hostMappings    = []string{}
    43  		firstInGroupMap map[string]int
    44  		lastInGroupMap  map[string]int
    45  	)
    46  	firstInGroupMap = make(map[string]int)
    47  	lastInGroupMap = make(map[string]int)
    48  	sort.Sort(byPrivatePort(ports))
    49  	for _, port := range ports {
    50  		var (
    51  			current      = port.PrivatePort
    52  			portKey      = port.Type
    53  			firstInGroup int
    54  			lastInGroup  int
    55  		)
    56  		if port.IP != "" {
    57  			if port.PublicPort != current {
    58  				hostMappings = append(hostMappings, fmt.Sprintf("%s:%d->%d/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type))
    59  				continue
    60  			}
    61  			portKey = fmt.Sprintf("%s/%s", port.IP, port.Type)
    62  		}
    63  		firstInGroup = firstInGroupMap[portKey]
    64  		lastInGroup = lastInGroupMap[portKey]
    65  
    66  		if firstInGroup == 0 {
    67  			firstInGroupMap[portKey] = current
    68  			lastInGroupMap[portKey] = current
    69  			continue
    70  		}
    71  
    72  		if current == (lastInGroup + 1) {
    73  			lastInGroupMap[portKey] = current
    74  			continue
    75  		}
    76  		result = append(result, formGroup(portKey, firstInGroup, lastInGroup))
    77  		firstInGroupMap[portKey] = current
    78  		lastInGroupMap[portKey] = current
    79  	}
    80  	for portKey, firstInGroup := range firstInGroupMap {
    81  		result = append(result, formGroup(portKey, firstInGroup, lastInGroupMap[portKey]))
    82  	}
    83  	result = append(result, hostMappings...)
    84  	return strings.Join(result, ", ")
    85  }
    86  
    87  func formGroup(key string, start, last int) string {
    88  	var (
    89  		group     string
    90  		parts     = strings.Split(key, "/")
    91  		groupType = parts[0]
    92  		ip        = ""
    93  	)
    94  	if len(parts) > 1 {
    95  		ip = parts[0]
    96  		groupType = parts[1]
    97  	}
    98  	if start == last {
    99  		group = fmt.Sprintf("%d", start)
   100  	} else {
   101  		group = fmt.Sprintf("%d-%d", start, last)
   102  	}
   103  	if ip != "" {
   104  		group = fmt.Sprintf("%s:%s->%s", ip, group, group)
   105  	}
   106  	return fmt.Sprintf("%s/%s", group, groupType)
   107  }
   108  
   109  // MatchesContentType validates the content type against the expected one
   110  func MatchesContentType(contentType, expectedType string) bool {
   111  	mimetype, _, err := mime.ParseMediaType(contentType)
   112  	if err != nil {
   113  		logrus.Errorf("Error parsing media type: %s error: %v", contentType, err)
   114  	}
   115  	return err == nil && mimetype == expectedType
   116  }
   117  
   118  // LoadOrCreateTrustKey attempts to load the libtrust key at the given path,
   119  // otherwise generates a new one
   120  func LoadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) {
   121  	err := system.MkdirAll(filepath.Dir(trustKeyPath), 0700)
   122  	if err != nil {
   123  		return nil, err
   124  	}
   125  	trustKey, err := libtrust.LoadKeyFile(trustKeyPath)
   126  	if err == libtrust.ErrKeyFileDoesNotExist {
   127  		trustKey, err = libtrust.GenerateECP256PrivateKey()
   128  		if err != nil {
   129  			return nil, fmt.Errorf("Error generating key: %s", err)
   130  		}
   131  		if err := libtrust.SaveKey(trustKeyPath, trustKey); err != nil {
   132  			return nil, fmt.Errorf("Error saving key file: %s", err)
   133  		}
   134  	} else if err != nil {
   135  		return nil, fmt.Errorf("Error loading key file %s: %s", trustKeyPath, err)
   136  	}
   137  	return trustKey, nil
   138  }