-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
Microsoft.Extensions.Hosting.SystemdHostBuilderExtensions.AddSystemd() calls SystemdHelpers.IsSystemdService() to determine whether it should add the SystemdNotifier and SystemdLifetime services to the services container.
IsSystemdService() goes out of its way to try and verify that its parent process is actually called "systemd", and also has an additional edgecase for PID 1 for if it is invoked in a service container.
I can't see any reason why the check needs to be this strict and specific. It also appears to have a few drawbacks:
-
This check only works with services directly invoked from systemd, but this isn't actually required.
AddSystemd()is primarily concerned with notifying theNOTIFY_SOCKET(akasd_notify) that the service has started up or is shutting down. Non-systemd systems often include tools like start-stop-daemon which also support a minimalNOTIFY_SOCKETinterface, but are needlessly excluded by this check. -
This check causes false positives when the service is invoked from systemd on an interactive shell, for example: UseSystemd can detect an interactive shell as
running as systemd serviceextensions#2525. AFAIK this issue is marked as resolved but has not actually been fixed. -
This check causes a false positive if the service is not configured as
Type=notify. -
The code is more complicated and requires a workaround for container invocation where the PID is 1 and there is no parent systemd process.
A significantly simpler and more robust solution would be to only check for the presence of the NOTIFY_SOCKET environment variable (and also that we're on Unix). If NOTIFY_SOCKET is set, it should be notified, otherwise don't notify it. The presence of the environment variable should be enough of an indication that the interface is supported and notification is required.
The current SystemdHelpers.IsSystemdService() could still be used for changing the log format.
Example of AddSystemd() with changes:
public static IServiceCollection AddSystemd(this IServiceCollection services)
{
ThrowHelper.ThrowIfNull(services);
if (SystemdHelpers.IsSystemdService())
{
services.Configure<ConsoleLoggerOptions>(options =>
{
options.FormatterName = ConsoleFormatterNames.Systemd;
});
}
if (Environment.OSVersion.Platform == PlatformID.Unix &&
!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("NOTIFY_SOCKET")))
{
services.AddSingleton<ISystemdNotifier, SystemdNotifier>();
services.AddSingleton<IHostLifetime, SystemdLifetime>();
}
return services;
}Does this seem like a sensible change to consider?