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

timer_retention #1845

Merged
merged 1 commit into from
Apr 26, 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
121 changes: 121 additions & 0 deletions src/ApiService/ApiService/TimerRetention.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
using Microsoft.Azure.Functions.Worker;

namespace Microsoft.OneFuzz.Service;

public class TimerRetention
{
private readonly TimeSpan RETENTION_POLICY = TimeSpan.FromDays(18 * 30);
private readonly TimeSpan SEARCH_EXTENT = TimeSpan.FromDays(20 * 30);

private readonly ILogTracer _log;
private readonly ITaskOperations _taskOps;
private readonly INotificationOperations _notificaitonOps;
private readonly IJobOperations _jobOps;
private readonly IReproOperations _reproOps;

public TimerRetention(
ILogTracer log,
ITaskOperations taskOps,
INotificationOperations notificaitonOps,
IJobOperations jobOps,
IReproOperations reproOps)
{
_log = log;
_taskOps = taskOps;
_notificaitonOps = notificaitonOps;
_jobOps = jobOps;
_reproOps = reproOps;
}


public async Async.Task Run([TimerTrigger("20:00:00")] TimerInfo t)
{
var now = DateTimeOffset.UtcNow;

var timeRetainedOlder = now - RETENTION_POLICY;
var timeRetainedNewer = now + SEARCH_EXTENT;

var timeFilter = $"Timestamp lt datetime'{timeRetainedOlder.ToString("o")}' and Timestamp gt datetime'{timeRetainedNewer.ToString("o")}'";
var timeFilterNewer = $"Timestamp gt datetime '{timeRetainedOlder.ToString("o")}'";

// Collecting 'still relevant' task containers.
// NOTE: This must be done before potentially modifying tasks otherwise
// the task timestamps will not be useful.\

var usedContainers = new HashSet<Container>();

await foreach (var task in _taskOps.QueryAsync(timeFilter))
{
var containerNames =
from container in task.Config.Containers
select container.Name;

foreach (var c in containerNames)
{
usedContainers.Add(c);
}
}


await foreach (var notification in _notificaitonOps.QueryAsync(timeFilter))
{
_log.Verbose($"checking expired notification for removal: {notification.NotificationId}");
var container = notification.Container;

if (!usedContainers.Contains(container))
{
_log.Info($"deleting expired notification: {notification.NotificationId}");
var r = await _notificaitonOps.Delete(notification);
if (!r.IsOk)
{
_log.Error($"failed to delete notification with id {notification.NotificationId} due to [{r.ErrorV.Item1}] {r.ErrorV.Item2}");
}
}
}

await foreach (var job in _jobOps.QueryAsync($"{timeFilter} and state eq '{JobState.Enabled}'"))
{
if (job.UserInfo is not null && job.UserInfo.Upn is not null)
{
_log.Info($"removing PII from job {job.JobId}");
var userInfo = job.UserInfo with { Upn = null };
var updatedJob = job with { UserInfo = userInfo };
var r = await _jobOps.Replace(updatedJob);
if (!r.IsOk)
{
_log.Error($"Failed to save job {updatedJob.JobId} due to [{r.ErrorV.Item1}] {r.ErrorV.Item2}");
}
}
}

await foreach (var task in _taskOps.QueryAsync($"{timeFilter} and state eq '{TaskState.Stopped}'"))
{
if (task.UserInfo is not null && task.UserInfo.Upn is not null)
{
_log.Info($"removing PII from task {task.TaskId}");
var userInfo = task.UserInfo with { Upn = null };
var updatedTask = task with { UserInfo = userInfo };
var r = await _taskOps.Replace(updatedTask);
if (!r.IsOk)
{
_log.Error($"Failed to save task {updatedTask.TaskId} due to [{r.ErrorV.Item1}] {r.ErrorV.Item2}");
}
}
}

await foreach (var repro in _reproOps.QueryAsync(timeFilter))
{
if (repro.UserInfo is not null && repro.UserInfo.Upn is not null)
{
_log.Info($"removing PII from repro: {repro.VmId}");
var userInfo = repro.UserInfo with { Upn = null };
var updatedRepro = repro with { UserInfo = userInfo };
var r = await _reproOps.Replace(updatedRepro);
if (!r.IsOk)
{
_log.Error($"Failed to save repro {updatedRepro.VmId} due to [{r.ErrorV.Item1}] {r.ErrorV.Item2}");
}
}
}
}
}
3 changes: 0 additions & 3 deletions src/ApiService/ApiService/onefuzzlib/Containers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,6 @@ private static Uri GetUrl(string accountName)
var SAS_START_TIME_DELTA = TimeSpan.FromHours(6);
var SAS_END_TIME_DELTA = TimeSpan.FromMinutes(6);

// SAS_START_TIME_DELTA = datetime.timedelta(hours = 6)
//SAS_END_TIME_DELTA = datetime.timedelta(minutes = 15)

var now = DateTimeOffset.UtcNow;
var start = now - SAS_START_TIME_DELTA;
var expiry = now + timeSpan + SAS_END_TIME_DELTA;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Microsoft.OneFuzz.Service;

public interface INotificationOperations
public interface INotificationOperations : IOrm<Notification>
{
Async.Task NewFiles(Container container, string filename, bool failTaskOnTransientError);
}
Expand Down
2 changes: 1 addition & 1 deletion src/ApiService/ApiService/onefuzzlib/ReproOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Microsoft.OneFuzz.Service;

public interface IReproOperations
public interface IReproOperations : IStatefulOrm<Repro, VmState>
{
public IAsyncEnumerable<Repro?> SearchExpired();
}
Expand Down
7 changes: 7 additions & 0 deletions src/ApiService/Tests/OrmModelsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,13 @@ public bool RegressionReportOrReport(RegressionReportOrReport e)
return Test(e);
}

[Property]
public bool Job(Job e)
{
return Test(e);
}


/*
//Sample function on how repro a failing test run, using Replay
//functionality of FsCheck. Feel free to
Expand Down