From 2edae8a425ae3442ee73469ca3fd2f3bf9422301 Mon Sep 17 00:00:00 2001 From: liuxu Date: Mon, 16 Dec 2024 17:11:04 +0800 Subject: [PATCH 197/198] coco:support confidential containers Signed-off-by: liuxu --- cmake/options.cmake | 11 +++ src/common/constants.h | 6 ++ src/daemon/common/cri/v1/v1_cri_helpers.cc | 71 +++++++++++++--- src/daemon/common/cri/v1/v1_cri_helpers.h | 4 + .../v1/v1_cri_container_manager_service.cc | 5 ++ .../v1/v1_cri_pod_sandbox_manager_service.cc | 14 +++- .../executor/container_cb/execution_create.c | 12 +++ src/daemon/modules/api/image_api.h | 3 + src/daemon/modules/image/CMakeLists.txt | 10 +++ src/daemon/modules/image/image.c | 46 +++++++++++ .../modules/image/remote/CMakeLists.txt | 13 +++ .../modules/image/remote/remote_image.c | 81 +++++++++++++++++++ .../modules/image/remote/remote_image.h | 40 +++++++++ .../sandbox/sandboxer/sandboxer_sandbox.cc | 10 ++- 14 files changed, 308 insertions(+), 18 deletions(-) create mode 100644 src/daemon/modules/image/remote/CMakeLists.txt create mode 100644 src/daemon/modules/image/remote/remote_image.c create mode 100644 src/daemon/modules/image/remote/remote_image.h diff --git a/cmake/options.cmake b/cmake/options.cmake index 018502d7..efbd0a52 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -62,6 +62,17 @@ if (ENABLE_SANDBOXER STREQUAL "ON") endif() endif() +option(ENABLE_REMOTE_IMAGE "Enable remote image" OFF) +if (ENABLE_REMOTE_IMAGE STREQUAL "ON") + if (ENABLE_SANDBOXER) + add_definitions(-DENABLE_REMOTE_IMAGE) + set(ENABLE_REMOTE_IMAGE 1) + message("${Green}-- Enable remote image${ColourReset}") + else() + message("${Yellow}-- Can not enable remote image, remote image need enable sandboxer first ${ColourReset}") + endif() +endif() + option(ENABLE_OOM_MONITOR "Enable oom monitor" ON) if (ENABLE_OOM_MONITOR STREQUAL "ON") add_definitions(-DENABLE_OOM_MONITOR) diff --git a/src/common/constants.h b/src/common/constants.h index 8a6f86d8..7759896f 100644 --- a/src/common/constants.h +++ b/src/common/constants.h @@ -218,6 +218,12 @@ typedef enum { WAIT_CONDITION_STOPPED = 0, WAIT_CONDITION_REMOVED = 1 } wait_con #define CRI_CONTAINER_TYPE_LABEL_KEY "cri.isulad.type" #define CRI_CONTAINER_TYPE_LABEL_SANDBOX "podsandbox" +#ifdef ENABLE_REMOTE_IMAGE +// Note: Currently, remote image is used only in confidentail container, so the image is supposed to be encrypted +#define SANDBOX_IMAGE_TYPE_REMOTE "remote" +#define IMAGE_NAME_COCO "[Encrypted]" +#endif + #ifdef __cplusplus } #endif diff --git a/src/daemon/common/cri/v1/v1_cri_helpers.cc b/src/daemon/common/cri/v1/v1_cri_helpers.cc index d71e3681..48dcfb45 100644 --- a/src/daemon/common/cri/v1/v1_cri_helpers.cc +++ b/src/daemon/common/cri/v1/v1_cri_helpers.cc @@ -325,10 +325,32 @@ void AddSecurityOptsToHostConfig(std::vector &securityOpts, host_co } #ifdef ENABLE_SANDBOXER +static defs_map_string_object_sandboxer_element *GetCRISandboxer( + const std::string &runtime, struct service_arguments *args) +{ + defs_map_string_object_sandboxer_element *criSandboxer = nullptr; + defs_map_string_object_sandboxer *criSandboxerList = nullptr; + + criSandboxerList = args->json_confs->cri_sandboxers; + for (size_t i = 0; i < criSandboxerList->len; i++) { + if (criSandboxerList->keys[i] == nullptr || criSandboxerList->values[i] == nullptr || + criSandboxerList->values[i]->name == nullptr) { + WARN("CRI runtimes key or value is null"); + continue; + } + + if (runtime == std::string(criSandboxerList->keys[i])) { + criSandboxer = criSandboxerList->values[i]; + break; + } + } + return criSandboxer; +} + std::string CRISandboxerConvert(const std::string &runtime) { std::string sandboxer; - defs_map_string_object_sandboxer *criSandboxerList = nullptr; + defs_map_string_object_sandboxer_element *criSandboxer = nullptr; if (runtime.empty()) { return DEFAULT_SANDBOXER_NAME; @@ -346,24 +368,47 @@ std::string CRISandboxerConvert(const std::string &runtime) } sandboxer = DEFAULT_SANDBOXER_NAME; - criSandboxerList = args->json_confs->cri_sandboxers; - for (size_t i = 0; i < criSandboxerList->len; i++) { - if (criSandboxerList->keys[i] == nullptr || criSandboxerList->values[i] == nullptr || - criSandboxerList->values[i]->name == nullptr) { - WARN("CRI runtimes key or value is null"); - continue; - } - - if (runtime == std::string(criSandboxerList->keys[i])) { - sandboxer = std::string(criSandboxerList->values[i]->name); - break; - } + criSandboxer = GetCRISandboxer(runtime, args); + if (criSandboxer != nullptr) { + sandboxer = std::string(criSandboxer->name); } out: (void)isulad_server_conf_unlock(); return sandboxer; } + +#ifdef ENABLE_REMOTE_IMAGE +std::string GetCRISandboxerImageType(const std::string &runtime) +{ + std::string imageType = ""; + defs_map_string_object_sandboxer_element *criSandboxer = nullptr; + + if (runtime.empty()) { + return imageType; + } + + if (isulad_server_conf_rdlock()) { + ERROR("Lock isulad server conf failed"); + return imageType; + } + + struct service_arguments *args = conf_get_server_conf(); + if (args == nullptr || args->json_confs == nullptr || args->json_confs->cri_sandboxers == nullptr) { + ERROR("Cannot get cri sandboxer list"); + goto out; + } + + criSandboxer = GetCRISandboxer(runtime, args); + if (criSandboxer != nullptr && criSandboxer->image_type != nullptr) { + imageType = std::string(criSandboxer->image_type); + } + +out: + (void)isulad_server_conf_unlock(); + return imageType; +} +#endif #else std::string CRISandboxerConvert(const std::string &runtime) { diff --git a/src/daemon/common/cri/v1/v1_cri_helpers.h b/src/daemon/common/cri/v1/v1_cri_helpers.h index 6a848581..4fd15d0b 100644 --- a/src/daemon/common/cri/v1/v1_cri_helpers.h +++ b/src/daemon/common/cri/v1/v1_cri_helpers.h @@ -69,6 +69,10 @@ void AddSecurityOptsToHostConfig(std::vector &securityOpts, host_co std::string CRISandboxerConvert(const std::string &runtime); +#ifdef ENABLE_REMOTE_IMAGE +std::string GetCRISandboxerImageType(const std::string &runtime); +#endif + void ApplySandboxSecurityContextToHostConfig(const runtime::v1::LinuxSandboxSecurityContext &context, host_config *hc, Errors &error); #ifdef ENABLE_CDI diff --git a/src/daemon/entry/cri/v1/v1_cri_container_manager_service.cc b/src/daemon/entry/cri/v1/v1_cri_container_manager_service.cc index fe1cca0c..1cc584fb 100644 --- a/src/daemon/entry/cri/v1/v1_cri_container_manager_service.cc +++ b/src/daemon/entry/cri/v1/v1_cri_container_manager_service.cc @@ -371,6 +371,11 @@ auto ContainerManagerService::GenerateSandboxInfo( } sandbox_info->sandboxer = util_strdup_s(sandbox.GetSandboxer().c_str()); +#ifdef ENABLE_REMOTE_IMAGE + sandbox_info->image_type = util_strdup_s( + CRIHelpersV1::GetCRISandboxerImageType(sandbox.GetSandboxer()).c_str() + ); +#endif sandbox_info->id = util_strdup_s(sandbox.GetId().c_str()); sandbox_info->pid = sandbox.GetPid(); sandbox_info->task_address = util_strdup_s(sandbox.GetTaskAddress().c_str()); diff --git a/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.cc b/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.cc index 8a7779ad..fd87e90b 100644 --- a/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.cc +++ b/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.cc @@ -468,11 +468,17 @@ auto PodSandboxManagerService::RunPodSandbox(const runtime::v1::PodSandboxConfig // But pull image interface is only in CRI image service, and it can't be called in shim controller, // so we pull image in CRI pod service. const std::string &image = m_podSandboxImage; - if (!EnsureSandboxImageExists(image, runtimeInfo.sandboxer, error)) { - ERROR("Failed to pull sandbox image %s: %s", image.c_str(), error.NotEmpty() ? error.GetCMessage() : ""); - error.Errorf("Failed to pull sandbox image %s: %s", image.c_str(), error.NotEmpty() ? error.GetCMessage() : ""); - return response_id; +#ifdef ENABLE_REMOTE_IMAGE + if (CRIHelpersV1::GetCRISandboxerImageType(runtimeInfo.sandboxer) != std::string(SANDBOX_IMAGE_TYPE_REMOTE)) { +#endif + if (!EnsureSandboxImageExists(image, runtimeInfo.sandboxer, error)) { + ERROR("Failed to pull sandbox image %s: %s", image.c_str(), error.NotEmpty() ? error.GetCMessage() : ""); + error.Errorf("Failed to pull sandbox image %s: %s", image.c_str(), error.NotEmpty() ? error.GetCMessage() : ""); + return response_id; + } +#ifdef ENABLE_REMOTE_IMAGE } +#endif // Step 3: Prepare sandbox checkpoint PrepareSandboxCheckpoint(config, jsonCheckpoint, error); diff --git a/src/daemon/executor/container_cb/execution_create.c b/src/daemon/executor/container_cb/execution_create.c index dcbdd1d3..6cd860c2 100644 --- a/src/daemon/executor/container_cb/execution_create.c +++ b/src/daemon/executor/container_cb/execution_create.c @@ -1016,6 +1016,18 @@ static int get_request_container_info(const container_create_request *request, c static int get_request_image_info(const container_create_request *request, char **image_type, char **image_name) { +#ifdef ENABLE_REMOTE_IMAGE + if (is_container_in_sandbox(request->sandbox) && + strcmp(request->sandbox->image_type, IMAGE_TYPE_REMOTE) == 0) { + /* + * Note: Currently, remote image type and coco image type + * are considered to be the same type. + */ + *image_type = util_strdup_s(IMAGE_TYPE_REMOTE); + *image_name = util_strdup_s(IMAGE_NAME_COCO); + return 0; + } +#endif *image_type = im_get_image_type(request->image, request->rootfs); if (*image_type == NULL) { return -1; diff --git a/src/daemon/modules/api/image_api.h b/src/daemon/modules/api/image_api.h index f35cd013..062684c9 100644 --- a/src/daemon/modules/api/image_api.h +++ b/src/daemon/modules/api/image_api.h @@ -41,6 +41,9 @@ extern "C" { #define IMAGE_TYPE_OCI "oci" #define IMAGE_TYPE_EMBEDDED "embedded" #define IMAGE_TYPE_EXTERNAL "external" +#ifdef ENABLE_REMOTE_IMAGE +#define IMAGE_TYPE_REMOTE SANDBOX_IMAGE_TYPE_REMOTE +#endif typedef struct { char *image; diff --git a/src/daemon/modules/image/CMakeLists.txt b/src/daemon/modules/image/CMakeLists.txt index d8b78ce1..6d31a1ea 100644 --- a/src/daemon/modules/image/CMakeLists.txt +++ b/src/daemon/modules/image/CMakeLists.txt @@ -33,6 +33,16 @@ if (ENABLE_EMBEDDED_IMAGE) ) endif() +if (ENABLE_REMOTE_IMAGE) + add_subdirectory(remote) + list(APPEND local_image_srcs + ${REMOTE_SRCS} + ) + list(APPEND local_image_incs + ${REMOTE_INCS} + ) +endif() + set(IMAGE_SRCS ${local_image_srcs} PARENT_SCOPE diff --git a/src/daemon/modules/image/image.c b/src/daemon/modules/image/image.c index 871f5f39..baf2ba9d 100644 --- a/src/daemon/modules/image/image.c +++ b/src/daemon/modules/image/image.c @@ -125,6 +125,10 @@ struct bim_type { #include "oci_image.h" #endif +#ifdef ENABLE_REMOTE_IMAGE +#include "remote_image.h" +#endif + #ifdef ENABLE_EMBEDDED_IMAGE #include "embedded_image.h" #include "db_all.h" @@ -243,6 +247,45 @@ static const struct bim_ops g_ext_ops = { #endif }; +#ifdef ENABLE_REMOTE_IMAGE +/* remote */ +static const struct bim_ops g_remote_ops = { + .init = NULL, + .clean_resource = NULL, + .detect = NULL, + + .prepare_rf = remote_prepare_rf, + .mount_rf = remote_mount_rf, + .umount_rf = remote_umount_rf, + .delete_rf = remote_delete_rf, + .delete_broken_rf = remote_delete_broken_rf, + .export_rf = NULL, + .get_dir_rf = NULL, + + .merge_conf = remote_merge_conf_rf, + .get_user_conf = remote_get_user_conf, + + .list_ims = NULL, + .get_image_count = NULL, + .rm_image = remote_rmi, + .inspect_image = NULL, + .resolve_image_name = remote_resolve_image_name, + .container_fs_usage = remote_container_filesystem_usage, + .get_filesystem_info = remote_get_filesystem_info, + .image_status = NULL, + .load_image = NULL, + .pull_image = NULL, + .login = NULL, + .logout = NULL, + .tag_image = NULL, + .import = NULL, + .image_summary = NULL, +#ifdef ENABLE_IMAGE_SEARCH + .search_image = NULL, +#endif +}; +#endif + static const struct bim_type g_bims[] = { #ifdef ENABLE_OCI_IMAGE { @@ -254,6 +297,9 @@ static const struct bim_type g_bims[] = { #ifdef ENABLE_EMBEDDED_IMAGE { .image_type = IMAGE_TYPE_EMBEDDED, .ops = &g_embedded_ops }, #endif +#ifdef ENABLE_REMOTE_IMAGE + { .image_type = IMAGE_TYPE_REMOTE, .ops = &g_remote_ops }, +#endif }; diff --git a/src/daemon/modules/image/remote/CMakeLists.txt b/src/daemon/modules/image/remote/CMakeLists.txt new file mode 100644 index 00000000..6e7dab6d --- /dev/null +++ b/src/daemon/modules/image/remote/CMakeLists.txt @@ -0,0 +1,13 @@ +# get current directory sources files +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} local_remote_srcs) + +set(REMOTE_SRCS + ${local_remote_srcs} + PARENT_SCOPE + ) + +set(REMOTE_INCS + ${CMAKE_CURRENT_SOURCE_DIR} + PARENT_SCOPE + ) + diff --git a/src/daemon/modules/image/remote/remote_image.c b/src/daemon/modules/image/remote/remote_image.c new file mode 100644 index 00000000..87b7593d --- /dev/null +++ b/src/daemon/modules/image/remote/remote_image.c @@ -0,0 +1,81 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2026. All rights reserved. + * iSulad licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * 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 v2 for more details. + * Author: liuxu + * Create: 2025-02-11 + * Explanation: provide remote image function + ******************************************************************************/ +#include "remote_image.h" + +#include + +#include "utils.h" + + +char *remote_resolve_image_name(const char *name) +{ + return util_strdup_s(IMAGE_NAME_COCO); +} + +int remote_prepare_rf(const im_prepare_request *request, char **real_rootfs) +{ + if (real_rootfs == NULL) { + ERROR("Failed to prepare remote rootfs, rootfs is NULL."); + return -1; + } + // real_rootfs will be changed by runtime when sandbox image type is "remote" + *real_rootfs = util_strdup_s("rootfs"); + return 0; +} + +int remote_rmi(const im_rmi_request *request) +{ + return 0; +} + +int remote_get_filesystem_info(im_fs_info_response **response) +{ + return 0; +} + +int remote_container_filesystem_usage(const im_container_fs_usage_request *request, imagetool_fs_info **fs_usage) +{ + return 0; +} + +int remote_delete_broken_rf(const im_delete_rootfs_request *request) +{ + return 0; +} + +int remote_delete_rf(const im_delete_rootfs_request *request) +{ + return 0; +} + +int remote_umount_rf(const im_umount_request *request) +{ + return 0; +} + +int remote_mount_rf(const im_mount_request *request) +{ + return 0; +} + +int remote_merge_conf_rf(const char *img_name, container_config *container_spec) +{ + return 0; +} + +int remote_get_user_conf(const char *basefs, host_config *hc, const char *userstr, defs_process_user *puser) +{ + return 0; +} diff --git a/src/daemon/modules/image/remote/remote_image.h b/src/daemon/modules/image/remote/remote_image.h new file mode 100644 index 00000000..be952129 --- /dev/null +++ b/src/daemon/modules/image/remote/remote_image.h @@ -0,0 +1,40 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2026. All rights reserved. + * iSulad licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * 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 v2 for more details. + * Author: liuxu + * Create: 2025-02-11 + * Explanation: provide remote image function definition + ******************************************************************************/ +#ifndef DAEMON_MODULES_IMAGE_REMOTE_IMAGE_H +#define DAEMON_MODULES_IMAGE_REMOTE_IMAGE_H + +#include "image_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +char *remote_resolve_image_name(const char *name); +int remote_prepare_rf(const im_prepare_request *request, char **real_rootfs); +int remote_rmi(const im_rmi_request *request); +int remote_get_filesystem_info(im_fs_info_response **response); +int remote_container_filesystem_usage(const im_container_fs_usage_request *request, imagetool_fs_info **fs_usage); +int remote_delete_broken_rf(const im_delete_rootfs_request *request); +int remote_delete_rf(const im_delete_rootfs_request *request); +int remote_umount_rf(const im_umount_request *request); +int remote_mount_rf(const im_mount_request *request); +int remote_merge_conf_rf(const char *img_name, container_config *container_spec); +int remote_get_user_conf(const char *basefs, host_config *hc, const char *userstr, defs_process_user *puser); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/daemon/sandbox/sandboxer/sandboxer_sandbox.cc b/src/daemon/sandbox/sandboxer/sandboxer_sandbox.cc index b2e2fb32..e26b87c8 100644 --- a/src/daemon/sandbox/sandboxer/sandboxer_sandbox.cc +++ b/src/daemon/sandbox/sandboxer/sandboxer_sandbox.cc @@ -31,6 +31,8 @@ #include "cxxutils.h" #include "utils_timestamp.h" #include "utils_array.h" +#include "constants.h" +#include "v1_cri_helpers.h" namespace sandbox { @@ -297,6 +299,12 @@ static defs_process *clone_defs_process(defs_process *process_spec) auto SandboxerSandbox::GenerateCtrlRootfs(sandbox_task *task, const char *baseFs) -> int { +#ifdef ENABLE_REMOTE_IMAGE + // do not mount image to vm for remote or confidential containers + if (CRIHelpersV1::GetCRISandboxerImageType(GetSandboxer()) == std::string(SANDBOX_IMAGE_TYPE_REMOTE)) { + return 0; + } +#endif size_t len = 1; if (nullptr == baseFs) { ERROR("Container %s has no base fs", task->task_id); @@ -573,7 +581,7 @@ auto SandboxerSandbox::PrepareExec(const char *containerId, const char *execId, } process = process_wrapper->move(); if (InitApiSandbox(apiSandbox) != 0) { - ERROR("Failed to init %s api sandbox.", containerId); + ERROR("Failed to update %s api sandbox.", containerId); goto del_out; } if (DoSandboxUpdate(apiSandbox) != 0) { -- 2.34.1