Skip to content

Commit

Permalink
Merge pull request #1079 from thaJeztah/fix_update_memory_cpu_limit
Browse files Browse the repository at this point in the history
Fix cpu/memory limits and reservations being reset on service update
  • Loading branch information
Vincent Demeester authored May 24, 2018
2 parents 7307813 + df9a0c7 commit 57ce5aa
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 4 deletions.
9 changes: 5 additions & 4 deletions cli/command/service/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,13 +313,14 @@ func updateService(ctx context.Context, apiClient client.NetworkAPIClient, flags
return err
}

if flags.Changed(flagLimitCPU) || flags.Changed(flagLimitMemory) {
taskResources().Limits = &swarm.Resources{}
if anyChanged(flags, flagLimitCPU, flagLimitMemory) {
taskResources().Limits = spec.TaskTemplate.Resources.Limits
updateInt64Value(flagLimitCPU, &task.Resources.Limits.NanoCPUs)
updateInt64Value(flagLimitMemory, &task.Resources.Limits.MemoryBytes)
}
if flags.Changed(flagReserveCPU) || flags.Changed(flagReserveMemory) {
taskResources().Reservations = &swarm.Resources{}

if anyChanged(flags, flagReserveCPU, flagReserveMemory) {
taskResources().Reservations = spec.TaskTemplate.Resources.Reservations
updateInt64Value(flagReserveCPU, &task.Resources.Reservations.NanoCPUs)
updateInt64Value(flagReserveMemory, &task.Resources.Reservations.MemoryBytes)
}
Expand Down
44 changes: 44 additions & 0 deletions cli/command/service/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,50 @@ func TestUpdateIsolationValid(t *testing.T) {
assert.Check(t, is.Equal(container.IsolationProcess, spec.TaskTemplate.ContainerSpec.Isolation))
}

// TestUpdateLimitsReservations tests that limits and reservations are updated,
// and that values are not updated are not reset to their default value
func TestUpdateLimitsReservations(t *testing.T) {
spec := swarm.ServiceSpec{
TaskTemplate: swarm.TaskSpec{
ContainerSpec: &swarm.ContainerSpec{},
Resources: &swarm.ResourceRequirements{
Limits: &swarm.Resources{
NanoCPUs: 1000000000,
MemoryBytes: 104857600,
},
Reservations: &swarm.Resources{
NanoCPUs: 1000000000,
MemoryBytes: 104857600,
},
},
},
}

flags := newUpdateCommand(nil).Flags()
err := flags.Set(flagLimitCPU, "2")
assert.NilError(t, err)
err = flags.Set(flagReserveCPU, "2")
assert.NilError(t, err)
err = updateService(context.Background(), nil, flags, &spec)
assert.NilError(t, err)
assert.Check(t, is.Equal(spec.TaskTemplate.Resources.Limits.NanoCPUs, int64(2000000000)))
assert.Check(t, is.Equal(spec.TaskTemplate.Resources.Limits.MemoryBytes, int64(104857600)))
assert.Check(t, is.Equal(spec.TaskTemplate.Resources.Reservations.NanoCPUs, int64(2000000000)))
assert.Check(t, is.Equal(spec.TaskTemplate.Resources.Reservations.MemoryBytes, int64(104857600)))

flags = newUpdateCommand(nil).Flags()
err = flags.Set(flagLimitMemory, "200M")
assert.NilError(t, err)
err = flags.Set(flagReserveMemory, "200M")
assert.NilError(t, err)
err = updateService(context.Background(), nil, flags, &spec)
assert.NilError(t, err)
assert.Check(t, is.Equal(spec.TaskTemplate.Resources.Limits.NanoCPUs, int64(2000000000)))
assert.Check(t, is.Equal(spec.TaskTemplate.Resources.Limits.MemoryBytes, int64(209715200)))
assert.Check(t, is.Equal(spec.TaskTemplate.Resources.Reservations.NanoCPUs, int64(2000000000)))
assert.Check(t, is.Equal(spec.TaskTemplate.Resources.Reservations.MemoryBytes, int64(209715200)))
}

func TestUpdateIsolationInvalid(t *testing.T) {
// validation depends on daemon os / version so validation should be done on the daemon side
flags := newUpdateCommand(nil).Flags()
Expand Down

0 comments on commit 57ce5aa

Please sign in to comment.