static ActivationStatus activate(GPtrArray *union_array, const ActivationMappingKey *key, GPtrArray *target_array, const gboolean dry_run, GHashTable *pids) { /* Retrieve the mapping from the union array */ ActivationMapping *actual_mapping = find_activation_mapping(union_array, key); /* First, activate all inter-dependency mappings */ if(actual_mapping->depends_on != NULL) { unsigned int i; ActivationStatus status; for(i = 0; i < actual_mapping->depends_on->len; i++) { ActivationMappingKey *dependency = g_ptr_array_index(actual_mapping->depends_on, i); status = activate(union_array, dependency, target_array, dry_run, pids); if(status != ACTIVATION_DONE) return status; /* If any of the inter-dependencies has not been activated yet, relay its status */ } } /* Finally, activate the mapping itself if it is not activated yet */ switch(actual_mapping->status) { case ACTIVATIONMAPPING_DEACTIVATED: { Target *target = find_target(target_array, actual_mapping->target); if(request_available_target_core(target)) /* Check if machine has any cores available, if not wait and try again later */ { gchar **arguments = generate_activation_arguments(target); /* Generate an array of key=value pairs from infrastructure properties */ unsigned int arguments_size = g_strv_length(arguments); /* Determine length of the activation arguments array */ gchar *interface = find_target_client_interface(target); pid_t pid; print_activation_step(TRUE, actual_mapping, arguments, arguments_size); /* Print debug message */ if(dry_run) pid = exec_true(); /* Execute dummy process */ else pid = exec_activate(interface, actual_mapping->target, actual_mapping->type, arguments, arguments_size, actual_mapping->service); /* Execute the activation operation asynchronously */ /* Cleanup */ g_strfreev(arguments); if(pid == -1) { g_printerr("[target: %s]: Cannot fork activation process of service: %s!\n", actual_mapping->target, actual_mapping->key); return ACTIVATION_ERROR; } else { gint *pidKey = g_malloc(sizeof(gint)); *pidKey = pid; actual_mapping->status = ACTIVATIONMAPPING_IN_PROGRESS; /* Mark activation mapping as in progress */ g_hash_table_insert(pids, pidKey, actual_mapping); /* Add mapping to the pids table so that we can retrieve its status later */ return ACTIVATION_IN_PROGRESS; } } else return ACTIVATION_WAIT; } case ACTIVATIONMAPPING_ACTIVATED: return ACTIVATION_DONE; case ACTIVATIONMAPPING_IN_PROGRESS: return ACTIVATION_IN_PROGRESS; default: return ACTIVATION_ERROR; /* Should never happen */ } }
static pid_t dry_run_deactivate_mapping(ActivationMapping *mapping, Target *target, gchar **arguments, const unsigned int arguments_length) { print_activation_step("Dry-run deactivating", mapping, arguments, arguments_length); /* Print debug message */ return exec_true(); /* Execute dummy process */ }
static int deactivate(GPtrArray *union_array, const ActivationMappingKey *key, GPtrArray *target_array, const gboolean dry_run, GHashTable *pids) { /* Retrieve the mapping from the union array */ ActivationMapping *actual_mapping = find_activation_mapping(union_array, key); /* Find all interdependent mapping on this mapping */ GPtrArray *interdependent_mappings = find_interdependent_mappings(union_array, actual_mapping); /* First deactivate all mappings which have an inter-dependency on this mapping */ unsigned int i; for(i = 0; i < interdependent_mappings->len; i++) { ActivationMapping *dependency_mapping = g_ptr_array_index(interdependent_mappings, i); ActivationStatus status = deactivate(union_array, (ActivationMappingKey*)dependency_mapping, target_array, dry_run, pids); if(status != ACTIVATION_DONE) { g_ptr_array_free(interdependent_mappings, TRUE); return status; /* If any inter-dependency is not deactivated, relay its status */ } } g_ptr_array_free(interdependent_mappings, TRUE); /* Finally deactivate the mapping itself if it has not been deactivated yet */ switch(actual_mapping->status) { case ACTIVATIONMAPPING_ACTIVATED: { Target *target = find_target(target_array, actual_mapping->target); if(target == NULL) { g_print("[target: %s]: Skip deactivation of service with key: %s deploying package: %s since machine is not present!\n", actual_mapping->key, actual_mapping->target, actual_mapping->service); actual_mapping->status = ACTIVATIONMAPPING_DEACTIVATED; return ACTIVATION_DONE; } else if(request_available_target_core(target)) { gchar **arguments = generate_activation_arguments(target); /* Generate an array of key=value pairs from infrastructure properties */ unsigned int arguments_size = g_strv_length(arguments); /* Determine length of the activation arguments array */ gchar *interface = find_target_client_interface(target); pid_t pid; print_activation_step(FALSE, actual_mapping, arguments, arguments_size); /* Print debug message */ if(dry_run) pid = exec_true(); /* Execute dummy process */ else pid = exec_deactivate(interface, actual_mapping->target, actual_mapping->type, arguments, arguments_size, actual_mapping->service); /* Execute the deactivation operation asynchronously */ /* Cleanup */ g_free(arguments); if(pid == -1) { g_printerr("[target: %s]: Cannot fork deactivation process of service: %s!\n", actual_mapping->target, actual_mapping->key); return ACTIVATION_ERROR; } else { gint *pidKey = g_malloc(sizeof(gint)); *pidKey = pid; actual_mapping->status = ACTIVATIONMAPPING_IN_PROGRESS; /* Mark activation mapping as in progress */ g_hash_table_insert(pids, pidKey, actual_mapping); /* Add mapping to the pids table so that we can retrieve its status later */ return ACTIVATION_IN_PROGRESS; } } else return ACTIVATION_WAIT; } case ACTIVATIONMAPPING_DEACTIVATED: return ACTIVATION_DONE; case ACTIVATIONMAPPING_IN_PROGRESS: return ACTIVATION_IN_PROGRESS; default: return ACTIVATION_ERROR; /* Should never happen */ } }