in tools/gsnapshot/Disks.cs [100:220]
public async Task<ComputeData.Disk?> _CreateDiskFromSnapshotAsync(
string projectId, string diskName, ComputeData.Disk originalDisk,
ComputeData.Snapshot snapshot, string snapshotDiskType, bool eraseVss) {
ComputeBetaData.Disk requestBody = new ComputeBetaData.Disk();
string diskType = _utils.GetLastPartN(originalDisk.Type, 4);
bool regional = (diskType == "regions" ? true : false);
requestBody.Name = diskName;
requestBody.SourceSnapshot = snapshot.SelfLink;
requestBody.Description = originalDisk.Description;
requestBody.SizeGb = snapshot.DiskSizeGb;
// Attempting to restore a 0 length snapshot means it can't have VSS signature
requestBody.EraseWindowsVssSignature = eraseVss;
if (!regional) {
requestBody.Type =
$"projects/{projectId}/zones/{_utils.GetLastPart(originalDisk.Zone)}/diskTypes/{snapshotDiskType}";
} else {
requestBody.Type =
$"projects/{projectId}/regions/{_utils.GetLastPart(originalDisk.Region)}/diskTypes/{snapshotDiskType}";
requestBody.ReplicaZones = originalDisk.ReplicaZones;
}
if (originalDisk.GuestOsFeatures != null) {
requestBody.GuestOsFeatures = new List<ComputeBetaData.GuestOsFeature>();
foreach (ComputeData.GuestOsFeature feature in originalDisk.GuestOsFeatures) {
ComputeBetaData.GuestOsFeature betaFeature = new ComputeBetaData.GuestOsFeature();
betaFeature.Type = feature.Type;
betaFeature.ETag = feature.ETag;
requestBody.GuestOsFeatures.Add(betaFeature);
}
}
requestBody.Labels = originalDisk.Labels;
requestBody.ResourcePolicies = originalDisk.ResourcePolicies;
if (originalDisk.Labels == null) {
requestBody.Labels = new Dictionary<string, string>();
} else {
requestBody.Labels = originalDisk.Labels;
}
requestBody.Labels["gsnapshot"] = snapshot.Name;
if (!regional) {
string zone = _utils.GetLastPart(originalDisk.Zone);
_logger.LogInformation(
$"Creating new zonal disk {diskName} in {zone} from snapshot {snapshot.Name}...");
ComputeBeta.DisksResource.InsertRequest request =
betaComputeService.Disks.Insert(requestBody, projectId, zone);
ComputeBetaData.Operation response = await request.ExecuteAsync();
bool operationCompleted = false;
if (!eraseVss) {
bool done = await _operations.WaitForOperation(projectId, Operations.ZONE, zone,
_utils.GetLastPart(response.SelfLink));
if (done) {
operationCompleted = true;
}
} else {
string done = await _operations.WaitOrFailForOperation(
projectId, Operations.ZONE, zone, _utils.GetLastPart(response.SelfLink));
if (done == "INTERNAL_ERROR") // Disk probably didn't have a VSS signature
{
_logger.LogDebug(
"Disk creation resulted in internal error, will retry with VSS signature erasing turned off...");
requestBody.EraseWindowsVssSignature = false;
request = betaComputeService.Disks.Insert(requestBody, projectId, zone);
response = await request.ExecuteAsync();
done = await _operations.WaitOrFailForOperation(projectId, Operations.ZONE, zone,
_utils.GetLastPart(response.SelfLink));
}
if (done == "") {
operationCompleted = true;
}
}
if (operationCompleted) {
var disk = await GetDiskAsync(projectId, zone, diskName);
return disk;
} else {
_logger.LogCritical(
$"Failed to create a zonal new disk, operation {response.SelfLink} failed to complete.");
return null;
}
} else {
string region = _utils.GetLastPart(originalDisk.Region);
_logger.LogInformation(
$"Creating new regional disk {diskName} in {region} from snapshot {snapshot.Name}...");
ComputeBeta.RegionDisksResource.InsertRequest request =
betaComputeService.RegionDisks.Insert(requestBody, projectId, region);
ComputeBetaData.Operation response = await request.ExecuteAsync();
bool operationCompleted = false;
if (!eraseVss) {
bool done = await _operations.WaitForOperation(projectId, Operations.REGION, region,
_utils.GetLastPart(response.SelfLink));
if (done) {
operationCompleted = true;
}
} else {
string done = await _operations.WaitOrFailForOperation(
projectId, Operations.REGION, region, _utils.GetLastPart(response.SelfLink));
if (done == "INTERNAL_ERROR") // Disk probably didn't have a VSS signature
{
_logger.LogDebug(
"Disk creation resulted in internal error, will retry with VSS signature erasing turned off...");
requestBody.EraseWindowsVssSignature = false;
request = betaComputeService.RegionDisks.Insert(requestBody, projectId, region);
response = await request.ExecuteAsync();
done = await _operations.WaitOrFailForOperation(projectId, Operations.REGION, region,
_utils.GetLastPart(response.SelfLink));
}
if (done == "") {
operationCompleted = true;
}
}
if (operationCompleted) {
var disk = await GetRegionalDiskAsync(projectId, region, diskName);
return disk;
} else {
_logger.LogCritical(
$"Failed to create a new regional disk, operation {response.SelfLink} failed to complete.");
return null;
}
}
}