Initial commit (history squashed)
This commit is contained in:
		
							
								
								
									
										79
									
								
								src/StellaOps.Cli/Services/ScannerInstaller.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/StellaOps.Cli/Services/ScannerInstaller.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
 | 
			
		||||
namespace StellaOps.Cli.Services;
 | 
			
		||||
 | 
			
		||||
internal sealed class ScannerInstaller : IScannerInstaller
 | 
			
		||||
{
 | 
			
		||||
    private readonly ILogger<ScannerInstaller> _logger;
 | 
			
		||||
 | 
			
		||||
    public ScannerInstaller(ILogger<ScannerInstaller> logger)
 | 
			
		||||
    {
 | 
			
		||||
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async Task InstallAsync(string artifactPath, bool verbose, CancellationToken cancellationToken)
 | 
			
		||||
    {
 | 
			
		||||
        if (string.IsNullOrWhiteSpace(artifactPath) || !File.Exists(artifactPath))
 | 
			
		||||
        {
 | 
			
		||||
            throw new FileNotFoundException("Scanner artifact not found for installation.", artifactPath);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Current implementation assumes docker-based scanner bundle.
 | 
			
		||||
        var processInfo = new ProcessStartInfo
 | 
			
		||||
        {
 | 
			
		||||
            FileName = "docker",
 | 
			
		||||
            ArgumentList = { "load", "-i", artifactPath },
 | 
			
		||||
            RedirectStandardOutput = true,
 | 
			
		||||
            RedirectStandardError = true,
 | 
			
		||||
            UseShellExecute = false
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        using var process = new Process { StartInfo = processInfo, EnableRaisingEvents = true };
 | 
			
		||||
 | 
			
		||||
        process.OutputDataReceived += (_, args) =>
 | 
			
		||||
        {
 | 
			
		||||
            if (args.Data is null)
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (verbose)
 | 
			
		||||
            {
 | 
			
		||||
                _logger.LogInformation("[install] {Line}", args.Data);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        process.ErrorDataReceived += (_, args) =>
 | 
			
		||||
        {
 | 
			
		||||
            if (args.Data is null)
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _logger.LogError("[install] {Line}", args.Data);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        _logger.LogInformation("Installing scanner container from {Path}...", artifactPath);
 | 
			
		||||
        if (!process.Start())
 | 
			
		||||
        {
 | 
			
		||||
            throw new InvalidOperationException("Failed to start container installation process.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        process.BeginOutputReadLine();
 | 
			
		||||
        process.BeginErrorReadLine();
 | 
			
		||||
 | 
			
		||||
        await process.WaitForExitAsync(cancellationToken).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
        if (process.ExitCode != 0)
 | 
			
		||||
        {
 | 
			
		||||
            throw new InvalidOperationException($"Container installation failed with exit code {process.ExitCode}.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _logger.LogInformation("Scanner container installed successfully.");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user