diff --git a/cri/v1alpha1/cri.go b/cri/v1alpha1/cri.go index 32ca19b691..bc61a0cc1e 100644 --- a/cri/v1alpha1/cri.go +++ b/cri/v1alpha1/cri.go @@ -701,7 +701,34 @@ func (c *CriManager) ListContainerStats(ctx context.Context, r *runtime.ListCont // UpdateContainerResources updates ContainerConfig of the container. func (c *CriManager) UpdateContainerResources(ctx context.Context, r *runtime.UpdateContainerResourcesRequest) (*runtime.UpdateContainerResourcesResponse, error) { - return nil, fmt.Errorf("UpdateContainerResources Not Implemented Yet") + containerID := r.GetContainerId() + container, err := c.ContainerMgr.Get(ctx, containerID) + if err != nil { + return nil, fmt.Errorf("failed to get container %q: %v", containerID, err) + } + + // cannot update container resource when it is in removing state + if container.IsRemoving() { + return nil, fmt.Errorf("cannot to update resource for container %q when it is in removing state", containerID) + } + + resources := r.GetLinux() + updateConfig := &apitypes.UpdateConfig{ + Resources: apitypes.Resources{ + CPUPeriod: resources.GetCpuPeriod(), + CPUQuota: resources.GetCpuQuota(), + CPUShares: resources.GetCpuShares(), + Memory: resources.GetMemoryLimitInBytes(), + CpusetCpus: resources.GetCpusetCpus(), + CpusetMems: resources.GetCpusetMems(), + }, + } + err = c.ContainerMgr.Update(ctx, containerID, updateConfig) + if err != nil { + return nil, fmt.Errorf("failed to update resource for container %q: %v", containerID, err) + } + + return &runtime.UpdateContainerResourcesResponse{}, nil } // ExecSync executes a command in the container, and returns the stdout output. diff --git a/cri/v1alpha2/cri.go b/cri/v1alpha2/cri.go index 852e1ecc99..dca1864e8e 100644 --- a/cri/v1alpha2/cri.go +++ b/cri/v1alpha2/cri.go @@ -698,7 +698,34 @@ func (c *CriManager) ListContainerStats(ctx context.Context, r *runtime.ListCont // UpdateContainerResources updates ContainerConfig of the container. func (c *CriManager) UpdateContainerResources(ctx context.Context, r *runtime.UpdateContainerResourcesRequest) (*runtime.UpdateContainerResourcesResponse, error) { - return nil, fmt.Errorf("UpdateContainerResources Not Implemented Yet") + containerID := r.GetContainerId() + container, err := c.ContainerMgr.Get(ctx, containerID) + if err != nil { + return nil, fmt.Errorf("failed to get container %q: %v", containerID, err) + } + + // cannot update container resource when it is in removing state + if container.IsRemoving() { + return nil, fmt.Errorf("cannot to update resource for container %q when it is in removing state", containerID) + } + + resources := r.GetLinux() + updateConfig := &apitypes.UpdateConfig{ + Resources: apitypes.Resources{ + CPUPeriod: resources.GetCpuPeriod(), + CPUQuota: resources.GetCpuQuota(), + CPUShares: resources.GetCpuShares(), + Memory: resources.GetMemoryLimitInBytes(), + CpusetCpus: resources.GetCpusetCpus(), + CpusetMems: resources.GetCpusetMems(), + }, + } + err = c.ContainerMgr.Update(ctx, containerID, updateConfig) + if err != nil { + return nil, fmt.Errorf("failed to update resource for container %q: %v", containerID, err) + } + + return &runtime.UpdateContainerResourcesResponse{}, nil } // ReopenContainerLog asks runtime to reopen the stdout/stderr log file diff --git a/daemon/mgr/container.go b/daemon/mgr/container.go index 0124e5ed31..f264696165 100644 --- a/daemon/mgr/container.go +++ b/daemon/mgr/container.go @@ -817,7 +817,7 @@ func (mgr *ContainerManager) Update(ctx context.Context, name string, config *ty c.Lock() // TODO update restartpolicy when container is running. - if config.RestartPolicy.Name != "" { + if config.RestartPolicy != nil && config.RestartPolicy.Name != "" { c.HostConfig.RestartPolicy = config.RestartPolicy } c.Unlock() diff --git a/daemon/mgr/container_state.go b/daemon/mgr/container_state.go index f92aca56cb..811ec33c12 100644 --- a/daemon/mgr/container_state.go +++ b/daemon/mgr/container_state.go @@ -42,6 +42,13 @@ func (c *Container) IsPaused() bool { return c.State.Status == types.StatusPaused } +// IsRemoving returns container is removing or not. +func (c *Container) IsRemoving() bool { + c.Lock() + defer c.Unlock() + return c.State.Status == types.StatusRemoving +} + // IsDead returns container is dead or not. func (c *Container) IsDead() bool { c.Lock()