Only fetch VM InstanceView data when required (#2506)

* Only fetch VM InstanceView data when reuqired

* Missed one
This commit is contained in:
George Pollard 2022-10-12 15:34:27 +13:00 committed by GitHub
parent 7596cf4bd0
commit 0fab487d76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 22 deletions

View File

@ -1,7 +1,6 @@
using System.Threading.Tasks;
using ApiService.OneFuzzLib.Orm;
using Azure.Data.Tables;
using Azure.ResourceManager.Compute;
using Azure.ResourceManager.Compute.Models;
using Azure.Storage.Sas;
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;
@ -175,7 +174,13 @@ public class ProxyOperations : StatefulOrm<Proxy, VmState, ProxyOperations>, IPr
if (vmData != null) {
if (vmData.ProvisioningState == "Failed") {
return await SetProvisionFailed(proxy, vmData);
var failedVmData = await _context.VmOperations.GetVmWithInstanceView(vm.Name);
if (failedVmData is null) {
// this should exist since we just loaded the VM above
throw new InvalidOperationException("Unable to load instance-view data for VM");
}
return await SetProvisionFailed(proxy, failedVmData.InstanceView);
} else {
await SaveProxyConfig(proxy);
return await SetState(proxy, VmState.ExtensionsLaunch);
@ -207,8 +212,8 @@ public class ProxyOperations : StatefulOrm<Proxy, VmState, ProxyOperations>, IPr
}
}
private async System.Threading.Tasks.Task<Proxy> SetProvisionFailed(Proxy proxy, VirtualMachineData vmData) {
var errors = GetErrors(proxy, vmData).ToArray();
private async System.Threading.Tasks.Task<Proxy> SetProvisionFailed(Proxy proxy, VirtualMachineInstanceView? instanceView) {
var errors = GetErrors(proxy, instanceView).ToArray();
return await SetFailed(proxy, new Error(ErrorCode.PROXY_FAILED, errors));
}
@ -223,8 +228,7 @@ public class ProxyOperations : StatefulOrm<Proxy, VmState, ProxyOperations>, IPr
}
private static IEnumerable<string> GetErrors(Proxy proxy, VirtualMachineData vmData) {
var instanceView = vmData.InstanceView;
private static IEnumerable<string> GetErrors(Proxy proxy, VirtualMachineInstanceView? instanceView) {
yield return "provisioning failed";
if (instanceView is null) {
yield break;
@ -262,13 +266,18 @@ public class ProxyOperations : StatefulOrm<Proxy, VmState, ProxyOperations>, IPr
var config = await _context.ConfigOperations.Fetch();
var vm = GetVm(proxy, config);
var vmData = await _context.VmOperations.GetVm(vm.Name);
if (vmData is null) {
return await SetFailed(proxy, new Error(ErrorCode.PROXY_FAILED, new[] { "azure not able to find vm" }));
}
if (vmData.ProvisioningState == "Failed") {
return await SetProvisionFailed(proxy, vmData);
var failedVmData = await _context.VmOperations.GetVmWithInstanceView(vm.Name);
if (failedVmData is null) {
// this should exist since we just loaded the VM above
throw new InvalidOperationException("Unable to load instance-view data for VM");
}
return await SetProvisionFailed(proxy, failedVmData.InstanceView);
}
var ip = await _context.IpOperations.GetPublicIp(vmData.NetworkProfile.NetworkInterfaces[0].Id);

View File

@ -1,7 +1,7 @@
using System.Globalization;
using System.Threading.Tasks;
using ApiService.OneFuzzLib.Orm;
using Azure.ResourceManager.Compute;
using Azure.ResourceManager.Compute.Models;
namespace Microsoft.OneFuzz.Service;
@ -10,7 +10,7 @@ public interface IReproOperations : IStatefulOrm<Repro, VmState> {
public IAsyncEnumerable<Repro> SearchStates(IEnumerable<VmState>? states);
public Async.Task<Repro> SetFailed(Repro repro, VirtualMachineData vmData);
public Async.Task<Repro> SetFailed(Repro repro, VirtualMachineInstanceView instanceView);
public Async.Task<Repro> SetError(Repro repro, Error result);
@ -131,7 +131,13 @@ public class ReproOperations : StatefulOrm<Repro, VmState, ReproOperations>, IRe
var vmData = await _context.VmOperations.GetVm(vm.Name);
if (vmData != null) {
if (vmData.ProvisioningState == "Failed") {
return await _context.ReproOperations.SetFailed(repro, vmData);
var failedVmData = await _context.VmOperations.GetVmWithInstanceView(vm.Name);
if (failedVmData is null) {
// this should exist since we just loaded the VM above
throw new InvalidOperationException("Unable to fetch instance-view data for VM");
}
return await _context.ReproOperations.SetFailed(repro, failedVmData.InstanceView);
} else {
var scriptResult = await BuildReproScript(repro);
if (!scriptResult.IsOk) {
@ -181,7 +187,13 @@ public class ReproOperations : StatefulOrm<Repro, VmState, ReproOperations>, IRe
}
if (vmData.ProvisioningState == "Failed") {
return await _context.ReproOperations.SetFailed(repro, vmData);
var failedVmData = await _context.VmOperations.GetVmWithInstanceView(vm.Name);
if (failedVmData is null) {
// this should exist since we loaded the VM above
throw new InvalidOperationException("Unable to find instance-view data fro VM");
}
return await _context.ReproOperations.SetFailed(repro, failedVmData.InstanceView);
}
if (string.IsNullOrEmpty(repro.Ip)) {
@ -209,8 +221,8 @@ public class ReproOperations : StatefulOrm<Repro, VmState, ReproOperations>, IRe
return repro;
}
public async Async.Task<Repro> SetFailed(Repro repro, VirtualMachineData vmData) {
var errors = vmData.InstanceView.Statuses
public async Async.Task<Repro> SetFailed(Repro repro, VirtualMachineInstanceView instanceView) {
var errors = instanceView.Statuses
.Where(status => status.Level.HasValue && string.Equals(status.Level?.ToString(), "error", StringComparison.OrdinalIgnoreCase))
.Select(status => $"{status.Code} {status.DisplayStatus} {status.Message}")
.ToArray();

View File

@ -13,6 +13,8 @@ public interface IVmOperations {
Task<VirtualMachineData?> GetVm(string name);
Task<VirtualMachineData?> GetVmWithInstanceView(string name);
Async.Task<bool> Delete(Vm vm);
Async.Task<OneFuzzResultVoid> Create(Vm vm);
@ -65,22 +67,31 @@ public class VmOperations : IVmOperations {
}
public async Task<VirtualMachineData?> GetVm(string name) {
// _logTracer.Debug($"getting vm: {name}");
try {
var result = await _context.Creds.GetResourceGroupResource().GetVirtualMachineAsync(name, InstanceViewTypes.InstanceView);
if (result == null) {
var result = await _context.Creds.GetResourceGroupResource().GetVirtualMachineAsync(name);
if (result is null || !result.Value.HasData) {
return null;
}
if (result.Value.HasData) {
return result.Value.Data;
}
return result.Value.Data;
} catch (RequestFailedException) {
// _logTracer.Debug($"vm does not exist {ex});
// TODO: we shouldn't hide this error, only if it doesn't exist
return null;
}
}
return null;
public async Task<VirtualMachineData?> GetVmWithInstanceView(string name) {
try {
var result = await _context.Creds.GetResourceGroupResource().GetVirtualMachineAsync(name, InstanceViewTypes.InstanceView);
if (result is null || !result.Value.HasData) {
return null;
}
return result.Value.Data;
} catch (RequestFailedException) {
// TODO: we shouldn't hide this error, only if it doesn't exist
return null;
}
}
public async Async.Task<bool> Delete(Vm vm) {