2017-02-07 21:33:23 +00:00
|
|
|
package yaml
|
|
|
|
|
|
|
|
import (
|
2017-07-06 14:28:13 +00:00
|
|
|
"errors"
|
2017-02-07 21:33:23 +00:00
|
|
|
"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.
|
2017-07-06 14:28:13 +00:00
|
|
|
func (u Ulimits) MarshalYAML() (interface{}, error) {
|
2017-02-07 21:33:23 +00:00
|
|
|
ulimitMap := make(map[string]Ulimit)
|
|
|
|
for _, ulimit := range u.Elements {
|
|
|
|
ulimitMap[ulimit.Name] = ulimit
|
|
|
|
}
|
2017-07-06 14:28:13 +00:00
|
|
|
return ulimitMap, nil
|
2017-02-07 21:33:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalYAML implements the Unmarshaller interface.
|
2017-07-06 14:28:13 +00:00
|
|
|
func (u *Ulimits) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
2017-02-07 21:33:23 +00:00
|
|
|
ulimits := make(map[string]Ulimit)
|
2017-07-06 14:28:13 +00:00
|
|
|
|
|
|
|
var mapType map[interface{}]interface{}
|
|
|
|
if err := unmarshal(&mapType); err == nil {
|
|
|
|
for mapKey, mapValue := range mapType {
|
2017-02-07 21:33:23 +00:00
|
|
|
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) {
|
2017-07-06 14:28:13 +00:00
|
|
|
case int:
|
|
|
|
soft = int64(mv)
|
|
|
|
hard = int64(mv)
|
2017-02-07 21:33:23 +00:00
|
|
|
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":
|
2017-07-06 14:28:13 +00:00
|
|
|
soft = int64(mvalue.(int))
|
2017-02-07 21:33:23 +00:00
|
|
|
case "hard":
|
2017-07-06 14:28:13 +00:00
|
|
|
hard = int64(mvalue.(int))
|
2017-02-07 21:33:23 +00:00
|
|
|
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])
|
|
|
|
}
|
2017-07-06 14:28:13 +00:00
|
|
|
return nil
|
2017-02-07 21:33:23 +00:00
|
|
|
}
|
2017-07-06 14:28:13 +00:00
|
|
|
|
|
|
|
return errors.New("Failed to unmarshal Ulimit")
|
2017-02-07 21:33:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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.
|
2017-07-06 14:28:13 +00:00
|
|
|
func (u Ulimit) MarshalYAML() (interface{}, error) {
|
2017-02-07 21:33:23 +00:00
|
|
|
if u.Soft == u.Hard {
|
2017-07-06 14:28:13 +00:00
|
|
|
return u.Soft, nil
|
2017-02-07 21:33:23 +00:00
|
|
|
}
|
2017-07-06 14:28:13 +00:00
|
|
|
return u.ulimitValues, nil
|
2017-02-07 21:33:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|