in tools/gsnapshot/Runner.cs [204:338]
private void RollbackScheduled(Options options) {
if (!CheckProjectAndInstance(options)) {
return;
}
Dictionary<string, Dictionary<string, Tuple<ComputeData.Disk, ComputeData.Snapshot?>>>
snapshots = _snapshots
.GetScheduledSnapshotsForInstance(
options.Project, _instances.AllInstances[options.Instance])
.GetAwaiter()
.GetResult();
var rollbackInstance =
_instances.GetInstance(options.Project, _instances.AllInstances[options.Instance]);
Dictionary<string, string> allSnapshots = new Dictionary<string, string>();
_logger.LogInformation(
$"Found the following scheduled snapshots for {rollbackInstance.Name}:");
foreach (KeyValuePair<string,
Dictionary<string, Tuple<ComputeData.Disk, ComputeData.Snapshot?>>>
entry in snapshots) {
allSnapshots[entry.Key] = entry.Key;
_logger.LogInformation($" Snapshot ID: {entry.Key}");
int diskNameLength = 0, snapshotNameLength = 0, timestampLength = 0;
foreach (KeyValuePair<string, Tuple<ComputeData.Disk, ComputeData.Snapshot?>> disk in entry
.Value) {
string diskName = _utils.GetLastPart(disk.Key);
if (diskName.Length > diskNameLength) {
diskNameLength = diskName.Length;
}
if (disk.Value.Item2 != null) {
if (disk.Value.Item2.Name.Length > snapshotNameLength) {
snapshotNameLength = disk.Value.Item2.Name.Length;
}
string timestamp =
DateTimeOffset.Parse(disk.Value.Item2.CreationTimestamp).ToLocalTime().ToString();
if (timestamp.Length > timestampLength) {
timestampLength = timestamp.Length;
}
}
}
foreach (KeyValuePair<string, Tuple<ComputeData.Disk, ComputeData.Snapshot?>> disk in entry
.Value) {
string diskName = _utils.GetLastPart(disk.Key);
string _disk = String.Format("{0,-" + diskNameLength + "}", diskName);
if (disk.Value.Item2 != null && disk.Value.Item2.StorageBytes != null) {
string snapshotName = disk.Value.Item2.Name;
var size = ByteSize.FromBytes((double)disk.Value.Item2.StorageBytes);
string _snapshot = String.Format("{0,-" + snapshotNameLength + "}", snapshotName);
string timestamp = String.Format(
"{0,-" + timestampLength + "}",
DateTimeOffset.Parse(disk.Value.Item2.CreationTimestamp).ToLocalTime().ToString());
_logger.LogInformation(
$" Disk: {_disk} Snapshot: {_snapshot} Timestamp: {timestamp} Size: {size.ToString()}");
} else {
string _snapshot = String.Format("{0,-" + snapshotNameLength + "}", "N/A");
string timestamp = String.Format("{0,-" + timestampLength + "}", "N/A");
_logger.LogInformation(
$" Disk: {_disk} Snapshot: {_snapshot} Timestamp: {timestamp} Size: N/A");
}
}
}
string snapshotId = "";
if (!String.IsNullOrEmpty(options.ScheduledID)) {
if (snapshots.ContainsKey(options.ScheduledID)) {
_logger.LogInformation($"Rolling back to snapshot ID: {options.ScheduledID}");
snapshotId = options.ScheduledID;
} else {
_logger.LogCritical($"Unknown snapshot ID specified: {options.ScheduledID}");
System.Environment.Exit(11);
}
}
if (String.IsNullOrEmpty(snapshotId)) {
ReadLine.AutoCompletionHandler = new AutoCompletionHandler(allSnapshots);
var oldColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.White;
snapshotId = ReadLine.Read(
"Snapshot ID for rollback (empty for all, tab to autocomplete, ^C to cancel)> ");
Console.ForegroundColor = oldColor;
}
if (String.IsNullOrEmpty(snapshotId) || !snapshots.ContainsKey(snapshotId)) {
_logger.LogCritical($"Unknown snapshot ID specified: {snapshotId}");
System.Environment.Exit(11);
}
Dictionary<string, Tuple<ComputeData.Disk, ComputeData.Snapshot>> rollbacks =
new Dictionary<string, Tuple<ComputeData.Disk, ComputeData.Snapshot>>();
foreach (KeyValuePair<string, Tuple<ComputeData.Disk, ComputeData.Snapshot?>> entry in
snapshots[snapshotId]) {
rollbacks[entry.Key] =
new Tuple<ComputeData.Disk, ComputeData.Snapshot>(entry.Value.Item1, entry.Value.Item2);
}
Dictionary<string, ComputeData.Disk?> newDisks =
_disks
.CreateScheduledRollbackDisksAsync(options.Project,
_instances.AllInstances[options.Instance],
rollbacks, options.EraseVSS)
.GetAwaiter()
.GetResult();
_instances.CheckInstanceRunning(options.Project, _instances.AllInstances[options.Instance],
options.Stop, "rollback");
string snapshotPrefix = $"gsnapshot-scheduled-{snapshotId}";
bool done = _disks
.AttachNewDisksAsync(options.Project, snapshotPrefix,
_instances.AllInstances[options.Instance], newDisks)
.GetAwaiter()
.GetResult();
if (done) {
_logger.LogInformation($"Rollback finished for snapshot ID {snapshotId}!");
rollbackInstance =
_instances.GetInstance(options.Project, _instances.AllInstances[options.Instance]);
if (rollbackInstance.Status == "TERMINATED") {
bool startServer = options.Start;
if (!options.Start) {
_logger.LogWarning($"Instance is stopped, do you want to start it?");
startServer = _utils.GetYesNo("Start server (Y/n)?", true);
}
if (startServer) {
_logger.LogInformation($"Starting instance {rollbackInstance.Name}...");
bool serverStarted =
_instances.StartInstance(options.Project, _instances.AllInstances[options.Instance])
.GetAwaiter()
.GetResult();
}
}
} else {
_logger.LogWarning($"Rollback was not entirely completed.");
}
_logger.LogInformation("Instance rollback finished.");
}