github.com/kobeld/docker@v1.12.0-rc1/api/common.go (about)

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