Merge pull request #7470 from lengrongfu/feat/sandbox_api_status
Sandbox API: implement Controller.Status for SandboxAPI
This commit is contained in:
		| @@ -22,6 +22,7 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/containerd/containerd" | 	"github.com/containerd/containerd" | ||||||
|  | 	eventtypes "github.com/containerd/containerd/api/events" | ||||||
| 	api "github.com/containerd/containerd/api/services/sandbox/v1" | 	api "github.com/containerd/containerd/api/services/sandbox/v1" | ||||||
| 	"github.com/containerd/containerd/errdefs" | 	"github.com/containerd/containerd/errdefs" | ||||||
| 	"github.com/containerd/containerd/oci" | 	"github.com/containerd/containerd/oci" | ||||||
| @@ -84,8 +85,23 @@ func New( | |||||||
| var _ sandbox.Controller = (*Controller)(nil) | var _ sandbox.Controller = (*Controller)(nil) | ||||||
|  |  | ||||||
| func (c *Controller) Status(ctx context.Context, sandboxID string) (*api.ControllerStatusResponse, error) { | func (c *Controller) Status(ctx context.Context, sandboxID string) (*api.ControllerStatusResponse, error) { | ||||||
| 	//TODO implement me | 	sandbox, err := c.sandboxStore.Get(sandboxID) | ||||||
| 	panic("implement me") | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("an error occurred while trying to find sandbox %q: %w", | ||||||
|  | 			sandboxID, err) | ||||||
|  | 	} | ||||||
|  | 	status := sandbox.Status.Get() | ||||||
|  | 	resp := &api.ControllerStatusResponse{ | ||||||
|  | 		ID:         sandboxID, | ||||||
|  | 		Pid:        status.Pid, | ||||||
|  | 		State:      status.State.String(), | ||||||
|  | 		ExitStatus: status.ExitStatus, | ||||||
|  | 		Extra:      nil, | ||||||
|  | 	} | ||||||
|  | 	if !status.ExitedAt.IsZero() { | ||||||
|  | 		resp.ExitedAt = protobuf.ToTimestamp(status.ExitedAt) | ||||||
|  | 	} | ||||||
|  | 	return resp, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *Controller) Wait(ctx context.Context, sandboxID string) (*api.ControllerWaitResponse, error) { | func (c *Controller) Wait(ctx context.Context, sandboxID string) (*api.ControllerWaitResponse, error) { | ||||||
| @@ -123,7 +139,7 @@ func (c *Controller) waitSandboxExit(ctx context.Context, id string, exitCh <-ch | |||||||
|  |  | ||||||
| 			sb, err := c.sandboxStore.Get(id) | 			sb, err := c.sandboxStore.Get(id) | ||||||
| 			if err == nil { | 			if err == nil { | ||||||
| 				if err := handleSandboxExit(dctx, sb); err != nil { | 				if err := handleSandboxExit(dctx, sb, &eventtypes.TaskExit{ExitStatus: exitStatus, ExitedAt: protobuf.ToTimestamp(exitedAt)}); err != nil { | ||||||
| 					return err | 					return err | ||||||
| 				} | 				} | ||||||
| 				return nil | 				return nil | ||||||
| @@ -144,7 +160,8 @@ func (c *Controller) waitSandboxExit(ctx context.Context, id string, exitCh <-ch | |||||||
| } | } | ||||||
|  |  | ||||||
| // handleSandboxExit handles TaskExit event for sandbox. | // handleSandboxExit handles TaskExit event for sandbox. | ||||||
| func handleSandboxExit(ctx context.Context, sb sandboxstore.Sandbox) error { | // TODO https://github.com/containerd/containerd/issues/7548 | ||||||
|  | func handleSandboxExit(ctx context.Context, sb sandboxstore.Sandbox, e *eventtypes.TaskExit) error { | ||||||
| 	// No stream attached to sandbox container. | 	// No stream attached to sandbox container. | ||||||
| 	task, err := sb.Container.Task(ctx, nil) | 	task, err := sb.Container.Task(ctx, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -163,6 +180,8 @@ func handleSandboxExit(ctx context.Context, sb sandboxstore.Sandbox) error { | |||||||
| 	sb.Status.Update(func(status sandboxstore.Status) (sandboxstore.Status, error) { | 	sb.Status.Update(func(status sandboxstore.Status) (sandboxstore.Status, error) { | ||||||
| 		status.State = sandboxstore.StateNotReady | 		status.State = sandboxstore.StateNotReady | ||||||
| 		status.Pid = 0 | 		status.Pid = 0 | ||||||
|  | 		status.ExitStatus = e.ExitStatus | ||||||
|  | 		status.ExitedAt = e.ExitedAt.AsTime() | ||||||
| 		return status, nil | 		return status, nil | ||||||
| 	}) | 	}) | ||||||
| 	// Using channel to propagate the information of sandbox stop | 	// Using channel to propagate the information of sandbox stop | ||||||
|   | |||||||
| @@ -17,10 +17,16 @@ | |||||||
| package podsandbox | package podsandbox | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	criconfig "github.com/containerd/containerd/pkg/cri/config" | 	criconfig "github.com/containerd/containerd/pkg/cri/config" | ||||||
| 	"github.com/containerd/containerd/pkg/cri/store/label" | 	"github.com/containerd/containerd/pkg/cri/store/label" | ||||||
| 	sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox" | 	sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox" | ||||||
| 	ostesting "github.com/containerd/containerd/pkg/os/testing" | 	ostesting "github.com/containerd/containerd/pkg/os/testing" | ||||||
|  | 	"github.com/containerd/containerd/protobuf" | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| @@ -50,3 +56,34 @@ func newControllerService() *Controller { | |||||||
| 		sandboxStore: sandboxstore.NewStore(labels), | 		sandboxStore: sandboxstore.NewStore(labels), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func Test_Status(t *testing.T) { | ||||||
|  | 	sandboxID, pid, exitStatus := "1", uint32(1), uint32(0) | ||||||
|  | 	createdAt, exitedAt := time.Now(), time.Now() | ||||||
|  | 	controller := newControllerService() | ||||||
|  | 	status := sandboxstore.Status{ | ||||||
|  | 		Pid:        pid, | ||||||
|  | 		CreatedAt:  createdAt, | ||||||
|  | 		ExitStatus: exitStatus, | ||||||
|  | 		ExitedAt:   exitedAt, | ||||||
|  | 		State:      sandboxstore.StateReady, | ||||||
|  | 	} | ||||||
|  | 	sb := sandboxstore.Sandbox{ | ||||||
|  | 		Metadata: sandboxstore.Metadata{ | ||||||
|  | 			ID: sandboxID, | ||||||
|  | 		}, | ||||||
|  | 		Status: sandboxstore.StoreStatus(status), | ||||||
|  | 	} | ||||||
|  | 	err := controller.sandboxStore.Add(sb) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  | 	s, err := controller.Status(context.Background(), sandboxID) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  | 	assert.Equal(t, s.Pid, pid) | ||||||
|  | 	assert.Equal(t, s.ExitStatus, exitStatus) | ||||||
|  | 	assert.Equal(t, s.ExitedAt, protobuf.ToTimestamp(exitedAt)) | ||||||
|  | 	assert.Equal(t, s.State, sandboxstore.StateReady.String()) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"syscall" | 	"syscall" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/sirupsen/logrus" | 	"github.com/sirupsen/logrus" | ||||||
|  |  | ||||||
| @@ -135,5 +136,5 @@ func (c *Controller) waitSandboxStop(ctx context.Context, sandbox sandboxstore.S | |||||||
| // cleanupUnknownSandbox cleanup stopped sandbox in unknown state. | // cleanupUnknownSandbox cleanup stopped sandbox in unknown state. | ||||||
| func cleanupUnknownSandbox(ctx context.Context, id string, sandbox sandboxstore.Sandbox) error { | func cleanupUnknownSandbox(ctx context.Context, id string, sandbox sandboxstore.Sandbox) error { | ||||||
| 	// Reuse handleSandboxExit to do the cleanup. | 	// Reuse handleSandboxExit to do the cleanup. | ||||||
| 	return handleSandboxExit(ctx, sandbox) | 	return handleSandboxExit(ctx, sandbox, &eventtypes.TaskExit{ExitStatus: unknownExitCode, ExitedAt: protobuf.ToTimestamp(time.Now())}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -99,6 +99,10 @@ type Status struct { | |||||||
| 	Pid uint32 | 	Pid uint32 | ||||||
| 	// CreatedAt is the created timestamp. | 	// CreatedAt is the created timestamp. | ||||||
| 	CreatedAt time.Time | 	CreatedAt time.Time | ||||||
|  | 	// ExitedAt is the stop timestamp | ||||||
|  | 	ExitedAt time.Time | ||||||
|  | 	// ExitStatus is the stop sandbox status | ||||||
|  | 	ExitStatus uint32 | ||||||
| 	// State is the state of the sandbox. | 	// State is the state of the sandbox. | ||||||
| 	State State | 	State State | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Maksym Pavlenko
					Maksym Pavlenko