mirror of
https://github.com/MAKS-IT-COM/maksit-certs-ui.git
synced 2026-05-16 12:58:11 +02:00
(bugfix): resolved backend database sturtup initialization, npgsql missing container package
This commit is contained in:
parent
f43bd04157
commit
d8cb164de9
11
CHANGELOG.md
11
CHANGELOG.md
@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [3.3.8] - 2026-04-26
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **Startup / database:** `InitializationHostedService` now runs FluentMigrator (`EnsureCertsEngineMigratedAsync`) before acquiring the bootstrap PostgreSQL lease, so `app_runtime_leases` exists on an empty database (same ordering idea as Vault: migrate first, then coordination).
|
||||||
|
- **Startup:** While waiting for the bootstrap lease, migrations are not re-run on every poll interval (`migrationsApplied` guard).
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **Container image:** `MaksIT.CertsUI` Dockerfile installs `libgssapi-krb5-2` so Npgsql can load GSS/Kerberos support without missing-library warnings on slim `aspnet` images.
|
||||||
|
|
||||||
## [3.3.7] - 2026-04-25
|
## [3.3.7] - 2026-04-25
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="147.5" height="20" role="img" aria-label="Branch Coverage: 7.9%">
|
<svg xmlns="http://www.w3.org/2000/svg" width="147.5" height="20" role="img" aria-label="Branch Coverage: 7.8%">
|
||||||
<title>Branch Coverage: 7.9%</title>
|
<title>Branch Coverage: 7.8%</title>
|
||||||
<linearGradient id="s" x2="0" y2="100%">
|
<linearGradient id="s" x2="0" y2="100%">
|
||||||
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
||||||
<stop offset="1" stop-opacity=".1"/>
|
<stop offset="1" stop-opacity=".1"/>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="11">
|
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="11">
|
||||||
<text aria-hidden="true" x="53.75" y="15" fill="#010101" fill-opacity=".3">Branch Coverage</text>
|
<text aria-hidden="true" x="53.75" y="15" fill="#010101" fill-opacity=".3">Branch Coverage</text>
|
||||||
<text x="53.75" y="14" fill="#fff">Branch Coverage</text>
|
<text x="53.75" y="14" fill="#fff">Branch Coverage</text>
|
||||||
<text aria-hidden="true" x="127.5" y="15" fill="#010101" fill-opacity=".3">7.9%</text>
|
<text aria-hidden="true" x="127.5" y="15" fill="#010101" fill-opacity=".3">7.8%</text>
|
||||||
<text x="127.5" y="14" fill="#fff">7.9%</text>
|
<text x="127.5" y="14" fill="#fff">7.8%</text>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
@ -21,6 +21,11 @@ ARG BUILD_CONFIGURATION=Release
|
|||||||
RUN dotnet publish "./MaksIT.CertsUI.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
RUN dotnet publish "./MaksIT.CertsUI.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||||
|
|
||||||
FROM base AS final
|
FROM base AS final
|
||||||
|
USER root
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends libgssapi-krb5-2 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=publish /app/publish .
|
COPY --from=publish /app/publish .
|
||||||
|
USER app
|
||||||
ENTRYPOINT ["dotnet", "MaksIT.CertsUI.dll"]
|
ENTRYPOINT ["dotnet", "MaksIT.CertsUI.dll"]
|
||||||
@ -8,7 +8,8 @@ namespace MaksIT.CertsUI.HostedServices;
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Runs startup initialization (migrations + identity bootstrap) before the API starts serving requests.
|
/// Runs startup initialization (migrations + identity bootstrap) before the API starts serving requests.
|
||||||
/// Uses a PostgreSQL lease so only one replica runs migrations at a time.
|
/// FluentMigrator runs first on every instance (same pattern as Vault); the bootstrap lease then ensures
|
||||||
|
/// only one replica performs identity bootstrap against shared <see cref="Configuration.CertsUIEngineConfiguration.DataFolder"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class InitializationHostedService(
|
public sealed class InitializationHostedService(
|
||||||
ILogger<InitializationHostedService> logger,
|
ILogger<InitializationHostedService> logger,
|
||||||
@ -22,11 +23,18 @@ public sealed class InitializationHostedService(
|
|||||||
|
|
||||||
public async Task StartAsync(CancellationToken cancellationToken) {
|
public async Task StartAsync(CancellationToken cancellationToken) {
|
||||||
const int delayMilliseconds = 2000;
|
const int delayMilliseconds = 2000;
|
||||||
|
var migrationsApplied = false;
|
||||||
|
|
||||||
while (!cancellationToken.IsCancellationRequested) {
|
while (!cancellationToken.IsCancellationRequested) {
|
||||||
try {
|
try {
|
||||||
logger.LogInformation("Running startup initialization...");
|
logger.LogInformation("Running startup initialization...");
|
||||||
|
|
||||||
|
// Migrations must run before lease acquisition: app_runtime_leases is created by FluentMigrator.
|
||||||
|
if (!migrationsApplied) {
|
||||||
|
await serviceProvider.EnsureCertsEngineMigratedAsync().ConfigureAwait(false);
|
||||||
|
migrationsApplied = true;
|
||||||
|
}
|
||||||
|
|
||||||
var holder = runtimeInstance.InstanceId;
|
var holder = runtimeInstance.InstanceId;
|
||||||
var acquired = await runtimeLease.TryAcquireAsync(RuntimeLeaseNames.Bootstrap, holder, BootstrapLeaseTtl, cancellationToken).ConfigureAwait(false);
|
var acquired = await runtimeLease.TryAcquireAsync(RuntimeLeaseNames.Bootstrap, holder, BootstrapLeaseTtl, cancellationToken).ConfigureAwait(false);
|
||||||
if (!acquired.IsSuccess)
|
if (!acquired.IsSuccess)
|
||||||
@ -38,8 +46,6 @@ public sealed class InitializationHostedService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await serviceProvider.EnsureCertsEngineMigratedAsync().ConfigureAwait(false);
|
|
||||||
|
|
||||||
await using var scope = serviceProvider.CreateAsyncScope();
|
await using var scope = serviceProvider.CreateAsyncScope();
|
||||||
var identityDomainService = scope.ServiceProvider.GetRequiredService<IIdentityDomainService>();
|
var identityDomainService = scope.ServiceProvider.GetRequiredService<IIdentityDomainService>();
|
||||||
await EnsureIdentityInitializedAsync(appSettings.Value, identityDomainService, cancellationToken).ConfigureAwait(false);
|
await EnsureIdentityInitializedAsync(appSettings.Value, identityDomainService, cancellationToken).ConfigureAwait(false);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>3.3.7</Version>
|
<Version>3.3.8</Version>
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user