save work
This commit is contained in:
@@ -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"));
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 |
|
||||
|
||||
Reference in New Issue
Block a user