siemens/pycontainerd

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:

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)

@anmult can we close this issue? It looks as if @thediveo help resolved it, right?

@Silvanoc I think we can close this issue as there has been no feedback.