feat: Implement container logs functionality in InstancesViewModel
- 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.
This commit is contained in:
@@ -99,10 +99,22 @@ public class InstanceService
|
||||
_logger.LogInformation("Fetching template repo: {RepoUrl}", repoUrl);
|
||||
var templateConfig = await _git.FetchAsync(repoUrl, repoPat);
|
||||
|
||||
// ── 1b. Remove any stale stack that might hold references to old secrets ─
|
||||
_logger.LogInformation("Removing stale stack (if any): {StackName}", stackName);
|
||||
await _docker.RemoveStackAsync(stackName);
|
||||
await Task.Delay(2000);
|
||||
// ── 1b. Remove stale stack (and optionally its cached volumes) ─────
|
||||
// docker stack rm alone leaves named volumes behind; those volumes
|
||||
// retain their old driver_opts and Docker re-uses them on the next
|
||||
// deploy, ignoring the new (correct) options in the compose file.
|
||||
// PurgeStaleVolumes must be explicitly opted into to avoid accidental data loss.
|
||||
if (dto.PurgeStaleVolumes)
|
||||
{
|
||||
_logger.LogInformation("Purging stale stack and volumes (PurgeStaleVolumes=true): {StackName}", stackName);
|
||||
await _docker.RemoveStackVolumesAsync(stackName);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogInformation("Removing stale stack (if any): {StackName}", stackName);
|
||||
await _docker.RemoveStackAsync(stackName);
|
||||
await Task.Delay(2000);
|
||||
}
|
||||
|
||||
// ── 2. Generate MySQL credentials ──────────────────────────────
|
||||
var mysqlPassword = GenerateRandomPassword(32);
|
||||
@@ -129,12 +141,11 @@ public class InstanceService
|
||||
throw new InvalidOperationException($"MySQL database/user setup failed: {mysqlMsg}");
|
||||
_logger.LogInformation("MySQL setup complete: {Message}", mysqlMsg);
|
||||
|
||||
// ── 2c. Persist password (encrypted) for future redeploys ────────
|
||||
// ── 2c. Persist password for future redeploys ────────
|
||||
await _settings.SetAsync(
|
||||
SettingsService.InstanceMySqlPassword(abbrev), mysqlPassword,
|
||||
SettingsService.CatInstance, isSensitive: true);
|
||||
await _db.SaveChangesAsync();
|
||||
_logger.LogInformation("MySQL password stored in settings for instance {Abbrev}", abbrev);
|
||||
_logger.LogInformation("MySQL password stored in Bitwarden for instance {Abbrev}", abbrev);
|
||||
|
||||
// ── 3. Read settings ────────────────────────────────────────────
|
||||
var mySqlHost = mySqlHostValue;
|
||||
@@ -238,11 +249,7 @@ public class InstanceService
|
||||
+ "(2) NFS export has root_squash enabled — set 'No mapping' / no_root_squash on the NFS server.");
|
||||
}
|
||||
|
||||
// ── 6. Remove stale NFS volumes ─────────────────────────────────
|
||||
_logger.LogInformation("Removing stale NFS volumes for stack {StackName}", stackName);
|
||||
await _docker.RemoveStackVolumesAsync(stackName);
|
||||
|
||||
// ── 7. Deploy stack ─────────────────────────────────────────────
|
||||
// ── 6. Deploy stack ─────────────────────────────────────────────
|
||||
var deployResult = await _docker.DeployStackAsync(stackName, composeYaml);
|
||||
if (!deployResult.Success)
|
||||
throw new InvalidOperationException($"Stack deployment failed: {deployResult.ErrorMessage}");
|
||||
@@ -258,13 +265,15 @@ public class InstanceService
|
||||
|
||||
_logger.LogInformation("Instance created: {StackName} | duration={DurationMs}ms", stackName, sw.ElapsedMilliseconds);
|
||||
|
||||
// ── 8. Post-instance init (fire-and-forget background task) ──────
|
||||
// Waits for Xibo to be ready then creates admin user, OAuth app, and sets theme.
|
||||
var instanceUrl = $"https://{cmsServerName}";
|
||||
_ = Task.Run(async () => await _postInit.RunAsync(abbrev, instanceUrl));
|
||||
// ── 7. Return result — post-init will be triggered by the UI ──────
|
||||
// after the user creates an OAuth2 app in the Xibo web UI and supplies
|
||||
// the client_id and client_secret.
|
||||
var instanceUrl = $"https://{cmsServerName}/{abbrev}";
|
||||
|
||||
deployResult.InstanceUrl = instanceUrl;
|
||||
deployResult.Abbrev = abbrev;
|
||||
deployResult.ServiceCount = 4;
|
||||
deployResult.Message = "Instance deployed successfully. Post-install setup is running in background.";
|
||||
deployResult.Message = "Instance deployed successfully. Complete post-install setup by providing OAuth credentials.";
|
||||
return deployResult;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
Reference in New Issue
Block a user