Skip to content

Commit

Permalink
Merge pull request #909 from Scalingo/feat/901/run_attached_one_off_a…
Browse files Browse the repository at this point in the history
…synchronously

feat(one-off): allow attached one-off to be run asynchronously
  • Loading branch information
ipfaze authored Mar 20, 2023
2 parents 95702c5 + 2c17bff commit 7b9b8df
Show file tree
Hide file tree
Showing 22 changed files with 483 additions and 41 deletions.
52 changes: 43 additions & 9 deletions apps/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,26 @@ import (
"path/filepath"
"time"

"gopkg.in/errgo.v1"

"github.com/Scalingo/cli/config"
"github.com/Scalingo/cli/io"
"github.com/Scalingo/go-scalingo/v6"
scalingo "github.com/Scalingo/go-scalingo/v6"
errors "github.com/Scalingo/go-utils/errors/v2"
)

func handleOperation(ctx context.Context, app string, res *http.Response) error {
opURL, err := url.Parse(res.Header.Get("Location"))
operationURL := res.Header.Get("Location")
return handleOperationWithURL(ctx, app, operationURL)
}

func handleOperationWithURL(ctx context.Context, app string, operationURL string, containerLabel ...string) error {
opURL, err := url.Parse(operationURL)
if err != nil {
return errgo.Mask(err)
return errors.Notef(ctx, err, "parse url of operation")
}

c, err := config.ScalingoClient(ctx)
if err != nil {
return errgo.Notef(err, "fail to get Scalingo client")
return errors.Notef(ctx, err, "get Scalingo client")
}

var op *scalingo.Operation
Expand All @@ -35,6 +39,11 @@ func handleOperation(ctx context.Context, app string, res *http.Response) error
defer close(done)
defer close(errs)

op, err = c.OperationsShow(ctx, app, opID)
if err != nil {
return errors.Notef(ctx, err, "get operation %v", opID)
}

go func() {
for {
op, err = c.OperationsShow(ctx, app, opID)
Expand All @@ -51,23 +60,48 @@ func handleOperation(ctx context.Context, app string, res *http.Response) error
}
}()

fmt.Print("Status: ")
if op.Type == scalingo.OperationTypeStartOneOff {
fmt.Printf("-----> Starting container %v ", containerLabel)
} else {
fmt.Print("Status: ")
}
spinner := io.NewSpinner(os.Stderr)
go spinner.Start()
defer spinner.Stop()

for {
select {
case err := <-errs:
return errgo.Mask(err)
return errors.Notef(ctx, err, "get operation %v", op.ID)
case <-done:
if op.Status == "done" {
fmt.Printf("\bDone in %.3f seconds\n", op.ElapsedDuration())
return nil
} else if op.Status == "error" {
fmt.Printf("\bOperation '%s' failed, an error occurred: %v\n", op.Type, op.Error)
return nil
return errors.Newf(ctx, "operation %v failed", op.ID)
}
}
}
}

func GetAttachURLFromOperationWithURL(ctx context.Context, app string, operationURL string) (string, error) {
opURL, err := url.Parse(operationURL)
if err != nil {
return "", errors.Notef(ctx, err, "parse url of operation")
}

c, err := config.ScalingoClient(ctx)
if err != nil {
return "", errors.Notef(ctx, err, "get Scalingo client")
}

var operation *scalingo.Operation
opID := filepath.Base(opURL.Path)
operation, err = c.OperationsShow(ctx, app, opID)
if err != nil {
return "", errors.Notef(ctx, err, "get operation %v", opID)
}

return operation.StartOneOffData.AttachURL, nil
}
32 changes: 26 additions & 6 deletions apps/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"runtime"
"strings"

"gopkg.in/errgo.v1"
errgo "gopkg.in/errgo.v1"

"github.com/Scalingo/cli/apps/run"
"github.com/Scalingo/cli/config"
Expand All @@ -37,6 +37,7 @@ type RunOpts struct {
DisplayCmd string
Silent bool
Detached bool
Async bool
Size string
Type string
Cmd []string
Expand All @@ -58,7 +59,7 @@ type runContext struct {
func Run(ctx context.Context, opts RunOpts) error {
c, err := config.ScalingoClient(ctx)
if err != nil {
return errgo.Notef(err, "fail to get Scalingo client")
return errgo.Notef(err, "get Scalingo client")
}

firstReadDone := make(chan struct{})
Expand Down Expand Up @@ -103,6 +104,9 @@ func Run(ctx context.Context, opts RunOpts) error {
if opts.StdoutCopyFunc != nil {
runCtx.stdoutCopyFunc = opts.StdoutCopyFunc
}
if opts.Detached {
opts.Async = false
}

env, err := runCtx.buildEnv(opts.CmdEnv)
if err != nil {
Expand All @@ -122,10 +126,13 @@ func Run(ctx context.Context, opts RunOpts) error {
Env: env,
Size: opts.Size,
Detached: opts.Detached,
})
Async: opts.Async,
},
)
if err != nil {
return errgo.Mask(err, errgo.Any)
}

debug.Printf("%+v\n", runRes)

if opts.Detached {
Expand All @@ -138,7 +145,17 @@ func Run(ctx context.Context, opts RunOpts) error {
return nil
}

runCtx.attachURL = runRes.AttachURL
err = handleOperationWithURL(ctx, opts.App, runRes.OperationURL, runRes.Container.Label)
if err != nil {
return errgo.Mask(err, errgo.Any)
}

attachURL, err := GetAttachURLFromOperationWithURL(ctx, opts.App, runRes.OperationURL)
if err != nil {
return errgo.Mask(err, errgo.Any)
}

runCtx.attachURL = attachURL
debug.Println("Run Service URL is", runCtx.attachURL)

if len(opts.Files) > 0 {
Expand Down Expand Up @@ -221,6 +238,9 @@ func Run(ctx context.Context, opts RunOpts) error {
}()

_, err = runCtx.stdoutCopyFunc(os.Stdout, socket)
if err != nil {
return errgo.Mask(err, errgo.Any)
}

stopSignalsMonitoring <- true

Expand All @@ -235,11 +255,11 @@ func Run(ctx context.Context, opts RunOpts) error {
return errgo.Mask(err, errgo.Any)
}

os.Exit(exitCode)
defer os.Exit(exitCode)
return nil
}

func (ctx *runContext) buildEnv(cmdEnv []string) (map[string]string, error) {
func (runCtx *runContext) buildEnv(cmdEnv []string) (map[string]string, error) {
env := map[string]string{
"TERM": os.Getenv("TERM"),
"CLIENT_OS": runtime.GOOS,
Expand Down
1 change: 1 addition & 0 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ var (
Files: c.StringSlice("f"),
Silent: c.Bool("silent"),
Detached: c.Bool("detached"),
Async: true,
}
if (c.Args().Len() == 0 && c.String("t") == "") || (c.Args().Len() > 0 && c.String("t") != "") {
cli.ShowCommandHelp(c, "run")
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ go 1.20
require (
github.com/AlecAivazis/survey/v2 v2.3.6
github.com/ScaleFT/sshkeys v1.2.0
github.com/Scalingo/go-scalingo/v6 v6.3.0
github.com/Scalingo/go-scalingo/v6 v6.4.0
github.com/Scalingo/go-utils/errors v1.1.1
github.com/Scalingo/go-utils/errors/v2 v2.2.0
github.com/Scalingo/go-utils/logger v1.2.0
github.com/Scalingo/go-utils/retry v1.1.1
github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0A
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
github.com/ScaleFT/sshkeys v1.2.0 h1:5BRp6rTVIhJzXT3VcUQrKgXR8zWA3sOsNeuyW15WUA8=
github.com/ScaleFT/sshkeys v1.2.0/go.mod h1:gxOHeajFfvGQh/fxlC8oOKBe23xnnJTif00IFFbiT+o=
github.com/Scalingo/go-scalingo/v6 v6.3.0 h1:ADtzCCEqx1pdI6VaiOh3u9l8L2tScPp6cIKzvo/lcgE=
github.com/Scalingo/go-scalingo/v6 v6.3.0/go.mod h1:Y3QByF4s5i3lpJh87c5FEkSN07CWomN5FPt0X/Qzg0I=
github.com/Scalingo/go-scalingo/v6 v6.4.0 h1:kkSJlPE0SavvO7yrH8dpdYIw2te8d0th5NzkAISS/BY=
github.com/Scalingo/go-scalingo/v6 v6.4.0/go.mod h1:u3ROWLWw78ug4EQaunzOBzSPKy4ukNQTDrCFaKMG938=
github.com/Scalingo/go-utils/errors v1.1.1 h1:G7zypaDBj0O6QFvX0xL5dMDXbiBgq+3KKuodldtOpg0=
github.com/Scalingo/go-utils/errors v1.1.1/go.mod h1:gsnGOMma5x3CSgPb8i5eMuHcKi3RvTJ9dWPNRev161c=
github.com/Scalingo/go-utils/errors/v2 v2.2.0 h1:n93hge0DzfZ3KbI/jdnxKDTRDD+PXsGwNPKyHRzQYEE=
github.com/Scalingo/go-utils/errors/v2 v2.2.0/go.mod h1:pkLy6Qz9UNm6FpXtFJGZRC0W5lqbqHpPchrQV80gw5E=
github.com/Scalingo/go-utils/logger v1.2.0 h1:E3jtaoRxpIsFcZu/jsvWew8ttUAwKUYQufdPqGYp7EU=
github.com/Scalingo/go-utils/logger v1.2.0/go.mod h1:JArjD1gHdB/vwnlcVG7rYxuIY0tk8/VG4MtirnRwn8k=
github.com/Scalingo/go-utils/retry v1.1.1 h1:zc5HbXbBzf0fo7zMvhEMvx75qaL2FH7SxDhCoBfS7jE=
Expand Down
6 changes: 6 additions & 0 deletions vendor/github.com/Scalingo/go-scalingo/v6/CHANGELOG.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions vendor/github.com/Scalingo/go-scalingo/v6/Dockerfile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions vendor/github.com/Scalingo/go-scalingo/v6/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion vendor/github.com/Scalingo/go-scalingo/v6/backups.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions vendor/github.com/Scalingo/go-scalingo/v6/deployments.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 16 additions & 9 deletions vendor/github.com/Scalingo/go-scalingo/v6/operations.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 10 additions & 6 deletions vendor/github.com/Scalingo/go-scalingo/v6/run.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vendor/github.com/Scalingo/go-scalingo/v6/version.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 7b9b8df

Please sign in to comment.