mirror of
https://github.com/thegeeklab/drone-yaml.git
synced 2024-11-25 03:20:39 +00:00
Merge pull request #35 from drone/implement-cpu-resource
Implement cpu resource
This commit is contained in:
commit
f53100ba37
@ -29,5 +29,5 @@ $ drone-yaml verify 642909eb4c3d47e33999235c0598353c samples/simple.yml
|
|||||||
Compile the yaml file:
|
Compile the yaml file:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
$ drone-yaml compile samples/simple.yml > samples/simple.json
|
$ drone-yaml compile samples/simple.yml samples/simple.json
|
||||||
```
|
```
|
||||||
|
3
main.go
3
main.go
@ -201,7 +201,6 @@ var (
|
|||||||
password = compile.Flag("netrc-password", "netrc password").PlaceHolder("x-oauth-basic").String()
|
password = compile.Flag("netrc-password", "netrc password").PlaceHolder("x-oauth-basic").String()
|
||||||
machine = compile.Flag("netrc-machine", "netrc machine").PlaceHolder("github.com").String()
|
machine = compile.Flag("netrc-machine", "netrc machine").PlaceHolder("github.com").String()
|
||||||
memlimit = compile.Flag("mem-limit", "memory limit").PlaceHolder("1GB").Bytes()
|
memlimit = compile.Flag("mem-limit", "memory limit").PlaceHolder("1GB").Bytes()
|
||||||
cpulimit = compile.Flag("cpu-limit", "cpu limit").PlaceHolder("2").Int64()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func runCompile() error {
|
func runCompile() error {
|
||||||
@ -269,7 +268,7 @@ func runCompile() error {
|
|||||||
transform.WithEnviron(*environ),
|
transform.WithEnviron(*environ),
|
||||||
transform.WithEnviron(defaultEnvs()),
|
transform.WithEnviron(defaultEnvs()),
|
||||||
transform.WithLables(*labels),
|
transform.WithLables(*labels),
|
||||||
transform.WithLimits(int64(*memlimit), int64(*cpulimit)),
|
transform.WithLimits(int64(*memlimit), 0),
|
||||||
transform.WithNetrc(*machine, *username, *password),
|
transform.WithNetrc(*machine, *username, *password),
|
||||||
transform.WithNetworks(*network),
|
transform.WithNetworks(*network),
|
||||||
transform.WithProxy(),
|
transform.WithProxy(),
|
||||||
|
@ -84,7 +84,14 @@ func toResourceObject(from *yaml.ResourceObject) *engine.ResourceObject {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &engine.ResourceObject{
|
return &engine.ResourceObject{
|
||||||
CPU: int64(from.CPU),
|
CPU: toCPUMillis(from.CPU),
|
||||||
Memory: int64(from.Memory),
|
Memory: int64(from.Memory),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toCPUMillis(f float64) int64 {
|
||||||
|
if f > 0 {
|
||||||
|
f *= 1000
|
||||||
|
}
|
||||||
|
return int64(f)
|
||||||
|
}
|
||||||
|
@ -136,9 +136,11 @@ func Test_toResources(t *testing.T) {
|
|||||||
Resources: &yaml.Resources{
|
Resources: &yaml.Resources{
|
||||||
Limits: &yaml.ResourceObject{
|
Limits: &yaml.ResourceObject{
|
||||||
Memory: yaml.BytesSize(1000),
|
Memory: yaml.BytesSize(1000),
|
||||||
|
CPU: 4,
|
||||||
},
|
},
|
||||||
Requests: &yaml.ResourceObject{
|
Requests: &yaml.ResourceObject{
|
||||||
Memory: yaml.BytesSize(2000),
|
Memory: yaml.BytesSize(2000),
|
||||||
|
CPU: 0.1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -146,9 +148,11 @@ func Test_toResources(t *testing.T) {
|
|||||||
b = &engine.Resources{
|
b = &engine.Resources{
|
||||||
Limits: &engine.ResourceObject{
|
Limits: &engine.ResourceObject{
|
||||||
Memory: 1000,
|
Memory: 1000,
|
||||||
|
CPU: 4000,
|
||||||
},
|
},
|
||||||
Requests: &engine.ResourceObject{
|
Requests: &engine.ResourceObject{
|
||||||
Memory: 2000,
|
Memory: 2000,
|
||||||
|
CPU: 100,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if diff := cmp.Diff(a, b); diff != "" {
|
if diff := cmp.Diff(a, b); diff != "" {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
// Copyright Jesse Haka.
|
|
||||||
// Copyright the Drone Authors.
|
// Copyright the Drone Authors.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -19,7 +18,7 @@ import "github.com/drone/drone-runtime/engine"
|
|||||||
|
|
||||||
// WithLimits is a transform function that applies
|
// WithLimits is a transform function that applies
|
||||||
// resource limits to the container processes.
|
// resource limits to the container processes.
|
||||||
func WithLimits(memlimit int64, cpulimit int64) func(*engine.Spec) {
|
func WithLimits(memlimit, cpulimit int64) func(*engine.Spec) {
|
||||||
return func(spec *engine.Spec) {
|
return func(spec *engine.Spec) {
|
||||||
// if no limits are defined exit immediately.
|
// if no limits are defined exit immediately.
|
||||||
if memlimit == 0 && cpulimit == 0 {
|
if memlimit == 0 && cpulimit == 0 {
|
||||||
@ -34,12 +33,8 @@ func WithLimits(memlimit int64, cpulimit int64) func(*engine.Spec) {
|
|||||||
if step.Resources.Limits == nil {
|
if step.Resources.Limits == nil {
|
||||||
step.Resources.Limits = &engine.ResourceObject{}
|
step.Resources.Limits = &engine.ResourceObject{}
|
||||||
}
|
}
|
||||||
if memlimit != 0 {
|
|
||||||
step.Resources.Limits.Memory = memlimit
|
step.Resources.Limits.Memory = memlimit
|
||||||
}
|
step.Resources.Limits.CPU = cpulimit
|
||||||
if cpulimit != 0 {
|
|
||||||
step.Resources.Limits.CPU = cpulimit * 1000
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
// Copyright Jesse Haka.
|
|
||||||
// Copyright the Drone Authors.
|
// Copyright the Drone Authors.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -36,47 +35,7 @@ func TestWithLimits(t *testing.T) {
|
|||||||
if got, want := step.Resources.Limits.Memory, int64(1); got != want {
|
if got, want := step.Resources.Limits.Memory, int64(1); got != want {
|
||||||
t.Errorf("Want memory limit %v, got %v", want, got)
|
t.Errorf("Want memory limit %v, got %v", want, got)
|
||||||
}
|
}
|
||||||
if got, want := step.Resources.Limits.CPU, int64(2000); got != want {
|
if got, want := step.Resources.Limits.CPU, int64(2); got != want {
|
||||||
t.Errorf("Want cpu limit %v, got %v", want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWithMemory(t *testing.T) {
|
|
||||||
step := &engine.Step{
|
|
||||||
Metadata: engine.Metadata{
|
|
||||||
UID: "1",
|
|
||||||
Name: "build",
|
|
||||||
},
|
|
||||||
Docker: &engine.DockerStep{},
|
|
||||||
}
|
|
||||||
spec := &engine.Spec{
|
|
||||||
Steps: []*engine.Step{step},
|
|
||||||
}
|
|
||||||
WithLimits(1, 0)(spec)
|
|
||||||
if got, want := step.Resources.Limits.Memory, int64(1); got != want {
|
|
||||||
t.Errorf("Want memory limit %v, got %v", want, got)
|
|
||||||
}
|
|
||||||
if got, want := step.Resources.Limits.CPU, int64(0); got != want {
|
|
||||||
t.Errorf("Want cpu limit %v, got %v", want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWithCPU(t *testing.T) {
|
|
||||||
step := &engine.Step{
|
|
||||||
Metadata: engine.Metadata{
|
|
||||||
UID: "1",
|
|
||||||
Name: "build",
|
|
||||||
},
|
|
||||||
Docker: &engine.DockerStep{},
|
|
||||||
}
|
|
||||||
spec := &engine.Spec{
|
|
||||||
Steps: []*engine.Step{step},
|
|
||||||
}
|
|
||||||
WithLimits(0, 3)(spec)
|
|
||||||
if got, want := step.Resources.Limits.Memory, int64(0); got != want {
|
|
||||||
t.Errorf("Want memory limit %v, got %v", want, got)
|
|
||||||
}
|
|
||||||
if got, want := step.Resources.Limits.CPU, int64(3000); got != want {
|
|
||||||
t.Errorf("Want cpu limit %v, got %v", want, got)
|
t.Errorf("Want cpu limit %v, got %v", want, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ type (
|
|||||||
// ResourceObject describes compute resource
|
// ResourceObject describes compute resource
|
||||||
// requirements.
|
// requirements.
|
||||||
ResourceObject struct {
|
ResourceObject struct {
|
||||||
CPU MilliSize `json:"cpu"`
|
CPU float64 `json:"cpu" yaml:"cpu"`
|
||||||
Memory BytesSize `json:"memory"`
|
Memory BytesSize `json:"memory"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
yaml/pretty/testdata/pipeline_resources.yml
vendored
2
yaml/pretty/testdata/pipeline_resources.yml
vendored
@ -11,5 +11,5 @@ steps:
|
|||||||
cpu: 2
|
cpu: 2
|
||||||
memory: '100Mi'
|
memory: '100Mi'
|
||||||
requests:
|
requests:
|
||||||
cpu: 100m
|
cpu: 1
|
||||||
memory: '50Mi'
|
memory: '50Mi'
|
||||||
|
@ -13,10 +13,10 @@ steps:
|
|||||||
- go build
|
- go build
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
cpu: 2000
|
cpu: 2
|
||||||
memory: 100MiB
|
memory: 100MiB
|
||||||
requests:
|
requests:
|
||||||
cpu: 100
|
cpu: 1
|
||||||
memory: 50MiB
|
memory: 50MiB
|
||||||
|
|
||||||
...
|
...
|
||||||
|
@ -18,12 +18,10 @@ import "github.com/drone/drone-yaml/yaml"
|
|||||||
|
|
||||||
func isPrimative(v interface{}) bool {
|
func isPrimative(v interface{}) bool {
|
||||||
switch v.(type) {
|
switch v.(type) {
|
||||||
case bool, string, int, float64:
|
case bool, string, int, int64, float64:
|
||||||
return true
|
return true
|
||||||
case yaml.BytesSize:
|
case yaml.BytesSize:
|
||||||
return true
|
return true
|
||||||
case yaml.MilliSize:
|
|
||||||
return true
|
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -183,6 +183,12 @@ func writeInt(w writer, v int) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeInt64(w writer, v int64) {
|
||||||
|
w.WriteString(
|
||||||
|
strconv.FormatInt(v, 10),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func writeEncode(w writer, v string) {
|
func writeEncode(w writer, v string) {
|
||||||
if len(v) == 0 {
|
if len(v) == 0 {
|
||||||
w.WriteByte('"')
|
w.WriteByte('"')
|
||||||
@ -204,7 +210,7 @@ func writeValue(w writer, v interface{}) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
case bool, int, float64, string:
|
case bool, int, int64, float64, string:
|
||||||
writeScalar(w, v)
|
writeScalar(w, v)
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
writeSequence(w, v)
|
writeSequence(w, v)
|
||||||
@ -216,8 +222,6 @@ func writeValue(w writer, v interface{}) {
|
|||||||
writeMappingStr(w, v)
|
writeMappingStr(w, v)
|
||||||
case yaml.BytesSize:
|
case yaml.BytesSize:
|
||||||
writeValue(w, v.String())
|
writeValue(w, v.String())
|
||||||
case yaml.MilliSize:
|
|
||||||
writeValue(w, v.String())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,6 +231,8 @@ func writeScalar(w writer, v interface{}) {
|
|||||||
writeBool(w, v)
|
writeBool(w, v)
|
||||||
case int:
|
case int:
|
||||||
writeInt(w, v)
|
writeInt(w, v)
|
||||||
|
case int64:
|
||||||
|
writeInt64(w, v)
|
||||||
case float64:
|
case float64:
|
||||||
writeFloat(w, v)
|
writeFloat(w, v)
|
||||||
case string:
|
case string:
|
||||||
|
40
yaml/unit.go
40
yaml/unit.go
@ -1,4 +1,3 @@
|
|||||||
// Copyright Jesse Haka.
|
|
||||||
// Copyright the Drone Authors.
|
// Copyright the Drone Authors.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -16,9 +15,6 @@
|
|||||||
package yaml
|
package yaml
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/docker/go-units"
|
"github.com/docker/go-units"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -53,39 +49,3 @@ func (b *BytesSize) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||||||
func (b BytesSize) String() string {
|
func (b BytesSize) String() string {
|
||||||
return units.BytesSize(float64(b))
|
return units.BytesSize(float64(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
// MilliSize will convert cpus to millicpus as int64.
|
|
||||||
// for instance "1" will be converted to 1000 and "100m" to 100
|
|
||||||
type MilliSize int64
|
|
||||||
|
|
||||||
// UnmarshalYAML implements yaml unmarshalling.
|
|
||||||
func (m *MilliSize) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|
||||||
var intType int64
|
|
||||||
if err := unmarshal(&intType); err == nil {
|
|
||||||
*m = MilliSize(intType * 1000)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var stringType string
|
|
||||||
if err := unmarshal(&stringType); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(stringType) > 0 {
|
|
||||||
lastChar := string(stringType[len(stringType)-1:])
|
|
||||||
if lastChar == "m" {
|
|
||||||
// convert to int64
|
|
||||||
i, err := strconv.ParseInt(strings.TrimSuffix(stringType, "m"), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*m = MilliSize(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a human-readable cpu millis,
|
|
||||||
// (eg. "1000", "10").
|
|
||||||
func (m MilliSize) String() string {
|
|
||||||
return strconv.FormatInt(int64(m), 10)
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
// Copyright Jesse Haka.
|
|
||||||
// Copyright the Drone Authors.
|
// Copyright the Drone Authors.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -59,42 +58,3 @@ func TestBytesSize(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMilliSize(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
yaml string
|
|
||||||
size int64
|
|
||||||
text string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
yaml: "100m",
|
|
||||||
size: 100,
|
|
||||||
text: "100",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
yaml: "1",
|
|
||||||
size: 1000,
|
|
||||||
text: "1000",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
yaml: "0m",
|
|
||||||
size: 0,
|
|
||||||
text: "0",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, test := range tests {
|
|
||||||
in := []byte(test.yaml)
|
|
||||||
out := MilliSize(0)
|
|
||||||
err := yaml.Unmarshal(in, &out)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if got, want := int64(out), test.size; got != want {
|
|
||||||
t.Errorf("Want millis %d, got %d", want, got)
|
|
||||||
}
|
|
||||||
if got, want := out.String(), test.text; got != want {
|
|
||||||
t.Errorf("Want text %s, got %s", want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user