save work

This commit is contained in:
StellaOps Bot
2025-12-19 09:40:41 +02:00
parent 2eafe98d44
commit 43882078a4
44 changed files with 3044 additions and 492 deletions

View File

@@ -5,6 +5,7 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@@ -67,8 +68,9 @@ internal sealed class CompositeScanAnalyzerDispatcher : IScanAnalyzerDispatcher
var osAnalyzers = _osCatalog.CreateAnalyzers(services);
var languageAnalyzers = _languageCatalog.CreateAnalyzers(services);
var nativeAnalyzersEnabled = _options.NativeAnalyzers.Enabled;
if (osAnalyzers.Count == 0 && languageAnalyzers.Count == 0)
if (osAnalyzers.Count == 0 && languageAnalyzers.Count == 0 && !nativeAnalyzersEnabled)
{
_logger.LogWarning("No analyzer plug-ins available; skipping analyzer stage for job {JobId}.", context.JobId);
return;
@@ -89,6 +91,11 @@ internal sealed class CompositeScanAnalyzerDispatcher : IScanAnalyzerDispatcher
await ExecuteLanguageAnalyzersAsync(context, languageAnalyzers, services, workspacePath, cancellationToken)
.ConfigureAwait(false);
}
if (nativeAnalyzersEnabled)
{
await ExecuteNativeAnalyzerAsync(context, services, rootfsPath, cancellationToken).ConfigureAwait(false);
}
}
private async Task ExecuteOsAnalyzersAsync(
@@ -329,6 +336,59 @@ internal sealed class CompositeScanAnalyzerDispatcher : IScanAnalyzerDispatcher
}
}
private async Task ExecuteNativeAnalyzerAsync(
ScanJobContext context,
IServiceProvider services,
string? rootfsPath,
CancellationToken cancellationToken)
{
if (rootfsPath is null)
{
_logger.LogWarning(
"Metadata key '{MetadataKey}' missing for job {JobId}; unable to locate root filesystem. Native analyzer skipped.",
_options.Analyzers.RootFilesystemMetadataKey,
context.JobId);
return;
}
NativeAnalysisResult result;
try
{
var executor = services.GetRequiredService<NativeAnalyzerExecutor>();
result = await executor.ExecuteAsync(rootfsPath, context, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.LogError(ex, "Native analyzer execution failed for job {JobId}.", context.JobId);
return;
}
if (result.Components is null || result.Components.Count == 0)
{
return;
}
var layerDigest = ComputeLayerDigest("native");
var records = result.Components
.Select(component => component.ToComponentRecord(layerDigest))
.ToList();
if (records.Count == 0)
{
return;
}
var fragment = LayerComponentFragment.Create(layerDigest, ImmutableArray.CreateRange(records));
context.Analysis.AppendLayerFragments(ImmutableArray.Create(fragment));
}
private static string ComputeLayerDigest(string kind)
{
var normalized = $"stellaops:{kind.Trim().ToLowerInvariant()}";
var hash = SHA256.HashData(Encoding.UTF8.GetBytes(normalized));
return $"sha256:{Convert.ToHexString(hash).ToLowerInvariant()}";
}
private void LoadPlugins()
{
_osPluginDirectories = NormalizeDirectories(_options.Analyzers.PluginDirectories, Path.Combine("plugins", "scanner", "analyzers", "os"));

View File

@@ -12,9 +12,11 @@ using StellaOps.Scanner.Reachability;
using StellaOps.Scanner.Reachability.Gates;
using StellaOps.Scanner.Analyzers.OS.Plugin;
using StellaOps.Scanner.Analyzers.Lang.Plugin;
using StellaOps.Scanner.Analyzers.Native.Index;
using StellaOps.Scanner.EntryTrace;
using StellaOps.Scanner.Core.Contracts;
using StellaOps.Scanner.Core.Security;
using StellaOps.Scanner.Emit.Native;
using StellaOps.Scanner.Surface.Env;
using StellaOps.Scanner.Surface.FS;
using StellaOps.Scanner.Surface.Secrets;
@@ -45,6 +47,10 @@ builder.Services.AddOptions<ScannerWorkerOptions>()
}
});
builder.Services.AddOptions<NativeAnalyzerOptions>()
.BindConfiguration(NativeAnalyzerOptions.SectionName)
.ValidateOnStart();
builder.Services.AddSingleton<IValidateOptions<ScannerWorkerOptions>, ScannerWorkerOptionsValidator>();
var workerOptions = builder.Configuration.GetSection(ScannerWorkerOptions.SectionName).Get<ScannerWorkerOptions>() ?? new ScannerWorkerOptions();
@@ -143,6 +149,10 @@ builder.Services.TryAddSingleton<IScanJobSource, NullScanJobSource>();
builder.Services.TryAddSingleton<IPluginCatalogGuard, RestartOnlyPluginGuard>();
builder.Services.AddSingleton<IOSAnalyzerPluginCatalog, OsAnalyzerPluginCatalog>();
builder.Services.AddSingleton<ILanguageAnalyzerPluginCatalog, LanguageAnalyzerPluginCatalog>();
builder.Services.AddSingleton<IBuildIdIndex, OfflineBuildIdIndex>();
builder.Services.AddSingleton<INativeComponentEmitter, NativeComponentEmitter>();
builder.Services.AddSingleton<NativeBinaryDiscovery>();
builder.Services.AddSingleton<NativeAnalyzerExecutor>();
builder.Services.AddSingleton<IScanAnalyzerDispatcher, CompositeScanAnalyzerDispatcher>();
builder.Services.AddSingleton<IScanStageExecutor, RegistrySecretStageExecutor>();
builder.Services.AddSingleton<IScanStageExecutor, AnalyzerStageExecutor>();

View File

@@ -30,6 +30,6 @@
<ProjectReference Include="../__Libraries/StellaOps.Scanner.Surface.FS/StellaOps.Scanner.Surface.FS.csproj" />
<ProjectReference Include="../__Libraries/StellaOps.Scanner.Storage/StellaOps.Scanner.Storage.csproj" />
<ProjectReference Include="../__Libraries/StellaOps.Scanner.Emit/StellaOps.Scanner.Emit.csproj" />
<ProjectReference Include="../__Libraries/StellaOps.Scanner.Analyzers.Native/StellaOps.Scanner.Analyzers.Native.csproj" />
<ProjectReference Include="../StellaOps.Scanner.Analyzers.Native/StellaOps.Scanner.Analyzers.Native.csproj" />
</ItemGroup>
</Project>

View File

@@ -3,4 +3,6 @@
| Task ID | Status | Notes | Updated (UTC) |
| --- | --- | --- | --- |
| SCAN-NL-0409-002 | DONE | OS analyzer surface-cache wiring + hit/miss metrics + worker tests updated to current APIs. | 2025-12-12 |
| SCAN-NATIVE-3500-0014 | DONE | Native analyzer stage integrated into dispatcher (discovery → emit → layer fragments) + unit tests for native stage execution. | 2025-12-19 |
| NAI-003 | DONE | Native analyzer stage wired into `CompositeScanAnalyzerDispatcher` (and Worker project references canonical `StellaOps.Scanner.Analyzers.Native` so `*.Index` types resolve). | 2025-12-19 |
| NAI-005 | DONE | Integration tests for native analyzer stage + fragment append behavior (`StellaOps.Scanner.Worker.Tests`). | 2025-12-19 |