Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Only fetch VM InstanceView data when required #2506

Merged
merged 2 commits into from
Oct 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions src/ApiService/ApiService/onefuzzlib/ProxyOperations.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -175,7 +174,13 @@ public async Async.Task<Proxy> Init(Proxy proxy) {

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);
Expand Down Expand Up @@ -207,8 +212,8 @@ public async Async.Task<Proxy> Init(Proxy proxy) {
}
}

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));
}

Expand All @@ -223,8 +228,7 @@ private async Task<Proxy> SetFailed(Proxy proxy, Error error) {
}


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;
Expand Down Expand Up @@ -262,13 +266,18 @@ public async Task<Proxy> ExtensionsLaunch(Proxy proxy) {
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);
Expand Down
24 changes: 18 additions & 6 deletions src/ApiService/ApiService/onefuzzlib/ReproOperations.cs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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);

Expand Down Expand Up @@ -131,7 +131,13 @@ public async Async.Task<Repro> Init(Repro repro) {
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) {
Expand Down Expand Up @@ -181,7 +187,13 @@ public async Async.Task<Repro> ExtensionsLaunch(Repro repro) {
}

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)) {
Expand Down Expand Up @@ -209,8 +221,8 @@ await _context.ReproOperations.GetSetupContainer(repro)
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();
Expand Down
27 changes: 19 additions & 8 deletions src/ApiService/ApiService/onefuzzlib/VmOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -65,22 +67,31 @@ public async Async.Task<bool> HasComponents(string name) {
}

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;
}
}

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 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) {
Expand Down