From f4d01ee879341c4b98013a75310adae4ec67c69d Mon Sep 17 00:00:00 2001 From: Helio Machado <0x2b3bfa0+git@googlemail.com> Date: Thu, 20 Oct 2022 15:41:28 +0000 Subject: [PATCH 1/5] Implement `read --follow` --- cmd/leo/read/read.go | 90 +++++++++++++++++++++++++++++++------------- task/aws/task.go | 8 ---- task/az/task.go | 7 ---- task/gcp/task.go | 8 ---- 4 files changed, 64 insertions(+), 49 deletions(-) diff --git a/cmd/leo/read/read.go b/cmd/leo/read/read.go index 6422ae2e..d26fa9a3 100644 --- a/cmd/leo/read/read.go +++ b/cmd/leo/read/read.go @@ -3,7 +3,9 @@ package read import ( "context" "fmt" + "os" "strings" + "time" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -12,12 +14,19 @@ import ( "terraform-provider-iterative/task/common" ) +type status string + +const ( + statusQueued status = "queued" + statusSucceeded status = "succeeded" + statusFailed status = "failed" + statusRunning status = "running" +) + type Options struct { Parallelism int Timestamps bool - Status bool - Events bool - Logs bool + Follow bool } func New(cloud *common.Cloud) *cobra.Command { @@ -35,9 +44,7 @@ func New(cloud *common.Cloud) *cobra.Command { cmd.Flags().IntVar(&o.Parallelism, "parallelism", 1, "parallelism") cmd.Flags().BoolVar(&o.Timestamps, "timestamps", false, "display timestamps") - cmd.Flags().BoolVar(&o.Status, "status", true, "read status") - cmd.Flags().BoolVar(&o.Logs, "logs", false, "read logs") - cmd.MarkFlagsMutuallyExclusive("status", "logs") + cmd.Flags().BoolVar(&o.Follow, "follow", false, "follow logs") return cmd } @@ -62,39 +69,70 @@ func (o *Options) Run(cmd *cobra.Command, args []string, cloud *common.Cloud) er return err } - if err := tsk.Read(ctx); err != nil { - return err - } + for last := 0; ; { + if err := tsk.Read(ctx); err != nil { + return err + } + + logs, err := o.getLogs(ctx, tsk) + if err != nil { + return err + } + status, err := o.getStatus(ctx, tsk) + if err != nil { + return err + } + + delta := strings.Join(logs[last:], "\n") + last = len(logs) - switch { - case o.Logs: - return o.printLogs(ctx, tsk) - case o.Status: - return o.printStatus(ctx, tsk) + if delta != "" { + fmt.Println(delta) + } + + switch o.Follow { + case true: + logrus.SetLevel(logrus.WarnLevel) + case false: + return nil + } + + switch status { + case statusSucceeded: + fmt.Print("\n") + os.Exit(0) + case statusFailed: + fmt.Print("\n") + os.Exit(1) + default: + time.Sleep(3 * time.Second) + } } return nil } -func (o *Options) printLogs(ctx context.Context, tsk task.Task) error { +func (o *Options) getLogs(ctx context.Context, tsk task.Task) ([]string, error) { logs, err := tsk.Logs(ctx) if err != nil { - return err + return nil, err } + var result []string + for _, log := range logs { for _, line := range strings.Split(strings.Trim(log, "\n"), "\n") { if !o.Timestamps { _, line, _ = strings.Cut(line, " ") } - fmt.Println(line) + result = append(result, line) } } - return nil + return result, nil } -func (o *Options) printStatus(ctx context.Context, tsk task.Task) error { +func (o *Options) getStatus(ctx context.Context, tsk task.Task) (status, error) { for _, event := range tsk.Events(ctx) { line := fmt.Sprintf("%s: %s", event.Code, strings.Join(event.Description, " ")) if o.Timestamps { @@ -106,21 +144,21 @@ func (o *Options) printStatus(ctx context.Context, tsk task.Task) error { status, err := tsk.Status(ctx) if err != nil { - return err + return "", err } - message := "queued" + result := statusQueued if status["succeeded"] >= o.Parallelism { - message = "succeeded" + result = statusSucceeded } if status["failed"] > 0 { - message = "failed" + result = statusFailed } if status["running"] >= o.Parallelism { - message = "running" + result = statusRunning } - fmt.Println(message) - return nil + logrus.Debug(result) + return result, nil } diff --git a/task/aws/task.go b/task/aws/task.go index 9de5df93..64588164 100644 --- a/task/aws/task.go +++ b/task/aws/task.go @@ -255,10 +255,6 @@ func (t *Task) Delete(ctx context.Context) error { } func (t *Task) Logs(ctx context.Context) ([]string, error) { - if err := t.Read(ctx); err != nil { - return nil, err - } - return machine.Logs(ctx, t.DataSources.Credentials.Resource["RCLONE_REMOTE"]) } @@ -299,10 +295,6 @@ func (t *Task) Events(ctx context.Context) []common.Event { } func (t *Task) Status(ctx context.Context) (common.Status, error) { - if err := t.Read(ctx); err != nil { - return nil, err - } - return machine.Status(ctx, t.DataSources.Credentials.Resource["RCLONE_REMOTE"], t.Attributes.Status) } diff --git a/task/az/task.go b/task/az/task.go index 304d813a..b3563a80 100644 --- a/task/az/task.go +++ b/task/az/task.go @@ -251,10 +251,6 @@ func (t *Task) Delete(ctx context.Context) error { } func (t *Task) Logs(ctx context.Context) ([]string, error) { - if err := t.Read(ctx); err != nil { - return nil, err - } - return machine.Logs(ctx, t.DataSources.Credentials.Resource["RCLONE_REMOTE"]) } @@ -295,9 +291,6 @@ func (t *Task) Events(ctx context.Context) []common.Event { } func (t *Task) Status(ctx context.Context) (common.Status, error) { - if err := t.Read(ctx); err != nil { - return nil, err - } return machine.Status(ctx, t.DataSources.Credentials.Resource["RCLONE_REMOTE"], t.Attributes.Status) } diff --git a/task/gcp/task.go b/task/gcp/task.go index 687fcd66..38e1e1dc 100644 --- a/task/gcp/task.go +++ b/task/gcp/task.go @@ -330,10 +330,6 @@ func (t *Task) Delete(ctx context.Context) error { } func (t *Task) Logs(ctx context.Context) ([]string, error) { - if err := t.Read(ctx); err != nil { - return nil, err - } - return machine.Logs(ctx, t.DataSources.Credentials.Resource["RCLONE_REMOTE"]) } @@ -374,10 +370,6 @@ func (t *Task) Events(ctx context.Context) []common.Event { } func (t *Task) Status(ctx context.Context) (common.Status, error) { - if err := t.Read(ctx); err != nil { - return nil, err - } - return machine.Status(ctx, t.DataSources.Credentials.Resource["RCLONE_REMOTE"], t.Attributes.Status) } From 7b03fbed0e4f87779a9f29f5727c31f57f609a22 Mon Sep 17 00:00:00 2001 From: Helio Machado <0x2b3bfa0+git@googlemail.com> Date: Thu, 20 Oct 2022 15:56:55 +0000 Subject: [PATCH 2/5] Avoid timeout on `--watch` --- cmd/leo/read/read.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/leo/read/read.go b/cmd/leo/read/read.go index d26fa9a3..3dafaa8a 100644 --- a/cmd/leo/read/read.go +++ b/cmd/leo/read/read.go @@ -93,6 +93,7 @@ func (o *Options) Run(cmd *cobra.Command, args []string, cloud *common.Cloud) er switch o.Follow { case true: logrus.SetLevel(logrus.WarnLevel) + ctx = context.Background() case false: return nil } From 44f5d9fa8cd4c49c826c1de340c9908950e9a847 Mon Sep 17 00:00:00 2001 From: Helio Machado <0x2b3bfa0+git@googlemail.com> Date: Fri, 21 Oct 2022 05:06:29 +0200 Subject: [PATCH 3/5] Simplify logic --- cmd/leo/read/read.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/cmd/leo/read/read.go b/cmd/leo/read/read.go index 3dafaa8a..8ee1f619 100644 --- a/cmd/leo/read/read.go +++ b/cmd/leo/read/read.go @@ -69,7 +69,7 @@ func (o *Options) Run(cmd *cobra.Command, args []string, cloud *common.Cloud) er return err } - for last := 0; ; { + for last := 0;; { if err := tsk.Read(ctx); err != nil { return err } @@ -78,16 +78,15 @@ func (o *Options) Run(cmd *cobra.Command, args []string, cloud *common.Cloud) er if err != nil { return err } + status, err := o.getStatus(ctx, tsk) if err != nil { return err } - delta := strings.Join(logs[last:], "\n") - last = len(logs) - - if delta != "" { + if delta := strings.Join(logs[last:], "\n"); delta != "" { fmt.Println(delta) + last = len(logs) } switch o.Follow { @@ -100,17 +99,13 @@ func (o *Options) Run(cmd *cobra.Command, args []string, cloud *common.Cloud) er switch status { case statusSucceeded: - fmt.Print("\n") os.Exit(0) case statusFailed: - fmt.Print("\n") os.Exit(1) default: time.Sleep(3 * time.Second) } } - - return nil } func (o *Options) getLogs(ctx context.Context, tsk task.Task) ([]string, error) { From 7347e8b5825e531dc3f021526b8e7dd8aba5020d Mon Sep 17 00:00:00 2001 From: Helio Machado <0x2b3bfa0+git@googlemail.com> Date: Fri, 21 Oct 2022 05:23:40 +0000 Subject: [PATCH 4/5] Improve timeout logic --- cmd/leo/read/read.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cmd/leo/read/read.go b/cmd/leo/read/read.go index 8ee1f619..1db2da3e 100644 --- a/cmd/leo/read/read.go +++ b/cmd/leo/read/read.go @@ -57,7 +57,6 @@ func (o *Options) Run(cmd *cobra.Command, args []string, cloud *common.Cloud) er } ctx, cancel := context.WithTimeout(context.Background(), cloud.Timeouts.Read) - defer cancel() id, err := common.ParseIdentifier(args[0]) if err != nil { @@ -69,7 +68,7 @@ func (o *Options) Run(cmd *cobra.Command, args []string, cloud *common.Cloud) er return err } - for last := 0;; { + for last := 0; ; { if err := tsk.Read(ctx); err != nil { return err } @@ -91,8 +90,11 @@ func (o *Options) Run(cmd *cobra.Command, args []string, cloud *common.Cloud) er switch o.Follow { case true: + // disable debug logs for subsequent iterations logrus.SetLevel(logrus.WarnLevel) - ctx = context.Background() + // create a new context to reset timeout on every iteration + ctx, cancel = context.WithTimeout(context.Background(), cloud.Timeouts.Read) + defer cancel() case false: return nil } @@ -145,13 +147,13 @@ func (o *Options) getStatus(ctx context.Context, tsk task.Task) (status, error) result := statusQueued - if status["succeeded"] >= o.Parallelism { + if status[common.StatusCodeSucceeded] >= o.Parallelism { result = statusSucceeded } - if status["failed"] > 0 { + if status[common.StatusCodeFailed] > 0 { result = statusFailed } - if status["running"] >= o.Parallelism { + if status[common.StatusCodeActive] >= o.Parallelism { result = statusRunning } From 173f95b1c63740628105aebf3034e18b905ceb27 Mon Sep 17 00:00:00 2001 From: Helio Machado <0x2b3bfa0+git@googlemail.com> Date: Fri, 21 Oct 2022 11:25:59 +0200 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: Domas Monkus --- cmd/leo/read/read.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/leo/read/read.go b/cmd/leo/read/read.go index 1db2da3e..4b473584 100644 --- a/cmd/leo/read/read.go +++ b/cmd/leo/read/read.go @@ -68,7 +68,8 @@ func (o *Options) Run(cmd *cobra.Command, args []string, cloud *common.Cloud) er return err } - for last := 0; ; { + var last int + for { if err := tsk.Read(ctx); err != nil { return err }