Seraph
Seraph

Reputation: 307

Capture the output of Docker EXEC through API

I'm writing a C function to take arguments "container name" and "command" to run the command inside the appointed container and return the output. I'm using libdocker to call the Restful API with curl. Currently the command can be executed successfully, but I don't know how to redirect and capture the output. Here is my code:

char * docker_exec(const char * name, const char * cmd) {
    json_error_t error;
    DOCKER *docker = docker_init(DOCKER_API_VERSION);
    DOCKER *docker2 = docker_init(DOCKER_API_VERSION);
    char url[100];
    long http_status = 0;
    char postdata[1024];

    // Create exec instance
    sprintf(postdata, "{\"AttachStdout\":true,\"AttachStderr\":true,\"Cmd\":[\"%s\"]}", cmd);
    sprintf(url, "http://%s/containers/%s/exec", DOCKER_API_VERSION, name);
    CURLcode response = docker_post_with_http_status(docker, url, postdata, &http_status);

    // Start exec instance with its ID
    json_t * j_id = json_loads(docker_buffer(docker), JSON_COMPACT, &error);
    sprintf(url, "http://%s/exec/%s/start", DOCKER_API_VERSION, 
    json_string_value(json_object_get(j_id, "Id")));
    response = docker_post_with_http_status(docker2, url, "{\"Detach\":false,\"Tty\":false}", &http_status);
    
    ...

    return ???; // The buffer of docker2 is empty.
}

I found the official Python test code for this function, This is basically what I want. I also tested cURL command in terminal with no problem:

curl -H "Content-Type: application/json" -X POST http://localhost:2375/containers/[container_id]/exec -d '{ "AttachStdout": true, "AttachStderr": true, "Cmd": ["ls", "-l", "/"] }'
curl -H "Content-Type: application/json" -X POST http://localhost:2375/exec/[exec_id]/start -d '{"Detach": false, "Tty": false}' --output -

and tried to modify libdocker with no luck:

curl_easy_setopt(client->curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(client->curl, CURLOPT_WRITEDATA, docker_buffer(client));
// callback function to test output, print nothing
static size_t write_callback(char *contents, size_t size, size_t nmemb, void *userp) {
    printf("%s\n", contents);
    return size * nmemb;
}

The buffer of Docker instance to start the exec is always empty.

Upvotes: 2

Views: 399

Answers (0)

Related Questions