Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
245 lines
7.9 KiB
C#
245 lines
7.9 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.IO;
|
|
using StellaOps.Configuration;
|
|
using StellaOps.Scanner.Core.Contracts;
|
|
|
|
namespace StellaOps.Scanner.Worker.Options;
|
|
|
|
public sealed class ScannerWorkerOptions
|
|
{
|
|
public const string SectionName = "Scanner:Worker";
|
|
|
|
public int MaxConcurrentJobs { get; set; } = 2;
|
|
|
|
public QueueOptions Queue { get; } = new();
|
|
|
|
public PollingOptions Polling { get; } = new();
|
|
|
|
public AuthorityOptions Authority { get; } = new();
|
|
|
|
public TelemetryOptions Telemetry { get; } = new();
|
|
|
|
public ShutdownOptions Shutdown { get; } = new();
|
|
|
|
public AnalyzerOptions Analyzers { get; } = new();
|
|
|
|
public StellaOpsCryptoOptions Crypto { get; } = new();
|
|
|
|
public SigningOptions Signing { get; } = new();
|
|
|
|
public DeterminismOptions Determinism { get; } = new();
|
|
|
|
public sealed class QueueOptions
|
|
{
|
|
public int MaxAttempts { get; set; } = 5;
|
|
|
|
public double HeartbeatSafetyFactor { get; set; } = 3.0;
|
|
|
|
public int MaxHeartbeatJitterMilliseconds { get; set; } = 750;
|
|
|
|
public IReadOnlyList<TimeSpan> HeartbeatRetryDelays => _heartbeatRetryDelays;
|
|
|
|
public TimeSpan MinHeartbeatInterval { get; set; } = TimeSpan.FromSeconds(10);
|
|
|
|
public TimeSpan MaxHeartbeatInterval { get; set; } = TimeSpan.FromSeconds(30);
|
|
|
|
public void SetHeartbeatRetryDelays(IEnumerable<TimeSpan> delays)
|
|
{
|
|
_heartbeatRetryDelays = NormalizeDelays(delays);
|
|
}
|
|
|
|
internal IReadOnlyList<TimeSpan> NormalizedHeartbeatRetryDelays => _heartbeatRetryDelays;
|
|
|
|
private static IReadOnlyList<TimeSpan> NormalizeDelays(IEnumerable<TimeSpan> delays)
|
|
{
|
|
var buffer = new List<TimeSpan>();
|
|
foreach (var delay in delays)
|
|
{
|
|
if (delay <= TimeSpan.Zero)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
buffer.Add(delay);
|
|
}
|
|
|
|
buffer.Sort();
|
|
return new ReadOnlyCollection<TimeSpan>(buffer);
|
|
}
|
|
|
|
private IReadOnlyList<TimeSpan> _heartbeatRetryDelays = new ReadOnlyCollection<TimeSpan>(new TimeSpan[]
|
|
{
|
|
TimeSpan.FromSeconds(2),
|
|
TimeSpan.FromSeconds(5),
|
|
TimeSpan.FromSeconds(10),
|
|
});
|
|
}
|
|
|
|
public sealed class PollingOptions
|
|
{
|
|
public TimeSpan InitialDelay { get; set; } = TimeSpan.FromMilliseconds(200);
|
|
|
|
public TimeSpan MaxDelay { get; set; } = TimeSpan.FromSeconds(5);
|
|
|
|
public double JitterRatio { get; set; } = 0.2;
|
|
}
|
|
|
|
public sealed class AuthorityOptions
|
|
{
|
|
public bool Enabled { get; set; }
|
|
|
|
public string? Issuer { get; set; }
|
|
|
|
public string? ClientId { get; set; }
|
|
|
|
public string? ClientSecret { get; set; }
|
|
|
|
public bool RequireHttpsMetadata { get; set; } = true;
|
|
|
|
public string? MetadataAddress { get; set; }
|
|
|
|
public int BackchannelTimeoutSeconds { get; set; } = 20;
|
|
|
|
public int TokenClockSkewSeconds { get; set; } = 30;
|
|
|
|
public IList<string> Scopes { get; } = new List<string> { "scanner.scan" };
|
|
|
|
public ResilienceOptions Resilience { get; } = new();
|
|
}
|
|
|
|
public sealed class ResilienceOptions
|
|
{
|
|
public bool? EnableRetries { get; set; }
|
|
|
|
public IList<TimeSpan> RetryDelays { get; } = new List<TimeSpan>
|
|
{
|
|
TimeSpan.FromMilliseconds(250),
|
|
TimeSpan.FromMilliseconds(500),
|
|
TimeSpan.FromSeconds(1),
|
|
TimeSpan.FromSeconds(5),
|
|
};
|
|
|
|
public bool? AllowOfflineCacheFallback { get; set; }
|
|
|
|
public TimeSpan? OfflineCacheTolerance { get; set; }
|
|
}
|
|
|
|
public sealed class TelemetryOptions
|
|
{
|
|
public bool EnableLogging { get; set; } = true;
|
|
|
|
public bool EnableTelemetry { get; set; } = true;
|
|
|
|
public bool EnableTracing { get; set; }
|
|
|
|
public bool EnableMetrics { get; set; } = true;
|
|
|
|
public string ServiceName { get; set; } = "stellaops-scanner-worker";
|
|
|
|
public string? OtlpEndpoint { get; set; }
|
|
|
|
public bool ExportConsole { get; set; }
|
|
|
|
public IDictionary<string, string?> ResourceAttributes { get; } = new ConcurrentDictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
public sealed class ShutdownOptions
|
|
{
|
|
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(30);
|
|
}
|
|
|
|
public sealed class AnalyzerOptions
|
|
{
|
|
public AnalyzerOptions()
|
|
{
|
|
PluginDirectories = new List<string>
|
|
{
|
|
Path.Combine("plugins", "scanner", "analyzers", "os"),
|
|
};
|
|
LanguagePluginDirectories = new List<string>
|
|
{
|
|
Path.Combine("plugins", "scanner", "analyzers", "lang"),
|
|
};
|
|
}
|
|
|
|
public IList<string> PluginDirectories { get; }
|
|
|
|
public IList<string> LanguagePluginDirectories { get; }
|
|
|
|
public string RootFilesystemMetadataKey { get; set; } = ScanMetadataKeys.RootFilesystemPath;
|
|
|
|
public string WorkspaceMetadataKey { get; set; } = ScanMetadataKeys.WorkspacePath;
|
|
|
|
public string EntryTraceConfigMetadataKey { get; set; } = ScanMetadataKeys.ImageConfigPath;
|
|
|
|
public string EntryTraceLayerDirectoriesMetadataKey { get; set; } = ScanMetadataKeys.LayerDirectories;
|
|
|
|
public string EntryTraceLayerArchivesMetadataKey { get; set; } = ScanMetadataKeys.LayerArchives;
|
|
|
|
public string EntryTraceProcRootMetadataKey { get; set; } = ScanMetadataKeys.RuntimeProcRoot;
|
|
}
|
|
|
|
public sealed class DeterminismOptions
|
|
{
|
|
/// <summary>
|
|
/// If true, the worker uses a fixed clock to ensure deterministic timestamps.
|
|
/// </summary>
|
|
public bool FixedClock { get; set; }
|
|
|
|
/// <summary>
|
|
/// Fixed UTC timestamp to emit when FixedClock is enabled. Defaults to Unix epoch.
|
|
/// </summary>
|
|
public DateTimeOffset FixedInstantUtc { get; set; } = DateTimeOffset.UnixEpoch;
|
|
|
|
/// <summary>
|
|
/// Optional seed for RNG-based components when determinism is required.
|
|
/// </summary>
|
|
public int? RngSeed { get; set; }
|
|
|
|
/// <summary>
|
|
/// If true, trims noisy log fields (duration, PIDs) to stable placeholders.
|
|
/// </summary>
|
|
public bool FilterLogs { get; set; }
|
|
|
|
/// <summary>
|
|
/// Optional hard cap for in-flight jobs to keep replay runs hermetic.
|
|
/// When set, the worker will clamp MaxConcurrentJobs to this value.
|
|
/// </summary>
|
|
public int? ConcurrencyLimit { get; set; }
|
|
}
|
|
|
|
public sealed class SigningOptions
|
|
{
|
|
/// <summary>
|
|
/// Enable DSSE signing for surface artifacts (composition recipe, layer fragments).
|
|
/// When disabled, the worker will fall back to deterministic hash envelopes.
|
|
/// </summary>
|
|
public bool EnableDsseSigning { get; set; }
|
|
|
|
/// <summary>
|
|
/// Identifier recorded in DSSE signatures.
|
|
/// </summary>
|
|
public string KeyId { get; set; } = "scanner-hmac";
|
|
|
|
/// <summary>
|
|
/// Shared secret material for HMAC-based DSSE signatures (base64 or hex).
|
|
/// Prefer <see cref=\"SharedSecretFile\"/> for file-based loading.
|
|
/// </summary>
|
|
public string? SharedSecret { get; set; }
|
|
|
|
/// <summary>
|
|
/// Optional path to a file containing the shared secret (base64 or hex).
|
|
/// </summary>
|
|
public string? SharedSecretFile { get; set; }
|
|
|
|
/// <summary>
|
|
/// Allow deterministic fallback when signing is enabled but no secret is provided.
|
|
/// Keeps offline determinism while avoiding hard failures in sealed-mode runs.
|
|
/// </summary>
|
|
public bool AllowDeterministicFallback { get; set; } = true;
|
|
}
|
|
}
|