@@ -24,13 +24,14 @@ import (
2424 gocontext "context"
2525 "fmt"
2626
27+ "github.com/containerd/typeurl"
28+ runtimespec "github.com/opencontainers/runtime-spec/specs-go"
29+ runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
30+
2731 "github.com/containerd/containerd"
2832 "github.com/containerd/containerd/containers"
2933 "github.com/containerd/containerd/errdefs"
3034 "github.com/containerd/containerd/log"
31- "github.com/containerd/typeurl"
32- runtimespec "github.com/opencontainers/runtime-spec/specs-go"
33- runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
3435
3536 containerstore "github.com/containerd/containerd/pkg/cri/store/container"
3637 ctrdutil "github.com/containerd/containerd/pkg/cri/util"
@@ -45,8 +46,8 @@ func (c *criService) UpdateContainerResources(ctx context.Context, r *runtime.Up
4546 // Update resources in status update transaction, so that:
4647 // 1) There won't be race condition with container start.
4748 // 2) There won't be concurrent resource update to the same container.
48- if err := container .Status .Update (func (status containerstore.Status ) (containerstore.Status , error ) {
49- return status , c .updateContainerResources (ctx , container , r , status )
49+ if err := container .Status .UpdateSync (func (status containerstore.Status ) (containerstore.Status , error ) {
50+ return c .updateContainerResources (ctx , container , r , status )
5051 }); err != nil {
5152 return nil , fmt .Errorf ("failed to update resources: %w" , err )
5253 }
@@ -56,11 +57,13 @@ func (c *criService) UpdateContainerResources(ctx context.Context, r *runtime.Up
5657func (c * criService ) updateContainerResources (ctx context.Context ,
5758 cntr containerstore.Container ,
5859 r * runtime.UpdateContainerResourcesRequest ,
59- status containerstore.Status ) (retErr error ) {
60+ status containerstore.Status ) (newStatus containerstore.Status , retErr error ) {
61+
62+ newStatus = status
6063 id := cntr .ID
6164 // Do not update the container when there is a removal in progress.
6265 if status .Removing {
63- return fmt .Errorf ("container %q is in removing state" , id )
66+ return newStatus , fmt .Errorf ("container %q is in removing state" , id )
6467 }
6568
6669 // Update container spec. If the container is not started yet, updating
@@ -69,15 +72,15 @@ func (c *criService) updateContainerResources(ctx context.Context,
6972 // the spec will become our source of truth for resource limits.
7073 oldSpec , err := cntr .Container .Spec (ctx )
7174 if err != nil {
72- return fmt .Errorf ("failed to get container spec: %w" , err )
75+ return newStatus , fmt .Errorf ("failed to get container spec: %w" , err )
7376 }
7477 newSpec , err := updateOCIResource (ctx , oldSpec , r , c .config )
7578 if err != nil {
76- return fmt .Errorf ("failed to update resource in spec: %w" , err )
79+ return newStatus , fmt .Errorf ("failed to update resource in spec: %w" , err )
7780 }
7881
7982 if err := updateContainerSpec (ctx , cntr .Container , newSpec ); err != nil {
80- return err
83+ return newStatus , err
8184 }
8285 defer func () {
8386 if retErr != nil {
@@ -87,32 +90,35 @@ func (c *criService) updateContainerResources(ctx context.Context,
8790 if err := updateContainerSpec (deferCtx , cntr .Container , oldSpec ); err != nil {
8891 log .G (ctx ).WithError (err ).Errorf ("Failed to update spec %+v for container %q" , oldSpec , id )
8992 }
93+ } else {
94+ // Update container status only when the spec is updated
95+ newStatus = copyResourcesToStatus (newSpec , status )
9096 }
9197 }()
9298
9399 // If container is not running, only update spec is enough, new resource
94100 // limit will be applied when container start.
95101 if status .State () != runtime .ContainerState_CONTAINER_RUNNING {
96- return nil
102+ return newStatus , nil
97103 }
98104
99105 task , err := cntr .Container .Task (ctx , nil )
100106 if err != nil {
101107 if errdefs .IsNotFound (err ) {
102108 // Task exited already.
103- return nil
109+ return newStatus , nil
104110 }
105- return fmt .Errorf ("failed to get task: %w" , err )
111+ return newStatus , fmt .Errorf ("failed to get task: %w" , err )
106112 }
107113 // newSpec.Linux / newSpec.Windows won't be nil
108114 if err := task .Update (ctx , containerd .WithResources (getResources (newSpec ))); err != nil {
109115 if errdefs .IsNotFound (err ) {
110116 // Task exited already.
111- return nil
117+ return newStatus , nil
112118 }
113- return fmt .Errorf ("failed to update resources: %w" , err )
119+ return newStatus , fmt .Errorf ("failed to update resources: %w" , err )
114120 }
115- return nil
121+ return newStatus , nil
116122}
117123
118124// updateContainerSpec updates container spec.
0 commit comments