Add --resume-flag to plan run subcommand
Allows to skip phases in plan execution. Change-Id: Iee0e0da5ae9836f27ec1810ac0d333247a6ddb8f Signed-off-by: Ruslan Aliev <raliev@mirantis.com> Closes: #667
This commit is contained in:
parent
4f7a9dbf6d
commit
89bd08e102
@ -39,7 +39,7 @@ Perform a dry run of a plan
|
|||||||
// NewRunCommand creates a command which execute a particular phase plan
|
// NewRunCommand creates a command which execute a particular phase plan
|
||||||
func NewRunCommand(cfgFactory config.Factory) *cobra.Command {
|
func NewRunCommand(cfgFactory config.Factory) *cobra.Command {
|
||||||
r := &phase.PlanRunCommand{Factory: cfgFactory}
|
r := &phase.PlanRunCommand{Factory: cfgFactory}
|
||||||
f := &phase.RunFlags{}
|
f := &phase.PlanRunFlags{}
|
||||||
|
|
||||||
runCmd := &cobra.Command{
|
runCmd := &cobra.Command{
|
||||||
Use: "run PLAN_NAME",
|
Use: "run PLAN_NAME",
|
||||||
@ -55,6 +55,8 @@ func NewRunCommand(cfgFactory config.Factory) *cobra.Command {
|
|||||||
r.Options.DryRun = f.DryRun
|
r.Options.DryRun = f.DryRun
|
||||||
case "wait-timeout":
|
case "wait-timeout":
|
||||||
r.Options.Timeout = &f.Timeout
|
r.Options.Timeout = &f.Timeout
|
||||||
|
case "resume-from":
|
||||||
|
r.Options.ResumeFromPhase = f.ResumeFromPhase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd.Flags().Visit(fn)
|
cmd.Flags().Visit(fn)
|
||||||
@ -63,6 +65,7 @@ func NewRunCommand(cfgFactory config.Factory) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
flags := runCmd.Flags()
|
flags := runCmd.Flags()
|
||||||
|
flags.StringVar(&f.ResumeFromPhase, "resume-from", "", "skip all phases before the specified one")
|
||||||
flags.BoolVar(&f.DryRun, "dry-run", false, "simulate phase execution")
|
flags.BoolVar(&f.DryRun, "dry-run", false, "simulate phase execution")
|
||||||
flags.DurationVar(&f.Timeout, "wait-timeout", 0, "wait timeout")
|
flags.DurationVar(&f.Timeout, "wait-timeout", 0, "wait timeout")
|
||||||
return runCmd
|
return runCmd
|
||||||
|
@ -16,4 +16,5 @@ Perform a dry run of a plan
|
|||||||
Flags:
|
Flags:
|
||||||
--dry-run simulate phase execution
|
--dry-run simulate phase execution
|
||||||
-h, --help help for run
|
-h, --help help for run
|
||||||
|
--resume-from string skip all phases before the specified one
|
||||||
--wait-timeout duration wait timeout
|
--wait-timeout duration wait timeout
|
||||||
|
@ -37,6 +37,7 @@ Options
|
|||||||
|
|
||||||
--dry-run simulate phase execution
|
--dry-run simulate phase execution
|
||||||
-h, --help help for run
|
-h, --help help for run
|
||||||
|
--resume-from string skip all phases before the specified one
|
||||||
--wait-timeout duration wait timeout
|
--wait-timeout duration wait timeout
|
||||||
|
|
||||||
Options inherited from parent commands
|
Options inherited from parent commands
|
||||||
|
@ -270,7 +270,16 @@ func (p *plan) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run function executes Run method for each phase
|
// Run function executes Run method for each phase
|
||||||
func (p *plan) Run(ro ifc.RunOptions) error {
|
func (p *plan) Run(ro ifc.PlanRunOptions) error {
|
||||||
|
if ro.ResumeFromPhase != "" {
|
||||||
|
for i, phase := range p.apiObj.Phases {
|
||||||
|
if phase.Name == ro.ResumeFromPhase {
|
||||||
|
p.apiObj.Phases = p.apiObj.Phases[i:]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, step := range p.apiObj.Phases {
|
for _, step := range p.apiObj.Phases {
|
||||||
phaseRunner, err := p.phaseClient.PhaseByID(ifc.ID{Name: step.Name})
|
phaseRunner, err := p.phaseClient.PhaseByID(ifc.ID{Name: step.Name})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -278,7 +287,7 @@ func (p *plan) Run(ro ifc.RunOptions) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("executing phase: %s\n", step.Name)
|
log.Printf("executing phase: %s\n", step.Name)
|
||||||
if err = phaseRunner.Run(ro); err != nil {
|
if err = phaseRunner.Run(ro.RunOptions); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -436,7 +436,7 @@ func TestPlanRun(t *testing.T) {
|
|||||||
require.NotNil(t, client)
|
require.NotNil(t, client)
|
||||||
p, err := client.PlanByID(tt.planID)
|
p, err := client.PlanByID(tt.planID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = p.Run(ifc.RunOptions{DryRun: true})
|
err = p.Run(ifc.PlanRunOptions{RunOptions: ifc.RunOptions{DryRun: true}})
|
||||||
if tt.errContains != "" {
|
if tt.errContains != "" {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
assert.Contains(t, err.Error(), tt.errContains)
|
assert.Contains(t, err.Error(), tt.errContains)
|
||||||
|
@ -202,12 +202,13 @@ func (c *PlanListCommand) RunE() error {
|
|||||||
// PlanRunFlags options for phase run command
|
// PlanRunFlags options for phase run command
|
||||||
type PlanRunFlags struct {
|
type PlanRunFlags struct {
|
||||||
GenericRunFlags
|
GenericRunFlags
|
||||||
|
ResumeFromPhase string
|
||||||
}
|
}
|
||||||
|
|
||||||
// PlanRunCommand phase run command
|
// PlanRunCommand phase run command
|
||||||
type PlanRunCommand struct {
|
type PlanRunCommand struct {
|
||||||
PlanID ifc.ID
|
PlanID ifc.ID
|
||||||
Options ifc.RunOptions
|
Options ifc.PlanRunOptions
|
||||||
Factory config.Factory
|
Factory config.Factory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,8 +482,10 @@ func TestPlanRunCommand(t *testing.T) {
|
|||||||
tt := tc
|
tt := tc
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
cmd := phase.PlanRunCommand{
|
cmd := phase.PlanRunCommand{
|
||||||
Options: ifc.RunOptions{
|
Options: ifc.PlanRunOptions{
|
||||||
DryRun: true,
|
RunOptions: ifc.RunOptions{
|
||||||
|
DryRun: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Factory: tt.factory,
|
Factory: tt.factory,
|
||||||
PlanID: tt.planID,
|
PlanID: tt.planID,
|
||||||
|
@ -43,6 +43,12 @@ type RunOptions struct {
|
|||||||
Timeout *time.Duration
|
Timeout *time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PlanRunOptions holds options for plan run method
|
||||||
|
type PlanRunOptions struct {
|
||||||
|
RunOptions
|
||||||
|
ResumeFromPhase string
|
||||||
|
}
|
||||||
|
|
||||||
// RenderOptions holds options for render method
|
// RenderOptions holds options for render method
|
||||||
type RenderOptions struct {
|
type RenderOptions struct {
|
||||||
FilterSelector document.Selector
|
FilterSelector document.Selector
|
||||||
|
@ -40,7 +40,7 @@ type PhaseStatus struct {
|
|||||||
// Plan provides a way to interact with phase plans
|
// Plan provides a way to interact with phase plans
|
||||||
type Plan interface {
|
type Plan interface {
|
||||||
Validate() error
|
Validate() error
|
||||||
Run(RunOptions) error
|
Run(PlanRunOptions) error
|
||||||
Status(StatusOptions) (PlanStatus, error)
|
Status(StatusOptions) (PlanStatus, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user