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"));