github.com/bdwilliams/libcompose@v0.3.1-0.20160826154243-d81a9bdacff0/yaml/ulimit.go (about) 1 package yaml 2 3 import ( 4 "errors" 5 "fmt" 6 "sort" 7 ) 8 9 // Ulimits represents a list of Ulimit. 10 // It is, however, represented in yaml as keys (and thus map in Go) 11 type Ulimits struct { 12 Elements []Ulimit 13 } 14 15 // MarshalYAML implements the Marshaller interface. 16 func (u Ulimits) MarshalYAML() (interface{}, error) { 17 ulimitMap := make(map[string]Ulimit) 18 for _, ulimit := range u.Elements { 19 ulimitMap[ulimit.Name] = ulimit 20 } 21 return ulimitMap, nil 22 } 23 24 // UnmarshalYAML implements the Unmarshaller interface. 25 func (u *Ulimits) UnmarshalYAML(unmarshal func(interface{}) error) error { 26 ulimits := make(map[string]Ulimit) 27 28 var mapType map[interface{}]interface{} 29 if err := unmarshal(&mapType); err == nil { 30 for mapKey, mapValue := range mapType { 31 name, ok := mapKey.(string) 32 if !ok { 33 return fmt.Errorf("Cannot unmarshal '%v' to type %T into a string value", name, name) 34 } 35 var soft, hard int64 36 switch mv := mapValue.(type) { 37 case int: 38 soft = int64(mv) 39 hard = int64(mv) 40 case map[interface{}]interface{}: 41 if len(mv) != 2 { 42 return fmt.Errorf("Failed to unmarshal Ulimit: %#v", mapValue) 43 } 44 for mkey, mvalue := range mv { 45 switch mkey { 46 case "soft": 47 soft = int64(mvalue.(int)) 48 case "hard": 49 hard = int64(mvalue.(int)) 50 default: 51 // FIXME(vdemeester) Should we ignore or fail ? 52 continue 53 } 54 } 55 default: 56 return fmt.Errorf("Failed to unmarshal Ulimit: %v, %T", mapValue, mapValue) 57 } 58 ulimits[name] = Ulimit{ 59 Name: name, 60 ulimitValues: ulimitValues{ 61 Soft: soft, 62 Hard: hard, 63 }, 64 } 65 } 66 keys := make([]string, 0, len(ulimits)) 67 for key := range ulimits { 68 keys = append(keys, key) 69 } 70 sort.Strings(keys) 71 for _, key := range keys { 72 u.Elements = append(u.Elements, ulimits[key]) 73 } 74 return nil 75 } 76 77 return errors.New("Failed to unmarshal Ulimit") 78 } 79 80 // Ulimit represents ulimit information. 81 type Ulimit struct { 82 ulimitValues 83 Name string 84 } 85 86 type ulimitValues struct { 87 Soft int64 `yaml:"soft"` 88 Hard int64 `yaml:"hard"` 89 } 90 91 // MarshalYAML implements the Marshaller interface. 92 func (u Ulimit) MarshalYAML() (interface{}, error) { 93 if u.Soft == u.Hard { 94 return u.Soft, nil 95 } 96 return u.ulimitValues, nil 97 } 98 99 // NewUlimit creates a Ulimit based on the specified parts. 100 func NewUlimit(name string, soft int64, hard int64) Ulimit { 101 return Ulimit{ 102 Name: name, 103 ulimitValues: ulimitValues{ 104 Soft: soft, 105 Hard: hard, 106 }, 107 } 108 }