diff --git a/cri/v1alpha2/cri.go b/cri/v1alpha2/cri.go index 0f0520478e..48111b27a1 100644 --- a/cri/v1alpha2/cri.go +++ b/cri/v1alpha2/cri.go @@ -125,6 +125,9 @@ type CriManager struct { // SandboxStore stores the configuration of sandboxes. SandboxStore *meta.Store + // ContainerStore stores the configuration of containers. + ContainerStore *meta.Store + // SnapshotStore stores information of all snapshots. SnapshotStore *mgr.SnapshotStore @@ -180,6 +183,20 @@ func NewCriManager(config *config.Config, ctrMgr mgr.ContainerMgr, imgMgr mgr.Im return nil, fmt.Errorf("failed to create sandbox meta store: %v", err) } + c.ContainerStore, err = meta.NewStore(meta.Config{ + Driver: "local", + BaseDir: path.Join(config.HomeDir, "containers-meta"), + Buckets: []meta.Bucket{ + { + Name: meta.MetaJSONFile, + Type: reflect.TypeOf(ContainerMeta{}), + }, + }, + }) + if err != nil { + return nil, fmt.Errorf("failed to create container meta store: %v", err) + } + c.imageFSPath = imageFSPath(path.Join(config.HomeDir, "containerd/root"), defaultSnapshotterName) logrus.Infof("Get image filesystem path %q", c.imageFSPath) @@ -532,28 +549,29 @@ func (c *CriManager) RemovePodSandbox(ctx context.Context, r *runtime.RemovePodS // Remove all containers in the sandbox. for _, container := range containers { - err = c.ContainerMgr.Remove(ctx, container.ID, &apitypes.ContainerRemoveOptions{Volumes: true, Force: true}) - if err != nil { + if err = c.ContainerMgr.Remove(ctx, container.ID, &apitypes.ContainerRemoveOptions{Volumes: true, Force: true}); err != nil { return nil, fmt.Errorf("failed to remove container %q of sandbox %q: %v", container.ID, podSandboxID, err) } + + if err = c.ContainerStore.Remove(container.ID); err != nil { + return nil, fmt.Errorf("failed to remove container meta %q: %v", container.ID, err) + } logrus.Infof("success to remove container %q of sandbox %q", container.ID, podSandboxID) } // Remove the sandbox container. - err = c.ContainerMgr.Remove(ctx, podSandboxID, &apitypes.ContainerRemoveOptions{Volumes: true, Force: true}) - if err != nil { + if err = c.ContainerMgr.Remove(ctx, podSandboxID, &apitypes.ContainerRemoveOptions{Volumes: true, Force: true}); err != nil { return nil, fmt.Errorf("failed to remove sandbox %q: %v", podSandboxID, err) } // Cleanup the sandbox root directory. sandboxRootDir := path.Join(c.SandboxBaseDir, podSandboxID) - err = os.RemoveAll(sandboxRootDir) - if err != nil { + + if err = os.RemoveAll(sandboxRootDir); err != nil { return nil, fmt.Errorf("failed to remove root directory %q: %v", sandboxRootDir, err) } - err = c.SandboxStore.Remove(podSandboxID) - if err != nil { + if err = c.SandboxStore.Remove(podSandboxID); err != nil { return nil, fmt.Errorf("failed to remove meta %q: %v", sandboxRootDir, err) } @@ -801,6 +819,13 @@ func (c *CriManager) CreateContainer(ctx context.Context, r *runtime.CreateConta if err := c.ContainerMgr.AttachCRILog(ctx, containerID, logPath); err != nil { return nil, err } + + // store the logpath of container + containerMeta := &ContainerMeta{ + ID: containerID, + CRILogPath: logPath, + } + c.ContainerStore.Put(containerMeta) } metrics.ContainerSuccessActionsCounter.WithLabelValues(label).Inc() @@ -858,11 +883,14 @@ func (c *CriManager) RemoveContainer(ctx context.Context, r *runtime.RemoveConta containerID := r.GetContainerId() - err := c.ContainerMgr.Remove(ctx, containerID, &apitypes.ContainerRemoveOptions{Volumes: true, Force: true}) - if err != nil { + if err := c.ContainerMgr.Remove(ctx, containerID, &apitypes.ContainerRemoveOptions{Volumes: true, Force: true}); err != nil { return nil, fmt.Errorf("failed to remove container %q: %v", containerID, err) } + if err := c.ContainerStore.Remove(containerID); err != nil { + return nil, fmt.Errorf("failed to remove container meta %q: %v", containerID, err) + } + metrics.ContainerSuccessActionsCounter.WithLabelValues(label).Inc() return &runtime.RemoveContainerResponse{}, nil @@ -1161,7 +1189,30 @@ func (c *CriManager) UpdateContainerResources(ctx context.Context, r *runtime.Up // to either create a new log file and return nil, or return an error. // Once it returns error, new container log file MUST NOT be created. func (c *CriManager) ReopenContainerLog(ctx context.Context, r *runtime.ReopenContainerLogRequest) (*runtime.ReopenContainerLogResponse, error) { - return nil, fmt.Errorf("ReopenContainerLog 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 with error: %v", containerID, err) + } + if !container.IsRunning() { + return nil, fmt.Errorf("container is not running") + } + + res, err := c.ContainerStore.Get(containerID) + if err != nil { + return nil, err + } + containerMeta, ok := res.(*ContainerMeta) + if !ok { + return nil, fmt.Errorf("failed to type asseration for containerMeta: %v", res) + } + + if err := c.ContainerMgr.AttachCRILog(ctx, container.Name, containerMeta.CRILogPath); err != nil { + return nil, err + } + + return &runtime.ReopenContainerLogResponse{}, nil } // ExecSync executes a command in the container, and returns the stdout output. diff --git a/cri/v1alpha2/cri_types.go b/cri/v1alpha2/cri_types.go index 7096dbd0fc..73e949daf4 100644 --- a/cri/v1alpha2/cri_types.go +++ b/cri/v1alpha2/cri_types.go @@ -29,3 +29,17 @@ type SandboxMeta struct { func (meta *SandboxMeta) Key() string { return meta.ID } + +// ContainerMeta represents the container's meta data. +type ContainerMeta struct { + // ID is the id of container. + ID string + + // CRILogPath is the path of the cri log. + CRILogPath string +} + +// Key returns sandbox's id. +func (meta *ContainerMeta) Key() string { + return meta.ID +} diff --git a/hack/testing/run_daemon_cri_integration.sh b/hack/testing/run_daemon_cri_integration.sh index 85b3aec244..1ece503249 100755 --- a/hack/testing/run_daemon_cri_integration.sh +++ b/hack/testing/run_daemon_cri_integration.sh @@ -20,7 +20,6 @@ export PATH="${GOPATH}/bin:${PATH}" # CRI_SKIP skips the test to skip. DEFAULT_CRI_SKIP="seccomp localhost" DEFAULT_CRI_SKIP="${DEFAULT_CRI_SKIP}|should error on create with wrong options" -DEFAULT_CRI_SKIP="${DEFAULT_CRI_SKIP}|runtime should support reopening container log" CRI_SKIP="${CRI_SKIP:-"${DEFAULT_CRI_SKIP}"}" # CRI_FOCUS focuses the test to run.