iSulad/src/connect/client/rest/rest_containers_client.c
LiFeng e2728aa73e iSulad: internal change
Signed-off-by: LiFeng <lifeng68@huawei.com>
2020-01-06 05:11:01 -05:00

1776 lines
53 KiB
C

/******************************************************************************
* Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
* iSulad licensed under the Mulan PSL v1.
* You can use this software according to the terms and conditions of the Mulan PSL v1.
* You may obtain a copy of Mulan PSL v1 at:
* http://license.coscl.org.cn/MulanPSL
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
* PURPOSE.
* See the Mulan PSL v1 for more details.
* Author: lifeng
* Create: 2018-11-08
* Description: provide container restful functions
******************************************************************************/
#include <unistd.h>
#include "error.h"
#include "log.h"
#include "lcrc_connect.h"
#include "container.rest.h"
#include "pack_config.h"
#include "rest_common.h"
#include "rest_containers_client.h"
/* create request to rest */
static int create_request_to_rest(const struct lcrc_create_request *lc_request, char **body, size_t *body_len)
{
container_create_request *crequest = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
crequest = util_common_calloc_s(sizeof(container_create_request));
if (crequest == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
ret = generate_hostconfig(lc_request->hostconfig, &crequest->hostconfig);
if (ret != 0) {
ERROR("Failed to pack host config");
ret = EINVALIDARGS;
goto out;
}
ret = generate_container_config(lc_request->config, &crequest->customconfig);
if (ret != 0) {
ERROR("Failed to pack custom config");
ret = EINVALIDARGS;
goto out;
}
if (lc_request->name != NULL) {
crequest->id = util_strdup_s(lc_request->name);
}
if (lc_request->image != NULL) {
crequest->image = util_strdup_s(lc_request->image);
}
if (lc_request->rootfs != NULL) {
crequest->rootfs = util_strdup_s(lc_request->rootfs);
}
if (lc_request->runtime != NULL) {
crequest->runtime = util_strdup_s(lc_request->runtime);
}
*body = container_create_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate create request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_create_request(crequest);
return ret;
}
/* start request to rest */
static int start_request_to_rest(const struct lcrc_start_request *ls_request, char **body, size_t *body_len)
{
container_start_request *crequest = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
crequest = util_common_calloc_s(sizeof(container_start_request));
if (crequest == NULL) {
ERROR("Out of memory");
return -1;
}
if (ls_request->name != NULL) {
crequest->id = util_strdup_s(ls_request->name);
}
if (ls_request->stdout != NULL) {
crequest->stdout = util_strdup_s(ls_request->stdout);
}
if (ls_request->stdin != NULL) {
crequest->stdin = util_strdup_s(ls_request->stdin);
}
if (ls_request->stderr != NULL) {
crequest->stderr = util_strdup_s(ls_request->stderr);
}
crequest->attach_stdin = ls_request->attach_stdin;
crequest->attach_stdout = ls_request->attach_stdout;
crequest->attach_stderr = ls_request->attach_stderr;
*body = container_start_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate start request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_start_request(crequest);
return ret;
}
/* list request to rest */
static int list_request_to_rest(const struct lcrc_list_request *ll_request, char **body, size_t *body_len)
{
container_list_request *crequest = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
size_t i, len;
crequest = util_common_calloc_s(sizeof(container_list_request));
if (crequest == NULL) {
ERROR("Out of memory");
return -1;
}
crequest->all = ll_request->all;
if (ll_request->filters == NULL || ll_request->filters->len == 0) {
goto pack_json;
}
crequest->filters = util_common_calloc_s(sizeof(defs_filters));
if (crequest->filters == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
len = ll_request->filters->len;
if (len > SIZE_MAX / sizeof(char *)) {
ERROR("Too many filters");
ret = -1;
goto out;
}
crequest->filters->keys = (char **)util_common_calloc_s(len * sizeof(char *));
if (crequest->filters->keys == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
crequest->filters->values = (json_map_string_bool **)util_common_calloc_s(len * sizeof(json_map_string_bool *));
if (crequest->filters->values == NULL) {
ERROR("Out of memory");
free(crequest->filters->keys);
crequest->filters->keys = NULL;
ret = -1;
goto out;
}
for (i = 0; i < ll_request->filters->len; i++) {
crequest->filters->values[crequest->filters->len] = util_common_calloc_s(sizeof(json_map_string_bool));
if (crequest->filters->values[crequest->filters->len] == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
if (append_json_map_string_bool(crequest->filters->values[crequest->filters->len],
ll_request->filters->values[i], true)) {
free(crequest->filters->values[crequest->filters->len]);
crequest->filters->values[crequest->filters->len] = NULL;
ERROR("Append failed");
ret = -1;
goto out;
}
crequest->filters->keys[crequest->filters->len] = util_strdup_s(ll_request->filters->keys[i]);
crequest->filters->len++;
}
pack_json:
*body = container_list_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate list request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_list_request(crequest);
return ret;
}
/* attach request to rest */
static int attach_request_to_rest(const struct lcrc_attach_request *la_request, char **body, size_t *body_len)
{
container_attach_request *crequest = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
crequest = util_common_calloc_s(sizeof(container_attach_request));
if (crequest == NULL) {
ERROR("Out of memory");
return -1;
}
if (la_request->name != NULL) {
crequest->container_id = util_strdup_s(la_request->name);
}
if (la_request->stdout != NULL) {
crequest->stdout = util_strdup_s(la_request->stdout);
}
if (la_request->stdin != NULL) {
crequest->stdin = util_strdup_s(la_request->stdin);
}
if (la_request->stderr != NULL) {
crequest->stderr = util_strdup_s(la_request->stderr);
}
*body = container_attach_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate attach request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_attach_request(crequest);
return ret;
}
/* resume request to rest */
static int resume_request_to_rest(const struct lcrc_resume_request *lr_request, char **body, size_t *body_len)
{
container_resume_request *crequest = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
crequest = util_common_calloc_s(sizeof(container_resume_request));
if (crequest == NULL) {
ERROR("Out of memory");
return -1;
}
if (lr_request->name != NULL) {
crequest->id = util_strdup_s(lr_request->name);
}
*body = container_resume_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate resume request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_resume_request(crequest);
return ret;
}
/* wait request to rest */
static int wait_request_to_rest(const struct lcrc_wait_request *lw_request, char **body, size_t *body_len)
{
container_wait_request *crequest = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
crequest = util_common_calloc_s(sizeof(container_wait_request));
if (crequest == NULL) {
ERROR("Out of memory");
return -1;
}
if (lw_request->id != NULL) {
crequest->id = util_strdup_s(lw_request->id);
}
crequest->condition = lw_request->condition;
*body = container_wait_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate wait request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_wait_request(crequest);
return ret;
}
/* unpack create response */
static int unpack_create_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_create_response *response = arg;
container_create_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_create_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid create response:%s", err);
ret = -1;
goto out;
}
response->server_errono = cresponse->cc;
if (cresponse->errmsg != NULL) {
response->errmsg = util_strdup_s(cresponse->errmsg);
}
if (cresponse->id != NULL) {
response->id = util_strdup_s(cresponse->id);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free(err);
free_container_create_response(cresponse);
return ret;
}
/* unpack start response */
static int unpack_start_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_start_response *start_response = arg;
container_start_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_start_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid start response:%s", err);
ret = -1;
goto out;
}
start_response->server_errono = cresponse->cc;
if (cresponse->errmsg != NULL) {
start_response->errmsg = util_strdup_s(cresponse->errmsg);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free(err);
free_container_start_response(cresponse);
return ret;
}
static int unpack_container_info_for_list_response(container_list_response *cresponse,
struct lcrc_list_response *response)
{
size_t num = 0;
size_t i = 0;
struct lcrc_container_summary_info **summary_info = NULL;
if (cresponse == NULL || response == NULL) {
return -1;
}
num = cresponse->containers_len;
if (num == 0) {
return 0;
}
if (num > SIZE_MAX / sizeof(struct lcrc_container_summary_info *)) {
ERROR("Too many container summaries");
return -1;
}
summary_info = (struct lcrc_container_summary_info **)util_common_calloc_s(
sizeof(struct lcrc_container_summary_info *) * num);
if (summary_info == NULL) {
ERROR("out of memory");
return -1;
}
response->container_num = num;
response->container_summary = summary_info;
for (i = 0; i < num; i++) {
summary_info[i] =
(struct lcrc_container_summary_info *)util_common_calloc_s(sizeof(struct lcrc_container_summary_info));
if (summary_info[i] == NULL) {
ERROR("Out of memory");
return -1;
}
summary_info[i]->id = cresponse->containers[i]->id ? util_strdup_s(cresponse->containers[i]->id)
: util_strdup_s("-");
summary_info[i]->name = cresponse->containers[i]->name ? util_strdup_s(cresponse->containers[i]->name)
: util_strdup_s("-");
summary_info[i]->runtime = cresponse->containers[i]->runtime ? util_strdup_s(cresponse->containers[i]->runtime)
: util_strdup_s("-");
summary_info[i]->has_pid = cresponse->containers[i]->pid != 0;
summary_info[i]->pid = cresponse->containers[i]->pid;
summary_info[i]->status = cresponse->containers[i]->status;
summary_info[i]->image = cresponse->containers[i]->image ? util_strdup_s(cresponse->containers[i]->image)
: util_strdup_s("-");
summary_info[i]->command = cresponse->containers[i]->command ? util_strdup_s(cresponse->containers[i]->command)
: util_strdup_s("-");
summary_info[i]->startat = cresponse->containers[i]->startat ? util_strdup_s(cresponse->containers[i]->startat)
: util_strdup_s("-");
summary_info[i]->finishat = cresponse->containers[i]->finishat ?
util_strdup_s(cresponse->containers[i]->finishat) : util_strdup_s("-");
summary_info[i]->exit_code = cresponse->containers[i]->exit_code;
summary_info[i]->restart_count = (unsigned int)cresponse->containers[i]->restartcount;
}
return 0;
}
/* unpack list response */
static int unpack_list_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_list_response *response = arg;
container_list_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_list_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid list response:%s", err);
ret = -1;
goto out;
}
response->server_errono = cresponse->cc;
if (cresponse->errmsg != NULL) {
response->errmsg = util_strdup_s(cresponse->errmsg);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
if (unpack_container_info_for_list_response(cresponse, response)) {
ret = -1;
goto out;
}
out:
free(err);
free_container_list_response(cresponse);
return ret;
}
/* unpack attach response */
static int unpack_attach_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_attach_response *attach_response = arg;
container_attach_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_attach_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid attach response:%s", err);
ret = -1;
goto out;
}
attach_response->server_errono = cresponse->cc;
if (cresponse->errmsg != NULL) {
attach_response->errmsg = util_strdup_s(cresponse->errmsg);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free(err);
free_container_attach_response(cresponse);
return ret;
}
/* unpack resume response */
static int unpack_resume_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_resume_response *resume_response = arg;
container_resume_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_resume_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid resume response:%s", err);
ret = -1;
goto out;
}
resume_response->server_errono = cresponse->cc;
if (cresponse->errmsg != NULL) {
resume_response->errmsg = util_strdup_s(cresponse->errmsg);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free(err);
free_container_resume_response(cresponse);
return ret;
}
/* unpack wait response */
static int unpack_wait_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_wait_response *response = arg;
container_wait_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_wait_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid create response:%s", err);
ret = -1;
goto out;
}
response->server_errono = cresponse->cc;
response->exit_code = (int)cresponse->exit_code;
if (cresponse->errmsg != NULL) {
response->errmsg = util_strdup_s(cresponse->errmsg);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free_container_wait_response(cresponse);
free(err);
return ret;
}
/* rest container create */
static int rest_container_create(const struct lcrc_create_request *lc_request,
struct lcrc_create_response *lc_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len = 0;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *c_output = NULL;
ret = create_request_to_rest(lc_request, &body, &len);
if (ret != 0) {
lc_response->cc = LCRD_ERR_INPUT;
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceCreate, body, len, &c_output);
if (ret != 0) {
lc_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
lc_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(c_output, unpack_create_response, (void *)lc_response);
if (ret != 0) {
goto out;
}
out:
if (c_output != NULL) {
buffer_free(c_output);
}
put_body(body);
return ret;
}
/* rest container start */
static int rest_container_start(const struct lcrc_start_request *ls_request, struct lcrc_start_response *ls_response,
void *arg)
{
char *body = NULL;
int ret = 0;
size_t len = 0;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *s_output = NULL;
ret = start_request_to_rest(ls_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceStart, body, len, &s_output);
if (ret != 0) {
ls_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
ls_response->cc = LCRD_ERR_EXEC;
ls_response->server_errono = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(s_output, unpack_start_response, (void *)ls_response);
if (ret != 0) {
goto out;
}
out:
if (s_output != NULL) {
buffer_free(s_output);
}
put_body(body);
return ret;
}
/* rest container attach */
static int rest_container_attach(const struct lcrc_attach_request *la_request,
struct lcrc_attach_response *la_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len = 0;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *a_output = NULL;
ret = attach_request_to_rest(la_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceAttach, body, len, &a_output);
if (ret != 0) {
la_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
la_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(a_output, unpack_attach_response, (void *)la_response);
if (ret != 0) {
goto out;
}
out:
if (a_output != NULL) {
buffer_free(a_output);
}
put_body(body);
return ret;
}
/* rest container list */
static int rest_container_list(const struct lcrc_list_request *ll_request,
struct lcrc_list_response *ll_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len = 0;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *l_output = NULL;
ret = list_request_to_rest(ll_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceList, body, len, &l_output);
if (ret != 0) {
ll_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
ll_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(l_output, unpack_list_response, (void *)ll_response);
if (ret != 0) {
goto out;
}
out:
if (l_output != NULL) {
buffer_free(l_output);
}
put_body(body);
return ret;
}
/* rest container resume */
static int rest_container_resume(const struct lcrc_resume_request *lr_request,
struct lcrc_resume_response *lr_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len = 0;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *r_output = NULL;
ret = resume_request_to_rest(lr_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceResume, body, len, &r_output);
if (ret != 0) {
lr_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
lr_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(r_output, unpack_resume_response, (void *)lr_response);
if (ret != 0) {
goto out;
}
out:
if (r_output != NULL) {
buffer_free(r_output);
}
put_body(body);
return ret;
}
/* rest container wait */
static int rest_container_wait(const struct lcrc_wait_request *lw_request,
struct lcrc_wait_response *lw_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len = 0;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *w_output = NULL;
ret = wait_request_to_rest(lw_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceWait, body, len, &w_output);
if (ret != 0) {
lw_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
lw_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(w_output, unpack_wait_response, (void *)lw_response);
if (ret != 0) {
goto out;
}
out:
if (w_output != NULL) {
buffer_free(w_output);
}
put_body(body);
return ret;
}
/* stop request to rest */
static int stop_request_to_rest(const struct lcrc_stop_request *ls_request, char **body, size_t *body_len)
{
container_stop_request *crequest = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
crequest = util_common_calloc_s(sizeof(container_stop_request));
if (crequest == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
if (ls_request->name != NULL) {
crequest->id = util_strdup_s(ls_request->name);
}
crequest->force = ls_request->force;
crequest->timeout = ls_request->timeout;
*body = container_stop_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate stop request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_stop_request(crequest);
return ret;
}
/* unpack stop response */
static int unpack_stop_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_stop_response *stop_response = arg;
container_stop_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_stop_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid stop response:%s", err);
ret = -1;
goto out;
}
stop_response->server_errono = cresponse->cc;
if (cresponse->errmsg != NULL) {
stop_response->errmsg = util_strdup_s(cresponse->errmsg);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free(err);
free_container_stop_response(cresponse);
return ret;
}
/* rest container stop */
static int rest_container_stop(const struct lcrc_stop_request *ls_request,
struct lcrc_stop_response *ls_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len = 0;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *output = NULL;
ret = stop_request_to_rest(ls_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceStop, body, len, &output);
if (ret != 0) {
ls_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
ls_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(output, unpack_stop_response, (void *)ls_response);
if (ret != 0) {
goto out;
}
out:
if (output != NULL) {
buffer_free(output);
}
put_body(body);
return ret;
}
/* restart request to rest */
static int restart_request_to_rest(const struct lcrc_restart_request *lr_request, char **body, size_t *body_len)
{
container_restart_request *creq = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
creq = util_common_calloc_s(sizeof(container_restart_request));
if (creq == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
if (lr_request->name != NULL) {
creq->id = util_strdup_s(lr_request->name);
}
creq->timeout = (int32_t)lr_request->timeout;
*body = container_restart_request_generate_json(creq, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate restart request json: %s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_restart_request(creq);
return ret;
}
/* unpack restart response */
static int unpack_restart_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_restart_response *response = arg;
container_restart_response *cres = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cres = container_restart_response_parse_data(message->body, NULL, &err);
if (cres == NULL) {
ERROR("Invalid restart response: %s", err);
ret = -1;
goto out;
}
response->server_errono = cres->cc;
if (cres->errmsg != NULL) {
response->errmsg = util_strdup_s(cres->errmsg);
}
ret = (cres->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free(err);
free_container_restart_response(cres);
return ret;
}
/* rest container restart */
static int rest_container_restart(const struct lcrc_restart_request *lr_request,
struct lcrc_restart_response *lr_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len = 0;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *output = NULL;
ret = restart_request_to_rest(lr_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceRestart, body, len, &output);
if (ret != 0) {
lr_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
lr_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(output, unpack_restart_response, (void *)lr_response);
out:
if (output != NULL) {
buffer_free(output);
}
put_body(body);
return ret;
}
/* update request to rest */
static int update_request_to_rest(const struct lcrc_update_request *lu_request, char **body, size_t *body_len)
{
container_update_request *crequest = NULL;
lcrc_host_config_t srcconfig;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
char *srcconfigjson = NULL;
int ret = 0;
(void)memset(&srcconfig, 0, sizeof(srcconfig));
crequest = util_common_calloc_s(sizeof(container_update_request));
if (crequest == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
if (lu_request->updateconfig != NULL) {
srcconfig.restart_policy = lu_request->updateconfig->restart_policy;
srcconfig.cr = lu_request->updateconfig->cr;
}
ret = generate_hostconfig(&srcconfig, &srcconfigjson);
if (ret != 0) {
ERROR("Failed to generate hostconfig json");
ret = -1;
goto out;
}
crequest->host_config = srcconfigjson;
if (lu_request->name != NULL) {
crequest->name = util_strdup_s(lu_request->name);
}
*body = container_update_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate update request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_update_request(crequest);
return ret;
}
/* unpack update response */
static int unpack_update_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_update_response *update_response = arg;
container_update_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_update_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid update response:%s", err);
ret = -1;
goto out;
}
update_response->server_errono = cresponse->cc;
if (cresponse->errmsg != NULL) {
update_response->errmsg = util_strdup_s(cresponse->errmsg);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free(err);
free_container_update_response(cresponse);
return ret;
}
/* rest container update */
static int rest_container_update(const struct lcrc_update_request *lu_request,
struct lcrc_update_response *lu_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len = 0;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *output = NULL;
ret = update_request_to_rest(lu_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceUpdate, body, len, &output);
if (ret != 0) {
lu_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
lu_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(output, unpack_update_response, (void *)lu_response);
if (ret != 0) {
goto out;
}
out:
if (output != NULL) {
buffer_free(output);
}
put_body(body);
return ret;
}
/* version request to rest */
static int version_request_to_rest(const struct lcrc_version_request *lv_request, char **body, size_t *body_len)
{
container_version_request *crequest = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
crequest = util_common_calloc_s(sizeof(container_version_request));
if (crequest == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
*body = container_version_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate version request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_version_request(crequest);
return ret;
}
/* unpack version response */
static int unpack_version_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_version_response *version_response = arg;
container_version_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_version_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid version response:%s", err);
ret = -1;
goto out;
}
version_response->server_errono = cresponse->cc;
if (cresponse->version != NULL) {
version_response->version = util_strdup_s(cresponse->version);
}
if (cresponse->git_commit != NULL) {
version_response->git_commit = util_strdup_s(cresponse->git_commit);
}
if (cresponse->build_time != NULL) {
version_response->build_time = util_strdup_s(cresponse->build_time);
}
if (cresponse->root_path != NULL) {
version_response->root_path = util_strdup_s(cresponse->root_path);
}
if (cresponse->errmsg != NULL) {
version_response->errmsg = util_strdup_s(cresponse->errmsg);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free(err);
free_container_version_response(cresponse);
return ret;
}
/* rest container version */
static int rest_container_version(const struct lcrc_version_request *lv_request,
struct lcrc_version_response *lv_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len = 0;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *output = NULL;
ret = version_request_to_rest(lv_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceVersion, body, len, &output);
if (ret != 0) {
lv_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
lv_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(output, unpack_version_response, (void *)lv_response);
if (ret != 0) {
goto out;
}
out:
if (output != NULL) {
buffer_free(output);
}
put_body(body);
return ret;
}
/* pause request to rest */
static int pause_request_to_rest(const struct lcrc_pause_request *lp_request, char **body, size_t *body_len)
{
container_pause_request *crequest = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
crequest = util_common_calloc_s(sizeof(container_pause_request));
if (crequest == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
if (lp_request->name != NULL) {
crequest->id = util_strdup_s(lp_request->name);
}
*body = container_pause_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate pause request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_pause_request(crequest);
return ret;
}
/* unpack pause response */
static int unpack_pause_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_pause_response *pause_response = arg;
container_pause_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_pause_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid pause response:%s", err);
ret = -1;
goto out;
}
pause_response->server_errono = cresponse->cc;
if (cresponse->errmsg != NULL) {
pause_response->errmsg = util_strdup_s(cresponse->errmsg);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free(err);
free_container_pause_response(cresponse);
return ret;
}
/* rest container pause */
static int rest_container_pause(const struct lcrc_pause_request *lp_request,
struct lcrc_pause_response *lp_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len = 0;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *output = NULL;
ret = pause_request_to_rest(lp_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServicePause, body, len, &output);
if (ret != 0) {
lp_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
lp_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(output, unpack_pause_response, (void *)lp_response);
if (ret != 0) {
goto out;
}
out:
if (output != NULL) {
buffer_free(output);
}
put_body(body);
return ret;
}
/* kill request to rest */
static int kill_request_to_rest(const struct lcrc_kill_request *lk_request, char **body, size_t *body_len)
{
container_kill_request *crequest = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
crequest = util_common_calloc_s(sizeof(container_kill_request));
if (crequest == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
if (lk_request->name != NULL) {
crequest->id = util_strdup_s(lk_request->name);
}
crequest->signal = lk_request->signal;
*body = container_kill_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate kill request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_kill_request(crequest);
return ret;
}
/* unpack kill response */
static int unpack_kill_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_kill_response *kill_response = arg;
container_kill_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_kill_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid kill response:%s", err);
ret = -1;
goto out;
}
kill_response->server_errono = cresponse->cc;
if (cresponse->errmsg != NULL) {
kill_response->errmsg = util_strdup_s(cresponse->errmsg);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free(err);
free_container_kill_response(cresponse);
return ret;
}
/* rest container kill */
static int rest_container_kill(const struct lcrc_kill_request *lk_request,
struct lcrc_kill_response *lk_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len = 0;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *output = NULL;
ret = kill_request_to_rest(lk_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceKill, body, len, &output);
if (ret != 0) {
lk_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
lk_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(output, unpack_kill_response, (void *)lk_response);
if (ret != 0) {
goto out;
}
out:
if (output != NULL) {
buffer_free(output);
}
put_body(body);
return ret;
}
/* remove request to rest */
static int remove_request_to_rest(const struct lcrc_delete_request *ld_request, char **body, size_t *body_len)
{
container_delete_request *crequest = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
crequest = util_common_calloc_s(sizeof(container_delete_request));
if (crequest == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
if (ld_request->name != NULL) {
crequest->id = util_strdup_s(ld_request->name);
}
crequest->force = ld_request->force;
*body = container_delete_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate remove request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_delete_request(crequest);
return ret;
}
/* unpack remove response */
static int unpack_remove_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_delete_response *delete_response = arg;
container_delete_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_delete_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid remove response:%s", err);
ret = -1;
goto out;
}
delete_response->server_errono = cresponse->cc;
if (cresponse->errmsg != NULL) {
delete_response->errmsg = util_strdup_s(cresponse->errmsg);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free(err);
free_container_delete_response(cresponse);
return ret;
}
/* rest container remove */
static int rest_container_remove(const struct lcrc_delete_request *ld_request,
struct lcrc_delete_response *ld_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *r_output = NULL;
ret = remove_request_to_rest(ld_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceRemove, body, len, &r_output);
if (ret != 0) {
ld_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
ld_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(r_output, unpack_remove_response, (void *)ld_response);
if (ret != 0) {
goto out;
}
out:
if (r_output != NULL) {
buffer_free(r_output);
}
put_body(body);
return ret;
}
/* inspect request to rest */
static int inspect_request_to_rest(const struct lcrc_inspect_request *li_request, char **body, size_t *body_len)
{
container_inspect_request *crequest = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
crequest = util_common_calloc_s(sizeof(container_inspect_request));
if (crequest == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
if (li_request->name != NULL) {
crequest->id = util_strdup_s(li_request->name);
}
crequest->bformat = li_request->bformat;
crequest->timeout = li_request->timeout;
*body = container_inspect_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate inspect request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_inspect_request(crequest);
return ret;
}
/* unpack inspect response */
static int unpack_inspect_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_inspect_response *response = arg;
container_inspect_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_inspect_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid inspect response:%s", err);
ret = -1;
goto out;
}
response->server_errono = cresponse->cc;
if (cresponse->container_json != NULL) {
response->json = util_strdup_s(cresponse->container_json);
}
if (cresponse->errmsg != NULL) {
response->errmsg = util_strdup_s(cresponse->errmsg);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free(err);
free_container_inspect_response(cresponse);
return ret;
}
/* rest container inspect */
static int rest_container_inspect(const struct lcrc_inspect_request *li_request,
struct lcrc_inspect_response *li_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *output = NULL;
ret = inspect_request_to_rest(li_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceInspect, body, len, &output);
if (ret != 0) {
li_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
li_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(output, unpack_inspect_response, (void *)li_response);
if (ret != 0) {
goto out;
}
out:
if (output != NULL) {
buffer_free(output);
}
put_body(body);
return ret;
}
/* exec request to rest */
static int exec_request_to_rest(const struct lcrc_exec_request *le_request, char **body, size_t *body_len)
{
container_exec_request *crequest = NULL;
struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 };
parser_error err = NULL;
int ret = 0;
crequest = util_common_calloc_s(sizeof(container_exec_request));
if (crequest == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
crequest->tty = le_request->tty;
crequest->attach_stdin = le_request->attach_stdin;
crequest->attach_stdout = le_request->attach_stdout;
crequest->attach_stderr = le_request->attach_stderr;
if (le_request->name != NULL) {
crequest->container_id = util_strdup_s(le_request->name);
}
if (le_request->stdout != NULL) {
crequest->stdout = util_strdup_s(le_request->stdout);
}
if (le_request->stdin != NULL) {
crequest->stdin = util_strdup_s(le_request->stdin);
}
if (le_request->stderr != NULL) {
crequest->stderr = util_strdup_s(le_request->stderr);
}
int i = 0;
if (le_request->argc > 0) {
if ((size_t)le_request->argc > SIZE_MAX / sizeof(char *)) {
ERROR("Too many arguments!");
ret = -1;
goto out;
}
crequest->argv = (char **)util_common_calloc_s(sizeof(char *) * (size_t)le_request->argc);
if (crequest->argv == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
for (i = 0; i < le_request->argc; i++) {
crequest->argv[i] = util_strdup_s(le_request->argv[i]);
}
crequest->argv_len = (size_t)le_request->argc;
}
if (le_request->env_len > 0) {
if ((size_t)le_request->env_len > SIZE_MAX / sizeof(char *)) {
ERROR("Too many environmental variables!");
ret = -1;
goto out;
}
crequest->env = (char **)util_common_calloc_s(sizeof(char *) * (size_t)le_request->env_len);
if (crequest->env == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
for (i = 0; i < le_request->env_len; i++) {
crequest->env[i] = util_strdup_s(le_request->env[i]);
}
crequest->env_len = (size_t)le_request->env_len;
}
*body = container_exec_request_generate_json(crequest, &ctx, &err);
if (*body == NULL) {
ERROR("Failed to generate exec request json:%s", err);
ret = -1;
goto out;
}
*body_len = strlen(*body) + 1;
out:
free(err);
free_container_exec_request(crequest);
return ret;
}
/* unpack exec response */
static int unpack_exec_response(const struct parsed_http_message *message, void *arg)
{
struct lcrc_exec_response *response = arg;
container_exec_response *cresponse = NULL;
parser_error err = NULL;
int ret = 0;
ret = check_status_code(message->status_code);
if (ret != 0) {
goto out;
}
cresponse = container_exec_response_parse_data(message->body, NULL, &err);
if (cresponse == NULL) {
ERROR("Invalid exec response:%s", err);
ret = -1;
goto out;
}
response->server_errono = cresponse->cc;
response->exit_code = cresponse->exit_code;
if (cresponse->errmsg != NULL) {
response->errmsg = util_strdup_s(cresponse->errmsg);
}
ret = (cresponse->cc == LCRD_SUCCESS) ? 0 : -1;
if (message->status_code == EVHTP_RES_SERVERR) {
ret = -1;
}
out:
free(err);
free_container_exec_response(cresponse);
return ret;
}
/* rest container exec */
static int rest_container_exec(const struct lcrc_exec_request *le_request,
struct lcrc_exec_response *le_response, void *arg)
{
char *body = NULL;
int ret = 0;
size_t len;
client_connect_config_t *connect_config = (client_connect_config_t *)arg;
const char *socketname = (const char *)(connect_config->socket);
Buffer *output = NULL;
ret = exec_request_to_rest(le_request, &body, &len);
if (ret != 0) {
goto out;
}
ret = rest_send_requst(socketname, RestHttpHead ContainerServiceExec, body, len, &output);
if (ret != 0) {
le_response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
le_response->cc = LCRD_ERR_EXEC;
goto out;
}
ret = get_response(output, unpack_exec_response, (void *)le_response);
if (ret != 0) {
goto out;
}
out:
if (output != NULL) {
buffer_free(output);
}
put_body(body);
return ret;
}
/* rest containers client ops init */
int rest_containers_client_ops_init(lcrc_connect_ops *ops)
{
if (ops == NULL) {
return -1;
}
ops->container.create = &rest_container_create;
ops->container.start = &rest_container_start;
ops->container.stop = &rest_container_stop;
ops->container.restart = &rest_container_restart;
ops->container.remove = &rest_container_remove;
ops->container.inspect = &rest_container_inspect;
ops->container.list = &rest_container_list;
ops->container.exec = &rest_container_exec;
ops->container.pause = &rest_container_pause;
ops->container.attach = &rest_container_attach;
ops->container.resume = &rest_container_resume;
ops->container.update = &rest_container_update;
ops->container.kill = &rest_container_kill;
ops->container.version = &rest_container_version;
ops->container.wait = &rest_container_wait;
return 0;
}