int query_installed(gchar *interface, const gchar *target_property, gchar *infrastructure_expr, gchar *profile, OutputFormat format) { /* Retrieve an array of all target machines from the infrastructure expression */ GPtrArray *target_array = create_target_array(infrastructure_expr); if(target_array == NULL) { g_printerr("[coordinator]: Error retrieving targets from infrastructure model!\n"); return 1; } else { int success; /* Iterate over targets and capture their installed services */ GPtrArray *profile_manifest_target_array = g_ptr_array_new(); QueryInstalledServicesData data = { profile, profile_manifest_target_array }; ProcReact_FutureIterator iterator = create_target_future_iterator(target_array, target_property, interface, query_installed_services_on_target, complete_query_installed_services_on_target, &data); procreact_fork_in_parallel_buffer_and_wait(&iterator); success = target_iterator_has_succeeded(iterator.data); /* Print the captured configurations */ print_installed_services(&data, format); /* Cleanup */ destroy_target_future_iterator(&iterator); delete_profile_manifest_target_array(profile_manifest_target_array); delete_target_array(target_array); /* Return exit status */ return (!success); } }
int capture_manifest(gchar *interface, const gchar *target_property, gchar *infrastructure_expr, gchar *profile, const unsigned int max_concurrent_transfers) { /* Retrieve an array of all target machines from the infrastructure expression */ GPtrArray *target_array = create_target_array(infrastructure_expr); if(target_array == NULL) { g_printerr("[coordinator]: Error retrieving targets from infrastructure model!\n"); return 1; } else { GPtrArray *profile_manifest_target_array = g_ptr_array_new(); int exit_status; if(resolve_profiles(target_array, interface, target_property, profile, profile_manifest_target_array) && retrieve_profiles(interface, profile_manifest_target_array, max_concurrent_transfers)) { print_nix_expression_for_profile_manifest_target_array(profile_manifest_target_array); exit_status = 0; } else exit_status = 1; /* Cleanup */ delete_profile_manifest_target_array(profile_manifest_target_array); delete_target_array(target_array); /* Return exit status */ return exit_status; } }
int clean_snapshots(gchar *interface, const gchar *target_property, gchar *infrastructure_expr, int keep, gchar *container, gchar *component) { /* Retrieve an array of all target machines from the infrastructure expression */ GPtrArray *target_array = create_target_array(infrastructure_expr); if(target_array == NULL) { g_printerr("[coordinator]: Error retrieving targets from infrastructure model!\n"); return 1; } else { /* Iterate over all targets and run clean snapshots operation in parallel */ int success; CleanSnapshotsData data = { keep, container, component }; ProcReact_PidIterator iterator = create_target_pid_iterator(target_array, target_property, interface, clean_snapshots_on_target, complete_clean_snapshots_on_target, &data); procreact_fork_in_parallel_and_wait(&iterator); success = target_iterator_has_succeeded(iterator.data); /* Cleanup */ destroy_target_pid_iterator(&iterator); delete_target_array(target_array); /* Return the exit status, which is 0 if everything succeeds */ return (!success); } }
int lock_or_unlock(const int do_lock, const gchar *manifest_file, const gchar *coordinator_profile_path, gchar *profile) { GPtrArray *distribution_array; GPtrArray *target_array; int exit_status; if(manifest_file == NULL) { /* Get current username */ char *username = (getpwuid(geteuid()))->pw_name; /* If no manifest file has been provided, try opening the last deployed one */ gchar *old_manifest_file = determine_previous_manifest_file(coordinator_profile_path, username, profile); if(old_manifest_file == NULL) { g_printerr("[coordinator]: No previous manifest file exists, so no locking operations will be executed!\n"); return 0; } else { distribution_array = generate_distribution_array(old_manifest_file); target_array = generate_target_array(old_manifest_file); g_free(old_manifest_file); } } else { /* Open the provided manifest */ distribution_array = generate_distribution_array(manifest_file); target_array = generate_target_array(manifest_file); } if(distribution_array == NULL || target_array == NULL) { g_printerr("ERROR: Cannot open manifest file!\n"); exit_status = 1; } else { /* Override SIGINT's behaviour to allow stuff to be rollbacked in case of an interruption */ set_flag_on_interrupt(); /* Do the locking */ if(do_lock) exit_status = lock(distribution_array, target_array, profile); else exit_status = unlock(distribution_array, target_array, profile); } /* Cleanup */ delete_target_array(target_array); delete_distribution_array(distribution_array); /* Return exit status */ return exit_status; }
void delete_manifest(Manifest *manifest) { if(manifest != NULL) { delete_distribution_array(manifest->distribution_array); delete_activation_array(manifest->activation_array); delete_snapshots_array(manifest->snapshots_array); delete_target_array(manifest->target_array); g_free(manifest); } }
GPtrArray *generate_target_array(const gchar *manifest_file) { /* Declarations */ xmlDocPtr doc; xmlNodePtr node_root; xmlXPathObjectPtr result; GPtrArray *targets_array = NULL; /* Parse the XML document */ if((doc = xmlParseFile(manifest_file)) == NULL) { g_printerr("Error with parsing the manifest XML file!\n"); xmlCleanupParser(); return NULL; } /* Retrieve root element */ node_root = xmlDocGetRootElement(doc); if(node_root == NULL) { g_printerr("The manifest XML file is empty!\n"); xmlFreeDoc(doc); xmlCleanupParser(); return NULL; } /* Query the targets elements */ result = executeXPathQuery(doc, "/manifest/targets/target"); /* Iterate over all the targets elements and add them to the array */ if(result) { unsigned int i; xmlNodeSetPtr nodeset = result->nodesetval; /* Create a targets array */ targets_array = g_ptr_array_new(); /* Iterate over all the target elements */ for(i = 0; i < nodeset->nodeNr; i++) { xmlNodePtr targets_children = nodeset->nodeTab[i]->children; Target *target = (Target*)g_malloc(sizeof(Target)); gchar *system = NULL; gchar *client_interface = NULL; gchar *target_property = NULL; int num_of_cores = 0; int available_cores = 0; GPtrArray *properties = NULL; GPtrArray *containers = NULL; while(targets_children != NULL) { if(xmlStrcmp(targets_children->name, (xmlChar*) "system") == 0) system = duplicate_node_text(targets_children); else if(xmlStrcmp(targets_children->name, (xmlChar*) "clientInterface") == 0) client_interface = duplicate_node_text(targets_children); else if(xmlStrcmp(targets_children->name, (xmlChar*) "targetProperty") == 0) target_property = duplicate_node_text(targets_children); else if(xmlStrcmp(targets_children->name, (xmlChar*) "numOfCores") == 0) { gchar *num_of_cores_str = duplicate_node_text(targets_children); if(num_of_cores_str != NULL) { num_of_cores = atoi((char*)num_of_cores_str); available_cores = num_of_cores; g_free(num_of_cores_str); } } else if(xmlStrcmp(targets_children->name, (xmlChar*) "properties") == 0) { xmlNodePtr properties_children = targets_children->children; properties = g_ptr_array_new(); /* Iterate over all properties */ while(properties_children != NULL) { TargetProperty *target_property = (TargetProperty*)g_malloc(sizeof(TargetProperty)); target_property->name = g_strdup((gchar*)properties_children->name); target_property->value = duplicate_node_text(properties_children); g_ptr_array_add(properties, target_property); properties_children = properties_children->next; } /* Sort the target properties */ g_ptr_array_sort(properties, (GCompareFunc)compare_target_property); } else if(xmlStrcmp(targets_children->name, (xmlChar*) "containers") == 0) { xmlNodePtr container_children = targets_children->children; containers = g_ptr_array_new(); /* Iterate over all containers */ while(container_children != NULL) { Container *container = (Container*)g_malloc(sizeof(Container)); container->name = g_strdup((gchar*)container_children->name); if(container_children->children == NULL) container->properties = NULL; else { xmlNodePtr properties_children = container_children->children; GPtrArray *properties = g_ptr_array_new(); /* Iterate over all properties */ while(properties_children != NULL) { TargetProperty *target_property = (TargetProperty*)g_malloc(sizeof(TargetProperty)); target_property->name = g_strdup((gchar*)properties_children->name); target_property->value = duplicate_node_text(properties_children); g_ptr_array_add(properties, target_property); properties_children = properties_children->next; } /* Sort the target properties */ g_ptr_array_sort(properties, (GCompareFunc)compare_target_property); container->properties = properties; } g_ptr_array_add(containers, container); container_children = container_children->next; } /* Sort the containers */ g_ptr_array_sort(containers, (GCompareFunc)compare_container); } targets_children = targets_children->next; } target->system = system; target->client_interface = client_interface; target->target_property = target_property; target->num_of_cores = num_of_cores; target->available_cores = available_cores; target->properties = properties; target->containers = containers; if(target->system == NULL || target->client_interface == NULL || target->target_property == NULL) { /* Check if all mandatory properties have been provided */ g_printerr("A mandatory property seems to be missing. Have you provided a correct\n"); g_printerr("manifest file?\n"); delete_target_array(targets_array); targets_array = NULL; break; } else g_ptr_array_add(targets_array, target); /* Add target item to the targets array */ } /* Sort the targets array */ if(targets_array != NULL) g_ptr_array_sort(targets_array, (GCompareFunc)compare_target); /* Cleanup */ xmlXPathFreeObject(result); } /* Cleanup */ xmlFreeDoc(doc); xmlCleanupParser(); /* Sort the targets array */ if(targets_array != NULL) g_ptr_array_sort(targets_array, (GCompareFunc)compare_target); /* Return the targets array */ return targets_array; }
int graphcol(const char *services_xml, const char *infrastructure_xml) { GPtrArray *service_property_array = create_service_property_array(services_xml); GPtrArray *targets_array = create_target_array_from_xml(infrastructure_xml); GPtrArray *adjacency_array = g_ptr_array_new(); VertexAdjacency *max_adjacency = NULL; unsigned int i; int colored_vertices = 0; /* Create adjacency array */ for(i = 0; i < service_property_array->len; i++) { Service *current_service = g_ptr_array_index(service_property_array, i); ServiceProperty *dependsOn = find_service_property(current_service, "dependsOn"); VertexAdjacency *vertex_adjacency = (VertexAdjacency*)g_malloc(sizeof(VertexAdjacency)); vertex_adjacency->service = current_service->name; vertex_adjacency->adjacentServices = g_ptr_array_new(); if(dependsOn != NULL && dependsOn->value != NULL) { unsigned int j; gchar **dependencies = g_strsplit(dependsOn->value, " ", 0); for(j = 0; j < g_strv_length(dependencies) - 1; j++) g_ptr_array_add(vertex_adjacency->adjacentServices, dependencies[j]); g_free(dependencies); } vertex_adjacency->target = NULL; g_ptr_array_add(adjacency_array, vertex_adjacency); } /* Add interdependent services on given service to the adjacency array */ for(i = 0; i < service_property_array->len; i++) { Service *current_service = g_ptr_array_index(service_property_array, i); ServiceProperty *dependsOn = find_service_property(current_service, "dependsOn"); if(dependsOn != NULL && dependsOn->value != NULL) { unsigned int j; gchar **dependencies = g_strsplit(dependsOn->value, " ", 0); for(j = 0; j < g_strv_length(dependencies) - 1; j++) { VertexAdjacency *vertex_adjacency = find_vertex_adjacency_item(adjacency_array, dependencies[j]); g_ptr_array_add(vertex_adjacency->adjacentServices, current_service->name); } g_free(dependencies); } } /* Determine a vertex with max degree */ for(i = 0; i < adjacency_array->len; i++) { VertexAdjacency *current_adjacency = g_ptr_array_index(adjacency_array, i); if((max_adjacency == NULL) || (current_adjacency->adjacentServices->len > max_adjacency->adjacentServices->len)) max_adjacency = current_adjacency; } /* Color the max degree vertex with the first color */ max_adjacency->target = ((Target*)g_ptr_array_index(targets_array, 0))->name; colored_vertices++; while(colored_vertices < adjacency_array->len) { gchar *pickTarget = NULL; VertexAdjacency *max_saturation_adjacency = NULL; int maxSaturationDegree = 0; /* Determine the uncolored vertex with maximum saturation degree */ for(i = 0; i < adjacency_array->len; i++) { VertexAdjacency *current_adjacency = g_ptr_array_index(adjacency_array, i); unsigned int j; if(current_adjacency->target == NULL) { int saturationDegree = 0; for(j = 0; j < current_adjacency->adjacentServices->len; j++) { gchar *adjacentServiceName = g_ptr_array_index(current_adjacency->adjacentServices, j); VertexAdjacency *adjacentService = find_vertex_adjacency_item(adjacency_array, adjacentServiceName); if(adjacentService->target != NULL) saturationDegree++; } if((max_saturation_adjacency == NULL) || (saturationDegree > maxSaturationDegree)) { maxSaturationDegree = saturationDegree; max_saturation_adjacency = current_adjacency; } } } /* Color the vertex with max saturation degree, with the lowest available color */ /* Determine which colors are already used by the neighbours */ GPtrArray *used_targets = g_ptr_array_new(); for(i = 0; i < max_saturation_adjacency->adjacentServices->len; i++) { gchar *adjacentServiceName = g_ptr_array_index(max_saturation_adjacency->adjacentServices, i); VertexAdjacency *adjacentService = find_vertex_adjacency_item(adjacency_array, adjacentServiceName); if(adjacentService->target != NULL) g_ptr_array_add(used_targets, adjacentService->target); } /* Look in the targets array for the first target that is not in used targets (which we mean by the lowest color) */ for(i = 0; i < targets_array->len; i++) { unsigned int j; Target *current_target = g_ptr_array_index(targets_array, i); int exists = FALSE; for(j = 0; j < used_targets->len; j++) { gchar *current_used_target = g_ptr_array_index(used_targets, j); if(g_strcmp0(current_target->name, current_used_target) == 0) { exists = TRUE; break; } } if(!exists) { pickTarget = current_target->name; break; } } g_ptr_array_free(used_targets, TRUE); if(pickTarget == NULL) { g_printerr("Cannot pick a target for service: %s\n", max_saturation_adjacency->service); return 1; } else { max_saturation_adjacency->target = pickTarget; colored_vertices++; } } /* Print output expression */ g_print("{\n"); for(i = 0; i < adjacency_array->len; i++) { VertexAdjacency *current_adjacency = g_ptr_array_index(adjacency_array, i); if(current_adjacency->target == NULL) g_print(" %s = [];\n", current_adjacency->service); else g_print(" %s = [ \"%s\" ];\n", current_adjacency->service, current_adjacency->target); } g_print("}\n"); /* Cleanup */ delete_service_property_array(service_property_array); delete_target_array(targets_array); return 0; }