[cloud] handle unreachable run tasks
This commit is contained in:
parent
3e9ae69a12
commit
2938ec43fa
|
@ -351,9 +351,10 @@ in order to capture the filesystem context the remote workspace expects:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Await collective run tasks
|
// Await pre-apply run tasks
|
||||||
if len(r.TaskStage) > 0 {
|
if len(r.TaskStage) > 0 {
|
||||||
context := NewIntegrationContext(stopCtx, cancelCtx, b, op, r)
|
context := NewIntegrationContext(stopCtx, cancelCtx, b, op, r)
|
||||||
|
// TODO: this only works while there is exactly 1 task stage
|
||||||
err = b.runTasks(context, context.BeginOutput("Run Tasks (pre-apply)"), r.TaskStage[0].ID)
|
err = b.runTasks(context, context.BeginOutput("Run Tasks (pre-apply)"), r.TaskStage[0].ID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type taskResultSummary struct {
|
type taskResultSummary struct {
|
||||||
|
unreachable bool
|
||||||
pending int
|
pending int
|
||||||
failed int
|
failed int
|
||||||
failedMandatory int
|
failedMandatory int
|
||||||
|
@ -17,10 +18,14 @@ type taskResultSummary struct {
|
||||||
|
|
||||||
type taskStageReadFunc func(b *Cloud, stopCtx context.Context) (*tfe.TaskStage, error)
|
type taskStageReadFunc func(b *Cloud, stopCtx context.Context) (*tfe.TaskStage, error)
|
||||||
|
|
||||||
func summarizeTaskResults(taskResults []*tfe.TaskResult) taskResultSummary {
|
func summarizeTaskResults(taskResults []*tfe.TaskResult) *taskResultSummary {
|
||||||
var pe, er, erm, pa int
|
var pe, er, erm, pa int
|
||||||
for _, task := range taskResults {
|
for _, task := range taskResults {
|
||||||
if task.Status == "running" || task.Status == "pending" {
|
if task.Status == "unreachable" {
|
||||||
|
return &taskResultSummary{
|
||||||
|
unreachable: true,
|
||||||
|
}
|
||||||
|
} else if task.Status == "running" || task.Status == "pending" {
|
||||||
pe++
|
pe++
|
||||||
} else if task.Status == "passed" {
|
} else if task.Status == "passed" {
|
||||||
pa++
|
pa++
|
||||||
|
@ -33,7 +38,8 @@ func summarizeTaskResults(taskResults []*tfe.TaskResult) taskResultSummary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return taskResultSummary{
|
return &taskResultSummary{
|
||||||
|
unreachable: false,
|
||||||
pending: pe,
|
pending: pe,
|
||||||
failed: er,
|
failed: er,
|
||||||
failedMandatory: erm,
|
failedMandatory: erm,
|
||||||
|
@ -41,19 +47,7 @@ func summarizeTaskResults(taskResults []*tfe.TaskResult) taskResultSummary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// elapsedMessageMax is 50 chars: the length of this message with 6 digits
|
|
||||||
// 99 tasks still pending, 99 passed, 99 failed ...
|
|
||||||
const elapsedMessageMax int = 50
|
|
||||||
|
|
||||||
func (b *Cloud) runTasksWithTaskResults(context *IntegrationContext, output IntegrationOutputWriter, fetchTaskStage taskStageReadFunc) error {
|
func (b *Cloud) runTasksWithTaskResults(context *IntegrationContext, output IntegrationOutputWriter, fetchTaskStage taskStageReadFunc) error {
|
||||||
// TODO: Do not fetch run tasks if there are no changes to infrastructure
|
|
||||||
// if !context.Run.HasChanges {
|
|
||||||
// output.Output("No Changes. Tasks will not run")
|
|
||||||
// output.End()
|
|
||||||
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
return context.Poll(func(i int) (bool, error) {
|
return context.Poll(func(i int) (bool, error) {
|
||||||
// TODO: get the stage that corresponds to an argument passed to this function
|
// TODO: get the stage that corresponds to an argument passed to this function
|
||||||
stage, err := fetchTaskStage(b, context.StopContext)
|
stage, err := fetchTaskStage(b, context.StopContext)
|
||||||
|
@ -63,12 +57,20 @@ func (b *Cloud) runTasksWithTaskResults(context *IntegrationContext, output Inte
|
||||||
}
|
}
|
||||||
|
|
||||||
summary := summarizeTaskResults(stage.TaskResults)
|
summary := summarizeTaskResults(stage.TaskResults)
|
||||||
|
|
||||||
|
if summary.unreachable {
|
||||||
|
output.Output("Skipping task results.")
|
||||||
|
output.End()
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
if summary.pending > 0 {
|
if summary.pending > 0 {
|
||||||
message := fmt.Sprintf("%d tasks still pending, %d passed, %d failed ... ", summary.pending, summary.passed, summary.failed)
|
pendingMessage := "%d tasks still pending, %d passed, %d failed ... "
|
||||||
|
message := fmt.Sprintf(pendingMessage, summary.pending, summary.passed, summary.failed)
|
||||||
|
|
||||||
if i%4 == 0 {
|
if i%4 == 0 {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
output.OutputElapsed(message, elapsedMessageMax)
|
output.OutputElapsed(message, len(pendingMessage)) // Up to 2 digits are allowed by the max message allocation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|
|
@ -118,6 +118,16 @@ func TestCloud_runTasksWithTaskResults(t *testing.T) {
|
||||||
expectedOutputs: []string{"Failed (Advisory)", "Overall Result: Passed with advisory failure"},
|
expectedOutputs: []string{"Failed (Advisory)", "Overall Result: Passed with advisory failure"},
|
||||||
isError: false,
|
isError: false,
|
||||||
},
|
},
|
||||||
|
"unreachable": {
|
||||||
|
taskResults: []*tfe.TaskResult{
|
||||||
|
{ID: "1", TaskName: "Mandatory", Message: "", Status: "unreachable", WorkspaceTaskEnforcementLevel: "mandatory"},
|
||||||
|
{ID: "2", TaskName: "Advisory", Message: "", Status: "unreachable", WorkspaceTaskEnforcementLevel: "advisory"},
|
||||||
|
},
|
||||||
|
writer: writer,
|
||||||
|
context: integrationContext,
|
||||||
|
expectedOutputs: []string{"Skipping"},
|
||||||
|
isError: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for caseName, c := range cases {
|
for caseName, c := range cases {
|
||||||
|
|
Loading…
Reference in New Issue