1761 lines
42 KiB
C
1761 lines
42 KiB
C
/******************************************************************************
|
|
* Copyright (c) Huawei Technologies Co., Ltd. 2017-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: tanyifeng
|
|
* Create: 2017-11-22
|
|
* Description: provide image functions
|
|
******************************************************************************/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
#include <limits.h>
|
|
#include <sys/utsname.h>
|
|
#include <ctype.h>
|
|
|
|
#include "image.h"
|
|
#include "liblcrd.h"
|
|
#include "log.h"
|
|
#include "utils.h"
|
|
|
|
#include "ext_image.h"
|
|
#include "filters.h"
|
|
|
|
#ifdef ENABLE_OCI_IMAGE
|
|
#include "isula_image.h"
|
|
#include "oci_images_store.h"
|
|
#endif
|
|
|
|
#ifdef ENABLE_EMBEDDED_IMAGE
|
|
#include "embedded_image.h"
|
|
#include "db_all.h"
|
|
|
|
/* embedded */
|
|
static const struct bim_ops g_embedded_ops = {
|
|
.init = embedded_init,
|
|
.clean_resource = NULL,
|
|
.detect = embedded_detect,
|
|
|
|
.prepare_rf = embedded_prepare_rf,
|
|
.mount_rf = embedded_mount_rf,
|
|
.umount_rf = embedded_umount_rf,
|
|
.delete_rf = embedded_delete_rf,
|
|
.export_rf = NULL,
|
|
|
|
.merge_conf = embedded_merge_conf,
|
|
.get_user_conf = embedded_get_user_conf,
|
|
|
|
.list_ims = embedded_list_images,
|
|
.get_image_count = NULL,
|
|
.rm_image = embedded_remove_image,
|
|
.inspect_image = embedded_inspect_image,
|
|
.resolve_image_name = embedded_resolve_image_name,
|
|
.container_fs_usage = embedded_filesystem_usage,
|
|
.get_filesystem_info = NULL,
|
|
.get_storage_status = NULL,
|
|
.image_status = NULL,
|
|
.load_image = embedded_load_image,
|
|
.pull_image = NULL,
|
|
|
|
.login = NULL,
|
|
.logout = NULL,
|
|
|
|
.health_check = NULL,
|
|
};
|
|
#endif
|
|
|
|
/* isula image server */
|
|
#ifdef ENABLE_OCI_IMAGE
|
|
static const struct bim_ops g_isula_ops = {
|
|
.init = isula_init,
|
|
.clean_resource = isula_exit,
|
|
.detect = oci_detect,
|
|
|
|
.prepare_rf = isula_prepare_rf,
|
|
.mount_rf = isula_mount_rf,
|
|
.umount_rf = isula_umount_rf,
|
|
.delete_rf = isula_delete_rf,
|
|
.export_rf = isula_export_rf,
|
|
|
|
.merge_conf = isula_merge_conf_rf,
|
|
.get_user_conf = oci_get_user_conf,
|
|
|
|
.list_ims = oci_list_images,
|
|
.get_image_count = oci_images_store_size,
|
|
.rm_image = isula_rmi,
|
|
.inspect_image = oci_inspect_image,
|
|
.resolve_image_name = oci_resolve_image_name,
|
|
.container_fs_usage = isula_container_filesystem_usage,
|
|
.get_filesystem_info = isula_get_filesystem_info,
|
|
.get_storage_status = isula_get_storage_status,
|
|
.image_status = oci_status_image,
|
|
.load_image = isual_load_image,
|
|
.pull_image = isula_pull_rf,
|
|
.login = isula_login,
|
|
.logout = isula_logout,
|
|
|
|
.health_check = isula_health_check,
|
|
};
|
|
#endif
|
|
|
|
/* external */
|
|
static const struct bim_ops g_ext_ops = {
|
|
.init = ext_init,
|
|
.clean_resource = NULL,
|
|
.detect = ext_detect,
|
|
|
|
.prepare_rf = ext_prepare_rf,
|
|
.mount_rf = ext_mount_rf,
|
|
.umount_rf = ext_umount_rf,
|
|
.delete_rf = ext_delete_rf,
|
|
.export_rf = NULL,
|
|
|
|
.merge_conf = ext_merge_conf,
|
|
.get_user_conf = ext_get_user_conf,
|
|
|
|
.list_ims = ext_list_images,
|
|
.get_image_count = NULL,
|
|
.rm_image = ext_remove_image,
|
|
.inspect_image = ext_inspect_image,
|
|
.resolve_image_name = ext_resolve_image_name,
|
|
.container_fs_usage = ext_filesystem_usage,
|
|
.image_status = NULL,
|
|
.get_filesystem_info = NULL,
|
|
.get_storage_status = NULL,
|
|
.load_image = ext_load_image,
|
|
.pull_image = NULL,
|
|
.login = ext_login,
|
|
.logout = ext_logout,
|
|
|
|
.health_check = NULL,
|
|
};
|
|
|
|
static const struct bim_type g_bims[] = {
|
|
#ifdef ENABLE_OCI_IMAGE
|
|
{
|
|
.image_type = IMAGE_TYPE_OCI,
|
|
.ops = &g_isula_ops,
|
|
},
|
|
#endif
|
|
{ .image_type = IMAGE_TYPE_EXTERNAL, .ops = &g_ext_ops },
|
|
#ifdef ENABLE_EMBEDDED_IMAGE
|
|
{ .image_type = IMAGE_TYPE_EMBEDDED, .ops = &g_embedded_ops },
|
|
#endif
|
|
};
|
|
|
|
static const size_t g_numbims = sizeof(g_bims) / sizeof(struct bim_type);
|
|
|
|
static const struct bim_type *bim_query(const char *image_name)
|
|
{
|
|
size_t i;
|
|
char *temp = NULL;
|
|
|
|
for (i = 0; i < g_numbims; i++) {
|
|
if (g_bims[i].ops->resolve_image_name == NULL) {
|
|
WARN("Unimplements resolve image name in %s", g_bims[i].image_type);
|
|
continue;
|
|
}
|
|
temp = g_bims[i].ops->resolve_image_name(image_name);
|
|
if (temp == NULL) {
|
|
lcrd_append_error_message("Failed to resovle image name%s", image_name);
|
|
return NULL;
|
|
}
|
|
int r = g_bims[i].ops->detect(temp);
|
|
|
|
free(temp);
|
|
temp = NULL;
|
|
|
|
if (r != 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i == g_numbims) {
|
|
return NULL;
|
|
}
|
|
return &g_bims[i];
|
|
}
|
|
|
|
static const struct bim_type *get_bim_by_type(const char *image_type)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; i < g_numbims; i++) {
|
|
if (strcmp(g_bims[i].image_type, image_type) == 0) {
|
|
return &g_bims[i];
|
|
}
|
|
}
|
|
|
|
ERROR("Backing store %s unknown but not caught earlier\n", image_type);
|
|
return NULL;
|
|
}
|
|
|
|
static void bim_put(struct bim *bim)
|
|
{
|
|
if (bim == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(bim->image_name);
|
|
bim->image_name = NULL;
|
|
free(bim->ext_config_image);
|
|
bim->ext_config_image = NULL;
|
|
free(bim->container_id);
|
|
bim->container_id = NULL;
|
|
free(bim);
|
|
}
|
|
|
|
static struct bim *bim_get(const char *image_type, const char *image_name, const char *ext_config_image,
|
|
const char *container_id)
|
|
{
|
|
struct bim *bim = NULL;
|
|
const struct bim_type *q = NULL;
|
|
|
|
if (image_type == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
q = get_bim_by_type(image_type);
|
|
if (q == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
bim = util_common_calloc_s(sizeof(struct bim));
|
|
if (bim == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
bim->ops = q->ops;
|
|
bim->type = q->image_type;
|
|
|
|
if (image_name != NULL) {
|
|
bim->image_name = bim->ops->resolve_image_name(image_name);
|
|
if (bim->image_name == NULL) {
|
|
lcrd_append_error_message("Failed to resovle image name%s", image_name);
|
|
bim_put(bim);
|
|
return NULL;
|
|
}
|
|
}
|
|
if (ext_config_image != NULL) {
|
|
bim->ext_config_image = util_strdup_s(ext_config_image);
|
|
}
|
|
if (container_id != NULL) {
|
|
bim->container_id = util_strdup_s(container_id);
|
|
}
|
|
return bim;
|
|
}
|
|
|
|
int im_resolv_image_name(const char *image_type, const char *image_name, char **resolved_name)
|
|
{
|
|
int ret = -1;
|
|
const struct bim_type *q = NULL;
|
|
|
|
if (image_type == NULL) {
|
|
ERROR("Image type is required");
|
|
goto out;
|
|
}
|
|
q = get_bim_by_type(image_type);
|
|
if (q == NULL) {
|
|
goto out;
|
|
}
|
|
if (q->ops->resolve_image_name == NULL) {
|
|
ERROR("Get resolve image name umimplements");
|
|
goto out;
|
|
}
|
|
|
|
*resolved_name = q->ops->resolve_image_name(image_name);
|
|
if (*resolved_name == NULL) {
|
|
goto out;
|
|
}
|
|
|
|
ret = 0;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
int im_get_storage_status(const char *image_type, im_storage_status_response **response)
|
|
{
|
|
int ret = -1;
|
|
const struct bim_type *q = NULL;
|
|
|
|
if (image_type == NULL) {
|
|
ERROR("Image type is required");
|
|
goto out;
|
|
}
|
|
q = get_bim_by_type(image_type);
|
|
if (q == NULL) {
|
|
goto out;
|
|
}
|
|
if (q->ops->get_storage_status == NULL) {
|
|
ERROR("Get storage status umimplements");
|
|
goto out;
|
|
}
|
|
|
|
ret = q->ops->get_storage_status(response);
|
|
if (ret != 0) {
|
|
ERROR("Get storage status failed");
|
|
free_im_storage_status_response(*response);
|
|
*response = NULL;
|
|
goto out;
|
|
}
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
int im_get_filesystem_info(const char *image_type, im_fs_info_response **response)
|
|
{
|
|
int ret = -1;
|
|
const struct bim_type *q = NULL;
|
|
|
|
if (image_type == NULL) {
|
|
ERROR("Image type is required");
|
|
goto out;
|
|
}
|
|
|
|
q = get_bim_by_type(image_type);
|
|
if (q == NULL) {
|
|
goto out;
|
|
}
|
|
if (q->ops->get_filesystem_info == NULL) {
|
|
ERROR("Get filesystem info umimplements");
|
|
goto out;
|
|
}
|
|
|
|
EVENT("Event: {Object: get image filesystem info, Type: inspecting}");
|
|
ret = q->ops->get_filesystem_info(response);
|
|
if (ret != 0) {
|
|
if (response != NULL && *response != NULL) {
|
|
ERROR("Get filesystem info failed: %s", (*response)->errmsg);
|
|
} else {
|
|
ERROR("Get filesystem info failed");
|
|
}
|
|
goto out;
|
|
}
|
|
EVENT("Event: {Object: get image filesystem info, Type: inspected}");
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
int im_health_check(const char *image_type)
|
|
{
|
|
int ret = -1;
|
|
const struct bim_type *q = NULL;
|
|
|
|
if (image_type == NULL) {
|
|
ERROR("Image type is required");
|
|
goto out;
|
|
}
|
|
|
|
q = get_bim_by_type(image_type);
|
|
if (q == NULL) {
|
|
ERROR("Get bim failed");
|
|
goto out;
|
|
}
|
|
|
|
if (q->ops->health_check == NULL) {
|
|
ERROR("Health check umimplement");
|
|
goto out;
|
|
}
|
|
|
|
ret = q->ops->health_check();
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
int im_get_container_filesystem_usage(const char *image_type, const char *id, imagetool_fs_info **fs_usage)
|
|
{
|
|
int ret = 0;
|
|
imagetool_fs_info *filesystemusage = NULL;
|
|
const struct bim_type *q = NULL;
|
|
im_container_fs_usage_request *request = NULL;
|
|
|
|
if (image_type == NULL || id == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
q = get_bim_by_type(image_type);
|
|
if (q == NULL) {
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
if (q->ops->container_fs_usage == NULL) {
|
|
ERROR("Unimplements filesystem usage in %s", image_type);
|
|
goto out;
|
|
}
|
|
|
|
request = util_common_calloc_s(sizeof(im_container_fs_usage_request));
|
|
if (request == NULL) {
|
|
ERROR("Out of memory");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
if (id != NULL) {
|
|
request->name_id = util_strdup_s(id);
|
|
}
|
|
|
|
EVENT("Event: {Object: container \'%s\' filesystem info, Type: inspecting}", id != NULL ? id : "");
|
|
ret = q->ops->container_fs_usage(request, &filesystemusage);
|
|
if (ret != 0) {
|
|
ERROR("Failed to get filesystem usage for container %s", id);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
*fs_usage = filesystemusage;
|
|
EVENT("Event: {Object: container \'%s\' filesystem info, Type: inspected}", id != NULL ? id : "");
|
|
|
|
out:
|
|
free_im_container_fs_usage_request(request);
|
|
return ret;
|
|
}
|
|
|
|
int im_remove_container_rootfs(const char *image_type, const char *container_id)
|
|
{
|
|
int ret = 0;
|
|
im_delete_request *request = NULL;
|
|
struct bim *bim = NULL;
|
|
|
|
if (container_id == NULL || image_type == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
bim = bim_get(image_type, NULL, NULL, container_id);
|
|
if (bim == NULL) {
|
|
ERROR("Failed to init bim for container %s", container_id);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
if (bim->ops->delete_rf == NULL) {
|
|
ERROR("Unimplements delete in %s", bim->type);
|
|
goto out;
|
|
}
|
|
|
|
request = util_common_calloc_s(sizeof(im_delete_request));
|
|
if (request == NULL) {
|
|
ERROR("Out of memory");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
request->name_id = util_strdup_s(container_id);
|
|
|
|
EVENT("Event: {Object: %s, Type: removeing rootfs}", container_id);
|
|
ret = bim->ops->delete_rf(request);
|
|
if (ret != 0) {
|
|
ERROR("Failed to delete rootfs for container %s", container_id);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
EVENT("Event: {Object: %s, Type: removed rootfs}", container_id);
|
|
|
|
out:
|
|
bim_put(bim);
|
|
free_im_delete_request(request);
|
|
return ret;
|
|
}
|
|
|
|
void free_im_container_fs_usage_request(im_container_fs_usage_request *request)
|
|
{
|
|
if (request == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(request->name_id);
|
|
request->name_id = NULL;
|
|
free(request);
|
|
}
|
|
|
|
void free_im_prepare_request(im_prepare_request *request)
|
|
{
|
|
if (request == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(request->image_name);
|
|
request->image_name = NULL;
|
|
free(request->container_id);
|
|
request->container_id = NULL;
|
|
free(request->ext_config_image);
|
|
request->ext_config_image = NULL;
|
|
|
|
free_json_map_string_string(request->storage_opt);
|
|
request->storage_opt = NULL;
|
|
|
|
free(request);
|
|
}
|
|
|
|
void free_im_mount_request(im_mount_request *request)
|
|
{
|
|
if (request == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(request->name_id);
|
|
request->name_id = NULL;
|
|
free(request);
|
|
}
|
|
|
|
void free_im_delete_request(im_delete_request *request)
|
|
{
|
|
if (request == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(request->name_id);
|
|
request->name_id = NULL;
|
|
free(request);
|
|
}
|
|
|
|
void free_im_umount_request(im_umount_request *request)
|
|
{
|
|
if (request == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(request->name_id);
|
|
request->name_id = NULL;
|
|
free(request);
|
|
}
|
|
|
|
int im_umount_container_rootfs(const char *image_type, const char *image_name, const char *container_id)
|
|
{
|
|
int ret = 0;
|
|
struct bim *bim = NULL;
|
|
im_umount_request *request = NULL;
|
|
|
|
if (container_id == NULL || image_type == NULL || image_name == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
bim = bim_get(image_type, image_name, NULL, container_id);
|
|
if (bim == NULL) {
|
|
ERROR("Failed to init bim for container %s", container_id);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
if (bim->ops->umount_rf == NULL) {
|
|
ERROR("Unimplements umount in %s", bim->type);
|
|
goto out;
|
|
}
|
|
|
|
request = (im_umount_request *)util_common_calloc_s(sizeof(im_umount_request));
|
|
if (request == NULL) {
|
|
ERROR("Out of memory");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
request->force = false;
|
|
request->name_id = bim->container_id;
|
|
bim->container_id = NULL;
|
|
|
|
EVENT("Event: {Object: %s, Type: umounting rootfs}", container_id);
|
|
ret = bim->ops->umount_rf(request);
|
|
if (ret != 0) {
|
|
ERROR("Failed to umount rootfs for container %s", container_id);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
EVENT("Event: {Object: %s, Type: umounted rootfs}", container_id);
|
|
|
|
out:
|
|
bim_put(bim);
|
|
free_im_umount_request(request);
|
|
return ret;
|
|
}
|
|
|
|
int im_mount_container_rootfs(const char *image_type, const char *image_name, const char *container_id)
|
|
{
|
|
int ret = 0;
|
|
struct bim *bim = NULL;
|
|
im_mount_request *request = NULL;
|
|
|
|
if (image_name == NULL || container_id == NULL || image_type == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
bim = bim_get(image_type, image_name, NULL, container_id);
|
|
if (bim == NULL) {
|
|
ERROR("Failed to init bim for container %s", container_id);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
if (bim->ops->mount_rf == NULL) {
|
|
ERROR("Unimplements mount in %s", bim->type);
|
|
goto out;
|
|
}
|
|
|
|
request = util_common_calloc_s(sizeof(im_mount_request));
|
|
if (request == NULL) {
|
|
ERROR("Out of memory");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
request->name_id = util_strdup_s(container_id);
|
|
|
|
EVENT("Event: {Object: %s, Type: mounting rootfs}", container_id);
|
|
ret = bim->ops->mount_rf(request);
|
|
if (ret != 0) {
|
|
ERROR("Failed to mount rootfs for container %s", container_id);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
EVENT("Event: {Object: %s, Type: mounted rootfs}", container_id);
|
|
|
|
out:
|
|
bim_put(bim);
|
|
free_im_mount_request(request);
|
|
return ret;
|
|
}
|
|
|
|
char *im_get_image_type(const char *image, const char *external_rootfs)
|
|
{
|
|
const char *image_name = NULL;
|
|
const struct bim_type *bim_type = NULL;
|
|
|
|
image_name = (external_rootfs != NULL) ? external_rootfs : image;
|
|
if (image_name == NULL) {
|
|
ERROR("Should specify the image name or external rootfs");
|
|
return NULL;
|
|
}
|
|
|
|
bim_type = bim_query(image_name);
|
|
if (bim_type == NULL) {
|
|
ERROR("Failed to query type of image %s", image_name);
|
|
lcrd_set_error_message("No such image:%s", image_name);
|
|
return NULL;
|
|
}
|
|
|
|
return util_strdup_s(bim_type->image_type);
|
|
}
|
|
|
|
bool im_config_image_exist(const char *image_name)
|
|
{
|
|
const struct bim_type *bim_type = NULL;
|
|
|
|
bim_type = bim_query(image_name);
|
|
if (bim_type == NULL) {
|
|
ERROR("Config image %s not exist", image_name);
|
|
lcrd_set_error_message("Image %s not exist", image_name);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int im_merge_image_config(const char *id, const char *image_type, const char *image_name,
|
|
const char *ext_config_image, oci_runtime_spec *oci_spec,
|
|
host_config *host_spec, container_custom_config *custom_spec,
|
|
char **real_rootfs)
|
|
{
|
|
int ret = 0;
|
|
struct bim *bim = NULL;
|
|
im_prepare_request *request = NULL;
|
|
|
|
if (real_rootfs == NULL || oci_spec == NULL || image_type == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
bim = bim_get(image_type, image_name, ext_config_image, id);
|
|
if (bim == NULL) {
|
|
ERROR("Failed to init bim of image %s", image_name);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
if (bim->ops->merge_conf == NULL) {
|
|
ERROR("Unimplements merge config in %s", bim->type);
|
|
goto out;
|
|
}
|
|
|
|
request = util_common_calloc_s(sizeof(im_prepare_request));
|
|
if (request == NULL) {
|
|
ERROR("Out of memory");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
request->container_id = util_strdup_s(id);
|
|
request->image_name = util_strdup_s(image_name);
|
|
request->ext_config_image = util_strdup_s(ext_config_image);
|
|
if (host_spec != NULL) {
|
|
request->storage_opt = host_spec->storage_opt;
|
|
}
|
|
|
|
EVENT("Event: {Object: %s, Type: preparing rootfs with image %s}", id, image_name);
|
|
|
|
ret = bim->ops->merge_conf(oci_spec, host_spec, custom_spec, request, real_rootfs);
|
|
request->storage_opt = NULL;
|
|
if (ret != 0) {
|
|
ERROR("Failed to merge image %s config, config image is %s", image_name, ext_config_image);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
EVENT("Event: {Object: %s, Type: prepared rootfs with image %s}", id, image_name);
|
|
|
|
INFO("Use real rootfs: %s with type: %s", *real_rootfs, image_type);
|
|
|
|
out:
|
|
bim_put(bim);
|
|
free_im_prepare_request(request);
|
|
return ret;
|
|
}
|
|
|
|
int im_get_user_conf(const char *image_type, const char *basefs, host_config *hc, const char *userstr,
|
|
oci_runtime_spec_process_user *puser)
|
|
{
|
|
int ret = 0;
|
|
struct bim *bim = NULL;
|
|
|
|
if (basefs == NULL || hc == NULL || image_type == NULL || puser == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
bim = bim_get(image_type, NULL, NULL, NULL);
|
|
if (bim == NULL) {
|
|
ERROR("Failed to init bim for image type: %s", image_type);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
if (bim->ops->get_user_conf == NULL) {
|
|
ERROR("Unimplements get user config in %s", bim->type);
|
|
goto out;
|
|
}
|
|
|
|
ret = bim->ops->get_user_conf(basefs, hc, userstr, puser);
|
|
if (ret != 0) {
|
|
ERROR("Failed to get user config");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
out:
|
|
bim_put(bim);
|
|
return ret;
|
|
}
|
|
|
|
static int append_images_to_response(im_list_response *response, imagetool_images_list *images_in)
|
|
{
|
|
int ret = 0;
|
|
size_t images_num = 0;
|
|
size_t old_num = 0;
|
|
imagetool_image **tmp = NULL;
|
|
size_t i = 0;
|
|
size_t new_size = 0;
|
|
size_t old_size = 0;
|
|
|
|
if (images_in == NULL || response == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
if (response->images == NULL) {
|
|
response->images = util_common_calloc_s(sizeof(imagetool_images_list));
|
|
if (response->images == NULL) {
|
|
ERROR("Memeory out");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
images_num = images_in->images_len;
|
|
// no images need to append
|
|
if (images_num == 0) {
|
|
goto out;
|
|
}
|
|
if (images_num > SIZE_MAX / sizeof(imagetool_image *) - response->images->images_len) {
|
|
ERROR("Too many images to append!");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
old_num = response->images->images_len;
|
|
|
|
new_size = (old_num + images_num) * sizeof(imagetool_image *);
|
|
old_size = old_num * sizeof(imagetool_image *);
|
|
ret = mem_realloc((void **)(&tmp), new_size, response->images->images, old_size);
|
|
if (ret != 0) {
|
|
ERROR("Failed to realloc memory for append images");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
response->images->images = tmp;
|
|
for (i = 0; i < images_num; i++) {
|
|
response->images->images[old_num + i] = images_in->images[i];
|
|
images_in->images[i] = NULL;
|
|
images_in->images_len--;
|
|
response->images->images_len++;
|
|
}
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
int im_list_images(const im_list_request *ctx, im_list_response **response)
|
|
{
|
|
size_t i;
|
|
imagetool_images_list *images_tmp = NULL;
|
|
|
|
*response = util_common_calloc_s(sizeof(im_list_response));
|
|
if (*response == NULL) {
|
|
ERROR("Out of memory");
|
|
return -1;
|
|
}
|
|
|
|
EVENT("Event: {Object: list images, Type: listing}");
|
|
|
|
for (i = 0; i < g_numbims; i++) {
|
|
if (g_bims[i].ops->list_ims == NULL) {
|
|
DEBUG("bim %s umimplements list images operator", g_bims[i].image_type);
|
|
continue;
|
|
}
|
|
int ret = g_bims[i].ops->list_ims(ctx, &images_tmp);
|
|
if (ret != 0) {
|
|
ERROR("Failed to list all images with type:%s", g_bims[i].image_type);
|
|
continue;
|
|
}
|
|
ret = append_images_to_response(*response, images_tmp);
|
|
if (ret != 0) {
|
|
ERROR("Failed to append images with type:%s", g_bims[i].image_type);
|
|
}
|
|
free_imagetool_images_list(images_tmp);
|
|
images_tmp = NULL;
|
|
}
|
|
|
|
EVENT("Event: {Object: list images, Type: listed}");
|
|
|
|
if (g_lcrd_errmsg != NULL) {
|
|
(*response)->errmsg = util_strdup_s(g_lcrd_errmsg);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void free_im_list_request(im_list_request *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
free(ptr->filter.image.image);
|
|
ptr->filter.image.image = NULL;
|
|
|
|
filters_args_free(ptr->image_filters);
|
|
ptr->image_filters = NULL;
|
|
free(ptr);
|
|
}
|
|
|
|
void free_im_list_response(im_list_response *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
free_imagetool_images_list(ptr->images);
|
|
ptr->images = NULL;
|
|
free(ptr->errmsg);
|
|
ptr->errmsg = NULL;
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
static bool check_im_pull_args(const im_pull_request *req, im_pull_response * const *resp)
|
|
{
|
|
if (req == NULL || resp == NULL) {
|
|
ERROR("Request or response is NULL");
|
|
return false;
|
|
}
|
|
if (req->image == NULL) {
|
|
ERROR("Empty image required");
|
|
lcrd_set_error_message("Empty image required");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int im_pull_image(const im_pull_request *request, im_pull_response **response)
|
|
{
|
|
int ret = -1;
|
|
struct bim *bim = NULL;
|
|
|
|
if (!check_im_pull_args(request, response)) {
|
|
return ret;
|
|
}
|
|
|
|
bim = bim_get(request->type, NULL, NULL, NULL);
|
|
if (bim == NULL) {
|
|
ERROR("Failed to init bim, image type: %s", request->type);
|
|
goto out;
|
|
}
|
|
|
|
if (bim->ops->pull_image == NULL) {
|
|
ERROR("Unimplements pull image in %s", bim->type);
|
|
goto out;
|
|
}
|
|
|
|
EVENT("Event: {Object: %s, Type: Pulling}", request->image);
|
|
ret = bim->ops->pull_image(request, response);
|
|
if (ret != 0) {
|
|
ERROR("Pull image %s failed", request->image);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
EVENT("Event: {Object: %s, Type: Pulled}", request->image);
|
|
|
|
out:
|
|
bim_put(bim);
|
|
return ret;
|
|
}
|
|
|
|
void free_im_pull_request(im_pull_request *req)
|
|
{
|
|
if (req == NULL) {
|
|
return;
|
|
}
|
|
free(req->type);
|
|
req->type = NULL;
|
|
free(req->image);
|
|
req->image = NULL;
|
|
free_sensitive_string(req->username);
|
|
req->username = NULL;
|
|
free_sensitive_string(req->password);
|
|
req->password = NULL;
|
|
free_sensitive_string(req->auth);
|
|
req->auth = NULL;
|
|
free_sensitive_string(req->server_address);
|
|
req->server_address = NULL;
|
|
free_sensitive_string(req->registry_token);
|
|
req->registry_token = NULL;
|
|
free_sensitive_string(req->identity_token);
|
|
req->identity_token = NULL;
|
|
free(req);
|
|
}
|
|
|
|
void free_im_pull_response(im_pull_response *resp)
|
|
{
|
|
if (resp == NULL) {
|
|
return;
|
|
}
|
|
free(resp->image_ref);
|
|
resp->image_ref = NULL;
|
|
free(resp->errmsg);
|
|
resp->errmsg = NULL;
|
|
free(resp);
|
|
}
|
|
|
|
int im_load_image(const im_load_request *request, im_load_response **response)
|
|
{
|
|
int ret = -1;
|
|
struct bim *bim = NULL;
|
|
|
|
if (request == NULL || response == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
return -1;
|
|
}
|
|
|
|
*response = util_common_calloc_s(sizeof(im_load_response));
|
|
if (*response == NULL) {
|
|
ERROR("Out of memory");
|
|
return -1;
|
|
}
|
|
|
|
if (request->file == NULL) {
|
|
ERROR("Load image requires image tarball file path");
|
|
lcrd_set_error_message("Load image requires image tarball file path");
|
|
goto pack_response;
|
|
}
|
|
|
|
if (request->type == NULL) {
|
|
ERROR("Missing image type");
|
|
lcrd_set_error_message("Missing image type");
|
|
goto pack_response;
|
|
}
|
|
|
|
bim = bim_get(request->type, NULL, NULL, NULL);
|
|
if (bim == NULL) {
|
|
ERROR("Failed to init bim, image type:%s", request->type);
|
|
goto pack_response;
|
|
}
|
|
if (bim->ops->load_image == NULL) {
|
|
ERROR("Unimplements load image in %s", bim->type);
|
|
goto pack_response;
|
|
}
|
|
|
|
EVENT("Event: {Object: %s, Type: loading}", request->file);
|
|
|
|
ret = bim->ops->load_image(request);
|
|
if (ret != 0) {
|
|
ERROR("Failed to load image from %s with tag %s and type %s", request->file, request->tag, request->type);
|
|
ret = -1;
|
|
goto pack_response;
|
|
}
|
|
|
|
EVENT("Event: {Object: %s, Type: loaded}", request->file);
|
|
|
|
pack_response:
|
|
if (g_lcrd_errmsg != NULL) {
|
|
(*response)->errmsg = util_strdup_s(g_lcrd_errmsg);
|
|
}
|
|
|
|
bim_put(bim);
|
|
return ret;
|
|
}
|
|
|
|
void free_im_load_request(im_load_request *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(ptr->file);
|
|
ptr->file = NULL;
|
|
|
|
free(ptr->tag);
|
|
ptr->file = NULL;
|
|
|
|
free(ptr->type);
|
|
ptr->type = NULL;
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
void free_im_load_response(im_load_response *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(ptr->errmsg);
|
|
ptr->errmsg = NULL;
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
int im_login(const im_login_request *request, im_login_response **response)
|
|
{
|
|
int ret = -1;
|
|
struct bim *bim = NULL;
|
|
|
|
if (request == NULL || response == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
return -1;
|
|
}
|
|
|
|
*response = util_common_calloc_s(sizeof(im_login_response));
|
|
if (*response == NULL) {
|
|
ERROR("Out of memory");
|
|
return -1;
|
|
}
|
|
|
|
if (request->server == NULL) {
|
|
ERROR("Login requires server address");
|
|
lcrd_set_error_message("Login requires server address");
|
|
goto pack_response;
|
|
}
|
|
|
|
if (request->type == NULL) {
|
|
ERROR("Login requires image type");
|
|
lcrd_set_error_message("Login requires image type");
|
|
goto pack_response;
|
|
}
|
|
|
|
if (request->username == NULL || request->password == NULL) {
|
|
ERROR("Missing username or password");
|
|
lcrd_set_error_message("Missing username or password");
|
|
goto pack_response;
|
|
}
|
|
|
|
bim = bim_get(request->type, NULL, NULL, NULL);
|
|
if (bim == NULL) {
|
|
ERROR("Failed to init bim, image type:%s", request->type);
|
|
goto pack_response;
|
|
}
|
|
|
|
EVENT("Event: {Object: %s, Type: logining}", request->server);
|
|
|
|
ret = bim->ops->login(request);
|
|
if (ret != 0) {
|
|
ERROR("Failed to login %s", request->server);
|
|
ret = -1;
|
|
goto pack_response;
|
|
}
|
|
|
|
EVENT("Event: {Object: %s, Type: logined}", request->server);
|
|
|
|
pack_response:
|
|
if (g_lcrd_errmsg != NULL) {
|
|
(*response)->errmsg = util_strdup_s(g_lcrd_errmsg);
|
|
}
|
|
|
|
bim_put(bim);
|
|
return ret;
|
|
}
|
|
|
|
void free_im_login_request(im_login_request *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
|
|
free_sensitive_string(ptr->username);
|
|
ptr->username = NULL;
|
|
|
|
free_sensitive_string(ptr->password);
|
|
ptr->password = NULL;
|
|
|
|
free(ptr->type);
|
|
ptr->type = NULL;
|
|
|
|
free_sensitive_string(ptr->server);
|
|
ptr->server = NULL;
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
void free_im_login_response(im_login_response *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(ptr->errmsg);
|
|
ptr->errmsg = NULL;
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
int im_logout(const im_logout_request *request, im_logout_response **response)
|
|
{
|
|
int ret = -1;
|
|
struct bim *bim = NULL;
|
|
|
|
if (request == NULL || response == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
return -1;
|
|
}
|
|
|
|
*response = util_common_calloc_s(sizeof(im_logout_response));
|
|
if (*response == NULL) {
|
|
ERROR("Out of memory");
|
|
return -1;
|
|
}
|
|
|
|
if (request->server == NULL) {
|
|
ERROR("Logout requires server address");
|
|
lcrd_set_error_message("Logout requires server address");
|
|
goto pack_response;
|
|
}
|
|
|
|
if (request->type == NULL) {
|
|
ERROR("Logout requires image type");
|
|
lcrd_set_error_message("Logout requires image type");
|
|
goto pack_response;
|
|
}
|
|
|
|
bim = bim_get(request->type, NULL, NULL, NULL);
|
|
if (bim == NULL) {
|
|
ERROR("Failed to init bim, image type:%s", request->type);
|
|
goto pack_response;
|
|
}
|
|
|
|
EVENT("Event: {Object: %s, Type: logouting}", request->server);
|
|
|
|
ret = bim->ops->logout(request);
|
|
if (ret != 0) {
|
|
ERROR("Failed to logout %s", request->server);
|
|
ret = -1;
|
|
goto pack_response;
|
|
}
|
|
|
|
EVENT("Event: {Object: %s, Type: logouted}", request->server);
|
|
|
|
pack_response:
|
|
if (g_lcrd_errmsg != NULL) {
|
|
(*response)->errmsg = util_strdup_s(g_lcrd_errmsg);
|
|
}
|
|
|
|
bim_put(bim);
|
|
return ret;
|
|
}
|
|
|
|
void free_im_logout_request(im_logout_request *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(ptr->type);
|
|
ptr->type = NULL;
|
|
|
|
free(ptr->server);
|
|
ptr->server = NULL;
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
void free_im_logout_response(im_logout_response *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(ptr->errmsg);
|
|
ptr->errmsg = NULL;
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
int im_image_status(im_status_request *request, im_status_response **response)
|
|
{
|
|
int ret = -1;
|
|
char *image_ref = NULL;
|
|
const struct bim_type *bim_type = NULL;
|
|
struct bim *bim = NULL;
|
|
|
|
if (request == NULL || response == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
return -1;
|
|
}
|
|
|
|
*response = (im_status_response *)util_common_calloc_s(sizeof(im_status_response));
|
|
if (*response == NULL) {
|
|
ERROR("Out of memory");
|
|
return -1;
|
|
}
|
|
|
|
if (request->image.image == NULL) {
|
|
ERROR("get image status requires image ref");
|
|
lcrd_set_error_message("get image status requires image ref");
|
|
goto pack_response;
|
|
}
|
|
|
|
image_ref = util_strdup_s(request->image.image);
|
|
|
|
bim_type = bim_query(image_ref);
|
|
if (bim_type == NULL) {
|
|
ERROR("No such image:%s", image_ref);
|
|
lcrd_set_error_message("No such image:%s", image_ref);
|
|
goto pack_response;
|
|
}
|
|
|
|
bim = bim_get(bim_type->image_type, image_ref, NULL, NULL);
|
|
if (bim == NULL) {
|
|
ERROR("Failed to init bim for image %s", image_ref);
|
|
goto pack_response;
|
|
}
|
|
if (bim->ops->image_status == NULL) {
|
|
ERROR("Unimplements image status in %s", bim->type);
|
|
goto pack_response;
|
|
}
|
|
|
|
ret = bim->ops->image_status(request, response);
|
|
if (ret != 0) {
|
|
ERROR("Failed to get status of image %s", image_ref);
|
|
ret = -1;
|
|
}
|
|
|
|
pack_response:
|
|
if (g_lcrd_errmsg != NULL) {
|
|
free((*response)->errmsg);
|
|
(*response)->errmsg = util_strdup_s(g_lcrd_errmsg);
|
|
}
|
|
free(image_ref);
|
|
bim_put(bim);
|
|
return ret;
|
|
}
|
|
|
|
int im_rm_image(const im_remove_request *request, im_remove_response **response)
|
|
{
|
|
int ret = -1;
|
|
char *image_ref = NULL;
|
|
const struct bim_type *bim_type = NULL;
|
|
struct bim *bim = NULL;
|
|
|
|
if (request == NULL || response == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
return -1;
|
|
}
|
|
|
|
*response = util_common_calloc_s(sizeof(im_remove_response));
|
|
if (*response == NULL) {
|
|
ERROR("Out of memory");
|
|
return -1;
|
|
}
|
|
|
|
if (request->image.image == NULL) {
|
|
ERROR("remove image requires image ref");
|
|
lcrd_set_error_message("remove image requires image ref");
|
|
goto pack_response;
|
|
}
|
|
|
|
image_ref = util_strdup_s(request->image.image);
|
|
|
|
EVENT("Event: {Object: %s, Type: image removing}", image_ref);
|
|
|
|
bim_type = bim_query(image_ref);
|
|
if (bim_type == NULL) {
|
|
ERROR("No such image:%s", image_ref);
|
|
lcrd_set_error_message("No such image:%s", image_ref);
|
|
goto pack_response;
|
|
}
|
|
|
|
bim = bim_get(bim_type->image_type, image_ref, NULL, NULL);
|
|
if (bim == NULL) {
|
|
ERROR("Failed to init bim for image %s", image_ref);
|
|
goto pack_response;
|
|
}
|
|
if (bim->ops->rm_image == NULL) {
|
|
ERROR("Unimplements rm image in %s", bim->type);
|
|
goto pack_response;
|
|
}
|
|
|
|
ret = bim->ops->rm_image(request);
|
|
if (ret != 0) {
|
|
ERROR("Failed to remove image %s", image_ref);
|
|
ret = -1;
|
|
goto pack_response;
|
|
}
|
|
|
|
EVENT("Event: {Object: %s, Type: image removed}", image_ref);
|
|
|
|
pack_response:
|
|
if (g_lcrd_errmsg != NULL) {
|
|
(*response)->errmsg = util_strdup_s(g_lcrd_errmsg);
|
|
}
|
|
free(image_ref);
|
|
bim_put(bim);
|
|
return ret;
|
|
}
|
|
|
|
void free_im_remove_request(im_remove_request *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
free(ptr->image.image);
|
|
ptr->image.image = NULL;
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
void free_im_remove_response(im_remove_response *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(ptr->errmsg);
|
|
ptr->errmsg = NULL;
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
static int do_im_inspect_image(struct bim *bim, char **inspected_json)
|
|
{
|
|
int ret = 0;
|
|
im_inspect_request *update_request = NULL;
|
|
|
|
if (bim->ops->inspect_image == NULL) {
|
|
ERROR("Unimplements inspect image in %s", bim->type);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
update_request = util_common_calloc_s(sizeof(im_inspect_request));
|
|
if (update_request == NULL) {
|
|
ERROR("Out of memory");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
update_request->image.image = bim->image_name;
|
|
bim->image_name = NULL;
|
|
|
|
ret = bim->ops->inspect_image(update_request, inspected_json);
|
|
if (ret != 0) {
|
|
ERROR("Failed to inspect image %s", update_request->image.image);
|
|
ret = -1;
|
|
}
|
|
|
|
out:
|
|
free_im_inspect_request(update_request);
|
|
return ret;
|
|
}
|
|
|
|
int im_inspect_image(const im_inspect_request *request, im_inspect_response **response)
|
|
{
|
|
int ret = 0;
|
|
char *image_ref = NULL;
|
|
char *inspected_json = NULL;
|
|
const struct bim_type *bim_type = NULL;
|
|
struct bim *bim = NULL;
|
|
|
|
if (request == NULL || response == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
return -1;
|
|
}
|
|
|
|
*response = util_common_calloc_s(sizeof(im_inspect_response));
|
|
if (*response == NULL) {
|
|
ERROR("Out of memory");
|
|
return -1;
|
|
}
|
|
|
|
if (request->image.image == NULL) {
|
|
ERROR("inspect image requires image ref");
|
|
lcrd_set_error_message("inspect image requires image ref");
|
|
ret = -1;
|
|
goto pack_response;
|
|
}
|
|
|
|
image_ref = util_strdup_s(request->image.image);
|
|
|
|
EVENT("Event: {Object: %s, Type: image inspecting}", image_ref);
|
|
|
|
bim_type = bim_query(image_ref);
|
|
if (bim_type == NULL) {
|
|
ERROR("No such image:%s", image_ref);
|
|
lcrd_set_error_message("No such image:%s", image_ref);
|
|
ret = -1;
|
|
goto pack_response;
|
|
}
|
|
|
|
bim = bim_get(bim_type->image_type, image_ref, NULL, NULL);
|
|
if (bim == NULL) {
|
|
ERROR("Failed to init bim for image %s", image_ref);
|
|
ret = -1;
|
|
goto pack_response;
|
|
}
|
|
|
|
ret = do_im_inspect_image(bim, &inspected_json);
|
|
if (ret != 0) {
|
|
goto pack_response;
|
|
}
|
|
|
|
EVENT("Event: {Object: %s, Type: image inspected}", image_ref);
|
|
|
|
pack_response:
|
|
if (g_lcrd_errmsg != NULL) {
|
|
(*response)->errmsg = util_strdup_s(g_lcrd_errmsg);
|
|
}
|
|
if (inspected_json != NULL) {
|
|
(*response)->im_inspect_json = util_strdup_s(inspected_json);
|
|
}
|
|
free(image_ref);
|
|
free(inspected_json);
|
|
bim_put(bim);
|
|
return ret;
|
|
}
|
|
|
|
void free_im_inspect_request(im_inspect_request *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
free(ptr->image.image);
|
|
ptr->image.image = NULL;
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
void free_im_inspect_response(im_inspect_response *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(ptr->im_inspect_json);
|
|
ptr->im_inspect_json = NULL;
|
|
|
|
free(ptr->errmsg);
|
|
ptr->errmsg = NULL;
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
/*
|
|
* parameters: image type
|
|
* return: error return 0, success return image count
|
|
* */
|
|
size_t im_get_image_count(const im_image_count_request *request)
|
|
{
|
|
size_t ret = 0;
|
|
const struct bim_type *q = NULL;
|
|
|
|
if (request == NULL || request->type == NULL) {
|
|
ERROR("Image type is required");
|
|
goto out;
|
|
}
|
|
q = get_bim_by_type(request->type);
|
|
if (q == NULL) {
|
|
goto out;
|
|
}
|
|
if (q->ops->get_image_count == NULL) {
|
|
ERROR("Get image count umimplements");
|
|
goto out;
|
|
}
|
|
|
|
ret = q->ops->get_image_count();
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
void free_im_image_count_request(im_image_count_request *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
free(ptr->type);
|
|
ptr->type = NULL;
|
|
free(ptr);
|
|
}
|
|
|
|
int im_container_export(const im_export_request *request)
|
|
{
|
|
int ret = 0;
|
|
int nret = 0;
|
|
struct bim *bim = NULL;
|
|
|
|
if (request == NULL) {
|
|
ERROR("Invalid input arguments");
|
|
return -1;
|
|
}
|
|
|
|
if (request->file == NULL) {
|
|
ERROR("Container export requires output file path");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
if (request->name_id == NULL) {
|
|
ERROR("Container export requires container id");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
if (request->type == NULL) {
|
|
ERROR("Missing image type");
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
bim = bim_get(request->type, NULL, NULL, NULL);
|
|
if (bim == NULL) {
|
|
ERROR("Failed to init bim, image type:%s", request->type);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
if (bim->ops->export_rf == NULL) {
|
|
ERROR("Unimplements container export in %s", bim->type);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
EVENT("Event: {Object: %s, Type: exporting}", request->file);
|
|
|
|
nret = bim->ops->export_rf(request);
|
|
if (nret != 0) {
|
|
ERROR("Failed to export container from %s into file %s and type %s",
|
|
request->name_id, request->file, request->type);
|
|
ret = -1;
|
|
goto out;
|
|
}
|
|
|
|
EVENT("Event: {Object: %s, Type: exported}", request->name_id);
|
|
|
|
out:
|
|
bim_put(bim);
|
|
return ret;
|
|
}
|
|
|
|
void free_im_export_request(im_export_request *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
free(ptr->type);
|
|
ptr->type = NULL;
|
|
free(ptr->file);
|
|
ptr->file = NULL;
|
|
free(ptr->name_id);
|
|
ptr->name_id = NULL;
|
|
free(ptr);
|
|
}
|
|
|
|
void free_im_configs(struct im_configs *conf)
|
|
{
|
|
if (conf == NULL) {
|
|
return;
|
|
}
|
|
free(conf->rootpath);
|
|
conf->rootpath = NULL;
|
|
free(conf->server_sock);
|
|
conf->server_sock = NULL;
|
|
free(conf);
|
|
}
|
|
|
|
static int bims_init(const struct im_configs *conf)
|
|
{
|
|
int ret = 0;
|
|
size_t i;
|
|
|
|
for (i = 0; i < g_numbims; i++) {
|
|
ret = g_bims[i].ops->init(conf);
|
|
if (ret != 0) {
|
|
ERROR("Failed to init bim %s", g_bims[i].image_type);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int image_module_init(const char *rootpath)
|
|
{
|
|
struct im_configs *conf;
|
|
int ret = -1;
|
|
|
|
conf = (struct im_configs *)util_common_calloc_s(sizeof(struct im_configs));
|
|
if (conf == NULL) {
|
|
ERROR("Out of memory");
|
|
return ret;
|
|
}
|
|
conf->rootpath = util_strdup_s(rootpath);
|
|
ret = bims_init(conf);
|
|
|
|
free_im_configs(conf);
|
|
return ret;
|
|
}
|
|
|
|
void image_module_exit()
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; i < g_numbims; i++) {
|
|
if (g_bims[i].ops->clean_resource == NULL) {
|
|
continue;
|
|
}
|
|
g_bims[i].ops->clean_resource();
|
|
}
|
|
}
|
|
|
|
int map_to_key_value_string(const json_map_string_string *map, char ***array, size_t *array_len)
|
|
{
|
|
char **strings = NULL;
|
|
size_t strings_len = 0;
|
|
size_t i;
|
|
int ret;
|
|
|
|
if (map == NULL) {
|
|
return 0;
|
|
}
|
|
for (i = 0; i < map->len; i++) {
|
|
char *str = NULL;
|
|
size_t len;
|
|
if (strlen(map->keys[i]) > (SIZE_MAX - strlen(map->values[i])) - 2) {
|
|
ERROR("Invalid keys/values");
|
|
goto cleanup;
|
|
}
|
|
len = strlen(map->keys[i]) + strlen(map->values[i]) + 2;
|
|
str = util_common_calloc_s(len);
|
|
if (str == NULL) {
|
|
ERROR("Out of memory");
|
|
goto cleanup;
|
|
}
|
|
ret = snprintf(str, len, "%s=%s", map->keys[i], map->values[i]);
|
|
if (ret < 0 || (size_t)ret >= len) {
|
|
ERROR("Failed to print string");
|
|
free(str);
|
|
goto cleanup;
|
|
}
|
|
ret = util_array_append(&strings, str);
|
|
free(str);
|
|
if (ret != 0) {
|
|
ERROR("Failed to append array");
|
|
goto cleanup;
|
|
}
|
|
strings_len++;
|
|
}
|
|
*array = strings;
|
|
*array_len = strings_len;
|
|
return 0;
|
|
|
|
cleanup:
|
|
util_free_array(strings);
|
|
return -1;
|
|
}
|
|
|
|
void free_im_status_request(im_status_request *req)
|
|
{
|
|
if (req == NULL) {
|
|
return;
|
|
}
|
|
free(req->image.image);
|
|
req->image.image = NULL;
|
|
|
|
free(req);
|
|
}
|
|
|
|
void free_im_status_response(im_status_response *req)
|
|
{
|
|
if (req == NULL) {
|
|
return;
|
|
}
|
|
free_imagetool_image_status(req->image_info);
|
|
req->image_info = NULL;
|
|
free(req->errmsg);
|
|
req->errmsg = NULL;
|
|
|
|
free(req);
|
|
}
|
|
|
|
void free_im_fs_info_response(im_fs_info_response *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
free_imagetool_fs_info(ptr->fs_info);
|
|
ptr->fs_info = NULL;
|
|
free(ptr->errmsg);
|
|
ptr->errmsg = NULL;
|
|
|
|
free(ptr);
|
|
}
|
|
|
|
void free_im_storage_status_response(im_storage_status_response *ptr)
|
|
{
|
|
if (ptr == NULL) {
|
|
return;
|
|
}
|
|
free(ptr->backing_fs);
|
|
ptr->backing_fs = NULL;
|
|
free(ptr);
|
|
}
|
|
|
|
void im_sync_containers_isuladkit(void)
|
|
{
|
|
DEBUG("Sync containers...");
|
|
#ifdef ENABLE_OCI_IMAGE
|
|
if (isula_sync_containers() != 0) {
|
|
WARN("Sync containers with remote failed!!");
|
|
}
|
|
#endif
|
|
}
|
|
|