Skip to content

Commit fdcaab5

Browse files
committed
Merge branch 'dev'
2 parents 23f7a59 + 65c9a87 commit fdcaab5

File tree

15 files changed

+167
-6
lines changed

15 files changed

+167
-6
lines changed

README.md

+50-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ steps:
7171

7272
This workflow will run `kubectl apply -f manifest.yml` first. If it returns with exist status 0 (it ran successfully), will then run `kubectl wait --for=condition=complete job/myjob` until it returns with exist status 0 and considers the step successful.
7373

74-
Trackman can continue running if a step fails if the step has a `continue_on_failure: true`.
74+
Trackman can continue running if a step fails if the step has a `continue_on_fail: true`.
7575

7676
### Timeouts
7777

@@ -141,8 +141,45 @@ steps:
141141
message: "Oh nose!"
142142
```
143143

144+
## Workflow Attributes
145+
146+
The following attributes can be set for the workflow:
147+
| Attribute | Description | Default |
148+
|---|---|---|
149+
| version | Workflow format version | `1` |
150+
| version | Any metadata for the workflow | None |
151+
| steps | List of all workflow steps (See below) | [] |
152+
153+
## Step Attributes
154+
155+
The following attributes can be set for each step:
156+
157+
| Attribute | Description | Default |
158+
|---|---|---|
159+
| metadata | Any metadata for the step | None |
160+
| name | Given name for the step | `''` |
161+
| command | Command to run, including arguments | `''` |
162+
| continue_on_fail | Continue to the next step even after failure | `false` |
163+
| timeout | Timeout after which the step will be stopped. A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". | Never |
164+
| workdir | Work directory for the step | None |
165+
| probe | Health probe definition. See above | None |
166+
| depends_on | List of the steps this one depends on (should run after all of them have successfully finished) | [] |
167+
| preflights | List of pre-flight checks (see above) | None |
168+
| ask_to_proceed | Stops the execution of the workflow and asks the user for a confirmation to continue | `false` |
169+
| show_command | Shows the command and arguments for this step before running it | `false` |
170+
144171
## Trackman CLI
145172

173+
### Global Options
174+
175+
The CLI supports the following global options:
176+
177+
| Option | Description | Default |
178+
|---|---|---|
179+
| config | Config file | $HOME/.trackman.yaml |
180+
| log-level | Log level | info |
181+
| no-update | Don't update trackman CLI automatically | false |
182+
146183
### Run
147184

148185
Runs the given workflow. Use `--help` for more details.
@@ -151,6 +188,18 @@ Runs the given workflow. Use `--help` for more details.
151188
$ trackman run -f file.yml
152189
```
153190

191+
### Params
192+
193+
Run command supports the following options
194+
195+
| Option | Description | Default |
196+
|---|---|---|
197+
| file, f | Workflow file | None |
198+
| timeout | Timeout after which the step will be stopped. A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". | 10 seconds |
199+
| concurrency | Number of concurrent steps to run | Number of CPUs - 1 |
200+
| yes, y | Answer Yes to all `ask_to_proceed` questions | false |
201+
202+
154203
### Update
155204

156205
Manually checks for updates. It can also switch the current release channel.

cmd/root.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ var (
2727
func init() {
2828
UpdateDone = &sync.WaitGroup{}
2929
cobra.OnInitialize(initConfig)
30-
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
30+
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.trackman.yaml)")
3131
rootCmd.PersistentFlags().String("log-level", "info", "log level. Use debug to see process output")
3232
rootCmd.PersistentFlags().Bool("no-update", false, "turn off auto update")
3333

cmd/run.go

+2
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@ func init() {
2929
runCmd.Flags().StringVarP(&workflowFile, "file", "f", "", "workflow file to run")
3030
runCmd.Flags().DurationP("timeout", "", 10*time.Second, "global timeout unless overwritten by a step")
3131
runCmd.Flags().IntP("concurrency", "", runtime.NumCPU()-1, "maximum number of concurrent steps to run")
32+
runCmd.Flags().BoolP("yes", "y", false, "Answer Yes to all confirmation questions")
3233

3334
_ = viper.BindPFlag("timeout", runCmd.Flags().Lookup("timeout"))
3435
_ = viper.BindPFlag("concurrency", runCmd.Flags().Lookup("concurrency"))
36+
_ = viper.BindPFlag("confirm.yes", runCmd.Flags().Lookup("yes"))
3537

3638
rootCmd.AddCommand(runCmd)
3739
}

samples/kubernetes/job.yml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: batch/v1
2+
kind: Job
3+
metadata:
4+
name: pi
5+
spec:
6+
template:
7+
spec:
8+
containers:
9+
- name: pi
10+
image: perl
11+
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
12+
restartPolicy: Never
13+
backoffLimit: 4

samples/kubernetes/workflow-1.yml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
version: 1
2+
steps:
3+
- name: run
4+
command: kubectl apply -f job.yml

samples/kubernetes/workflow-2.yml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
version: 1
2+
steps:
3+
- name: run
4+
command: kubectl apply -f job.yml
5+
timeout: 1m
6+
probe:
7+
command: kubectl wait --for=condition=complete job/pi
8+
timeout: 1m

samples/kubernetes/workflow-3.yml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: 1
2+
steps:
3+
- name: run
4+
command: kubectl apply -f job.yml
5+
probe:
6+
command: kubectl wait --for=condition=complete job/pi
7+
timeout: 1m
8+
- name: cleanup
9+
command: kubectl delete job pi
10+
depends_on:
11+
- run

samples/kubernetes/workflow-4.yml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: 1
2+
steps:
3+
- name: run
4+
command: kubectl apply -f job.yml
5+
probe:
6+
command: kubectl wait --for=condition=complete job/pi
7+
timeout: 1m
8+
preflights:
9+
- command: kubectl version
10+
- name: cleanup
11+
command: kubectl delete job pi
12+
depends_on:
13+
- run

samples/timeout.yml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
version: 1
2+
steps:
3+
- name: hello
4+
command: echo "Hello, World!"
5+
depends_on:
6+
- timeout
7+
- name: timeout
8+
ask_to_proceed: true
9+
show_command: true
10+
command: sleep 20
11+
timeout: 10s
12+
continue_on_fail: true

utils/interactive.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package utils
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"log"
7+
"os"
8+
"strings"
9+
)
10+
11+
func confirm(s string, tries int) bool {
12+
r := bufio.NewReader(os.Stdin)
13+
14+
for ; tries > 0; tries-- {
15+
fmt.Printf("%s [y/N]: ", s)
16+
17+
res, err := r.ReadString('\n')
18+
if err != nil {
19+
log.Fatal(err)
20+
}
21+
22+
// Empty input (i.e. "\n")
23+
if len(res) < 2 {
24+
continue
25+
}
26+
27+
return strings.ToLower(strings.TrimSpace(res))[0] == 'y'
28+
}
29+
30+
return false
31+
}

utils/spinner.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ import (
77
"syscall"
88
"time"
99

10-
"github.com/kballard/go-shellquote"
11-
1210
"github.com/google/uuid"
11+
"github.com/kballard/go-shellquote"
1312
"github.com/sirupsen/logrus"
1413
)
1514

@@ -165,6 +164,7 @@ func (s *Spinner) Run(ctx context.Context) error {
165164
errChannel := NewLogWriter(ctx, logrus.ErrorLevel)
166165

167166
logger.WithField(FldStep, s.Name).Tracef("Running %s with %s", s.cmd, s.args)
167+
168168
cmd := exec.CommandContext(cmdCtx, s.cmd, s.args...)
169169
cmd.Stderr = errChannel
170170
cmd.Stdout = outChannel
@@ -183,7 +183,7 @@ func (s *Spinner) Run(ctx context.Context) error {
183183
if cmdCtx.Err() == context.DeadlineExceeded {
184184
s.push(ctx, NewEvent(s, EventRunTimeout, nil))
185185

186-
return fmt.Errorf("step %s timed out after %s", s.step.Name, s.timeout)
186+
return fmt.Errorf("Timed out after %s", s.timeout)
187187
}
188188

189189
if exitErr, ok := err.(*exec.ExitError); ok {

utils/step.go

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ type Step struct {
3232
Probe *Probe `yaml:"probe" json:"probe"`
3333
DependsOn []string `yaml:"depends_on" json:"depends_on"`
3434
Preflights []Preflight `yaml:"preflights" json:"preflights"`
35+
AskToProceed bool `yaml:"ask_to_proceed" json:"ask_to_proceed"`
36+
ShowCommand bool `yaml:"show_command" json:"show_command"`
3537

3638
options *StepOptions
3739
workflow *Workflow

utils/workflow.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import (
99
"time"
1010

1111
"github.com/hashicorp/go-multierror"
12-
1312
"github.com/sirupsen/logrus"
13+
"github.com/spf13/viper"
1414
"golang.org/x/sync/semaphore"
1515
"gopkg.in/yaml.v2"
1616
)
@@ -166,6 +166,18 @@ func (w *Workflow) Run(ctx context.Context) (runErrors error, stepErrors error)
166166

167167
w.logger.WithField(FldStep, toRun.Name).Trace("Preparing to run")
168168

169+
if toRun.ShowCommand {
170+
w.logger.WithField(FldStep, toRun.Name).Info(toRun.Command)
171+
}
172+
173+
if toRun.AskToProceed && !viper.GetBool("confirm.yes") {
174+
// we need an interactive permission for this
175+
if !confirm(fmt.Sprintf("Run %s?", toRun.Name), 1) {
176+
w.logger.WithField(FldStep, toRun.Name).Info("Stopping execution")
177+
w.stop(ctx)
178+
}
179+
}
180+
169181
err := toRun.Run(ctx)
170182
if err != nil {
171183
stepErrors = multierror.Append(err, stepErrors)

vendor/github.com/sirupsen/logrus/go.mod

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/spf13/viper/go.mod

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)