1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Clean up old releases

This commit is contained in:
Robert 2023-03-04 19:25:31 +01:00
parent 5d01665d6e
commit ee19776afa
6 changed files with 65 additions and 39 deletions

View File

@ -7,6 +7,7 @@ public class ReleaseEntity
public Guid Id { get; set; } public Guid Id { get; set; }
public string Version { get; set; } public string Version { get; set; }
public string ReleaseId { get; set; }
public ReleaseEntityStatus Status { get; set; } public ReleaseEntityStatus Status { get; set; }
public DateTimeOffset? InstalledAt { get; set; } public DateTimeOffset? InstalledAt { get; set; }
} }
@ -15,5 +16,6 @@ public enum ReleaseEntityStatus
{ {
Queued, Queued,
Installed, Installed,
Historical Historical,
Unknown
} }

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Artemis.Storage.Entities.General; using Artemis.Storage.Entities.General;
using Artemis.Storage.Repositories.Interfaces; using Artemis.Storage.Repositories.Interfaces;
using LiteDB; using LiteDB;
@ -18,25 +17,25 @@ public class ReleaseRepository : IReleaseRepository
_repository.Database.GetCollection<ReleaseEntity>().EnsureIndex(s => s.Status); _repository.Database.GetCollection<ReleaseEntity>().EnsureIndex(s => s.Status);
} }
public string GetQueuedVersion() public ReleaseEntity GetQueuedVersion()
{ {
return _repository.Query<ReleaseEntity>().Where(r => r.Status == ReleaseEntityStatus.Queued).FirstOrDefault()?.Version; return _repository.Query<ReleaseEntity>().Where(r => r.Status == ReleaseEntityStatus.Queued).FirstOrDefault();
} }
public string GetInstalledVersion() public ReleaseEntity GetInstalledVersion()
{ {
return _repository.Query<ReleaseEntity>().Where(r => r.Status == ReleaseEntityStatus.Installed).FirstOrDefault()?.Version; return _repository.Query<ReleaseEntity>().Where(r => r.Status == ReleaseEntityStatus.Installed).FirstOrDefault();
} }
public string GetPreviousInstalledVersion() public ReleaseEntity GetPreviousInstalledVersion()
{ {
return _repository.Query<ReleaseEntity>().Where(r => r.Status == ReleaseEntityStatus.Historical).OrderByDescending(r => r.InstalledAt).FirstOrDefault()?.Version; return _repository.Query<ReleaseEntity>().Where(r => r.Status == ReleaseEntityStatus.Historical).OrderByDescending(r => r.InstalledAt).FirstOrDefault();
} }
public void QueueInstallation(string version) public void QueueInstallation(string version, string releaseId)
{ {
// Mark release as queued and add if missing // Mark release as queued and add if missing
ReleaseEntity release = _repository.Query<ReleaseEntity>().Where(r => r.Version == version).FirstOrDefault() ?? new ReleaseEntity {Version = version}; ReleaseEntity release = _repository.Query<ReleaseEntity>().Where(r => r.Version == version).FirstOrDefault() ?? new ReleaseEntity {Version = version, ReleaseId = releaseId};
release.Status = ReleaseEntityStatus.Queued; release.Status = ReleaseEntityStatus.Queued;
_repository.Upsert(release); _repository.Upsert(release);
} }
@ -50,10 +49,7 @@ public class ReleaseRepository : IReleaseRepository
_repository.Upsert(release); _repository.Upsert(release);
// Mark other releases as historical // Mark other releases as historical
List<ReleaseEntity> oldReleases = _repository.Query<ReleaseEntity>().Where(r => r.Version != version && r.Status == ReleaseEntityStatus.Installed).ToList(); List<ReleaseEntity> oldReleases = _repository.Query<ReleaseEntity>().Where(r => r.Version != version && r.Status != ReleaseEntityStatus.Historical).ToList();
if (!oldReleases.Any())
return;
foreach (ReleaseEntity oldRelease in oldReleases) foreach (ReleaseEntity oldRelease in oldReleases)
oldRelease.Status = ReleaseEntityStatus.Historical; oldRelease.Status = ReleaseEntityStatus.Historical;
_repository.Update<ReleaseEntity>(oldReleases); _repository.Update<ReleaseEntity>(oldReleases);
@ -61,16 +57,20 @@ public class ReleaseRepository : IReleaseRepository
public void DequeueInstallation() public void DequeueInstallation()
{ {
_repository.DeleteMany<ReleaseEntity>(r => r.Status == ReleaseEntityStatus.Queued); // Mark all queued releases as unknown, until FinishInstallation is called we don't know the status
List<ReleaseEntity> queuedReleases = _repository.Query<ReleaseEntity>().Where(r => r.Status == ReleaseEntityStatus.Queued).ToList();
foreach (ReleaseEntity queuedRelease in queuedReleases)
queuedRelease.Status = ReleaseEntityStatus.Unknown;
_repository.Update<ReleaseEntity>(queuedReleases);
} }
} }
public interface IReleaseRepository : IRepository public interface IReleaseRepository : IRepository
{ {
string GetQueuedVersion(); ReleaseEntity GetQueuedVersion();
string GetInstalledVersion(); ReleaseEntity GetInstalledVersion();
string GetPreviousInstalledVersion(); ReleaseEntity GetPreviousInstalledVersion();
void QueueInstallation(string version); void QueueInstallation(string version, string releaseId);
void FinishInstallation(string version); void FinishInstallation(string version);
void DequeueInstallation(); void DequeueInstallation();
} }

View File

@ -128,7 +128,7 @@ public class WindowsUpdateNotificationProvider : IUpdateNotificationProvider
} }
// Queue an update in case the user interrupts the process after everything has been prepared // Queue an update in case the user interrupts the process after everything has been prepared
_updateService.QueueUpdate(releaseVersion); _updateService.QueueUpdate(releaseVersion, releaseId);
GetBuilderForRelease(releaseId, releaseVersion) GetBuilderForRelease(releaseId, releaseVersion)
.AddAudio(new ToastAudio {Silent = true}) .AddAudio(new ToastAudio {Silent = true})

View File

@ -158,7 +158,7 @@ public class ReleaseViewModel : ActivatableViewModelBase
{ {
InstallationInProgress = true; InstallationInProgress = true;
await ReleaseInstaller.InstallAsync(_installerCts.Token); await ReleaseInstaller.InstallAsync(_installerCts.Token);
_updateService.QueueUpdate(Version); _updateService.QueueUpdate(Version, ReleaseId);
InstallationFinished = true; InstallationFinished = true;
} }
catch (Exception e) catch (Exception e)

View File

@ -12,7 +12,7 @@ public interface IUpdateService : IArtemisUIService
Task CacheLatestRelease(); Task CacheLatestRelease();
Task<bool> CheckForUpdate(); Task<bool> CheckForUpdate();
void QueueUpdate(string version); void QueueUpdate(string version, string releaseId);
ReleaseInstaller GetReleaseInstaller(string releaseId); ReleaseInstaller GetReleaseInstaller(string releaseId);
void RestartForUpdate(bool silent); void RestartForUpdate(bool silent);

View File

@ -1,9 +1,11 @@
using System; using System;
using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.Services; using Artemis.Core.Services;
using Artemis.Storage.Entities.General;
using Artemis.Storage.Repositories; using Artemis.Storage.Repositories;
using Artemis.UI.Shared.Services.MainWindow; using Artemis.UI.Shared.Services.MainWindow;
using Artemis.WebClient.Updating; using Artemis.WebClient.Updating;
@ -18,13 +20,13 @@ public class UpdateService : IUpdateService
private const double UPDATE_CHECK_INTERVAL = 3_600_000; // once per hour private const double UPDATE_CHECK_INTERVAL = 3_600_000; // once per hour
private readonly PluginSetting<bool> _autoCheck; private readonly PluginSetting<bool> _autoCheck;
private readonly PluginSetting<bool> _autoInstall; private readonly PluginSetting<bool> _autoInstall;
private readonly Platform _updatePlatform; private readonly Func<string, ReleaseInstaller> _getReleaseInstaller;
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IUpdatingClient _updatingClient;
private readonly IReleaseRepository _releaseRepository; private readonly IReleaseRepository _releaseRepository;
private readonly Lazy<IUpdateNotificationProvider> _updateNotificationProvider; private readonly Lazy<IUpdateNotificationProvider> _updateNotificationProvider;
private readonly Func<string, ReleaseInstaller> _getReleaseInstaller; private readonly Platform _updatePlatform;
private readonly IUpdatingClient _updatingClient;
private bool _suspendAutoCheck; private bool _suspendAutoCheck;
@ -69,28 +71,46 @@ public class UpdateService : IUpdateService
ProcessReleaseStatus(); ProcessReleaseStatus();
} }
public string Channel { get; }
public string? PreviousVersion { get; set; }
public IGetNextRelease_NextPublishedRelease? CachedLatestRelease { get; private set; }
private void ProcessReleaseStatus() private void ProcessReleaseStatus()
{ {
// If an update is queued, don't bother with anything else // If an update is queued, don't bother with anything else
string? queued = _releaseRepository.GetQueuedVersion(); ReleaseEntity? queued = _releaseRepository.GetQueuedVersion();
if (queued != null) if (queued != null)
{ {
// Remove the queued installation, in case something goes wrong then at least we don't end up in a loop // Remove the queued installation, in case something goes wrong then at least we don't end up in a loop
_logger.Information("Installing queued version {Version}", queued); _logger.Information("Installing queued version {Version}", queued.Version);
RestartForUpdate(true); RestartForUpdate(true);
return; return;
} }
// If a different version was installed, mark it as such // If a different version was installed, mark it as such
string? installed = _releaseRepository.GetInstalledVersion(); ReleaseEntity? installed = _releaseRepository.GetInstalledVersion();
if (installed != Constants.CurrentVersion) if (installed?.Version != Constants.CurrentVersion)
_releaseRepository.FinishInstallation(Constants.CurrentVersion); _releaseRepository.FinishInstallation(Constants.CurrentVersion);
PreviousVersion = _releaseRepository.GetPreviousInstalledVersion(); PreviousVersion = _releaseRepository.GetPreviousInstalledVersion()?.Version;
if (!Directory.Exists(Path.Combine(Constants.DataFolder, "updating")))
return;
// Clean up the update folder, leaving only the last ZIP
foreach (string file in Directory.GetFiles(Path.Combine(Constants.DataFolder, "updating")))
{
if (Path.GetExtension(file) != ".zip")
continue;
if (installed != null && Path.GetFileName(file) == $"{installed.ReleaseId}.zip")
continue;
try
{
_logger.Debug("Cleaning up old update file at {FilePath}", file);
File.Delete(file);
}
catch (Exception e)
{
_logger.Warning(e, "Failed to clean up old update file at {FilePath}", file);
}
}
} }
private void ShowUpdateNotification(IGetNextRelease_NextPublishedRelease release) private void ShowUpdateNotification(IGetNextRelease_NextPublishedRelease release)
@ -120,6 +140,10 @@ public class UpdateService : IUpdateService
} }
} }
public string Channel { get; }
public string? PreviousVersion { get; set; }
public IGetNextRelease_NextPublishedRelease? CachedLatestRelease { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public async Task CacheLatestRelease() public async Task CacheLatestRelease()
{ {
@ -159,9 +183,9 @@ public class UpdateService : IUpdateService
} }
/// <inheritdoc /> /// <inheritdoc />
public void QueueUpdate(string version) public void QueueUpdate(string version, string releaseId)
{ {
_releaseRepository.QueueInstallation(version); _releaseRepository.QueueInstallation(version, releaseId);
} }
/// <inheritdoc /> /// <inheritdoc />