@inherits ShadcnBlazor.Extras.Dialogs.DialogBase @using System.Text.Json @using LucideBlazor @using Moonlight.Shared.Http @using Moonlight.Shared.Http.Events @using Moonlight.Shared.Http.Requests.Admin.ContainerHelper @using ShadcnBlazor.Buttons @using ShadcnBlazor.Dialogs @using ShadcnBlazor.Progresses @using ShadcnBlazor.Spinners @inject HttpClient HttpClient Updating instance to @Version...
@for (var i = 0; i < Steps.Length; i++) { if (CurrentStep == i) {
@if (IsFailed) { } else { } @Steps[i]
} else { if (i < CurrentStep) {
@Steps[i]
} else {
@Steps[i]
} } }
@for (var i = LogLines.Count - 1; i >= 0; i--) {
@LogLines[i]
}
@if (CurrentStep == Steps.Length || IsFailed) { } else { } @code { [Parameter] public string Version { get; set; } [Parameter] public bool NoBuildCache { get; set; } private bool IsFailed; private int Progress; private int CurrentStep; private readonly string[] Steps = [ "Checking", // 0 "Updating configuration files", // 1 "Starting rebuild task", // 2 "Building docker image", // 3 "Redeploying container instance", // 4 "Waiting for container instance to start up", // 5 "Update complete" // 6 ]; private readonly List LogLines = new(); protected override async Task OnAfterRenderAsync(bool firstRender) { if (!firstRender) return; // Checking CurrentStep = 0; Progress = 0; await InvokeAsync(StateHasChanged); await Task.Delay(2000); // Update configuration CurrentStep = 1; Progress = 20; await InvokeAsync(StateHasChanged); await HttpClient.PostAsJsonAsync("api/admin/ch/version", new SetVersionDto() { Version = Version }, SerializationContext.Default.Options); // Starting rebuild task CurrentStep = 2; Progress = 30; await InvokeAsync(StateHasChanged); var request = new HttpRequestMessage(HttpMethod.Post, "api/admin/ch/rebuild"); request.Content = JsonContent.Create( new RequestRebuildDto(NoBuildCache), null, SerializationContext.Default.Options ); var response = await HttpClient.SendAsync( request, HttpCompletionOption.ResponseHeadersRead ); await using var responseStream = await response.Content.ReadAsStreamAsync(); using var streamReader = new StreamReader(responseStream); do { try { var line = await streamReader.ReadLineAsync(); if (line == null) break; if (string.IsNullOrWhiteSpace(line)) continue; var data = line.Trim("data: "); var deserializedData = JsonSerializer.Deserialize(data, SerializationContext.Default.Options); switch (deserializedData.Type) { case RebuildEventType.Log: LogLines.Add(deserializedData.Data); break; case RebuildEventType.Step: switch (deserializedData.Data) { case "BuildImage": // Building docker image CurrentStep = 3; Progress = 40; await InvokeAsync(StateHasChanged); break; case "ServiceDown": // Redeploying container instance CurrentStep = 4; Progress = 60; await InvokeAsync(StateHasChanged); break; } break; case RebuildEventType.Failed: IsFailed = true; await InvokeAsync(StateHasChanged); return; } await InvokeAsync(StateHasChanged); } catch (Exception) { break; } } while (true); // Waiting for container instance to start up CurrentStep = 5; Progress = 90; await InvokeAsync(StateHasChanged); // Wait some time for instance to shut down await Task.Delay(TimeSpan.FromSeconds(5)); // Ping instance until its reachable again while (true) { try { await HttpClient.GetStringAsync("api/ping"); break; } catch (Exception) { // Ignored } await Task.Delay(3000); } // Update complete CurrentStep = 7; Progress = 100; await InvokeAsync(StateHasChanged); } }