mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
Introduce install checkpoint support and resume logic for updates, plus related locking and validation. Adds InstallCheckpoint model, AppJsonContext serialization, and UpdatePaths helpers for deployment lock, apply-in-progress lock and install-checkpoint path. UpdateEngineService gains checkpoint load/save/delete, incoming-state validation, resume logic for PLONDS and legacy updates, apply lock handling, and safer cleanup; ApplyPendingPlondsUpdateAsync and ApplyPendingUpdate flow updated accordingly. Add DeploymentLock contract and extend UpdateState with pause/resume/cancel helpers. Tests updated to cover stale/valid checkpoint resume and legacy/PLONDS flows. CI: enhance ddss-publish to detect release channel, validate S3 assets, prepare and atomically publish channel pointer; add ddss-rollback workflow to publish rollbacks; adjust plonds-build concurrency and release events.
84 lines
3.4 KiB
C#
84 lines
3.4 KiB
C#
namespace LanMountainDesktop.Shared.Contracts.Update;
|
|
|
|
public static class UpdatePaths
|
|
{
|
|
private const string LauncherDirectoryName = ".Launcher";
|
|
private const string UpdateDirectoryName = "update";
|
|
private const string IncomingDirectoryName = "incoming";
|
|
private const string ObjectsDirectoryName = "objects";
|
|
private const string SnapshotsDirectoryName = "snapshots";
|
|
|
|
public static string ResolveLauncherRoot(string appBaseDirectory)
|
|
{
|
|
var trimmed = appBaseDirectory.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
|
var parent = Path.GetDirectoryName(trimmed);
|
|
return string.IsNullOrWhiteSpace(parent) ? appBaseDirectory : parent;
|
|
}
|
|
|
|
public static string GetLauncherDataRoot(string launcherRoot)
|
|
{
|
|
return Path.Combine(launcherRoot, LauncherDirectoryName);
|
|
}
|
|
|
|
public static string GetIncomingDirectory(string launcherRoot)
|
|
{
|
|
return Path.Combine(launcherRoot, LauncherDirectoryName, UpdateDirectoryName, IncomingDirectoryName);
|
|
}
|
|
|
|
public static string GetObjectsDirectory(string launcherRoot)
|
|
{
|
|
return Path.Combine(GetIncomingDirectory(launcherRoot), ObjectsDirectoryName);
|
|
}
|
|
|
|
public static string GetSnapshotsDirectory(string launcherRoot)
|
|
{
|
|
return Path.Combine(launcherRoot, LauncherDirectoryName, SnapshotsDirectoryName);
|
|
}
|
|
|
|
public static string GetDownloadMarkerPath(string launcherRoot)
|
|
{
|
|
return Path.Combine(GetIncomingDirectory(launcherRoot), ".download-complete");
|
|
}
|
|
|
|
public static string GetPlondsFileMapName() => "plonds-filemap.json";
|
|
public static string GetPlondsSignatureName() => "plonds-filemap.sig";
|
|
public static string GetPlondsUpdateMetadataName() => "plonds-update.json";
|
|
public static string GetLegacyFileMapName() => "files.json";
|
|
public static string GetLegacySignatureName() => "files.json.sig";
|
|
public static string GetLegacyArchiveName() => "update.zip";
|
|
public static string GetPublicKeyFileName() => "public-key.pem";
|
|
|
|
public static string GetPlondsFileMapPath(string launcherRoot)
|
|
=> Path.Combine(GetIncomingDirectory(launcherRoot), GetPlondsFileMapName());
|
|
|
|
public static string GetPlondsSignaturePath(string launcherRoot)
|
|
=> Path.Combine(GetIncomingDirectory(launcherRoot), GetPlondsSignatureName());
|
|
|
|
public static string GetDeploymentLockName() => "deployment.lock";
|
|
|
|
public static string GetDeploymentLockPath(string launcherRoot)
|
|
=> Path.Combine(GetIncomingDirectory(launcherRoot), GetDeploymentLockName());
|
|
|
|
public static string GetApplyInProgressLockName() => "apply-in-progress.lock";
|
|
|
|
public static string GetApplyInProgressLockPath(string launcherRoot)
|
|
=> Path.Combine(GetIncomingDirectory(launcherRoot), GetApplyInProgressLockName());
|
|
|
|
public static string GetInstallCheckpointName() => "install-checkpoint.json";
|
|
|
|
public static string GetInstallCheckpointPath(string launcherRoot)
|
|
=> Path.Combine(GetIncomingDirectory(launcherRoot), GetInstallCheckpointName());
|
|
|
|
public static string GetDownloadMarkerContent(string manifestSha256, string targetVersion, int objectCount)
|
|
{
|
|
return $$"""
|
|
{
|
|
"manifestSha256": "{{manifestSha256}}",
|
|
"targetVersion": "{{targetVersion}}",
|
|
"objectCount": {{objectCount}},
|
|
"completedAt": "{{DateTimeOffset.UtcNow:O}}"
|
|
}
|
|
""";
|
|
}
|
|
}
|