From cd18a717e414326116ccbd19bc87e29fa9c4ffc6 Mon Sep 17 00:00:00 2001 From: Lu Jingxiao Date: Mon, 30 Dec 2024 22:28:35 +0800 Subject: [PATCH] Sync patches from upstream for refactoring sandbox and bugfixing including: 15dd7690 add layer storage ut test 7a3d70db bugfix for parse_http_header 3144357f bugfix: mem leak 02a8be62 image store:fix code style 4f030e07 registry module code improve 0340a824 fix some bad code 7dfa6916 add image storage unit test 1e9031cc UT: del shim_sandbox and change sandbox ops 16da6634 sandbox: del shim_sandbox and change sandbox ops Signed-off-by: Lu Jingxiao --- ...-shim_sandbox-and-change-sandbox-ops.patch | 1167 +++++++++++++++++ ...-shim_sandbox-and-change-sandbox-ops.patch | 348 +++++ 0169-add-image-storage-unit-test.patch | 135 ++ 0170-fix-some-bad-code.patch | 165 +++ 0171-registry-module-code-improve.patch | 578 ++++++++ 0172-image-store-fix-code-style.patch | 147 +++ 0173-bugfix-mem-leak.patch | 64 + 0174-bugfix-for-parse_http_header.patch | 25 + 0175-add-layer-storage-ut-test.patch | 244 ++++ iSulad.spec | 18 +- 10 files changed, 2889 insertions(+), 2 deletions(-) create mode 100644 0167-sandbox-del-shim_sandbox-and-change-sandbox-ops.patch create mode 100644 0168-UT-del-shim_sandbox-and-change-sandbox-ops.patch create mode 100644 0169-add-image-storage-unit-test.patch create mode 100644 0170-fix-some-bad-code.patch create mode 100644 0171-registry-module-code-improve.patch create mode 100644 0172-image-store-fix-code-style.patch create mode 100644 0173-bugfix-mem-leak.patch create mode 100644 0174-bugfix-for-parse_http_header.patch create mode 100644 0175-add-layer-storage-ut-test.patch diff --git a/0167-sandbox-del-shim_sandbox-and-change-sandbox-ops.patch b/0167-sandbox-del-shim_sandbox-and-change-sandbox-ops.patch new file mode 100644 index 0000000..ec48baa --- /dev/null +++ b/0167-sandbox-del-shim_sandbox-and-change-sandbox-ops.patch @@ -0,0 +1,1167 @@ +From 16da66344854a75ce7a9d7908e0a75732eb147dc Mon Sep 17 00:00:00 2001 +From: liuxu +Date: Wed, 27 Nov 2024 15:11:57 +0800 +Subject: [PATCH 01/11] sandbox: del shim_sandbox and change sandbox ops + +Signed-off-by: liuxu +--- + src/daemon/sandbox/sandbox.cc | 28 ++ + src/daemon/sandbox/sandbox.h | 15 +- + src/daemon/sandbox/sandbox_manager.cc | 9 +- + src/daemon/sandbox/sandbox_ops.cc | 363 +--------------- + .../sandbox/sandboxer/sandboxer_sandbox.cc | 401 ++++++++++++++++++ + .../sandbox/sandboxer/sandboxer_sandbox.h | 33 +- + src/daemon/sandbox/shim/shim_sandbox.cc | 65 --- + src/daemon/sandbox/shim/shim_sandbox.h | 49 --- + 8 files changed, 469 insertions(+), 494 deletions(-) + delete mode 100644 src/daemon/sandbox/shim/shim_sandbox.cc + delete mode 100644 src/daemon/sandbox/shim/shim_sandbox.h + +diff --git a/src/daemon/sandbox/sandbox.cc b/src/daemon/sandbox/sandbox.cc +index 3715e5e0..d105d71a 100644 +--- a/src/daemon/sandbox/sandbox.cc ++++ b/src/daemon/sandbox/sandbox.cc +@@ -1118,4 +1118,32 @@ void Sandbox::FillSandboxMetadata(sandbox_metadata* metadata, Errors &error) + + metadata->sandbox_config_json = util_strdup_s(jsonStr.c_str()); + } ++ ++void Sandbox::LoadSandboxTasks() ++{ ++} ++ ++auto Sandbox::PrepareContainer(const char *containerId, const char *baseFs, ++ const oci_runtime_spec *ociSpec, ++ const char *consoleFifos[]) -> int ++{ ++ return 0; ++} ++ ++auto Sandbox::PrepareExec(const char *containerId, const char *execId, ++ defs_process *processSpec, const char *consoleFifos[]) -> int ++{ ++ return 0; ++} ++ ++auto Sandbox::PurgeContainer(const char *containerId) -> int ++{ ++ return 0; ++} ++ ++auto Sandbox::PurgeExec(const char *containerId, const char *execId) -> int ++{ ++ return 0; ++} ++ + } +\ No newline at end of file +diff --git a/src/daemon/sandbox/sandbox.h b/src/daemon/sandbox/sandbox.h +index 415406ff..58d60ecb 100644 +--- a/src/daemon/sandbox/sandbox.h ++++ b/src/daemon/sandbox/sandbox.h +@@ -141,13 +141,14 @@ public: + void Status(runtime::v1::PodSandboxStatus &status); + + // for sandbox api update +- virtual void LoadSandboxTasks() = 0; +- virtual auto SaveSandboxTasks() -> bool = 0; +- virtual auto AddSandboxTasks(sandbox_task *task) -> bool = 0; +- virtual auto GetAnySandboxTasks() -> std::string = 0; +- virtual void DeleteSandboxTasks(const char *containerId) = 0; +- virtual auto AddSandboxTasksProcess(const char *containerId, sandbox_process *processes) -> bool = 0; +- virtual void DeleteSandboxTasksProcess(const char *containerId, const char *execId) = 0; ++ virtual void LoadSandboxTasks(); ++ virtual auto PrepareContainer(const char *containerId, const char *baseFs, ++ const oci_runtime_spec *ociSpec, ++ const char *consoleFifos[]) -> int; ++ virtual auto PrepareExec(const char *containerId, const char *execId, ++ defs_process *processSpec, const char *consoleFifos[]) -> int; ++ virtual auto PurgeContainer(const char *containerId) -> int; ++ virtual auto PurgeExec(const char *containerId, const char *execId) -> int; + + private: + auto SaveState(Errors &error) -> bool; +diff --git a/src/daemon/sandbox/sandbox_manager.cc b/src/daemon/sandbox/sandbox_manager.cc +index ba003d56..a7908a60 100644 +--- a/src/daemon/sandbox/sandbox_manager.cc ++++ b/src/daemon/sandbox/sandbox_manager.cc +@@ -27,7 +27,6 @@ + #ifdef ENABLE_SANDBOXER + #include "sandboxer_sandbox.h" + #endif +-#include "shim_sandbox.h" + #include "isulad_config.h" + #include "utils_verify.h" + #include "utils_file.h" +@@ -116,12 +115,12 @@ auto SandboxManager::CreateSandbox(const std::string &name, RuntimeInfo &info, s + + #ifdef ENABLE_SANDBOXER + if (info.sandboxer == SHIM_CONTROLLER_NAME) { +- sandbox = std::make_shared(id, m_rootdir, m_statedir, name, info, netMode, netNsPath, sandboxConfig, image); ++ sandbox = std::make_shared(id, m_rootdir, m_statedir, name, info, netMode, netNsPath, sandboxConfig, image); + } else { + sandbox = std::make_shared(id, m_rootdir, m_statedir, name, info, netMode, netNsPath, sandboxConfig, image); + } + #else +- sandbox = std::make_shared(id, m_rootdir, m_statedir, name, info, netMode, netNsPath, sandboxConfig, image); ++ sandbox = std::make_shared(id, m_rootdir, m_statedir, name, info, netMode, netNsPath, sandboxConfig, image); + #endif + if (sandbox == nullptr) { + ERROR("Failed to malloc for sandbox: %s", name.c_str()); +@@ -485,12 +484,12 @@ auto SandboxManager::LoadSandbox(std::string &id) -> std::shared_ptr + + #ifdef ENABLE_SANDBOXER + if (IsShimSandbox(id, m_rootdir)) { +- sandbox = std::make_shared(id, m_rootdir, m_statedir); ++ sandbox = std::make_shared(id, m_rootdir, m_statedir); + } else { + sandbox = std::make_shared(id, m_rootdir, m_statedir); + } + #else +- sandbox = std::make_shared(id, m_rootdir, m_statedir); ++ sandbox = std::make_shared(id, m_rootdir, m_statedir); + #endif + if (sandbox == nullptr) { + ERROR("Failed to malloc for sandboxes: %s", id.c_str()); +diff --git a/src/daemon/sandbox/sandbox_ops.cc b/src/daemon/sandbox/sandbox_ops.cc +index f50a1033..ae881933 100644 +--- a/src/daemon/sandbox/sandbox_ops.cc ++++ b/src/daemon/sandbox/sandbox_ops.cc +@@ -24,12 +24,6 @@ + #include "sandbox.h" + #include "namespace.h" + #include "utils.h" +-#include "utils_timestamp.h" +-#include "utils_array.h" +- +-const std::string SANDBOX_EXTENSIONS_TASKS = "extensions.tasks"; +-const std::string SANDBOX_TASKS_KEY = "tasks"; +-const std::string SANDBOX_TASKS_TYPEURL = "github.com/containerd/containerd/Tasks"; + + static inline bool validate_sandbox_info(const container_sandbox_info *sandbox) + { +@@ -37,99 +31,6 @@ static inline bool validate_sandbox_info(const container_sandbox_info *sandbox) + sandbox->id != NULL); + } + +-static int generate_ctrl_rootfs(sandbox_task *task, +- const container_config_v2_common_config *config) +-{ +- size_t len = 1; +- if (nullptr == config->base_fs) { +- ERROR("Container %s has no base fs", config->id); +- return -1; +- } +- +- // TODO: rootfs's options left to be configured +- task->rootfs = (sandbox_mount **)util_smart_calloc_s(sizeof(sandbox_mount *), len); +- if (task->rootfs == nullptr) { +- ERROR("Out of memory."); +- return -1; +- } +- task->rootfs[0] = (sandbox_mount *)util_common_calloc_s(sizeof(sandbox_mount)); +- if (task->rootfs[0] == nullptr) { +- ERROR("Out of memory."); +- return -1; +- } +- task->rootfs_len = len; +- task->rootfs[0]->type = util_strdup_s(MOUNT_TYPE_BIND); +- task->rootfs[0]->source = util_strdup_s(config->base_fs); +- +- return 0; +-} +- +-static int do_sandbox_update(std::shared_ptr &sandbox, sandbox_sandbox *apiSandbox) +-{ +- Errors err; +- size_t fields_len = 1; +- __isula_auto_string_array_t string_array *fields = nullptr; +- +- fields = util_string_array_new(fields_len); +- if (fields == nullptr) { +- ERROR("Out of memory."); +- return -1; +- } +- if (util_append_string_array(fields, SANDBOX_EXTENSIONS_TASKS.c_str())) { +- ERROR("Out of memory."); +- return -1; +- } +- +- auto controller = sandbox::ControllerManager::GetInstance()->GetController(sandbox->GetSandboxer()); +- if (nullptr == controller) { +- ERROR("Invalid sandboxer name: %s", sandbox->GetSandboxer().c_str()); +- return -1; +- } +- +- if (!controller->Update(apiSandbox, fields, err)) { +- ERROR("Failed to update in container controller update: %s", err.GetCMessage()); +- return -1; +- } +- +- return 0; +-} +- +-static oci_runtime_spec *clone_oci_runtime_spec(const oci_runtime_spec *oci_spec) +-{ +- __isula_auto_free char *json_str = nullptr; +- __isula_auto_free parser_error err = nullptr; +- oci_runtime_spec *ret = nullptr; +- +- json_str = oci_runtime_spec_generate_json(oci_spec, nullptr, &err); +- if (json_str == nullptr) { +- ERROR("Failed to generate spec json: %s", err); +- return nullptr; +- } +- ret = oci_runtime_spec_parse_data(json_str, nullptr, &err); +- if (ret == nullptr) { +- ERROR("Failed to generate spec: %s", err); +- } +- return ret; +-} +- +-static defs_process *clone_defs_process(defs_process *process_spec) +-{ +- __isula_auto_free char *json_str = nullptr; +- __isula_auto_free parser_error err = nullptr; +- defs_process *ret = nullptr; +- +- json_str = defs_process_generate_json(process_spec, nullptr, &err); +- if (json_str == nullptr) { +- ERROR("Failed to generate process spec json: %s", err); +- return nullptr; +- } +- ret = defs_process_parse_data(json_str, nullptr, &err); +- if (ret == nullptr) { +- ERROR("Failed to generate process spec: %s", err); +- } +- return ret; +-} +- + static std::shared_ptr get_prepare_sandbox(const container_config_v2_common_config *config) + { + if (nullptr == config || nullptr == config->id) { +@@ -151,126 +52,11 @@ static std::shared_ptr get_prepare_sandbox(const container_con + return sandbox; + } + +-static sandbox_sandbox_runtime *init_sandbox_runtime(std::shared_ptr sandbox) +-{ +- sandbox_sandbox_runtime *runtime = nullptr; +- +- auto runtime_wrapper = makeUniquePtrCStructWrapper(free_sandbox_sandbox_runtime); +- if (runtime_wrapper == nullptr) { +- ERROR("Out of memory"); +- return nullptr; +- } +- runtime = runtime_wrapper->get(); +- runtime->name = util_strdup_s(sandbox->GetRuntime().c_str()); +- // Just ignore options for now +- +- return runtime_wrapper->move(); +-} +- +-static json_map_string_string *init_sandbox_labels(std::shared_ptr sandbox) +-{ +- json_map_string_string *labels = nullptr; +- +- auto labels_wrapper = makeUniquePtrCStructWrapper(free_json_map_string_string); +- if (labels_wrapper == nullptr) { +- ERROR("Out of memory"); +- return nullptr; +- } +- labels = labels_wrapper->get(); +- if (append_json_map_string_string(labels, "name", sandbox->GetName().c_str()) != 0) { +- ERROR("Out of memory"); +- return nullptr; +- } +- +- return labels_wrapper->move(); +-} +- +-static defs_map_string_object_any *init_sandbox_extensions(std::shared_ptr sandbox) +-{ +- defs_map_string_object_any *extensions = nullptr; +- size_t len = 1; +- std::string task_json; +- +- auto extensions_wrapper = makeUniquePtrCStructWrapper(free_defs_map_string_object_any); +- if (extensions_wrapper == nullptr) { +- ERROR("Out of memory"); +- return nullptr; +- } +- extensions = extensions_wrapper->get(); +- extensions->keys = (char **)util_smart_calloc_s(sizeof(char *), len); +- if (extensions->keys == nullptr) { +- ERROR("Out of memory."); +- return nullptr; +- } +- extensions->len = len; +- extensions->values = (defs_map_string_object_any_element **) +- util_smart_calloc_s(sizeof(defs_map_string_object_any_element *), len); +- if (extensions->values == nullptr) { +- ERROR("Out of memory."); +- return nullptr; +- } +- extensions->values[0] = (defs_map_string_object_any_element *) +- util_common_calloc_s(sizeof(defs_map_string_object_any_element)); +- if (extensions->values[0] == nullptr) { +- ERROR("Out of memory."); +- return nullptr; +- } +- extensions->values[0]->element = (defs_any *)util_common_calloc_s(sizeof(defs_any)); +- if (extensions->values[0]->element == nullptr) { +- ERROR("Out of memory."); +- return nullptr; +- } +- +- extensions->keys[0] = util_strdup_s(SANDBOX_TASKS_KEY.c_str()); +- task_json = sandbox->GetAnySandboxTasks(); +- if (task_json.empty()) { +- ERROR("Failed to get any sandbox tasks"); +- return nullptr; +- } +- DEBUG("Get any sandbox tasks %s", task_json.c_str()); +- extensions->values[0]->element->type_url = util_strdup_s(SANDBOX_TASKS_TYPEURL.c_str()); +- extensions->values[0]->element->value = reinterpret_cast(util_strdup_s(task_json.c_str())); +- extensions->values[0]->element->value_len = strlen(task_json.c_str()); +- +- return extensions_wrapper->move(); +-} +- +-static int init_api_sandbox(std::shared_ptr sandbox, sandbox_sandbox *apiSandbox) +-{ +- apiSandbox->sandbox_id = util_strdup_s(sandbox->GetId().c_str()); +- apiSandbox->runtime = init_sandbox_runtime(sandbox); +- if (apiSandbox->runtime == nullptr) { +- ERROR("Failed to init sandbox runtime"); +- return -1; +- } +- // Just ignore spec +- apiSandbox->labels = init_sandbox_labels(sandbox); +- if (apiSandbox->labels == nullptr) { +- ERROR("Failed to init sandbox runtime"); +- return -1; +- } +- apiSandbox->created_at = sandbox->GetCreatedAt(); +- apiSandbox->updated_at = util_get_now_time_nanos(); +- apiSandbox->extensions = init_sandbox_extensions(sandbox); +- if (apiSandbox->extensions == nullptr) { +- ERROR("Failed to init sandbox runtime"); +- return -1; +- } +- apiSandbox->sandboxer = util_strdup_s(sandbox->GetSandboxer().c_str()); +- +- return 0; +-} + + int sandbox_prepare_container(const container_config_v2_common_config *config, + const oci_runtime_spec *oci_spec, + const char * console_fifos[], bool tty) + { +- sandbox_task *task = nullptr; +- sandbox_sandbox *apiSandbox = nullptr; +- int ret = -1; +- +- INFO("Prepare container for sandbox"); +- + if (nullptr == console_fifos) { + ERROR("Invlaid parameter: console_fifos"); + return -1; +@@ -282,67 +68,13 @@ int sandbox_prepare_container(const container_config_v2_common_config *config, + return -1; + } + +- auto apiSandbox_wrapper = makeUniquePtrCStructWrapper(free_sandbox_sandbox); +- if (apiSandbox_wrapper == nullptr) { +- ERROR("Out of memory"); +- return -1; +- } +- apiSandbox = apiSandbox_wrapper->get(); +- auto task_wrapper = makeUniquePtrCStructWrapper(free_sandbox_task); +- if (task_wrapper == nullptr) { +- ERROR("Out of memory"); +- return -1; +- } +- task = task_wrapper->get(); +- +- task->task_id = util_strdup_s(config->id); +- task->spec = clone_oci_runtime_spec(oci_spec); +- if (task->spec == nullptr) { +- ERROR("Out of memory."); +- return -1; +- } +- if (generate_ctrl_rootfs(task, config) != 0) { +- ERROR("Invalid rootfs"); +- return -1; +- } +- task->stdin = util_strdup_s((nullptr == console_fifos[0]) ? "" : console_fifos[0]); +- task->stdout = util_strdup_s((nullptr == console_fifos[1]) ? "" : console_fifos[1]); +- task->stderr = util_strdup_s((nullptr == console_fifos[2]) ? "" : console_fifos[2]); +- +- if (!sandbox->AddSandboxTasks(task)) { +- ERROR("Failed to add sandbox %s task.", config->id); +- return -1; +- } +- task = task_wrapper->move(); +- ret = init_api_sandbox(sandbox, apiSandbox); +- if (ret != 0) { +- ERROR("Failed to init %s api sandbox.", config->id); +- goto del_out; +- } +- ret = do_sandbox_update(sandbox, apiSandbox); +- +-del_out: +- if (ret != 0) { +- sandbox->DeleteSandboxTasks(config->id); +- } +- if (!sandbox->SaveSandboxTasks()) { +- ERROR("Failed to Save %s sandbox tasks.", config->id); +- ret = -1; +- } +- +- return ret; ++ return sandbox->PrepareContainer(config->id, config->base_fs, oci_spec, console_fifos); + } + + int sandbox_prepare_exec(const container_config_v2_common_config *config, + const char *exec_id, defs_process *process_spec, + const char * console_fifos[], bool tty) + { +- sandbox_process *process = nullptr; +- sandbox_sandbox *apiSandbox = nullptr; +- int ret = -1; +- +- INFO("Prepare exec for container in sandbox"); +- + if (nullptr == console_fifos) { + ERROR("Invlaid parameter: console_fifos"); + return -1; +@@ -354,116 +86,29 @@ int sandbox_prepare_exec(const container_config_v2_common_config *config, + return -1; + } + +- auto apiSandbox_wrapper = makeUniquePtrCStructWrapper(free_sandbox_sandbox); +- if (apiSandbox_wrapper == nullptr) { +- ERROR("Out of memory"); +- return -1; +- } +- apiSandbox = apiSandbox_wrapper->get(); +- auto process_wrapper = makeUniquePtrCStructWrapper(free_sandbox_process); +- if (process_wrapper == nullptr) { +- ERROR("Out of memory"); +- return -1; +- } +- process = process_wrapper->get(); +- +- process->exec_id = util_strdup_s(exec_id); +- process->spec = clone_defs_process(process_spec); +- if (process->spec == nullptr) { +- ERROR("Out of memory."); +- return -1; +- } +- process->stdin = util_strdup_s((nullptr == console_fifos[0]) ? "" : console_fifos[0]); +- process->stdout = util_strdup_s((nullptr == console_fifos[1]) ? "" : console_fifos[1]); +- process->stderr = util_strdup_s((nullptr == console_fifos[2]) ? "" : console_fifos[2]); +- +- if (!sandbox->AddSandboxTasksProcess(config->id, process)) { +- ERROR("Failed to add sandbox %s process.", config->id); +- return -1; +- } +- process = process_wrapper->move(); +- ret = init_api_sandbox(sandbox, apiSandbox); +- if (ret != 0) { +- ERROR("Failed to init %s api sandbox.", config->id); +- goto del_out; +- } +- ret = do_sandbox_update(sandbox, apiSandbox); +- +-del_out: +- if (ret != 0) { +- sandbox->DeleteSandboxTasksProcess(config->id, exec_id); +- } +- if (!sandbox->SaveSandboxTasks()) { +- ERROR("Failed to Save %s sandbox tasks.", config->id); +- ret = -1; +- } +- +- return ret; ++ return sandbox->PrepareExec(config->id, exec_id, process_spec, console_fifos); + } + + int sandbox_purge_container(const container_config_v2_common_config *config) + { +- sandbox_sandbox *apiSandbox = nullptr; +- +- INFO("Purge container for sandbox"); +- + auto sandbox = get_prepare_sandbox(config); + if (sandbox == nullptr) { + ERROR("Sandbox not found"); + return -1; + } + +- auto apiSandbox_wrapper = makeUniquePtrCStructWrapper(free_sandbox_sandbox); +- if (apiSandbox_wrapper == nullptr) { +- ERROR("Out of memory"); +- return -1; +- } +- apiSandbox = apiSandbox_wrapper->get(); +- +- sandbox->DeleteSandboxTasks(config->id); +- if (!sandbox->SaveSandboxTasks()) { +- ERROR("Failed to Save %s sandbox tasks.", config->id); +- return -1; +- } +- +- if (init_api_sandbox(sandbox, apiSandbox) != 0) { +- ERROR("Failed to init %s api sandbox.", config->id); +- return -1; +- } +- return do_sandbox_update(sandbox, apiSandbox); ++ return sandbox->PurgeContainer(config->id); + } + + int sandbox_purge_exec(const container_config_v2_common_config *config, const char *exec_id) + { +- sandbox_sandbox *apiSandbox = nullptr; +- +- INFO("Purge exec for container in sandbox"); +- + auto sandbox = get_prepare_sandbox(config); + if (sandbox == nullptr) { + ERROR("Sandbox not found"); + return -1; + } + +- auto apiSandbox_wrapper = makeUniquePtrCStructWrapper(free_sandbox_sandbox); +- if (apiSandbox_wrapper == nullptr) { +- ERROR("Out of memory"); +- return -1; +- } +- apiSandbox = apiSandbox_wrapper->get(); +- +- sandbox->DeleteSandboxTasksProcess(config->id, exec_id); +- if (!sandbox->SaveSandboxTasks()) { +- ERROR("Failed to Save %s sandbox tasks.", config->id); +- return -1; +- } +- +- if (init_api_sandbox(sandbox, apiSandbox) != 0) { +- ERROR("Failed to init %s api sandbox.", exec_id); +- return -1; +- } +- +- return do_sandbox_update(sandbox, apiSandbox); ++ return sandbox->PurgeExec(config->id, exec_id); + } + + int sandbox_on_sandbox_exit(const char *sandbox_id, int exit_code) +diff --git a/src/daemon/sandbox/sandboxer/sandboxer_sandbox.cc b/src/daemon/sandbox/sandboxer/sandboxer_sandbox.cc +index 726b7b3a..b2e2fb32 100644 +--- a/src/daemon/sandbox/sandboxer/sandboxer_sandbox.cc ++++ b/src/daemon/sandbox/sandboxer/sandboxer_sandbox.cc +@@ -23,13 +23,21 @@ + + #include + #include ++#include ++#include + + #include "utils_file.h" + #include "utils.h" + #include "cxxutils.h" ++#include "utils_timestamp.h" ++#include "utils_array.h" + + namespace sandbox { + ++const std::string SANDBOX_EXTENSIONS_TASKS = "extensions.tasks"; ++const std::string SANDBOX_TASKS_KEY = "tasks"; ++const std::string SANDBOX_TASKS_TYPEURL = "github.com/containerd/containerd/Tasks"; ++ + SandboxerSandbox::SandboxerSandbox(const std::string id, const std::string &rootdir, const std::string &statedir, const std::string name, + const RuntimeInfo info, std::string netMode, std::string netNsPath, const runtime::v1::PodSandboxConfig sandboxConfig, + const std::string image):Sandbox(id, rootdir, statedir, name, info, netMode, +@@ -251,4 +259,397 @@ void SandboxerSandbox::DeleteSandboxTasksProcess(const char *containerId, const + iter->second->DeleteSandboxTasksProcess(execId); + } + ++static oci_runtime_spec *clone_oci_runtime_spec(const oci_runtime_spec *oci_spec) ++{ ++ __isula_auto_free char *json_str = nullptr; ++ __isula_auto_free parser_error err = nullptr; ++ oci_runtime_spec *ret = nullptr; ++ ++ json_str = oci_runtime_spec_generate_json(oci_spec, nullptr, &err); ++ if (json_str == nullptr) { ++ ERROR("Failed to generate spec json: %s", err); ++ return nullptr; ++ } ++ ret = oci_runtime_spec_parse_data(json_str, nullptr, &err); ++ if (ret == nullptr) { ++ ERROR("Failed to generate spec: %s", err); ++ } ++ return ret; ++} ++ ++static defs_process *clone_defs_process(defs_process *process_spec) ++{ ++ __isula_auto_free char *json_str = nullptr; ++ __isula_auto_free parser_error err = nullptr; ++ defs_process *ret = nullptr; ++ ++ json_str = defs_process_generate_json(process_spec, nullptr, &err); ++ if (json_str == nullptr) { ++ ERROR("Failed to generate process spec json: %s", err); ++ return nullptr; ++ } ++ ret = defs_process_parse_data(json_str, nullptr, &err); ++ if (ret == nullptr) { ++ ERROR("Failed to generate process spec: %s", err); ++ } ++ return ret; ++} ++ ++auto SandboxerSandbox::GenerateCtrlRootfs(sandbox_task *task, const char *baseFs) -> int ++{ ++ size_t len = 1; ++ if (nullptr == baseFs) { ++ ERROR("Container %s has no base fs", task->task_id); ++ return -1; ++ } ++ ++ // TODO: rootfs's options left to be configured ++ task->rootfs = (sandbox_mount **)util_smart_calloc_s(sizeof(sandbox_mount *), len); ++ if (task->rootfs == nullptr) { ++ ERROR("Out of memory."); ++ return -1; ++ } ++ task->rootfs[0] = (sandbox_mount *)util_common_calloc_s(sizeof(sandbox_mount)); ++ if (task->rootfs[0] == nullptr) { ++ ERROR("Out of memory."); ++ return -1; ++ } ++ task->rootfs_len = len; ++ task->rootfs[0]->type = util_strdup_s(MOUNT_TYPE_BIND); ++ task->rootfs[0]->source = util_strdup_s(baseFs); ++ ++ return 0; ++} ++ ++auto SandboxerSandbox::InitSandboxRuntime() -> sandbox_sandbox_runtime * ++{ ++ sandbox_sandbox_runtime *runtime = nullptr; ++ ++ auto runtime_wrapper = makeUniquePtrCStructWrapper(free_sandbox_sandbox_runtime); ++ if (runtime_wrapper == nullptr) { ++ ERROR("Out of memory"); ++ return nullptr; ++ } ++ runtime = runtime_wrapper->get(); ++ runtime->name = util_strdup_s(GetRuntime().c_str()); ++ // Just ignore options for now ++ ++ return runtime_wrapper->move(); ++} ++ ++auto SandboxerSandbox::InitSandboxLabels() -> json_map_string_string * ++{ ++ json_map_string_string *labels = nullptr; ++ ++ auto labels_wrapper = makeUniquePtrCStructWrapper(free_json_map_string_string); ++ if (labels_wrapper == nullptr) { ++ ERROR("Out of memory"); ++ return nullptr; ++ } ++ labels = labels_wrapper->get(); ++ if (append_json_map_string_string(labels, "name", GetName().c_str()) != 0) { ++ ERROR("Out of memory"); ++ return nullptr; ++ } ++ ++ return labels_wrapper->move(); ++} ++ ++auto SandboxerSandbox::InitSandboxExtensions() -> defs_map_string_object_any * ++{ ++ defs_map_string_object_any *extensions = nullptr; ++ size_t len = 1; ++ std::string task_json; ++ ++ auto extensions_wrapper = makeUniquePtrCStructWrapper(free_defs_map_string_object_any); ++ if (extensions_wrapper == nullptr) { ++ ERROR("Out of memory"); ++ return nullptr; ++ } ++ extensions = extensions_wrapper->get(); ++ ++ extensions->keys = (char **)util_smart_calloc_s(sizeof(char *), len); ++ if (extensions->keys == nullptr) { ++ ERROR("Out of memory."); ++ return nullptr; ++ } ++ extensions->values = (defs_map_string_object_any_element **) ++ util_smart_calloc_s(sizeof(defs_map_string_object_any_element *), len); ++ if (extensions->values == nullptr) { ++ ERROR("Out of memory."); ++ free(extensions->keys); ++ extensions->keys = nullptr; ++ return nullptr; ++ } ++ extensions->len = len; ++ ++ extensions->values[0] = (defs_map_string_object_any_element *) ++ util_common_calloc_s(sizeof(defs_map_string_object_any_element)); ++ if (extensions->values[0] == nullptr) { ++ ERROR("Out of memory."); ++ return nullptr; ++ } ++ extensions->values[0]->element = (defs_any *)util_common_calloc_s(sizeof(defs_any)); ++ if (extensions->values[0]->element == nullptr) { ++ ERROR("Out of memory."); ++ return nullptr; ++ } ++ ++ extensions->keys[0] = util_strdup_s(SANDBOX_TASKS_KEY.c_str()); ++ task_json = GetAnySandboxTasks(); ++ if (task_json.empty()) { ++ ERROR("Failed to get any sandbox tasks"); ++ return nullptr; ++ } ++ DEBUG("Get any sandbox tasks %s", task_json.c_str()); ++ extensions->values[0]->element->type_url = util_strdup_s(SANDBOX_TASKS_TYPEURL.c_str()); ++ extensions->values[0]->element->value = reinterpret_cast(util_strdup_s(task_json.c_str())); ++ extensions->values[0]->element->value_len = strlen(task_json.c_str()); ++ ++ return extensions_wrapper->move(); ++} ++ ++auto SandboxerSandbox::InitApiSandbox(sandbox_sandbox *apiSandbox) -> int ++{ ++ apiSandbox->sandbox_id = util_strdup_s(GetId().c_str()); ++ apiSandbox->runtime = InitSandboxRuntime(); ++ if (apiSandbox->runtime == nullptr) { ++ ERROR("Failed to init sandbox runtime"); ++ return -1; ++ } ++ // Just ignore spec ++ apiSandbox->labels = InitSandboxLabels(); ++ if (apiSandbox->labels == nullptr) { ++ ERROR("Failed to init sandbox runtime"); ++ return -1; ++ } ++ apiSandbox->created_at = GetCreatedAt(); ++ apiSandbox->updated_at = util_get_now_time_nanos(); ++ apiSandbox->extensions = InitSandboxExtensions(); ++ if (apiSandbox->extensions == nullptr) { ++ ERROR("Failed to init sandbox runtime"); ++ return -1; ++ } ++ apiSandbox->sandboxer = util_strdup_s(GetSandboxer().c_str()); ++ ++ return 0; ++} ++ ++auto SandboxerSandbox::DoSandboxUpdate(sandbox_sandbox *apiSandbox) -> int ++{ ++ Errors err; ++ size_t fields_len = 1; ++ __isula_auto_string_array_t string_array *fields = nullptr; ++ ++ fields = util_string_array_new(fields_len); ++ if (fields == nullptr) { ++ ERROR("Out of memory."); ++ return -1; ++ } ++ if (util_append_string_array(fields, SANDBOX_EXTENSIONS_TASKS.c_str())) { ++ ERROR("Out of memory."); ++ return -1; ++ } ++ ++ auto controller = sandbox::ControllerManager::GetInstance()->GetController(GetSandboxer()); ++ if (nullptr == controller) { ++ ERROR("Invalid sandboxer name: %s", GetSandboxer().c_str()); ++ return -1; ++ } ++ ++ if (!controller->Update(apiSandbox, fields, err)) { ++ ERROR("Failed to update in container controller update: %s", err.GetCMessage()); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++auto SandboxerSandbox::PrepareContainer(const char *containerId, const char *baseFs, ++ const oci_runtime_spec *ociSpec, ++ const char *consoleFifos[]) -> int ++{ ++ sandbox_task *task = nullptr; ++ sandbox_sandbox *apiSandbox = nullptr; ++ ++ INFO("Prepare container for sandbox"); ++ ++ if (nullptr == consoleFifos) { ++ ERROR("Invlaid parameter: consoleFifos"); ++ return -1; ++ } ++ ++ auto apiSandbox_wrapper = makeUniquePtrCStructWrapper(free_sandbox_sandbox); ++ if (apiSandbox_wrapper == nullptr) { ++ ERROR("Out of memory"); ++ return -1; ++ } ++ apiSandbox = apiSandbox_wrapper->get(); ++ auto task_wrapper = makeUniquePtrCStructWrapper(free_sandbox_task); ++ if (task_wrapper == nullptr) { ++ ERROR("Out of memory"); ++ return -1; ++ } ++ task = task_wrapper->get(); ++ ++ task->task_id = util_strdup_s(containerId); ++ task->spec = clone_oci_runtime_spec(ociSpec); ++ if (task->spec == nullptr) { ++ ERROR("Out of memory."); ++ return -1; ++ } ++ if (GenerateCtrlRootfs(task, baseFs) != 0) { ++ ERROR("Invalid rootfs"); ++ return -1; ++ } ++ task->stdin = util_strdup_s((nullptr == consoleFifos[0]) ? "" : consoleFifos[0]); ++ task->stdout = util_strdup_s((nullptr == consoleFifos[1]) ? "" : consoleFifos[1]); ++ task->stderr = util_strdup_s((nullptr == consoleFifos[2]) ? "" : consoleFifos[2]); ++ ++ if (!AddSandboxTasks(task)) { ++ ERROR("Failed to add sandbox %s task.", containerId); ++ return -1; ++ } ++ task = task_wrapper->move(); ++ if (InitApiSandbox(apiSandbox) != 0) { ++ ERROR("Failed to init %s api sandbox.", containerId); ++ goto del_out; ++ } ++ if (DoSandboxUpdate(apiSandbox) != 0) { ++ ERROR("Failed to update %s api sandbox.", containerId); ++ goto del_out; ++ } ++ if (!SaveSandboxTasks()) { ++ ERROR("Failed to Save %s sandbox tasks.", containerId); ++ (void)PurgeContainer(containerId); ++ return -1; ++ } ++ return 0; ++ ++del_out: ++ DeleteSandboxTasks(containerId); ++ return -1; ++} ++ ++auto SandboxerSandbox::PrepareExec(const char *containerId, const char *execId, ++ defs_process *processSpec, const char *consoleFifos[]) -> int ++{ ++ sandbox_process *process = nullptr; ++ sandbox_sandbox *apiSandbox = nullptr; ++ ++ INFO("Prepare exec for container in sandbox"); ++ ++ if (nullptr == consoleFifos) { ++ ERROR("Invlaid parameter: consoleFifos"); ++ return -1; ++ } ++ ++ auto apiSandbox_wrapper = makeUniquePtrCStructWrapper(free_sandbox_sandbox); ++ if (apiSandbox_wrapper == nullptr) { ++ ERROR("Out of memory"); ++ return -1; ++ } ++ apiSandbox = apiSandbox_wrapper->get(); ++ auto process_wrapper = makeUniquePtrCStructWrapper(free_sandbox_process); ++ if (process_wrapper == nullptr) { ++ ERROR("Out of memory"); ++ return -1; ++ } ++ process = process_wrapper->get(); ++ ++ process->exec_id = util_strdup_s(execId); ++ process->spec = clone_defs_process(processSpec); ++ if (process->spec == nullptr) { ++ ERROR("Out of memory."); ++ return -1; ++ } ++ process->stdin = util_strdup_s((nullptr == consoleFifos[0]) ? "" : consoleFifos[0]); ++ process->stdout = util_strdup_s((nullptr == consoleFifos[1]) ? "" : consoleFifos[1]); ++ process->stderr = util_strdup_s((nullptr == consoleFifos[2]) ? "" : consoleFifos[2]); ++ ++ if (!AddSandboxTasksProcess(containerId, process)) { ++ ERROR("Failed to add sandbox %s process.", containerId); ++ return -1; ++ } ++ process = process_wrapper->move(); ++ if (InitApiSandbox(apiSandbox) != 0) { ++ ERROR("Failed to init %s api sandbox.", containerId); ++ goto del_out; ++ } ++ if (DoSandboxUpdate(apiSandbox) != 0) { ++ ERROR("Failed to init %s api sandbox.", containerId); ++ goto del_out; ++ } ++ if (!SaveSandboxTasks()) { ++ ERROR("Failed to Save %s sandbox tasks.", containerId); ++ (void)PurgeExec(containerId, execId); ++ return -1; ++ } ++ return 0; ++ ++del_out: ++ DeleteSandboxTasksProcess(containerId, execId); ++ return -1; ++} ++ ++auto SandboxerSandbox::PurgeContainer(const char *containerId) -> int ++{ ++ sandbox_sandbox *apiSandbox = nullptr; ++ ++ INFO("Purge container for sandbox"); ++ ++ auto apiSandbox_wrapper = makeUniquePtrCStructWrapper(free_sandbox_sandbox); ++ if (apiSandbox_wrapper == nullptr) { ++ ERROR("Out of memory"); ++ return -1; ++ } ++ apiSandbox = apiSandbox_wrapper->get(); ++ ++ DeleteSandboxTasks(containerId); ++ ++ if (InitApiSandbox(apiSandbox) != 0) { ++ ERROR("Failed to init %s api sandbox.", containerId); ++ return -1; ++ } ++ if (DoSandboxUpdate(apiSandbox) != 0) { ++ ERROR("Failed to update %s api sandbox.", containerId); ++ return -1; ++ } ++ if (!SaveSandboxTasks()) { ++ ERROR("Failed to Save %s sandbox tasks.", containerId); ++ return -1; ++ } ++ return 0; ++} ++ ++auto SandboxerSandbox::PurgeExec(const char *containerId, const char *execId) -> int ++{ ++ sandbox_sandbox *apiSandbox = nullptr; ++ ++ INFO("Purge exec for container in sandbox"); ++ ++ auto apiSandbox_wrapper = makeUniquePtrCStructWrapper(free_sandbox_sandbox); ++ if (apiSandbox_wrapper == nullptr) { ++ ERROR("Out of memory"); ++ return -1; ++ } ++ apiSandbox = apiSandbox_wrapper->get(); ++ ++ DeleteSandboxTasksProcess(containerId, execId); ++ ++ if (InitApiSandbox(apiSandbox) != 0) { ++ ERROR("Failed to init %s api sandbox.", execId); ++ return -1; ++ } ++ if (DoSandboxUpdate(apiSandbox) != 0) { ++ ERROR("Failed to update %s api sandbox.", execId); ++ return -1; ++ } ++ if (!SaveSandboxTasks()) { ++ ERROR("Failed to Save %s sandbox tasks.", containerId); ++ return -1; ++ } ++ return 0; ++} ++ + } +\ No newline at end of file +diff --git a/src/daemon/sandbox/sandboxer/sandboxer_sandbox.h b/src/daemon/sandbox/sandboxer/sandboxer_sandbox.h +index 552eb328..37a96cd6 100644 +--- a/src/daemon/sandbox/sandboxer/sandboxer_sandbox.h ++++ b/src/daemon/sandbox/sandboxer/sandboxer_sandbox.h +@@ -33,24 +33,39 @@ public: + const runtime::v1::PodSandboxConfig sandboxConfig = runtime::v1::PodSandboxConfig::default_instance(), + const std::string image = ""); + virtual ~SandboxerSandbox() = default; +- +- // for sandbox api update +- auto GetTasksJsonPath() -> std::string; ++ + void LoadSandboxTasks() override; +- auto SaveSandboxTasks() -> bool override; +- auto AddSandboxTasks(sandbox_task *task) -> bool override; +- auto GetAnySandboxTasks() -> std::string override; +- void DeleteSandboxTasks(const char *containerId) override; +- auto AddSandboxTasksProcess(const char *containerId, sandbox_process *processes) -> bool override; +- void DeleteSandboxTasksProcess(const char *containerId, const char *execId) override; ++ ++ auto PrepareContainer(const char *containerId, const char *baseFs, ++ const oci_runtime_spec *ociSpec, ++ const char *consoleFifos[]) -> int override; ++ auto PrepareExec(const char *containerId, const char *execId, ++ defs_process *processSpec, const char *consoleFifos[]) -> int override; ++ auto PurgeContainer(const char *containerId) -> int override; ++ auto PurgeExec(const char *containerId, const char *execId) -> int override; + + private: ++ auto GetTasksJsonPath() -> std::string; ++ auto SaveSandboxTasks() -> bool; ++ auto AddSandboxTasks(sandbox_task *task) -> bool; ++ auto GetAnySandboxTasks() -> std::string; ++ void DeleteSandboxTasks(const char *containerId); ++ auto AddSandboxTasksProcess(const char *containerId, sandbox_process *processes) -> bool; ++ void DeleteSandboxTasksProcess(const char *containerId, const char *execId); ++ + auto AddTaskById(const char *task_id, sandbox_task *task) -> bool; + auto ReadSandboxTasksJson() -> sandbox_tasks *; + auto WriteSandboxTasksJson(std::string &tasks_json) -> bool; + auto DeleteSandboxTasksJson() -> bool; + void AddSandboxTasksByArray(sandbox_tasks *tasksArray); + ++ auto GenerateCtrlRootfs(sandbox_task *task, const char *baseFs) -> int; ++ auto InitSandboxRuntime() -> sandbox_sandbox_runtime *; ++ auto InitSandboxLabels() -> json_map_string_string *; ++ auto InitSandboxExtensions() -> defs_map_string_object_any *; ++ auto InitApiSandbox(sandbox_sandbox *apiSandbox) -> int; ++ auto DoSandboxUpdate(sandbox_sandbox *apiSandbox) -> int; ++ + private: + // use m_tasksMutex to ensure the correctness of the tasks + RWMutex m_tasksMutex; +diff --git a/src/daemon/sandbox/shim/shim_sandbox.cc b/src/daemon/sandbox/shim/shim_sandbox.cc +deleted file mode 100644 +index 2efb8d7c..00000000 +--- a/src/daemon/sandbox/shim/shim_sandbox.cc ++++ /dev/null +@@ -1,65 +0,0 @@ +-/****************************************************************************** +- * Copyright (c) Huawei Technologies Co., Ltd. 2024. 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: 2024-11-20 +- * Description: provide sandboxer sandbox class definition +- *********************************************************************************/ +-#include "shim_sandbox.h" +- +-#include +-#include +- +-#include +-#include +- +- +-namespace sandbox { +- +-ShimSandbox::ShimSandbox(const std::string id, const std::string &rootdir, const std::string &statedir, const std::string name, +- const RuntimeInfo info, std::string netMode, std::string netNsPath, const runtime::v1::PodSandboxConfig sandboxConfig, +- const std::string image):Sandbox(id, rootdir, statedir, name, info, netMode, +- netNsPath, sandboxConfig, image) +-{ +-} +- +-void ShimSandbox::LoadSandboxTasks() +-{ +-} +- +-auto ShimSandbox::SaveSandboxTasks() -> bool +-{ +- return true; +-} +- +-auto ShimSandbox::AddSandboxTasks(sandbox_task *task) -> bool +-{ +- return true; +-} +- +-auto ShimSandbox::GetAnySandboxTasks() -> std::string +-{ +- return std::string("Nothing for shim."); +-} +- +-void ShimSandbox::DeleteSandboxTasks(const char *containerId) +-{ +-} +- +-auto ShimSandbox::AddSandboxTasksProcess(const char *containerId, sandbox_process *processes) -> bool +-{ +- return true; +-} +- +-void ShimSandbox::DeleteSandboxTasksProcess(const char *containerId, const char *execId) +-{ +-} +- +-} +\ No newline at end of file +diff --git a/src/daemon/sandbox/shim/shim_sandbox.h b/src/daemon/sandbox/shim/shim_sandbox.h +deleted file mode 100644 +index 82da0573..00000000 +--- a/src/daemon/sandbox/shim/shim_sandbox.h ++++ /dev/null +@@ -1,49 +0,0 @@ +-/****************************************************************************** +- * Copyright (c) Huawei Technologies Co., Ltd. 2024. 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: 2024-11-20 +- * Description: provide shim sandbox class definition +- *********************************************************************************/ +- +-#ifndef DAEMON_SANDBOX_SHIM_SANDBOX_H +-#define DAEMON_SANDBOX_SHIM_SANDBOX_H +- +-#include +-#include +-#include +- +-#include "read_write_lock.h" +-#include "sandbox_task.h" +-#include "sandbox.h" +- +-namespace sandbox { +- +-class ShimSandbox : public Sandbox { +-public: +- ShimSandbox(const std::string id, const std::string &rootdir, const std::string &statedir, const std::string name = "", +- const RuntimeInfo info = {"", "", ""}, std::string netMode = DEFAULT_NETMODE, std::string netNsPath = "", +- const runtime::v1::PodSandboxConfig sandboxConfig = runtime::v1::PodSandboxConfig::default_instance(), +- const std::string image = ""); +- virtual ~ShimSandbox() = default; +- +- // for sandbox api update +- void LoadSandboxTasks() override; +- auto SaveSandboxTasks() -> bool override; +- auto AddSandboxTasks(sandbox_task *task) -> bool override; +- auto GetAnySandboxTasks() -> std::string override; +- void DeleteSandboxTasks(const char *containerId) override; +- auto AddSandboxTasksProcess(const char *containerId, sandbox_process *processes) -> bool override; +- void DeleteSandboxTasksProcess(const char *containerId, const char *execId) override; +-}; +- +-} // namespace sandbox +- +-#endif // DAEMON_SANDBOX_SHIM_SANDBOX_H +\ No newline at end of file +-- +2.23.0 + diff --git a/0168-UT-del-shim_sandbox-and-change-sandbox-ops.patch b/0168-UT-del-shim_sandbox-and-change-sandbox-ops.patch new file mode 100644 index 0000000..e9bba80 --- /dev/null +++ b/0168-UT-del-shim_sandbox-and-change-sandbox-ops.patch @@ -0,0 +1,348 @@ +From 1e9031cc064f6980250287641e6b3311af755485 Mon Sep 17 00:00:00 2001 +From: liuxu +Date: Sat, 30 Nov 2024 09:50:33 +0800 +Subject: [PATCH 02/11] UT: del shim_sandbox and change sandbox ops + +Signed-off-by: liuxu +--- + test/mocks/sandbox_mock.cc | 26 ++++++++ + test/mocks/sandbox_mock.h | 9 +++ + test/mocks/sandboxer_sandbox_mock.cc | 35 +++++----- + test/mocks/sandboxer_sandbox_mock.h | 13 ++-- + test/mocks/shim_sandbox_mock.cc | 72 --------------------- + test/mocks/shim_sandbox_mock.h | 43 ------------ + test/sandbox/sandbox/CMakeLists.txt | 1 - + test/sandbox/sandbox/sandbox_ut.cc | 5 +- + test/sandbox/sandbox_manager/CMakeLists.txt | 1 - + 9 files changed, 61 insertions(+), 144 deletions(-) + delete mode 100644 test/mocks/shim_sandbox_mock.cc + delete mode 100644 test/mocks/shim_sandbox_mock.h + +diff --git a/test/mocks/sandbox_mock.cc b/test/mocks/sandbox_mock.cc +index 9db57a93..cce5a1b6 100644 +--- a/test/mocks/sandbox_mock.cc ++++ b/test/mocks/sandbox_mock.cc +@@ -221,4 +221,30 @@ bool Sandbox::Remove(Errors &error) + } + return true; + } ++ ++void Sandbox::LoadSandboxTasks() {} ++ ++auto Sandbox::PrepareContainer(const char *containerId, const char *baseFs, ++ const oci_runtime_spec *ociSpec, ++ const char *consoleFifos[]) -> int ++{ ++ return 0; ++} ++ ++auto Sandbox::PrepareExec(const char *containerId, const char *execId, ++ defs_process *processSpec, const char *consoleFifos[]) -> int ++{ ++ return 0; ++} ++ ++auto Sandbox::PurgeContainer(const char *containerId) -> int ++{ ++ return 0; ++} ++ ++auto Sandbox::PurgeExec(const char *containerId, const char *execId) -> int ++{ ++ return 0; ++} ++ + } +\ No newline at end of file +diff --git a/test/mocks/sandbox_mock.h b/test/mocks/sandbox_mock.h +index 98f40ad2..4908bcd9 100644 +--- a/test/mocks/sandbox_mock.h ++++ b/test/mocks/sandbox_mock.h +@@ -58,6 +58,15 @@ public: + MOCK_METHOD2(Stop, bool(uint32_t timeoutSecs, Errors &error)); + MOCK_METHOD1(Remove, bool(Errors &error)); + MOCK_METHOD1(Status, void(runtime::v1::PodSandboxStatus &status)); ++ ++ MOCK_METHOD0(LoadSandboxTasks, void()); ++ MOCK_METHOD4(PrepareContainer, int(const char *containerId, const char *baseFs, ++ const oci_runtime_spec *ociSpec, ++ const char *consoleFifos[])); ++ MOCK_METHOD4(PrepareExec, int(const char *containerId, const char *execId, ++ defs_process *processSpec, const char *consoleFifos[])); ++ MOCK_METHOD1(PurgeContainer, int(const char *containerId)); ++ MOCK_METHOD2(PurgeExec, int(const char *containerId, const char *execId)); + }; + + void MockSandbox_SetMock(MockSandbox *mock); +diff --git a/test/mocks/sandboxer_sandbox_mock.cc b/test/mocks/sandboxer_sandbox_mock.cc +index cce58842..6ebe2820 100644 +--- a/test/mocks/sandboxer_sandbox_mock.cc ++++ b/test/mocks/sandboxer_sandbox_mock.cc +@@ -33,40 +33,39 @@ void MockSandboxerSandbox_SetMock(MockSandboxerSandbox *mock) + + void SandboxerSandbox::LoadSandboxTasks() {} + +-auto SandboxerSandbox::SaveSandboxTasks() -> bool ++auto SandboxerSandbox::PrepareContainer(const char *containerId, const char *baseFs, ++ const oci_runtime_spec *ociSpec, ++ const char *consoleFifos[]) -> int + { + if (g_sandboxer_sandbox_mock != nullptr) { +- return g_sandboxer_sandbox_mock->SaveSandboxTasks(); ++ return g_sandboxer_sandbox_mock->PrepareContainer(containerId, baseFs, ociSpec, consoleFifos); + } +- return true; +-} ++ return 0; ++} + +-auto SandboxerSandbox::AddSandboxTasks(sandbox_task *task) -> bool ++auto SandboxerSandbox::PrepareExec(const char *containerId, const char *execId, ++ defs_process *processSpec, const char *consoleFifos[]) -> int + { + if (g_sandboxer_sandbox_mock != nullptr) { +- return g_sandboxer_sandbox_mock->AddSandboxTasks(task); ++ return g_sandboxer_sandbox_mock->PrepareExec(containerId, execId, processSpec, consoleFifos); + } +- return true; +-} ++ return 0; ++} + +-auto SandboxerSandbox::GetAnySandboxTasks() -> std::string ++auto SandboxerSandbox::PurgeContainer(const char *containerId) -> int + { + if (g_sandboxer_sandbox_mock != nullptr) { +- return g_sandboxer_sandbox_mock->GetAnySandboxTasks(); ++ return g_sandboxer_sandbox_mock->PurgeContainer(containerId); + } +- return std::string("Nothing for sandboxer."); ++ return 0; + } + +-void SandboxerSandbox::DeleteSandboxTasks(const char *containerId) {} +- +-auto SandboxerSandbox::AddSandboxTasksProcess(const char *containerId, sandbox_process *processes) -> bool ++auto SandboxerSandbox::PurgeExec(const char *containerId, const char *execId) -> int + { + if (g_sandboxer_sandbox_mock != nullptr) { +- return g_sandboxer_sandbox_mock->AddSandboxTasksProcess(containerId, processes); ++ return g_sandboxer_sandbox_mock->PurgeExec(containerId, execId); + } +- return true; ++ return 0; + } + +-void SandboxerSandbox::DeleteSandboxTasksProcess(const char *containerId, const char *execId) {} +- + } +\ No newline at end of file +diff --git a/test/mocks/sandboxer_sandbox_mock.h b/test/mocks/sandboxer_sandbox_mock.h +index 4f76e5fc..020fe4d6 100644 +--- a/test/mocks/sandboxer_sandbox_mock.h ++++ b/test/mocks/sandboxer_sandbox_mock.h +@@ -28,12 +28,13 @@ public: + virtual ~MockSandboxerSandbox() = default; + + MOCK_METHOD0(LoadSandboxTasks, void()); +- MOCK_METHOD0(SaveSandboxTasks, bool()); +- MOCK_METHOD1(AddSandboxTasks, bool(sandbox_task *task)); +- MOCK_METHOD0(GetAnySandboxTasks, std::string()); +- MOCK_METHOD1(DeleteSandboxTasks, void(const char *containerId)); +- MOCK_METHOD2(AddSandboxTasksProcess, bool(const char *containerId, sandbox_process *processes)); +- MOCK_METHOD2(DeleteSandboxTasksProcess, void(const char *containerId, const char *execId)); ++ MOCK_METHOD4(PrepareContainer, int(const char *containerId, const char *baseFs, ++ const oci_runtime_spec *ociSpec, ++ const char *consoleFifos[])); ++ MOCK_METHOD4(PrepareExec, int(const char *containerId, const char *execId, ++ defs_process *processSpec, const char *consoleFifos[])); ++ MOCK_METHOD1(PurgeContainer, int(const char *containerId)); ++ MOCK_METHOD2(PurgeExec, int(const char *containerId, const char *execId)); + }; + + void MockSandboxerSandbox_SetMock(MockSandboxerSandbox *mock); +diff --git a/test/mocks/shim_sandbox_mock.cc b/test/mocks/shim_sandbox_mock.cc +deleted file mode 100644 +index ccefb424..00000000 +--- a/test/mocks/shim_sandbox_mock.cc ++++ /dev/null +@@ -1,72 +0,0 @@ +-/****************************************************************************** +- * Copyright (c) Huawei Technologies Co., Ltd. 2023. 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: 2024-11-21 +- * Description: provide sandbox mock +- ******************************************************************************/ +- +-#include +-#include "shim_sandbox_mock.h" +- +-namespace sandbox { +-MockShimSandbox *g_shim_sandbox_mock = nullptr; +- +-ShimSandbox::ShimSandbox(const std::string id, const std::string &rootdir, const std::string &statedir, const std::string name, +- const RuntimeInfo info, std::string netMode, std::string netNsPath, const runtime::v1::PodSandboxConfig sandboxConfig, +- std::string image):Sandbox(id, rootdir, statedir, name, info, netMode, +- netNsPath, sandboxConfig, image) +-{ +-} +- +-void MockShimSandbox_SetMock(MockShimSandbox *mock) +-{ +- g_shim_sandbox_mock = mock; +-} +- +-void ShimSandbox::LoadSandboxTasks() {} +- +-auto ShimSandbox::SaveSandboxTasks() -> bool +-{ +- if (g_shim_sandbox_mock != nullptr) { +- return g_shim_sandbox_mock->SaveSandboxTasks(); +- } +- return true; +-} +- +-auto ShimSandbox::AddSandboxTasks(sandbox_task *task) -> bool +-{ +- if (g_shim_sandbox_mock != nullptr) { +- return g_shim_sandbox_mock->AddSandboxTasks(task); +- } +- return true; +-} +- +-auto ShimSandbox::GetAnySandboxTasks() -> std::string +-{ +- if (g_shim_sandbox_mock != nullptr) { +- return g_shim_sandbox_mock->GetAnySandboxTasks(); +- } +- return std::string("Nothing for shim."); +-} +- +-void ShimSandbox::DeleteSandboxTasks(const char *containerId) {} +- +-auto ShimSandbox::AddSandboxTasksProcess(const char *containerId, sandbox_process *processes) -> bool +-{ +- if (g_shim_sandbox_mock != nullptr) { +- return g_shim_sandbox_mock->AddSandboxTasksProcess(containerId, processes); +- } +- return true; +-} +- +-void ShimSandbox::DeleteSandboxTasksProcess(const char *containerId, const char *execId) {} +- +-} +\ No newline at end of file +diff --git a/test/mocks/shim_sandbox_mock.h b/test/mocks/shim_sandbox_mock.h +deleted file mode 100644 +index 1b16a4cc..00000000 +--- a/test/mocks/shim_sandbox_mock.h ++++ /dev/null +@@ -1,43 +0,0 @@ +-/****************************************************************************** +- * Copyright (c) Huawei Technologies Co., Ltd. 2023. 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: 2024-11-21 +- * Description: provide sandbox mock +- ******************************************************************************/ +- +-#ifndef _ISULAD_TEST_MOCKS_SHIM_SANDBOX_MOCK_H +-#define _ISULAD_TEST_MOCKS_SHIM_SANDBOX_MOCK_H +- +-#include +-#include "sandbox_mock.h" +-#include "shim_sandbox.h" +- +-namespace sandbox { +- +-class MockShimSandbox : public MockSandbox { +-public: +- MockShimSandbox() = default; +- virtual ~MockShimSandbox() = default; +- +- MOCK_METHOD0(LoadSandboxTasks, void()); +- MOCK_METHOD0(SaveSandboxTasks, bool()); +- MOCK_METHOD1(AddSandboxTasks, bool(sandbox_task *task)); +- MOCK_METHOD0(GetAnySandboxTasks, std::string()); +- MOCK_METHOD1(DeleteSandboxTasks, void(const char *containerId)); +- MOCK_METHOD2(AddSandboxTasksProcess, bool(const char *containerId, sandbox_process *processes)); +- MOCK_METHOD2(DeleteSandboxTasksProcess, void(const char *containerId, const char *execId)); +-}; +- +-void MockShimSandbox_SetMock(MockShimSandbox *mock); +- +-} +- +-#endif +diff --git a/test/sandbox/sandbox/CMakeLists.txt b/test/sandbox/sandbox/CMakeLists.txt +index 9ee67033..6dd6c3ee 100644 +--- a/test/sandbox/sandbox/CMakeLists.txt ++++ b/test/sandbox/sandbox/CMakeLists.txt +@@ -16,7 +16,6 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/sandbox/sandbox_task.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/sandbox/controller_manager.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/sandbox/sandboxer/controller/sandboxer_controller.cc +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/sandbox/shim/shim_sandbox.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/id_name_manager.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/config/isulad_config.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../test/sandbox/controller/controller_common.cc +diff --git a/test/sandbox/sandbox/sandbox_ut.cc b/test/sandbox/sandbox/sandbox_ut.cc +index 192d46ef..dd84d8fb 100644 +--- a/test/sandbox/sandbox/sandbox_ut.cc ++++ b/test/sandbox/sandbox/sandbox_ut.cc +@@ -16,7 +16,6 @@ + #include + + #include "sandbox.h" +-#include "shim_sandbox.h" + + namespace sandbox { + +@@ -41,7 +40,7 @@ TEST_F(SandboxTest, TestDefaultGetters) + std::string name = "test"; + RuntimeInfo info = {"runc", "shim", "kuasar"}; + +- auto sandbox = new ShimSandbox(id, rootdir, statedir, name, info); ++ auto sandbox = new Sandbox(id, rootdir, statedir, name, info); + ASSERT_NE(sandbox, nullptr); + + ASSERT_EQ(sandbox->IsReady(), false); +@@ -67,7 +66,7 @@ TEST_F(SandboxTest, TestGettersAndSetters) + std::string statedir = "/test2/statedir"; + std::string mode = "host"; + +- auto sandbox = new ShimSandbox(id, rootdir, statedir); ++ auto sandbox = new Sandbox(id, rootdir, statedir); + ASSERT_NE(sandbox, nullptr); + + sandbox->SetNetMode(mode); +diff --git a/test/sandbox/sandbox_manager/CMakeLists.txt b/test/sandbox/sandbox_manager/CMakeLists.txt +index 9254263c..a7dd8c9d 100644 +--- a/test/sandbox/sandbox_manager/CMakeLists.txt ++++ b/test/sandbox/sandbox_manager/CMakeLists.txt +@@ -12,7 +12,6 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cpputils/read_write_lock.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cpputils/transform.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../../test/mocks/sandbox_mock.cc +- ${CMAKE_CURRENT_SOURCE_DIR}/../../../test/mocks/shim_sandbox_mock.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../../test/mocks/sandboxer_sandbox_mock.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/sandbox/sandbox_manager.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/daemon/common/id_name_manager.c +-- +2.23.0 + diff --git a/0169-add-image-storage-unit-test.patch b/0169-add-image-storage-unit-test.patch new file mode 100644 index 0000000..e5770ee --- /dev/null +++ b/0169-add-image-storage-unit-test.patch @@ -0,0 +1,135 @@ +From 7dfa69162cd5ef01592808df555626a0688e6f4c Mon Sep 17 00:00:00 2001 +From: zhongtao +Date: Wed, 11 Dec 2024 19:09:20 +1400 +Subject: [PATCH 03/11] add image storage unit test + +Signed-off-by: zhongtao +--- + .../oci/storage/image_store/image_store.c | 4 +- + test/image/oci/storage/images/CMakeLists.txt | 2 + + .../oci/storage/images/storage_images_ut.cc | 51 +++++++++++++++++++ + 3 files changed, 56 insertions(+), 1 deletion(-) + +diff --git a/src/daemon/modules/image/oci/storage/image_store/image_store.c b/src/daemon/modules/image/oci/storage/image_store/image_store.c +index afe53764..71bf36e0 100644 +--- a/src/daemon/modules/image/oci/storage/image_store/image_store.c ++++ b/src/daemon/modules/image/oci/storage/image_store/image_store.c +@@ -27,6 +27,8 @@ + #include + #include + ++#include ++ + #include "utils.h" + #include "utils_file.h" + #include "utils_images.h" +@@ -3004,7 +3006,7 @@ static int do_append_image(storage_image *im) + return 0; + } + +-static void strip_host_prefix(char **name) ++STATIC void strip_host_prefix(char **name) + { + char *new_image_name = NULL; + +diff --git a/test/image/oci/storage/images/CMakeLists.txt b/test/image/oci/storage/images/CMakeLists.txt +index 28e0b505..04e60a69 100644 +--- a/test/image/oci/storage/images/CMakeLists.txt ++++ b/test/image/oci/storage/images/CMakeLists.txt +@@ -2,6 +2,8 @@ project(iSulad_UT) + + SET(EXE storage_images_ut) + ++add_definitions(-DUNIT_TEST=ON) ++ + add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/utils.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/utils_regex.c +diff --git a/test/image/oci/storage/images/storage_images_ut.cc b/test/image/oci/storage/images/storage_images_ut.cc +index ad0084d6..15da586e 100644 +--- a/test/image/oci/storage/images/storage_images_ut.cc ++++ b/test/image/oci/storage/images/storage_images_ut.cc +@@ -46,6 +46,10 @@ using ::testing::AtLeast; + using ::testing::Invoke; + using ::testing::_; + ++extern "C" { ++ void strip_host_prefix(char **name); ++} ++ + std::string GetDirectory() + { + char abs_path[PATH_MAX] { 0x00 }; +@@ -299,11 +303,13 @@ protected: + ASSERT_EQ(image_store_init(&opts), 0); + free(opts.storage_root); + free(opts.driver_name); ++ MockIsuladConf_SetMock(&m_isulad_conf); + } + + void TearDown() override + { + image_store_free(); ++ MockIsuladConf_SetMock(nullptr); + } + + void BackUp() +@@ -325,6 +331,7 @@ protected: + std::vector ids { "39891ff67da98ab8540d71320915f33d2eb80ab42908e398472cab3c1ce7ac10", + "e4db68de4ff27c2adfea0c54bbb73a61a42f5b667c326de4d7d5b19ab71c6a3b" }; + char store_real_path[PATH_MAX] = { 0x00 }; ++ NiceMock m_isulad_conf; + }; + + TEST_F(StorageImagesUnitTest, test_images_load) +@@ -714,3 +721,47 @@ TEST_F(StorageImagesUnitTest, test_image_store_remove_multi_name) + + Restore(); + } ++ ++static isulad_daemon_constants *g_test_isulad_daemon_constants = NULL; ++ ++isulad_daemon_constants *invoke_get_isulad_daemon_constants(void) ++{ ++ g_test_isulad_daemon_constants = (isulad_daemon_constants *)util_common_calloc_s(sizeof(isulad_daemon_constants)); ++ if (g_test_isulad_daemon_constants == NULL) { ++ return NULL; ++ } ++ g_test_isulad_daemon_constants->default_host = util_strdup_s("docker.io"); ++ ++ return g_test_isulad_daemon_constants; ++} ++ ++TEST_F(StorageImagesUnitTest, test_strip_host_prefix) ++{ ++ char *name = util_strdup_s("docker.io/test_image"); ++ std::string test_name = "test_image"; ++ std::string test_name_origin = "docker.io/test_image"; ++ char *null_name = NULL; ++ ++ strip_host_prefix(&name); ++ ASSERT_STREQ(name, test_name_origin.c_str()); ++ ++ EXPECT_CALL(m_isulad_conf, GetIsuladDaemonConstants()).WillRepeatedly(Invoke(invoke_get_isulad_daemon_constants)); ++ ++ strip_host_prefix(&name); ++ ASSERT_STREQ(name, test_name.c_str()); ++ ++ strip_host_prefix(&null_name); ++ ASSERT_EQ(null_name, nullptr); ++ ++ free(name); ++ free_isulad_daemon_constants(g_test_isulad_daemon_constants); ++} ++ ++#ifdef ENABLE_REMOTE_LAYER_STORE ++TEST_F(StorageImagesUnitTest, test_remote_layer_common) ++{ ++ ASSERT_EQ(remote_append_image_by_directory_with_lock(NULL), -1); ++ ASSERT_EQ(remote_remove_image_from_memory_with_lock(NULL), -1); ++ ASSERT_EQ(remote_image_get_top_layer_from_json(NULL), nullptr); ++} ++#endif +-- +2.23.0 + diff --git a/0170-fix-some-bad-code.patch b/0170-fix-some-bad-code.patch new file mode 100644 index 0000000..9be0493 --- /dev/null +++ b/0170-fix-some-bad-code.patch @@ -0,0 +1,165 @@ +From 0340a8248e8a4fb133ab3638679755d8590dafae Mon Sep 17 00:00:00 2001 +From: xuxuepeng +Date: Wed, 11 Dec 2024 13:03:21 +0800 +Subject: [PATCH 04/11] fix some bad code + +Signed-off-by: xuxuepeng +--- + .../storage/layer_store/graphdriver/driver.c | 19 +++++---------- + .../graphdriver/overlay2/driver_overlay2.c | 24 ++++++++++++++----- + 2 files changed, 24 insertions(+), 19 deletions(-) + +diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/driver.c b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/driver.c +index 94235b80..99fd573c 100644 +--- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/driver.c ++++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/driver.c +@@ -121,36 +121,31 @@ static inline void driver_unlock() + + int graphdriver_init(const struct storage_module_init_options *opts) + { +- int ret = 0; + size_t i = 0; + char driver_home[PATH_MAX] = { 0 }; + + if (opts == NULL || opts->storage_root == NULL || opts->driver_name == NULL) { +- ret = -1; +- goto out; ++ return -1; + } + + int nret = snprintf(driver_home, PATH_MAX, "%s/%s", opts->storage_root, opts->driver_name); + if (nret < 0 || (size_t)nret >= PATH_MAX) { + ERROR("Sprintf graph driver path failed"); +- ret = -1; +- goto out; ++ return -1; + } + + for (i = 0; i < g_numdrivers; i++) { + if (strcmp(opts->driver_name, g_drivers[i].name) == 0) { + if (pthread_rwlock_init(&(g_drivers[i].rwlock), NULL) != 0) { + ERROR("Failed to init driver rwlock"); +- ret = -1; +- goto out; ++ return -1; + } + #ifdef ENABLE_REMOTE_LAYER_STORE + g_drivers[i].enable_remote_layer = opts->enable_remote_layer; + #endif + if (g_drivers[i].ops->init(&g_drivers[i], driver_home, (const char **)opts->driver_opts, + opts->driver_opts_len) != 0) { +- ret = -1; +- goto out; ++ return -1; + } + g_graphdriver = &g_drivers[i]; + break; +@@ -159,12 +154,10 @@ int graphdriver_init(const struct storage_module_init_options *opts) + + if (i == g_numdrivers) { + ERROR("unsupported driver %s", opts->driver_name); +- ret = -1; +- goto out; ++ return -1; + } + +-out: +- return ret; ++ return 0; + } + + int graphdriver_create_rw(const char *id, const char *parent, struct driver_create_opts *create_opts) +diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c +index 6d45f463..cc24909a 100644 +--- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c ++++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c +@@ -64,6 +64,9 @@ struct io_read_wrapper; + + #define QUOTA_SIZE_OPTION "overlay2.size" + #define QUOTA_BASESIZE_OPTIONS "overlay2.basesize" ++#define OVERRIDE_KERNELCHECK_OPTIONS "overlay2.override_kernel_check" ++#define SKIP_MOUNT_HOME_OPTIONS "overlay2.skip_mount_home" ++#define MOUNT_OPTIONS "overlay2.mountopt" + // MAX_LAYER_ID_LENGTH represents the number of random characters which can be used to create the unique link identifer + // for every layer. If this value is too long then the page size limit for the mount command may be exceeded. + // The idLength should be selected such that following equation is true (512 is a buffer for label metadata). +@@ -150,7 +153,7 @@ static int overlay2_parse_options(struct graphdriver *driver, const char **optio + goto out; + } + overlay_opts->default_quota = converted; +- } else if (strcasecmp(dup, "overlay2.override_kernel_check") == 0) { ++ } else if (strcasecmp(dup, OVERRIDE_KERNELCHECK_OPTIONS) == 0) { + bool converted_bool = 0; + ret = util_str_to_bool(val, &converted_bool); + if (ret != 0) { +@@ -160,7 +163,7 @@ static int overlay2_parse_options(struct graphdriver *driver, const char **optio + goto out; + } + overlay_opts->override_kernelcheck = converted_bool; +- } else if (strcasecmp(dup, "overlay2.skip_mount_home") == 0) { ++ } else if (strcasecmp(dup, SKIP_MOUNT_HOME_OPTIONS) == 0) { + bool converted_bool = 0; + ret = util_str_to_bool(val, &converted_bool); + if (ret != 0) { +@@ -170,7 +173,7 @@ static int overlay2_parse_options(struct graphdriver *driver, const char **optio + goto out; + } + overlay_opts->skip_mount_home = converted_bool; +- } else if (strcasecmp(dup, "overlay2.mountopt") == 0) { ++ } else if (strcasecmp(dup, MOUNT_OPTIONS) == 0) { + overlay_opts->mount_options = util_strdup_s(val); + } else { + ERROR("Overlay2: unknown option: '%s'", dup); +@@ -693,6 +696,10 @@ static char *get_lower(const char *parent, const char *driver_home) + goto out; + } + ++ /* ++ * lower format: "l/5697636c0104156cb2bd94be25", so "/" and "\0" must be ++ * counted in the size for snprintf. ++ */ + lower_len = strlen(OVERLAY_LINK_DIR) + 1 + strlen(parent_link) + 1; + + parent_lower_file = util_path_join(parent_dir, OVERLAY_LAYER_LOWER); +@@ -707,6 +714,11 @@ static char *get_lower(const char *parent, const char *driver_home) + ERROR("parent lower %s too large", parent_link_file); + goto out; + } ++ /* ++ * with parent link, the lower format will be like ++ * "l/5697636c0104156cb2bd94be25:l/df53b618a57bb50a61755b5623", ++ * so ":" must be counted. ++ */ + lower_len = lower_len + strlen(parent_lowers) + 1; + } + +@@ -911,7 +923,7 @@ static int do_create_remote_ro(const char *id, const char *parent, const struct + #ifdef ENABLE_USERNS_REMAP + if (set_file_owner_for_userns_remap(layer_dir, userns_remap) != 0) { + ERROR("Unable to change directory %s owner for user remap.", layer_dir); +- goto out; ++ goto err_out; + } + #endif + +@@ -977,7 +989,7 @@ static int do_create(const char *id, const char *parent, const struct graphdrive + if (set_file_owner_for_userns_remap(layer_dir, userns_remap) != 0) { + ERROR("Unable to change directory %s owner for user remap.", layer_dir); + ret = -1; +- goto out; ++ goto err_out; + } + #endif + +@@ -1790,7 +1802,7 @@ out: + return ret; + } + +-bool is_valid_layer_link(const char *link_id, const struct graphdriver *driver) ++static bool is_valid_layer_link(const char *link_id, const struct graphdriver *driver) + { + bool valid = false; + char *link_dir = NULL; +-- +2.23.0 + diff --git a/0171-registry-module-code-improve.patch b/0171-registry-module-code-improve.patch new file mode 100644 index 0000000..96ca326 --- /dev/null +++ b/0171-registry-module-code-improve.patch @@ -0,0 +1,578 @@ +From 4f030e07e99dfe996897b69c9d950f3226363afe Mon Sep 17 00:00:00 2001 +From: zhongtao +Date: Wed, 11 Dec 2024 04:04:45 +1400 +Subject: [PATCH 05/11] registry module code improve + +Signed-off-by: zhongtao +--- + src/daemon/modules/image/oci/oci_pull.c | 2 +- + .../modules/image/oci/registry/http_request.c | 30 +++----- + .../modules/image/oci/registry/registry.c | 74 +++++++++---------- + .../image/oci/registry/registry_apiv1.c | 11 +-- + .../image/oci/registry/registry_apiv2.c | 62 +++++----------- + 5 files changed, 72 insertions(+), 107 deletions(-) + +diff --git a/src/daemon/modules/image/oci/oci_pull.c b/src/daemon/modules/image/oci/oci_pull.c +index 1c486974..245d14fd 100644 +--- a/src/daemon/modules/image/oci/oci_pull.c ++++ b/src/daemon/modules/image/oci/oci_pull.c +@@ -105,7 +105,7 @@ static int pull_image(const im_pull_request *request, progress_status_map *progr + options = (registry_pull_options *)util_common_calloc_s(sizeof(registry_pull_options)); + if (options == NULL) { + ERROR("Out of memory"); +- goto out; ++ return ret; + } + + if (request->auth != NULL) { +diff --git a/src/daemon/modules/image/oci/registry/http_request.c b/src/daemon/modules/image/oci/registry/http_request.c +index 80fc2184..b9b29c39 100644 +--- a/src/daemon/modules/image/oci/registry/http_request.c ++++ b/src/daemon/modules/image/oci/registry/http_request.c +@@ -16,9 +16,6 @@ + #define _GNU_SOURCE /* See feature_test_macros(7) */ + #include "http_request.h" + #include +-#include +-#include +-#include + #include + #include + #include +@@ -27,6 +24,10 @@ + #include + #include + ++#include ++#include ++#include ++ + #include "buffer.h" + #include "certs.h" + #include "err_msg.h" +@@ -128,7 +129,6 @@ static int setup_ssl_config(pull_descriptor *desc, struct http_get_options *opti + options->ssl_verify_host = !desc->skip_tls_verify; + + out: +- + free(host); + host = NULL; + +@@ -437,16 +437,14 @@ static int setup_common_options(pull_descriptor *desc, struct http_get_options * + if (ret != 0) { + ERROR("Failed setup ssl config"); + isulad_try_set_error_message("setup ssl config failed"); +- ret = -1; +- goto out; ++ return -1; + } + + if (custom_headers != NULL) { + options->custom_headers = util_str_array_dup(custom_headers, util_array_len(custom_headers)); + if (options->custom_headers == NULL) { + ERROR("dup headers failed"); +- ret = -1; +- goto out; ++ return -1; + } + } + +@@ -454,14 +452,10 @@ static int setup_common_options(pull_descriptor *desc, struct http_get_options * + if (ret != 0) { + ERROR("setup auth challenges failed"); + isulad_try_set_error_message("setup auth challenges failed"); +- ret = -1; +- goto out; ++ return -1; + } + + options->debug = false; +- +-out: +- + return ret; + } + +@@ -478,21 +472,16 @@ static int setup_get_token_options(pull_descriptor *desc, struct http_get_option + ret = setup_ssl_config(desc, options, url); + if (ret != 0) { + ERROR("Failed setup ssl config"); +- ret = -1; +- goto out; ++ return -1; + } + + ret = setup_auth_basic(desc, &options->custom_headers); + if (ret != 0) { + ERROR("dup headers failed"); +- ret = -1; +- goto out; ++ return -1; + } + + options->debug = false; +- +-out: +- + return ret; + } + +@@ -526,7 +515,6 @@ static int http_request_buf_options(pull_descriptor *desc, struct http_get_optio + + *output = util_strdup_s(output_buffer->contents); + out: +- + buffer_free(output_buffer); + + return ret; +diff --git a/src/daemon/modules/image/oci/registry/registry.c b/src/daemon/modules/image/oci/registry/registry.c +index 2e99255a..9a3b59a1 100644 +--- a/src/daemon/modules/image/oci/registry/registry.c ++++ b/src/daemon/modules/image/oci/registry/registry.c +@@ -20,13 +20,21 @@ + #include + #include + #include ++#include ++#include ++ + #include + #include + #include + #include + #include +-#include +-#include ++#include ++#include ++#include ++#include ++#ifdef ENABLE_IMAGE_SEARCH ++#include ++#endif + + #include "mediatype.h" + #include "isula_libutils/log.h" +@@ -35,13 +43,6 @@ + #include "registry_apiv1.h" + #include "certs.h" + #include "auths.h" +-#include "isula_libutils/registry_manifest_schema2.h" +-#include "isula_libutils/registry_manifest_schema1.h" +-#include "isula_libutils/docker_image_config_v2.h" +-#include "isula_libutils/image_manifest_v1_compatibility.h" +-#ifdef ENABLE_IMAGE_SEARCH +-#include "isula_libutils/image_search_image.h" +-#endif + #include "sha256.h" + #include "map.h" + #include "linked_list.h" +@@ -536,7 +537,6 @@ static char *calc_chain_id(char *parent_chain_id, char *diff_id) + full_digest = util_full_digest(digest); + + out: +- + free(digest); + digest = NULL; + +@@ -797,7 +797,6 @@ static int set_config(pull_descriptor *desc, char *image_id) + } + + out: +- + free(config_str); + config_str = NULL; + +@@ -812,17 +811,15 @@ static int set_loaded_time(pull_descriptor *desc, char *image_id) + if (!util_get_now_time_stamp(&now)) { + ret = -1; + ERROR("get now time stamp failed"); +- goto out; ++ return ret; + } + + ret = storage_img_set_loaded_time(image_id, &now); + if (ret != 0) { + ERROR("set loaded time failed"); +- goto out; ++ return ret; + } + +-out: +- + return ret; + } + +@@ -984,7 +981,6 @@ static int parse_docker_config(pull_descriptor *desc) + desc->config.create_time = util_to_timestamp_from_str(config->created); + + out: +- + free_docker_image_config_v2(config); + config = NULL; + free(err); +@@ -1084,17 +1080,15 @@ static int fetch_and_parse_config(pull_descriptor *desc) + ret = fetch_config(desc); + if (ret != 0) { + ERROR("fetch config failed"); +- goto out; ++ return ret; + } + + ret = parse_config(desc); + if (ret != 0) { + ERROR("parse config failed"); +- goto out; ++ return ret; + } + +-out: +- + return ret; + } + +@@ -1110,17 +1104,15 @@ static int fetch_and_parse_manifest(pull_descriptor *desc) + ret = fetch_manifest(desc); + if (ret != 0) { + ERROR("fetch manifest failed"); +- goto out; ++ return ret; + } + + ret = parse_manifest(desc); + if (ret != 0) { + ERROR("parse manifest failed"); +- goto out; ++ return ret; + } + +-out: +- + return ret; + } + +@@ -2116,6 +2108,26 @@ static void cached_layers_kvfree(void *key, void *value) + return; + } + ++static void free_registry_global(registry_global *registry) ++{ ++ if (registry == NULL) { ++ return; ++ } ++ ++ if (registry->cond_inited) { ++ pthread_cond_destroy(®istry->cond); ++ } ++ if (registry->mutex_inited) { ++ pthread_mutex_destroy(®istry->mutex); ++ } ++ if (registry->image_mutex_inited) { ++ pthread_mutex_destroy(®istry->image_mutex); ++ } ++ map_free(registry->cached_layers); ++ registry->cached_layers = NULL; ++ free(registry); ++} ++ + int registry_init(char *auths_dir, char *certs_dir) + { + int ret = 0; +@@ -2160,18 +2172,7 @@ int registry_init(char *auths_dir, char *certs_dir) + out: + + if (ret != 0) { +- if (g_shared->cond_inited) { +- pthread_cond_destroy(&g_shared->cond); +- } +- if (g_shared->mutex_inited) { +- pthread_mutex_destroy(&g_shared->mutex); +- } +- if (g_shared->image_mutex_inited) { +- pthread_mutex_destroy(&g_shared->image_mutex); +- } +- map_free(g_shared->cached_layers); +- g_shared->cached_layers = NULL; +- free(g_shared); ++ free_registry_global(g_shared); + g_shared = NULL; + } + +@@ -2221,7 +2222,6 @@ int registry_login(registry_login_options *options) + } + + out: +- + free_pull_desc(desc); + desc = NULL; + +diff --git a/src/daemon/modules/image/oci/registry/registry_apiv1.c b/src/daemon/modules/image/oci/registry/registry_apiv1.c +index 6da24c1d..d45f3876 100644 +--- a/src/daemon/modules/image/oci/registry/registry_apiv1.c ++++ b/src/daemon/modules/image/oci/registry/registry_apiv1.c +@@ -18,12 +18,16 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include + ++#include ++#include ++#include ++#include ++#include ++ + #include "registry_type.h" + #include "isula_libutils/log.h" + #include "http.h" +@@ -31,9 +35,6 @@ + #include "utils.h" + #include "parser.h" + #include "mediatype.h" +-#include "isula_libutils/oci_image_index.h" +-#include "isula_libutils/registry_manifest_list.h" +-#include "isula_libutils/imagetool_search_result.h" + #include "auths.h" + #include "err_msg.h" + #include "sha256.h" +diff --git a/src/daemon/modules/image/oci/registry/registry_apiv2.c b/src/daemon/modules/image/oci/registry/registry_apiv2.c +index dd49fab7..5d83b425 100644 +--- a/src/daemon/modules/image/oci/registry/registry_apiv2.c ++++ b/src/daemon/modules/image/oci/registry/registry_apiv2.c +@@ -18,12 +18,15 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include + ++#include ++#include ++#include ++#include ++ + #include "registry_type.h" + #include "isula_libutils/log.h" + #include "http.h" +@@ -31,8 +34,6 @@ + #include "utils.h" + #include "parser.h" + #include "mediatype.h" +-#include "isula_libutils/oci_image_index.h" +-#include "isula_libutils/registry_manifest_list.h" + #include "auths.h" + #include "err_msg.h" + #include "sha256.h" +@@ -60,7 +61,6 @@ static void set_body_null_if_exist(char *message) + static int parse_http_header(char *resp_buf, size_t buf_size, struct parsed_http_message *message) + { + char *real_message = NULL; +- int ret = 0; + + if (resp_buf == NULL || message == NULL) { + ERROR("Invalid NULL param"); +@@ -70,8 +70,7 @@ static int parse_http_header(char *resp_buf, size_t buf_size, struct parsed_http + real_message = strstr(resp_buf, "HTTP/1.1"); + if (real_message == NULL) { + ERROR("Failed to parse response, the response do not have HTTP/1.1"); +- ret = -1; +- goto out; ++ return -1; + } + + set_body_null_if_exist(real_message); +@@ -79,13 +78,10 @@ static int parse_http_header(char *resp_buf, size_t buf_size, struct parsed_http + ret = parse_http(real_message, strlen(real_message), message, HTTP_RESPONSE); + if (ret != 0) { + ERROR("Failed to parse response: %s", real_message); +- ret = -1; +- goto out; ++ return -1; + } + +-out: +- +- return ret; ++ return 0; + } + + static int parse_challenges(pull_descriptor *desc, char *schema, char *params) +@@ -225,7 +221,6 @@ static void free_parsed_http_message(struct parsed_http_message **message) + (*message)->body = NULL; + free(*message); + *message = NULL; +- return; + } + + static struct parsed_http_message *get_parsed_message(char *http_head) +@@ -386,7 +381,7 @@ static int registry_ping(pull_descriptor *desc) + ret = registry_pingv2(desc, "https"); + if (ret == 0) { + desc->protocol = util_strdup_s("https"); +- goto out; ++ return ret; + } + + if (desc->insecure_registry) { +@@ -396,15 +391,13 @@ static int registry_ping(pull_descriptor *desc) + ret = registry_pingv2(desc, "http"); + if (ret != 0) { + ERROR("ping %s with http failed", desc->host); +- goto out; ++ return ret; + } + desc->protocol = util_strdup_s("http"); + } else { + ERROR("ping %s with https failed", desc->host); + } + +-out: +- + return ret; + } + +@@ -552,7 +545,6 @@ static int parse_manifest_head(char *http_head, char **content_type, char **dige + } + + out: +- + if (ret != 0) { + free(*content_type); + *content_type = NULL; +@@ -584,19 +576,16 @@ static int append_manifests_accepts(char ***custom_headers) + sret = snprintf(accept, MAX_ACCEPT_LEN, "Accept: %s", mediatypes[i]); + if (sret < 0 || (size_t)sret >= MAX_ACCEPT_LEN) { + ERROR("Failed to sprintf accept media type %s", mediatypes[i]); +- ret = -1; +- goto out; ++ return -1; + } + + ret = util_array_append(custom_headers, accept); + if (ret != 0) { + ERROR("append accepts failed"); +- goto out; ++ return ret; + } + } + +-out: +- + return ret; + } + +@@ -703,7 +692,6 @@ static int fetch_manifest_list(pull_descriptor *desc, char *file, char **content + } + + out: +- + free(http_head); + http_head = NULL; + util_free_array(custom_headers); +@@ -727,7 +715,6 @@ static void try_log_resp_body(char *path, char *file) + ERROR("Get %s response message body: %s", path, body); + } + free(body); +- return; + } + + static int fetch_data(pull_descriptor *desc, char *path, char *file, char *content_type, char *digest) +@@ -1009,25 +996,22 @@ static int fetch_manifest_data(pull_descriptor *desc, char *file, char **content + ERROR("select manifest failed, manifests:%s", manifest_text); + free(manifest_text); + manifest_text = NULL; +- goto out; ++ return ret; + } + + sret = snprintf(path, sizeof(path), "/v2/%s/manifests/%s", desc->name, *digest); + if (sret < 0 || (size_t)sret >= sizeof(path)) { + ERROR("Failed to sprintf path for manifest"); +- ret = -1; +- goto out; ++ return -1; + } + + ret = fetch_data(desc, path, file, *content_type, *digest); + if (ret != 0) { + ERROR("registry: Get %s failed", path); +- goto out; ++ return ret; + } + } + +-out: +- + return ret; + } + +@@ -1096,20 +1080,17 @@ int fetch_config(pull_descriptor *desc) + sret = snprintf(path, sizeof(path), "/v2/%s/blobs/%s", desc->name, desc->config.digest); + if (sret < 0 || (size_t)sret >= sizeof(path)) { + ERROR("Failed to sprintf path for config"); +- ret = -1; +- goto out; ++ return -1; + } + + ret = fetch_data(desc, path, file, desc->config.media_type, desc->config.digest); + if (ret != 0) { + ERROR("registry: Get %s failed", path); +- goto out; ++ return ret; + } + + desc->config.file = util_strdup_s(file); + +-out: +- + return ret; + } + +@@ -1141,18 +1122,15 @@ int fetch_layer(pull_descriptor *desc, size_t index) + sret = snprintf(path, sizeof(path), "/v2/%s/blobs/%s", desc->name, layer->digest); + if (sret < 0 || (size_t)sret >= sizeof(path)) { + ERROR("Failed to sprintf path for layer %zu, name %s, digest %s", index, desc->name, layer->digest); +- ret = -1; +- goto out; ++ return -1; + } + + ret = fetch_data(desc, path, file, layer->media_type, layer->digest); + if (ret != 0) { + ERROR("registry: Get %s failed", path); +- goto out; ++ return ret; + } + +-out: +- + return ret; + } + +@@ -1185,7 +1163,6 @@ int parse_login(char *http_head, char *host) + } + + out: +- + free_parsed_http_message(&message); + + return ret; +@@ -1230,7 +1207,6 @@ int login_to_registry(pull_descriptor *desc) + goto out; + } + out: +- + free(resp_buffer); + resp_buffer = NULL; + +-- +2.23.0 + diff --git a/0172-image-store-fix-code-style.patch b/0172-image-store-fix-code-style.patch new file mode 100644 index 0000000..3194f14 --- /dev/null +++ b/0172-image-store-fix-code-style.patch @@ -0,0 +1,147 @@ +From 02a8be62cc7c1a492be5c9bc1fdf816b7d223b96 Mon Sep 17 00:00:00 2001 +From: zhongjiawei +Date: Wed, 11 Dec 2024 15:48:55 +0800 +Subject: [PATCH 06/11] image store:fix code style + +--- + .../oci/storage/image_store/image_store.c | 29 +++++++++---------- + .../oci/storage/image_store/image_store.h | 9 +++--- + .../oci/storage/image_store/image_type.c | 6 ++-- + .../oci/storage/image_store/image_type.h | 6 ++-- + 4 files changed, 25 insertions(+), 25 deletions(-) + +diff --git a/src/daemon/modules/image/oci/storage/image_store/image_store.c b/src/daemon/modules/image/oci/storage/image_store/image_store.c +index 71bf36e0..1909e7f7 100644 +--- a/src/daemon/modules/image/oci/storage/image_store/image_store.c ++++ b/src/daemon/modules/image/oci/storage/image_store/image_store.c +@@ -19,33 +19,34 @@ + #include + #include + #include ++#include ++#include ++#include ++ ++#include ++#include + #include + #include + #include + #include +-#include +-#include +-#include ++#include ++#include ++#include ++#include ++#include ++#include + + #include + + #include "utils.h" + #include "utils_file.h" + #include "utils_images.h" +-#include "isula_libutils/log.h" + #include "constants.h" + #include "utils_array.h" + #include "utils_string.h" + #include "utils_regex.h" +-#include "isula_libutils/defs.h" + #include "map.h" + #include "utils_convert.h" +-#include "isula_libutils/imagetool_image.h" +-#include "isula_libutils/imagetool_image_summary.h" +-#include "isula_libutils/registry_manifest_schema1.h" +-#include "isula_libutils/registry_manifest_schema2.h" +-#include "isula_libutils/oci_image_manifest.h" +-#include "isula_libutils/image_manifest_v1_compatibility.h" + #include "registry_type.h" + #include "mediatype.h" + #include "storage.h" +@@ -1361,8 +1362,7 @@ int image_store_set_big_data(const char *id, const char *key, const char *data) + + if (!image_store_lock(EXCLUSIVE)) { + ERROR("Failed to lock image store with exclusive lock, not allowed to change image big data assignments"); +- ret = -1; +- goto out; ++ return -1; + } + + img = lookup(id); +@@ -1648,8 +1648,7 @@ int image_store_get_names(const char *id, char ***names, size_t *names_len) + + if (!image_store_lock(SHARED)) { + ERROR("Failed to lock image store with shared lock, not allowed to get image names assignments"); +- ret = -1; +- goto out; ++ return -1; + } + + img = lookup(id); +diff --git a/src/daemon/modules/image/oci/storage/image_store/image_store.h b/src/daemon/modules/image/oci/storage/image_store/image_store.h +index 4544f84b..82bc1696 100644 +--- a/src/daemon/modules/image/oci/storage/image_store/image_store.h ++++ b/src/daemon/modules/image/oci/storage/image_store/image_store.h +@@ -18,16 +18,17 @@ + #include + #include + #include +-#include + #include + ++#include ++#include ++#include ++#include ++ + #include "storage.h" + #include "utils_timestamp.h" + #include "map.h" + #include "linked_list.h" +-#include "isula_libutils/imagetool_image.h" +-#include "isula_libutils/imagetool_images_list.h" +-#include "isula_libutils/imagetool_image_summary.h" + + #ifdef __cplusplus + extern "C" { +diff --git a/src/daemon/modules/image/oci/storage/image_store/image_type.c b/src/daemon/modules/image/oci/storage/image_store/image_type.c +index 50a81db2..67421cd6 100644 +--- a/src/daemon/modules/image/oci/storage/image_store/image_type.c ++++ b/src/daemon/modules/image/oci/storage/image_store/image_type.c +@@ -19,11 +19,11 @@ + #include + #include + +-#include "isula_libutils/storage_image.h" ++#include ++#include ++ + #include "util_atomic.h" + #include "utils.h" +-#include "isula_libutils/log.h" +- + #include "utils_images.h" + + static image_t *create_empty_image() +diff --git a/src/daemon/modules/image/oci/storage/image_store/image_type.h b/src/daemon/modules/image/oci/storage/image_store/image_type.h +index d8376644..bbf7a7dc 100644 +--- a/src/daemon/modules/image/oci/storage/image_store/image_type.h ++++ b/src/daemon/modules/image/oci/storage/image_store/image_type.h +@@ -19,9 +19,9 @@ + #include + #include + +-#include "isula_libutils/storage_image.h" +-#include "isula_libutils/log.h" +-#include "isula_libutils/oci_image_spec.h" ++#include ++#include ++#include + + #ifdef __cplusplus + extern "C" { +-- +2.23.0 + diff --git a/0173-bugfix-mem-leak.patch b/0173-bugfix-mem-leak.patch new file mode 100644 index 0000000..a477201 --- /dev/null +++ b/0173-bugfix-mem-leak.patch @@ -0,0 +1,64 @@ +From 3144357f7c735e24af180b9352378618ce8b2368 Mon Sep 17 00:00:00 2001 +From: liuxu +Date: Wed, 11 Dec 2024 11:32:06 +0800 +Subject: [PATCH 07/11] bugfix: mem leak + +Signed-off-by: liuxu +--- + src/daemon/executor/container_cb/execution_network.c | 2 ++ + src/daemon/modules/service/inspect_container.c | 2 ++ + src/utils/cutils/utils.c | 9 ++++++++- + 3 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/daemon/executor/container_cb/execution_network.c b/src/daemon/executor/container_cb/execution_network.c +index a145e33a..8e34998c 100644 +--- a/src/daemon/executor/container_cb/execution_network.c ++++ b/src/daemon/executor/container_cb/execution_network.c +@@ -1213,6 +1213,8 @@ static int generate_network_element(const char **bridges, const size_t len, defs + defs_map_string_object_networks_element *), len); + if (networks->values == NULL) { + ERROR("Out of memory "); ++ free(networks->keys); ++ networks->keys = NULL; + return -1; + } + +diff --git a/src/daemon/modules/service/inspect_container.c b/src/daemon/modules/service/inspect_container.c +index 40cf7aa1..ca3955c6 100644 +--- a/src/daemon/modules/service/inspect_container.c ++++ b/src/daemon/modules/service/inspect_container.c +@@ -629,6 +629,8 @@ static int do_transform_cni_to_map(container_network_settings *settings) + util_smart_calloc_s(sizeof(defs_map_string_object_port_bindings_element *), settings->cni_ports_len); + if (result->values == NULL) { + ERROR("Out of memory"); ++ free(result->keys); ++ result->keys = NULL; + ret = -1; + goto out; + } +diff --git a/src/utils/cutils/utils.c b/src/utils/cutils/utils.c +index 69f6dbf0..cf207acc 100644 +--- a/src/utils/cutils/utils.c ++++ b/src/utils/cutils/utils.c +@@ -1609,10 +1609,17 @@ defs_map_string_object *dup_map_string_empty_object(defs_map_string_object *src) + } + + dst->keys = util_smart_calloc_s(sizeof(char *), src->len); ++ if (dst->keys == NULL) { ++ ERROR("Out of memory"); ++ ret = -1; ++ goto out; ++ } + dst->values = util_smart_calloc_s(sizeof(defs_map_string_object_element *), src->len); +- if (dst->keys == NULL || dst->values == NULL) { ++ if (dst->values == NULL) { + ERROR("Out of memory"); + ret = -1; ++ free(dst->keys); ++ dst->keys = NULL; + goto out; + } + +-- +2.23.0 + diff --git a/0174-bugfix-for-parse_http_header.patch b/0174-bugfix-for-parse_http_header.patch new file mode 100644 index 0000000..c30030b --- /dev/null +++ b/0174-bugfix-for-parse_http_header.patch @@ -0,0 +1,25 @@ +From 7a3d70dba97facedf1394e65a80f7cc12be8273c Mon Sep 17 00:00:00 2001 +From: zhongtao +Date: Wed, 18 Dec 2024 16:37:33 +1400 +Subject: [PATCH 08/11] bugfix for parse_http_header + +Signed-off-by: zhongtao +--- + src/daemon/modules/image/oci/registry/registry_apiv2.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/daemon/modules/image/oci/registry/registry_apiv2.c b/src/daemon/modules/image/oci/registry/registry_apiv2.c +index 5d83b425..7f33646d 100644 +--- a/src/daemon/modules/image/oci/registry/registry_apiv2.c ++++ b/src/daemon/modules/image/oci/registry/registry_apiv2.c +@@ -61,6 +61,7 @@ static void set_body_null_if_exist(char *message) + static int parse_http_header(char *resp_buf, size_t buf_size, struct parsed_http_message *message) + { + char *real_message = NULL; ++ int ret = 0; + + if (resp_buf == NULL || message == NULL) { + ERROR("Invalid NULL param"); +-- +2.23.0 + diff --git a/0175-add-layer-storage-ut-test.patch b/0175-add-layer-storage-ut-test.patch new file mode 100644 index 0000000..264fb09 --- /dev/null +++ b/0175-add-layer-storage-ut-test.patch @@ -0,0 +1,244 @@ +From 96ce67b474de6d6cff1a87cd652ff00dafda7d6e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E6=AD=A6=E7=A7=AF=E8=B6=85?= +Date: Tue, 24 Dec 2024 19:39:26 +0800 +Subject: [PATCH 11/11] add layer storage ut test + +--- + test/image/oci/storage/layers/CMakeLists.txt | 1 + + .../oci/storage/layers/storage_layers_ut.cc | 166 +++++++++++++++++- + 2 files changed, 165 insertions(+), 2 deletions(-) + +diff --git a/test/image/oci/storage/layers/CMakeLists.txt b/test/image/oci/storage/layers/CMakeLists.txt +index e1c76453..c4384e8f 100644 +--- a/test/image/oci/storage/layers/CMakeLists.txt ++++ b/test/image/oci/storage/layers/CMakeLists.txt +@@ -148,5 +148,6 @@ target_link_libraries(${LAYER_EXE} + ${LIBTAR_LIBRARY} + -lwebsockets -lcrypto -lyajl -larchive ${SELINUX_LIBRARY} -ldevmapper -lz -lcap) + ++set_target_properties(${LAYER_EXE} PROPERTIES LINK_FLAGS "-Wl,--wrap,map_new -Wl,--wrap,map_insert -Wl,--wrap,map_search -Wl,--wrap,util_common_calloc_s -Wl,--wrap,util_smart_calloc_s") + add_test(NAME ${LAYER_EXE} COMMAND ${LAYER_EXE} --gtest_output=xml:${LAYER_EXE}-Results.xml) + set_tests_properties(${LAYER_EXE} PROPERTIES TIMEOUT 120) +diff --git a/test/image/oci/storage/layers/storage_layers_ut.cc b/test/image/oci/storage/layers/storage_layers_ut.cc +index 73611fdc..a03f4ce8 100644 +--- a/test/image/oci/storage/layers/storage_layers_ut.cc ++++ b/test/image/oci/storage/layers/storage_layers_ut.cc +@@ -29,6 +29,8 @@ + #include "storage.h" + #include "layer.h" + #include "driver_quota_mock.h" ++#include "map.h" ++#include "mock.h" + + using ::testing::Args; + using ::testing::ByRef; +@@ -41,6 +43,95 @@ using ::testing::AtLeast; + using ::testing::Invoke; + using ::testing::_; + ++static int g_map_search_count = 0; ++static int g_map_search_match = 1; ++static int g_map_new_count = 0; ++static int g_map_new_match = 1; ++static int g_map_insert_count = 0; ++static int g_map_insert_match = 1; ++ ++extern "C" { ++ DECLARE_WRAPPER_V(map_new, map_t *, (map_type_t kvtype, map_cmp_func comparator, map_kvfree_func kvfree)); ++ DEFINE_WRAPPER_V(map_new, map_t *, (map_type_t kvtype, map_cmp_func comparator, map_kvfree_func kvfree), (kvtype, comparator, kvfree)); ++ DECLARE_WRAPPER_V(map_insert, bool, (map_t *map, void *key, void *value)); ++ DEFINE_WRAPPER_V(map_insert, bool, (map_t *map, void *key, void *value), (map, key, value)); ++ DECLARE_WRAPPER_V(map_search, void *, (const map_t *map, void *key)); ++ DEFINE_WRAPPER_V(map_search, void *, (const map_t *map, void *key), (map, key)); ++ ++ DECLARE_WRAPPER_V(util_smart_calloc_s, void *, (size_t size, size_t len)); ++ DEFINE_WRAPPER_V(util_smart_calloc_s, void *, (size_t size, size_t len), (size, len)); ++ DECLARE_WRAPPER_V(util_common_calloc_s, void *, (size_t size)); ++ DEFINE_WRAPPER_V(util_common_calloc_s, void *, (size_t size), (size)); ++} ++ ++/* ++* Repeatedly calling the function executes the wrapper function and original function in the following order: ++* wrapper function; original function, wrapper function; original function, original function, wrapper function;... ++* Similar to regular queues (1 means wrapper, 0 means original): 1; 0 1; 0 0 1; 0 0 0 1; ... ++* It's used to MOCK a function that repeat permutation. ++* If you want a regular queue, the variables needs to be assigned back to the initial value. ++*/ ++static map_t *map_new_return_null(map_type_t kvtype, map_cmp_func comparator, map_kvfree_func kvfree) ++{ ++ g_map_new_count++; ++ if (g_map_new_count == g_map_new_match) { ++ g_map_new_match++; ++ g_map_new_count = 0; ++ return nullptr; ++ } else { ++ return __real_map_new(kvtype, comparator, kvfree); ++ } ++} ++ ++/* ++* Repeatedly calling the function executes the wrapper function and original function in the following order: ++* wrapper function; original function, wrapper function; original function, original function, wrapper function;... ++* Similar to regular queues (1 means wrapper, 0 means original): 1; 0 1; 0 0 1; 0 0 0 1; ... ++* It's used to MOCK a function that repeat permutation. ++* If you want a regular queue, the variables needs to be assigned back to the initial value. ++*/ ++static bool map_insert_return_false(map_t *map, void *key, void *value) ++{ ++ g_map_insert_count++; ++ if (g_map_insert_count == g_map_insert_match) { ++ g_map_insert_match++; ++ g_map_insert_count = 0; ++ return false; ++ } else { ++ return __real_map_insert(map, key, value); ++ } ++} ++ ++/* ++* Repeatedly calling the function executes the wrapper function and original function in the following order: ++* wrapper function; original function, wrapper function; original function, original function, wrapper function;... ++* Similar to regular queues (1 means wrapper, 0 means original): 1; 0 1; 0 0 1; 0 0 0 1; ... ++* It's used to MOCK a function that repeat permutation. ++* If you want a regular queue, the variables needs to be assigned back to the initial value. ++*/ ++void *map_search_fail(const map_t *map, void *key) ++{ ++ g_map_search_count++; ++ if (g_map_search_count == g_map_search_match) { ++ g_map_search_match++; ++ g_map_search_count = 0; ++ return nullptr; ++ } else { ++ return __real_map_search(map, key); ++ } ++ ++} ++ ++void *util_common_calloc_s_fail(size_t size) ++{ ++ return nullptr; ++} ++ ++void *util_smart_calloc_s_fail(size_t size, size_t len) ++{ ++ return nullptr; ++} ++ + std::string GetDirectory() + { + char abs_path[PATH_MAX] { 0x00 }; +@@ -178,6 +269,7 @@ protected: + std::string isulad_dir = "/tmp/isulad/"; + mkdir(isulad_dir.c_str(), 0755); + std::string root_dir = isulad_dir + "data"; ++ mkdir(root_dir.c_str(), 0755); + std::string run_dir = isulad_dir + "data/run"; + std::string data_dir = GetDirectory() + "/data"; + +@@ -194,12 +286,40 @@ protected: + opts.storage_root = strdup(real_path); + ASSERT_STRNE(util_clean_path(run_dir.c_str(), real_run_path, sizeof(real_run_path)), nullptr); + opts.storage_run_root = strdup(real_run_path); +- opts.driver_name = strdup("overlay"); + opts.driver_opts = static_cast(util_smart_calloc_s(sizeof(char *), 1)); + opts.driver_opts[0] = strdup("overlay2.skip_mount_home=true"); + opts.driver_opts_len = 1; +- ++#ifdef ENABLE_REMOTE_LAYER_STORE ++ opts.enable_remote_layer = true; ++#endif + EXPECT_CALL(m_driver_quota_mock, QuotaCtl(_, _, _, _)).WillRepeatedly(Invoke(invokeQuotaCtl)); ++ ++ opts.driver_name = NULL; ++ ASSERT_EQ(layer_store_init(&opts), -1); ++ ++ char over_path_max_driver_name[5000] { 0x00 }; // PATH_MAX = 4096 ++ std::memset(over_path_max_driver_name, 'a', 4999); ++ over_path_max_driver_name[4999]= '\0'; ++ opts.driver_name = over_path_max_driver_name; ++ ASSERT_EQ(layer_store_init(&opts), -1); ++ ++ opts.driver_name = strdup("overlay"); ++ MOCK_SET_V(map_new, map_new_return_null); ++ g_map_new_count = 0; ++ g_map_new_match = 1; ++ ASSERT_EQ(layer_store_init(&opts), -1); ++ ASSERT_EQ(layer_store_init(&opts), -1); ++ ASSERT_EQ(layer_store_init(&opts), -1); ++ ASSERT_EQ(layer_store_init(&opts), -1); ++ MOCK_CLEAR(map_new); ++ ++ MOCK_SET_V(map_insert, map_insert_return_false); ++ g_map_insert_count = 0; ++ g_map_insert_match = 1; ++ ASSERT_EQ(layer_store_init(&opts), -1); ++ ASSERT_EQ(layer_store_init(&opts), -1); ++ MOCK_CLEAR(map_insert); ++ + ASSERT_EQ(layer_store_init(&opts), 0); + + free(opts.storage_root); +@@ -238,6 +358,13 @@ TEST_F(StorageLayersUnitTest, test_layers_load) + struct layer_list *layer_list = (struct layer_list *)util_common_calloc_s(sizeof(struct layer_list)); + ASSERT_NE(layer_list, nullptr); + ++ ASSERT_EQ(layer_store_list(NULL), -1); ++ MOCK_SET_V(util_smart_calloc_s, util_smart_calloc_s_fail); ++ ASSERT_EQ(layer_store_list(layer_list), -1); ++ MOCK_CLEAR(util_smart_calloc_s); ++ MOCK_SET_V(util_common_calloc_s, util_common_calloc_s_fail); ++ ASSERT_EQ(layer_store_list(layer_list), -1); ++ MOCK_CLEAR(util_common_calloc_s); + ASSERT_EQ(layer_store_list(layer_list), 0); + ASSERT_EQ(layer_list->layers_len, 2); + +@@ -315,6 +442,18 @@ TEST_F(StorageLayersUnitTest, test_layer_store_by_compress_digest) + std::string id { "9c27e219663c25e0f28493790cc0b88bc973ba3b1686355f221c38a36978ac63" }; + struct layer_list *layer_list = (struct layer_list *)util_common_calloc_s(sizeof(struct layer_list)); + ++ MOCK_SET_V(util_smart_calloc_s, util_smart_calloc_s_fail); ++ ASSERT_EQ(layer_store_by_compress_digest(compress.c_str(), layer_list), -1); ++ MOCK_CLEAR(util_smart_calloc_s); ++ MOCK_SET_V(util_common_calloc_s, util_common_calloc_s_fail); ++ ASSERT_EQ(layer_store_by_compress_digest(compress.c_str(), layer_list), -1); ++ MOCK_CLEAR(util_common_calloc_s); ++ MOCK_SET_V(map_search, map_search_fail); ++ g_map_search_count = 0; ++ g_map_search_match = 1; ++ ASSERT_EQ(layer_store_by_compress_digest(compress.c_str(), layer_list), -1); ++ MOCK_CLEAR(map_search); ++ + ASSERT_EQ(layer_store_by_compress_digest(compress.c_str(), layer_list), 0); + ASSERT_EQ(layer_list->layers_len, 1); + +@@ -324,3 +463,26 @@ TEST_F(StorageLayersUnitTest, test_layer_store_by_compress_digest) + + free_layer_list(layer_list); + } ++ ++#ifdef ENABLE_REMOTE_LAYER_STORE ++TEST_F(StorageLayersUnitTest, test_remote_layer_common) ++{ ++ ASSERT_EQ(remote_layer_remove_memory_stores_with_lock(NULL), -1); ++ char arr[] = "random_id"; ++ const char *random_id = arr; ++ MOCK_SET_V(map_search, map_search_fail); ++ g_map_search_count = 0; ++ g_map_search_match = 1; ++ ASSERT_EQ(remote_layer_remove_memory_stores_with_lock(random_id), 0); ++ MOCK_CLEAR(map_search); ++ ++ ASSERT_EQ(remote_load_one_layer(NULL), -1); ++ MOCK_SET_V(map_search, map_search_fail); ++ g_map_search_count = 0; ++ g_map_search_match = 1; ++ ASSERT_EQ(remote_load_one_layer(random_id), -1); ++ MOCK_CLEAR(map_search); ++ ++ ASSERT_EQ(remote_load_one_layer(random_id), -1); ++} ++#endif +-- +2.23.0 + diff --git a/iSulad.spec b/iSulad.spec index 6127983..d9e894f 100644 --- a/iSulad.spec +++ b/iSulad.spec @@ -1,5 +1,5 @@ %global _version 2.1.5 -%global _release 17 +%global _release 18 %global is_systemd 1 %global enable_criv1 1 %global enable_cdi 1 @@ -187,7 +187,15 @@ Patch0163: 0163-image-layer-fix-code-style.patch Patch0164: 0164-image-store-add-UT.patch Patch0165: 0165-bugfix-do-purge-container-when-do_start_container-fa.patch Patch0166: 0166-supplementary-registry-design-documentation.patch - +Patch0167: 0167-sandbox-del-shim_sandbox-and-change-sandbox-ops.patch +Patch0168: 0168-UT-del-shim_sandbox-and-change-sandbox-ops.patch +Patch0169: 0169-add-image-storage-unit-test.patch +Patch0170: 0170-fix-some-bad-code.patch +Patch0171: 0171-registry-module-code-improve.patch +Patch0172: 0172-image-store-fix-code-style.patch +Patch0173: 0173-bugfix-mem-leak.patch +Patch0174: 0174-bugfix-for-parse_http_header.patch +Patch0175: 0175-add-layer-storage-ut-test.patch %ifarch x86_64 aarch64 Provides: libhttpclient.so()(64bit) @@ -455,6 +463,12 @@ fi %endif %changelog +* Mon Dec 30 2024 jingxiaolu - 2.1.5-18 +- Type: bugfix +- ID: NA +- SUG: NA +- DESC: sync patches from upstream for refactoring sandbox and bugfixing + * Mon Dec 30 2024 jingxiaolu - 2.1.5-17 - Type: bugfix - ID: NA -- Gitee