cli: fix panic when starting stopped jobs with no scaling policies (#26131)

Restoring scaling policies during the start of a stopped job did not account for
jobs that didn't have any scaling policies, and led to a panic when users tried
to restart such jobs.
This commit is contained in:
Piotr Kazmierczak
2025-06-25 11:19:56 +02:00
committed by GitHub
parent 7a5f5750b0
commit 7647491588
3 changed files with 74 additions and 12 deletions

3
.changelog/26131.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:bug
cli: Fix panic when restarting stopped job with no scaling policies
```

View File

@@ -159,7 +159,13 @@ func (c *JobStartCommand) Run(args []string) int {
sps := lastJob.GetScalingPoliciesPerTaskGroup()
for _, tg := range job.TaskGroups {
tg.Scaling.Enabled = sps[*tg.Name].Enabled
// guard for nil values in case the tg doesn't have any scaling policy
if sps[*tg.Name] != nil {
if tg.Scaling == nil {
tg.Scaling = &api.ScalingPolicy{}
}
tg.Scaling.Enabled = sps[*tg.Name].Enabled
}
}
}
}

View File

@@ -24,20 +24,24 @@ var _ cli.Command = (*JobStartCommand)(nil)
func TestStartCommand(t *testing.T) {
ci.Parallel(t)
srv, _, addr := testServer(t, true, func(c *agent.Config) {
c.DevMode = true
})
defer srv.Shutdown()
ui := cli.NewMockUi()
cmd := &JobStartCommand{
Meta: Meta{
Ui: ui,
flagAddress: addr,
},
testSetup := func() (*agent.TestAgent, *JobStartCommand, string) {
srv, _, addr := testServer(t, true, func(c *agent.Config) {
c.DevMode = true
})
ui := cli.NewMockUi()
cmd := &JobStartCommand{
Meta: Meta{
Ui: ui,
flagAddress: addr,
},
}
return srv, cmd, addr
}
t.Run("succeeds when starting a stopped job", func(t *testing.T) {
srv, cmd, addr := testSetup()
defer srv.Shutdown()
job := testJob(uuid.Generate())
client, err := cmd.Meta.Client()
@@ -72,6 +76,9 @@ func TestStartCommand(t *testing.T) {
})
t.Run("succeeds when starting a stopped job with disabled scaling policies and no submissions", func(t *testing.T) {
srv, cmd, addr := testSetup()
defer srv.Shutdown()
job := testJob(uuid.Generate())
client, err := cmd.Meta.Client()
@@ -100,6 +107,9 @@ func TestStartCommand(t *testing.T) {
})
t.Run("succeeds when starting a stopped job with enabled scaling policies", func(t *testing.T) {
srv, cmd, addr := testSetup()
defer srv.Shutdown()
job := testJob(uuid.Generate())
client, err := cmd.Meta.Client()
@@ -135,7 +145,47 @@ func TestStartCommand(t *testing.T) {
})
t.Run("succeeds when starting a stopped job with no scaling policies", func(t *testing.T) {
srv, cmd, addr := testSetup()
defer srv.Shutdown()
job := testJob(uuid.Generate())
client, err := cmd.Meta.Client()
must.NoError(t, err)
job.TaskGroups[0].Scaling = nil
jsonBytes, err := json.Marshal(job)
must.NoError(t, err)
_, _, err = client.Jobs().RegisterOpts(job, &api.RegisterOptions{
Submission: &api.JobSubmission{
Source: string(jsonBytes),
Format: "json",
},
}, nil)
must.NoError(t, err)
waitForJobAllocsStatus(t, client, *job.ID, api.AllocClientStatusRunning, "")
_, _, err = client.Jobs().Deregister(*job.ID, false, nil)
must.Nil(t, err)
waitForJobAllocsStatus(t, client, *job.ID, api.AllocClientStatusComplete, "")
res := cmd.Run([]string{"-address", addr, *job.ID})
must.Zero(t, res)
pol, _, err := client.Scaling().ListPolicies(nil)
must.NoError(t, err)
must.Zero(t, len(pol))
})
t.Run("fails to start a job not previously stopped", func(t *testing.T) {
srv, cmd, addr := testSetup()
defer srv.Shutdown()
job := testJob(uuid.Generate())
client, err := cmd.Meta.Client()
@@ -151,6 +201,9 @@ func TestStartCommand(t *testing.T) {
})
t.Run("fails to start a non-existant job", func(t *testing.T) {
srv, cmd, addr := testSetup()
defer srv.Shutdown()
res := cmd.Run([]string{"-address", addr, "non-existant"})
must.Eq(t, 1, res)
})