Skip to content

Commit 98c075b

Browse files
committed
feat(workflow-cli): add volume expand support
1 parent a1f391f commit 98c075b

8 files changed

Lines changed: 123 additions & 23 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ workflow-cli
2929
coverage.txt
3030
.DS_Store
3131
.idea/*
32+
.vscode/*

cmd/cmd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ type Commander interface {
9898
PrintErrf(string, ...interface{}) (int, error)
9999
Version(bool) error
100100
VolumesCreate(string, string, string) error
101+
VolumesExpand(string, string, string) error
101102
VolumesDelete(string, string) error
102103
VolumesList(string, int) error
103104
VolumesMount(string, string, []string) error

cmd/volumes.go

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ package cmd
22

33
import (
44
"fmt"
5-
"github.com/drycc/pkg/prettyprint"
65
"io"
76
"regexp"
87
"strings"
98

9+
"github.com/drycc/pkg/prettyprint"
10+
1011
"github.com/drycc/controller-sdk-go/api"
1112
"github.com/drycc/controller-sdk-go/volumes"
1213
)
@@ -68,16 +69,16 @@ func printVolumes(d *DryccCmd, appID string, volumes api.Volumes, wOut io.Writer
6869
}
6970

7071
// VolumesCreate create a volume for the application
71-
func (d *DryccCmd) VolumesCreate(appID, name string, size string) error {
72+
func (d *DryccCmd) VolumesCreate(appID, name, size string) error {
7273
s, appID, err := load(d.ConfigFile, appID)
7374

7475
if err != nil {
7576
return err
7677
}
77-
regex := regexp.MustCompile("^([1-9][0-9]*[mgMG])$")
78+
regex := regexp.MustCompile("^([1-9][0-9]*[gG])$")
7879
if !regex.MatchString(size) {
7980
return fmt.Errorf(`%s doesn't fit format #unit
80-
Examples: 2G 2g 500M 500m`, size)
81+
Examples: 2G 2g`, size)
8182
}
8283

8384
d.Printf("Creating %s to %s... ", name, appID)
@@ -98,6 +99,37 @@ Examples: 2G 2g 500M 500m`, size)
9899
return nil
99100
}
100101

102+
// VolumesExpand create a volume for the application
103+
func (d *DryccCmd) VolumesExpand(appID, name, size string) error {
104+
s, appID, err := load(d.ConfigFile, appID)
105+
106+
if err != nil {
107+
return err
108+
}
109+
regex := regexp.MustCompile("^([1-9][0-9]*[gG])$")
110+
if !regex.MatchString(size) {
111+
return fmt.Errorf(`%s doesn't fit format #unit
112+
Examples: 2G 2g`, size)
113+
}
114+
115+
d.Printf("Expand %s to %s... ", name, appID)
116+
117+
quit := progress(d.WOut)
118+
volume := api.Volume{
119+
Name: name,
120+
Size: size,
121+
}
122+
_, err = volumes.Expand(s.Client, appID, volume)
123+
quit <- true
124+
<-quit
125+
if d.checkAPICompatibility(s.Client, err) != nil {
126+
return err
127+
}
128+
129+
d.Println("done")
130+
return nil
131+
}
132+
101133
// VolumesDelete delete a volume from the application
102134
func (d *DryccCmd) VolumesDelete(appID, name string) error {
103135
s, appID, err := load(d.ConfigFile, appID)

cmd/volumes_test.go

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func TestVolumesList(t *testing.T) {
3333
"owner": "test",
3434
"app": "example-go",
3535
"name": "myvolume",
36-
"size": "500M",
36+
"size": "500G",
3737
"path": {"cmd": "/data/cmd1", "cmd123": "/data/cmd123"},
3838
"created": "2020-08-26T00:00:00UTC",
3939
"updated": "2020-08-26T00:00:00UTC"
@@ -46,7 +46,7 @@ func TestVolumesList(t *testing.T) {
4646
assert.NoErr(t, err)
4747

4848
assert.Equal(t, b.String(), `=== example-go volumes
49-
--- myvolume 500M
49+
--- myvolume 500G
5050
cmd /data/cmd1
5151
cmd123 /data/cmd123
5252
`, "output")
@@ -63,23 +63,51 @@ func TestVolumesCreate(t *testing.T) {
6363
cmdr := DryccCmd{WOut: &b, ConfigFile: cf}
6464

6565
server.Mux.HandleFunc("/v2/apps/example-go/volumes/", func(w http.ResponseWriter, r *http.Request) {
66-
testutil.AssertBody(t, api.Volume{Name: "myvolume", Size: "500M"}, r)
66+
testutil.AssertBody(t, api.Volume{Name: "myvolume", Size: "500G"}, r)
6767
testutil.SetHeaders(w)
6868
w.WriteHeader(http.StatusCreated)
6969
// Body isn't used by CLI, so it isn't set.
7070
w.Write([]byte("{}"))
7171
})
7272

73-
err = cmdr.VolumesCreate("example-go", "myvolume", "500M")
73+
err = cmdr.VolumesCreate("example-go", "myvolume", "500G")
7474
assert.NoErr(t, err)
7575
err = cmdr.VolumesCreate("example-go", "myvolume", "500K")
7676
expected := `500K doesn't fit format #unit
77-
Examples: 2G 2g 500M 500m`
77+
Examples: 2G 2g`
7878
assert.Equal(t, err.Error(), expected, "output")
7979

8080
assert.Equal(t, testutil.StripProgress(b.String()), "Creating myvolume to example-go... done\n", "output")
8181
}
8282

83+
func TestVolumesExpand(t *testing.T) {
84+
t.Parallel()
85+
cf, server, err := testutil.NewTestServerAndClient()
86+
if err != nil {
87+
t.Fatal(err)
88+
}
89+
defer server.Close()
90+
var b bytes.Buffer
91+
cmdr := DryccCmd{WOut: &b, ConfigFile: cf}
92+
93+
server.Mux.HandleFunc("/v2/apps/example-go/volumes/myvolume/", func(w http.ResponseWriter, r *http.Request) {
94+
testutil.AssertBody(t, api.Volume{Name: "myvolume", Size: "500G"}, r)
95+
testutil.SetHeaders(w)
96+
w.WriteHeader(http.StatusCreated)
97+
// Body isn't used by CLI, so it isn't set.
98+
w.Write([]byte("{}"))
99+
})
100+
101+
err = cmdr.VolumesExpand("example-go", "myvolume", "500G")
102+
assert.NoErr(t, err)
103+
err = cmdr.VolumesExpand("example-go", "myvolume", "500K")
104+
expected := `500K doesn't fit format #unit
105+
Examples: 2G 2g`
106+
assert.Equal(t, err.Error(), expected, "output")
107+
108+
assert.Equal(t, testutil.StripProgress(b.String()), "Expand myvolume to example-go... done\n", "output")
109+
}
110+
83111
func TestVolumesDelete(t *testing.T) {
84112
t.Parallel()
85113
cf, server, err := testutil.NewTestServerAndClient()
@@ -123,7 +151,7 @@ func TestVolumesMount(t *testing.T) {
123151
"owner": "test",
124152
"app": "example-go",
125153
"name": "myvolume",
126-
"size": "500M",
154+
"size": "500G",
127155
"path": {"cmd": "/data/cmd1"},
128156
"created": "2020-08-26T00:00:00UTC",
129157
"updated": "2020-08-26T00:00:00UTC"
@@ -162,7 +190,7 @@ func TestVolumesUnmount(t *testing.T) {
162190
"owner": "test",
163191
"app": "example-go",
164192
"name": "myvolume",
165-
"size": "500M",
193+
"size": "500G",
166194
"path": {},
167195
"created": "2020-08-26T00:00:00UTC",
168196
"updated": "2020-08-26T00:00:00UTC"

go.mod

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
module github.com/drycc/workflow-cli
22

3-
go 1.17
3+
go 1.18
44

55
require (
66
github.com/arschles/assert v1.0.1-0.20191213221312-71f210f9375a
77
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
8-
github.com/drycc/controller-sdk-go v0.0.0-20211213072304-8a9f2f28d524
8+
github.com/drycc/controller-sdk-go v0.0.0-20220801120356-de65d8cb5598
99
github.com/drycc/pkg v0.0.0-20210826011456-c60b87108840
1010
github.com/olekukonko/tablewriter v0.0.5
11-
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
1211
gopkg.in/yaml.v2 v2.4.0
1312
)
1413

go.sum

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
4949
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5050
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ=
5151
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
52-
github.com/drycc/controller-sdk-go v0.0.0-20210826011521-d57f3c75935a h1:TKz7m1cwN3ktK9bGWorLVSSmkLrDO4qALhdGUxTRToo=
53-
github.com/drycc/controller-sdk-go v0.0.0-20210826011521-d57f3c75935a/go.mod h1:DmVcssrb6yJMWI8sGT+8Xy3caVR5kSlsctD3a7Zn6FA=
54-
github.com/drycc/controller-sdk-go v0.0.0-20211124095117-dbf56da8c5a8 h1:cddNthWLhOdgvpF5S78Fc7j8I5ESDRUtTZhHIFTLcC0=
55-
github.com/drycc/controller-sdk-go v0.0.0-20211124095117-dbf56da8c5a8/go.mod h1:aGxL2AkmmG7d5afWiUGy93/+UPDnIxgsWSwxuznjteE=
56-
github.com/drycc/controller-sdk-go v0.0.0-20211213072304-8a9f2f28d524 h1:45Ufw74Ye6AXR3X5IzwJvSeByFiaV1nw3eh++mvLQbE=
57-
github.com/drycc/controller-sdk-go v0.0.0-20211213072304-8a9f2f28d524/go.mod h1:aGxL2AkmmG7d5afWiUGy93/+UPDnIxgsWSwxuznjteE=
52+
github.com/drycc/controller-sdk-go v0.0.0-20220801120356-de65d8cb5598 h1:SfwHwhoe7QpNzEmN96G6egIbZKWkfiyLCFk7SlhpQ8U=
53+
github.com/drycc/controller-sdk-go v0.0.0-20220801120356-de65d8cb5598/go.mod h1:aGxL2AkmmG7d5afWiUGy93/+UPDnIxgsWSwxuznjteE=
5854
github.com/drycc/pkg v0.0.0-20210826011456-c60b87108840 h1:0OhP9AQ0mh3q0TMxK4PJTPSFwD/wj0xugiaZ3lnLcNA=
5955
github.com/drycc/pkg v0.0.0-20210826011456-c60b87108840/go.mod h1:KX1FLm7Fq6FLCsjjRsgfI/bMQuHZXqYf1ZXU9fzJhDw=
6056
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
@@ -141,6 +137,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
141137
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
142138
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
143139
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
140+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
144141
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
145142
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
146143
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -154,6 +151,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
154151
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
155152
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
156153
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
154+
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
157155
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
158156
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
159157
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
@@ -192,7 +190,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
192190
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
193191
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
194192
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
195-
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
196193
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
197194
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
198195
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -394,6 +391,7 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
394391
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
395392
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
396393
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
394+
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
397395
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
398396
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
399397
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=

parser/volumes.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ func Volumes(argv []string, cmdr cmd.Commander) error {
1111
Valid commands for volumes:
1212
1313
volumes:create create a volume for the application
14+
volumes:expand expand a volume for the application
1415
volumes:list list volumes in the application
1516
volumes:delete delete a volume from the application
1617
volumes:mount mount a volume to process of the application
@@ -22,6 +23,8 @@ Use 'drycc help [command]' to learn more.
2223
switch argv[0] {
2324
case "volumes:create":
2425
return volumesCreate(argv, cmdr)
26+
case "volumes:expand":
27+
return volumesExpand(argv, cmdr)
2528
case "volumes:list":
2629
return volumesList(argv, cmdr)
2730
case "volumes:delete":
@@ -55,7 +58,7 @@ Arguments:
5558
<name>
5659
the volume name.
5760
<size>
58-
the volume size, such as '500M'.
61+
the volume size, such as '500G'.
5962
6063
Options:
6164
-a --app=<app>
@@ -75,6 +78,36 @@ Options:
7578
return cmdr.VolumesCreate(app, name, size)
7679
}
7780

81+
func volumesExpand(argv []string, cmdr cmd.Commander) error {
82+
usage := `
83+
Create a volume for the application.
84+
85+
Usage: drycc volumes:expand <name> <size> [options]
86+
87+
Arguments:
88+
<name>
89+
the volume name.
90+
<size>
91+
the volume size, such as '500G'.
92+
93+
Options:
94+
-a --app=<app>
95+
the uniquely identifiable name for the application.
96+
`
97+
98+
args, err := docopt.Parse(usage, argv, true, "", false, true)
99+
100+
if err != nil {
101+
return err
102+
}
103+
104+
app := safeGetValue(args, "--app")
105+
name := safeGetValue(args, "<name>")
106+
size := safeGetValue(args, "<size>")
107+
108+
return cmdr.VolumesExpand(app, name, size)
109+
}
110+
78111
func volumesList(argv []string, cmdr cmd.Commander) error {
79112
usage := `
80113
List volumes in the application.

parser/volumes_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ func (d FakeDryccCmd) VolumesCreate(string, string, string) error {
2020
return errors.New("volumes:create")
2121
}
2222

23+
func (d FakeDryccCmd) VolumesExpand(string, string, string) error {
24+
return errors.New("volumes:expand")
25+
}
26+
2327
func (d FakeDryccCmd) VolumesDelete(string, string) error {
2428
return errors.New("volumes:delete")
2529
}
@@ -50,7 +54,11 @@ func TestVolumes(t *testing.T) {
5054
expected string
5155
}{
5256
{
53-
args: []string{"volumes:create", "myvolume", "500M"},
57+
args: []string{"volumes:create", "myvolume", "500G"},
58+
expected: "",
59+
},
60+
{
61+
args: []string{"volumes:expand", "myvolume", "500G"},
5462
expected: "",
5563
},
5664
{

0 commit comments

Comments
 (0)