gchar *determine_manifest_to_open(const gchar *old_manifest, const gchar *coordinator_profile_path, gchar *profile) { if(old_manifest == NULL) return determine_previous_manifest_file(coordinator_profile_path, profile); else return g_strdup(old_manifest); }
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; }
int restore(const gchar *manifest_file, const unsigned int max_concurrent_transfers, const int transfer_only, const int all, const gchar *old_manifest, const gchar *coordinator_profile_path, gchar *profile, const gboolean no_upgrade, const gchar *container_filter, const gchar *component_filter) { /* Generate a distribution array from the manifest file */ Manifest *manifest = open_provided_or_previous_manifest_file(manifest_file, coordinator_profile_path, profile, MANIFEST_SNAPSHOT_FLAG, container_filter, component_filter); if(manifest == NULL) { g_print("[coordinator]: Error while opening manifest file!\n"); return 1; } else { int exit_status; GPtrArray *snapshots_array; gchar *old_manifest_file; if(old_manifest == NULL) old_manifest_file = determine_previous_manifest_file(coordinator_profile_path, profile); else old_manifest_file = g_strdup(old_manifest); if(no_upgrade || old_manifest_file == NULL) { g_printerr("[coordinator]: Sending snapshots of all components...\n"); snapshots_array = manifest->snapshots_array; } else { GPtrArray *old_snapshots_array = create_snapshots_array(old_manifest_file, container_filter, component_filter); g_printerr("[coordinator]: Snapshotting state of moved components...\n"); snapshots_array = subtract_snapshot_mappings(manifest->snapshots_array, old_snapshots_array); delete_snapshots_array(old_snapshots_array); } if(send_snapshots(snapshots_array, manifest->target_array, max_concurrent_transfers, all) /* First, send the snapshots to the remote machines */ && (transfer_only || restore_services(snapshots_array, manifest->target_array))) /* Then, restore them on the remote machines */ exit_status = 0; else exit_status = 1; /* Cleanup */ g_free(old_manifest_file); if(!no_upgrade && old_manifest_file != NULL) g_ptr_array_free(snapshots_array, TRUE); delete_manifest(manifest); /* Return the exit status */ return exit_status; } }
Manifest *open_provided_or_previous_manifest_file(const gchar *manifest_file, const gchar *coordinator_profile_path, gchar *profile, const unsigned int flags, const gchar *container, const gchar *component) { if(manifest_file == NULL) { /* If no manifest file has been provided, try opening the last deployed one */ gchar *old_manifest_file = determine_previous_manifest_file(coordinator_profile_path, profile); if(old_manifest_file == NULL) return NULL; /* There is no previously deployed manifest */ else { /* Open the previously deployed manifest */ Manifest *manifest; g_printerr("[coordinator]: Using previous manifest: %s\n", old_manifest_file); manifest = create_manifest(old_manifest_file, flags, container, component); g_free(old_manifest_file); return manifest; } } else return create_manifest(manifest_file, flags, container, component); /* Open the provided manifest file */ }
int activate_system(const gchar *new_manifest, const gchar *old_manifest, const gchar *coordinator_profile_path, gchar *profile, const gboolean no_upgrade, const gboolean no_rollback, const gboolean dry_run) { Manifest *manifest = create_manifest(new_manifest, MANIFEST_ACTIVATION_FLAG, NULL, NULL); if(manifest == NULL) { g_printerr("[coordinator]: Error opening manifest file!\n"); return 1; } else { TransitionStatus status; gchar *old_manifest_file; GPtrArray *old_activation_mappings; /* If no previous configuration is given, check whether we have one in the coordinator profile, otherwise use the given one */ if(old_manifest == NULL) old_manifest_file = determine_previous_manifest_file(coordinator_profile_path, profile); else old_manifest_file = g_strdup(old_manifest); /* If we have an old configuration -> open it */ if(!no_upgrade && old_manifest_file != NULL) { g_print("[coordinator]: Doing an upgrade from previous manifest file: %s\n", old_manifest_file); old_activation_mappings = create_activation_array(old_manifest_file); } else { g_print("[coordinator]: Doing an installation from scratch\n"); old_activation_mappings = NULL; } /* Override SIGINT's behaviour to allow stuff to be rollbacked in case of an interruption */ set_flag_on_interrupt(); /* Execute transition */ g_print("[coordinator]: Executing the transition to the new deployment state\n"); if((status = transition(manifest->activation_array, old_activation_mappings, manifest->target_array, no_rollback, dry_run)) == TRANSITION_SUCCESS) g_printerr("[coordinator]: The new configuration has been successfully activated!\n"); else { g_printerr("[coordinator]: ERROR: Transition phase execution failed!\n"); if(old_manifest_file != NULL && status == TRANSITION_ROLLBACK_FAILED) { g_printerr("The rollback failed! This means the system is now inconsistent! Please\n"); g_printerr("manually diagnose the errors before doing another redeployment!\n\n"); g_printerr("When the problems have been solved, the rollback can be triggered again, by\n"); g_printerr("running:\n\n"); g_printerr("$ disnix-activate --no-rollback -p %s ", profile); if(coordinator_profile_path != NULL) g_printerr("--coordinator-profile-path %s ", coordinator_profile_path); g_printerr("-o %s %s\n\n", new_manifest, old_manifest_file); } } /* Cleanup */ g_free(old_manifest_file); delete_manifest(manifest); delete_activation_array(old_activation_mappings); /* Return the transition status */ return status; } }