- Added properties for managing container logs, including log entries, service filters, and auto-refresh options. - Introduced commands for refreshing logs, toggling auto-refresh, and closing the logs panel. - Implemented log fetching logic with error handling and status messages. - Integrated log display in the InstancesView with a dedicated logs panel. feat: Enhance navigation to Instances page with auto-selection - Added method to navigate to the Instances page and auto-select an instance based on abbreviation. feat: Update SettingsViewModel to load and save Bitwarden configuration - Integrated Bitwarden configuration loading from IOptions and saving to appsettings.json. - Added properties for Bitwarden instance project ID and connection status. - Updated UI to reflect Bitwarden settings and connection status. feat: Add advanced options for instance creation - Introduced a new expander in CreateInstanceView for advanced options, including purging stale volumes. feat: Improve InstanceDetailsWindow with pending setup banner - Added a banner to indicate pending setup for Xibo OAuth credentials, with editable fields for client ID and secret. fix: Update appsettings.json to include Bitwarden configuration structure - Added Bitwarden section to appsettings.json for storing configuration values. chore: Update Docker Compose template with health checks - Added health check configuration for web service in template.yml to ensure service availability. refactor: Drop AppSettings table from database - Removed AppSettings table and related migration files as part of database cleanup. feat: Create ServiceLogEntry DTO for log management - Added ServiceLogEntry class to represent individual log entries from Docker services.
114 lines
4.8 KiB
C#
114 lines
4.8 KiB
C#
using MySqlConnector;
|
|
using OTSSignsOrchestrator.Core.Models.DTOs;
|
|
|
|
namespace OTSSignsOrchestrator.Core.Services;
|
|
|
|
// Re-export for convenience so consumers only need one using
|
|
using ServiceLogEntry = OTSSignsOrchestrator.Core.Models.DTOs.ServiceLogEntry;
|
|
|
|
/// <summary>
|
|
/// Abstraction for Docker CLI stack operations (deploy, remove, list, inspect).
|
|
/// Implementations may use local docker CLI or SSH-based remote execution.
|
|
/// </summary>
|
|
public interface IDockerCliService
|
|
{
|
|
Task<DeploymentResultDto> DeployStackAsync(string stackName, string composeYaml, bool resolveImage = false);
|
|
Task<DeploymentResultDto> RemoveStackAsync(string stackName);
|
|
Task<List<StackInfo>> ListStacksAsync();
|
|
Task<List<ServiceInfo>> InspectStackServicesAsync(string stackName);
|
|
|
|
/// <summary>Ensures a directory exists on the target host (equivalent to mkdir -p).</summary>
|
|
Task<bool> EnsureDirectoryAsync(string path);
|
|
|
|
/// <summary>
|
|
/// Ensures the required folders exist on an NFS export, creating any that are missing.
|
|
/// If <paramref name="nfsExportFolder"/> is non-empty, creates it first as a subfolder of the export,
|
|
/// then creates the volume folders inside it.
|
|
/// Temporarily mounts the NFS export on the Docker host to create the directories.
|
|
/// </summary>
|
|
Task<bool> EnsureNfsFoldersAsync(
|
|
string nfsServer,
|
|
string nfsExport,
|
|
IEnumerable<string> folderNames,
|
|
string? nfsExportFolder = null);
|
|
|
|
/// <summary>
|
|
/// Same as <see cref="EnsureNfsFoldersAsync"/> but returns the error message on failure
|
|
/// so callers can surface actionable diagnostics.
|
|
/// </summary>
|
|
Task<(bool Success, string? Error)> EnsureNfsFoldersWithErrorAsync(
|
|
string nfsServer,
|
|
string nfsExport,
|
|
IEnumerable<string> folderNames,
|
|
string? nfsExportFolder = null);
|
|
|
|
/// <summary>
|
|
/// Removes all Docker volumes whose names start with <paramref name="stackName"/>_.
|
|
/// Volumes currently in use by running containers will be skipped.
|
|
/// Safe for NFS volumes since data lives on the remote export, not in the local volume.
|
|
/// </summary>
|
|
Task<bool> RemoveStackVolumesAsync(string stackName);
|
|
|
|
/// <summary>
|
|
/// Lists all nodes in the Docker Swarm cluster.
|
|
/// Must be executed against a Swarm manager node.
|
|
/// </summary>
|
|
Task<List<NodeInfo>> ListNodesAsync();
|
|
|
|
/// <summary>
|
|
/// Force-updates a service so all its tasks are restarted and pick up any changed
|
|
/// secrets or config (equivalent to docker service update --force).
|
|
/// </summary>
|
|
Task<bool> ForceUpdateServiceAsync(string serviceName);
|
|
|
|
/// <summary>
|
|
/// Opens a <see cref="MySqlConnection"/> to a remote MySQL server through the
|
|
/// implementation's transport (e.g. an SSH tunnel). The caller must dispose
|
|
/// both the connection <b>and</b> the returned <c>tunnel</c> handle when finished.
|
|
/// </summary>
|
|
/// <returns>
|
|
/// A tuple of (connection, tunnel). <c>tunnel</c> is <see cref="IDisposable"/>
|
|
/// and MUST be disposed after the connection is closed.
|
|
/// </returns>
|
|
Task<(MySqlConnection Connection, IDisposable Tunnel)> OpenMySqlConnectionAsync(
|
|
string mysqlHost, int port,
|
|
string adminUser, string adminPassword);
|
|
|
|
/// <summary>
|
|
/// Executes <c>ALTER USER … IDENTIFIED BY …</c> on a remote MySQL server via
|
|
/// <see cref="OpenMySqlConnectionAsync"/>.
|
|
/// </summary>
|
|
Task<(bool Success, string Error)> AlterMySqlUserPasswordAsync(
|
|
string mysqlHost, int port,
|
|
string adminUser, string adminPassword,
|
|
string targetUser, string newPassword);
|
|
|
|
/// <summary>
|
|
/// Atomically swaps one secret reference on a running service:
|
|
/// removes <paramref name="oldSecretName"/> and adds <paramref name="newSecretName"/>,
|
|
/// preserving the in-container path as <paramref name="targetAlias"/> (defaults to
|
|
/// <paramref name="oldSecretName"/> when null, keeping the same /run/secrets/ filename).
|
|
/// </summary>
|
|
Task<bool> ServiceSwapSecretAsync(string serviceName, string oldSecretName, string newSecretName, string? targetAlias = null);
|
|
|
|
/// <summary>
|
|
/// Fetches the last <paramref name="tailLines"/> log lines from a Docker Swarm service.
|
|
/// If <paramref name="serviceName"/> is null, fetches logs from all services in the stack.
|
|
/// Returns parsed log entries sorted by timestamp ascending.
|
|
/// </summary>
|
|
Task<List<ServiceLogEntry>> GetServiceLogsAsync(string stackName, string? serviceName = null, int tailLines = 200);
|
|
}
|
|
|
|
public class StackInfo
|
|
{
|
|
public string Name { get; set; } = string.Empty;
|
|
public int ServiceCount { get; set; }
|
|
}
|
|
|
|
public class ServiceInfo
|
|
{
|
|
public string Name { get; set; } = string.Empty;
|
|
public string Image { get; set; } = string.Empty;
|
|
public string Replicas { get; set; } = string.Empty;
|
|
}
|