From 8ab7bfcd540d814e3bf4d67ab664da108ebada6e Mon Sep 17 00:00:00 2001 From: Starnop Date: Tue, 12 Jun 2018 11:07:12 +0800 Subject: [PATCH] feature: UpdateContainerResources of CRI Manager Signed-off-by: Starnop --- cri/v1alpha1/cri.go | 22 +++++++++++++++++++++- cri/v1alpha1/cri_utils.go | 24 ++++++++++++++++++++++++ cri/v1alpha2/cri.go | 22 +++++++++++++++++++++- cri/v1alpha2/cri_utils.go | 24 ++++++++++++++++++++++++ daemon/mgr/container.go | 2 +- 5 files changed, 91 insertions(+), 3 deletions(-) diff --git a/cri/v1alpha1/cri.go b/cri/v1alpha1/cri.go index 9144595a30..abd9c1a1fb 100644 --- a/cri/v1alpha1/cri.go +++ b/cri/v1alpha1/cri.go @@ -689,7 +689,27 @@ 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.State.Status == apitypes.StatusRemoving { + return nil, fmt.Errorf("container %q is in removing state", containerID) + } + + resources := resourceToCriResource(r.GetLinux()) + updateConfig := &apitypes.UpdateConfig{ + Resources: resources, + } + err = c.ContainerMgr.Update(ctx, containerID, updateConfig) + if err != nil { + return nil, fmt.Errorf("failed to update resource for container %q", containerID) + } + + return &runtime.UpdateContainerResourcesResponse{}, nil } // ExecSync executes a command in the container, and returns the stdout output. diff --git a/cri/v1alpha1/cri_utils.go b/cri/v1alpha1/cri_utils.go index 1904629950..347a71eb54 100644 --- a/cri/v1alpha1/cri_utils.go +++ b/cri/v1alpha1/cri_utils.go @@ -770,3 +770,27 @@ func parseUserFromImageUser(id string) string { // no group, just return the id return id } + +// resourceToCriResource converts OCILinuxResource to apitypes.Resources Object. +func resourceToCriResource(newResource *runtime.LinuxContainerResources) apitypes.Resources { + var resources apitypes.Resources + if newResource.GetCpuPeriod() != 0 { + resources.CPUPeriod = newResource.GetCpuPeriod() + } + if newResource.GetCpuQuota() != 0 { + resources.CPUQuota = newResource.GetCpuQuota() + } + if newResource.GetCpuShares() != 0 { + resources.CPUShares = newResource.GetCpuShares() + } + if newResource.GetMemoryLimitInBytes() != 0 { + resources.Memory = newResource.GetMemoryLimitInBytes() + } + if newResource.GetCpusetCpus() != "" { + resources.CpusetCpus = newResource.GetCpusetCpus() + } + if newResource.GetCpusetMems() != "" { + resources.CpusetMems = newResource.GetCpusetMems() + } + return resources +} diff --git a/cri/v1alpha2/cri.go b/cri/v1alpha2/cri.go index cadb266eda..5166c367dc 100644 --- a/cri/v1alpha2/cri.go +++ b/cri/v1alpha2/cri.go @@ -686,7 +686,27 @@ 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.State.Status == apitypes.StatusRemoving { + return nil, fmt.Errorf("container %q is in removing state", containerID) + } + + resources := resourceToCriResource(r.GetLinux()) + updateConfig := &apitypes.UpdateConfig{ + Resources: resources, + } + err = c.ContainerMgr.Update(ctx, containerID, updateConfig) + if err != nil { + return nil, fmt.Errorf("failed to update resource for container %q", containerID) + } + + return &runtime.UpdateContainerResourcesResponse{}, nil } // ReopenContainerLog asks runtime to reopen the stdout/stderr log file diff --git a/cri/v1alpha2/cri_utils.go b/cri/v1alpha2/cri_utils.go index d65b879ad0..6ce0990e56 100644 --- a/cri/v1alpha2/cri_utils.go +++ b/cri/v1alpha2/cri_utils.go @@ -791,3 +791,27 @@ func (c *CriManager) attachLog(logPath string, containerID string) error { } return nil } + +// resourceToCriResource converts OCILinuxResource to apitypes.Resources Object. +func resourceToCriResource(newResource *runtime.LinuxContainerResources) apitypes.Resources { + var resources apitypes.Resources + if newResource.GetCpuPeriod() != 0 { + resources.CPUPeriod = newResource.GetCpuPeriod() + } + if newResource.GetCpuQuota() != 0 { + resources.CPUQuota = newResource.GetCpuQuota() + } + if newResource.GetCpuShares() != 0 { + resources.CPUShares = newResource.GetCpuShares() + } + if newResource.GetMemoryLimitInBytes() != 0 { + resources.Memory = newResource.GetMemoryLimitInBytes() + } + if newResource.GetCpusetCpus() != "" { + resources.CpusetCpus = newResource.GetCpusetCpus() + } + if newResource.GetCpusetMems() != "" { + resources.CpusetMems = newResource.GetCpusetMems() + } + return resources +} diff --git a/daemon/mgr/container.go b/daemon/mgr/container.go index 02aa886b63..eb717efacb 100644 --- a/daemon/mgr/container.go +++ b/daemon/mgr/container.go @@ -823,7 +823,7 @@ func (mgr *ContainerManager) Update(ctx context.Context, name string, config *ty } // TODO update restartpolicy when container is running. - if config.RestartPolicy.Name != "" { + if config.RestartPolicy != nil && config.RestartPolicy.Name != "" { c.HostConfig.RestartPolicy = config.RestartPolicy }