Skip to content

Commit c56cfdb

Browse files
committed
address code review requests
1 parent b97b122 commit c56cfdb

File tree

6 files changed

+47
-27
lines changed

6 files changed

+47
-27
lines changed

.changelog/14127.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
```release-note:improvement
2-
client: add option to restart all tasks of an allocation, even if the task already run, such as non-sidecar prestart and poststart tasks.
2+
client: add option to restart all tasks of an allocation, regardless of lifecycle type or state.
33
```
44

55
```release-note:improvement

api/allocations.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ func (a *Allocations) GC(alloc *Allocation, q *QueryOptions) error {
141141
return err
142142
}
143143

144-
// Restart restarts an allocation.
144+
// Restart restarts the tasks that are currently running or a specific task if
145+
// taskName is provided. An error is returned if the task to be restarted is
146+
// not running.
145147
//
146148
// Note: for cluster topologies where API consumers don't have network access to
147149
// Nomad clients, set api.ClientConnTimeout to a small value (ex 1ms) to avoid
@@ -156,6 +158,12 @@ func (a *Allocations) Restart(alloc *Allocation, taskName string, q *QueryOption
156158
return err
157159
}
158160

161+
// RestartAllTasks restarts all tasks in the allocation, regardless of
162+
// lifecycle type or state. Tasks will restart following their lifecycle order.
163+
//
164+
// Note: for cluster topologies where API consumers don't have network access to
165+
// Nomad clients, set api.ClientConnTimeout to a small value (ex 1ms) to avoid
166+
// long pauses on this API call.
159167
func (a *Allocations) RestartAllTasks(alloc *Allocation, q *QueryOptions) error {
160168
req := AllocationRestartRequest{
161169
AllTasks: true,

client/allocrunner/alloc_runner.go

+21-14
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,8 @@ func (ar *allocRunner) handleTaskStateUpdates() {
548548

549549
if len(liveRunners) > 0 {
550550
// if all live runners are sidecars - kill alloc
551-
if killEvent == nil && hasSidecars && !hasNonSidecarTasks(liveRunners) {
551+
hasLiveSidecars := hasSidecars && !hasNonSidecarTasks(liveRunners)
552+
if killEvent == nil && hasLiveSidecars {
552553
killEvent = structs.NewTaskEvent(structs.TaskMainDead)
553554
}
554555

@@ -573,11 +574,11 @@ func (ar *allocRunner) handleTaskStateUpdates() {
573574
// Kill 'em all
574575
states = ar.killTasks()
575576

576-
// Wait for TaskRunners to exit before continuing to
577-
// prevent looping before TaskRunners have transitioned
578-
// to Dead.
577+
// Wait for TaskRunners to exit before continuing. This will
578+
// prevent looping before TaskRunners have transitioned to
579+
// Dead.
579580
for _, tr := range liveRunners {
580-
ar.logger.Info("killing task", "task", tr.Task().Name)
581+
ar.logger.Info("waiting for task to exit", "task", tr.Task().Name)
581582
select {
582583
case <-tr.WaitCh():
583584
case <-ar.waitCh:
@@ -1228,20 +1229,24 @@ func (ar *allocRunner) GetTaskEventHandler(taskName string) drivermanager.EventH
12281229
}
12291230

12301231
// Restart satisfies the WorkloadRestarter interface and restarts all tasks
1231-
// that are currently running. Only the TaskRestartRunningSignal event type may
1232-
// be used.
1232+
// that are currently running.
1233+
//
1234+
// The event type will be set to TaskRestartRunningSignal to comply with
1235+
// internal restart logic requirements.
12331236
func (ar *allocRunner) Restart(ctx context.Context, event *structs.TaskEvent, failure bool) error {
12341237
if event.Type != structs.TaskRestartRunningSignal {
1235-
return fmt.Errorf("Invalid event %s for alloc restart request", event.Type)
1238+
event.Type = structs.TaskRestartRunningSignal
12361239
}
12371240
return ar.restartTasks(ctx, event, failure)
12381241
}
12391242

1240-
// RestartTask restarts the provided task. Only TaskRestartSignal event type
1241-
// may be used.
1243+
// RestartTask restarts the provided task.
1244+
//
1245+
// The event type will be set to TaskRestartSignal to comply with internal
1246+
// restart logic requirements.
12421247
func (ar *allocRunner) RestartTask(taskName string, event *structs.TaskEvent) error {
12431248
if event.Type != structs.TaskRestartSignal {
1244-
return fmt.Errorf("Invalid event %s for task restart request", event.Type)
1249+
event.Type = structs.TaskRestartSignal
12451250
}
12461251

12471252
tr, ok := ar.tasks[taskName]
@@ -1252,11 +1257,13 @@ func (ar *allocRunner) RestartTask(taskName string, event *structs.TaskEvent) er
12521257
return tr.Restart(context.TODO(), event, false)
12531258
}
12541259

1255-
// RestartRunning restarts all tasks that are currently running. Only the
1256-
// TaskRestartRunningSignal event type may be used.
1260+
// RestartRunning restarts all tasks that are currently running.
1261+
//
1262+
// The event type will be set to TaskRestartRunningSignal to comply with
1263+
// internal restart logic requirements.
12571264
func (ar *allocRunner) RestartRunning(event *structs.TaskEvent) error {
12581265
if event.Type != structs.TaskRestartRunningSignal {
1259-
return fmt.Errorf("Invalid event %s for running tasks restart request", event.Type)
1266+
event.Type = structs.TaskRestartRunningSignal
12601267
}
12611268
return ar.restartTasks(context.TODO(), event, false)
12621269
}

client/allocrunner/alloc_runner_test.go

+2-10
Original file line numberDiff line numberDiff line change
@@ -1676,11 +1676,7 @@ func TestAllocRunner_MoveAllocDir(t *testing.T) {
16761676
ar.Run()
16771677
defer destroy(ar)
16781678

1679-
testutil.WaitForResult(func() (bool, error) {
1680-
return ar.AllocState().ClientStatus == structs.AllocClientStatusComplete, nil
1681-
}, func(_ error) {
1682-
t.Fatalf("expected alloc to be complete")
1683-
})
1679+
WaitForClientState(t, ar, structs.AllocClientStatusComplete)
16841680

16851681
// Step 2. Modify its directory
16861682
task := alloc.Job.TaskGroups[0].Tasks[0]
@@ -1708,11 +1704,7 @@ func TestAllocRunner_MoveAllocDir(t *testing.T) {
17081704
ar2.Run()
17091705
defer destroy(ar2)
17101706

1711-
testutil.WaitForResult(func() (bool, error) {
1712-
return ar.AllocState().ClientStatus == structs.AllocClientStatusComplete, nil
1713-
}, func(_ error) {
1714-
t.Fatalf("expected alloc to be complete")
1715-
})
1707+
WaitForClientState(t, ar, structs.AllocClientStatusComplete)
17161708

17171709
// Ensure that data from ar was moved to ar2
17181710
dataFile = filepath.Join(ar2.allocDir.SharedDir, "data", "data_file")

client/allocrunner/testing.go

+12
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package allocrunner
55

66
import (
7+
"fmt"
78
"sync"
89
"testing"
910

@@ -20,6 +21,7 @@ import (
2021
"github.com/hashicorp/nomad/client/state"
2122
"github.com/hashicorp/nomad/client/vaultclient"
2223
"github.com/hashicorp/nomad/nomad/structs"
24+
"github.com/hashicorp/nomad/testutil"
2325
"github.com/stretchr/testify/require"
2426
)
2527

@@ -104,3 +106,13 @@ func TestAllocRunnerFromAlloc(t *testing.T, alloc *structs.Allocation) (*allocRu
104106

105107
return ar, cleanup
106108
}
109+
110+
func WaitForClientState(t *testing.T, ar *allocRunner, state string) {
111+
testutil.WaitForResult(func() (bool, error) {
112+
got := ar.AllocState().ClientStatus
113+
return got == state,
114+
fmt.Errorf("expected alloc runner to be in state %s, got %s", state, got)
115+
}, func(err error) {
116+
require.NoError(t, err)
117+
})
118+
}

command/alloc_restart.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ Restart Specific Options:
3636
3737
-all-tasks
3838
If set, all tasks in the allocation will be restarted, even the ones that
39-
already ran. This option cannot be used if a task is defined.
39+
already ran. This option cannot be used with '-task' or the '<task>'
40+
argument.
4041
4142
-task <task-name>
4243
Specify the individual task to restart. If task name is given with both an

0 commit comments

Comments
 (0)