Skip to content

Commit 71e761a

Browse files
authored
feat(workflow-cli): add pts cmd
1 parent c77c82a commit 71e761a

19 files changed

Lines changed: 930 additions & 258 deletions

cli/cli.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ var Shortcuts = map[string]string{
1212
"pull": "builds:create",
1313
"rollback": "releases:rollback",
1414
"run": "apps:run",
15-
"scale": "ps:scale",
15+
"scale": "pts:scale",
1616
"sharing": "perms:list",
1717
"sharing:list": "perms:list",
1818
"sharing:add": "perms:create",

cmd/cmd.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ type Commander interface {
3737
CertAttach(string, string) error
3838
CertDetach(string, string) error
3939
ConfigList(string, string) error
40-
ConfigSet(string, string, []string) error
41-
ConfigUnset(string, string, []string) error
40+
ConfigSet(string, string, []string, string) error
41+
ConfigUnset(string, string, []string, string) error
4242
ConfigPull(string, string, string, bool, bool) error
43-
ConfigPush(string, string, string) error
43+
ConfigPush(string, string, string, string) error
4444
DomainsList(string, int) error
4545
DomainsAdd(string, string, string) error
4646
DomainsRemove(string, string) error
@@ -82,9 +82,12 @@ type Commander interface {
8282
PsList(string, int) error
8383
PsLogs(string, string, int, bool, string) error
8484
PsExec(string, string, bool, bool, []string) error
85-
PsScale(string, []string) error
86-
PsRestart(string, []string, string) error
8785
PsDescribe(string, string) error
86+
PsDelete(string, []string) error
87+
PtsList(string, int) error
88+
PtsDescribe(string, string) error
89+
PtsScale(string, []string) error
90+
PtsRestart(string, []string, string) error
8891
RegistryList(string) error
8992
RegistrySet(string, []string) error
9093
RegistryUnset(string, []string) error

cmd/config.go

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package cmd
22

33
import (
4+
"bufio"
45
"bytes"
56
"encoding/base64"
67
"fmt"
78
"os"
89
"regexp"
10+
"runtime"
911
"strings"
1012

1113
"github.com/drycc/controller-sdk-go/api"
@@ -37,18 +39,36 @@ func (d *DryccCmd) ConfigList(appID string, procType string) error {
3739
fmt.Sprintf("%v", configValues[key]),
3840
})
3941
}
42+
43+
// common config
44+
if procType != "" {
45+
table.Append([]string{"--- Common Config:"})
46+
configValues = config.Values
47+
keys = *sortKeys(configValues)
48+
for _, key := range keys {
49+
table.Append([]string{
50+
key,
51+
fmt.Sprintf("%v", configValues[key]),
52+
})
53+
}
54+
}
4055
table.Render()
4156
return nil
4257
}
4358

4459
// ConfigSet sets an app's config variables.
45-
func (d *DryccCmd) ConfigSet(appID string, procType string, configVars []string) error {
60+
func (d *DryccCmd) ConfigSet(appID string, procType string, configVars []string, confirm string) error {
4661
s, appID, err := load(d.ConfigFile, appID)
4762

4863
if err != nil {
4964
return err
5065
}
5166

67+
err = configConfirmAction(procType, confirm)
68+
if err != nil {
69+
return err
70+
}
71+
5272
configMap, err := parseConfig(configVars)
5373
if err != nil {
5474
return err
@@ -97,13 +117,18 @@ to set up healthchecks. This functionality has been deprecated. In the future, p
97117
}
98118

99119
// ConfigUnset removes a config variable from an app.
100-
func (d *DryccCmd) ConfigUnset(appID string, procType string, configVars []string) error {
120+
func (d *DryccCmd) ConfigUnset(appID string, procType string, configVars []string, confirm string) error {
101121
s, appID, err := load(d.ConfigFile, appID)
102122

103123
if err != nil {
104124
return err
105125
}
106126

127+
err = configConfirmAction(procType, confirm)
128+
if err != nil {
129+
return err
130+
}
131+
107132
d.Print("Removing config... ")
108133

109134
quit := progress(d.WOut)
@@ -207,7 +232,7 @@ func (d *DryccCmd) ConfigPull(appID, procType, fileName string, interactive bool
207232
}
208233

209234
// ConfigPush pushes an app's config from a file.
210-
func (d *DryccCmd) ConfigPush(appID, procType string, fileName string) error {
235+
func (d *DryccCmd) ConfigPush(appID, procType string, fileName string, confirm string) error {
211236
stat, err := os.Stdin.Stat()
212237

213238
if err != nil {
@@ -217,10 +242,19 @@ func (d *DryccCmd) ConfigPush(appID, procType string, fileName string) error {
217242
var contents []byte
218243

219244
if (stat.Mode() & os.ModeCharDevice) == 0 {
245+
err = configConfirmActionStdin(procType, confirm)
246+
if err != nil {
247+
return err
248+
}
220249
buffer := new(bytes.Buffer)
221250
buffer.ReadFrom(os.Stdin)
222251
contents = buffer.Bytes()
223252
} else {
253+
err = configConfirmAction(procType, confirm)
254+
if err != nil {
255+
return err
256+
}
257+
224258
contents, err = os.ReadFile(fileName)
225259

226260
if err != nil {
@@ -239,7 +273,7 @@ func (d *DryccCmd) ConfigPush(appID, procType string, fileName string) error {
239273
}
240274
}
241275

242-
return d.ConfigSet(appID, procType, config)
276+
return d.ConfigSet(appID, procType, config, "yes")
243277
}
244278

245279
func parseConfig(configVars []string) (api.ConfigValues, error) {
@@ -304,3 +338,52 @@ func formatConfig(configVars map[string]interface{}) string {
304338

305339
return formattedConfig
306340
}
341+
342+
func configConfirmAction(procType string, confirm string) error {
343+
if procType == "" && (confirm == "" || confirm != "yes") {
344+
fmt.Printf(` ! WARNING: Potentially Config Action
345+
! This command will deploy all processes of the application
346+
! To proceed, type "yes" !
347+
348+
> `)
349+
350+
fmt.Scanln(&confirm)
351+
if confirm != "yes" {
352+
return fmt.Errorf("cancel the config action")
353+
}
354+
}
355+
return nil
356+
}
357+
358+
func configConfirmActionStdin(procType string, confirm string) error {
359+
var reader *bufio.Reader
360+
if runtime.GOOS == "windows" {
361+
reader = bufio.NewReader(os.Stdin)
362+
} else {
363+
file, err := os.Open("/dev/tty")
364+
if err != nil {
365+
return err
366+
}
367+
defer file.Close()
368+
reader = bufio.NewReader(file)
369+
}
370+
371+
if procType == "" && (confirm == "" || confirm != "yes") {
372+
fmt.Printf(` ! WARNING: Potentially Config Action
373+
! This command will deploy all processes of the application
374+
! To proceed, type "yes" !
375+
376+
> `)
377+
378+
confirm, err := reader.ReadString('\n')
379+
if err != nil {
380+
return err
381+
}
382+
383+
confirm = strings.TrimSpace(confirm)
384+
if confirm != "yes" {
385+
return fmt.Errorf("cancel the config action")
386+
}
387+
}
388+
return nil
389+
}

cmd/config_test.go

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,13 @@ TRUE false
136136
b.Reset()
137137
err = cmdr.ConfigList("foo", "web")
138138
assert.NoError(t, err)
139-
assert.Equal(t, b.String(), `NAME VALUE
140-
PORT 9000
139+
assert.Equal(t, b.String(), `NAME VALUE
140+
PORT 9000
141+
--- Common Config:
142+
FLOAT 12.34
143+
NCC 1701
144+
TEST testing
145+
TRUE false
141146
`, "output")
142147

143148
}
@@ -184,7 +189,7 @@ func TestConfigSet(t *testing.T) {
184189
var b bytes.Buffer
185190
cmdr := DryccCmd{WOut: &b, ConfigFile: cf}
186191

187-
err = cmdr.ConfigSet("foo", "", []string{"TRUE=false", "SSH_KEY=-----BEGIN OPENSSH PRIVATE KEY-----"})
192+
err = cmdr.ConfigSet("foo", "", []string{"TRUE=false", "SSH_KEY=-----BEGIN OPENSSH PRIVATE KEY-----"}, "yes")
188193
assert.NoError(t, err)
189194

190195
assert.Equal(t, testutil.StripProgress(b.String()), `Creating config... done
@@ -238,7 +243,7 @@ func TestConfigUnset(t *testing.T) {
238243
var b bytes.Buffer
239244
cmdr := DryccCmd{WOut: &b, ConfigFile: cf}
240245

241-
err = cmdr.ConfigUnset("foo", "", []string{"FOO"})
246+
err = cmdr.ConfigUnset("foo", "", []string{"FOO"}, "yes")
242247
assert.NoError(t, err)
243248

244249
assert.Equal(t, testutil.StripProgress(b.String()), `Removing config... done
@@ -298,15 +303,17 @@ func TestConfigUnsetTypedValues(t *testing.T) {
298303
var b bytes.Buffer
299304
cmdr := DryccCmd{WOut: &b, ConfigFile: cf}
300305

301-
err = cmdr.ConfigUnset("foo", "web", []string{"FOO"})
306+
err = cmdr.ConfigUnset("foo", "web", []string{"FOO"}, "")
302307
assert.NoError(t, err)
303308

304309
assert.Equal(t, testutil.StripProgress(b.String()), `Removing config... done
305310
306-
NAME VALUE
307-
FLOAT 12.34
308-
NCC 1701
309-
TEST testing
310-
TRUE false
311+
NAME VALUE
312+
FLOAT 12.34
313+
NCC 1701
314+
TEST testing
315+
TRUE false
316+
--- Common Config:
317+
RELEASE_VERSION v1
311318
`, "output")
312319
}

cmd/ps.go

Lines changed: 42 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"github.com/containerd/console"
1515
"github.com/drycc/controller-sdk-go/api"
16+
"github.com/drycc/controller-sdk-go/events"
1617
"github.com/drycc/controller-sdk-go/ps"
1718
"github.com/drycc/workflow-cli/pkg/logging"
1819
"golang.org/x/net/websocket"
@@ -103,76 +104,6 @@ func (d *DryccCmd) PsExec(appID, podID string, tty, stdin bool, command []string
103104
return nil
104105
}
105106

106-
// PsScale scales an app's processes.
107-
func (d *DryccCmd) PsScale(appID string, targets []string) error {
108-
s, appID, err := load(d.ConfigFile, appID)
109-
if err != nil {
110-
return err
111-
}
112-
113-
targetMap, err := parsePsTargets(targets)
114-
if err != nil {
115-
return err
116-
}
117-
118-
d.Printf("Scaling processes... but first, %s!\n", drinkOfChoice())
119-
startTime := time.Now()
120-
quit := progress(d.WOut)
121-
122-
err = ps.Scale(s.Client, appID, targetMap)
123-
quit <- true
124-
<-quit
125-
if d.checkAPICompatibility(s.Client, err) != nil {
126-
return err
127-
}
128-
129-
d.Printf("done in %ds\n\n", int(time.Since(startTime).Seconds()))
130-
131-
processes, _, err := ps.List(s.Client, appID, s.Limit)
132-
if err != nil {
133-
return err
134-
}
135-
136-
printProcesses(d, appID, processes)
137-
return nil
138-
}
139-
140-
// PsRestart restarts an app's processes.
141-
func (d *DryccCmd) PsRestart(appID string, targets []string, confirm string) error {
142-
s, appID, err := load(d.ConfigFile, appID)
143-
if err != nil {
144-
return err
145-
}
146-
if len(targets) == 0 && confirm == "" {
147-
d.Printf(` ! WARNING: Potentially Restart Action
148-
! This command will restart all processes of the application
149-
! To proceed, type "yes" !
150-
151-
> `)
152-
153-
fmt.Scanln(&confirm)
154-
if confirm != "yes" {
155-
return fmt.Errorf("cancel the restart action")
156-
}
157-
}
158-
d.Printf("Restarting processes... but first, %s!\n", drinkOfChoice())
159-
startTime := time.Now()
160-
quit := progress(d.WOut)
161-
ptypes := strings.Join(targets, ",")
162-
targetMap := map[string]string{
163-
"types": ptypes,
164-
}
165-
err = ps.Restart(s.Client, appID, targetMap)
166-
quit <- true
167-
<-quit
168-
if err != nil {
169-
return err
170-
}
171-
172-
d.Printf("done in %ds\n", int(time.Since(startTime).Seconds()))
173-
return nil
174-
}
175-
176107
// PsDescribe describe an app's processes.
177108
func (d *DryccCmd) PsDescribe(appID, podID string) error {
178109
s, appID, err := load(d.ConfigFile, appID)
@@ -217,6 +148,47 @@ func (d *DryccCmd) PsDescribe(appID, podID string) error {
217148
table.Append([]string{})
218149
}
219150
table.Render()
151+
// display events
152+
events, _, err := events.ListPodEvents(s.Client, appID, podID, 1000)
153+
if err != nil {
154+
return err
155+
}
156+
if len(events) != 0 {
157+
// table event
158+
te := d.getDefaultFormatTable([]string{})
159+
te.Append([]string{"Events:"})
160+
te.Append([]string{" REASON", "MESSAGE", "CREATED"})
161+
for _, ev := range events {
162+
te.Append([]string{
163+
fmt.Sprintf(" %s", ev.Reason),
164+
ev.Message,
165+
ev.Created.Format("2006-01-02T15:04:05MST"),
166+
})
167+
}
168+
te.Render()
169+
}
170+
return nil
171+
}
172+
173+
// PsDelete delete an pod.
174+
func (d *DryccCmd) PsDelete(appID string, podIDs []string) error {
175+
s, appID, err := load(d.ConfigFile, appID)
176+
177+
if err != nil {
178+
return err
179+
}
180+
pods := strings.Join(podIDs, ",")
181+
d.Printf("Deleting %s from %s... ", pods, appID)
182+
183+
quit := progress(d.WOut)
184+
err = ps.Delete(s.Client, appID, pods)
185+
quit <- true
186+
<-quit
187+
if d.checkAPICompatibility(s.Client, err) != nil {
188+
return err
189+
}
190+
191+
d.Println("done")
220192
return nil
221193
}
222194

0 commit comments

Comments
 (0)