api/common.go
551355c9
 package api
 
 import (
 	"fmt"
d54dec4d
 	"mime"
2cd5b7da
 	"path/filepath"
065648a8
 	"sort"
01112989
 	"strconv"
d54dec4d
 	"strings"
 
6f4d8470
 	"github.com/Sirupsen/logrus"
86d1223a
 	"github.com/docker/docker/pkg/system"
b3ee9ac7
 	"github.com/docker/docker/pkg/version"
907407d0
 	"github.com/docker/engine-api/types"
7c7026bd
 	"github.com/docker/libtrust"
551355c9
 )
 
c136591f
 // Common constants for daemon and client.
551355c9
 const (
cfeab585
 	// Version of Current REST API
a0fab35f
 	DefaultVersion version.Version = "1.23"
910322a8
 
927b334e
 	// MinVersion represents Minimum REST API version supported
910322a8
 	MinVersion version.Version = "1.12"
 
e6806223
 	// NoBaseImageSpecifier is the symbol used by the FROM
 	// command to specify that no base image is to be used.
 	NoBaseImageSpecifier string = "scratch"
551355c9
 )
 
c4c6d33b
 // byPortInfo is a temporary type used to sort types.Port by its fields
 type byPortInfo []types.Port
065648a8
 
c4c6d33b
 func (r byPortInfo) Len() int      { return len(r) }
 func (r byPortInfo) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
 func (r byPortInfo) Less(i, j int) bool {
 	if r[i].PrivatePort != r[j].PrivatePort {
 		return r[i].PrivatePort < r[j].PrivatePort
 	}
 
 	if r[i].IP != r[j].IP {
 		return r[i].IP < r[j].IP
 	}
 
 	if r[i].PublicPort != r[j].PublicPort {
 		return r[i].PublicPort < r[j].PublicPort
 	}
 
 	return r[i].Type < r[j].Type
 }
065648a8
 
cfeab585
 // DisplayablePorts returns formatted string representing open ports of container
 // e.g. "0.0.0.0:80->9090/tcp, 9988/tcp"
 // it's used by command 'docker ps'
1bfa80bd
 func DisplayablePorts(ports []types.Port) string {
01112989
 	type portGroup struct {
 		first int
 		last  int
 	}
 	groupMap := make(map[string]*portGroup)
 	var result []string
 	var hostMappings []string
c4c6d33b
 	var groupMapKeys []string
 	sort.Sort(byPortInfo(ports))
065648a8
 	for _, port := range ports {
01112989
 		current := port.PrivatePort
 		portKey := port.Type
065648a8
 		if port.IP != "" {
 			if port.PublicPort != current {
 				hostMappings = append(hostMappings, fmt.Sprintf("%s:%d->%d/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type))
 				continue
 			}
 			portKey = fmt.Sprintf("%s/%s", port.IP, port.Type)
 		}
01112989
 		group := groupMap[portKey]
065648a8
 
01112989
 		if group == nil {
 			groupMap[portKey] = &portGroup{first: current, last: current}
c4c6d33b
 			// record order that groupMap keys are created
 			groupMapKeys = append(groupMapKeys, portKey)
5dfef4fe
 			continue
 		}
01112989
 		if current == (group.last + 1) {
 			group.last = current
5dfef4fe
 			continue
 		}
01112989
 
 		result = append(result, formGroup(portKey, group.first, group.last))
 		groupMap[portKey] = &portGroup{first: current, last: current}
5dfef4fe
 	}
c4c6d33b
 	for _, portKey := range groupMapKeys {
 		g := groupMap[portKey]
01112989
 		result = append(result, formGroup(portKey, g.first, g.last))
551355c9
 	}
5dfef4fe
 	result = append(result, hostMappings...)
551355c9
 	return strings.Join(result, ", ")
 }
 
cfeab585
 func formGroup(key string, start, last int) string {
01112989
 	parts := strings.Split(key, "/")
 	groupType := parts[0]
 	var ip string
5dfef4fe
 	if len(parts) > 1 {
 		ip = parts[0]
 		groupType = parts[1]
 	}
01112989
 	group := strconv.Itoa(start)
 	if start != last {
 		group = fmt.Sprintf("%s-%d", group, last)
5dfef4fe
 	}
 	if ip != "" {
 		group = fmt.Sprintf("%s:%s->%s", ip, group, group)
 	}
 	return fmt.Sprintf("%s/%s", group, groupType)
 }
 
cfeab585
 // MatchesContentType validates the content type against the expected one
551355c9
 func MatchesContentType(contentType, expectedType string) bool {
 	mimetype, _, err := mime.ParseMediaType(contentType)
 	if err != nil {
6f4d8470
 		logrus.Errorf("Error parsing media type: %s error: %v", contentType, err)
551355c9
 	}
 	return err == nil && mimetype == expectedType
 }
9a85f60c
 
 // LoadOrCreateTrustKey attempts to load the libtrust key at the given path,
 // otherwise generates a new one
 func LoadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) {
86d1223a
 	err := system.MkdirAll(filepath.Dir(trustKeyPath), 0700)
 	if err != nil {
9a85f60c
 		return nil, err
 	}
 	trustKey, err := libtrust.LoadKeyFile(trustKeyPath)
 	if err == libtrust.ErrKeyFileDoesNotExist {
 		trustKey, err = libtrust.GenerateECP256PrivateKey()
 		if err != nil {
 			return nil, fmt.Errorf("Error generating key: %s", err)
 		}
 		if err := libtrust.SaveKey(trustKeyPath, trustKey); err != nil {
 			return nil, fmt.Errorf("Error saving key file: %s", err)
 		}
 	} else if err != nil {
a90e91b5
 		return nil, fmt.Errorf("Error loading key file %s: %s", trustKeyPath, err)
9a85f60c
 	}
 	return trustKey, nil
 }