traefik/integration/vendor/github.com/docker/libcompose/yaml/ulimit.go
2017-03-09 13:13:03 +01:00

106 lines
2.4 KiB
Go

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,
},
}
}