X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=sim%2Fo1-interface.git;a=blobdiff_plain;f=ntsimulator%2Fntsim-ng%2Fcore%2Fapp%2Fmanager.c;h=cc522dc26133d6fb0783032c546e0c23020999f9;hp=48816610a6b79f3b9372988bfd74f222205e3a3a;hb=3bbf9d8a3c81afebcffb2b926cef219336dd53d6;hpb=312a154cc4d60a09596fba8fd1259345e048cdc2 diff --git a/ntsimulator/ntsim-ng/core/app/manager.c b/ntsimulator/ntsim-ng/core/app/manager.c index 4881661..cc522dc 100644 --- a/ntsimulator/ntsim-ng/core/app/manager.c +++ b/ntsimulator/ntsim-ng/core/app/manager.c @@ -29,568 +29,261 @@ #include "core/framework.h" #include "core/session.h" #include "core/context.h" -#include "core/docker.h" -#define NTS_MANAGER_MODULE "nts-manager" -#define NTS_SIMULATION_SCHEMA_XPATH "/nts-manager:simulation" -#define NTS_FUNCTION_LIST_SCHEMA_XPATH "/nts-manager:simulation/network-functions/network-function" -#define NTS_SDN_CONTROLLER_CONFIG_XPATH "/nts-manager:simulation/sdn-controller" -#define NTS_VES_ENDPOINT_CONFIG_XPATH "/nts-manager:simulation/ves-endpoint" +#include "app_common.h" -#define NTS_NETWORK_FUNCTION_FTYPE_SCHEMA_XPATH "/nts-network-function:simulation/network-function/function-type" - -static manager_network_function_type *manager_context = 0; -static int manager_installed_function_types_count = 0; - -static int manager_populate_sysrepo_network_function_list(void); -static int manager_populate_static_status(void); - -static void manager_context_free(manager_network_function_type *context); - -static int manager_process_change(int context_index, manager_network_function_type *new_context); static int manager_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data); static int manager_instances_get_items_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data); -static int manager_stats_get_items_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data); int manager_run(void) { assert_session(); - log_message(1, LOG_COLOR_BOLD_YELLOW"\nrunning as MANAGER daemon...\n"LOG_COLOR_RESET); - - manager_operations_init(); - docker_device_init(); - - //get installed function types - struct lys_node_leaf *elem = (struct lys_node_leaf *)ly_ctx_get_node(session_context, 0, NTS_FUNCTION_LIST_SCHEMA_XPATH"/function-type", 0); - if(elem == 0) { - log_error("ly_ctx_get_node failed for xpath: %s", NTS_FUNCTION_LIST_SCHEMA_XPATH"/function-type"); - return NTS_ERR_FAILED; - } + log_add_verbose(1, LOG_COLOR_BOLD_YELLOW"starting MANAGER...\n"LOG_COLOR_RESET); - struct lys_ident **found = 0; - manager_installed_function_types_count = context_get_identity_leafs_of_type(elem->type.info.ident.ref[0], &found); - if(!manager_installed_function_types_count) { - log_error("error network functions"); - return NTS_ERR_FAILED; - } - - //initial list population - manager_context = (manager_network_function_type *)malloc(sizeof(manager_network_function_type) * manager_installed_function_types_count); - for(int i = 0; i < manager_installed_function_types_count; i++) { - manager_context[i].instance = 0; - - manager_context[i].function_type = found[i]; - asprintf(&manager_context[i].function_type_string, "%s:%s", found[i]->module->name, found[i]->name); - manager_context[i].docker_image_name = manager_context[i].function_type->ref; - manager_context[i].started_instances = 0; - manager_context[i].mounted_instances = 0; - manager_context[i].mount_point_addressing_method = strdup("docker-mapping"); - manager_context[i].docker_instance_name = strdup(manager_context[i].function_type->name); - manager_context[i].docker_version_tag = strdup("latest"); - manager_context[i].docker_repository = strdup("local"); - } - free(found); - - //do initial sysrepo list population - int rc = manager_populate_sysrepo_network_function_list(); + int rc = app_common_init(); if(rc != NTS_ERR_OK) { - log_error("manager_populate_sysrepo_network_function_list failed"); - return NTS_ERR_FAILED; - } - - rc = manager_populate_static_status(); - if(rc != NTS_ERR_OK) { - log_error("manager_populate_static_status failed"); + log_error("app_common_init failed\n"); return NTS_ERR_FAILED; } - //subscribe to any changes on the list - rc = sr_module_change_subscribe(session_running, NTS_MANAGER_MODULE, NTS_SIMULATION_SCHEMA_XPATH, manager_change_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &session_subscription); - if(rc != SR_ERR_OK) { - log_error("could not subscribe to simulation changes"); + //init manager context + rc = manager_context_init(); + if(rc != NTS_ERR_OK) { + log_error("manager_context_init failed\n"); return NTS_ERR_FAILED; } - rc = sr_oper_get_items_subscribe(session_running, NTS_MANAGER_MODULE, NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_instances_get_items_cb, NULL, SR_SUBSCR_CTX_REUSE, &session_subscription); - if(rc != SR_ERR_OK) { - log_error("could not subscribe to oper faults"); - return 0; - } - - rc = sr_oper_get_items_subscribe(session_running, NTS_MANAGER_MODULE, NTS_SIMULATION_SCHEMA_XPATH, manager_stats_get_items_cb, NULL, SR_SUBSCR_CTX_REUSE, &session_subscription); - if(rc != SR_ERR_OK) { - log_error("could not subscribe to oper faults"); - return 0; - } - - //daemonize - while(!framework_sigint) { - sleep(1); - } - - for(int i = 0; i < manager_installed_function_types_count; i++) { - while(manager_context[i].started_instances) { - manager_stop_instance(&manager_context[i]); - } - manager_context_free(&manager_context[i]); - } - - free(manager_context); - - return NTS_ERR_OK; -} - -static int manager_populate_sysrepo_network_function_list(void) { - //check whether everything is already populated, read and update (if previously ran) - sr_val_t *values = 0; - size_t value_count = 0; - int rc = sr_get_items(session_running, NTS_FUNCTION_LIST_SCHEMA_XPATH, 0, 0, &values, &value_count); - if(rc != SR_ERR_OK) { - log_error("get items failed"); + //init operations + rc = manager_operations_init(); + if(rc != NTS_ERR_OK) { + log_error("manager_operations_init failed\n"); return NTS_ERR_FAILED; } - //either get values, or if data inconclusive, delete everything - if(value_count) { - log_message(2, "nts-manager instances found (%d). cleaning up for fresh start...\n", value_count); - - for(int i = 0; i < value_count; i++) { - rc = sr_delete_item(session_running, values[i].xpath, 0); - if(rc != SR_ERR_OK) { - log_error("sr_delete_item failed"); - return NTS_ERR_FAILED; - } - } - rc = sr_apply_changes(session_running, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_apply_changes failed"); - return NTS_ERR_FAILED; - } - } - - //populate everything if needed - for(int i = 0; i < manager_installed_function_types_count; i++) { - char *xpath = 0; - - asprintf(&xpath, "%s[function-type='%s']/function-type", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string); - rc = sr_set_item_str(session_running, xpath, (const char *)manager_context[i].function_type_string, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - free(xpath); - - asprintf(&xpath, "%s[function-type='%s']/started-instances", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string); - rc = sr_set_item_str(session_running, xpath, "0", 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - free(xpath); - - asprintf(&xpath, "%s[function-type='%s']/mounted-instances", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string); - rc = sr_set_item_str(session_running, xpath, "0", 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - free(xpath); - - asprintf(&xpath, "%s[function-type='%s']/mount-point-addressing-method", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string); - rc = sr_set_item_str(session_running, xpath, (const char*)manager_context[i].mount_point_addressing_method, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - free(xpath); - - asprintf(&xpath, "%s[function-type='%s']/docker-instance-name", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string); - rc = sr_set_item_str(session_running, xpath, (const char*)manager_context[i].docker_instance_name, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - free(xpath); - - asprintf(&xpath, "%s[function-type='%s']/docker-version-tag", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string); - rc = sr_set_item_str(session_running, xpath, (const char*)manager_context[i].docker_version_tag, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - free(xpath); - - asprintf(&xpath, "%s[function-type='%s']/docker-repository", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string); - rc = sr_set_item_str(session_running, xpath, (const char*)manager_context[i].docker_repository, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - free(xpath); - } - - char int_to_str[30]; - - //setup sdn-controller defaults - if(strlen(framework_environment.sdn_controller_ip)) { - rc = sr_set_item_str(session_running, NTS_SDN_CONTROLLER_CONFIG_XPATH"/controller-ip", (const char*)framework_environment.sdn_controller_ip, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; + //print everything on the manager's screen + log_add_verbose(1, LOG_COLOR_BOLD_CYAN"Available images: \n"LOG_COLOR_RESET); + for(int i = 0; i < docker_context_count; i++) { + log_add_verbose(1, LOG_COLOR_BOLD_CYAN"- %s\n"LOG_COLOR_RESET, docker_context[i].image); + for(int j = 0; j < docker_context[i].available_images_count; j++) { + log_add_verbose(1, " - "LOG_COLOR_RED"%s/"LOG_COLOR_CYAN"%s"LOG_COLOR_RESET":"LOG_COLOR_YELLOW"%s\n"LOG_COLOR_RESET, docker_context[i].available_images[j].repo, docker_context[i].image, docker_context[i].available_images[j].tag); } } - - sprintf(int_to_str, "%d", framework_environment.sdn_controller_port); - rc = sr_set_item_str(session_running, NTS_SDN_CONTROLLER_CONFIG_XPATH"/controller-port", (const char*)int_to_str, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - - sprintf(int_to_str, "%d", framework_environment.sdn_controller_callhome_port); - rc = sr_set_item_str(session_running, NTS_SDN_CONTROLLER_CONFIG_XPATH"/controller-netconf-call-home-port", (const char*)int_to_str, 0, 0); + + // subscribe to any changes on the list + rc = sr_module_change_subscribe(session_running, NTS_MANAGER_MODULE, NTS_SIMULATION_SCHEMA_XPATH, manager_change_cb, NULL, 0, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_UPDATE, &session_subscription); if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); + log_error("could not subscribe to simulation changes\n"); return NTS_ERR_FAILED; } - if(strlen(framework_environment.sdn_controller_username)) { - rc = sr_set_item_str(session_running, NTS_SDN_CONTROLLER_CONFIG_XPATH"/controller-username", (const char*)framework_environment.sdn_controller_username, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - } - - if(strlen(framework_environment.sdn_controller_password)) { - rc = sr_set_item_str(session_running, NTS_SDN_CONTROLLER_CONFIG_XPATH"/controller-password", (const char*)framework_environment.sdn_controller_password, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - } - - //setup ves-endpoint details - if(strlen(framework_environment.ves_endpoint_protocol)) { - rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-protocol", (const char*)framework_environment.ves_endpoint_protocol, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - } - - if(strlen(framework_environment.ves_endpoint_ip)) { - rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-ip", (const char*)framework_environment.ves_endpoint_ip, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - } - - sprintf(int_to_str, "%d", framework_environment.ves_endpoint_port); - rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-port", (const char*)int_to_str, 0, 0); + //subscribe to stats + rc = sr_oper_get_items_subscribe(session_running, NTS_MANAGER_MODULE, NTS_SIMULATION_SCHEMA_XPATH, manager_sr_stats_get_items_cb, NULL, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_OPER_MERGE, &session_subscription); if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); + log_error("could not subscribe to oper faults\n"); return NTS_ERR_FAILED; } - if(strlen(framework_environment.ves_endpoint_auth_method)) { - rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-auth-method", (const char*)framework_environment.ves_endpoint_auth_method, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - } - - if(strlen(framework_environment.ves_endpoint_username)) { - rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-username", (const char*)framework_environment.ves_endpoint_username, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - } - - if(strlen(framework_environment.ves_endpoint_password)) { - rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-password", (const char*)framework_environment.ves_endpoint_password, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - } - - if(strlen(framework_environment.ves_endpoint_certificate)) { - rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-certificate", (const char*)framework_environment.ves_endpoint_certificate, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; - } - } - - rc = sr_set_item_str(session_running, NTS_NETWORK_FUNCTION_FTYPE_SCHEMA_XPATH, "NTS_FUNCTION_TYPE_MANAGER", 0, 0); + //subscribe to instances oper change + rc = sr_oper_get_items_subscribe(session_running, NTS_MANAGER_MODULE, NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_instances_get_items_cb, NULL, SR_SUBSCR_CTX_REUSE, &session_subscription); if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; + log_error("could not subscribe to oper faults\n"); + return 0; } - - //apply all changes - rc = sr_apply_changes(session_running, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_apply_changes failed: %s", sr_strerror(rc)); + rc = manager_sr_update_static_stats(); + if(rc != NTS_ERR_OK) { + log_error("manager_sr_update_static_stats failed\n"); return NTS_ERR_FAILED; } - return NTS_ERR_OK; -} - -static int manager_populate_static_status(void) { - assert_session(); - - char int_to_str[30]; - - //setup sdn-controller defaults - sprintf(int_to_str, "%d", framework_environment.host_base_port); - int rc = sr_set_item_str(session_operational, NTS_SIMULATION_SCHEMA_XPATH"/base-port", (const char*)int_to_str, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; + log_add_verbose(1, LOG_COLOR_BOLD_YELLOW"nts-ng manager"LOG_COLOR_RESET" v%s build %s\n", framework_environment.nts.version, framework_environment.nts.build_time); + log_add_verbose(1, LOG_COLOR_BOLD_YELLOW"Host IP:"LOG_COLOR_RESET" %s\n", framework_environment.host.ip); + log_add_verbose(1, LOG_COLOR_BOLD_YELLOW"Host ports"LOG_COLOR_RESET": "); + if(framework_environment.settings.ssh_connections) { + log_add(1, "NETCONF SSH: %d (%d)", framework_environment.host.ssh_base_port, framework_environment.settings.ssh_connections); } - - sprintf(int_to_str, "%d", framework_environment.ssh_connections); - rc = sr_set_item_str(session_operational, NTS_SIMULATION_SCHEMA_XPATH"/ssh-connections", (const char*)int_to_str, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; + else { + log_add(1, "NETCONF SSH: disabled"); } - - sprintf(int_to_str, "%d", framework_environment.tls_connections); - rc = sr_set_item_str(session_operational, NTS_SIMULATION_SCHEMA_XPATH"/tls-connections", (const char*)int_to_str, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_set_item_str failed"); - return NTS_ERR_FAILED; + if(framework_environment.settings.tls_connections) { + log_add(1, " | NETCONF TLS: %d (%d)", framework_environment.host.tls_base_port, framework_environment.settings.tls_connections); } - - //apply all changes - rc = sr_apply_changes(session_operational, 0, 0); - if(rc != SR_ERR_OK) { - log_error("sr_apply_changes failed"); - return NTS_ERR_FAILED; + else { + log_add(1, " | NETCONF TLS: disabled"); } - - return NTS_ERR_OK; -} - -static void manager_context_free(manager_network_function_type *context) { - assert(context); - - free(context->function_type_string); - free(context->mount_point_addressing_method); - free(context->docker_instance_name); - free(context->docker_version_tag); - free(context->docker_repository); -} - -//take note that this happens in the sysrepo thread -static int manager_process_change(int context_index, manager_network_function_type *new_context) { - assert(context_index < manager_installed_function_types_count); - assert(new_context); - - manager_network_function_type *current_context = &manager_context[context_index]; - int rc = 0; - - current_context->data_changed |= new_context->data_changed; - - //process changes, and update data in current_context to resemble new_context - if(new_context->docker_instance_name != 0) { - free(current_context->docker_instance_name); - current_context->docker_instance_name = strdup(new_context->docker_instance_name); + if(framework_environment.settings.ftp_connections) { + log_add(1, " | FTP: %d (%d)", framework_environment.host.ftp_base_port, framework_environment.settings.ftp_connections); } - - if(new_context->docker_version_tag != 0) { - free(current_context->docker_version_tag); - current_context->docker_version_tag = strdup(new_context->docker_version_tag); + else { + log_add(1, " | FTP: disabled"); } - - if(new_context->docker_repository != 0) { - free(current_context->docker_repository); - current_context->docker_repository = strdup(new_context->docker_repository); + if(framework_environment.settings.sftp_connections) { + log_add(1, " | SFTP: %d (%d)", framework_environment.host.sftp_base_port, framework_environment.settings.sftp_connections); } - - if(new_context->mount_point_addressing_method != 0) { - free(current_context->mount_point_addressing_method); - current_context->mount_point_addressing_method = strdup(new_context->mount_point_addressing_method); + else { + log_add(1, " | SFTP: disabled"); } + log_add(1,"\n"); + log_add_verbose(1, LOG_COLOR_BOLD_GREEN"started!\n"LOG_COLOR_RESET); - if(new_context->started_instances != -1) { - if(new_context->started_instances < current_context->started_instances) { - //remove started instances - while(current_context->started_instances > new_context->started_instances) { - log_message(2, "stopping instance of type %s\n", current_context->function_type_string); - rc = manager_stop_instance(current_context); - if(rc != NTS_ERR_OK) { - log_error("manager_stop_instance failed"); - return NTS_ERR_FAILED; - break; - } - } - } - else if(new_context->started_instances > current_context->started_instances) { - //add started instances - while(current_context->started_instances < new_context->started_instances) { - log_message(2, "staring instance of type %s\n", current_context->function_type_string); - rc = manager_start_instance(current_context); - if(rc != NTS_ERR_OK) { - log_error("manager_start_instance failed"); - return NTS_ERR_FAILED; - break; - } - } - } + //daemonize + while(!framework_sigint) { + manager_operations_loop(); //caution - this function time-waits (1sec) on manager_operation_sem } - if(new_context->mounted_instances != -1) { - if(new_context->mounted_instances < current_context->mounted_instances) { - //remove mounted instances - while(current_context->mounted_instances > new_context->mounted_instances) { - log_message(2, "unmounting instance of type %s\n", current_context->function_type_string); - rc = manager_unmount_instance(current_context); - if(rc != NTS_ERR_OK) { - log_error("manager_unmount_instance failed"); - break; - } - } - } - else if(new_context->mounted_instances > current_context->mounted_instances) { - //add mounted instances - while(current_context->mounted_instances < new_context->mounted_instances) { - log_message(2, "mouting instance of type %s\n", current_context->function_type_string); - rc = manager_mount_instance(current_context); - if(rc != NTS_ERR_OK) { - log_error("manager_mount_instance failed"); - break; - } - } - } - } + manager_operations_free(); + manager_context_free(); return NTS_ERR_OK; } static int manager_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data) { sr_change_iter_t *it = 0; - int rc = SR_ERR_OK; sr_change_oper_t oper; sr_val_t *old_value = 0; sr_val_t *new_value = 0; + int rc = SR_ERR_OK; - if(event == SR_EV_CHANGE) { - manager_network_function_type new_context; - new_context.function_type = 0; //not to be used. use only from current_context - new_context.function_type_string = 0; //not to be used. use only from current_context - int index = -1; + if(manager_sr_get_context_sync()) { + return SR_ERR_OK; + } + if(event == SR_EV_UPDATE) { rc = sr_get_changes_iter(session, NTS_FUNCTION_LIST_SCHEMA_XPATH"//.", &it); if(rc != SR_ERR_OK) { - log_error("sr_get_changes_iter failed"); + log_error("sr_get_changes_iter failed\n"); return SR_ERR_VALIDATION_FAILED; } + manager_operation_t *new_oper = 0; while((rc = sr_get_change_next(session, it, &oper, &old_value, &new_value)) == SR_ERR_OK) { - char *ov = sr_val_to_str(old_value); - char *nv = sr_val_to_str(new_value); - - //get function type and index - char *function_type_string = strdup(strstr(new_value->xpath, "function-type='") + 15); - *strchr(function_type_string, '\'') = 0; - - //if context is new - if((new_context.function_type_string == 0) || (strcmp(new_context.function_type_string, function_type_string) != 0)) { - - if(new_context.function_type_string != 0) { - if(manager_process_change(index, &new_context) != NTS_ERR_OK) { - manager_context_free(&new_context); - return SR_ERR_VALIDATION_FAILED; + if(new_value) { + //get function type and index + char *nv = sr_val_to_str(new_value); + + char function_type[512]; + strncpy(function_type, strstr(new_value->xpath, "function-type='") + 15, 510); + *strchr(function_type, '\'') = 0; + + //if context is new + if((new_oper == 0) || (strcmp(new_oper->function_type, function_type) != 0)) { + + if(new_oper == 0) { + manager_operations_begin(); + } + else { + //validate and add the operation + if(manager_operations_validate(new_oper) != NTS_ERR_OK) { + manager_operations_free_oper(new_oper); + manager_operations_finish_with_error(); + return SR_ERR_VALIDATION_FAILED; + } + + manager_operations_add(new_oper); + } + + new_oper = manager_operations_new_oper(MANAGER_OPERATION_EDIT); + new_oper->function_type = strdup(function_type); + + //get ft_idnex + for(int i = 0; i < docker_context_count; i++) { + if(strcmp(new_oper->function_type, manager_context[i].function_type) == 0) { + new_oper->ft_index = i; + break; + } } - manager_context_free(&new_context); + if(new_oper->ft_index == -1) { + log_error("function-type not found: %s\n", new_oper->function_type); + return SR_ERR_VALIDATION_FAILED; + } } - //-1 means no change - new_context.function_type_string = function_type_string; - new_context.started_instances = -1; - new_context.mounted_instances = -1; - new_context.mount_point_addressing_method = 0; - new_context.docker_instance_name = 0; - new_context.docker_version_tag = 0; - new_context.docker_repository = 0; - - new_context.data_changed = false; - - //find intex in manager_context[] - for(int i = 0; i < manager_installed_function_types_count; i++) { - if(strcmp(function_type_string, manager_context[i].function_type_string) == 0) { - index = i; - break; + char *leaf_path = strdup(strstr(new_value->xpath, "']/") + 3); + if(strcmp(leaf_path, "started-instances") == 0) { + new_oper->started_instances = new_value->data.uint16_val; + rc = sr_set_item(session, old_value->xpath, old_value, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item failed\n"); + return SR_ERR_VALIDATION_FAILED; + } + } + else if(strcmp(leaf_path, "mounted-instances") == 0) { + new_oper->mounted_instances = new_value->data.uint16_val; + rc = sr_set_item(session, old_value->xpath, old_value, 0); + if(rc != SR_ERR_OK) { + log_error("sr_set_item failed\n"); + return SR_ERR_VALIDATION_FAILED; + } + } + else if(strcmp(leaf_path, "docker-instance-name") == 0) { + new_oper->docker_instance_name = strdup(nv); + free(manager_context[new_oper->ft_index].docker_instance_name); + manager_context[new_oper->ft_index].docker_instance_name = strdup(nv); + } + else if(strcmp(leaf_path, "docker-version-tag") == 0) { + new_oper->docker_version_tag = strdup(nv); + free(manager_context[new_oper->ft_index].docker_version_tag); + manager_context[new_oper->ft_index].docker_version_tag = strdup(nv); + } + else if(strcmp(leaf_path, "docker-repository") == 0) { + new_oper->docker_repository = strdup(nv); + free(manager_context[new_oper->ft_index].docker_repository); + manager_context[new_oper->ft_index].docker_repository = strdup(nv); + } + else if(strcmp(leaf_path, "mount-point-addressing-method") == 0) { + //update conetxt + free(manager_context[new_oper->ft_index].mount_point_addressing_method); + manager_context[new_oper->ft_index].mount_point_addressing_method = strdup(nv); + } + else { + //mark each instance for reconfiguration + for(int i = 0; i < manager_context[new_oper->ft_index].started_instances; i++) { + manager_context[new_oper->ft_index].instance[i].is_configured = false; } } - } - char *leaf_path = strdup(strstr(new_value->xpath, "']/") + 3); - if(strcmp(leaf_path, "started-instances") == 0) { - new_context.started_instances = new_value->data.uint16_val; - } - else if(strcmp(leaf_path, "mounted-instances") == 0) { - new_context.mounted_instances = new_value->data.uint16_val; - } - else if(strcmp(leaf_path, "mount-point-addressing-method") == 0) { - new_context.mount_point_addressing_method = strdup(nv); - } - else if(strcmp(leaf_path, "docker-instance-name") == 0) { - new_context.docker_instance_name = strdup(nv); - } - else if(strcmp(leaf_path, "docker-version-tag") == 0) { - new_context.docker_version_tag = strdup(nv); - } - else if(strcmp(leaf_path, "docker-repository") == 0) { - new_context.docker_repository = strdup(nv); - } - else { - new_context.data_changed = true; + free(leaf_path); + free(nv); } - free(leaf_path); - free(ov); - free(nv); sr_free_val(old_value); sr_free_val(new_value); } sr_free_change_iter(it); - - if(index != -1) { - if(manager_process_change(index, &new_context) != NTS_ERR_OK) { - manager_context_free(&new_context); + + //validate and add the operation, if any; can be 0 if no modifications to NF list + if(new_oper) { + if(manager_operations_validate(new_oper) != NTS_ERR_OK) { + manager_operations_free_oper(new_oper); + manager_operations_finish_with_error(); return SR_ERR_VALIDATION_FAILED; } - manager_context_free(&new_context); + manager_operations_add(new_oper); } } + else if(event == SR_EV_CHANGE) { + } else if(event == SR_EV_DONE) { - bool global_change = true; + bool global_change = false; + // go throughout all the changes, not just NF list rc = sr_get_changes_iter(session, NTS_SIMULATION_SCHEMA_XPATH"//.", &it); if(rc != SR_ERR_OK) { - log_error("sr_get_changes_iter failed"); + log_error("sr_get_changes_iter failed\n"); return SR_ERR_VALIDATION_FAILED; } while((rc = sr_get_change_next(session, it, &oper, &old_value, &new_value)) == SR_ERR_OK) { - if(strstr(new_value->xpath, NTS_FUNCTION_LIST_SCHEMA_XPATH) == new_value->xpath) { - global_change = false; - sr_free_val(old_value); - sr_free_val(new_value); - break; + if(new_value) { + if(strstr(new_value->xpath, NTS_FUNCTION_LIST_SCHEMA_XPATH) != new_value->xpath) { + global_change = true; + sr_free_val(old_value); + sr_free_val(new_value); + break; + } } sr_free_val(old_value); @@ -599,124 +292,56 @@ static int manager_change_cb(sr_session_ctx_t *session, const char *module_name, sr_free_change_iter(it); - // commit all updates - for(int i = 0; i < manager_installed_function_types_count; i++) { - for(int j = 0; j < manager_context[i].started_instances; j++) { - if(global_change || manager_context[i].data_changed || (manager_context[i].instance[j].is_configured == false)) { - log_message(2, "configuring instance %d of type %s\n", j, manager_context[i].function_type_string); - rc = manager_config_instance(&manager_context[i], &manager_context[i].instance[j]); - if(rc != NTS_ERR_OK) { - log_error("manager_config_instance failed"); - } + if(global_change) { + //mark each instance for reconfiguration + for(int i = 0; i < docker_context_count; i++) { + for(int j = 0; j < manager_context[i].started_instances; j++) { + manager_context[i].instance[j].is_configured = false; } } - - manager_context[i].data_changed = false; } - global_change = false; + + manager_operations_finish_and_execute(); //from this point on, manager_operations_loop will take over } return SR_ERR_OK; } static int manager_instances_get_items_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data) { - - char value[100]; *parent = lyd_new_path(NULL, sr_get_context(sr_session_get_connection(session)), NTS_FUNCTION_LIST_SCHEMA_XPATH, 0, 0, 0); if(*parent == 0) { - log_error("lyd_new_path failed"); + log_error("lyd_new_path failed\n"); return SR_ERR_OPERATION_FAILED; } - for(int i = 0; i < manager_installed_function_types_count; i++) { - char *ftype_path = 0; - asprintf(&ftype_path, "%s[function-type='%s']/instances/instance", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string); + for(int i = 0; i < docker_context_count; i++) { + char ftype_path[512]; + sprintf(ftype_path, "%s[function-type='%s']/instances/instance", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type); for(int j = 0; j < manager_context[i].started_instances; j++) { - char *instance_path = 0; - asprintf(&instance_path, "%s[name='%s']", ftype_path, manager_context[i].instance[j].name); + char instance_path[1024]; + sprintf(instance_path, "%s[name='%s']", ftype_path, manager_context[i].instance[j].container.name); - char *full_path = 0; + char full_path[2048]; - asprintf(&full_path, "%s/mount-point-addressing-method", instance_path); + sprintf(full_path, "%s/mount-point-addressing-method", instance_path); if(lyd_new_path(*parent, NULL, full_path, manager_context[i].instance[j].mount_point_addressing_method, 0, 0) == 0) { - log_error("lyd_new_path failed"); - return SR_ERR_OPERATION_FAILED; - } - free(full_path); - - asprintf(&full_path, "%s/networking/docker-ip", instance_path); - if(lyd_new_path(*parent, NULL, full_path, manager_context[i].instance[j].docker_ip, 0, 0) == 0) { - log_error("lyd_new_path failed"); - return SR_ERR_OPERATION_FAILED; - } - free(full_path); - - asprintf(&full_path, "%s/networking/docker-port", instance_path); - sprintf(value, "%d", manager_context[i].instance[j].docker_port); - if(lyd_new_path(*parent, NULL, full_path, value, 0, 0) == 0) { - log_error("lyd_new_path failed"); + log_error("lyd_new_path failed\n"); return SR_ERR_OPERATION_FAILED; } - free(full_path); - asprintf(&full_path, "%s/networking/host-ip", instance_path); - if(lyd_new_path(*parent, NULL, full_path, manager_context[i].instance[j].host_ip, 0, 0) == 0) { - log_error("lyd_new_path failed"); + sprintf(full_path, "%s/is-mounted", instance_path); + struct lyd_node *is_mounted = lyd_new_path(*parent, NULL, full_path, manager_context[i].instance[j].is_mounted ? "true" : "false", 0, LYD_PATH_OPT_NOPARENTRET); + if(is_mounted == 0) { + log_error("lyd_new_path failed\n"); return SR_ERR_OPERATION_FAILED; } - free(full_path); - asprintf(&full_path, "%s/networking/host-port", instance_path); - sprintf(value, "%d", manager_context[i].instance[j].host_port); - if(lyd_new_path(*parent, NULL, full_path, value, 0, 0) == 0) { - log_error("lyd_new_path failed"); + if(manager_sr_populate_networking(is_mounted->parent, &manager_context[i].instance[j]) != NTS_ERR_OK) { + log_error("manager_sr_populate_networking failed\n"); return SR_ERR_OPERATION_FAILED; } - free(full_path); - - free(instance_path); } - free(ftype_path); - } - - return SR_ERR_OK; -} - -static int manager_stats_get_items_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data) { - char value[128]; - - *parent = lyd_new_path(NULL, sr_get_context(sr_session_get_connection(session)), NTS_SIMULATION_SCHEMA_XPATH, 0, 0, 0); - if(*parent == 0) { - return SR_ERR_OPERATION_FAILED; - } - - docker_usage_t usage = docker_usage_get(manager_context, manager_installed_function_types_count); - - sprintf(value, "%.2f", usage.cpu); - if(lyd_new_path(*parent, NULL, NTS_SIMULATION_SCHEMA_XPATH"/cpu-usage", value, 0, 0) == 0) { - return SR_ERR_OPERATION_FAILED; - } - - sprintf(value, "%.0f", usage.mem); - if(lyd_new_path(*parent, NULL, NTS_SIMULATION_SCHEMA_XPATH"/mem-usage", value, 0, 0) == 0) { - return SR_ERR_OPERATION_FAILED; - } - - //setup sdn-controller defaults - sprintf(value, "%d", framework_environment.host_base_port); - if(lyd_new_path(*parent, NULL, NTS_SIMULATION_SCHEMA_XPATH"/base-port", value, 0, 0) == 0) { - return SR_ERR_OPERATION_FAILED; - } - - sprintf(value, "%d", framework_environment.ssh_connections); - if(lyd_new_path(*parent, NULL, NTS_SIMULATION_SCHEMA_XPATH"/ssh-connections", value, 0, 0) == 0) { - return SR_ERR_OPERATION_FAILED; - } - - sprintf(value, "%d", framework_environment.tls_connections); - if(lyd_new_path(*parent, NULL, NTS_SIMULATION_SCHEMA_XPATH"/tls-connections", value, 0, 0) == 0) { - return SR_ERR_OPERATION_FAILED; } return SR_ERR_OK;