Skip to content

Commit

Permalink
build: add RPM for gateway and agent (#1179)
Browse files Browse the repository at this point in the history
This commit adds RPM packages for Gateway and Agent to the release
assets.

`tlk.ps1 -TlkVerb package -Platform linux` now generates both a deb and
an rpm for the specified product.

The rpm is generated with fpm, a Linux packaging tool.
In CI, no cache is used for the fpm dependency since the cache would not
persist across release jobs.

The RPM includes all the assets of the corresponding Debian package,
including the changelog, copyright, maintainer scripts, and
webapp/libxmf.so for Gateway.

The changelog is copied directly from Debian. A separate PR will be made
to convert it to an RPM-friendly changelog format.

Tested with RHEL 9 (glibc 2.34).
  • Loading branch information
allan2 authored Jan 8, 2025
1 parent 8a52585 commit 3b8667d
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 24 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,10 @@ jobs:
rustup target add aarch64-unknown-linux-gnu
echo "STRIP_EXECUTABLE=aarch64-linux-gnu-strip" >> $GITHUB_ENV
- name: Install fpm
if: matrix.os == 'Linux'
run: sudo gem install --no-document fpm

- name: Configure Windows runner
if: matrix.os == 'windows'
run: |
Expand Down Expand Up @@ -602,6 +606,7 @@ jobs:
}
$Env:DGATEWAY_WEBCLIENT_PATH = Join-Path "webapp" "client" | Resolve-Path
$Env:DGATEWAY_WEBPLAYER_PATH = Join-Path "webapp" "player" | Resolve-Path
./ci/tlk.ps1 package -Product gateway -Platform ${{ matrix.os }} -Architecture ${{ matrix.arch }} -CargoProfile ${{ needs.preflight.outputs.rust-profile }}
Expand Down Expand Up @@ -698,6 +703,10 @@ jobs:
rustup target add aarch64-unknown-linux-gnu
echo "STRIP_EXECUTABLE=aarch64-linux-gnu-strip" >> $GITHUB_ENV
- name: Install fpm
if: matrix.os == 'Linux'
run: sudo gem install --no-document fpm

- name: Configure Windows runner
if: matrix.os == 'windows'
run: |
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ jobs:
$Env:DGATEWAY_EXECUTABLE = Get-ChildItem -Path $PackageRoot -Recurse -Include '*DevolutionsGateway*.exe' | Select -First 1
$Env:DGATEWAY_PSMODULE_PATH = Join-Path $PackageRoot PowerShell DevolutionsGateway
$Env:DGATEWAY_WEBCLIENT_PATH = Join-Path "webapp" "client" | Resolve-Path
$Env:DGATEWAY_WEBPLAYER_PATH = Join-Path "webapp" "player" | Resolve-Path
$Env:DGATEWAY_LIB_XMF_PATH = Join-Path "native-libs" "xmf.dll" | Resolve-Path
./ci/tlk.ps1 package -Product gateway -PackageOption generate
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ debug = 1
[profile.production]
inherits = "release"
lto = true
strip = "symbols"

[patch.crates-io]
tracing-appender = { git = "https://github.com/CBenoit/tracing.git", rev = "42097daf92e683cf18da7639ddccb056721a796c" }
Expand Down
97 changes: 79 additions & 18 deletions ci/tlk.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,8 @@ class TlkRecipe

[void] Package_Linux() {
$DebianArchitecture = $this.Target.DebianArchitecture()
$RpmArchitecture = $this.Target.Architecture

$Packager = "Devolutions Inc."
$Email = "[email protected]"
$Website = "https://devolutions.net"
Expand All @@ -656,15 +658,15 @@ class TlkRecipe
$Env:DEBFULLNAME = $Packager
$Env:DEBEMAIL = $Email

$DGatewayExecutable = $null
$Executable = $null
$DGatewayWebClient = $null
$DGatewayWebPlayer = $null
$DGatewayLibXmf = $null
$DAgentExecutable = $null

switch ($this.Product) {
"gateway" {
if (Test-Path Env:DGATEWAY_EXECUTABLE) {
$DGatewayExecutable = $Env:DGATEWAY_EXECUTABLE
$Executable = $Env:DGATEWAY_EXECUTABLE
} else {
throw ("Specify DGATEWAY_EXECUTABLE environment variable")
}
Expand All @@ -675,6 +677,12 @@ class TlkRecipe
throw ("Specify DGATEWAY_WEBCLIENT_PATH environment variable")
}

if (Test-Path Env:DGATEWAY_WEBPLAYER_PATH) {
$DGatewayWebPlayer = $Env:DGATEWAY_WEBPLAYER_PATH
} else {
throw ("Specify DGATEWAY_WEBPLAYER_PATH environment variable")
}

if (Test-Path Env:DGATEWAY_LIB_XMF_PATH) {
$DGatewayLibXmf = $Env:DGATEWAY_LIB_XMF_PATH
} else {
Expand All @@ -683,7 +691,7 @@ class TlkRecipe
}
"agent" {
if (Test-Path Env:DAGENT_EXECUTABLE) {
$DAgentExecutable = $Env:DAGENT_EXECUTABLE
$Executable = $Env:DAGENT_EXECUTABLE
} else {
throw ("Specify DAGENT_EXECUTABLE environment variable")
}
Expand All @@ -695,6 +703,11 @@ class TlkRecipe
"agent" { "Agent" }
}

$Description = switch ($this.Product) {
"gateway" { "Blazing fast relay server with desired levels of traffic inspection" }
"agent" { "Agent companion service for Devolutions Gateway" }
}

$InputPackagePath = Join-Path $this.SourcePath "package/$($InputPackagePathPrefix)Linux"

$OutputPath = Join-Path $this.SourcePath "output"
Expand All @@ -710,9 +723,10 @@ class TlkRecipe
Push-Location
Set-Location $OutputPackagePath

$DebPkgName = "devolutions-$($this.Product)"
$PkgNameVersion = "${DebPkgName}_$($this.Version).0"
$PkgNameTarget = "${PkgNameVersion}_${DebianArchitecture}"
$PkgName = "devolutions-$($this.Product)"
$PkgNameVersion = "${PkgName}_$($this.Version).0"
$DebPkgNameTarget = "${PkgNameVersion}_${DebianArchitecture}"
$RpmPkgNameTarget = "${PkgNameVersion}_${RpmArchitecture}"
$CopyrightFile = Join-Path $InputPackagePath "$($this.Product)/copyright"

# dh_make
Expand Down Expand Up @@ -745,17 +759,17 @@ class TlkRecipe
switch ($this.Product) {
"gateway" {
Merge-Tokens -TemplateFile $RulesTemplate -Tokens @{
root_path = $this.SourcePath
dgateway_executable = $DGatewayExecutable
executable = $Executable
dgateway_webclient = $DGatewayWebClient
dgateway_webplayer = $DGatewayWebPlayer
dgateway_libxmf = $DGatewayLibXmf
platform_dir = $InputPackagePath
dh_shlibdeps = $DhShLibDepsOverride
} -OutputFile $RulesFile
}
"agent" {
Merge-Tokens -TemplateFile $RulesTemplate -Tokens @{
dagent_executable = $DAgentExecutable
executable = $Executable
platform_dir = $InputPackagePath
dh_shlibdeps = $DhShLibDepsOverride
} -OutputFile $RulesFile
Expand All @@ -771,14 +785,15 @@ class TlkRecipe
email = $Email
packager = $Packager
website = $Website
description = $Description
} -OutputFile $ControlFile

# debian/copyright
$CopyrightFile = Join-Path $OutputDebianPath "copyright"
$CopyrightTemplate = Join-Path $InputPackagePath "template/copyright"

Merge-Tokens -TemplateFile $CopyrightTemplate -Tokens @{
package = $DebPkgName
package = $PkgName
packager = $Packager
year = $(Get-Date).Year
website = $Website
Expand All @@ -789,18 +804,22 @@ class TlkRecipe
$ChangelogTemplate = Join-Path $InputPackagePath "template/changelog"

Merge-Tokens -TemplateFile $ChangelogTemplate -Tokens @{
package = $DebPkgName
package = $PkgName
distro = $DistroCodeName
email = $Email
packager = $Packager
version = "${PackageVersion}.0"
date = $($(Get-Date -UFormat "%a, %d %b %Y %H:%M:%S %Z00") -Replace '\.','')
} -OutputFile $ChangelogFile

@('postinst', 'prerm', 'postrm') | % {
$InputFile = Join-Path $InputPackagePath "$($this.Product)/debian/$_"
$OutputFile = Join-Path $OutputDebianPath $_
Copy-Item $InputFile $OutputFile
$ScriptPath = Join-Path $InputPackagePath "$($this.Product)/debian"
$PostInstFile = Join-Path $ScriptPath 'postinst'
$PreRmFile = Join-Path $ScriptPath 'prerm'
$PostRmFile = Join-Path $ScriptPath 'postrm'

@($PostInstFile, $PreRmFile, $PostRmFile) | % {
$OutputFile = Join-Path $OutputDebianPath (Split-Path $_ -Leaf)
Copy-Item $_ $OutputFile
}

$DpkgBuildPackageArgs = @('-b', '-us', '-uc')
Expand All @@ -809,13 +828,55 @@ class TlkRecipe
$DpkgBuildPackageArgs += @('-a', $this.Target.DebianArchitecture())
}

# Disable dpkg-buildpackage stripping as the binary is already stripped.
$Env:DEB_BUILD_OPTIONS = "nostrip"
& 'dpkg-buildpackage' $DpkgBuildPackageArgs | Out-Host

$FpmArgs = @(
'--force',
'-s', 'dir',
'-t', 'rpm',
'-p', "$OutputPath/${RpmPkgNameTarget}.rpm",
'-n', $PkgName,
'-v', $PackageVersion,
'--maintainer', "$Packager <$Email>",
'--description', $Description,
'--url', $Website,
'--license', 'Apache-2.0 OR MIT'
'--rpm-attr', "755,root,root:/usr/bin/$PkgName"
)

if ($this.Product -eq "gateway") {
$FpmArgs += @(
'--after-install', $PostInstFile,
'--before-remove', $PreRmFile,
'--after-remove', $PostRmFile
)
}

$FpmArgs += @(
'--'
"$Executable=/usr/bin/$PkgName"
"$ChangeLogFile=/usr/share/$PkgName/changelog"
"$CopyrightFile=/usr/share/$PkgName/copyright"
)

if ($this.Product -eq "gateway") {
$FpmArgs += @(
"$DGatewayWebClient=/usr/share/devolutions-gateway/webapp",
"$DGatewayWebPlayer=/usr/share/devolutions-gateway/webapp",
"$DGatewayLibXmf=/usr/lib/devolutions-gateway/libxmf.so"
)
}

& 'fpm' @FpmArgs | Out-Host

if (Test-Path Env:TARGET_OUTPUT_PATH) {
$TargetOutputPath = $Env:TARGET_OUTPUT_PATH
New-Item -Path $TargetOutputPath -ItemType 'Directory' -Force | Out-Null
Copy-Item "$OutputPath/${PkgNameTarget}.deb" "$TargetOutputPath/${PkgNameTarget}.deb"
Copy-Item "$OutputPath/${PkgNameTarget}.changes" "$TargetOutputPath/${PkgNameTarget}.changes"
Copy-Item "$OutputPath/${DebPkgNameTarget}.deb" "$TargetOutputPath/${DebPkgNameTarget}.deb"
Copy-Item "$OutputPath/${DebPkgNameTarget}.changes" "$TargetOutputPath/${DebPkgNameTarget}.changes"
Copy-Item "$OutputPath/${RpmPkgNameTarget}.rpm" "$TargetOutputPath/${RpmPkgNameTarget}.rpm"
}

Pop-Location
Expand Down
2 changes: 1 addition & 1 deletion package/AgentLinux/agent/template/control
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ Homepage: {{ website }}
Package: devolutions-agent
Architecture: {{ arch }}
Depends: {{ deps }}
Description: Devolutions Agent
Description: {{ description }}
{{ website }}
2 changes: 1 addition & 1 deletion package/AgentLinux/agent/template/rules
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ override_dh_auto_build:
override_dh_auto_test:
override_dh_auto_install:
override_dh_usrlocal:
install -D -m 0755 {{ dagent_executable }} $$(pwd)/debian/devolutions-agent/usr/bin/devolutions-agent
install -D -m 0755 {{ executable }} $$(pwd)/debian/devolutions-agent/usr/bin/devolutions-agent
override_dh_install:
dh_install
override_dh_shlibdeps:
Expand Down
2 changes: 1 addition & 1 deletion package/Linux/gateway/template/control
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ Homepage: {{ website }}
Package: devolutions-gateway
Architecture: {{ arch }}
Depends: {{ deps }}
Description: Devolutions Gateway
Description: {{ description }}
{{ website }}
4 changes: 2 additions & 2 deletions package/Linux/gateway/template/rules
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ override_dh_auto_build:
override_dh_auto_test:
override_dh_auto_install:
override_dh_usrlocal:
install -D -m 0755 {{ dgateway_executable }} $$(pwd)/debian/devolutions-gateway/usr/bin/devolutions-gateway
install -D -m 0755 {{ executable }} $$(pwd)/debian/devolutions-gateway/usr/bin/devolutions-gateway
override_dh_install:
dh_install
mkdir -p $(WEBAPP_DIR)
cp -r {{ dgateway_webclient }} $(WEBAPP_DIR)
cp -r {{ root_path }}/webapp/player $(WEBAPP_DIR)
cp -r {{ dgateway_webplayer }} $(WEBAPP_DIR)
mkdir -p $(LIBXMF_DIR)
cp {{ dgateway_libxmf }} $(LIBXMF_DIR)/libxmf.so
override_dh_shlibdeps:
Expand Down
26 changes: 25 additions & 1 deletion package/WindowsManaged/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,30 @@ private static string DevolutionsWebClientPath
}
}

private static string DevolutionsWebPlayerPath
{
get
{
string path = Environment.GetEnvironmentVariable("DGATEWAY_WEBPLAYER_PATH");

if (string.IsNullOrEmpty(path) || !Directory.Exists(path))
{
#if DEBUG
path = "..\\..\\webapp\\player";
#else
throw new Exception("The environment variable DGATEWAY_WEBPLAYER_PATH is not specified or the directory does not exist");
#endif
}

if (!Directory.Exists(path))
{
throw new DirectoryNotFoundException("The web player was not found");
}

return path;
}
}

private static string LibXmfPath
{
get
Expand Down Expand Up @@ -311,7 +335,7 @@ static void Main()
Dirs = new Dir[]
{
new("client", new Files($@"{DevolutionsWebClientPath}\*.*")),
new("player", new Files(@"..\..\webapp\player\*.*"))
new("player", new Files($@"{DevolutionsWebPlayerPath}\*.*")),
}
}
}
Expand Down

0 comments on commit 3b8667d

Please sign in to comment.