Skip to content

Commit

Permalink
Systemd support (#60)
Browse files Browse the repository at this point in the history
* enable systemd support

Signed-off-by: clemensv <[email protected]>
  • Loading branch information
clemensv authored Sep 20, 2022
1 parent e969c35 commit 44cf8e1
Show file tree
Hide file tree
Showing 14 changed files with 78 additions and 98 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/main-ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ jobs:
- name: Build for Fedora 30-x64
run: dotnet msbuild /t:Restore,Package /p:WindowsOnly=false /p:RuntimeIdentifier=fedora.34-x64 /p:Configuration=Release /p:TargetFramework=net6.0 /p:VersionSuffix=rel
if: matrix.os == 'ubuntu-latest'
- name: Build for CentOS 9-x64
run: dotnet msbuild /t:Restore,Package /p:WindowsOnly=false /p:RuntimeIdentifier=centos.9-x64 /p:Configuration=Release /p:TargetFramework=net6.0 /p:VersionSuffix=rel
if: matrix.os == 'ubuntu-latest'

- name: Unit Test Windows x64
env:
Expand Down
5 changes: 4 additions & 1 deletion build/repo.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
<TargetFrameworks>$(CoreFrameworks)</TargetFrameworks>
<TargetFramework Condition="'$(TargetFramework)'==''">net6.0</TargetFramework>
<WindowsRuntimeIdentifiers Condition="'$(OS)'=='Windows_NT'">win10-x64;win10-x86;win10-arm64;</WindowsRuntimeIdentifiers>
<UnixRuntimeIdentifiers Condition="'$(WindowsOnly)'=='false'">osx-x64;debian.10-x64;ubuntu.18.04-x64;ubuntu.18.04-arm64;ubuntu.20.04-x64;ubuntu.20.04-arm64;opensuse.15.0-x64;fedora.34-x64</UnixRuntimeIdentifiers>
<UnixRuntimeIdentifiers Condition="'$(WindowsOnly)'=='false'">osx-x64;debian.10-x64;ubuntu.18.04-x64;ubuntu.18.04-arm64;ubuntu.20.04-x64;ubuntu.20.04-arm64;opensuse.15.0-x64;fedora.34-x64;centos.9-x64</UnixRuntimeIdentifiers>
<RuntimeIdentifiers>$(WindowsRuntimeIdentifiers)$(UnixRuntimeIdentifiers)</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="'$(OS)' == 'Windows_NT' OR $(RuntimeIdentifier.StartsWith('win'))">
<DefineConstants>_WINDOWS</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith('ubuntu')) OR $(RuntimeIdentifier.StartsWith('debian')) OR $(RuntimeIdentifier.StartsWith('rhel')) OR $(RuntimeIdentifier.StartsWith('centos')) OR $(RuntimeIdentifier.StartsWith('fedora')) ">
<DefineConstants>_SYSTEMD</DefineConstants>
</PropertyGroup>
<ItemGroup>
<DotNetCoreRuntime Include="$(MicrosoftNETCoreAppPackageVersion)" />
</ItemGroup>
Expand Down
7 changes: 4 additions & 3 deletions package-all.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ echo *** Building and packaging Windows Targets

if %_DOCKER_BUILD% == "true" (
echo *** Windows only
dotnet msbuild /t:clean,restore,package /p:Configuration=Release /p:WindowsOnly=true /p:TargetFramework=net6.0 /p:RuntimeIdentifier=win10-x64 %*
dotnet msbuild /t:clean,restore,Package /p:Configuration=Release /p:WindowsOnly=true /p:TargetFramework=net6.0 /p:RuntimeIdentifier=win10-arm64 %*
dotnet msbuild /t:clean,restore,Package /p:Configuration=Release /p:WindowsOnly=true /p:TargetFramework=net6.0 /p:RuntimeIdentifier=win10-x86 %*
dotnet msbuild /t:restore,package /p:Configuration=Release /p:WindowsOnly=true /p:TargetFramework=net6.0 /p:RuntimeIdentifier=win10-x64 %*
dotnet msbuild /t:restore,Package /p:Configuration=Release /p:WindowsOnly=true /p:TargetFramework=net6.0 /p:RuntimeIdentifier=win10-arm64 %*
dotnet msbuild /t:restore,Package /p:Configuration=Release /p:WindowsOnly=true /p:TargetFramework=net6.0 /p:RuntimeIdentifier=win10-x86 %*
) else (
echo *** All platforms
dotnet msbuild /t:restore,Package /p:Configuration=Release /p:WindowsOnly=true /p:TargetFramework=net6.0 /p:RuntimeIdentifier=win10-x64 %*
Expand All @@ -26,6 +26,7 @@ if %_DOCKER_BUILD% == "true" (
dotnet msbuild /t:restore,Package /p:Configuration=Release /p:WindowsOnly=false /p:TargetFramework=net6.0 /p:RuntimeIdentifier=ubuntu.20.04-arm64 %*
dotnet msbuild /t:restore,Package /p:Configuration=Release /p:WindowsOnly=false /p:TargetFramework=net6.0 /p:RuntimeIdentifier=opensuse.15.0-x64 %*
dotnet msbuild /t:restore,Package /p:Configuration=Release /p:WindowsOnly=false /p:TargetFramework=net6.0 /p:RuntimeIdentifier=fedora.34-x64 %*
dotnet msbuild /t:restore,Package /p:Configuration=Release /p:WindowsOnly=false /p:TargetFramework=net6.0 /p:RuntimeIdentifier=centos.9-x64 %*
)

if not errorlevel 0 exit /b 1
Expand Down
1 change: 1 addition & 0 deletions package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ dotnet msbuild /t:Package /p:Configuration=Release /p:WindowsOnly=false /p:Targe
dotnet msbuild /t:Package /p:Configuration=Release /p:WindowsOnly=false /p:TargetFramework=net6.0 /p:RuntimeIdentifier=ubuntu.20.04-arm64 $_BuildProp $_VersionProp $@
dotnet msbuild /t:Package /p:Configuration=Release /p:WindowsOnly=false /p:TargetFramework=net6.0 /p:RuntimeIdentifier=opensuse.15.0-x64 $_BuildProp $_VersionProp $@
dotnet msbuild /t:Package /p:Configuration=Release /p:WindowsOnly=false /p:TargetFramework=net6.0 /p:RuntimeIdentifier=fedora.34-x64 $_BuildProp $_VersionProp $@
dotnet msbuild /t:Package /p:Configuration=Release /p:WindowsOnly=false /p:TargetFramework=net6.0 /p:RuntimeIdentifier=centos.9-x64 $_BuildProp $_VersionProp $@

popd
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public class CommandLineSettings
public bool? ServiceInstall { get; set; }
[Option(CommandOptionType.NoValue, LongName = "svcuninstall", ShortName = "U", Description = "Uninstall Windows Service")]
public bool? ServiceUninstall { get; set; }
[Option(CommandOptionType.NoValue, LongName = "svc", ShortName = "svc", Description = "Reserved for Windows service control manager")]
public bool? ServiceRun { get; set; }
#endif
[Option(CommandOptionType.NoValue, LongName = "svc", ShortName = "svc", Description = "Reserved for background service invocation")]
public bool? ServiceRun { get; set; }
[Option(CommandOptionType.SingleValue, ShortName = "b", Description = "Source address of forwarding connections.")]
public string BindAddress { get; set; }
[Option(CommandOptionType.SingleValue, ShortName = "e", Description = "Relay endpoint URI")]
Expand Down
6 changes: 5 additions & 1 deletion src/azbridge/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,16 @@ static int Run(CommandLineSettings settings, string[] args)
ServiceLauncher.UninstallService();
return 0;
}
else if (settings.ServiceRun.HasValue && settings.ServiceRun.Value)
#endif
#if _WINDOWS || _SYSTEMD
if (settings.ServiceRun.HasValue && settings.ServiceRun.Value)
{
ServiceLauncher.RunAsync(settings).GetAwaiter().GetResult();
return 0;
}
#endif


if ( !string.IsNullOrEmpty(settings.ConfigFile) && !File.Exists(settings.ConfigFile))
{
Console.WriteLine($"The config file was not found: {settings.ConfigFile}");
Expand Down
19 changes: 11 additions & 8 deletions src/azbridge/RelayBridgeService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#if _WINDOWS
#if _WINDOWS || _SYSTEMD
using Microsoft.Azure.Relay.Bridge.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -47,33 +47,36 @@ public override Task StartAsync(CancellationToken cancellationToken)
}
}

public override Task StopAsync(CancellationToken cancellationToken)
public override async Task StopAsync(CancellationToken cancellationToken)
{
try
{
await base.StopAsync(cancellationToken);
if (host != null)
{
host.Stop();
host = null;
}
return base.StopAsync(cancellationToken);
}
}
catch (System.Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
Environment.Exit(1);
return Task.CompletedTask;
}
}

protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
if (host != null)
return Task.Run(() =>
{
host.Start();
}
if (host != null)
{
host.Start();
}
stoppingToken.WaitHandle.WaitOne();
});
}
catch (System.Exception ex)
{
Expand Down
84 changes: 11 additions & 73 deletions src/azbridge/ServiceLauncher.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#if _WINDOWS
#if _WINDOWS || _SYSTEMD
namespace azbridge
{
using Microsoft.Azure.Relay.Bridge.Configuration;
Expand Down Expand Up @@ -85,20 +85,25 @@ internal static async Task RunAsync(CommandLineSettings settings)
{
logLevel = LogLevel.None;
}


IHost host = Host.CreateDefaultBuilder()
#if _WINDOWS
.UseWindowsService(options =>
{
options.ServiceName = ServiceName;
})
#elif _SYSTEMD
.UseSystemd()
#endif

.ConfigureServices(services =>
{
LoggerProviderOptions.RegisterProviderOptions<EventLogSettings, EventLogLoggerProvider>(services);
services.Configure<EventLogSettings>(settings =>
{
settings.SourceName = ServiceName;
});
});
services.AddSingleton(config);
services.AddHostedService<RelayBridgeService>();
})
Expand All @@ -111,7 +116,7 @@ internal static async Task RunAsync(CommandLineSettings settings)
var dir = Path.GetDirectoryName(config.LogFileName);
var ext = Path.GetExtension(config.LogFileName);
var fileName = Path.Combine(dir, $"{fn}-{{Date}}{ext}");
logging.AddFile(fileName, logLevel);
logging.AddFile(fileName, logLevel);
}
})
.Build();
Expand Down Expand Up @@ -151,34 +156,12 @@ public static void ShellExecute(string command, string parameters)
};
process.Start();
process.WaitForExit();
if ( process.ExitCode != 0 )
if (process.ExitCode != 0)
{
throw new Exception($"Process failed with exit code {process.ExitCode}");
}
}

internal static void StartService()
{
if (!IsInstalled())
return;
#if _WINDOWS
#pragma warning disable CA1416 // Validate platform compatibility
using (ServiceController controller =
new ServiceController(ServiceName))
{
if (controller.Status != ServiceControllerStatus.Running)
{
controller.Start();
controller.WaitForStatus(ServiceControllerStatus.Running,
TimeSpan.FromSeconds(10));
}
}
#pragma warning restore CA1416 // Validate platform compatibility
#else
return true;
#endif
}

internal static bool IsInstalled()
{
#if _WINDOWS
Expand All @@ -200,51 +183,6 @@ internal static bool IsInstalled()
return true;
#endif
}

internal static bool IsRunning()
{
#if _WINDOWS
#pragma warning disable CA1416 // Validate platform compatibility

using (var controller = new ServiceController(ServiceName))
{
if (!IsInstalled())
return false;
return (controller.Status == ServiceControllerStatus.Running);
}
#pragma warning restore CA1416 // Validate platform compatibility
#else
return true;
#endif
}


internal static void StopService()
{
#if _WINDOWS
#pragma warning disable CA1416 // Validate platform compatibility
if (!IsInstalled())
return;
using (ServiceController controller =
new ServiceController(ServiceName))
{
try
{
if (controller.Status != ServiceControllerStatus.Stopped)
{
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped,
TimeSpan.FromSeconds(10));
}
}
catch
{
throw;
}
}
}
#pragma warning restore CA1416 // Validate platform compatibility
#endif
}
}
#endif
22 changes: 16 additions & 6 deletions src/azbridge/azbridge.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,20 @@
</PropertyGroup>

<Choose>
<When Condition="'$(OS)' == 'Windows_NT' OR $(RuntimeIdentifier.StartsWith('win'))">
<When Condition="$(DefineConstants.Contains('_WINDOWS'))">
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
</ItemGroup>
</Otherwise>
</Choose>


Expand All @@ -55,6 +62,9 @@
<Content Include="azbridge_config.machine.yml" CopyToPublishDirectory="PreserveNewest" Condition="! $(RuntimeIdentifier.StartsWith('win'))">
<LinuxPath>/etc/azbridge/azbridge_config.machine.yml</LinuxPath>
</Content>
<Content Include="azbridge.service" CopyToPublishDirectory="PreserveNewest" Condition="$(DefineConstants.Contains('_SYSTEMD'))">
<LinuxPath>/etc/systemd/system/azbridge.service</LinuxPath>
</Content>
<Content Include="azbridge.sh" CopyToPublishDirectory="PreserveNewest" Condition="! $(RuntimeIdentifier.StartsWith('win'))" RemoveOnUninstall="true">
<LinuxPath>/etc/profile.d/azbridge.sh</LinuxPath>
<LinuxFileMode Condition="!($(RuntimeIdentifier.StartsWith('rhel')) OR $(RuntimeIdentifier.StartsWith('fedora')) OR $(RuntimeIdentifier.StartsWith('opensuse')) OR $(RuntimeIdentifier.StartsWith('centos')))">0555</LinuxFileMode>
Expand All @@ -65,8 +75,8 @@
</ItemGroup>

<PropertyGroup>
<PostInstallScript>ln -sf /usr/share/azbridge/azbridge /usr/local/bin/azbridge</PostInstallScript>
<PostRemoveScript>rm /usr/local/bin/azbridge</PostRemoveScript>
<PostInstallScript>ln -sf /usr/share/azbridge/azbridge /usr/local/bin/azbridge;</PostInstallScript>
<PostRemoveScript>/bin/rm -f /usr/local/bin/azbridge;</PostRemoveScript>
</PropertyGroup>

<ItemGroup>
Expand Down Expand Up @@ -94,7 +104,7 @@
</ProjectReference>
</ItemGroup>

<!-- Fedora, CentOS, and RHEL dependencies -->
<!-- Debian and Ubuntu -->
<ItemGroup Condition="$(RuntimeIdentifier.StartsWith('debian')) OR $(RuntimeIdentifier.StartsWith('ubuntu')) OR $(RuntimeIdentifier.StartsWith('linuxmint'))">
<DebDependency Include="ca-certificates" Version="" />
</ItemGroup>
Expand All @@ -104,10 +114,10 @@
</ItemGroup>

<!-- Linux Daemon install properties -->
<PropertyGroup Condition="$(UnixRuntimeIdentifiers.Contains($(RuntimeIdentifier)))">
<PropertyGroup Condition="$(DefineConstants.Contains('_SYSTEMD'))">
<CreateUser>true</CreateUser>
<UserName>azbridge</UserName>
<InstallService>false</InstallService>
<InstallService>true</InstallService>
<SymlinkAppHostInBin>true</SymlinkAppHostInBin>
</PropertyGroup>

Expand Down
3 changes: 2 additions & 1 deletion src/azbridge/azbridge.service
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
Description=Azure Relay Bridge

[Service]
ExecStart=/usr/shared/azbridge
Type=notify
ExecStart=/usr/share/azbridge/azbridge --svc

[Install]
WantedBy=multi-user.target
4 changes: 2 additions & 2 deletions src/azbridge/azbridge_config.svc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ LocalForward :

LogLevel : ERROR

# Name of the log file. Not used in Windows service mode when logging is directed to
# the Windows event log.
# Name of the log file. Not used in Windows service mode or SystemD mode when logging is directed to
# the Windows event log or SystemD logs

LogFileName :

Expand Down
2 changes: 1 addition & 1 deletion test/nginx/Test.proj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<PropertyGroup>
<ImageSuffix Condition="$(RuntimeIdentifier.StartsWith('debian')) OR $(RuntimeIdentifier.StartsWith('ubuntu')) OR $(RuntimeIdentifier.StartsWith('linuxmint'))">deb</ImageSuffix>
<ImageSuffix Condition="$(RuntimeIdentifier.StartsWith('rhel')) OR $(RuntimeIdentifier.StartsWith('fedora')) OR $(RuntimeIdentifier.StartsWith('opensuse'))">rpm</ImageSuffix>
<ImageSuffix Condition="$(RuntimeIdentifier.StartsWith('rhel')) OR $(RuntimeIdentifier.StartsWith('fedora')) OR $(RuntimeIdentifier.StartsWith('opensuse')) OR $(RuntimeIdentifier.StartsWith('centos'))">rpm</ImageSuffix>
<ImageSuffix Condition="'$(ImageSuffix)' == ''">tar.gz</ImageSuffix>
</PropertyGroup>

Expand Down
8 changes: 8 additions & 0 deletions test/nginx/centos.9-x64.client.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM tgagor/centos:9 AS build1
RUN yum install -y wget >/dev/null

FROM build1 AS build2
ARG package_name
COPY ./tmp/$package_name .
RUN yum install -y ./$package_name

8 changes: 8 additions & 0 deletions test/nginx/centos.9-x64.server.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM tgagor/centos:9 AS build1
RUN yum install -y nginx >/dev/null
COPY index.html /usr/share/nginx/html

FROM build1 AS build2
ARG package_name
COPY ./tmp/$package_name .
RUN yum install -y ./$package_name

0 comments on commit 44cf8e1

Please sign in to comment.