-
Notifications
You must be signed in to change notification settings - Fork 13
/
ulimit.go
132 lines (109 loc) · 3.52 KB
/
ulimit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// SPDX-License-Identifier: Apache-2.0
package yaml
import (
"fmt"
"strconv"
"strings"
"github.com/go-vela/types/pipeline"
"github.com/go-vela/types/raw"
)
type (
// UlimitSlice is the yaml representation of
// the ulimits block for a step in a pipeline.
UlimitSlice []*Ulimit
// Ulimit is the yaml representation of a ulimit
// from the ulimits block for a step in a pipeline.
Ulimit struct {
Name string `yaml:"name,omitempty" json:"name,omitempty" jsonschema:"required,minLength=1,description=Unique name of the user limit.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ulimits-tag"`
Soft int64 `yaml:"soft,omitempty" json:"soft,omitempty" jsonschema:"description=Set the soft limit.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ulimits-tag"`
Hard int64 `yaml:"hard,omitempty" json:"hard,omitempty" jsonschema:"description=Set the hard limit.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ulimits-tag"`
}
)
// ToPipeline converts the UlimitSlice type
// to a pipeline UlimitSlice type.
func (u *UlimitSlice) ToPipeline() *pipeline.UlimitSlice {
// ulimit slice we want to return
ulimitSlice := new(pipeline.UlimitSlice)
// iterate through each element in the ulimit slice
for _, ulimit := range *u {
// append the element to the pipeline ulimit slice
*ulimitSlice = append(*ulimitSlice, &pipeline.Ulimit{
Name: ulimit.Name,
Soft: ulimit.Soft,
Hard: ulimit.Hard,
})
}
return ulimitSlice
}
// UnmarshalYAML implements the Unmarshaler interface for the UlimitSlice type.
func (u *UlimitSlice) UnmarshalYAML(unmarshal func(interface{}) error) error {
// string slice we try unmarshalling to
stringSlice := new(raw.StringSlice)
// attempt to unmarshal as a string slice type
err := unmarshal(stringSlice)
if err == nil {
// iterate through each element in the string slice
for _, ulimit := range *stringSlice {
// split each slice element into key/value pairs
parts := strings.Split(ulimit, "=")
if len(parts) != 2 {
return fmt.Errorf("ulimit %s must contain 1 `=` (equal)", ulimit)
}
// split each value into soft and hard limits
limitParts := strings.Split(parts[1], ":")
switch {
case len(limitParts) == 1:
// capture value for soft and hard limit
value, err := strconv.ParseInt(limitParts[0], 10, 64)
if err != nil {
return err
}
// append the element to the ulimit slice
*u = append(*u, &Ulimit{
Name: parts[0],
Soft: value,
Hard: value,
})
continue
case len(limitParts) == 2:
// capture value for soft limit
firstValue, err := strconv.ParseInt(limitParts[0], 10, 64)
if err != nil {
return err
}
// capture value for hard limit
secondValue, err := strconv.ParseInt(limitParts[1], 10, 64)
if err != nil {
return err
}
// append the element to the ulimit slice
*u = append(*u, &Ulimit{
Name: parts[0],
Soft: firstValue,
Hard: secondValue,
})
continue
default:
return fmt.Errorf("ulimit %s can only contain 1 `:` (colon)", ulimit)
}
}
return nil
}
// ulimit slice we try unmarshalling to
ulimits := new([]*Ulimit)
// attempt to unmarshal as a ulimit slice type
err = unmarshal(ulimits)
if err != nil {
return err
}
// iterate through each element in the volume slice
for _, ulimit := range *ulimits {
// implicitly set `hard` field if empty
if ulimit.Hard == 0 {
ulimit.Hard = ulimit.Soft
}
}
// overwrite existing UlimitSlice
*u = UlimitSlice(*ulimits)
return nil
}