Remove wait flags from the preview command

This commit is contained in:
Morten Torkildsen 2020-04-22 16:55:06 -07:00
parent 44ebecf23a
commit a2a4ed6d12
5 changed files with 54 additions and 49 deletions

View File

@ -7,6 +7,7 @@ import (
"context" "context"
"fmt" "fmt"
"strings" "strings"
"time"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
@ -47,6 +48,13 @@ func GetApplyRunner(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *A
cmd.Flags().StringVar(&r.output, "output", printers.DefaultPrinter(), cmd.Flags().StringVar(&r.output, "output", printers.DefaultPrinter(),
fmt.Sprintf("Output format, must be one of %s", strings.Join(printers.SupportedPrinters(), ","))) fmt.Sprintf("Output format, must be one of %s", strings.Join(printers.SupportedPrinters(), ",")))
cmd.Flags().BoolVar(&r.wait, "wait-for-reconcile", false,
"Wait for all applied resources to reach the Current status.")
cmd.Flags().DurationVar(&r.period, "wait-polling-period", 2*time.Second,
"Polling period for resource statuses.")
cmd.Flags().DurationVar(&r.timeout, "wait-timeout", time.Minute,
"Timeout threshold for waiting for all resources to reach the Current status.")
r.command = cmd r.command = cmd
return r return r
} }
@ -60,7 +68,10 @@ type ApplyRunner struct {
ioStreams genericclioptions.IOStreams ioStreams genericclioptions.IOStreams
applier *apply.Applier applier *apply.Applier
output string output string
wait bool
period time.Duration
timeout time.Duration
} }
func (r *ApplyRunner) Run(cmd *cobra.Command, args []string) { func (r *ApplyRunner) Run(cmd *cobra.Command, args []string) {
@ -69,9 +80,12 @@ func (r *ApplyRunner) Run(cmd *cobra.Command, args []string) {
// Run the applier. It will return a channel where we can receive updates // Run the applier. It will return a channel where we can receive updates
// to keep track of progress and any issues. // to keep track of progress and any issues.
ch := r.applier.Run(context.Background(), apply.Options{ ch := r.applier.Run(context.Background(), apply.Options{
WaitForReconcile: r.wait,
PollInterval: r.period,
WaitTimeout: r.timeout,
// If we are not waiting for status, tell the applier to not // If we are not waiting for status, tell the applier to not
// emit the events. // emit the events.
EmitStatusEvents: r.applier.StatusOptions.Wait, EmitStatusEvents: r.wait,
}) })
// The printer will print updates from the channel. It will block // The printer will print updates from the channel. It will block

View File

@ -39,9 +39,8 @@ func NewCmdPreview(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *co
applier.DryRun = true applier.DryRun = true
cmdutil.CheckErr(applier.Initialize(cmd, args)) cmdutil.CheckErr(applier.Initialize(cmd, args))
// Create a context with the provided timout from the cobra parameter. // Create a context
ctx, cancel := context.WithTimeout(context.Background(), applier.StatusOptions.Timeout) ctx := context.Background()
defer cancel()
// Run the applier. It will return a channel where we can receive updates // Run the applier. It will return a channel where we can receive updates
// to keep track of progress and any issues. // to keep track of progress and any issues.

View File

@ -7,6 +7,7 @@ import (
"context" "context"
"fmt" "fmt"
"sort" "sort"
"time"
"github.com/go-errors/errors" "github.com/go-errors/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -36,8 +37,7 @@ import (
func NewApplier(factory util.Factory, ioStreams genericclioptions.IOStreams) *Applier { func NewApplier(factory util.Factory, ioStreams genericclioptions.IOStreams) *Applier {
applyOptions := apply.NewApplyOptions(ioStreams) applyOptions := apply.NewApplyOptions(ioStreams)
return &Applier{ return &Applier{
ApplyOptions: applyOptions, ApplyOptions: applyOptions,
StatusOptions: NewStatusOptions(),
// VisitedUids keeps track of the unique identifiers for all // VisitedUids keeps track of the unique identifiers for all
// currently applied objects. Used to calculate prune set. // currently applied objects. Used to calculate prune set.
PruneOptions: prune.NewPruneOptions(applyOptions.VisitedUids), PruneOptions: prune.NewPruneOptions(applyOptions.VisitedUids),
@ -60,10 +60,9 @@ type Applier struct {
factory util.Factory factory util.Factory
ioStreams genericclioptions.IOStreams ioStreams genericclioptions.IOStreams
ApplyOptions *apply.ApplyOptions ApplyOptions *apply.ApplyOptions
StatusOptions *StatusOptions PruneOptions *prune.PruneOptions
PruneOptions *prune.PruneOptions statusPoller poller.Poller
statusPoller poller.Poller
NoPrune bool NoPrune bool
DryRun bool DryRun bool
@ -118,7 +117,6 @@ func (a *Applier) SetFlags(cmd *cobra.Command) error {
_ = cmd.Flags().MarkHidden("grace-period") _ = cmd.Flags().MarkHidden("grace-period")
_ = cmd.Flags().MarkHidden("timeout") _ = cmd.Flags().MarkHidden("timeout")
_ = cmd.Flags().MarkHidden("wait") _ = cmd.Flags().MarkHidden("wait")
a.StatusOptions.AddFlags(cmd)
a.ApplyOptions.Overwrite = true a.ApplyOptions.Overwrite = true
return nil return nil
} }
@ -204,6 +202,7 @@ func splitInfos(infos []*resource.Info) ([]*resource.Info, []*resource.Info) {
// resources to become current. // resources to become current.
func (a *Applier) Run(ctx context.Context, options Options) <-chan event.Event { func (a *Applier) Run(ctx context.Context, options Options) <-chan event.Event {
eventChannel := make(chan event.Event) eventChannel := make(chan event.Event)
setDefaults(&options)
go func() { go func() {
defer close(eventChannel) defer close(eventChannel)
@ -235,8 +234,8 @@ func (a *Applier) Run(ctx context.Context, options Options) <-chan event.Event {
ApplyOptions: a.ApplyOptions, ApplyOptions: a.ApplyOptions,
PruneOptions: a.PruneOptions, PruneOptions: a.PruneOptions,
}).BuildTaskQueue(infos, solver.Options{ }).BuildTaskQueue(infos, solver.Options{
WaitForReconcile: a.StatusOptions.Wait, WaitForReconcile: options.WaitForReconcile,
WaitForReconcileTimeout: a.StatusOptions.Timeout, WaitForReconcileTimeout: options.WaitTimeout,
Prune: !a.NoPrune, Prune: !a.NoPrune,
}) })
@ -257,7 +256,7 @@ func (a *Applier) Run(ctx context.Context, options Options) <-chan event.Event {
// Create a new TaskStatusRunner to execute the taskQueue. // Create a new TaskStatusRunner to execute the taskQueue.
runner := taskrunner.NewTaskStatusRunner(identifiers, a.statusPoller) runner := taskrunner.NewTaskStatusRunner(identifiers, a.statusPoller)
err = runner.Run(ctx, taskQueue, eventChannel, taskrunner.Options{ err = runner.Run(ctx, taskQueue, eventChannel, taskrunner.Options{
PollInterval: a.StatusOptions.period, PollInterval: options.PollInterval,
UseCache: true, UseCache: true,
EmitStatusEvents: options.EmitStatusEvents, EmitStatusEvents: options.EmitStatusEvents,
}) })
@ -269,9 +268,35 @@ func (a *Applier) Run(ctx context.Context, options Options) <-chan event.Event {
} }
type Options struct { type Options struct {
// WaitForReconcile defines whether the applier should wait
// until all applied resources have been reconciled before
// pruning and exiting.
WaitForReconcile bool
// PollInterval defines how often we should poll for the status
// of resources.
PollInterval time.Duration
// WaitTimeout defines how long we should wait for resources
// to be reconciled before giving up.
WaitTimeout time.Duration
// EmitStatusEvents defines whether status events should be
// emitted on the eventChannel to the caller.
EmitStatusEvents bool EmitStatusEvents bool
} }
// setDefaults set the options to the default values if they
// have not been provided.
func setDefaults(o *Options) {
if o.PollInterval == time.Duration(0) {
o.PollInterval = 2 * time.Second
}
if o.WaitTimeout == time.Duration(0) {
o.WaitTimeout = time.Minute
}
}
func handleError(eventChannel chan event.Event, err error) { func handleError(eventChannel chan event.Event, err error) {
eventChannel <- event.Event{ eventChannel <- event.Event{
Type: event.ErrorType, Type: event.ErrorType,

View File

@ -14,7 +14,6 @@ import (
"path/filepath" "path/filepath"
"regexp" "regexp"
"testing" "testing"
"time"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -229,9 +228,6 @@ func TestApplier(t *testing.T) {
ioStreams, _, _, _ := genericclioptions.NewTestIOStreams() //nolint:dogsled ioStreams, _, _, _ := genericclioptions.NewTestIOStreams() //nolint:dogsled
applier := NewApplier(tf, ioStreams) applier := NewApplier(tf, ioStreams)
applier.StatusOptions.period = 2 * time.Second
applier.StatusOptions.Wait = tc.status
applier.NoPrune = !tc.prune applier.NoPrune = !tc.prune
cmd := &cobra.Command{} cmd := &cobra.Command{}
@ -252,6 +248,7 @@ func TestApplier(t *testing.T) {
ctx := context.Background() ctx := context.Background()
eventChannel := applier.Run(ctx, Options{ eventChannel := applier.Run(ctx, Options{
WaitForReconcile: tc.status,
EmitStatusEvents: true, EmitStatusEvents: true,
}) })

View File

@ -1,30 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package apply
import (
"time"
"github.com/spf13/cobra"
)
func NewStatusOptions() *StatusOptions {
return &StatusOptions{
Wait: false,
period: 2 * time.Second,
Timeout: time.Minute,
}
}
type StatusOptions struct {
Wait bool
period time.Duration
Timeout time.Duration
}
func (s *StatusOptions) AddFlags(c *cobra.Command) {
c.Flags().BoolVar(&s.Wait, "wait-for-reconcile", s.Wait, "Wait for all applied resources to reach the Current status.")
c.Flags().DurationVar(&s.period, "wait-polling-period", s.period, "Polling period for resource statuses.")
c.Flags().DurationVar(&s.Timeout, "wait-timeout", s.Timeout, "Timeout threshold for waiting for all resources to reach the Current status.")
}