1 /*************************************************************************
3 * Copyright 2020 highstreet technologies GmbH and others
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 ***************************************************************************/
21 #include "utils/log_utils.h"
22 #include "utils/sys_utils.h"
28 #include "core/framework.h"
29 #include "core/session.h"
30 #include "core/xpath.h"
32 static manager_operation_t *manager_operations;
33 static pthread_mutex_t manager_operations_mutex;
34 static sem_t manager_operations_sem;
36 manager_protocol_type_t manager_port[65536];
38 static int manager_operations_execute(manager_operation_t *oper);
40 int manager_operations_init(void) {
41 manager_operations = 0;
42 if(pthread_mutex_init(&manager_operations_mutex, NULL) != 0) {
43 log_error("mutex init has failed\n");
44 return NTS_ERR_FAILED;
47 if(sem_init(&manager_operations_sem, 0, 0) != 0) {
48 log_error("sem init has failed\n");
49 return NTS_ERR_FAILED;
52 //checkAL ar fi misto sa stim ce porturi sunt si ce porturi nu sunt available...
53 for(int i = 0; i < 1000; i++) {
54 manager_port[i] = MANAGER_PROTOCOL_UNAVAILABLE;
57 for(int i = 1000; i < 65536; i++) {
58 manager_port[i] = MANAGER_PROTOCOL_UNUSED;
64 void manager_operations_loop(void) {
68 clock_gettime(CLOCK_REALTIME, &ts);
71 if(sem_timedwait(&manager_operations_sem, &ts) == 0) {
74 rc = sr_lock(session_running, NTS_MANAGER_MODULE);
85 log_error("sr_lock failed\n");
86 //checkAL ce facem acum ?
89 pthread_mutex_lock(&manager_operations_mutex);
91 const char *status = "SUCCESS";
95 while(manager_operations) {
96 //pop operation from list
97 manager_operation_t *oper = manager_operations;
98 manager_operations = manager_operations->next;
100 //if operation is RPC first update any *other* fields
102 rc = manager_operations_execute(oper);
103 if(rc != NTS_ERR_OK) {
104 log_error("manager_operations_execute failed\n");
106 strcpy(errmsg, oper->errmsg);
107 manager_operations_free_oper(oper);
111 manager_operations_free_oper(oper);
114 for(int i = 0; i < docker_context_count; i++) {
115 //do any reconfig necesarry
116 for(int j = 0; j < manager_context[i].started_instances; j++) {
117 if(manager_context[i].instance[j].is_configured == false) {
118 rc = manager_actions_config_instance(&manager_context[i], &manager_context[i].instance[j]);
119 if(rc != NTS_ERR_OK) {
120 status = "reconfig FAILED";
121 sprintf(errmsg, "reconfig FAILED - instance %s", manager_context[i].instance[j].container.name);
122 log_error("%s\n", errmsg);
128 rc = manager_sr_on_last_operation_status(status, errmsg);
129 if(rc != NTS_ERR_OK) {
130 log_error("manager_sr_on_last_operation_status failed\n");
133 pthread_mutex_unlock(&manager_operations_mutex);
134 rc = sr_unlock(session_running, NTS_MANAGER_MODULE); //release datastore
135 if(rc != SR_ERR_OK) {
136 log_error("sr_unlock failed\n");
141 void manager_operations_free(void) {
142 //terminate all containers
143 for(int i = 0; i < docker_context_count; i++) {
144 while(manager_context[i].started_instances) {
145 manager_actions_stop(&manager_context[i]);
149 sem_destroy(&manager_operations_sem);
150 pthread_mutex_destroy(&manager_operations_mutex);
153 manager_operation_t *manager_operations_new_oper(manager_operation_type_t type) {
154 manager_operation_t *new_oper = malloc(sizeof(manager_operation_t));
156 log_error("malloc failed\n");
160 new_oper->type = type;
162 new_oper->ft_index = -1;
163 new_oper->function_type = 0;
165 new_oper->started_instances = -1;
166 new_oper->mounted_instances = -1;
168 new_oper->docker_instance_name = 0;
169 new_oper->docker_version_tag = 0;
170 new_oper->docker_repository = 0;
172 new_oper->mount_point_addressing_method = 0;
174 new_oper->fault_generation.delay_period = 0;
175 new_oper->fault_generation.delay_period_count = -1;
177 new_oper->netconf.faults_enabled = -1;
178 new_oper->netconf.call_home = -1;
180 new_oper->ves.faults_enabled = -1;
181 new_oper->ves.pnf_registration = -1;
182 new_oper->ves.heartbeat_period = -1;
184 new_oper->errmsg = 0;
190 int manager_operations_free_oper(manager_operation_t *oper) {
193 free(oper->function_type);
194 free(oper->docker_instance_name);
195 free(oper->docker_repository);
196 free(oper->docker_version_tag);
197 free(oper->mount_point_addressing_method);
204 int manager_operations_begin(void) {
205 return pthread_mutex_lock(&manager_operations_mutex);
208 int manager_operations_add(manager_operation_t *oper) {
211 if(manager_operations == 0) {
212 manager_operations = oper;
215 manager_operation_t *h = manager_operations;
225 void manager_operations_finish_and_execute(void) {
226 pthread_mutex_unlock(&manager_operations_mutex);
227 sem_post(&manager_operations_sem);
230 void manager_operations_finish_with_error(void) {
231 while(manager_operations) {
232 manager_operation_t *h = manager_operations->next;
233 manager_operations_free_oper(manager_operations);
234 manager_operations = h;
236 pthread_mutex_unlock(&manager_operations_mutex);
237 sem_post(&manager_operations_sem);
242 int manager_operations_validate(manager_operation_t *oper) {
245 //prepopulate unset values
246 if(oper->docker_instance_name == 0) {
247 oper->docker_instance_name = strdup(manager_context[oper->ft_index].docker_instance_name);
250 if(oper->docker_repository == 0) {
251 oper->docker_repository = strdup(manager_context[oper->ft_index].docker_repository);
254 if(oper->docker_version_tag == 0) {
255 oper->docker_version_tag = strdup(manager_context[oper->ft_index].docker_version_tag);
258 if(oper->started_instances == -1) {
259 oper->started_instances = manager_context[oper->ft_index].started_instances;
262 if(oper->mounted_instances == -1) {
263 oper->mounted_instances = manager_context[oper->ft_index].mounted_instances;
266 //check docker image if exists
268 for(int i = 0; i < docker_context[oper->ft_index].available_images_count; i++) {
269 if(strcmp(docker_context[oper->ft_index].available_images[i].repo, oper->docker_repository) == 0) {
270 if(strcmp(docker_context[oper->ft_index].available_images[i].tag, oper->docker_version_tag) == 0) {
278 log_error("could not find image: %s/%s:%s\n", oper->docker_repository, docker_context[oper->ft_index].image, oper->docker_version_tag);
279 return NTS_ERR_FAILED;
285 static int manager_operations_execute(manager_operation_t *oper) {
288 int k = oper->ft_index;
291 //operation --> actions
292 if(manager_context[k].started_instances > oper->started_instances) {
294 while(manager_context[k].started_instances > oper->started_instances) {
296 rc = manager_actions_stop(&manager_context[k]);
297 if(rc != NTS_ERR_OK) {
298 asprintf(&oper->errmsg, "stop FAILED - function-type %s", manager_context[k].function_type);
299 log_error("%s\n", oper->errmsg);
301 return NTS_ERR_FAILED;
304 rc = manager_sr_update_context(&manager_context[k]);
305 if(rc != NTS_ERR_OK) {
306 log_error("manager_sr_update_context failed\n");
311 else if(manager_context[k].started_instances < oper->started_instances) {
313 while(manager_context[k].started_instances < oper->started_instances) {
315 rc = manager_actions_start(&manager_context[k]);
316 if(rc != NTS_ERR_OK) {
317 asprintf(&oper->errmsg, "start FAILED - function-type %s", manager_context[k].function_type);
318 log_error("%s\n", oper->errmsg);
319 return NTS_ERR_FAILED;
322 rc = manager_sr_update_context(&manager_context[k]);
323 if(rc != NTS_ERR_OK) {
324 log_error("manager_sr_update_context failed\n");
327 rc = manager_actions_config_instance(&manager_context[k], &manager_context[k].instance[manager_context[k].started_instances - 1]);
328 if(rc != NTS_ERR_OK) {
329 asprintf(&oper->errmsg, "config FAILED - instance %s", manager_context[k].instance[manager_context[k].started_instances - 1].container.name);
330 log_error("%s\n", oper->errmsg);
335 if(manager_context[k].mounted_instances > oper->mounted_instances) {
337 while(manager_context[k].mounted_instances > oper->mounted_instances) {
338 rc = manager_actions_unmount(&manager_context[k]);
339 if(rc != NTS_ERR_OK) {
340 asprintf(&oper->errmsg, "unmount FAILED - instance %s", manager_context[k].instance[manager_context[k].mounted_instances - 1].container.name);
341 log_error("%s\n", oper->errmsg);
342 return NTS_ERR_FAILED;
345 rc = manager_sr_update_context(&manager_context[k]);
346 if(rc != NTS_ERR_OK) {
347 log_error("manager_sr_update_context failed\n");
352 else if(manager_context[k].mounted_instances < oper->mounted_instances) {
354 while(manager_context[k].mounted_instances < oper->mounted_instances) {
355 rc = manager_actions_mount(&manager_context[k]);
356 if(rc != NTS_ERR_OK) {
357 asprintf(&oper->errmsg, "mount FAILED - instance %s", manager_context[k].instance[manager_context[k].mounted_instances].container.name);
358 log_error("%s\n", oper->errmsg);
359 return NTS_ERR_FAILED;
362 rc = manager_sr_update_context(&manager_context[k]);
363 if(rc != NTS_ERR_OK) {
364 log_error("manager_sr_update_context failed\n");