1
0
Fork 0

Vendor integration dependencies.

This commit is contained in:
Timo Reimann 2017-02-07 22:33:23 +01:00
parent dd5e3fba01
commit 55b57c736b
2451 changed files with 731611 additions and 0 deletions

View file

@ -0,0 +1,109 @@
package yaml
import (
"fmt"
"strconv"
"strings"
)
// Build represents a build element in compose file.
// It can take multiple form in the compose file, hence this special type
type Build struct {
Context string
Dockerfile string
Args map[string]string
}
// MarshalYAML implements the Marshaller interface.
func (b Build) MarshalYAML() (tag string, value interface{}, err error) {
m := map[string]interface{}{}
if b.Context != "" {
m["context"] = b.Context
}
if b.Dockerfile != "" {
m["dockerfile"] = b.Dockerfile
}
if len(b.Args) > 0 {
m["args"] = b.Args
}
return "", m, nil
}
// UnmarshalYAML implements the Unmarshaller interface.
func (b *Build) UnmarshalYAML(tag string, value interface{}) error {
switch v := value.(type) {
case string:
b.Context = v
case map[interface{}]interface{}:
for mapKey, mapValue := range v {
switch mapKey {
case "context":
b.Context = mapValue.(string)
case "dockerfile":
b.Dockerfile = mapValue.(string)
case "args":
args, err := handleBuildArgs(mapValue)
if err != nil {
return err
}
b.Args = args
default:
// Ignore unknown keys
continue
}
}
default:
return fmt.Errorf("Failed to unmarshal Build: %#v", value)
}
return nil
}
func handleBuildArgs(value interface{}) (map[string]string, error) {
var args map[string]string
switch v := value.(type) {
case map[interface{}]interface{}:
return handleBuildArgMap(v)
case []interface{}:
return handleBuildArgSlice(v)
default:
return args, fmt.Errorf("Failed to unmarshal Build args: %#v", value)
}
}
func handleBuildArgSlice(s []interface{}) (map[string]string, error) {
var args = map[string]string{}
for _, arg := range s {
// check if a value is provided
switch v := strings.SplitN(arg.(string), "=", 2); len(v) {
case 1:
// if we have not specified a a value for this build arg, we assign it an ascii null value and query the environment
// later when we build the service
args[v[0]] = "\x00"
case 2:
// if we do have a value provided, we use it
args[v[0]] = v[1]
}
}
return args, nil
}
func handleBuildArgMap(m map[interface{}]interface{}) (map[string]string, error) {
args := map[string]string{}
for mapKey, mapValue := range m {
var argValue string
name, ok := mapKey.(string)
if !ok {
return args, fmt.Errorf("Cannot unmarshal '%v' to type %T into a string value", name, name)
}
switch a := mapValue.(type) {
case string:
argValue = a
case int64:
argValue = strconv.Itoa(int(a))
default:
return args, fmt.Errorf("Cannot unmarshal '%v' to type %T into a string value", mapValue, mapValue)
}
args[name] = argValue
}
return args, nil
}

View file

@ -0,0 +1,32 @@
package yaml
import (
"fmt"
"github.com/docker/engine-api/types/strslice"
"github.com/flynn/go-shlex"
)
// Command represents a docker command, can be a string or an array of strings.
type Command strslice.StrSlice
// UnmarshalYAML implements the Unmarshaller interface.
func (s *Command) UnmarshalYAML(tag string, value interface{}) error {
switch value := value.(type) {
case []interface{}:
parts, err := toStrings(value)
if err != nil {
return err
}
*s = parts
case string:
parts, err := shlex.Split(value)
if err != nil {
return err
}
*s = parts
default:
return fmt.Errorf("Failed to unmarshal Command: %#v", value)
}
return nil
}

View file

@ -0,0 +1,44 @@
package yaml
import (
"fmt"
)
// External represents an external network entry in compose file.
// It can be a boolean (true|false) or have a name
type External struct {
External bool
Name string
}
// MarshalYAML implements the Marshaller interface.
func (n External) MarshalYAML() (tag string, value interface{}, err error) {
if n.Name == "" {
return "", n.External, nil
}
return "", map[string]interface{}{
"name": n.Name,
}, nil
}
// UnmarshalYAML implements the Unmarshaller interface.
func (n *External) UnmarshalYAML(tag string, value interface{}) error {
switch v := value.(type) {
case bool:
n.External = v
case map[interface{}]interface{}:
for mapKey, mapValue := range v {
switch mapKey {
case "name":
n.Name = mapValue.(string)
default:
// Ignore unknown keys
continue
}
}
n.External = true
default:
return fmt.Errorf("Failed to unmarshal External: %#v", value)
}
return nil
}

View file

@ -0,0 +1,103 @@
package yaml
import (
"fmt"
)
// Networks represents a list of service networks in compose file.
// It has several representation, hence this specific struct.
type Networks struct {
Networks []*Network
}
// Network represents a service network in compose file.
type Network struct {
Name string `yaml:"-"`
RealName string `yaml:"-"`
Aliases []string `yaml:"aliases,omitempty"`
IPv4Address string `yaml:"ipv4_address,omitempty"`
IPv6Address string `yaml:"ipv6_address,omitempty"`
}
// MarshalYAML implements the Marshaller interface.
func (n Networks) MarshalYAML() (tag string, value interface{}, err error) {
m := map[string]*Network{}
for _, network := range n.Networks {
m[network.Name] = network
}
return "", m, nil
}
// UnmarshalYAML implements the Unmarshaller interface.
func (n *Networks) UnmarshalYAML(tag string, value interface{}) error {
switch v := value.(type) {
case []interface{}:
n.Networks = []*Network{}
for _, network := range v {
name, ok := network.(string)
if !ok {
return fmt.Errorf("Cannot unmarshal '%v' to type %T into a string value", name, name)
}
n.Networks = append(n.Networks, &Network{
Name: name,
})
}
case map[interface{}]interface{}:
n.Networks = []*Network{}
for mapKey, mapValue := range v {
name, ok := mapKey.(string)
if !ok {
return fmt.Errorf("Cannot unmarshal '%v' to type %T into a string value", name, name)
}
network, err := handleNetwork(name, mapValue)
if err != nil {
return err
}
n.Networks = append(n.Networks, network)
}
default:
return fmt.Errorf("Failed to unmarshal Networks: %#v", value)
}
return nil
}
func handleNetwork(name string, value interface{}) (*Network, error) {
if value == nil {
return &Network{
Name: name,
}, nil
}
switch v := value.(type) {
case map[interface{}]interface{}:
network := &Network{
Name: name,
}
for mapKey, mapValue := range v {
name, ok := mapKey.(string)
if !ok {
return &Network{}, fmt.Errorf("Cannot unmarshal '%v' to type %T into a string value", name, name)
}
switch name {
case "aliases":
aliases, ok := mapValue.([]interface{})
if !ok {
return &Network{}, fmt.Errorf("Cannot unmarshal '%v' to type %T into a string value", aliases, aliases)
}
network.Aliases = []string{}
for _, alias := range aliases {
network.Aliases = append(network.Aliases, alias.(string))
}
case "ipv4_address":
network.IPv4Address = mapValue.(string)
case "ipv6_address":
network.IPv6Address = mapValue.(string)
default:
// Ignorer unknown keys ?
continue
}
}
return network, nil
default:
return &Network{}, fmt.Errorf("Failed to unmarshal Network: %#v", value)
}
}

View file

@ -0,0 +1,189 @@
package yaml
import (
"fmt"
"strconv"
"strings"
"github.com/docker/engine-api/types/strslice"
)
// Stringorslice represents a string or an array of strings.
// Using engine-api Strslice and augment it with YAML marshalling stuff.
type Stringorslice strslice.StrSlice
// UnmarshalYAML implements the Unmarshaller interface.
func (s *Stringorslice) UnmarshalYAML(tag string, value interface{}) error {
switch value := value.(type) {
case []interface{}:
parts, err := toStrings(value)
if err != nil {
return err
}
*s = parts
case string:
*s = []string{value}
default:
return fmt.Errorf("Failed to unmarshal Stringorslice: %#v", value)
}
return nil
}
// SliceorMap represents a slice or a map of strings.
type SliceorMap map[string]string
// UnmarshalYAML implements the Unmarshaller interface.
func (s *SliceorMap) UnmarshalYAML(tag string, value interface{}) error {
switch value := value.(type) {
case map[interface{}]interface{}:
parts := map[string]string{}
for k, v := range value {
if sk, ok := k.(string); ok {
if sv, ok := v.(string); ok {
parts[sk] = sv
} else {
return fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", v, v)
}
} else {
return fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", k, k)
}
}
*s = parts
case []interface{}:
parts := map[string]string{}
for _, s := range value {
if str, ok := s.(string); ok {
str := strings.TrimSpace(str)
keyValueSlice := strings.SplitN(str, "=", 2)
key := keyValueSlice[0]
val := ""
if len(keyValueSlice) == 2 {
val = keyValueSlice[1]
}
parts[key] = val
} else {
return fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", s, s)
}
}
*s = parts
default:
return fmt.Errorf("Failed to unmarshal SliceorMap: %#v", value)
}
return nil
}
// MaporEqualSlice represents a slice of strings that gets unmarshal from a
// YAML map into 'key=value' string.
type MaporEqualSlice []string
// UnmarshalYAML implements the Unmarshaller interface.
func (s *MaporEqualSlice) UnmarshalYAML(tag string, value interface{}) error {
parts, err := unmarshalToStringOrSepMapParts(value, "=")
if err != nil {
return err
}
*s = parts
return nil
}
// ToMap returns the list of string as a map splitting using = the key=value
func (s *MaporEqualSlice) ToMap() map[string]string {
return toMap(*s, "=")
}
// MaporColonSlice represents a slice of strings that gets unmarshal from a
// YAML map into 'key:value' string.
type MaporColonSlice []string
// UnmarshalYAML implements the Unmarshaller interface.
func (s *MaporColonSlice) UnmarshalYAML(tag string, value interface{}) error {
parts, err := unmarshalToStringOrSepMapParts(value, ":")
if err != nil {
return err
}
*s = parts
return nil
}
// ToMap returns the list of string as a map splitting using = the key=value
func (s *MaporColonSlice) ToMap() map[string]string {
return toMap(*s, ":")
}
// MaporSpaceSlice represents a slice of strings that gets unmarshal from a
// YAML map into 'key value' string.
type MaporSpaceSlice []string
// UnmarshalYAML implements the Unmarshaller interface.
func (s *MaporSpaceSlice) UnmarshalYAML(tag string, value interface{}) error {
parts, err := unmarshalToStringOrSepMapParts(value, " ")
if err != nil {
return err
}
*s = parts
return nil
}
// ToMap returns the list of string as a map splitting using = the key=value
func (s *MaporSpaceSlice) ToMap() map[string]string {
return toMap(*s, " ")
}
func unmarshalToStringOrSepMapParts(value interface{}, key string) ([]string, error) {
switch value := value.(type) {
case []interface{}:
return toStrings(value)
case map[interface{}]interface{}:
return toSepMapParts(value, key)
default:
return nil, fmt.Errorf("Failed to unmarshal Map or Slice: %#v", value)
}
}
func toSepMapParts(value map[interface{}]interface{}, sep string) ([]string, error) {
if len(value) == 0 {
return nil, nil
}
parts := make([]string, 0, len(value))
for k, v := range value {
if sk, ok := k.(string); ok {
if sv, ok := v.(string); ok {
parts = append(parts, sk+sep+sv)
} else if sv, ok := v.(int64); ok {
parts = append(parts, sk+sep+strconv.FormatInt(sv, 10))
} else if v == nil {
parts = append(parts, sk)
} else {
return nil, fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", v, v)
}
} else {
return nil, fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", k, k)
}
}
return parts, nil
}
func toStrings(s []interface{}) ([]string, error) {
if len(s) == 0 {
return nil, nil
}
r := make([]string, len(s))
for k, v := range s {
if sv, ok := v.(string); ok {
r[k] = sv
} else {
return nil, fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", v, v)
}
}
return r, nil
}
func toMap(s []string, sep string) map[string]string {
m := map[string]string{}
for _, v := range s {
values := strings.Split(v, sep)
m[values[0]] = values[1]
}
return m
}

View file

@ -0,0 +1,106 @@
package yaml
import (
"fmt"
"sort"
)
// Ulimits represents a list of Ulimit.
// It is, however, represented in yaml as keys (and thus map in Go)
type Ulimits struct {
Elements []Ulimit
}
// MarshalYAML implements the Marshaller interface.
func (u Ulimits) MarshalYAML() (tag string, value interface{}, err error) {
ulimitMap := make(map[string]Ulimit)
for _, ulimit := range u.Elements {
ulimitMap[ulimit.Name] = ulimit
}
return "", ulimitMap, nil
}
// UnmarshalYAML implements the Unmarshaller interface.
func (u *Ulimits) UnmarshalYAML(tag string, value interface{}) error {
ulimits := make(map[string]Ulimit)
switch v := value.(type) {
case map[interface{}]interface{}:
for mapKey, mapValue := range v {
name, ok := mapKey.(string)
if !ok {
return fmt.Errorf("Cannot unmarshal '%v' to type %T into a string value", name, name)
}
var soft, hard int64
switch mv := mapValue.(type) {
case int64:
soft = mv
hard = mv
case map[interface{}]interface{}:
if len(mv) != 2 {
return fmt.Errorf("Failed to unmarshal Ulimit: %#v", mapValue)
}
for mkey, mvalue := range mv {
switch mkey {
case "soft":
soft = mvalue.(int64)
case "hard":
hard = mvalue.(int64)
default:
// FIXME(vdemeester) Should we ignore or fail ?
continue
}
}
default:
return fmt.Errorf("Failed to unmarshal Ulimit: %v, %T", mapValue, mapValue)
}
ulimits[name] = Ulimit{
Name: name,
ulimitValues: ulimitValues{
Soft: soft,
Hard: hard,
},
}
}
keys := make([]string, 0, len(ulimits))
for key := range ulimits {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
u.Elements = append(u.Elements, ulimits[key])
}
default:
return fmt.Errorf("Failed to unmarshal Ulimit: %#v", value)
}
return nil
}
// Ulimit represents ulimit information.
type Ulimit struct {
ulimitValues
Name string
}
type ulimitValues struct {
Soft int64 `yaml:"soft"`
Hard int64 `yaml:"hard"`
}
// MarshalYAML implements the Marshaller interface.
func (u Ulimit) MarshalYAML() (tag string, value interface{}, err error) {
if u.Soft == u.Hard {
return "", u.Soft, nil
}
return "", u.ulimitValues, err
}
// NewUlimit creates a Ulimit based on the specified parts.
func NewUlimit(name string, soft int64, hard int64) Ulimit {
return Ulimit{
Name: name,
ulimitValues: ulimitValues{
Soft: soft,
Hard: hard,
},
}
}