Use new container update function
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
@@ -61,7 +61,7 @@ func (c *criContainerdService) attachContainer(ctx context.Context, id string, s
|
||||
return fmt.Errorf("container is in %s state", criContainerStateToString(state))
|
||||
}
|
||||
|
||||
task, err := cntr.Container.Get().Task(ctx, nil)
|
||||
task, err := cntr.Container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load task: %v", err)
|
||||
}
|
||||
|
||||
@@ -87,8 +87,8 @@ func (c *criContainerdService) execInContainer(ctx context.Context, id string, o
|
||||
return nil, fmt.Errorf("container is in %s state", criContainerStateToString(state))
|
||||
}
|
||||
|
||||
container := cntr.Container.Get()
|
||||
spec, err := container.Spec()
|
||||
container := cntr.Container
|
||||
spec, err := container.Spec(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get container spec: %v", err)
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func (c *criContainerdService) RemoveContainer(ctx context.Context, r *runtime.R
|
||||
}
|
||||
|
||||
// Delete containerd container.
|
||||
if err := container.Container.Get().Delete(ctx, containerd.WithSnapshotCleanup); err != nil {
|
||||
if err := container.Container.Delete(ctx, containerd.WithSnapshotCleanup); err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return nil, fmt.Errorf("failed to delete containerd container %q: %v", id, err)
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ func (c *criContainerdService) startContainer(ctx context.Context,
|
||||
status *containerstore.Status) (retErr error) {
|
||||
id := cntr.ID
|
||||
meta := cntr.Metadata
|
||||
container := cntr.Container.Get()
|
||||
container := cntr.Container
|
||||
config := meta.Config
|
||||
|
||||
// Return error if container is not in created state.
|
||||
|
||||
@@ -88,7 +88,7 @@ func (c *criContainerdService) stopContainer(ctx context.Context, container cont
|
||||
}
|
||||
}
|
||||
glog.V(2).Infof("Stop container %q with signal %v", id, stopSignal)
|
||||
task, err := container.Container.Get().Task(ctx, nil)
|
||||
task, err := container.Container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to stop container, task not found for container %q: %v", id, err)
|
||||
@@ -111,7 +111,7 @@ func (c *criContainerdService) stopContainer(ctx context.Context, container cont
|
||||
glog.Errorf("Stop container %q timed out: %v", id, err)
|
||||
}
|
||||
|
||||
task, err := container.Container.Get().Task(ctx, nil)
|
||||
task, err := container.Container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to stop container, task not found for container %q: %v", id, err)
|
||||
|
||||
@@ -17,9 +17,11 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
gocontext "context"
|
||||
"fmt"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/typeurl"
|
||||
"github.com/golang/glog"
|
||||
@@ -63,7 +65,7 @@ func (c *criContainerdService) updateContainerResources(ctx context.Context,
|
||||
// spec makes sure that the resource limits are correct when start;
|
||||
// if the container is already started, updating spec is still required,
|
||||
// the spec will become our source of truth for resource limits.
|
||||
oldSpec, err := cntr.Container.Get().Spec()
|
||||
oldSpec, err := cntr.Container.Spec(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get container spec: %v", err)
|
||||
}
|
||||
@@ -72,42 +74,15 @@ func (c *criContainerdService) updateContainerResources(ctx context.Context,
|
||||
return fmt.Errorf("failed to update resource in spec: %v", err)
|
||||
}
|
||||
|
||||
info := cntr.Container.Get().Info()
|
||||
any, err := typeurl.MarshalAny(newSpec)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal spec %+v: %v", newSpec, err)
|
||||
}
|
||||
info.Spec = any
|
||||
// TODO(random-liu): Add helper function in containerd to do the update.
|
||||
if _, err := c.client.ContainerService().Update(ctx, info, "spec"); err != nil {
|
||||
return fmt.Errorf("failed to update container spec: %v", err)
|
||||
if err := updateContainerSpec(ctx, cntr.Container, newSpec); err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
// Reset spec on error.
|
||||
any, err := typeurl.MarshalAny(oldSpec)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to marshal spec %+v for container %q: %v", oldSpec, id, err)
|
||||
return
|
||||
if err := updateContainerSpec(ctx, cntr.Container, oldSpec); err != nil {
|
||||
glog.Errorf("Failed to update spec %+v for container %q: %v", oldSpec, id, err)
|
||||
}
|
||||
info.Spec = any
|
||||
if _, err := c.client.ContainerService().Update(ctx, info, "spec"); err != nil {
|
||||
glog.Errorf("Failed to recover spec %+v for container %q: %v", oldSpec, id, err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
container, err := c.client.LoadContainer(ctx, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load container: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
if retErr == nil {
|
||||
// Update container client if no error is returned.
|
||||
// NOTE(random-liu): By updating container client, we'll be able
|
||||
// to get latest OCI spec from it, which includes the up-to-date
|
||||
// container resource limits. This will be useful after the debug
|
||||
// api is introduced.
|
||||
cntr.Container.Set(container)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -117,7 +92,7 @@ func (c *criContainerdService) updateContainerResources(ctx context.Context,
|
||||
return nil
|
||||
}
|
||||
|
||||
task, err := container.Task(ctx, nil)
|
||||
task, err := cntr.Container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
// Task exited already.
|
||||
@@ -136,6 +111,21 @@ func (c *criContainerdService) updateContainerResources(ctx context.Context,
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateContainerSpec updates container spec.
|
||||
func updateContainerSpec(ctx context.Context, cntr containerd.Container, spec *runtimespec.Spec) error {
|
||||
any, err := typeurl.MarshalAny(spec)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal spec %+v: %v", spec, err)
|
||||
}
|
||||
if err := cntr.Update(ctx, func(ctx gocontext.Context, client *containerd.Client, c *containers.Container) error {
|
||||
c.Spec = any
|
||||
return nil
|
||||
}); err != nil {
|
||||
return fmt.Errorf("failed to update container spec: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateOCILinuxResource updates container resource limit.
|
||||
func updateOCILinuxResource(spec *runtimespec.Spec, new *runtime.LinuxContainerResources) (*runtimespec.Spec, error) {
|
||||
// Copy to make sure old spec is not changed.
|
||||
|
||||
@@ -104,7 +104,7 @@ func (em *eventMonitor) handleEvent(evt *events.Envelope) {
|
||||
return
|
||||
}
|
||||
// Attach container IO so that `Delete` could cleanup the stream properly.
|
||||
task, err := cntr.Container.Get().Task(context.Background(),
|
||||
task, err := cntr.Container.Task(context.Background(),
|
||||
func(*containerd.FIFOSet) (containerd.IO, error) {
|
||||
return cntr.IO, nil
|
||||
},
|
||||
|
||||
@@ -127,7 +127,11 @@ func loadContainer(ctx context.Context, cntr containerd.Container, containerDir
|
||||
id := cntr.ID()
|
||||
var container containerstore.Container
|
||||
// Load container metadata.
|
||||
ext, ok := cntr.Extensions()[containerMetadataExtension]
|
||||
exts, err := cntr.Extensions(ctx)
|
||||
if err != nil {
|
||||
return container, fmt.Errorf("failed to get container extensions: %v", err)
|
||||
}
|
||||
ext, ok := exts[containerMetadataExtension]
|
||||
if !ok {
|
||||
return container, fmt.Errorf("metadata extension %q not found", containerMetadataExtension)
|
||||
}
|
||||
@@ -278,7 +282,11 @@ func unknownContainerStatus() containerstore.Status {
|
||||
func loadSandbox(ctx context.Context, cntr containerd.Container) (sandboxstore.Sandbox, error) {
|
||||
var sandbox sandboxstore.Sandbox
|
||||
// Load sandbox metadata.
|
||||
ext, ok := cntr.Extensions()[sandboxMetadataExtension]
|
||||
exts, err := cntr.Extensions(ctx)
|
||||
if err != nil {
|
||||
return sandbox, fmt.Errorf("failed to get sandbox container extensions: %v", err)
|
||||
}
|
||||
ext, ok := exts[sandboxMetadataExtension]
|
||||
if !ok {
|
||||
return sandbox, fmt.Errorf("metadata extension %q not found", sandboxMetadataExtension)
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
tasks "github.com/containerd/containerd/api/services/tasks/v1"
|
||||
"github.com/containerd/containerd/api/types/task"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"golang.org/x/net/context"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||
|
||||
@@ -55,7 +56,15 @@ func (c *criContainerdService) ListPodSandbox(ctx context.Context, r *runtime.Li
|
||||
state = runtime.PodSandboxState_SANDBOX_READY
|
||||
}
|
||||
|
||||
createdAt := sandboxInStore.Container.Info().CreatedAt
|
||||
info, err := sandboxInStore.Container.Info(ctx)
|
||||
if err != nil {
|
||||
// It's possible that container gets deleted during list.
|
||||
if errdefs.IsNotFound(err) {
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get sandbox container %q info: %v", sandboxInStore.ID, err)
|
||||
}
|
||||
createdAt := info.CreatedAt
|
||||
sandboxes = append(sandboxes, toCRISandbox(sandboxInStore.Metadata, state, createdAt))
|
||||
}
|
||||
|
||||
|
||||
@@ -34,15 +34,12 @@ import (
|
||||
func (c *criContainerdService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandboxStatusRequest) (*runtime.PodSandboxStatusResponse, error) {
|
||||
sandbox, err := c.sandboxStore.Get(r.GetPodSandboxId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("an error occurred when try to find sandbox %q: %v",
|
||||
r.GetPodSandboxId(), err)
|
||||
return nil, fmt.Errorf("an error occurred when try to find sandbox: %v", err)
|
||||
}
|
||||
// Use the full sandbox id.
|
||||
id := sandbox.ID
|
||||
|
||||
task, err := sandbox.Container.Task(ctx, nil)
|
||||
if err != nil && !errdefs.IsNotFound(err) {
|
||||
return nil, fmt.Errorf("failed to get sandbox container info for %q: %v", id, err)
|
||||
return nil, fmt.Errorf("failed to get sandbox container task: %v", err)
|
||||
}
|
||||
|
||||
// Set sandbox state to NOTREADY by default.
|
||||
@@ -51,7 +48,7 @@ func (c *criContainerdService) PodSandboxStatus(ctx context.Context, r *runtime.
|
||||
if task != nil {
|
||||
taskStatus, err := task.Status(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get task status for sandbox container %q: %v", id, err)
|
||||
return nil, fmt.Errorf("failed to get task status: %v", err)
|
||||
}
|
||||
|
||||
if taskStatus.Status == containerd.Running {
|
||||
@@ -64,7 +61,11 @@ func (c *criContainerdService) PodSandboxStatus(ctx context.Context, r *runtime.
|
||||
return nil, fmt.Errorf("failed to get sandbox ip: %v", err)
|
||||
}
|
||||
|
||||
createdAt := sandbox.Container.Info().CreatedAt
|
||||
info, err := sandbox.Container.Info(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get sandbox container info: %v", err)
|
||||
}
|
||||
createdAt := info.CreatedAt
|
||||
status := toCRISandboxStatus(sandbox.Metadata, state, createdAt, ip)
|
||||
return &runtime.PodSandboxStatusResponse{Status: status}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user