X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=sim%2Fo1-interface.git;a=blobdiff_plain;f=ntsimulator%2Fntsim-ng%2Fcore%2Fdocker.c;h=25a9a83bdac469e38b8175084cfe7747c083fac9;hp=7e8588d5f3d715df539fba04f97e06e669008bec;hb=3bbf9d8a3c81afebcffb2b926cef219336dd53d6;hpb=312a154cc4d60a09596fba8fd1259345e048cdc2 diff --git a/ntsimulator/ntsim-ng/core/docker.c b/ntsimulator/ntsim-ng/core/docker.c index 7e8588d..25a9a83 100644 --- a/ntsimulator/ntsim-ng/core/docker.c +++ b/ntsimulator/ntsim-ng/core/docker.c @@ -20,12 +20,12 @@ #include "docker.h" #include "utils/log_utils.h" #include "utils/sys_utils.h" +#include "utils/nts_utils.h" #include "utils/http_client.h" #include "core/framework.h" #include "core/session.h" #include "core/context.h" #include -#include #include #include @@ -35,13 +35,6 @@ static cJSON *docker_network_info = 0; -struct installable_module { - char *name; - char *fullpath; - bool installed; - bool submodule; -}; - typedef struct { char *name; char *value; @@ -50,222 +43,26 @@ typedef struct { static environment_var_t *docker_environment_var; static int docker_environment_var_count = 0; -static int get_installable_modules(struct installable_module **modules); //list available modules for install -static void list_yangs(const char *path, struct installable_module **modules, int *total); - static char *docker_parse_json_message(const char *json_string); +static int docker_add_port(cJSON *portBindings, uint16_t docker_port, uint16_t host_port); -static int docker_container_create(const char *image, manager_network_function_instance_t *instance); -static int docker_container_start(manager_network_function_instance_t *instance); -static int docker_container_inspect(manager_network_function_instance_t *instance); - - -bool docker_container_init(void) { - int rc; - - sr_log_stderr(SR_LL_NONE); - log_message(1, "Entering container-init mode...\n"); - - // connect to sysrepo - rc = sr_connect(0, &session_connection); - if(SR_ERR_OK != rc) { - log_error("sr_connect failed"); - return false; - } - - /* get context */ - session_context = (struct ly_ctx *)sr_get_context(session_connection); - if(session_context == 0) { - log_error("sr_get_context failed"); - return false; - } - - /* install yang files */ - log_message(1, "Installing yang files...\n"); - struct installable_module *modules; - int total_modules = get_installable_modules(&modules); - log_message(1, "Found total modules: %d\n", total_modules); - - int old_failed_installations = 1; - int failed_installations = 0; - int install_round = 0; - while(failed_installations != old_failed_installations) { - old_failed_installations = failed_installations; - failed_installations = 0; - install_round++; - for(int i = 0; i < total_modules; i++) { - if(!modules[i].installed) { - modules[i].submodule = context_yang_is_module(modules[i].fullpath); - if(!modules[i].submodule) { - if(!framework_is_docker_excluded_module(modules[i].name)) { - log_message(1, "[round %d] trying to install module %s from %s... ", install_round, modules[i].name, modules[i].fullpath); - if(!context_module_install(modules[i].name, modules[i].fullpath)) { - failed_installations++; - log_message(1, LOG_COLOR_BOLD_YELLOW"failed"LOG_COLOR_RESET"\n"); - } - else { - log_message(1, LOG_COLOR_BOLD_GREEN"done"LOG_COLOR_RESET"\n"); - modules[i].installed = true; - } - } - else { - log_message(1, "[round %d] not installing module %s as it's excluded in config.\n", install_round, modules[i].name); - modules[i].installed = true; - } - } - else { - log_message(1, "[round %d] %s is a submodule... "LOG_COLOR_BOLD_YELLOW"skipping"LOG_COLOR_RESET"\n", install_round, modules[i].name); - modules[i].installed = true; - } - } - } - } - - if(failed_installations != 0) { - log_error("Failed to install all modules in %d rounds...", install_round); - return false; - } - else { - log_message(1, LOG_COLOR_BOLD_GREEN"successfully"LOG_COLOR_RESET" installed "LOG_COLOR_BOLD_GREEN"ALL"LOG_COLOR_RESET" modules in "LOG_COLOR_BOLD_YELLOW"%d"LOG_COLOR_RESET" rounds\n", (install_round - 1)); - } - - //set access for all installed modules - log_message(1, "Setting access configuration for installed modules... "); - for(int i = 0; i < total_modules; i++) { - if((!framework_is_docker_excluded_module(modules[i].name)) && (!modules[i].submodule)) { - if(!context_module_set_access(modules[i].name)) { - log_error("Failed to set access to module %s...", modules[i].name); - return false; - } - } - } - log_message(1, LOG_COLOR_BOLD_GREEN"done"LOG_COLOR_RESET"\n"); - - //cleanup module-install used memory - for(int i = 0; i < total_modules; i++) { - free(modules[i].name); - free(modules[i].fullpath); - } - free(modules); - - //get context - session_context = (struct ly_ctx *)sr_get_context(session_connection); - if(session_context == 0) { - log_error("sr_get_context failed"); - return false; - } - - //init context so we can see all the available modules, features, etc - rc = context_init(session_context); - if(rc != 0) { - log_error("context_init() failed"); - return false; - } - - /* enable features */ - log_message(1, "Enabling yang features...\n"); - char **available_features; - int total_available_features; - total_available_features = context_get_features(&available_features); - log_message(1, "Found total features: %d\n", total_available_features); - for(int i = 0; i < total_available_features; i++) { - log_message(1, "feature %s: ", available_features[i]); - - if(!context_get_feature_enabled(available_features[i])) { - if(!framework_is_docker_excluded_feature(available_features[i])) { - if(context_feature_enable(available_features[i])) { - log_message(1, "enabling... "LOG_COLOR_BOLD_GREEN"done"LOG_COLOR_RESET"\n"); - } - else { - log_error("enabling... failed\n"); - } - } - else { - log_message(1, "excluded in config, skipping\n"); - } - } - else { - log_message(1, "already "LOG_COLOR_BOLD_GREEN"enabled"LOG_COLOR_RESET", skipping.\n"); - } - } - for(int i = 0; i < total_available_features; i++) { - free(available_features[i]); - } - free(available_features); +static int docker_populate_images(docker_context_t *context, int count, const char *min_version); +static int docker_container_create(const char *image, docker_container_t *container); +static int docker_container_start(docker_container_t *container); +static int docker_container_inspect(docker_container_t *container); - sr_disconnect(session_connection); - context_free(); +int docker_init(const char **filter, int filter_count, const char *min_version, docker_context_t **context) { + assert(filter); + assert(filter_count); + assert(context); - log_message(1, LOG_COLOR_BOLD_GREEN"ntsim successfully initialized Docker container"LOG_COLOR_RESET"\n"); - return true; -} - -static int get_installable_modules(struct installable_module **modules) { - int total = 0; - *modules = 0; - list_yangs("/opt/dev/deploy/yang", modules, &total); - return total; -} - -static void list_yangs(const char *path, struct installable_module **modules, int *total) { - DIR *d; - struct dirent *dir; - d = opendir(path); - if(d) { - while((dir = readdir(d)) != NULL) { - if(dir->d_type == DT_DIR) { - if(strcmp(dir->d_name, ".") != 0 && strcmp(dir->d_name, "..") != 0) - { - char new_path[1024]; - snprintf(new_path, sizeof(new_path), "%s/%s", path, dir->d_name); - list_yangs(new_path, modules, total); - } - } else { - if(strstr(dir->d_name, ".yang") != 0) { - *modules = (struct installable_module *)realloc(*modules, sizeof(struct installable_module) * (*total + 1)); - if(!*modules) { - log_error("could not realloc"); - return; - } - - (*modules)[*total].name = (char*)malloc(sizeof(char) * (strlen(dir->d_name) + 1)); - if(!(*modules)[*total].name) { - log_error("could not alloc"); - return; - } - strcpy((*modules)[*total].name, dir->d_name); - (*modules)[*total].name[strlen(dir->d_name) - 5] = 0; //extract ".yang" - char *rev = strstr((*modules)[*total].name, "@"); - if(rev) { //extract revision, if exists - *rev = 0; - } - - (*modules)[*total].fullpath = (char*)malloc(sizeof(char) * (strlen(path) + 1 + strlen(dir->d_name) + 1)); - if(!(*modules)[*total].fullpath) { - log_error("could not alloc"); - return; - } - sprintf((*modules)[*total].fullpath, "%s/%s", path, dir->d_name); - - (*modules)[*total].installed = false; - (*modules)[*total].submodule = false; - - (*total)++; - } - } - } - closedir(d); - } -} - -int docker_device_init(void) { char *response = 0; char url[512]; - sprintf(url, "http://v%s/containers/%s/json", framework_environment.docker_engine_version, framework_environment.hostname); + sprintf(url, "http://v%s/containers/%s/json", framework_environment.settings.docker_engine_version, framework_environment.settings.hostname); int rc = http_socket_request(url, DOCKER_SOCK_FNAME, "GET", 0, 0, &response); if(rc != NTS_ERR_OK) { - log_error("http_socket_request failed"); + log_error("http_socket_request failed\n"); return NTS_ERR_FAILED; } @@ -273,20 +70,20 @@ int docker_device_init(void) { free(response); if(json_response == 0) { - log_error("could not parse JSON response for url=\"%s\"", url); + log_error("could not parse JSON response for url=\"%s\"\n", url); return NTS_ERR_FAILED; } cJSON *hostConfig = cJSON_GetObjectItemCaseSensitive(json_response, "HostConfig"); if(hostConfig == 0) { - log_error("could not get HostConfig object"); + log_error("could not get HostConfig object\n"); cJSON_Delete(json_response); return NTS_ERR_FAILED; } cJSON *networkMode = cJSON_GetObjectItemCaseSensitive(hostConfig, "NetworkMode"); if(networkMode == 0) { - log_error("could not get NetworkMode object"); + log_error("could not get NetworkMode object\n"); cJSON_Delete(json_response); return NTS_ERR_FAILED; } @@ -294,106 +91,173 @@ int docker_device_init(void) { docker_network_info = cJSON_Duplicate(networkMode, 1); cJSON_Delete(json_response); - log_message(2, "finished parsing docker inspect...\n"); - + log_add_verbose(2, "finished parsing docker inspect...\n"); - docker_environment_var_count = 5; + docker_environment_var_count = 9; docker_environment_var = (environment_var_t *)malloc(sizeof(environment_var_t) * docker_environment_var_count); if(docker_environment_var == 0) { - log_error("malloc failed"); + log_error("malloc failed\n"); cJSON_Delete(networkMode); return NTS_ERR_FAILED; } //set env variables for network functions docker_environment_var[0].name = ENV_VAR_SSH_CONNECTIONS; - asprintf(&docker_environment_var[0].value, "%d", framework_environment.ssh_connections); + asprintf(&docker_environment_var[0].value, "%d", framework_environment.settings.ssh_connections); docker_environment_var[1].name = ENV_VAR_TLS_CONNECTIONS; - asprintf(&docker_environment_var[1].value, "%d", framework_environment.tls_connections); + asprintf(&docker_environment_var[1].value, "%d", framework_environment.settings.tls_connections); docker_environment_var[2].name = ENV_VAR_IPV6ENABLED; - docker_environment_var[2].value = framework_environment.ip_v6_enabled ? "true" : "false"; + docker_environment_var[2].value = framework_environment.settings.ip_v6_enabled ? "true" : "false"; docker_environment_var[3].name = ENV_VAR_HOST_IP; - docker_environment_var[3].value = framework_environment.host_ip; - docker_environment_var[4].name = ENV_VAR_HOST_BASE_PORT; + docker_environment_var[3].value = framework_environment.host.ip; + + docker_environment_var[4].name = ENV_VAR_HOST_NETCONF_SSH_BASE_PORT; // docker_environment_var[4].value = will be updated by docker_create... + docker_environment_var[5].name = ENV_VAR_HOST_NETCONF_TLS_BASE_PORT; + // docker_environment_var[5].value = will be updated by docker_create... + docker_environment_var[6].name = ENV_VAR_HOST_TRANSFER_FTP_BASE_PORT; + // docker_environment_var[6].value = will be updated by docker_create... + docker_environment_var[7].name = ENV_VAR_HOST_TRANSFER_SFTP_BASE_PORT; + // docker_environment_var[7].value = will be updated by docker_create... + + docker_environment_var[8].name = ENV_VAR_VES_COMMON_HEADER_VERSION; + docker_environment_var[8].value = framework_environment.ves_endpoint.common_header_version; + + + + //docker context build + *context = (docker_context_t *)malloc(sizeof(docker_context_t) * filter_count); + if(*context == 0) { + log_error("bad malloc\n"); + free(docker_environment_var[0].value); + free(docker_environment_var[1].value); + free(docker_environment_var); + return NTS_ERR_FAILED; + } + + docker_context_t *ctx = *context; + for(int i = 0; i < filter_count; i++) { + ctx[i].image = strdup(filter[i]); + ctx[i].available_images = 0; + ctx[i].available_images_count = 0; + } + + docker_populate_images(ctx, filter_count, min_version); return NTS_ERR_OK; } -int docker_device_start(const manager_network_function_type *function_type, manager_network_function_instance_t *instance) { - assert(function_type); - assert(instance); +void docker_free(docker_context_t *context, int count) { + free(docker_environment_var[0].value); + free(docker_environment_var[1].value); + free(docker_environment_var); + + for(int i = 0; i < count; i++) { + free(context[i].image); + for(int j = 0; j < context[i].available_images_count; j++) { + free(context[i].available_images[j].repo); + free(context[i].available_images[j].tag); + } + free(context[i].available_images); + } +} + +int docker_start(const char *container_name, const char *tag, const char *image, const char *repo, uint16_t host_netconf_ssh_port, uint16_t host_netconf_tls_port, uint16_t host_ftp_port, uint16_t host_sftp_port, docker_container_t *container) { + assert(container_name); + assert(image); + assert(container); assert(docker_network_info); - char image[512]; - if(function_type->docker_version_tag && (function_type->docker_version_tag[0] != 0)) { - if(function_type->docker_repository && (function_type->docker_repository[0] != 0) && (strcmp(function_type->docker_repository, "local") != 0)) { - sprintf(image, "%s/%s:%s", function_type->docker_repository, function_type->docker_image_name, function_type->docker_version_tag); + char image_full[512]; + if(tag && (tag[0] != 0)) { + if(repo && (repo[0] != 0) && (strcmp(repo, "local") != 0)) { + sprintf(image_full, "%s/%s:%s", repo, image, tag); } else { - sprintf(image, "%s:%s", function_type->docker_image_name, function_type->docker_version_tag); + sprintf(image_full, "%s:%s", image, tag); } } else { - if(function_type->docker_repository && (function_type->docker_repository[0] != 0) && (strcmp(function_type->docker_repository, "local") != 0)) { - sprintf(image, "%s/%s:latest", function_type->docker_repository, function_type->docker_image_name); + if(repo && (repo[0] != 0) && (strcmp(repo, "local") != 0)) { + sprintf(image_full, "%s/%s:latest", repo, image); } else { - sprintf(image, "%s:latest", function_type->docker_image_name); + sprintf(image_full, "%s:latest", image); } } - int rc = docker_container_create(image, instance); + container->name = strdup(container_name); + container->id = 0; + container->docker_ip = 0; + container->docker_netconf_ssh_port = STANDARD_NETCONF_PORT; + container->docker_netconf_tls_port = container->docker_netconf_ssh_port + framework_environment.settings.ssh_connections; + container->docker_ftp_port= STANDARD_FTP_PORT; + container->docker_sftp_port= STANDARD_SFTP_PORT; + + container->host_ip = strdup(framework_environment.host.ip); + container->host_netconf_ssh_port = host_netconf_ssh_port; + container->host_netconf_tls_port = host_netconf_tls_port; + container->host_ftp_port = host_ftp_port; + container->host_sftp_port = host_sftp_port; + + int rc = docker_container_create(image_full, container); if(rc != NTS_ERR_OK) { - log_error("docker_container_create failed"); + log_error("docker_container_create failed\n"); return NTS_ERR_FAILED; } - rc = docker_container_start(instance); + rc = docker_container_start(container); if(rc != NTS_ERR_OK) { - log_error("docker_container_start failed"); - docker_device_stop(instance); + log_error("docker_container_start failed\n"); + docker_stop(container); return NTS_ERR_FAILED; } - rc = docker_container_inspect(instance); + rc = docker_container_inspect(container); if(rc != NTS_ERR_OK) { - log_error("docker_container_inspect failed"); - docker_device_stop(instance); + log_error("docker_container_inspect failed\n"); + docker_stop(container); return NTS_ERR_FAILED; } - log_message(2, "docker_device_start: docker_id: %s | name: %s | docker_ip: %s | host_port: %d\n", instance->docker_id, instance->name, instance->docker_ip, instance->host_port); + log_add_verbose(2, "docker_start: name: %s | id: %s | docker_ip: %s | netconf_ssh_port: (%d:%d) | netconf_tls_port: (%d:%d) | ftp_port: (%d:%d) | sftp_port: (%d:%d)\n", container->name, container->id, container->docker_ip, container->docker_netconf_ssh_port, container->host_netconf_ssh_port, container->docker_netconf_tls_port, container->host_netconf_tls_port, container->docker_ftp_port, container->host_ftp_port, container->docker_sftp_port, container->host_sftp_port); return NTS_ERR_OK; } -int docker_device_stop(manager_network_function_instance_t *instance) { - assert(instance); +int docker_stop(docker_container_t *container) { + assert(container); char url[512]; - sprintf(url, "http://v%s/containers/%s?force=true", framework_environment.docker_engine_version, instance->docker_id); + sprintf(url, "http://v%s/containers/%s?force=true", framework_environment.settings.docker_engine_version, container->id); + + free(container->name); + free(container->id); + free(container->docker_ip); + free(container->host_ip); int rc = http_socket_request(url, DOCKER_SOCK_FNAME, "DELETE", "", 0, 0); if(rc != NTS_ERR_OK) { - log_error("http_socket_request failed"); + log_error("http_socket_request failed\n"); return NTS_ERR_FAILED; } return NTS_ERR_OK; } -docker_usage_t docker_usage_get(const manager_network_function_type *function_type, int function_type_count) { - docker_usage_t ret; - ret.cpu = 0; - ret.mem = 0; +int docker_usage_get(const char **instances_id, int count, docker_usage_t *usage) { + assert(instances_id); + assert(usage); + + usage->cpu = 0; + usage->mem = 0; char buffer[1024]; char full_text[1024 * 1024]; FILE* pipe = popen("docker stats --no-stream --format \"table {{.ID}}|{{.CPUPerc}}|{{.MemUsage}}|\"", "r"); if (!pipe) { - log_error("popen() failed"); - return ret; + log_error("popen() failed\n"); + return NTS_ERR_FAILED; } int n = 1; @@ -465,19 +329,16 @@ docker_usage_t docker_usage_get(const manager_network_function_type *function_ty mem = strtof(buff, 0) * mul; - if(strcmp(container_name, framework_environment.hostname) == 0) { - ret.cpu += cpu; - ret.mem += mem; + if(strcmp(container_name, framework_environment.settings.hostname) == 0) { + usage->cpu += cpu; + usage->mem += mem; } else { - for(int i = 0; i < function_type_count; i++) { - for(int j = 0; j < function_type[i].started_instances; j++) { - - if(strcmp(container_name, function_type[i].instance[j].docker_id) == 0) { - ret.cpu += cpu; - ret.mem += mem; - break; - } + for(int i = 0; i < count; i++) { + if(strcmp(container_name, instances_id[i]) == 0) { + usage->cpu += cpu; + usage->mem += mem; + break; } } } @@ -486,10 +347,9 @@ docker_usage_t docker_usage_get(const manager_network_function_type *function_ty c = d; } + usage->cpu /= get_nprocs(); - ret.cpu /= get_nprocs(); - - return ret; + return NTS_ERR_OK; } static char *docker_parse_json_message(const char *json_string) { @@ -497,14 +357,13 @@ static char *docker_parse_json_message(const char *json_string) { cJSON *json_response = cJSON_Parse(json_string); if(json_response == 0) { - log_error("cJSON_Parse failed"); + log_error("cJSON_Parse failed\n"); return 0; } - cJSON *message; - message = cJSON_GetObjectItem(json_response, "message"); + cJSON *message = cJSON_GetObjectItem(json_response, "message"); if(message == 0) { - log_error("json parsing failed"); + log_error("json parsing failed\n"); cJSON_Delete(json_response); return 0; } @@ -514,30 +373,148 @@ static char *docker_parse_json_message(const char *json_string) { return ret; } -static int docker_container_create(const char *image, manager_network_function_instance_t *instance) { +static int docker_add_port(cJSON *portBindings, uint16_t docker_port, uint16_t host_port) { + assert(portBindings); + + cJSON *port = cJSON_CreateArray(); + if(port == 0) { + log_error("could not create JSON object: port\n"); + return NTS_ERR_FAILED; + } + + char dockerContainerPort[20]; + sprintf(dockerContainerPort, "%d/tcp", docker_port); + + if(cJSON_AddItemToObject(portBindings, dockerContainerPort, port) == 0) { + log_error("cJSON_AddItemToObject failed\n"); + return NTS_ERR_FAILED; + } + + cJSON *hostPort = cJSON_CreateObject(); + if(hostPort == 0) { + log_error("could not create JSON object: HostPort\n"); + return NTS_ERR_FAILED; + } + + char dockerHostPort[20]; + sprintf(dockerHostPort, "%d", host_port); + if(cJSON_AddStringToObject(hostPort, "HostPort", dockerHostPort) == 0) { + log_error("could not create JSON object: HostPortString\n"); + cJSON_Delete(hostPort); + return NTS_ERR_FAILED; + } + + if(cJSON_AddStringToObject(hostPort, "HostIp", "0.0.0.0") == 0) { //or, future, bind to container->host_ip + log_error("could not create JSON object: HostIpString\n"); + cJSON_Delete(hostPort); + return NTS_ERR_FAILED; + } + + if(cJSON_AddItemToArray(port, hostPort) == 0) { + log_error("cJSON_AddItemToArray failed\n"); + cJSON_Delete(hostPort); + return NTS_ERR_FAILED; + } + + return NTS_ERR_OK; +} + +static int docker_populate_images(docker_context_t *context, int count, const char *min_version) { + assert(context); + assert(count); + assert(min_version); + + char url[512]; + sprintf(url, "http://v%s/images/json", framework_environment.settings.docker_engine_version); + + char *response = 0; + int rc = http_socket_request(url, DOCKER_SOCK_FNAME, "GET", "", 0, &response); + if(rc != NTS_ERR_OK) { + log_error("http_socket_request failed\n"); + return NTS_ERR_FAILED; + } + + cJSON *json_response = cJSON_Parse(response); + free(response); + if(json_response == 0) { + log_error("cJSON_Parse failed\n"); + return NTS_ERR_FAILED; + } + + cJSON *element; + cJSON_ArrayForEach(element, json_response) { + cJSON *tag = cJSON_GetObjectItem(element, "RepoTags"); + if(tag) { + cJSON *ctag; + cJSON_ArrayForEach(ctag, tag) { + char *tag_name = ctag->valuestring; //contains repo/image:tag + for(int i = 0; i < count; i++) { + char *s = strstr(tag_name, context[i].image); + if(s != 0) { + char *tag = s + strlen(context[i].image); + if(*tag == ':') { + tag = strdup(s + strlen(context[i].image) + 1); + } + else if(*tag == 0) { + tag = strdup(""); + } + else { + continue; + } + + if(nts_vercmp(tag, min_version) >= 0) { + char *repo = 0; + if(s != tag_name) { + repo = strdup(tag_name); + *(strstr(repo, context[i].image) - 1) = 0; + } + else { + repo = strdup(""); + } + + context[i].available_images = (docker_available_images_t *)realloc(context[i].available_images, (sizeof(docker_available_images_t) * (context[i].available_images_count + 1))); + context[i].available_images[context[i].available_images_count].repo = repo; + context[i].available_images[context[i].available_images_count].tag = tag; + context[i].available_images_count++; + } + else { + free(tag); + } + } + } + } + } + } + + cJSON_Delete(json_response); + + return NTS_ERR_OK; +} + +static int docker_container_create(const char *image, docker_container_t *container) { assert(image); - assert(instance); + assert(container); cJSON *postDataJson = cJSON_CreateObject(); if(cJSON_AddStringToObject(postDataJson, "Image", image) == 0) { - log_error("could not create JSON object: Image"); + log_error("could not create JSON object: Image\n"); return NTS_ERR_FAILED; } - if(cJSON_AddStringToObject(postDataJson, "Hostname", instance->name) == 0) { - log_error("could not create JSON object: Hostname"); + if(cJSON_AddStringToObject(postDataJson, "Hostname", container->name) == 0) { + log_error("could not create JSON object: Hostname\n"); cJSON_Delete(postDataJson); return NTS_ERR_FAILED; } cJSON *hostConfig = cJSON_CreateObject(); if(hostConfig == 0) { - log_error("could not create JSON object: HostConfig"); + log_error("could not create JSON object: HostConfig\n"); cJSON_Delete(postDataJson); return NTS_ERR_FAILED; } if(cJSON_AddItemToObject(postDataJson, "HostConfig", hostConfig) == 0) { - log_error("cJSON_AddItemToObject failed"); + log_error("cJSON_AddItemToObject failed\n"); cJSON_Delete(postDataJson); return NTS_ERR_FAILED; } @@ -549,70 +526,57 @@ static int docker_container_create(const char *image, manager_network_function_i return NTS_ERR_FAILED; } if(cJSON_AddItemToObject(hostConfig, "PortBindings", portBindings) == 0) { - log_error("cJSON_AddItemToObject failed"); + log_error("cJSON_AddItemToObject failed\n"); cJSON_Delete(postDataJson); return NTS_ERR_FAILED; } - for(int i = 0; i < (framework_environment.ssh_connections + framework_environment.tls_connections + framework_environment.ftp_connections + framework_environment.sftp_connections); ++i) { - cJSON *port = cJSON_CreateArray(); - if(port == 0) { - log_error("could not create JSON object: port"); - cJSON_Delete(postDataJson); - return NTS_ERR_FAILED; - } - - char dockerContainerPort[20]; - if(i < framework_environment.ssh_connections + framework_environment.tls_connections) { - sprintf(dockerContainerPort, "%d/tcp", STANDARD_NETCONF_PORT + i); - } - else if(i < (framework_environment.ssh_connections + framework_environment.tls_connections + framework_environment.ftp_connections)) { - sprintf(dockerContainerPort, "%d/tcp", STANDARD_FTP_PORT); - } - else if(i < (framework_environment.ssh_connections + framework_environment.tls_connections + framework_environment.ftp_connections + framework_environment.sftp_connections)) { - sprintf(dockerContainerPort, "%d/tcp", STANDARD_SFTP_PORT); - } - if(cJSON_AddItemToObject(portBindings, dockerContainerPort, port) == 0) { - log_error("cJSON_AddItemToObject failed"); - cJSON_Delete(postDataJson); - return NTS_ERR_FAILED; - } - - cJSON *hostPort = cJSON_CreateObject(); - if(hostPort == 0) { - log_error("could not create JSON object: HostPort"); + for(int i = 0; i < framework_environment.settings.ssh_connections; i++) { + if(docker_add_port(portBindings, container->docker_netconf_ssh_port + i, container->host_netconf_ssh_port + i) != NTS_ERR_OK) { + log_error("docker_add_port() failed\n"); cJSON_Delete(postDataJson); return NTS_ERR_FAILED; } + } - char dockerHostPort[20]; - sprintf(dockerHostPort, "%d", instance->host_port + i); - if(cJSON_AddStringToObject(hostPort, "HostPort", dockerHostPort) == 0) { - log_error("could not create JSON object: HostPortString"); + for(int i = 0; i < framework_environment.settings.tls_connections; i++) { + if(docker_add_port(portBindings, container->docker_netconf_tls_port + i, container->host_netconf_tls_port + i) != NTS_ERR_OK) { + log_error("docker_add_port() failed\n"); cJSON_Delete(postDataJson); return NTS_ERR_FAILED; } + } - if(cJSON_AddStringToObject(hostPort, "HostIp", "0.0.0.0") == 0) { //instance->host_ip - log_error("could not create JSON object: HostIpString"); + for(int i = 0; i < framework_environment.settings.ftp_connections; i++) { + if(docker_add_port(portBindings, container->docker_ftp_port + i, container->host_ftp_port + i) != NTS_ERR_OK) { + log_error("docker_add_port() failed\n"); cJSON_Delete(postDataJson); return NTS_ERR_FAILED; } + } - if(cJSON_AddItemToArray(port, hostPort) == 0) { - log_error("cJSON_AddItemToArray failed"); + for(int i = 0; i < framework_environment.settings.sftp_connections; i++) { + if(docker_add_port(portBindings, container->docker_sftp_port + i, container->host_sftp_port + i) != NTS_ERR_OK) { + log_error("docker_add_port() failed\n"); cJSON_Delete(postDataJson); return NTS_ERR_FAILED; } } - //environment vars start - asprintf(&docker_environment_var[4].value, "%d", instance->host_port); + asprintf(&docker_environment_var[4].value, "%d", container->host_netconf_ssh_port); + asprintf(&docker_environment_var[5].value, "%d", container->host_netconf_tls_port); + asprintf(&docker_environment_var[6].value, "%d", container->host_ftp_port); + asprintf(&docker_environment_var[7].value, "%d", container->host_sftp_port); cJSON *env_variables_array = cJSON_CreateArray(); if(env_variables_array == 0) { - log_error("Could not create JSON object: Env array"); + log_error("Could not create JSON object: Env array\n"); + cJSON_Delete(postDataJson); + free(docker_environment_var[4].value); + free(docker_environment_var[5].value); + free(docker_environment_var[6].value); + free(docker_environment_var[7].value); return NTS_ERR_FAILED; } cJSON_AddItemToObject(postDataJson, "Env", env_variables_array); @@ -624,7 +588,13 @@ static int docker_container_create(const char *image, manager_network_function_i cJSON *env_var_obj = cJSON_CreateString(environment_var); if(env_var_obj == 0) { - log_error("could not create JSON object"); + log_error("could not create JSON object\n"); + cJSON_Delete(postDataJson); + free(docker_environment_var[4].value); + free(docker_environment_var[5].value); + free(docker_environment_var[6].value); + free(docker_environment_var[7].value); + free(environment_var); return NTS_ERR_FAILED; } cJSON_AddItemToArray(env_variables_array, env_var_obj); @@ -634,9 +604,11 @@ static int docker_container_create(const char *image, manager_network_function_i } free(docker_environment_var[4].value); + free(docker_environment_var[5].value); + free(docker_environment_var[6].value); + free(docker_environment_var[7].value); //environment vars finished - cJSON *netMode = cJSON_Duplicate(docker_network_info, 1); cJSON_AddItemToObject(hostConfig, "NetworkMode", netMode); @@ -645,20 +617,20 @@ static int docker_container_create(const char *image, manager_network_function_i cJSON_Delete(postDataJson); char url[512]; - sprintf(url, "http:/v%s/containers/create?name=%s", framework_environment.docker_engine_version, instance->name); + sprintf(url, "http:/v%s/containers/create?name=%s", framework_environment.settings.docker_engine_version, container->name); char *response = 0; int response_code = 0; int rc = http_socket_request(url, DOCKER_SOCK_FNAME, "POST", post_data_string, &response_code, &response); free(post_data_string); if(rc != NTS_ERR_OK) { - log_error("http_socket_request failed"); + log_error("http_socket_request failed\n"); return NTS_ERR_FAILED; } if(response_code != 201) { char *message = docker_parse_json_message(response); - log_error("docker_container_create failed (%d): %s", response_code, message); + log_error("docker_container_create failed (%d): %s\n", response_code, message); free(message); free(response); return NTS_ERR_FAILED; @@ -675,7 +647,7 @@ static int docker_container_create(const char *image, manager_network_function_i memset(container_id_short, '\0', sizeof(container_id_short)); strncpy(container_id_short, container_id->valuestring, 12); - instance->docker_id = strdup(container_id_short); + container->id = strdup(container_id_short); cJSON_Delete(json_response); return NTS_ERR_OK; @@ -687,17 +659,17 @@ static int docker_container_create(const char *image, manager_network_function_i } } -static int docker_container_start(manager_network_function_instance_t *instance) { - assert(instance); +static int docker_container_start(docker_container_t *container) { + assert(container); char url[512]; - sprintf(url, "http://v%s/containers/%s/start", framework_environment.docker_engine_version, instance->docker_id); + sprintf(url, "http://v%s/containers/%s/start", framework_environment.settings.docker_engine_version, container->id); char *response = 0; int response_code = 0; int rc = http_socket_request(url, DOCKER_SOCK_FNAME, "POST", "", &response_code, &response); if(rc != NTS_ERR_OK) { - log_error("http_socket_request failed"); + log_error("http_socket_request failed\n"); return NTS_ERR_FAILED; } else { @@ -708,7 +680,7 @@ static int docker_container_start(manager_network_function_instance_t *instance) } else if(response_code != 204) { char *message = docker_parse_json_message(response); - log_error("docker_container_start failed (%d): %s", response_code, message); + log_error("docker_container_start failed (%d): %s\n", response_code, message); free(message); free(response); return NTS_ERR_FAILED; @@ -719,50 +691,51 @@ static int docker_container_start(manager_network_function_instance_t *instance) return NTS_ERR_OK; } -static int docker_container_inspect(manager_network_function_instance_t *instance) { - assert(instance); +static int docker_container_inspect(docker_container_t *container) { + assert(container); char url[512]; - sprintf(url, "http://v%s/containers/%s/json", framework_environment.docker_engine_version, instance->docker_id); + sprintf(url, "http://v%s/containers/%s/json", framework_environment.settings.docker_engine_version, container->id); char *response = 0; int rc = http_socket_request(url, DOCKER_SOCK_FNAME, "GET", "", 0, &response); if(rc != NTS_ERR_OK) { - log_error("http_socket_request failed"); + log_error("http_socket_request failed\n"); + free(response); return NTS_ERR_FAILED; } cJSON *json_response = cJSON_Parse(response); free(response); if(json_response == 0) { - log_error("cJSON_Parse failed"); + log_error("cJSON_Parse failed\n"); return NTS_ERR_FAILED; } cJSON *main_node = cJSON_GetObjectItem(json_response, "NetworkSettings"); if(main_node == 0) { - log_error("json parsing failed"); + log_error("json parsing failed\n"); cJSON_Delete(json_response); return NTS_ERR_FAILED; } cJSON *node = cJSON_GetObjectItem(main_node, "Networks"); if(node == 0) { - log_error("json parsing failed"); + log_error("json parsing failed\n"); cJSON_Delete(json_response); return NTS_ERR_FAILED; } node = node->child; //get info from the first in array if(node == 0) { - log_error("json parsing failed"); + log_error("json parsing failed\n"); cJSON_Delete(json_response); return NTS_ERR_FAILED; } cJSON *element; - if(framework_environment.ip_v6_enabled) { + if(framework_environment.settings.ip_v6_enabled) { element = cJSON_GetObjectItem(node, "GlobalIPv6Address"); } else { @@ -770,12 +743,12 @@ static int docker_container_inspect(manager_network_function_instance_t *instanc } if(element == 0) { - log_error("json parsing failed"); + log_error("json parsing failed\n"); cJSON_Delete(json_response); return NTS_ERR_FAILED; } - instance->docker_ip = strdup(element->valuestring); + container->docker_ip = strdup(element->valuestring); cJSON_Delete(json_response); return NTS_ERR_OK;