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

Add extra_output container, rename extra container #3064

Merged
merged 40 commits into from
Jun 15, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
5e75ffa
Adding "extra_rw" container
Porges Apr 26, 2023
fd37bcb
Fix test failure
Porges Apr 26, 2023
17888b5
Remove dead code, format
Porges Apr 26, 2023
3ff5b38
Regenerate webhook_events.md
Porges Apr 26, 2023
bfee092
format fix
Porges Apr 26, 2023
8679e41
Reindent file
Porges Apr 26, 2023
ef375c3
Slight refactoring
Porges Apr 27, 2023
c70f8b1
Rename the extra container to extra_setup
Porges May 21, 2023
d841856
Rename extra_rw to extra_synced
Porges May 21, 2023
f663756
Reformat
Porges May 22, 2023
2caecba
Implement syncing in common code
Porges May 22, 2023
09c0699
Fix container name
Porges May 22, 2023
e7bba39
Add to expand places
Porges May 23, 2023
01ae18b
Add to libfuzzer expand
Porges May 23, 2023
a44b537
Fix renaming of extra_setup_url
Porges May 23, 2023
36b8531
Capture more info when IPC times out
Porges May 23, 2023
315c1c1
More information about bad config
Porges May 23, 2023
e91fa3a
doh.
Porges May 23, 2023
293b22c
Remove TODO
Porges May 23, 2023
a8ef068
Rename extra-synced to extra-output
Porges May 24, 2023
e518dde
Update docs
Porges May 24, 2023
322a430
Merge branch 'main' into extra-rw-container
Porges May 24, 2023
d64fea4
Merge branch 'main' into extra-rw-container
Porges May 24, 2023
3d63b6d
Merge branch 'main' into extra-rw-container
Porges May 26, 2023
1b1f54c
Undo structification
Porges May 28, 2023
b1ef14f
Merge branch 'main' into extra-rw-container
Porges May 29, 2023
f1c37d8
Factor out build_job
Porges May 30, 2023
2b93c70
Merge branch 'main' into extra-rw-container
Porges May 31, 2023
c923af1
Merge branch 'main' into extra-rw-container
Porges Jun 5, 2023
ee43b8d
cargo fmt
Porges Jun 6, 2023
1255745
Merge branch 'main' into extra-rw-container
Porges Jun 6, 2023
39c7e47
Merge branch 'main' into extra-rw-container
Porges Jun 7, 2023
84f0bc3
Merge branch 'main' into extra-rw-container
Porges Jun 8, 2023
969b49f
Somewhat-hacky integration test
Porges Jun 8, 2023
89dcc40
Fix types
Porges Jun 8, 2023
5781e6b
Rename Rust config to match C# config
Porges Jun 11, 2023
3dfd6cc
Merge branch 'main' into extra-rw-container
Porges Jun 11, 2023
eefc8be
Merge branch 'main' into extra-rw-container
Porges Jun 14, 2023
6b45dda
Merge branch 'main' into extra-rw-container
Porges Jun 14, 2023
6ec83ae
Merge branch 'main' into extra-rw-container
Porges Jun 15, 2023
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
3 changes: 2 additions & 1 deletion docs/command-replacements.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ The following values are replaced with the specific values at runtime.
* `{crashes_container}`: Container name for the `crashes` container
* `{microsoft_telemetry_key}`: Application Insights key used for collecting [non-attributable telemetry](telemetry.md) to improve OneFuzz.
* `{instance_telemetry_key}`: Application Insights key used for private, instance-owned telemetry and logging (See [OneFuzz Telemetry](telemetry.md).
* `{extra_dir}`: Path to the optionally provided `extra` directory
* `{extra_setup_dir}`: Path to the optionally provided `extra_setup` directory
* `{extra_output_dir}`: Path to the optionally provided `extra_output` directory

## Example

Expand Down
24 changes: 16 additions & 8 deletions docs/webhook_events.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ If webhook is set to have Event Grid message format then the payload will look a
"unique_reports",
"regression_reports",
"logs",
"extra"
"extra_setup",
"extra_output"
],
"title": "ContainerType"
},
Expand Down Expand Up @@ -2023,7 +2024,8 @@ If webhook is set to have Event Grid message format then the payload will look a
"unique_reports",
"regression_reports",
"logs",
"extra"
"extra_setup",
"extra_output"
],
"title": "ContainerType"
},
Expand Down Expand Up @@ -2959,7 +2961,8 @@ If webhook is set to have Event Grid message format then the payload will look a
"unique_reports",
"regression_reports",
"logs",
"extra"
"extra_setup",
"extra_output"
],
"title": "ContainerType"
},
Expand Down Expand Up @@ -3441,7 +3444,8 @@ If webhook is set to have Event Grid message format then the payload will look a
"unique_reports",
"regression_reports",
"logs",
"extra"
"extra_setup",
"extra_output"
],
"title": "ContainerType"
},
Expand Down Expand Up @@ -3976,7 +3980,8 @@ If webhook is set to have Event Grid message format then the payload will look a
"unique_reports",
"regression_reports",
"logs",
"extra"
"extra_setup",
"extra_output"
],
"title": "ContainerType"
},
Expand Down Expand Up @@ -4425,7 +4430,8 @@ If webhook is set to have Event Grid message format then the payload will look a
"unique_reports",
"regression_reports",
"logs",
"extra"
"extra_setup",
"extra_output"
],
"title": "ContainerType"
},
Expand Down Expand Up @@ -4901,7 +4907,8 @@ If webhook is set to have Event Grid message format then the payload will look a
"unique_reports",
"regression_reports",
"logs",
"extra"
"extra_setup",
"extra_output"
],
"title": "ContainerType"
},
Expand Down Expand Up @@ -5507,7 +5514,8 @@ If webhook is set to have Event Grid message format then the payload will look a
"unique_reports",
"regression_reports",
"logs",
"extra"
"extra_setup",
"extra_output"
],
"title": "ContainerType"
},
Expand Down
3 changes: 2 additions & 1 deletion src/ApiService/ApiService/OneFuzzTypes/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ public enum ContainerType {
UniqueReports,
RegressionReports,
Logs,
Extra
ExtraSetup,
ExtraOutput,
}


Expand Down
26 changes: 10 additions & 16 deletions src/ApiService/ApiService/OneFuzzTypes/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ public record VmDefinition(
long Value
);

public record TaskDefinition(
public readonly record struct TaskDefinition(
Porges marked this conversation as resolved.
Show resolved Hide resolved
TaskFeature[] Features,
VmDefinition Vm,
ContainerDefinition[] Containers,
Expand All @@ -927,42 +927,36 @@ public record TaskDefinition(
public record WorkSet(
bool Reboot,
Uri SetupUrl,
Uri? ExtraUrl,
Uri? ExtraSetupUrl,
bool Script,
List<WorkUnit> WorkUnits
);





public record ContainerDefinition(
public readonly record struct ContainerDefinition(
ContainerType Type,
Compare Compare,
long Value,
ContainerPermission Permissions);


// TODO: service shouldn't pass SyncedDir, but just the url and let the agent
// come up with paths
public record SyncedDir(string Path, Uri Url);

public readonly record struct SyncedDir(string Path, Uri Url);

[JsonConverter(typeof(ContainerDefConverter))]
public interface IContainerDef { }
public record SingleContainer(SyncedDir SyncedDir) : IContainerDef;
public record MultipleContainer(List<SyncedDir> SyncedDirs) : IContainerDef;
public record MultipleContainer(IReadOnlyList<SyncedDir> SyncedDirs) : IContainerDef;


public class ContainerDefConverter : JsonConverter<IContainerDef> {
public override IContainerDef? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
if (reader.TokenType == JsonTokenType.StartObject) {
var result = (SyncedDir?)JsonSerializer.Deserialize(ref reader, typeof(SyncedDir), options);
if (result is null) {
return null;
if (result is SyncedDir sd) {
return new SingleContainer(sd);
}

return new SingleContainer(result);
return null;
}

if (reader.TokenType == JsonTokenType.StartArray) {
Expand Down Expand Up @@ -1057,8 +1051,8 @@ Dictionary<string, string> Tags
public IContainerDef? UniqueInputs { get; set; }
public IContainerDef? UniqueReports { get; set; }
public IContainerDef? RegressionReports { get; set; }
public IContainerDef? Extra { get; set; }

public IContainerDef? ExtraSetup { get; set; }
public IContainerDef? ExtraOutput { get; set; }
}

public record NodeCommandEnvelope(
Expand Down
143 changes: 75 additions & 68 deletions src/ApiService/ApiService/onefuzzlib/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,75 +75,82 @@ private static BlobContainerSasPermissions ConvertPermissions(ContainerPermissio
);

if (definition.MonitorQueue != null) {
config.inputQueue = await _queue.GetQueueSas(task.TaskId.ToString(), StorageType.Corpus, QueueSasPermissions.Add | QueueSasPermissions.Read | QueueSasPermissions.Update | QueueSasPermissions.Process);
}

var containersByType = definition.Containers.Where(c => c.Type != ContainerType.Setup && task.Config.Containers != null)
.ToAsyncEnumerable()
.SelectAwait(async countainerDef => {
var containers = await
task.Config.Containers!
.Where(c => c.Type == countainerDef.Type).Select(container => (countainerDef, container))
.Where(x => x.container != null)
.ToAsyncEnumerable()
.SelectAwait(async (x, i) =>
new SyncedDir(
string.Join("_", "task", x.Item1.Type.ToString().ToLower(), i),
await _containers.GetContainerSasUrl(x.Item2.Name, StorageType.Corpus, ConvertPermissions(x.Item1.Permissions)))
).ToListAsync();
return (countainerDef, containers);
}
);

await foreach (var data in containersByType) {

if (!data.containers.Any()) {
continue;
}
config.inputQueue = await _queue.GetQueueSas(task.TaskId.ToString(), StorageType.Corpus, QueueSasPermissions.All);
}

if (task.Config.Containers is not null) {
var containersByType =
await Async.Task.WhenAll(
definition.Containers
.Where(c => c.Type is not ContainerType.Setup)
.Select(async countainerDef => {
var syncedDirs =
await Async.Task.WhenAll(
task.Config.Containers
.Where(c => c.Type == countainerDef.Type)
.Select(async (container, i) =>
new SyncedDir(
string.Join("_", "task", countainerDef.Type.ToString().ToLower(), i),
await _containers.GetContainerSasUrl(container.Name, StorageType.Corpus, ConvertPermissions(countainerDef.Permissions)))
));

return (countainerDef, syncedDirs);
}));

foreach (var (containerDef, syncedDirs) in containersByType) {
if (!syncedDirs.Any()) {
continue;
}

IContainerDef def = data.countainerDef switch {
ContainerDefinition { Compare: Compare.Equal, Value: 1 } or
ContainerDefinition { Compare: Compare.AtMost, Value: 1 } when data.containers.Count == 1 => new SingleContainer(data.containers[0]),
_ => new MultipleContainer(data.containers)
};

switch (data.countainerDef.Type) {
case ContainerType.Analysis:
config.Analysis = def;
break;
case ContainerType.Coverage:
config.Coverage = def;
break;
case ContainerType.Crashes:
config.Crashes = def;
break;
case ContainerType.Inputs:
config.Inputs = def;
break;
case ContainerType.NoRepro:
config.NoRepro = def;
break;
case ContainerType.ReadonlyInputs:
config.ReadonlyInputs = def;
break;
case ContainerType.Reports:
config.Reports = def;
break;
case ContainerType.Tools:
config.Tools = def;
break;
case ContainerType.UniqueInputs:
config.UniqueInputs = def;
break;
case ContainerType.UniqueReports:
config.UniqueReports = def;
break;
case ContainerType.RegressionReports:
config.RegressionReports = def;
break;
case ContainerType.Extra:
config.Extra = def;
break;
IContainerDef def = containerDef switch {
ContainerDefinition { Compare: Compare.Equal or Compare.AtMost, Value: 1 }
when syncedDirs is [var syncedDir] => new SingleContainer(syncedDir),
_ => new MultipleContainer(syncedDirs)
};

switch (containerDef.Type) {
case ContainerType.Analysis:
config.Analysis = def;
break;
case ContainerType.Coverage:
config.Coverage = def;
break;
case ContainerType.Crashes:
config.Crashes = def;
break;
case ContainerType.Inputs:
config.Inputs = def;
break;
case ContainerType.NoRepro:
config.NoRepro = def;
break;
case ContainerType.ReadonlyInputs:
config.ReadonlyInputs = def;
break;
case ContainerType.Reports:
config.Reports = def;
break;
case ContainerType.Tools:
config.Tools = def;
break;
case ContainerType.UniqueInputs:
config.UniqueInputs = def;
break;
case ContainerType.UniqueReports:
config.UniqueReports = def;
break;
case ContainerType.RegressionReports:
config.RegressionReports = def;
break;
case ContainerType.ExtraSetup:
config.ExtraSetup = def;
break;
case ContainerType.ExtraOutput:
config.ExtraOutput = def;
break;
default:
throw new InvalidDataException($"unknown container type: {containerDef.Type}");
}
}
}

Expand Down
Loading