1717package server
1818
1919import (
20- gocontext "context"
21-
22- "github.com/containerd/containerd"
23- "github.com/containerd/containerd/containers"
24- "github.com/containerd/containerd/errdefs"
25- "github.com/containerd/containerd/log"
26- "github.com/containerd/typeurl"
2720 runtimespec "github.com/opencontainers/runtime-spec/specs-go"
2821 "github.com/pkg/errors"
2922 "golang.org/x/net/context"
3023 runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
3124
25+ criconfig "github.com/containerd/containerd/pkg/cri/config"
3226 "github.com/containerd/containerd/pkg/cri/opts"
33- containerstore "github.com/containerd/containerd/pkg/cri/store/container"
3427 "github.com/containerd/containerd/pkg/cri/util"
35- ctrdutil "github.com/containerd/containerd/pkg/cri/util"
3628)
3729
38- // UpdateContainerResources updates ContainerConfig of the container.
39- func (c * criService ) UpdateContainerResources (ctx context.Context , r * runtime.UpdateContainerResourcesRequest ) (retRes * runtime.UpdateContainerResourcesResponse , retErr error ) {
40- container , err := c .containerStore .Get (r .GetContainerId ())
41- if err != nil {
42- return nil , errors .Wrap (err , "failed to find container" )
43- }
44- // Update resources in status update transaction, so that:
45- // 1) There won't be race condition with container start.
46- // 2) There won't be concurrent resource update to the same container.
47- if err := container .Status .Update (func (status containerstore.Status ) (containerstore.Status , error ) {
48- return status , c .updateContainerResources (ctx , container , r .GetLinux (), status )
49- }); err != nil {
50- return nil , errors .Wrap (err , "failed to update resources" )
51- }
52- return & runtime.UpdateContainerResourcesResponse {}, nil
53- }
54-
55- func (c * criService ) updateContainerResources (ctx context.Context ,
56- cntr containerstore.Container ,
57- resources * runtime.LinuxContainerResources ,
58- status containerstore.Status ) (retErr error ) {
59- id := cntr .ID
60- // Do not update the container when there is a removal in progress.
61- if status .Removing {
62- return errors .Errorf ("container %q is in removing state" , id )
63- }
64-
65- // Update container spec. If the container is not started yet, updating
66- // spec makes sure that the resource limits are correct when start;
67- // if the container is already started, updating spec is still required,
68- // the spec will become our source of truth for resource limits.
69- oldSpec , err := cntr .Container .Spec (ctx )
70- if err != nil {
71- return errors .Wrap (err , "failed to get container spec" )
72- }
73- newSpec , err := updateOCILinuxResource (ctx , oldSpec , resources ,
74- c .config .TolerateMissingHugetlbController , c .config .DisableHugetlbController )
75- if err != nil {
76- return errors .Wrap (err , "failed to update resource in spec" )
77- }
78-
79- if err := updateContainerSpec (ctx , cntr .Container , newSpec ); err != nil {
80- return err
81- }
82- defer func () {
83- if retErr != nil {
84- deferCtx , deferCancel := ctrdutil .DeferContext ()
85- defer deferCancel ()
86- // Reset spec on error.
87- if err := updateContainerSpec (deferCtx , cntr .Container , oldSpec ); err != nil {
88- log .G (ctx ).WithError (err ).Errorf ("Failed to update spec %+v for container %q" , oldSpec , id )
89- }
90- }
91- }()
30+ // updateOCIResource updates container resource limit.
31+ func updateOCIResource (ctx context.Context , spec * runtimespec.Spec , r * runtime.UpdateContainerResourcesRequest ,
32+ config criconfig.Config ) (* runtimespec.Spec , error ) {
9233
93- // If container is not running, only update spec is enough, new resource
94- // limit will be applied when container start.
95- if status .State () != runtime .ContainerState_CONTAINER_RUNNING {
96- return nil
97- }
98-
99- task , err := cntr .Container .Task (ctx , nil )
100- if err != nil {
101- if errdefs .IsNotFound (err ) {
102- // Task exited already.
103- return nil
104- }
105- return errors .Wrap (err , "failed to get task" )
106- }
107- // newSpec.Linux won't be nil
108- if err := task .Update (ctx , containerd .WithResources (newSpec .Linux .Resources )); err != nil {
109- if errdefs .IsNotFound (err ) {
110- // Task exited already.
111- return nil
112- }
113- return errors .Wrap (err , "failed to update resources" )
114- }
115- return nil
116- }
117-
118- // updateContainerSpec updates container spec.
119- func updateContainerSpec (ctx context.Context , cntr containerd.Container , spec * runtimespec.Spec ) error {
120- any , err := typeurl .MarshalAny (spec )
121- if err != nil {
122- return errors .Wrapf (err , "failed to marshal spec %+v" , spec )
123- }
124- if err := cntr .Update (ctx , func (ctx gocontext.Context , client * containerd.Client , c * containers.Container ) error {
125- c .Spec = any
126- return nil
127- }); err != nil {
128- return errors .Wrap (err , "failed to update container spec" )
129- }
130- return nil
131- }
132-
133- // updateOCILinuxResource updates container resource limit.
134- func updateOCILinuxResource (ctx context.Context , spec * runtimespec.Spec , new * runtime.LinuxContainerResources ,
135- tolerateMissingHugetlbController , disableHugetlbController bool ) (* runtimespec.Spec , error ) {
13634 // Copy to make sure old spec is not changed.
13735 var cloned runtimespec.Spec
13836 if err := util .DeepCopy (& cloned , spec ); err != nil {
@@ -141,8 +39,12 @@ func updateOCILinuxResource(ctx context.Context, spec *runtimespec.Spec, new *ru
14139 if cloned .Linux == nil {
14240 cloned .Linux = & runtimespec.Linux {}
14341 }
144- if err := opts .WithResources (new , tolerateMissingHugetlbController , disableHugetlbController )(ctx , nil , nil , & cloned ); err != nil {
42+ if err := opts .WithResources (r . GetLinux (), config . TolerateMissingHugetlbController , config . DisableHugetlbController )(ctx , nil , nil , & cloned ); err != nil {
14543 return nil , errors .Wrap (err , "unable to set linux container resources" )
14644 }
14745 return & cloned , nil
14846}
47+
48+ func getResources (spec * runtimespec.Spec ) interface {} {
49+ return spec .Linux .Resources
50+ }
0 commit comments