From af4c92c885795a7a808d743cd3154b270ce2c647 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..f8224c6fa9 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..8b2a15085e 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 }