runservice: allow restart run only if possible
This commit is contained in:
parent
1657a35a6f
commit
c9089c3ccc
|
@ -216,6 +216,16 @@ func (s *CommandHandler) recreateRun(ctx context.Context, req *RunCreateRequest)
|
||||||
return nil, errors.Wrapf(err, "run %q doens't exist", req.RunID)
|
return nil, errors.Wrapf(err, "run %q doens't exist", req.RunID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if req.FromStart {
|
||||||
|
if canRestart, reason := run.CanRestartFromScratch(); !canRestart {
|
||||||
|
return nil, errors.Errorf("run cannot be restarted: %s", reason)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if canRestart, reason := run.CanRestartFromFailedTasks(); !canRestart {
|
||||||
|
return nil, errors.Errorf("run cannot be restarted: %s", reason)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// update the run ID
|
// update the run ID
|
||||||
run.ID = id
|
run.ID = id
|
||||||
// reset run revision
|
// reset run revision
|
||||||
|
@ -231,7 +241,6 @@ func (s *CommandHandler) recreateRun(ctx context.Context, req *RunCreateRequest)
|
||||||
tasksToAdd := []*types.RunTask{}
|
tasksToAdd := []*types.RunTask{}
|
||||||
tasksToDelete := []string{}
|
tasksToDelete := []string{}
|
||||||
|
|
||||||
s.log.Infof("fromStart: %t", req.FromStart)
|
|
||||||
for _, rt := range run.RunTasks {
|
for _, rt := range run.RunTasks {
|
||||||
if req.FromStart || rt.Status != types.RunTaskStatusSuccess {
|
if req.FromStart || rt.Status != types.RunTaskStatusSuccess {
|
||||||
rct := rc.Tasks[rt.ID]
|
rct := rc.Tasks[rt.ID]
|
||||||
|
|
|
@ -17,6 +17,7 @@ package types
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sorintlab/agola/internal/util"
|
"github.com/sorintlab/agola/internal/util"
|
||||||
|
@ -131,6 +132,36 @@ func (r *Run) TasksWaitingApproval() []string {
|
||||||
return runTasksIDs
|
return runTasksIDs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CanRestartFromScratch reports if the run can be restarted from scratch
|
||||||
|
func (r *Run) CanRestartFromScratch() (bool, string) {
|
||||||
|
// can restart only if the run phase is finished or cancelled
|
||||||
|
if !r.Phase.IsFinished() {
|
||||||
|
return false, fmt.Sprintf("run is not finished, phase: %q", r.Phase)
|
||||||
|
}
|
||||||
|
return true, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanRestartFromFailedTasks reports if the run can be restarted from failed tasks
|
||||||
|
func (r *Run) CanRestartFromFailedTasks() (bool, string) {
|
||||||
|
// can restart only if the run phase is finished or cancelled
|
||||||
|
if !r.Phase.IsFinished() {
|
||||||
|
return false, fmt.Sprintf("run is not finished, phase: %q", r.Phase)
|
||||||
|
}
|
||||||
|
// can restart from failed tasks only if there're some failed tasks
|
||||||
|
if r.Result == RunResultSuccess {
|
||||||
|
return false, fmt.Sprintf("run %q has success result, cannot restart from failed tasks", r.ID)
|
||||||
|
}
|
||||||
|
// can restart only if the successful tasks are fully archived
|
||||||
|
for _, rt := range r.RunTasks {
|
||||||
|
if rt.Status == RunTaskStatusSuccess {
|
||||||
|
if !rt.LogsFetchFinished() || !rt.ArchivesFetchFinished() {
|
||||||
|
return false, fmt.Sprintf("run %q task %q not fully archived", r.ID, rt.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true, ""
|
||||||
|
}
|
||||||
|
|
||||||
type RunTaskStatus string
|
type RunTaskStatus string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
Loading…
Reference in New Issue