add example for Tasks.Exec API
anmult opened this issue · 5 comments
Hello,
Would you be kind to add example for Tasks.Exec API? I'm wondering how to make 'spec' parameter for 'ExecProcessRequest'.
Based on API DSL https://github.com/containerd/containerd/blob/release/1.4/api/services/tasks/v1/tasks.proto#L140 it's 'google.protobuf.Any' type and, as I understood, for 'runc' runtime the 'Process' struct from https://godoc.org/github.com/opencontainers/runtime-spec/specs-go#Process should be packed into protobuf 'Any'.
Unfortunately, I didn't find this data structure in python containerd distribution.
Library: pip3 install --user containerd==1.4.1
Example:
`
import grpc
from containerd.services.tasks.v1 import (
tasks_pb2,
tasks_pb2_grpc,
)
from google.protobuf.any_pb2 import Any
CONTAINERD_SOCKET_PATH = '/var/run/containerd/containerd.sock'
url = 'unix://' + CONTAINERD_SOCKET_PATH
namespace = '...'
container_id = '...'
channel = grpc.insecure_channel(url)
service = tasks_pb2_grpc.TasksStub(channel)
command = 'echo hello'
sub_message = ?
message = Any()
message.Pack(sub_message)
request = tasks_pb2.ExecProcessRequest(container_id=container_id, exec_id='myproc', spec=message)
result = service.Exec(request=request, timeout=15, metadata=(('containerd-namespace', namespace),))
print(result)
`
Thank you in advance!
This definition of Process
is not the same as the containerd API Process
, correct? Then it is not part of this containerd
package. I'm afraid that this will need a separate package from opencontainers project. Can you please contact them about a Python package with their API definitions and maybe link your opencontainer issue here?
Looking around further, I found https://github.com/opencontainers/runtime-spec/blob/master/config.md which says that the specification actually stems from a JSON schema definition, with Process
being defined here: https://github.com/opencontainers/runtime-spec/blob/7413a7f753e1bd9a6a9c6dc7f96f55888cbbd476/schema/config-schema.json#L59. Looking at the Go file you link to I notice that these are (usual) struct definitions with annotations for JSON (un)marshalling, to use the funny Golang terminology.
This appears to me as if you actually need to put a JSON document into the any
section, so there won't be any .proto definitions anyway. As for the encoding I dunno, but doesn't Python's json.dumps() emit binary strings? If not, you probably need to encode into utf8 and feed the resulting binary string into the any
part.
Appreciate your help!
After review of containerd' code I've found that CRI API suites me well. It encapsulates Tasks.Exec
low level stuff and provides simple API RuntimeService.ExecSync
for my use case.
Refs:
- https://github.com/containerd/cri/blob/release/1.4/pkg/server/container_execsync.go#L73
- https://github.com/kubernetes/cri-api/blob/master/pkg/apis/runtime/v1alpha2/api.proto
Here example:
# pip3 install --user container-runtime-interface-api
import grpc
import cri_api as api
CONTAINERD_SOCKET = 'unix:/var/run/containerd/containerd.sock'
channel = grpc.insecure_channel(CONTAINERD_SOCKET)
runtime_stub = api.RuntimeServiceStub(channel)
cid = <containerd_id>
cmd = ['/bin/echo', 'hello']
request = api.ExecSyncRequest(container_id=cid, cmd=cmd, timeout=5)
response = runtime_stub.ExecSync(request)
print(response)