Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#139 - Fix Launcher not starting on Systemd & multiple installations #154

Merged
merged 37 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
4505276
fixing Launcher not starting on Systemd
forsthug Jan 12, 2024
b04c2e8
as merge to main is againnot woking start logging again
forsthug Jan 12, 2024
1b9dd66
..
forsthug Jan 12, 2024
855b349
readd isSystemd
forsthug Jan 12, 2024
2e8b943
exclude linux
forsthug Jan 12, 2024
14bf566
..
forsthug Jan 12, 2024
8b650f8
add Systemd Lifetime
forsthug Jan 12, 2024
54b3ed3
check service installed
forsthug Jan 15, 2024
ae2c75c
..
forsthug Jan 15, 2024
debee08
..
forsthug Jan 15, 2024
ee47ce3
..
forsthug Jan 15, 2024
38b5983
..
forsthug Jan 15, 2024
cdcb9cd
exit code
forsthug Jan 15, 2024
93c30d0
..
forsthug Jan 15, 2024
0d86c0d
..
forsthug Jan 15, 2024
9318b36
tmp remove timeout
volllly Jan 17, 2024
cee31dc
Revert "tmp remove timeout"
volllly Jan 17, 2024
367bf80
set timoustartSeec
forsthug Jan 18, 2024
bfd3a58
..
forsthug Jan 18, 2024
0dd1769
added logging of service type
volllly Jan 22, 2024
b8cf8b7
Merge branch '#139-Error-installing-launcher-twice' of github.com:fis…
volllly Jan 22, 2024
5080556
add customized systemdHelper
forsthug Jan 23, 2024
cfea3c1
use custom lifetime in run
forsthug Jan 23, 2024
db831be
..
forsthug Jan 23, 2024
37448ed
test
forsthug Jan 24, 2024
aed63b5
add Servicetype
forsthug Jan 24, 2024
2657ae8
..
forsthug Jan 24, 2024
713ec48
..
forsthug Jan 24, 2024
07479e3
..
forsthug Jan 24, 2024
c1f49b8
..
forsthug Jan 24, 2024
2297e11
..
forsthug Jan 24, 2024
39cdd64
..
forsthug Jan 24, 2024
928f23f
log env var
volllly Jan 24, 2024
44fd186
fix systemd spawning
volllly Jan 24, 2024
0abf2c3
fix
volllly Jan 24, 2024
a4f2f4d
still use keyring
volllly Jan 25, 2024
9b5f6ed
Merge branch 'main' into #139-Error-installing-launcher-twice
volllly Jan 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Serilog.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="SemanticVersioning" Version="2.0.2" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="7.0.12" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="8.0.1" />
</ItemGroup>

</Project>
</Project>
28 changes: 20 additions & 8 deletions src/fiskaltrust.Launcher/Commands/Common.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,23 @@ public static async Task<int> HandleAsync<O, S>(
ECDiffieHellman? clientEcdh = null;
try
{
clientEcdh = await LoadCurve(launcherConfiguration.CashboxId!.Value, launcherConfiguration.AccessToken!, launcherConfiguration.ServiceFolder!, launcherConfiguration.UseOffline!.Value, useFallback: launcherConfiguration.UseLegacyDataProtection!.Value);
using var downloader = new ConfigurationDownloader(launcherConfiguration);
var exists = await downloader.DownloadConfigurationAsync(clientEcdh);
if (launcherConfiguration.UseOffline!.Value && !exists)
clientEcdh = await LoadCurve(launcherConfiguration.CashboxId!.Value, launcherConfiguration.AccessToken!, launcherConfiguration.ServiceFolder!, launcherConfiguration.UseOffline!.Value);
}
catch (Exception e)
{
Log.Fatal(e, "Could not load client curve.");
}

try
{
if (clientEcdh is not null)
{
Log.Warning("Cashbox configuration was not downloaded because UseOffline is set.");
using var downloader = new ConfigurationDownloader(launcherConfiguration);
var exists = await downloader.DownloadConfigurationAsync(clientEcdh);
if (launcherConfiguration.UseOffline!.Value && !exists)
{
Log.Warning("Cashbox configuration was not downloaded because UseOffline is set.");
}
}
}
catch (Exception e)
Expand Down Expand Up @@ -192,7 +203,7 @@ public static async Task<int> HandleAsync<O, S>(
try
{
cashboxConfiguration = CashBoxConfigurationExt.Deserialize(await File.ReadAllTextAsync(launcherConfiguration.CashboxConfigurationFile!));
cashboxConfiguration.Decrypt(launcherConfiguration, clientEcdh);
if (clientEcdh is not null) { cashboxConfiguration.Decrypt(launcherConfiguration, clientEcdh); }
}
catch (Exception e)
{
Expand Down Expand Up @@ -224,6 +235,7 @@ public static async Task<int> HandleAsync<O, S>(
Log.Debug("Cashbox Configuration File: {CashboxConfigurationFile}", launcherConfiguration.CashboxConfigurationFile);
Log.Debug("Launcher Configuration: {@LauncherConfiguration}", launcherConfiguration.Redacted());

Log.Debug("Launcher running as {ServiceType}", Enum.GetName(typeof(ServiceTypes), host.Services.GetRequiredService<ServiceType>().Type));

var dataProtectionProvider = DataProtectionExtensions.Create(launcherConfiguration.AccessToken, useFallback: launcherConfiguration.UseLegacyDataProtection!.Value);

Expand All @@ -236,12 +248,12 @@ public static async Task<int> HandleAsync<O, S>(
Log.Warning(e, "Error decrypring launcher configuration file.");
}

return await handler(options, new CommonProperties(launcherConfiguration, cashboxConfiguration, clientEcdh, dataProtectionProvider), specificOptions, host.Services.GetRequiredService<S>());
return await handler(options, new CommonProperties(launcherConfiguration, cashboxConfiguration, clientEcdh!, dataProtectionProvider), specificOptions, host.Services.GetRequiredService<S>());
}

private static async Task EnsureServiceDirectoryExists(LauncherConfiguration config)
{
var serviceDirectory = config.ServiceFolder;
var serviceDirectory = config.ServiceFolder!;
try
{
if (!Directory.Exists(serviceDirectory))
Expand Down
7 changes: 0 additions & 7 deletions src/fiskaltrust.Launcher/Commands/RunCommand.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.CommandLine;
using System.CommandLine.Invocation;
using fiskaltrust.Launcher.ProcessHost;
using fiskaltrust.Launcher.Services;
using Serilog;
Expand All @@ -8,12 +7,6 @@
using fiskaltrust.Launcher.Extensions;
using fiskaltrust.Launcher.Helpers;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using fiskaltrust.Launcher.Common.Configuration;
using fiskaltrust.storage.serialization.V0;
using System.Security.Cryptography;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;


namespace fiskaltrust.Launcher.Commands
Expand Down
103 changes: 101 additions & 2 deletions src/fiskaltrust.Launcher/Extensions/LifetimeExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using Microsoft.Extensions.Hosting.Systemd;
using Microsoft.Extensions.Hosting.WindowsServices;
using Microsoft.Extensions.Options;

namespace fiskaltrust.Launcher.Extensions
{
public record ServiceType(ServiceTypes Type);

public enum ServiceTypes
{
WindowsService,
SystemdService,
ConsoleApplication
}

static class LifetimeExtensions
{
public static IHostBuilder UseCustomHostLifetime(this IHostBuilder builder)
Expand All @@ -15,6 +27,7 @@ public static IHostBuilder UseCustomHostLifetime(this IHostBuilder builder)

return builder.ConfigureServices(services =>
{
services.AddSingleton(new ServiceType(ServiceTypes.WindowsService));
var lifetime = services.FirstOrDefault(s => s.ImplementationType == typeof(WindowsServiceLifetime));

if (lifetime != null)
Expand All @@ -28,10 +41,29 @@ public static IHostBuilder UseCustomHostLifetime(this IHostBuilder builder)
#pragma warning restore CA1416
});
}
else if (SystemdHelpers.IsSystemdService())
{
builder.UseSystemd();

return builder.ConfigureServices(services =>
{
services
.AddSingleton(new ServiceType(ServiceTypes.SystemdService))
.AddSingleton<ILifetime, Lifetime>();

// #pragma warning disable CA1416
// services.AddSingleton<ILifetime, CustomSystemDServiceLifetime>();
// services.AddSingleton<IHostLifetime>(sp => sp.GetRequiredService<ILifetime>());
// #pragma warning restore CA1416
});
}
else
{
Console.OutputEncoding = Encoding.UTF8;
builder.ConfigureServices(services => services.AddSingleton<ILifetime, Lifetime>());
builder.ConfigureServices(services => services
.AddSingleton<ILifetime, Lifetime>()
.AddSingleton(new ServiceType(ServiceTypes.ConsoleApplication)));

builder.UseConsoleLifetime();
return builder;
}
Expand Down Expand Up @@ -96,7 +128,7 @@ public CustomWindowsServiceLifetime(

public void ServiceStartupCompleted()
{
ApplicationLifetime.ApplicationStarted.Register(() => _started.Set());
ApplicationLifetime.ApplicationStarted.Register(_started.Set);
}

public new async Task WaitForStartAsync(CancellationToken cancellationToken)
Expand Down Expand Up @@ -133,4 +165,71 @@ protected override void Dispose(bool disposing)
base.Dispose(disposing);
}
}

[SupportedOSPlatform("linux")]
public class CustomSystemDServiceLifetime : ILifetime, IHostLifetime, IDisposable
{
private readonly CancellationTokenSource _started = new();
private readonly ISystemdNotifier _systemdNotifier;
public IHostApplicationLifetime ApplicationLifetime { get; init; }

private CancellationTokenRegistration _applicationStartedRegistration;
private CancellationTokenRegistration _applicationStoppingRegistration;
private PosixSignalRegistration? _sigTermRegistration;

public CustomSystemDServiceLifetime(
IHostApplicationLifetime applicationLifetime,
ISystemdNotifier systemdNotifier)
{
ApplicationLifetime = applicationLifetime;
_systemdNotifier = systemdNotifier;
}

public void ServiceStartupCompleted() => _started.Cancel();

public Task WaitForStartAsync(CancellationToken cancellationToken)
{
_applicationStartedRegistration = ApplicationLifetime.ApplicationStarted.Register(OnApplicationStarted);
_applicationStoppingRegistration = ApplicationLifetime.ApplicationStopping.Register(OnApplicationStopping);

RegisterShutdownHandlers();

return Task.CompletedTask;
}

private void OnApplicationStarted()
{
var cts = CancellationTokenSource.CreateLinkedTokenSource(_started.Token, ApplicationLifetime.ApplicationStopping);

cts.Token.Register(() =>
{
_systemdNotifier.Notify(ServiceState.Stopping);
});
}

private void OnApplicationStopping() => _systemdNotifier.Notify(ServiceState.Stopping);

public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;

private void RegisterShutdownHandlers() => _sigTermRegistration = PosixSignalRegistration.Create(PosixSignal.SIGTERM, HandlePosixSignal);

private void HandlePosixSignal(PosixSignalContext context)
{
Debug.Assert(context.Signal == PosixSignal.SIGTERM);

context.Cancel = true;
ApplicationLifetime.StopApplication();
}

private void UnregisterShutdownHandlers() => _sigTermRegistration?.Dispose();

public void Dispose()
{
_started.Cancel();

UnregisterShutdownHandlers();
_applicationStartedRegistration.Dispose();
_applicationStoppingRegistration.Dispose();
}
}
}
8 changes: 4 additions & 4 deletions src/fiskaltrust.Launcher/Helpers/ProcessHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ namespace fiskaltrust.Launcher.Helpers;
public static class ProcessHelper
{
public static async Task<(int exitCode, string output)> RunProcess(
string fileName,
IEnumerable<string> arguments,
LogEventLevel logLevel = LogEventLevel.Information)
string fileName,
IEnumerable<string> arguments,
LogEventLevel? logLevel = LogEventLevel.Information)
{
var process = new Process
{
Expand All @@ -30,7 +30,7 @@ public static class ProcessHelper
var stdOut = await process.StandardOutput.ReadToEndAsync();
if (!string.IsNullOrEmpty(stdOut))
{
Log.Write(logLevel, stdOut);
if (logLevel is not null) { Log.Write(logLevel.Value, stdOut); }
}

var stdErr = await process.StandardError.ReadToEndAsync();
Expand Down
14 changes: 7 additions & 7 deletions src/fiskaltrust.Launcher/ProcessHost/ProcessHostMonarch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ public ProcessHostMonarch(ILogger<ProcessHostMonarch> logger, LauncherConfigurat

_stopped = new TaskCompletionSource();
_started = new TaskCompletionSource();

// if (Debugger.IsAttached)
// {
// _process.StartInfo.Arguments += " --debugging";
// }
}

private void Setup()
Expand All @@ -61,11 +56,11 @@ private void Setup()
UseShellExecute = false,
FileName = _launcherExecutablePath.Path,
CreateNoWindow = false,
Arguments = string.Join(" ", new string[] {
Arguments = string.Join(" ", [
"host",
"--plebeian-configuration", $"\"{Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(new PlebeianConfiguration { PackageType = _packageType, PackageId = _packageConfiguration.Id }.Serialize()))}\"",
"--launcher-configuration", $"\"{Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(_launcherConfiguration.Serialize()))}\"",
}),
]),
RedirectStandardInput = true,
RedirectStandardError = true,
RedirectStandardOutput = true
Expand All @@ -75,6 +70,11 @@ private void Setup()

_process.OutputDataReceived += ReceiveStdOut;
_process.ErrorDataReceived += ReceiveStdOut;

// if (Debugger.IsAttached && _packageType == PackageType.Helper)
// {
// _process.StartInfo.Arguments += " --debugging";
// }
}

private void ReceiveStdOut(object sender, DataReceivedEventArgs e)
Expand Down
2 changes: 1 addition & 1 deletion src/fiskaltrust.Launcher/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

if (!args.Any())
{
args = new[] { runCommand.Name };
args = [runCommand.Name];
}

var subArguments = new SubArguments(args.SkipWhile(a => a != "--").Skip(1));
Expand Down
Loading
Loading