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

Commit c8986aa

Browse files
Revert "Release 8.7.1 (hotfix) (#3459)" (#3468)
This reverts commit c69deed.
1 parent c69deed commit c8986aa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+872
-1389
lines changed

.devcontainer/devcontainer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"**/target/**": true
1414
},
1515
"lldb.executable": "/usr/bin/lldb",
16+
"dotnet.server.useOmnisharp": true,
1617
"omnisharp.enableEditorConfigSupport": true,
1718
"omnisharp.enableRoslynAnalyzers": true,
1819
"python.defaultInterpreterPath": "/workspaces/onefuzz/src/venv/bin/python",
@@ -48,4 +49,4 @@
4849
"features": {
4950
"ghcr.io/devcontainers/features/azure-cli:1": {}
5051
}
51-
}
52+
}

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,9 +542,11 @@ jobs:
542542
543543
mkdir -p artifacts/linux-libfuzzer
544544
mkdir -p artifacts/linux-libfuzzer-with-options
545+
mkdir -p artifacts/mariner-libfuzzer
545546
(cd libfuzzer ; make )
546547
cp -r libfuzzer/fuzz.exe libfuzzer/seeds artifacts/linux-libfuzzer
547548
cp -r libfuzzer/fuzz.exe libfuzzer/seeds artifacts/linux-libfuzzer-with-options
549+
cp -r libfuzzer/fuzz.exe libfuzzer/seeds artifacts/mariner-libfuzzer
548550
549551
mkdir -p artifacts/linux-libfuzzer-regression
550552
(cd libfuzzer-regression ; make )

CHANGELOG.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@ All notable changes to this project will be documented in this file.
77
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
88
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
99

10-
## 8.7.1
11-
12-
### Fixed
13-
14-
* Service: Removed deprecated Azure retention policy setting that was causing scaleset deployment errors [#3452](https://github.com/microsoft/onefuzz/pull/3452)
15-
1610
## 8.7.0
1711

1812
### Added

CURRENT_VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8.7.1
1+
8.7.0
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System.Text.Json;
2+
using Microsoft.Azure.Functions.Worker;
3+
using Microsoft.Extensions.Logging;
4+
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;
5+
namespace Microsoft.OneFuzz.Service.Functions;
6+
7+
8+
public class QueueJobResult {
9+
private readonly ILogger _log;
10+
private readonly IOnefuzzContext _context;
11+
12+
public QueueJobResult(ILogger<QueueJobResult> logTracer, IOnefuzzContext context) {
13+
_log = logTracer;
14+
_context = context;
15+
}
16+
17+
[Function("QueueJobResult")]
18+
public async Async.Task Run([QueueTrigger("job-result", Connection = "AzureWebJobsStorage")] string msg) {
19+
20+
var _tasks = _context.TaskOperations;
21+
var _jobs = _context.JobOperations;
22+
23+
_log.LogInformation("job result: {msg}", msg);
24+
var jr = JsonSerializer.Deserialize<TaskJobResultEntry>(msg, EntityConverter.GetJsonSerializerOptions()).EnsureNotNull($"wrong data {msg}");
25+
26+
var task = await _tasks.GetByTaskId(jr.TaskId);
27+
if (task == null) {
28+
_log.LogWarning("invalid {TaskId}", jr.TaskId);
29+
return;
30+
}
31+
32+
var job = await _jobs.Get(task.JobId);
33+
if (job == null) {
34+
_log.LogWarning("invalid {JobId}", task.JobId);
35+
return;
36+
}
37+
38+
JobResultData? data = jr.Data;
39+
if (data == null) {
40+
_log.LogWarning($"job result data is empty, throwing out: {jr}");
41+
return;
42+
}
43+
44+
var jobResultType = data.Type;
45+
_log.LogInformation($"job result data type: {jobResultType}");
46+
47+
Dictionary<string, double> value;
48+
if (jr.Value.Count > 0) {
49+
value = jr.Value;
50+
} else {
51+
_log.LogWarning($"job result data is empty, throwing out: {jr}");
52+
return;
53+
}
54+
55+
var jobResult = await _context.JobResultOperations.CreateOrUpdate(job.JobId, jobResultType, value);
56+
if (!jobResult.IsOk) {
57+
_log.LogError("failed to create or update with job result {JobId}", job.JobId);
58+
}
59+
}
60+
}

src/ApiService/ApiService/OneFuzzTypes/Model.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ public enum HeartbeatType {
3333
TaskAlive,
3434
}
3535

36+
[SkipRename]
37+
public enum JobResultType {
38+
NewCrashingInput,
39+
NoReproCrashingInput,
40+
NewReport,
41+
NewUniqueReport,
42+
NewRegressionReport,
43+
NewCoverage,
44+
NewCrashDump,
45+
CoverageData,
46+
RuntimeStats,
47+
}
48+
3649
public record HeartbeatData(HeartbeatType Type);
3750

3851
public record TaskHeartbeatEntry(
@@ -41,6 +54,16 @@ public record TaskHeartbeatEntry(
4154
Guid MachineId,
4255
HeartbeatData[] Data);
4356

57+
public record JobResultData(JobResultType Type);
58+
59+
public record TaskJobResultEntry(
60+
Guid TaskId,
61+
Guid? JobId,
62+
Guid MachineId,
63+
JobResultData Data,
64+
Dictionary<string, double> Value
65+
);
66+
4467
public record NodeHeartbeatEntry(Guid NodeId, HeartbeatData[] Data);
4568

4669
public record NodeCommandStopIfFree();
@@ -892,6 +915,27 @@ public record SecretAddress<T>(Uri Url) : ISecret<T> {
892915
public record SecretData<T>(ISecret<T> Secret) {
893916
}
894917

918+
public record JobResult(
919+
[PartitionKey][RowKey] Guid JobId,
920+
string Project,
921+
string Name,
922+
double NewCrashingInput = 0,
923+
double NoReproCrashingInput = 0,
924+
double NewReport = 0,
925+
double NewUniqueReport = 0,
926+
double NewRegressionReport = 0,
927+
double NewCrashDump = 0,
928+
double InstructionsCovered = 0,
929+
double TotalInstructions = 0,
930+
double CoverageRate = 0,
931+
double IterationCount = 0
932+
) : EntityBase() {
933+
public JobResult(Guid JobId, string Project, string Name) : this(
934+
JobId: JobId,
935+
Project: Project,
936+
Name: Name, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) { }
937+
}
938+
895939
public record JobConfig(
896940
string Project,
897941
string Name,
@@ -1056,6 +1100,7 @@ public record TaskUnitConfig(
10561100
string? InstanceTelemetryKey,
10571101
string? MicrosoftTelemetryKey,
10581102
Uri HeartbeatQueue,
1103+
Uri JobResultQueue,
10591104
Dictionary<string, string> Tags
10601105
) {
10611106
public Uri? inputQueue { get; set; }

src/ApiService/ApiService/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ public static async Async.Task Main() {
118118
.AddScoped<IVmOperations, VmOperations>()
119119
.AddScoped<ISecretsOperations, SecretsOperations>()
120120
.AddScoped<IJobOperations, JobOperations>()
121+
.AddScoped<IJobResultOperations, JobResultOperations>()
121122
.AddScoped<INsgOperations, NsgOperations>()
122123
.AddScoped<IScheduler, Scheduler>()
123124
.AddScoped<IConfig, Config>()

src/ApiService/ApiService/onefuzzlib/Config.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ private static BlobContainerSasPermissions ConvertPermissions(ContainerPermissio
7171
InstanceTelemetryKey: _serviceConfig.ApplicationInsightsInstrumentationKey,
7272
MicrosoftTelemetryKey: _serviceConfig.OneFuzzTelemetry,
7373
HeartbeatQueue: await _queue.GetQueueSas("task-heartbeat", StorageType.Config, QueueSasPermissions.Add) ?? throw new Exception("unable to get heartbeat queue sas"),
74+
JobResultQueue: await _queue.GetQueueSas("job-result", StorageType.Config, QueueSasPermissions.Add) ?? throw new Exception("unable to get heartbeat queue sas"),
7475
Tags: task.Config.Tags ?? new Dictionary<string, string>()
7576
);
7677

src/ApiService/ApiService/onefuzzlib/Extension.cs

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ public async Async.Task<IList<VMExtensionWrapper>> GenericExtensions(AzureLocati
3636
var extensions = new List<VMExtensionWrapper>();
3737

3838
var instanceConfig = await _context.ConfigOperations.Fetch();
39-
extensions.Add(await MonitorExtension(region, vmOs));
39+
if (vmOs == Os.Windows) {
40+
extensions.Add(await MonitorExtension(region));
41+
}
4042

4143
var depenency = DependencyExtension(region, vmOs);
4244
if (depenency is not null) {
@@ -329,37 +331,21 @@ public async Async.Task<VMExtensionWrapper> AgentConfig(AzureLocation region, Os
329331
throw new NotSupportedException($"unsupported OS: {vmOs}");
330332
}
331333

332-
public async Async.Task<VMExtensionWrapper> MonitorExtension(AzureLocation region, Os vmOs) {
334+
public async Async.Task<VMExtensionWrapper> MonitorExtension(AzureLocation region) {
333335
var settings = await _context.LogAnalytics.GetMonitorSettings();
334336
var extensionSettings = JsonSerializer.Serialize(new { WorkspaceId = settings.Id }, _extensionSerializerOptions);
335337
var protectedExtensionSettings = JsonSerializer.Serialize(new { WorkspaceKey = settings.Key }, _extensionSerializerOptions);
336-
if (vmOs == Os.Windows) {
337-
return new VMExtensionWrapper {
338-
Location = region,
339-
Name = "OMSExtension",
340-
TypePropertiesType = "MicrosoftMonitoringAgent",
341-
Publisher = "Microsoft.EnterpriseCloud.Monitoring",
342-
TypeHandlerVersion = "1.0",
343-
AutoUpgradeMinorVersion = true,
344-
Settings = new BinaryData(extensionSettings),
345-
ProtectedSettings = new BinaryData(protectedExtensionSettings),
346-
EnableAutomaticUpgrade = false
347-
};
348-
} else if (vmOs == Os.Linux) {
349-
return new VMExtensionWrapper {
350-
Location = region,
351-
Name = "OmsAgentForLinux",
352-
TypePropertiesType = "OmsAgentForLinux",
353-
Publisher = "Microsoft.EnterpriseCloud.Monitoring",
354-
TypeHandlerVersion = "1.0",
355-
AutoUpgradeMinorVersion = true,
356-
Settings = new BinaryData(extensionSettings),
357-
ProtectedSettings = new BinaryData(protectedExtensionSettings),
358-
EnableAutomaticUpgrade = false
359-
};
360-
} else {
361-
throw new NotSupportedException($"unsupported os: {vmOs}");
362-
}
338+
return new VMExtensionWrapper {
339+
Location = region,
340+
Name = "OMSExtension",
341+
TypePropertiesType = "MicrosoftMonitoringAgent",
342+
Publisher = "Microsoft.EnterpriseCloud.Monitoring",
343+
TypeHandlerVersion = "1.0",
344+
AutoUpgradeMinorVersion = true,
345+
Settings = new BinaryData(extensionSettings),
346+
ProtectedSettings = new BinaryData(protectedExtensionSettings),
347+
EnableAutomaticUpgrade = false
348+
};
363349
}
364350

365351

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
using ApiService.OneFuzzLib.Orm;
2+
using Microsoft.Extensions.Logging;
3+
using Polly;
4+
namespace Microsoft.OneFuzz.Service;
5+
6+
public interface IJobResultOperations : IOrm<JobResult> {
7+
8+
Async.Task<JobResult?> GetJobResult(Guid jobId);
9+
Async.Task<OneFuzzResultVoid> CreateOrUpdate(Guid jobId, JobResultType resultType, Dictionary<string, double> resultValue);
10+
11+
}
12+
public class JobResultOperations : Orm<JobResult>, IJobResultOperations {
13+
14+
public JobResultOperations(ILogger<JobResultOperations> log, IOnefuzzContext context)
15+
: base(log, context) {
16+
}
17+
18+
public async Async.Task<JobResult?> GetJobResult(Guid jobId) {
19+
return await SearchByPartitionKeys(new[] { jobId.ToString() }).SingleOrDefaultAsync();
20+
}
21+
22+
private JobResult UpdateResult(JobResult result, JobResultType type, Dictionary<string, double> resultValue) {
23+
24+
var newResult = result;
25+
double newValue;
26+
switch (type) {
27+
case JobResultType.NewCrashingInput:
28+
newValue = result.NewCrashingInput + resultValue["count"];
29+
newResult = result with { NewCrashingInput = newValue };
30+
break;
31+
case JobResultType.NewReport:
32+
newValue = result.NewReport + resultValue["count"];
33+
newResult = result with { NewReport = newValue };
34+
break;
35+
case JobResultType.NewUniqueReport:
36+
newValue = result.NewUniqueReport + resultValue["count"];
37+
newResult = result with { NewUniqueReport = newValue };
38+
break;
39+
case JobResultType.NewRegressionReport:
40+
newValue = result.NewRegressionReport + resultValue["count"];
41+
newResult = result with { NewRegressionReport = newValue };
42+
break;
43+
case JobResultType.NewCrashDump:
44+
newValue = result.NewCrashDump + resultValue["count"];
45+
newResult = result with { NewCrashDump = newValue };
46+
break;
47+
case JobResultType.CoverageData:
48+
double newCovered = resultValue["covered"];
49+
double newTotalCovered = resultValue["features"];
50+
double newCoverageRate = resultValue["rate"];
51+
newResult = result with { InstructionsCovered = newCovered, TotalInstructions = newTotalCovered, CoverageRate = newCoverageRate };
52+
break;
53+
case JobResultType.RuntimeStats:
54+
double newTotalIterations = resultValue["total_count"];
55+
newResult = result with { IterationCount = newTotalIterations };
56+
break;
57+
default:
58+
_logTracer.LogWarning($"Invalid Field {type}.");
59+
break;
60+
}
61+
_logTracer.LogInformation($"Attempting to log new result: {newResult}");
62+
return newResult;
63+
}
64+
65+
private async Async.Task<bool> TryUpdate(Job job, JobResultType resultType, Dictionary<string, double> resultValue) {
66+
var jobId = job.JobId;
67+
68+
var jobResult = await GetJobResult(jobId);
69+
70+
if (jobResult == null) {
71+
_logTracer.LogInformation("Creating new JobResult for Job {JobId}", jobId);
72+
73+
var entry = new JobResult(JobId: jobId, Project: job.Config.Project, Name: job.Config.Name);
74+
75+
jobResult = UpdateResult(entry, resultType, resultValue);
76+
77+
var r = await Insert(jobResult);
78+
if (!r.IsOk) {
79+
throw new InvalidOperationException($"failed to insert job result {jobResult.JobId}");
80+
}
81+
_logTracer.LogInformation("created job result {JobId}", jobResult.JobId);
82+
} else {
83+
_logTracer.LogInformation("Updating existing JobResult entry for Job {JobId}", jobId);
84+
85+
jobResult = UpdateResult(jobResult, resultType, resultValue);
86+
87+
var r = await Update(jobResult);
88+
if (!r.IsOk) {
89+
throw new InvalidOperationException($"failed to insert job result {jobResult.JobId}");
90+
}
91+
_logTracer.LogInformation("updated job result {JobId}", jobResult.JobId);
92+
}
93+
94+
return true;
95+
}
96+
97+
public async Async.Task<OneFuzzResultVoid> CreateOrUpdate(Guid jobId, JobResultType resultType, Dictionary<string, double> resultValue) {
98+
99+
var job = await _context.JobOperations.Get(jobId);
100+
if (job == null) {
101+
return OneFuzzResultVoid.Error(ErrorCode.INVALID_REQUEST, "invalid job");
102+
}
103+
104+
var success = false;
105+
try {
106+
_logTracer.LogInformation("attempt to update job result {JobId}", job.JobId);
107+
var policy = Policy.Handle<InvalidOperationException>().WaitAndRetryAsync(50, _ => new TimeSpan(0, 0, 5));
108+
await policy.ExecuteAsync(async () => {
109+
success = await TryUpdate(job, resultType, resultValue);
110+
_logTracer.LogInformation("attempt {success}", success);
111+
});
112+
return OneFuzzResultVoid.Ok;
113+
} catch (Exception e) {
114+
return OneFuzzResultVoid.Error(ErrorCode.UNABLE_TO_UPDATE, new string[] {
115+
$"Unexpected failure when attempting to update job result for {job.JobId}",
116+
$"Exception: {e}"
117+
});
118+
}
119+
}
120+
}
121+

src/ApiService/ApiService/onefuzzlib/OnefuzzContext.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public interface IOnefuzzContext {
1919
IExtensions Extensions { get; }
2020
IIpOperations IpOperations { get; }
2121
IJobOperations JobOperations { get; }
22+
IJobResultOperations JobResultOperations { get; }
2223
ILogAnalytics LogAnalytics { get; }
2324
INodeMessageOperations NodeMessageOperations { get; }
2425
INodeOperations NodeOperations { get; }
@@ -83,6 +84,7 @@ public OnefuzzContext(IServiceProvider serviceProvider) {
8384
public IVmOperations VmOperations => _serviceProvider.GetRequiredService<IVmOperations>();
8485
public ISecretsOperations SecretsOperations => _serviceProvider.GetRequiredService<ISecretsOperations>();
8586
public IJobOperations JobOperations => _serviceProvider.GetRequiredService<IJobOperations>();
87+
public IJobResultOperations JobResultOperations => _serviceProvider.GetRequiredService<IJobResultOperations>();
8688
public IScheduler Scheduler => _serviceProvider.GetRequiredService<IScheduler>();
8789
public IConfig Config => _serviceProvider.GetRequiredService<IConfig>();
8890
public ILogAnalytics LogAnalytics => _serviceProvider.GetRequiredService<ILogAnalytics>();

0 commit comments

Comments
 (0)