chore(ci): build RPM package (#7190)

Refs #6145 

This bundles aarch64 and x86_64 RPMs in CI and CD.

We'll need a 2nd PR to add everything to the changelog and knowledge
base, after the first release with RPMs is cut.
This commit is contained in:
Reactor Scram
2024-11-01 13:06:09 -05:00
committed by GitHub
parent f7f9c76241
commit 7daa1a9ec3
13 changed files with 286 additions and 11 deletions

View File

@@ -115,6 +115,13 @@ jobs:
name: ${{ env.ARTIFACT_DST }}-pkg
path: ${{ env.ARTIFACT_SRC }}.${{ matrix.pkg-extension }}
if-no-files-found: error
- name: Upload rpm package
if: ${{ runner.os == 'Linux' }}
uses: actions/upload-artifact@v4
with:
name: ${{ env.ARTIFACT_DST }}-rpm
path: ${{ env.ARTIFACT_SRC }}.rpm
if-no-files-found: error
- name: Upload Release Assets
# Only upload the GUI Client build to the drafted release on main builds
if: ${{ github.ref_name == 'main' }}

8
rust/Dockerfile-rpm Normal file
View File

@@ -0,0 +1,8 @@
# Dockerfile for building RPM packages for CentOS
# CentOS Stream 9
FROM quay.io/centos/centos:stream9
RUN yum install -y rpm-build systemd-rpm-macros && yum clean all
RUN mkdir -p /root/rpmbuild
WORKDIR /root/rpmbuild

View File

@@ -0,0 +1,2 @@
node_modules/
rpmbuild/

View File

@@ -7,8 +7,9 @@ yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist-ssr
node_modules
rpmbuild
*.local
# Editor directories and files

View File

@@ -75,6 +75,33 @@ If that doesn't work:
- Click `New client secret`
- Note down the secret value. This should be entered into the GitHub repository's secrets as `AZURE_CLIENT_SECRET`.
## Installing on CentOS 9
These instructions will move to the knowledge base once the first release supporting CentOS 9 is cut.
### Install system tray
GNOME Shell 40 in CentOS 9 does not have a system tray by default. Use these steps to install it.
For other desktops like xfce4 or KDE, the system tray may already work properly.
1. `sudo dnf install epel-release` (Needed to get GNOME extensions)
2. `sudo dnf install gnome-shell-extension-appindicator`
3. Log out and back in to restart GNOME
4. `gnome-extensions enable appindicatorsupport@rgcjonas.gmail.com` (This will tab-complete.)
### Install Firezone
1. Download the RPM
2. `sudo dnf install systemd-resolved` (Installing it explicitly prevents it from being auto-removed if Firezone is removed)
3. `sudo dnf install ./firezone-client-gui-*.rpm`
4. `sudo usermod -aG firezone-client $USER`
5. `sudo systemctl enable firezone-client-ipc.service` (See https://www.freedesktop.org/software/systemd/man/latest/systemd.preset.html, "It is not recommended to ship preset files within the respective software packages implementing the units". The Fedora family of distros also seem to have their own policy that installing a service should not auto-start or enable it.)
6. Reboot to finish adding yourself to the group. Logging out and back in is not enough. This also starts the new services for us.
7. `sudo cp /etc/resolv.conf /etc/resolv.conf.before-firezone` Back up your resolv.conf file. If anything goes wrong with your DNS, you can copy this back into place.
8. `sudo ln --force --symbolic /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf` This puts `systemd-resolved`, and therefore Firezone, in control of the system's DNS. `systemd-resolved` does not do this automatically, since it's under `/etc`.
9. Run `firezone-client-gui` from the app menu.
## Running
From this dir:

View File

@@ -6,6 +6,9 @@ set -euo pipefail
# Dir where all the bundles are built
BUNDLES_DIR=../target/release/bundle/deb
# Prep the RPM container
docker build . -f ../Dockerfile-rpm -t rpmbuild
# Copy frontend dependencies
cp node_modules/flowbite/dist/flowbite.min.js src/
@@ -21,6 +24,23 @@ rm -rf "$BUNDLES_DIR"
# Compile Rust and bundle
pnpm tauri build
# Build the RPM file
docker run \
--rm \
-v $PWD/..:/root/rpmbuild \
-v /usr/lib:/root/libs \
-w /root/rpmbuild/gui-client \
rpmbuild \
rpmbuild \
-bb src-tauri/rpm_files/firezone-gui-client.spec \
--define "_topdir /root/rpmbuild/gui-client/rpmbuild"
# Un-mess-up the permissions Docker gave it
sudo chown --recursive $USER:$USER rpmbuild
# Give it a predictable name
cp rpmbuild/RPMS/*/firezone-client-gui-*rpm "firezone-client-gui.rpm"
# Delete the deb that Tauri built. We're going to modify and rebuild it.
rm "$BUNDLES_DIR"/*.deb
@@ -37,6 +57,6 @@ pushd "$INTERMEDIATE_DIR"
tar -C "control" -czf "control.tar.gz" control md5sums postinst prerm
# Rebuild the deb package, and give it a predictable name that
# `tauri-rename-ubuntu.sh` can fix
# `tauri-rename-linux.sh` can fix
ar rcs "../firezone-client-gui.deb" debian-binary control.tar.gz data.tar.gz
popd

View File

@@ -1,5 +1,7 @@
[Unit]
Description=Firezone Client
After=systemd-resolved.service
Wants=systemd-resolved.service
[Service]
AmbientCapabilities=CAP_NET_ADMIN
@@ -42,7 +44,7 @@ EnvironmentFile=-/etc/default/firezone-client-ipc
ExecStart=firezone-client-ipc run
Type=notify
# Unfortunately we may need root to control DNS
# Unfortunately we need root to control DNS
User=root
Group=firezone-client

View File

@@ -0,0 +1,8 @@
[Desktop Entry]
Categories=
Comment=Firezone
Exec=firezone-client-gui
Icon=firezone-client-gui
Name=firezone-client-gui
Terminal=false
Type=Application

View File

@@ -0,0 +1,197 @@
Name: firezone-client-gui
# mark:next-gui-version
Version: 1.3.11
Release: 1%{?dist}
Summary: The GUI Client for Firezone
URL: https://firezone.dev
License: Apache-2.0
Requires: systemd-resolved
BuildRequires: systemd-rpm-macros
# For some reason, the Ubuntu version of `rpmbuild` notices that we're providing our own WebKit and other libs, but the CentOS version doesn't. So we explicitly tell it not to worry about all these libs.
%global __requires_exclude ^(libdbus-1|libgdk-3|libgio-2.0|libglib-2.0|libgtk-3|libjavascriptcoregtk-4.1|libm|libsoup-3.0|libwebkit2gtk-4.1).so.*
%description
%prep
%build
%install
mkdir -p \
"%{buildroot}/usr/bin" \
"%{buildroot}/usr/lib/dev.firezone.client/unused"
BINS="%{_topdir}/../../target/release"
cp "$BINS/firezone-client-ipc" "%{buildroot}/usr/bin/"
cp "$BINS/firezone-client-gui" "%{buildroot}/usr/lib/dev.firezone.client/"
cp "%{_topdir}/../src-tauri/rpm_files/gui-shim.sh" "%{buildroot}/usr/bin/firezone-client-gui"
LIBS="/root/libs/$(uname -m)-linux-gnu"
# DNF expects libc and ld-linux to be packaged, because it checks the exes with ldd or something, but if we actually use them, the GUI process will segfault. So just dump them somewhere unused.
UNUSED_DIR="%{buildroot}/usr/lib/dev.firezone.client/unused"
%ifarch aarch64
cp \
"$LIBS/ld-linux-aarch64.so.1" \
"$LIBS/libc.so.6" \
"$UNUSED_DIR"
%endif
%ifarch x86_64
cp \
"$LIBS/ld-linux-x86-64.so.2" \
"$LIBS/libc.so.6" \
"$UNUSED_DIR"
%endif
cp \
"$LIBS/libappindicator3.so.1" \
"$LIBS/libayatana-appindicator3.so.1" \
"$LIBS/libayatana-ido3-0.4.so.0" \
"$LIBS/libayatana-indicator3.so.7" \
"$LIBS/libdbus-1.so.3" \
"$LIBS/libdbusmenu-glib.so.4" \
"$LIBS/libdbusmenu-gtk3.so.4" \
"$LIBS/libfreetype.so.6" \
"$LIBS/libgdk-3.so.0" \
"$LIBS/libgio-2.0.so.0" \
"$LIBS/libglib-2.0.so.0" \
"$LIBS/libgmodule-2.0.so.0" \
"$LIBS/libgtk-3.so.0" \
"$LIBS/libicudata.so.70" \
"$LIBS/libicui18n.so.70" \
"$LIBS/libicuuc.so.70" \
"$LIBS/libjavascriptcoregtk-4.1.so.0" \
"$LIBS/libjpeg.so.8" \
"$LIBS/libm.so.6" \
"$LIBS/libmanette-0.2.so.0" \
"$LIBS/libpcre.so.3" \
"$LIBS/libpcre2-8.so.0" \
"$LIBS/libsoup-3.0.so.0" \
"$LIBS/libstdc++.so.6" \
"$LIBS/libwayland-client.so.0" \
"$LIBS/libwayland-server.so.0" \
"$LIBS/libwebkit2gtk-4.1.so.0" \
"$LIBS/libxcb.so.1" \
"$LIBS/libxcb-shm.so.0" \
"$LIBS/libX11.so.6" \
"$LIBS/libX11-xcb.so.1" \
"%{buildroot}/usr/lib/dev.firezone.client/"
ls -lash "%{buildroot}/usr/lib/dev.firezone.client"
WEBKIT_DIR="$(uname -m)-linux-gnu/webkit2gtk-4.1"
mkdir -p "%{buildroot}/usr/lib/$WEBKIT_DIR"
cp \
"/root/libs/$WEBKIT_DIR/WebKitNetworkProcess" \
"/root/libs/$WEBKIT_DIR/WebKitWebProcess" \
"%{buildroot}/usr/lib/$WEBKIT_DIR"
ICONS="%{buildroot}/usr/share/icons/hicolor"
mkdir -p \
"%{buildroot}/usr/lib/systemd/system" \
"%{buildroot}/usr/lib/sysusers.d" \
"%{buildroot}/usr/share/applications" \
"$ICONS/32x32/apps" \
"$ICONS/128x128/apps" \
"$ICONS/512x512/apps"
cp \
"%{_topdir}/../src-tauri/deb_files/firezone-client-ipc.service" \
"%{buildroot}/usr/lib/systemd/system/"
cp \
"%{_topdir}/../src-tauri/deb_files/sysusers.conf" \
"%{buildroot}/usr/lib/sysusers.d/firezone-client-ipc.conf"
cp \
"%{_topdir}/../src-tauri/rpm_files/firezone-client-gui.desktop" \
"%{buildroot}/usr/share/applications/"
cp \
"%{_topdir}/../src-tauri/icons/32x32.png" \
"$ICONS/32x32/apps/firezone-client-gui.png"
cp \
"%{_topdir}/../src-tauri/icons/128x128.png" \
"$ICONS/128x128/apps/firezone-client-gui.png"
cp \
"%{_topdir}/../src-tauri/icons/icon.png" \
"$ICONS/512x512/apps/firezone-client-gui.png"
%files
/usr/bin/firezone-client-ipc
/usr/bin/firezone-client-gui
/usr/lib/dev.firezone.client/firezone-client-gui
/usr/lib/dev.firezone.client/libappindicator3.so.1
/usr/lib/dev.firezone.client/libayatana-appindicator3.so.1
/usr/lib/dev.firezone.client/libayatana-ido3-0.4.so.0
/usr/lib/dev.firezone.client/libayatana-indicator3.so.7
/usr/lib/dev.firezone.client/libdbus-1.so.3
/usr/lib/dev.firezone.client/libdbusmenu-glib.so.4
/usr/lib/dev.firezone.client/libdbusmenu-gtk3.so.4
/usr/lib/dev.firezone.client/libfreetype.so.6
/usr/lib/dev.firezone.client/libgdk-3.so.0
/usr/lib/dev.firezone.client/libgio-2.0.so.0
/usr/lib/dev.firezone.client/libglib-2.0.so.0
/usr/lib/dev.firezone.client/libgmodule-2.0.so.0
/usr/lib/dev.firezone.client/libgtk-3.so.0
/usr/lib/dev.firezone.client/libicudata.so.70
/usr/lib/dev.firezone.client/libicui18n.so.70
/usr/lib/dev.firezone.client/libicuuc.so.70
/usr/lib/dev.firezone.client/libjavascriptcoregtk-4.1.so.0
/usr/lib/dev.firezone.client/libjpeg.so.8
/usr/lib/dev.firezone.client/libm.so.6
/usr/lib/dev.firezone.client/libmanette-0.2.so.0
/usr/lib/dev.firezone.client/libpcre.so.3
/usr/lib/dev.firezone.client/libpcre2-8.so.0
/usr/lib/dev.firezone.client/libsoup-3.0.so.0
/usr/lib/dev.firezone.client/libstdc++.so.6
/usr/lib/dev.firezone.client/libwayland-client.so.0
/usr/lib/dev.firezone.client/libwayland-server.so.0
/usr/lib/dev.firezone.client/libwebkit2gtk-4.1.so.0
/usr/lib/dev.firezone.client/libxcb.so.1
/usr/lib/dev.firezone.client/libxcb-shm.so.0
/usr/lib/dev.firezone.client/libX11.so.6
/usr/lib/dev.firezone.client/libX11-xcb.so.1
/usr/lib/systemd/system/firezone-client-ipc.service
/usr/lib/sysusers.d/firezone-client-ipc.conf
/usr/share/applications/firezone-client-gui.desktop
/usr/share/icons/hicolor/32x32/apps/firezone-client-gui.png
/usr/share/icons/hicolor/128x128/apps/firezone-client-gui.png
/usr/share/icons/hicolor/512x512/apps/firezone-client-gui.png
%ifarch aarch64
/usr/lib/aarch64-linux-gnu/webkit2gtk-4.1/WebKitNetworkProcess
/usr/lib/aarch64-linux-gnu/webkit2gtk-4.1/WebKitWebProcess
/usr/lib/dev.firezone.client/unused/ld-linux-aarch64.so.1
/usr/lib/dev.firezone.client/unused/libc.so.6
%endif
%ifarch x86_64
/usr/lib/x86_64-linux-gnu/webkit2gtk-4.1/WebKitNetworkProcess
/usr/lib/x86_64-linux-gnu/webkit2gtk-4.1/WebKitWebProcess
/usr/lib/dev.firezone.client/unused/ld-linux-x86-64.so.2
/usr/lib/dev.firezone.client/unused/libc.so.6
%endif
%post
%systemd_post firezone-client-ipc.service
%preun
%systemd_preun firezone-client-ipc.service
%postun
%systemd_postun_with_restart firezone-client-ipc.service

View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
# Installed as `/usr/bin/firezone-client-gui` on RPM systems since we bundle a bunch of libs
set -euo pipefail
LD_LIBRARY_PATH=/usr/lib/dev.firezone.client exec /usr/lib/dev.firezone.client/firezone-client-gui

View File

@@ -13,18 +13,11 @@
"/usr/lib/systemd/system/firezone-client-ipc.service": "./deb_files/firezone-client-ipc.service",
"/usr/lib/sysusers.d/firezone-client-ipc.conf": "./deb_files/sysusers.conf"
}
},
"rpm": {
"files": {
"/usr/lib/systemd/system/firezone-client-ipc.service": "./deb_files/firezone-client-ipc.service",
"/usr/lib/sysusers.d/firezone-client-ipc.conf": "./deb_files/sysusers.conf"
}
}
},
"targets": [
"deb",
"msi",
"rpm"
"msi"
],
"windows": {
"wix": {

View File

@@ -20,6 +20,7 @@ ls "$TARGET_DIR/release" "$TARGET_DIR/release/bundle/deb"
cp "$TARGET_DIR/release/firezone-client-gui" "$BINARY_DEST_PATH"
cp "$TARGET_DIR/release/firezone-gui-client.dwp" "$BINARY_DEST_PATH.dwp"
cp "$TARGET_DIR/release/bundle/deb/firezone-client-gui.deb" "$BINARY_DEST_PATH.deb"
cp "$TARGET_DIR/../gui-client/firezone-client-gui.rpm" "$BINARY_DEST_PATH.rpm"
# TODO: Debug symbols for Linux
function make_hash() {
@@ -31,6 +32,7 @@ function make_hash() {
make_hash "$BINARY_DEST_PATH"
make_hash "$BINARY_DEST_PATH.dwp"
make_hash "$BINARY_DEST_PATH.deb"
make_hash "$BINARY_DEST_PATH.rpm"
# Test the deb package, since this script is the easiest place to get a release build
DEB_PATH=$(realpath "$BINARY_DEST_PATH.deb")

View File

@@ -15,5 +15,7 @@ fi
gh release upload "$TAG_NAME" \
"$BINARY_DEST_PATH".deb \
"$BINARY_DEST_PATH".deb.sha256sum.txt \
"$BINARY_DEST_PATH".rpm \
"$BINARY_DEST_PATH".rpm.sha256sum.txt \
$clobber \
--repo "$REPOSITORY"