477 lines
14 KiB
C
477 lines
14 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 image restful client functions
|
|
******************************************************************************/
|
|
#include <unistd.h>
|
|
#include "error.h"
|
|
#include <limits.h>
|
|
|
|
#include "log.h"
|
|
#include "lcrc_connect.h"
|
|
#include "image.rest.h"
|
|
#include "rest_common.h"
|
|
#include "rest_images_client.h"
|
|
|
|
/* image load request to rest */
|
|
static int image_load_request_to_rest(const struct lcrc_load_request *request, char **body, size_t *body_len)
|
|
{
|
|
image_load_image_request *crequest = NULL;
|
|
parser_error err = NULL;
|
|
int ret = 0;
|
|
|
|
crequest = util_common_calloc_s(sizeof(image_load_image_request));
|
|
if (crequest == NULL) {
|
|
ERROR("Out of memory");
|
|
return -1;
|
|
}
|
|
|
|
if (request->file != NULL) {
|
|
crequest->file = util_strdup_s(request->file);
|
|
}
|
|
if (request->type != NULL) {
|
|
crequest->type = util_strdup_s(request->type);
|
|
}
|
|
*body = image_load_image_request_generate_json(crequest, NULL, &err);
|
|
if (*body == NULL) {
|
|
ERROR("Failed to generate image load request json:%s", err);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
*body_len = strlen(*body) + 1;
|
|
out:
|
|
free(err);
|
|
free_image_load_image_request(crequest);
|
|
return ret;
|
|
}
|
|
|
|
/* image list request to rest */
|
|
static int image_list_request_to_rest(const struct lcrc_list_images_request *request, char **body, size_t *body_len)
|
|
{
|
|
image_list_images_request *crequest = NULL;
|
|
parser_error err = NULL;
|
|
int ret = 0;
|
|
|
|
crequest = util_common_calloc_s(sizeof(image_list_images_request));
|
|
if (crequest == NULL) {
|
|
ERROR("Out of memory");
|
|
return -1;
|
|
}
|
|
|
|
*body = image_list_images_request_generate_json(crequest, NULL, &err);
|
|
if (*body == NULL) {
|
|
ERROR("Failed to generate image list request json:%s", err);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
*body_len = strlen(*body) + 1;
|
|
out:
|
|
free(err);
|
|
free_image_list_images_request(crequest);
|
|
return ret;
|
|
}
|
|
|
|
/* image delete request to rest */
|
|
static int image_delete_request_to_rest(const struct lcrc_rmi_request *request, char **body, size_t *body_len)
|
|
{
|
|
image_delete_image_request *crequest = NULL;
|
|
parser_error err = NULL;
|
|
int ret = 0;
|
|
|
|
crequest = util_common_calloc_s(sizeof(image_delete_image_request));
|
|
if (crequest == NULL) {
|
|
ERROR("Out of memory");
|
|
return -1;
|
|
}
|
|
|
|
if (request->image_name) {
|
|
crequest->image_name = util_strdup_s(request->image_name);
|
|
}
|
|
crequest->force = request->force;
|
|
|
|
*body = image_delete_image_request_generate_json(crequest, NULL, &err);
|
|
if (*body == NULL) {
|
|
ERROR("Failed to generate image delete request json:%s", err);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
*body_len = strlen(*body) + 1;
|
|
out:
|
|
free(err);
|
|
free_image_delete_image_request(crequest);
|
|
return ret;
|
|
}
|
|
|
|
static int unpack_image_info_to_list_response(image_list_images_response *cresponse,
|
|
struct lcrc_list_images_response *response)
|
|
{
|
|
size_t num = 0;
|
|
struct lcrc_image_info *image_info = NULL;
|
|
|
|
if (cresponse == NULL || response == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
num = cresponse->images_len;
|
|
if (num > 0 && (num < (SIZE_MAX / sizeof(struct lcrc_image_info)))) {
|
|
size_t i;
|
|
image_info = (struct lcrc_image_info *)util_common_calloc_s(sizeof(struct lcrc_image_info) * num);
|
|
if (image_info == NULL) {
|
|
ERROR("out of memory");
|
|
return -1;
|
|
}
|
|
response->images_num = num;
|
|
response->images_list = image_info;
|
|
for (i = 0; i < num; i++) {
|
|
if (cresponse->images[i]->target != NULL) {
|
|
image_info[i].type = cresponse->images[i]->target->media_type ?
|
|
util_strdup_s(cresponse->images[i]->target->media_type) : util_strdup_s("-");
|
|
image_info[i].digest = cresponse->images[i]->target->digest ?
|
|
util_strdup_s(cresponse->images[i]->target->digest) : util_strdup_s("-");
|
|
image_info[i].size = cresponse->images[i]->target->size;
|
|
}
|
|
if (cresponse->images[i]->created_at != NULL) {
|
|
image_info[i].created = cresponse->images[i]->created_at->seconds;
|
|
image_info[i].created_nanos = cresponse->images[i]->created_at->nanos;
|
|
}
|
|
image_info[i].imageref = cresponse->images[i]->name ?
|
|
util_strdup_s(cresponse->images[i]->name) : util_strdup_s("-");
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
/* unpack image list response */
|
|
static int unpack_image_list_response(const struct parsed_http_message *message, void *arg)
|
|
{
|
|
struct lcrc_list_images_response *response = arg;
|
|
image_list_images_response *cresponse = NULL;
|
|
parser_error err = NULL;
|
|
int ret = 0;
|
|
|
|
ret = check_status_code(message->status_code);
|
|
if (ret != 0) {
|
|
goto out;
|
|
}
|
|
|
|
cresponse = image_list_images_response_parse_data(message->body, NULL, &err);
|
|
if (cresponse == NULL) {
|
|
ERROR("Invalid images 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_image_info_to_list_response(cresponse, response)) {
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
out:
|
|
free(err);
|
|
free_image_list_images_response(cresponse);
|
|
return ret;
|
|
}
|
|
|
|
/* unpack image load response */
|
|
static int unpack_image_load_response(const struct parsed_http_message *message, void *arg)
|
|
{
|
|
struct lcrc_load_response *c_load_response = arg;
|
|
image_load_image_response *load_response = NULL;
|
|
parser_error err = NULL;
|
|
int ret = 0;
|
|
|
|
ret = check_status_code(message->status_code);
|
|
if (ret != 0) {
|
|
goto out;
|
|
}
|
|
|
|
load_response = image_load_image_response_parse_data(message->body, NULL, &err);
|
|
if (load_response == NULL) {
|
|
ERROR("Invalid load image response:%s", err);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
c_load_response->server_errono = load_response->cc;
|
|
if (load_response->errmsg != NULL) {
|
|
c_load_response->errmsg = util_strdup_s(load_response->errmsg);
|
|
}
|
|
ret = (load_response->cc == LCRD_SUCCESS) ? 0 : -1;
|
|
if (message->status_code == EVHTP_RES_SERVERR) {
|
|
ret = -1;
|
|
}
|
|
|
|
out:
|
|
free(err);
|
|
free_image_load_image_response(load_response);
|
|
return ret;
|
|
}
|
|
|
|
/* rest image load */
|
|
static int rest_image_load(const struct lcrc_load_request *request, struct lcrc_load_response *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 = image_load_request_to_rest(request, &body, &len);
|
|
if (ret != 0) {
|
|
goto out;
|
|
}
|
|
ret = rest_send_requst(socketname, RestHttpHead ImagesServiceLoad, body, len, &output);
|
|
if (ret != 0) {
|
|
response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
|
|
response->cc = LCRD_ERR_EXEC;
|
|
goto out;
|
|
}
|
|
ret = get_response(output, unpack_image_load_response, (void *)response);
|
|
if (ret != 0) {
|
|
goto out;
|
|
}
|
|
out:
|
|
if (output != NULL) {
|
|
buffer_free(output);
|
|
}
|
|
put_body(body);
|
|
return ret;
|
|
}
|
|
|
|
/* unpack image delete response */
|
|
static int unpack_image_delete_response(const struct parsed_http_message *message, void *arg)
|
|
{
|
|
struct lcrc_rmi_response *c_rmi_response = arg;
|
|
image_delete_image_response *delete_response = NULL;
|
|
parser_error err = NULL;
|
|
int ret = 0;
|
|
|
|
ret = check_status_code(message->status_code);
|
|
if (ret != 0) {
|
|
goto out;
|
|
}
|
|
|
|
delete_response = image_delete_image_response_parse_data(message->body, NULL, &err);
|
|
if (delete_response == NULL) {
|
|
ERROR("Invalid delete image response:%s", err);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
c_rmi_response->server_errono = delete_response->cc;
|
|
if (delete_response->errmsg != NULL) {
|
|
c_rmi_response->errmsg = util_strdup_s(delete_response->errmsg);
|
|
}
|
|
ret = (delete_response->cc == LCRD_SUCCESS) ? 0 : -1;
|
|
if (message->status_code == EVHTP_RES_SERVERR) {
|
|
ret = -1;
|
|
}
|
|
|
|
out:
|
|
free(err);
|
|
free_image_delete_image_response(delete_response);
|
|
return ret;
|
|
}
|
|
|
|
/* rest image list */
|
|
static int rest_image_list(const struct lcrc_list_images_request *request, struct lcrc_list_images_response *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 = image_list_request_to_rest(request, &body, &len);
|
|
if (ret != 0) {
|
|
goto out;
|
|
}
|
|
ret = rest_send_requst(socketname, RestHttpHead ImagesServiceList, body, len, &output);
|
|
if (ret != 0) {
|
|
response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
|
|
response->cc = LCRD_ERR_EXEC;
|
|
goto out;
|
|
}
|
|
ret = get_response(output, unpack_image_list_response, (void *)response);
|
|
if (ret != 0) {
|
|
goto out;
|
|
}
|
|
out:
|
|
if (output != NULL) {
|
|
buffer_free(output);
|
|
}
|
|
put_body(body);
|
|
return ret;
|
|
}
|
|
|
|
/* rest image remove */
|
|
static int rest_image_remove(const struct lcrc_rmi_request *request, struct lcrc_rmi_response *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 = image_delete_request_to_rest(request, &body, &len);
|
|
if (ret != 0) {
|
|
goto out;
|
|
}
|
|
ret = rest_send_requst(socketname, RestHttpHead ImagesServiceDelete, body, len, &output);
|
|
if (ret != 0) {
|
|
response->errmsg = util_strdup_s(errno_to_error_message(LCRD_ERR_CONNECT));
|
|
response->cc = LCRD_ERR_EXEC;
|
|
goto out;
|
|
}
|
|
ret = get_response(output, unpack_image_delete_response, (void *)response);
|
|
if (ret != 0) {
|
|
goto out;
|
|
}
|
|
out:
|
|
if (output != NULL) {
|
|
buffer_free(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)
|
|
{
|
|
image_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(image_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 = image_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_image_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;
|
|
image_inspect_response *cresponse = NULL;
|
|
parser_error err = NULL;
|
|
int ret = 0;
|
|
|
|
ret = check_status_code(message->status_code);
|
|
if (ret != 0) {
|
|
goto out;
|
|
}
|
|
|
|
cresponse = image_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->image_json != NULL) {
|
|
response->json = util_strdup_s(cresponse->image_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_image_inspect_response(cresponse);
|
|
return ret;
|
|
}
|
|
|
|
/* rest image inspect */
|
|
static int rest_image_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 ImagesServiceInspect, 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;
|
|
}
|
|
|
|
/* rest images client ops init */
|
|
int rest_images_client_ops_init(lcrc_connect_ops *ops)
|
|
{
|
|
if (ops == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
ops->image.list = &rest_image_list;
|
|
ops->image.remove = &rest_image_remove;
|
|
ops->image.load = &rest_image_load;
|
|
ops->image.inspect = &rest_image_inspect;
|
|
|
|
return 0;
|
|
}
|
|
|