Don't log an error if we delete a Repro and it is already missing (#2563)

This commit is contained in:
George Pollard
2022-10-27 11:04:42 +13:00
committed by GitHub
parent 81e4b1542d
commit 9299357133
9 changed files with 41 additions and 29 deletions

View File

@ -114,7 +114,7 @@ public class ReproVmss {
var updatedRepro = vm with { State = VmState.Stopping }; var updatedRepro = vm with { State = VmState.Stopping };
var r = await _context.ReproOperations.Replace(updatedRepro); var r = await _context.ReproOperations.Replace(updatedRepro);
if (!r.IsOk) { if (!r.IsOk) {
_log.WithHttpStatus(r.ErrorV!).Error($"Failed to replace repro {updatedRepro.VmId:Tag:VmId}"); _log.WithHttpStatus(r.ErrorV).Error($"Failed to replace repro {updatedRepro.VmId:Tag:VmId}");
} }
var response = req.CreateResponse(HttpStatusCode.OK); var response = req.CreateResponse(HttpStatusCode.OK);

View File

@ -1,4 +1,5 @@
using System.Diagnostics; using System.Diagnostics;
using System.Net;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using Microsoft.ApplicationInsights; using Microsoft.ApplicationInsights;
@ -188,7 +189,7 @@ public interface ILogTracer {
ILogTracer WithTag(string k, string v); ILogTracer WithTag(string k, string v);
ILogTracer WithTags(IEnumerable<(string, string)>? tags); ILogTracer WithTags(IEnumerable<(string, string)>? tags);
ILogTracer WithHttpStatus((int, string) status); ILogTracer WithHttpStatus((HttpStatusCode Status, string Reason) result);
} }
internal interface ILogTracerInternal : ILogTracer { internal interface ILogTracerInternal : ILogTracer {
@ -252,8 +253,12 @@ public class LogTracer : ILogTracerInternal {
return WithTags(new[] { (k, v) }); return WithTags(new[] { (k, v) });
} }
public ILogTracer WithHttpStatus((int, string) status) { public ILogTracer WithHttpStatus((HttpStatusCode Status, string Reason) result) {
(string, string)[] tags = { ("StatusCode", status.Item1.ToString()), ("ReasonPhrase", status.Item2) }; (string, string)[] tags = {
("StatusCode", ((int)result.Status).ToString()),
("ReasonPhrase", result.Reason),
};
return WithTags(tags); return WithTags(tags);
} }

View File

@ -1,4 +1,5 @@
using System.Text.Json; using System.Net;
using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using ApiService.OneFuzzLib.Orm; using ApiService.OneFuzzLib.Orm;
using Azure; using Azure;
@ -10,7 +11,7 @@ namespace Microsoft.OneFuzz.Service;
public interface IAutoScaleOperations { public interface IAutoScaleOperations {
public Async.Task<ResultVoid<(int, string)>> Insert(AutoScale autoScale); public Async.Task<ResultVoid<(HttpStatusCode Status, string Reason)>> Insert(AutoScale autoScale);
public Async.Task<AutoScale?> GetSettingsForScaleset(Guid scalesetId); public Async.Task<AutoScale?> GetSettingsForScaleset(Guid scalesetId);

View File

@ -1,4 +1,5 @@
using System.Threading.Tasks; using System.Net;
using System.Threading.Tasks;
using ApiService.OneFuzzLib.Orm; using ApiService.OneFuzzLib.Orm;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
@ -32,7 +33,7 @@ public class ConfigOperations : Orm<InstanceConfig>, IConfigOperations {
public async Async.Task Save(InstanceConfig config, bool isNew = false, bool requireEtag = false) { public async Async.Task Save(InstanceConfig config, bool isNew = false, bool requireEtag = false) {
var newConfig = config with { InstanceName = _context.ServiceConfiguration.OneFuzzInstanceName ?? throw new Exception("Environment variable ONEFUZZ_INSTANCE_NAME is not set") }; var newConfig = config with { InstanceName = _context.ServiceConfiguration.OneFuzzInstanceName ?? throw new Exception("Environment variable ONEFUZZ_INSTANCE_NAME is not set") };
ResultVoid<(int, string)> r; ResultVoid<(HttpStatusCode Status, string Reason)> r;
if (isNew) { if (isNew) {
r = await Insert(newConfig); r = await Insert(newConfig);
if (!r.IsOk) { if (!r.IsOk) {

View File

@ -385,7 +385,7 @@ public class NodeOperations : StatefulOrm<Node, NodeState, NodeOperations>, INod
var node = new Node(poolName, machineId, poolId, version, ScalesetId: scaleSetId); var node = new Node(poolName, machineId, poolId, version, ScalesetId: scaleSetId);
ResultVoid<(int, string)> r; ResultVoid<(HttpStatusCode Status, string Reason)> r;
if (isNew) { if (isNew) {
try { try {
r = await Insert(node); r = await Insert(node);

View File

@ -1,4 +1,5 @@
using System.Globalization; using System.Globalization;
using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using ApiService.OneFuzzLib.Orm; using ApiService.OneFuzzLib.Orm;
using Azure.ResourceManager.Compute.Models; using Azure.ResourceManager.Compute.Models;
@ -111,9 +112,10 @@ public class ReproOperations : StatefulOrm<Repro, VmState, ReproOperations>, IRe
// BUG?: why are we updating repro and then deleting it and returning a new value // BUG?: why are we updating repro and then deleting it and returning a new value
repro = repro with { State = VmState.Stopped }; repro = repro with { State = VmState.Stopped };
var r = await Delete(repro); var r = await Delete(repro);
if (!r.IsOk) { if (!r.IsOk && r.ErrorV.Status != HttpStatusCode.NotFound) {
_logTracer.WithHttpStatus(r.ErrorV).Error($"failed to delete repro {repro.VmId:Tag:VmId} marked as stopped"); _logTracer.WithHttpStatus(r.ErrorV).Error($"failed to delete repro {repro.VmId:Tag:VmId} marked as stopped");
} }
return repro; return repro;
} }

View File

@ -1,4 +1,5 @@
using System.Threading.Tasks; using System.Net;
using System.Threading.Tasks;
using Azure; using Azure;
using Azure.Core; using Azure.Core;
using Azure.Data.Tables; using Azure.Data.Tables;
@ -69,7 +70,7 @@ public class VmssOperations : IVmssOperations {
var result = await r.DeleteAsync(WaitUntil.Started, forceDeletion: forceDeletion); var result = await r.DeleteAsync(WaitUntil.Started, forceDeletion: forceDeletion);
var raw = result.GetRawResponse(); var raw = result.GetRawResponse();
if (raw.IsError) { if (raw.IsError) {
_log.WithHttpStatus((raw.Status, raw.ReasonPhrase)).Error($"Failed to delete vmss: {name:Tag:VmssName}"); _log.WithHttpStatus(((HttpStatusCode)raw.Status, raw.ReasonPhrase)).Error($"Failed to delete vmss: {name:Tag:VmssName}");
return false; return false;
} else { } else {
return true; return true;

View File

@ -1,4 +1,5 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Azure; using Azure;
@ -14,10 +15,10 @@ namespace ApiService.OneFuzzLib.Orm {
IAsyncEnumerable<T> QueryAsync(string? filter = null); IAsyncEnumerable<T> QueryAsync(string? filter = null);
Task<T> GetEntityAsync(string partitionKey, string rowKey); Task<T> GetEntityAsync(string partitionKey, string rowKey);
Task<ResultVoid<(int, string)>> Insert(T entity); Task<ResultVoid<(HttpStatusCode Status, string Reason)>> Insert(T entity);
Task<ResultVoid<(int, string)>> Replace(T entity); Task<ResultVoid<(HttpStatusCode Status, string Reason)>> Replace(T entity);
Task<ResultVoid<(int, string)>> Update(T entity); Task<ResultVoid<(HttpStatusCode Status, string Reason)>> Update(T entity);
Task<ResultVoid<(int, string)>> Delete(T entity); Task<ResultVoid<(HttpStatusCode Status, string Reason)>> Delete(T entity);
Task<DeleteAllResult> DeleteAll(IEnumerable<(string?, string?)> keys); Task<DeleteAllResult> DeleteAll(IEnumerable<(string?, string?)> keys);
@ -62,34 +63,34 @@ namespace ApiService.OneFuzzLib.Orm {
/// Inserts the entity into table storage. /// Inserts the entity into table storage.
/// If successful, updates the ETag of the passed-in entity. /// If successful, updates the ETag of the passed-in entity.
public async Task<ResultVoid<(int, string)>> Insert(T entity) { public async Task<ResultVoid<(HttpStatusCode Status, string Reason)>> Insert(T entity) {
var tableClient = await GetTableClient(typeof(T).Name); var tableClient = await GetTableClient(typeof(T).Name);
var tableEntity = _entityConverter.ToTableEntity(entity); var tableEntity = _entityConverter.ToTableEntity(entity);
var response = await tableClient.AddEntityAsync(tableEntity); var response = await tableClient.AddEntityAsync(tableEntity);
if (response.IsError) { if (response.IsError) {
return ResultVoid<(int, string)>.Error((response.Status, response.ReasonPhrase)); return ResultVoid<(HttpStatusCode, string)>.Error(((HttpStatusCode)response.Status, response.ReasonPhrase));
} else { } else {
// update ETag // update ETag
entity.ETag = response.Headers.ETag; entity.ETag = response.Headers.ETag;
return ResultVoid<(int, string)>.Ok(); return ResultVoid<(HttpStatusCode, string)>.Ok();
} }
} }
public async Task<ResultVoid<(int, string)>> Replace(T entity) { public async Task<ResultVoid<(HttpStatusCode Status, string Reason)>> Replace(T entity) {
var tableClient = await GetTableClient(typeof(T).Name); var tableClient = await GetTableClient(typeof(T).Name);
var tableEntity = _entityConverter.ToTableEntity(entity); var tableEntity = _entityConverter.ToTableEntity(entity);
var response = await tableClient.UpsertEntityAsync(tableEntity, TableUpdateMode.Replace); var response = await tableClient.UpsertEntityAsync(tableEntity, TableUpdateMode.Replace);
if (response.IsError) { if (response.IsError) {
return ResultVoid<(int, string)>.Error((response.Status, response.ReasonPhrase)); return ResultVoid<(HttpStatusCode, string)>.Error(((HttpStatusCode)response.Status, response.ReasonPhrase));
} else { } else {
return ResultVoid<(int, string)>.Ok(); return ResultVoid<(HttpStatusCode, string)>.Ok();
} }
} }
public async Task<ResultVoid<(int, string)>> Update(T entity) { public async Task<ResultVoid<(HttpStatusCode Status, string Reason)>> Update(T entity) {
if (entity.ETag is null) { if (entity.ETag is null) {
throw new ArgumentException("ETag must be set when updating an entity", nameof(entity)); throw new ArgumentException("ETag must be set when updating an entity", nameof(entity));
} }
@ -99,9 +100,9 @@ namespace ApiService.OneFuzzLib.Orm {
var response = await tableClient.UpdateEntityAsync(tableEntity, entity.ETag.Value); var response = await tableClient.UpdateEntityAsync(tableEntity, entity.ETag.Value);
if (response.IsError) { if (response.IsError) {
return ResultVoid<(int, string)>.Error((response.Status, response.ReasonPhrase)); return ResultVoid<(HttpStatusCode, string)>.Error(((HttpStatusCode)response.Status, response.ReasonPhrase));
} else { } else {
return ResultVoid<(int, string)>.Ok(); return ResultVoid<(HttpStatusCode, string)>.Ok();
} }
} }
@ -118,14 +119,14 @@ namespace ApiService.OneFuzzLib.Orm {
return tableClient.GetTableClient(tableName); return tableClient.GetTableClient(tableName);
} }
public async Task<ResultVoid<(int, string)>> Delete(T entity) { public async Task<ResultVoid<(HttpStatusCode Status, string Reason)>> Delete(T entity) {
var tableClient = await GetTableClient(typeof(T).Name); var tableClient = await GetTableClient(typeof(T).Name);
var tableEntity = _entityConverter.ToTableEntity(entity); var tableEntity = _entityConverter.ToTableEntity(entity);
var response = await tableClient.DeleteEntityAsync(tableEntity.PartitionKey, tableEntity.RowKey); var response = await tableClient.DeleteEntityAsync(tableEntity.PartitionKey, tableEntity.RowKey);
if (response.IsError) { if (response.IsError) {
return ResultVoid<(int, string)>.Error((response.Status, response.ReasonPhrase)); return ResultVoid<(HttpStatusCode, string)>.Error(((HttpStatusCode)response.Status, response.ReasonPhrase));
} else { } else {
return ResultVoid<(int, string)>.Ok(); return ResultVoid<(HttpStatusCode, string)>.Ok();
} }
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net;
using Microsoft.OneFuzz.Service; using Microsoft.OneFuzz.Service;
using Xunit.Abstractions; using Xunit.Abstractions;
@ -48,7 +49,7 @@ sealed class TestLogTracer : ILogTracer {
_output.WriteLine($"[Warning] {message.ToString()}"); _output.WriteLine($"[Warning] {message.ToString()}");
} }
public ILogTracer WithHttpStatus((int, string) status) { public ILogTracer WithHttpStatus((HttpStatusCode Status, string Reason) result) {
return this; // TODO? return this; // TODO?
} }