Initial commit
This commit is contained in:
288
vendor/github.com/hyperhq/libcompose/yaml/types_yaml.go
generated
vendored
Normal file
288
vendor/github.com/hyperhq/libcompose/yaml/types_yaml.go
generated
vendored
Normal file
@@ -0,0 +1,288 @@
|
||||
package yaml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/engine-api/types/strslice"
|
||||
"github.com/flynn/go-shlex"
|
||||
)
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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)
|
||||
yamlUlimits := reflect.ValueOf(value)
|
||||
switch yamlUlimits.Kind() {
|
||||
case reflect.Map:
|
||||
for _, key := range yamlUlimits.MapKeys() {
|
||||
var name string
|
||||
var soft, hard int64
|
||||
mapValue := yamlUlimits.MapIndex(key).Elem()
|
||||
name = key.Elem().String()
|
||||
switch mapValue.Kind() {
|
||||
case reflect.Int64:
|
||||
soft = mapValue.Int()
|
||||
hard = mapValue.Int()
|
||||
case reflect.Map:
|
||||
if len(mapValue.MapKeys()) != 2 {
|
||||
return fmt.Errorf("Failed to unmarshal Ulimit: %#v", mapValue)
|
||||
}
|
||||
for _, subKey := range mapValue.MapKeys() {
|
||||
subValue := mapValue.MapIndex(subKey).Elem()
|
||||
switch subKey.Elem().String() {
|
||||
case "soft":
|
||||
soft = subValue.Int()
|
||||
case "hard":
|
||||
hard = subValue.Int()
|
||||
}
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("Failed to unmarshal Ulimit: %#v, %v", mapValue, mapValue.Kind())
|
||||
}
|
||||
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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
}
|
||||
278
vendor/github.com/hyperhq/libcompose/yaml/types_yaml_test.go
generated
vendored
Normal file
278
vendor/github.com/hyperhq/libcompose/yaml/types_yaml_test.go
generated
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
package yaml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type StructStringorslice struct {
|
||||
Foo Stringorslice
|
||||
}
|
||||
|
||||
func TestStringorsliceYaml(t *testing.T) {
|
||||
str := `{foo: [bar, baz]}`
|
||||
|
||||
s := StructStringorslice{}
|
||||
yaml.Unmarshal([]byte(str), &s)
|
||||
|
||||
assert.Equal(t, Stringorslice{"bar", "baz"}, s.Foo)
|
||||
|
||||
d, err := yaml.Marshal(&s)
|
||||
assert.Nil(t, err)
|
||||
|
||||
s2 := StructStringorslice{}
|
||||
yaml.Unmarshal(d, &s2)
|
||||
|
||||
assert.Equal(t, Stringorslice{"bar", "baz"}, s2.Foo)
|
||||
}
|
||||
|
||||
type StructSliceorMap struct {
|
||||
Foos SliceorMap `yaml:"foos,omitempty"`
|
||||
Bars []string `yaml:"bars"`
|
||||
}
|
||||
|
||||
type StructCommand struct {
|
||||
Entrypoint Command `yaml:"entrypoint,flow,omitempty"`
|
||||
Command Command `yaml:"command,flow,omitempty"`
|
||||
}
|
||||
|
||||
func TestSliceOrMapYaml(t *testing.T) {
|
||||
str := `{foos: [bar=baz, far=faz]}`
|
||||
|
||||
s := StructSliceorMap{}
|
||||
yaml.Unmarshal([]byte(str), &s)
|
||||
|
||||
assert.Equal(t, SliceorMap{"bar": "baz", "far": "faz"}, s.Foos)
|
||||
|
||||
d, err := yaml.Marshal(&s)
|
||||
assert.Nil(t, err)
|
||||
|
||||
s2 := StructSliceorMap{}
|
||||
yaml.Unmarshal(d, &s2)
|
||||
|
||||
assert.Equal(t, SliceorMap{"bar": "baz", "far": "faz"}, s2.Foos)
|
||||
}
|
||||
|
||||
var sampleStructSliceorMap = `
|
||||
foos:
|
||||
io.rancher.os.bar: baz
|
||||
io.rancher.os.far: true
|
||||
bars: []
|
||||
`
|
||||
|
||||
func TestUnmarshalSliceOrMap(t *testing.T) {
|
||||
s := StructSliceorMap{}
|
||||
err := yaml.Unmarshal([]byte(sampleStructSliceorMap), &s)
|
||||
assert.Equal(t, fmt.Errorf("Cannot unmarshal 'true' of type bool into a string value"), err)
|
||||
}
|
||||
|
||||
func TestStr2SliceOrMapPtrMap(t *testing.T) {
|
||||
s := map[string]*StructSliceorMap{"udav": {
|
||||
Foos: SliceorMap{"io.rancher.os.bar": "baz", "io.rancher.os.far": "true"},
|
||||
Bars: []string{},
|
||||
}}
|
||||
d, err := yaml.Marshal(&s)
|
||||
assert.Nil(t, err)
|
||||
|
||||
s2 := map[string]*StructSliceorMap{}
|
||||
yaml.Unmarshal(d, &s2)
|
||||
|
||||
assert.Equal(t, s, s2)
|
||||
}
|
||||
|
||||
type StructMaporslice struct {
|
||||
Foo MaporEqualSlice
|
||||
}
|
||||
|
||||
func contains(list []string, item string) bool {
|
||||
for _, test := range list {
|
||||
if test == item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func TestMaporsliceYaml(t *testing.T) {
|
||||
str := `{foo: {bar: baz, far: faz}}`
|
||||
|
||||
s := StructMaporslice{}
|
||||
yaml.Unmarshal([]byte(str), &s)
|
||||
|
||||
assert.Equal(t, 2, len(s.Foo))
|
||||
assert.True(t, contains(s.Foo, "bar=baz"))
|
||||
assert.True(t, contains(s.Foo, "far=faz"))
|
||||
|
||||
d, err := yaml.Marshal(&s)
|
||||
assert.Nil(t, err)
|
||||
|
||||
s2 := StructMaporslice{}
|
||||
yaml.Unmarshal(d, &s2)
|
||||
|
||||
assert.Equal(t, 2, len(s2.Foo))
|
||||
assert.True(t, contains(s2.Foo, "bar=baz"))
|
||||
assert.True(t, contains(s2.Foo, "far=faz"))
|
||||
}
|
||||
|
||||
var sampleStructCommand = `command: bash`
|
||||
|
||||
func TestUnmarshalCommand(t *testing.T) {
|
||||
s := &StructCommand{}
|
||||
err := yaml.Unmarshal([]byte(sampleStructCommand), s)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, Command{"bash"}, s.Command)
|
||||
assert.Nil(t, s.Entrypoint)
|
||||
bytes, err := yaml.Marshal(s)
|
||||
assert.Nil(t, err)
|
||||
|
||||
s2 := &StructCommand{}
|
||||
err = yaml.Unmarshal(bytes, s2)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, Command{"bash"}, s2.Command)
|
||||
assert.Nil(t, s2.Entrypoint)
|
||||
}
|
||||
|
||||
var sampleEmptyCommand = `{}`
|
||||
|
||||
func TestUnmarshalEmptyCommand(t *testing.T) {
|
||||
s := &StructCommand{}
|
||||
err := yaml.Unmarshal([]byte(sampleEmptyCommand), s)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, s.Command)
|
||||
|
||||
bytes, err := yaml.Marshal(s)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "{}", strings.TrimSpace(string(bytes)))
|
||||
|
||||
s2 := &StructCommand{}
|
||||
err = yaml.Unmarshal(bytes, s2)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, s2.Command)
|
||||
}
|
||||
|
||||
func TestMarshalUlimit(t *testing.T) {
|
||||
ulimits := []struct {
|
||||
ulimits *Ulimits
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
ulimits: &Ulimits{
|
||||
Elements: []Ulimit{
|
||||
{
|
||||
ulimitValues: ulimitValues{
|
||||
Soft: 65535,
|
||||
Hard: 65535,
|
||||
},
|
||||
Name: "nproc",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: `nproc: 65535
|
||||
`,
|
||||
},
|
||||
{
|
||||
ulimits: &Ulimits{
|
||||
Elements: []Ulimit{
|
||||
{
|
||||
Name: "nofile",
|
||||
ulimitValues: ulimitValues{
|
||||
Soft: 20000,
|
||||
Hard: 40000,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: `nofile:
|
||||
soft: 20000
|
||||
hard: 40000
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, ulimit := range ulimits {
|
||||
|
||||
bytes, err := yaml.Marshal(ulimit.ulimits)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, ulimit.expected, string(bytes), "should be equal")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalUlimits(t *testing.T) {
|
||||
ulimits := []struct {
|
||||
yaml string
|
||||
expected *Ulimits
|
||||
}{
|
||||
{
|
||||
yaml: "nproc: 65535",
|
||||
expected: &Ulimits{
|
||||
Elements: []Ulimit{
|
||||
{
|
||||
Name: "nproc",
|
||||
ulimitValues: ulimitValues{
|
||||
Soft: 65535,
|
||||
Hard: 65535,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
yaml: `nofile:
|
||||
soft: 20000
|
||||
hard: 40000`,
|
||||
expected: &Ulimits{
|
||||
Elements: []Ulimit{
|
||||
{
|
||||
Name: "nofile",
|
||||
ulimitValues: ulimitValues{
|
||||
Soft: 20000,
|
||||
Hard: 40000,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
yaml: `nproc: 65535
|
||||
nofile:
|
||||
soft: 20000
|
||||
hard: 40000`,
|
||||
expected: &Ulimits{
|
||||
Elements: []Ulimit{
|
||||
{
|
||||
Name: "nofile",
|
||||
ulimitValues: ulimitValues{
|
||||
Soft: 20000,
|
||||
Hard: 40000,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "nproc",
|
||||
ulimitValues: ulimitValues{
|
||||
Soft: 65535,
|
||||
Hard: 65535,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, ulimit := range ulimits {
|
||||
actual := &Ulimits{}
|
||||
err := yaml.Unmarshal([]byte(ulimit.yaml), actual)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, ulimit.expected, actual, "should be equal")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user