diff options
Diffstat (limited to '0004-network-support-version-opt.patch')
-rw-r--r-- | 0004-network-support-version-opt.patch | 482 |
1 files changed, 482 insertions, 0 deletions
diff --git a/0004-network-support-version-opt.patch b/0004-network-support-version-opt.patch new file mode 100644 index 0000000..db3a845 --- /dev/null +++ b/0004-network-support-version-opt.patch @@ -0,0 +1,482 @@ +From 7a2dd92a527c1f5ee79239d93b792dc9a9758e27 Mon Sep 17 00:00:00 2001 +From: liuxu <liuxu156@huawei.com> +Date: Tue, 7 Nov 2023 20:38:22 +0800 +Subject: [PATCH 04/14] network:support version opt + +--- + .../network/cni_operator/cni_operate.c | 16 +++ + .../network/cni_operator/cni_operate.h | 3 + + .../cni_operator/libcni/invoke/libcni_exec.c | 86 +++++++++++++- + .../cni_operator/libcni/invoke/libcni_exec.h | 2 + + .../libcni/invoke/libcni_result_parse.c | 29 +++++ + .../libcni/invoke/libcni_result_parse.h | 6 + + .../network/cni_operator/libcni/libcni_api.c | 106 ++++++++++++++++++ + .../network/cni_operator/libcni/libcni_api.h | 8 +- + .../cni_operator/libcni/libcni_result_type.c | 18 +++ + .../cni_operator/libcni/libcni_result_type.h | 12 ++ + .../modules/network/native/adaptor_native.c | 3 +- + 11 files changed, 281 insertions(+), 8 deletions(-) + +diff --git a/src/daemon/modules/network/cni_operator/cni_operate.c b/src/daemon/modules/network/cni_operator/cni_operate.c +index 62249f18..6db6db51 100644 +--- a/src/daemon/modules/network/cni_operator/cni_operate.c ++++ b/src/daemon/modules/network/cni_operator/cni_operate.c +@@ -926,6 +926,22 @@ out: + return ret; + } + ++int version_network_plane(const struct cni_network_list_conf *list, ++ struct cni_version_info_list **result_version_list) ++{ ++ if (list == NULL || list->list == NULL) { ++ ERROR("Invalid input params"); ++ return -1; ++ } ++ ++ if (cni_version_network_list(list, result_version_list) != 0) { ++ ERROR("Version CNI network failed"); ++ return -1; ++ } ++ ++ return 0; ++} ++ + int detach_loopback(const char *id, const char *netns) + { + int ret = 0; +diff --git a/src/daemon/modules/network/cni_operator/cni_operate.h b/src/daemon/modules/network/cni_operator/cni_operate.h +index 150c1154..7750ff00 100644 +--- a/src/daemon/modules/network/cni_operator/cni_operate.h ++++ b/src/daemon/modules/network/cni_operator/cni_operate.h +@@ -61,6 +61,9 @@ int detach_network_plane(const struct cni_manager *manager, const struct cni_net + int check_network_plane(const struct cni_manager *manager, const struct cni_network_list_conf *list, + struct cni_opt_result **result); + ++int version_network_plane(const struct cni_network_list_conf *list, ++ struct cni_version_info_list **result_version_list); ++ + #ifdef __cplusplus + } + #endif +diff --git a/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_exec.c b/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_exec.c +index c4bc81c0..4908565e 100644 +--- a/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_exec.c ++++ b/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_exec.c +@@ -28,7 +28,7 @@ + #include <sys/wait.h> + + #include <isula_libutils/cni_inner_plugin_info.h> +-#include <isula_libutils/cni_version.h> ++#include <isula_libutils/cni_version_info.h> + #include <isula_libutils/log.h> + #include <isula_libutils/cni_exec_error.h> + #include <isula_libutils/auto_cleanup.h> +@@ -183,10 +183,10 @@ static char *str_cni_exec_error(const cni_exec_error *e_err) + static char *cniversion_decode(const char *jsonstr) + { + __isula_auto_free parser_error err = NULL; +- cni_version *conf = NULL; ++ cni_version_info *conf = NULL; + char *result = NULL; + +- conf = cni_version_parse_data(jsonstr, NULL, &err); ++ conf = cni_version_info_parse_data(jsonstr, NULL, &err); + if (conf == NULL) { + ERROR("decoding config \"%s\", failed: %s", jsonstr, err); + goto out; +@@ -198,7 +198,7 @@ static char *cniversion_decode(const char *jsonstr) + + result = util_strdup_s(conf->cni_version); + out: +- free_cni_version(conf); ++ free_cni_version_info(conf); + return result; + } + +@@ -466,6 +466,84 @@ out: + return ret; + } + ++static char *get_default_version_stdin(void) ++{ ++ char *stdin_str = NULL; ++ int ret; ++ ++ ret = asprintf(&stdin_str, "{\"cniVersion\":\"%s\"}", CURRENT_VERSION); ++ if (ret < 0) { ++ ERROR("parse cni version failed"); ++ } ++ return stdin_str; ++} ++ ++static int do_parse_version_info_stdout_str(int exec_ret, const cni_exec_error *e_err, ++ const char *stdout_str, cni_version_info **result_version) ++{ ++ __isula_auto_free char *err_msg = NULL; ++ struct parser_context ctx = { OPT_GEN_SIMPLIFY, 0 }; ++ __isula_auto_free parser_error perr = NULL; ++ ++ if (exec_ret != 0) { ++ err_msg = str_cni_exec_error(e_err); ++ ERROR("raw exec failed: %s", err_msg); ++ isulad_append_error_message("raw exec failed: %s. ", err_msg); ++ return -1; ++ } ++ ++ if (stdout_str == NULL || strlen(stdout_str) == 0) { ++ ERROR("Get empty version result"); ++ return -1; ++ } ++ free_cni_version_info(*result_version); ++ *result_version = cni_version_info_parse_data(stdout_str, &ctx, &perr); ++ if (*result_version == NULL) { ++ ERROR("parse cni result version failed: %s", perr); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++int get_version_info(const char *plugin_path, cni_version_info **result_version) ++{ ++ __isula_auto_free char *err_msg = NULL; ++ char **envs = NULL; ++ __isula_auto_free char *stdout_str = NULL; ++ __isula_auto_free char *stdin_str = NULL; ++ cni_exec_error *e_err = NULL; ++ int ret = 0; ++ const struct cni_args cniargs = { ++ .command = "VERSION", ++ .netns = "dummy", ++ .ifname = "dummy", ++ .path = "dummy", ++ .container_id = "dummy" ++ }; ++ ++ stdin_str = get_default_version_stdin(); ++ if (stdin_str == NULL) { ++ return -1; ++ } ++ ++ envs = as_env(&cniargs); ++ if (envs == NULL) { ++ ERROR("create env failed"); ++ return -1; ++ } ++ ++ ret = raw_exec(plugin_path, stdin_str, envs, &stdout_str, &e_err); ++ DEBUG("Raw exec \"%s\" result: %d", plugin_path, ret); ++ DEBUG("Raw exec stdout: %s", stdout_str); ++ ret = do_parse_version_info_stdout_str(ret, e_err, stdout_str, result_version); ++ ++ util_free_array(envs); ++ free_cni_exec_error(e_err); ++ return ret; ++ ++} ++ + void free_cni_args(struct cni_args *cargs) + { + size_t i = 0; +diff --git a/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_exec.h b/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_exec.h +index 60b1c972..48d8d8b6 100644 +--- a/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_exec.h ++++ b/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_exec.h +@@ -40,6 +40,8 @@ int exec_plugin_with_result(const char *plugin_path, const char *cni_net_conf_js + + int exec_plugin_without_result(const char *plugin_path, const char *cni_net_conf_json, const struct cni_args *cniargs); + ++int get_version_info(const char *plugin_path, cni_version_info **result_version); ++ + #ifdef __cplusplus + } + #endif +diff --git a/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_result_parse.c b/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_result_parse.c +index 164b2e29..aa4f75cf 100644 +--- a/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_result_parse.c ++++ b/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_result_parse.c +@@ -741,3 +741,32 @@ struct cni_opt_result *new_result(const char *version, const char *jsonstr) + ERROR("unsupported CNI result version \"%s\"", version); + return NULL; + } ++ ++size_t get_curr_support_version_len(void) ++{ ++ return CURR_SUPPORT_VERSION_LEN; ++} ++ ++int get_support_version_pos(const char *version) ++{ ++ int i = 0; ++ if (version == NULL) { ++ return -1; ++ } ++ ++ for (i = CURR_SUPPORT_VERSION_LEN - 1; i >= 0; i--) { ++ if ((g_curr_support_versions[i] != NULL) && (strcmp(version, g_curr_support_versions[i]) == 0)) { ++ return i; ++ } ++ } ++ ++ return -1; ++} ++ ++const char *get_support_version_by_pos(size_t pos) ++{ ++ if (pos >= CURR_SUPPORT_VERSION_LEN) { ++ return NULL; ++ } ++ return g_curr_support_versions[pos]; ++} +\ No newline at end of file +diff --git a/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_result_parse.h b/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_result_parse.h +index 547bc915..438e1332 100644 +--- a/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_result_parse.h ++++ b/src/daemon/modules/network/cni_operator/libcni/invoke/libcni_result_parse.h +@@ -37,6 +37,12 @@ cni_result_curr *cni_result_curr_to_json_result(const struct cni_opt_result *src + + struct cni_opt_result *copy_result_from_current(const cni_result_curr *curr_result); + ++size_t get_curr_support_version_len(void); ++ ++int get_support_version_pos(const char *version); ++ ++const char *get_support_version_by_pos(size_t pos); ++ + #ifdef __cplusplus + } + #endif +diff --git a/src/daemon/modules/network/cni_operator/libcni/libcni_api.c b/src/daemon/modules/network/cni_operator/libcni/libcni_api.c +index 781759e8..7f62df78 100644 +--- a/src/daemon/modules/network/cni_operator/libcni/libcni_api.c ++++ b/src/daemon/modules/network/cni_operator/libcni/libcni_api.c +@@ -843,6 +843,112 @@ free_out: + return ret; + } + ++static int version_network(const char *plugin_name, cni_version_info **result_version) ++{ ++ int ret = 0; ++ __isula_auto_free char *plugin_path = NULL; ++ ++ if (plugin_name == NULL) { ++ ERROR("Empty plugin name"); ++ return -1; ++ } ++ ++ ret = find_plugin_in_path(plugin_name, (const char * const *)g_module_conf.bin_paths, ++ g_module_conf.bin_paths_len, &plugin_path); ++ if (ret != 0) { ++ ERROR("Failed to find plugin: \"%s\"", plugin_name); ++ isulad_append_error_message("Failed to find plugin: \"%s\". ", plugin_name); ++ return ret; ++ } ++ ++ // cni plugin calls should not take longer than 90 seconds ++ CALL_CHECK_TIMEOUT(90, ret = get_version_info(plugin_path, result_version)); ++ return ret; ++} ++ ++int cni_version_network_list(const struct cni_network_list_conf *list, ++ struct cni_version_info_list **result_version_list) ++{ ++ int ret = 0; ++ int i; ++ cni_version_info *tmp_result_version = NULL; ++ ++ if ((list == NULL) || (list->list == NULL) || (result_version_list == NULL)) { ++ ERROR("Empty arguments"); ++ return -1; ++ } ++ ++ *result_version_list = util_common_calloc_s(sizeof(struct cni_version_info_list)); ++ if (*result_version_list == NULL) { ++ ERROR("Out of memory"); ++ return -1; ++ } ++ (*result_version_list)->result_versions = util_smart_calloc_s(sizeof(cni_version_info *), list->list->plugins_len); ++ if ((*result_version_list)->result_versions == NULL) { ++ ERROR("Out of memory"); ++ ret = -1; ++ goto free_out; ++ } ++ ++ for (i = 0; i < list->list->plugins_len; i++) { ++ if (version_network(list->list->plugins[i]->type, &tmp_result_version) != 0) { ++ ret = -1; ++ ERROR("Run version plugin: %d failed", i); ++ goto free_out; ++ } ++ (*result_version_list)->result_versions[i] = tmp_result_version; ++ (*result_version_list)->result_versions_len += 1; ++ tmp_result_version = NULL; ++ } ++ ++ return ret; ++ ++free_out: ++ free_cni_version_info_list(*result_version_list); ++ *result_version_list = NULL; ++ return ret; ++} ++ ++/* get the latest CNI version supported by all plugins */ ++char *cni_get_plugins_supported_version(cni_net_conf_list *list) ++{ ++ // init to default version, if no found, just return default version ++ char *cni_version = util_strdup_s(CURRENT_VERSION); ++ int i, j, version_pos; ++ struct cni_version_info_list *result_version_list = NULL; ++ struct cni_network_list_conf network_list = { ++ .list = list, ++ }; ++ size_t curr_support_version_len = get_curr_support_version_len(); ++ __isula_auto_free size_t *plugin_version_count = util_smart_calloc_s(sizeof(size_t), curr_support_version_len); ++ if (plugin_version_count == NULL) { ++ return cni_version; ++ } ++ if (cni_version_network_list(&network_list, &result_version_list) != 0) { ++ return cni_version; ++ } ++ ++ // count plugin supported version ++ for (i = 0; i < result_version_list->result_versions_len; i++) { ++ for (j = result_version_list->result_versions[i]->supported_versions_len - 1; j >= 0 ; j--) { ++ version_pos = get_support_version_pos(result_version_list->result_versions[i]->supported_versions[j]); ++ if (version_pos < 0) { ++ break; ++ } ++ plugin_version_count[version_pos]++; ++ if (plugin_version_count[version_pos] == list->plugins_len) { ++ free(cni_version); ++ cni_version = util_strdup_s(get_support_version_by_pos(version_pos)); ++ goto free_out; ++ } ++ } ++ } ++ ++free_out: ++ free_cni_version_info_list(result_version_list); ++ return cni_version; ++} ++ + static int do_copy_plugin_args(const struct runtime_conf *rc, struct cni_args **cargs) + { + size_t i = 0; +diff --git a/src/daemon/modules/network/cni_operator/libcni/libcni_api.h b/src/daemon/modules/network/cni_operator/libcni/libcni_api.h +index 878cb1bb..f94ab3f7 100644 +--- a/src/daemon/modules/network/cni_operator/libcni/libcni_api.h ++++ b/src/daemon/modules/network/cni_operator/libcni/libcni_api.h +@@ -28,9 +28,6 @@ + extern "C" { + #endif + +-#define CURRENT_VERSION "1.0.0" +-#define SUPPORT_CACHE_AND_CHECK_VERSION "0.4.0" +- + #define SUPPORT_CAPABILITY_PORTMAPPINGS "portMappings" + #define SUPPORT_CAPABILITY_BANDWIDTH "bandwidth" + #define SUPPORT_CAPABILITY_IPRANGES "ipRanges" +@@ -87,6 +84,11 @@ int cni_del_network_list(const struct cni_network_list_conf *list, const struct + + int cni_check_network_list(const struct cni_network_list_conf *list, const struct runtime_conf *rc, + struct cni_opt_result **p_result); ++ ++int cni_version_network_list(const struct cni_network_list_conf *list, ++ struct cni_version_info_list **result_version_list); ++ ++char *cni_get_plugins_supported_version(cni_net_conf_list *list); + + void free_cni_port_mapping(struct cni_port_mapping *val); + +diff --git a/src/daemon/modules/network/cni_operator/libcni/libcni_result_type.c b/src/daemon/modules/network/cni_operator/libcni/libcni_result_type.c +index fd1091de..8a0ce1dd 100644 +--- a/src/daemon/modules/network/cni_operator/libcni/libcni_result_type.c ++++ b/src/daemon/modules/network/cni_operator/libcni/libcni_result_type.c +@@ -129,3 +129,21 @@ void free_cni_opt_result(struct cni_opt_result *val) + val->my_dns = NULL; + free(val); + } ++ ++void free_cni_version_info_list(struct cni_version_info_list *val) ++{ ++ size_t i = 0; ++ ++ if (val == NULL) { ++ return; ++ } ++ ++ for (i = 0; i < val->result_versions_len; i++) { ++ free_cni_version_info(val->result_versions[i]); ++ val->result_versions[i] = NULL; ++ } ++ free(val->result_versions); ++ val->result_versions = NULL; ++ ++ free(val); ++} +diff --git a/src/daemon/modules/network/cni_operator/libcni/libcni_result_type.h b/src/daemon/modules/network/cni_operator/libcni/libcni_result_type.h +index abbc22fe..36640e63 100644 +--- a/src/daemon/modules/network/cni_operator/libcni/libcni_result_type.h ++++ b/src/daemon/modules/network/cni_operator/libcni/libcni_result_type.h +@@ -19,10 +19,15 @@ + #include <sys/types.h> + #include <stdbool.h> + ++#include <isula_libutils/cni_version_info.h> ++ + #ifdef __cplusplus + extern "C" { + #endif + ++#define CURRENT_VERSION "1.0.0" ++#define SUPPORT_CACHE_AND_CHECK_VERSION "0.4.0" ++ + /* define types for version */ + struct cni_opt_result_interface { + char *name; +@@ -73,6 +78,11 @@ struct cni_opt_result { + struct cni_opt_result_dns *my_dns; + }; + ++struct cni_version_info_list { ++ cni_version_info **result_versions; ++ size_t result_versions_len; ++}; ++ + void free_cni_opt_result_ipconfig(struct cni_opt_result_ipconfig *ipc); + + void free_cni_opt_result_route(struct cni_opt_result_route *val); +@@ -83,6 +93,8 @@ void free_cni_opt_result_dns(struct cni_opt_result_dns *val); + + void free_cni_opt_result(struct cni_opt_result *val); + ++void free_cni_version_info_list(struct cni_version_info_list *val); ++ + #ifdef __cplusplus + } + #endif +diff --git a/src/daemon/modules/network/native/adaptor_native.c b/src/daemon/modules/network/native/adaptor_native.c +index 4c63dec1..45288d7e 100644 +--- a/src/daemon/modules/network/native/adaptor_native.c ++++ b/src/daemon/modules/network/native/adaptor_native.c +@@ -26,6 +26,7 @@ + #include "linked_list.h" + #include "isulad_config.h" + #include <isula_libutils/log.h> ++#include <isula_libutils/auto_cleanup.h> + #include "utils_network.h" + #include "network_tools.h" + #include "cni_operate.h" +@@ -1301,7 +1302,7 @@ static cni_net_conf_list *conf_bridge(const network_create_request *request, str + list->plugins_len++; + } + +- list->cni_version = util_strdup_s(CURRENT_VERSION); ++ list->cni_version = cni_get_plugins_supported_version(list); + if (request->name != NULL) { + list->name = util_strdup_s(request->name); + } else { +-- +2.42.0 + |