ctr: shim state query for old shims

Old shims do not implement containerd.task.v3.Task, but it can be
useful to use a new ctr with an older shim especially during upgrade
scenarios.

Signed-off-by: Samuel Karp <samuelkarp@google.com>
This commit is contained in:
Samuel Karp 2024-08-07 16:42:59 -07:00
parent d59e8a8404
commit 7d4da0cb28
No known key found for this signature in database
GPG Key ID: 997C5A3CD3167CB5

View File

@ -28,7 +28,8 @@ import (
"strings" "strings"
"github.com/containerd/console" "github.com/containerd/console"
"github.com/containerd/containerd/api/runtime/task/v3" taskv2 "github.com/containerd/containerd/api/runtime/task/v2"
task "github.com/containerd/containerd/api/runtime/task/v3"
"github.com/containerd/containerd/v2/cmd/ctr/commands" "github.com/containerd/containerd/v2/cmd/ctr/commands"
"github.com/containerd/containerd/v2/pkg/namespaces" "github.com/containerd/containerd/v2/pkg/namespaces"
ptypes "github.com/containerd/containerd/v2/pkg/protobuf/types" ptypes "github.com/containerd/containerd/v2/pkg/protobuf/types"
@ -122,22 +123,48 @@ var stateCommand = &cli.Command{
Aliases: []string{"t"}, Aliases: []string{"t"},
Usage: "task ID", Usage: "task ID",
}, },
&cli.IntFlag{
Name: "api-version",
Usage: "shim API version {2,3}",
Value: 3,
Action: func(c *cli.Context, v int) error {
if v != 2 && v != 3 {
return fmt.Errorf("api-version must be 2 or 3")
}
return nil
},
},
}, },
Action: func(cliContext *cli.Context) error { Action: func(cliContext *cli.Context) error {
service, err := getTaskService(cliContext)
if err != nil {
return err
}
id := cliContext.String("task-id") id := cliContext.String("task-id")
if id == "" { if id == "" {
id = cliContext.String("id") id = cliContext.String("id")
} }
r, err := service.State(context.Background(), &task.StateRequest{ var r any
ID: id, switch cliContext.Int("api-version") {
}) case 2:
if err != nil { service, err := getTaskServiceV2(cliContext)
return err if err != nil {
return err
}
r, err = service.State(context.Background(), &taskv2.StateRequest{
ID: id,
})
if err != nil {
return err
}
default:
service, err := getTaskService(cliContext)
if err != nil {
return err
}
r, err = service.State(context.Background(), &task.StateRequest{
ID: id,
})
if err != nil {
return err
}
} }
commands.PrintAsJSON(r) commands.PrintAsJSON(r)
return nil return nil
@ -246,6 +273,21 @@ var execCommand = &cli.Command{
} }
func getTaskService(cliContext *cli.Context) (task.TTRPCTaskService, error) { func getTaskService(cliContext *cli.Context) (task.TTRPCTaskService, error) {
client, err := getTTRPCClient(cliContext)
if err != nil {
return nil, err
}
return task.NewTTRPCTaskClient(client), nil
}
func getTaskServiceV2(cliContext *cli.Context) (taskv2.TaskService, error) {
client, err := getTTRPCClient(cliContext)
if err != nil {
return nil, err
}
return taskv2.NewTaskClient(client), nil
}
func getTTRPCClient(cliContext *cli.Context) (*ttrpc.Client, error) {
id := cliContext.String("id") id := cliContext.String("id")
if id == "" { if id == "" {
return nil, fmt.Errorf("container id must be specified") return nil, fmt.Errorf("container id must be specified")
@ -268,7 +310,7 @@ func getTaskService(cliContext *cli.Context) (task.TTRPCTaskService, error) {
// TODO(stevvooe): This actually leaks the connection. We were leaking it // TODO(stevvooe): This actually leaks the connection. We were leaking it
// before, so may not be a huge deal. // before, so may not be a huge deal.
return task.NewTTRPCTaskClient(client), nil return client, nil
} }
} }