Files
OTSSignsOrchestrator/OTSSignsOrchestrator/Health/Checks/NfsAccessHealthCheck.cs
Matt Batchelder fc510b9b20 Add production Docker Compose file for external PostgreSQL integration
- Introduced `docker-compose.prod.yml` for production deployment.
- Configured service to connect to an external PostgreSQL instance.
- Set environment variables for JWT and database connection strings.
- Defined network and volume for data protection keys.
2026-03-26 19:34:12 -04:00

67 lines
2.5 KiB
C#

using OTSSignsOrchestrator.Data.Entities;
using OTSSignsOrchestrator.Services;
namespace OTSSignsOrchestrator.Health.Checks;
/// <summary>
/// Verifies NFS paths for the instance are accessible by running <c>ls</c> via SSH.
/// </summary>
public sealed class NfsAccessHealthCheck : IHealthCheck
{
private readonly IServiceProvider _services;
private readonly ILogger<NfsAccessHealthCheck> _logger;
public string CheckName => "NfsAccess";
public bool AutoRemediate => false;
public NfsAccessHealthCheck(
IServiceProvider services,
ILogger<NfsAccessHealthCheck> logger)
{
_services = services;
_logger = logger;
}
public async Task<HealthCheckResult> RunAsync(Instance instance, CancellationToken ct)
{
var nfsPath = instance.NfsPath;
if (string.IsNullOrEmpty(nfsPath))
return new HealthCheckResult(HealthStatus.Critical, "No NFS path configured");
try
{
var settings = _services.GetRequiredService<SettingsService>();
var nfsServer = await settings.GetAsync(SettingsService.NfsServer);
var nfsExport = await settings.GetAsync(SettingsService.NfsExport);
if (string.IsNullOrEmpty(nfsServer) || string.IsNullOrEmpty(nfsExport))
return new HealthCheckResult(HealthStatus.Critical, "NFS server/export not configured");
await using var shell = _services.GetRequiredService<SwarmShellService>();
// Mount temporarily and check the path is listable.
// In local (privileged container) mode, sudo is a no-op as root.
var mountPoint = $"/tmp/healthcheck-nfs-{Guid.NewGuid():N}";
await shell.RunCommandAsync($"sudo mkdir -p {mountPoint}");
try
{
await shell.RunCommandAsync($"sudo mount -t nfs4 {nfsServer}:{nfsExport} {mountPoint}");
await shell.RunCommandAsync($"ls {mountPoint}/{nfsPath} 2>&1");
return new HealthCheckResult(HealthStatus.Healthy,
$"NFS path accessible: {nfsPath}");
}
finally
{
await shell.RunCommandAllowFailureAsync($"sudo umount {mountPoint}");
await shell.RunCommandAllowFailureAsync($"sudo rmdir {mountPoint}");
}
}
catch (Exception ex)
{
return new HealthCheckResult(HealthStatus.Critical,
$"NFS access check failed for {nfsPath}: {ex.Message}");
}
}
}