Add initial support for RPM packaging (#121)

- Add gen-rpm
- Package rpm in CI testing and releases
- Remove fedora 33 from testing (end of life)
- Update arguments for `build_private.sh` and `build_sunshine.sh`

Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com>
This commit is contained in:
h 2022-04-12 20:29:08 -07:00 committed by GitHub
parent 97f333c970
commit a6921fffad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 271 additions and 20 deletions

View File

@ -153,12 +153,9 @@ jobs:
distro: [ debian, ubuntu_18_04, ubuntu_20_04, ubuntu_21_04, ubuntu_21_10 ]
package: [ -p ]
extension: [ deb ]
include: # don't package these
- distro: fedora_33
package: ''
extension: rpm
include: # package these differently
- distro: fedora_35
package: ''
package: '-p'
extension: rpm
steps:
@ -176,7 +173,7 @@ jobs:
- name: Build Linux
run: |
cd scripts
sudo ./build-sunshine.sh ${{ matrix.package }} -u -n sunshine-${{ matrix.distro }} -s ..
sudo ./build-sunshine.sh ${{ matrix.package }} -e ${{ matrix.extension }} -u -n sunshine-${{ matrix.distro }} -s ..
- name: Package Linux
if: ${{ matrix.package != '' }}
run: |

View File

@ -313,6 +313,7 @@ else()
set(SUNSHINE_EXECUTABLE_PATH "sunshine")
endif()
configure_file(gen-deb.in gen-deb @ONLY)
configure_file(gen-rpm.in gen-rpm @ONLY)
configure_file(sunshine.desktop.in sunshine.desktop @ONLY)
configure_file(sunshine.service.in sunshine.service @ONLY)
endif()

View File

@ -21,7 +21,7 @@ They make use of docker to handle building Sunshine automatically
### Requirements:
Ubuntu 20.04:
#### Ubuntu 20.04:
Install the following:
#### Common
@ -52,15 +52,56 @@ On Ubuntu 20.04, the cuda compiler will fail since it's version is too old, it's
sudo apt install nvidia-cuda-dev nvidia-cuda-toolkit
```
#### Fedora 35:
You will need some things in the RPMFusion repo, nost notably ffmpeg.
```
sudo dnf install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
```
#### Development tools and libraries
```
sudo dnf install \
boost-devel \
boost-static.x86_64 \
cmake \
ffmpeg-devel \
gcc-c++ \
libevdev-devel \
libxcb-devel \
libX11-devel \
libXcursor-devel \
libXfixes-devel \
libXinerama-devel \
libXi-devel \
libXrandr-devel \
libXtst-devel \
mesa-libGL-devel \
openssl-devel \
opus-devel \
pulseaudio-libs-devel
```
#### If you need to build an RPM binary package:
```
sudo dnf install rpmbuild
```
#### Warning:
You might require ffmpeg version >= 4.3. Check the troubleshooting section for more information.
### Compilation:
- `git clone https://github.com/loki-47-6F-64/sunshine.git --recurse-submodules`
#### Ubuntu
- `git clone https://github.com/SunshineStream/Sunshine.git --recurse-submodules`
- `cd sunshine && mkdir build && cd build`
- `cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 ..`
- `make -j ${nproc}`
#### Fedora
- `git clone https://github.com/SunshineStream/Sunshine.git --recurse-submodules`
- `cd sunshine && mkdir build && cd build`
- `cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ ..`
- `make -j ${nproc}`
### Setup:
sunshine needs access to uinput to create mouse and gamepad events:

View File

@ -0,0 +1 @@
KERNEL=="uinput", GROUP="input", MODE="0660"

179
gen-rpm.in Executable file
View File

@ -0,0 +1,179 @@
#!/bin/sh
# Export filepaths
export BUILDDIR=@CMAKE_CURRENT_SOURCE_DIR@/build
export BUILDROOT=~/rpmbuild/
export RPMSRC=~/rpmbuild/SOURCES
export RPMSPEC=~/rpmbuild/SPECS
export RPMBUILD=~/rpmbuild/BUILD
# Check for Docker switch
if [ "$1" == "-d" ]; then
export DOCKERSTATUS=TRUE
else
export DOCKERSTATUS=FALSE
fi
# Check if user's rpmbuild folder is there, if so, temoprairly rename it.
if [ -d ~/rpmbuild ]; then
echo "Backing up rpmbuild"
~/rpmbuild ~/rpmbuild.bkp
export RPMBUILDEXISTS=TRUE
else
export RPMBUILDEXISTS=FALSE
fi
# Create rpmbuild folder structure
mkdir ~/rpmbuild
mkdir ~/rpmbuild/BUILD
mkdir ~/rpmbuild/BUILDROOT
mkdir ~/rpmbuild/RPMS
mkdir ~/rpmbuild/SOURCES
mkdir ~/rpmbuild/SPECS
mkdir ~/rpmbuild/SRPMS
# Create sunshine .spec file with preinstall and postinstall scripts
cat << 'EOF' > $RPMSPEC/sunshine.spec
Name: sunshine
Version: @PROJECT_VERSION@
Release: 1%{?dist}
Summary: An NVIDIA Gamestream-compatible hosting server
BuildArch: x86_64
License: GPLv3
URL: https://github.com/SunshineStream/Sunshine
Source0: sunshine-@PROJECT_VERSION@_bin.tar.gz
Requires: systemd
%description
An NVIDIA Gamestream-compatible hosting server
%pre
#!/bin/sh
# Sunshine Pre-Install Script
# Store backup for old config files to prevent it from being overwritten
if [ -f /etc/sunshine/sunshine.conf ]; then
cp /etc/sunshine/sunshine.conf /etc/sunshine/sunshine.conf.old
fi
if [ -f /etc/sunshine/apps_linux.json ]; then
cp /etc/sunshine/apps_linux.json /etc/sunshine/apps_linux.json.old
fi
%post
#!/bin/sh
# Sunshine Post-Install Script
export GROUP_INPUT=input
if [ -f /etc/group ]; then
if ! grep -q $GROUP_INPUT /etc/group; then
echo "Creating group $GROUP_INPUT"
groupadd $GROUP_INPUT
fi
else
echo "Warning: /etc/group not found"
fi
if [ -f /etc/sunshine/sunshine.conf.old ]; then
echo "Restoring old sunshine.conf"
mv /etc/sunshine/sunshine.conf.old /etc/sunshine/sunshine.conf
fi
if [ -f /etc/sunshine/apps_linux.json.old ]; then
echo "Restoring old apps_linux.json"
mv /etc/sunshine/apps_linux.json.old /etc/sunshine/apps_linux.json
fi
# Update permissions on config files for Web Manager
if [ -f /etc/sunshine/apps_linux.json ]; then
echo "chmod 666 /etc/sunshine/apps_linux.json"
chmod 666 /etc/sunshine/apps_linux.json
fi
if [ -f /etc/sunshine/sunshine.conf ]; then
echo "chmod 666 /etc/sunshine/sunshine.conf"
chmod 666 /etc/sunshine/sunshine.conf
fi
# Ensure Sunshine can grab images from KMS
path_to_setcap=$(which setcap)
if [ -x "$path_to_setcap" ] ; then
echo "$path_to_setcap cap_sys_admin+p /usr/bin/sunshine"
$path_to_setcap cap_sys_admin+p /usr/bin/sunshine
fi
%prep
%setup -q
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/%{_bindir}
mkdir -p $RPM_BUILD_ROOT/etc/sunshine
mkdir -p $RPM_BUILD_ROOT/usr/lib/systemd/user
mkdir -p $RPM_BUILD_ROOT/usr/share/applications
mkdir -p $RPM_BUILD_ROOT/etc/udev/rules.d
cp sunshine $RPM_BUILD_ROOT/%{_bindir}/sunshine
cp sunshine.conf $RPM_BUILD_ROOT/etc/sunshine/sunshine.conf
cp apps_linux.json $RPM_BUILD_ROOT/etc/sunshine/apps_linux.json
cp sunshine.service $RPM_BUILD_ROOT/usr/lib/systemd/user/sunshine.service
cp sunshine.desktop $RPM_BUILD_ROOT/usr/share/applications/sunshine.desktop
cp 85-sunshine-rules.rules $RPM_BUILD_ROOT/etc/udev/rules.d/85-sunshine-rules.rules
%clean
rm -rf $RPM_BUILD_ROOT
%files
%{_bindir}/sunshine
/usr/lib/systemd/user/sunshine.service
/etc/sunshine/sunshine.conf
/etc/sunshine/apps_linux.json
/usr/share/applications/sunshine.desktop
/etc/udev/rules.d/85-sunshine-rules.rules
%changelog
* Sat Mar 12 2022 h <65380846+thatsysadmin@users.noreply.github.com>
- Initial packaging of Sunshine.
EOF
# Copy over sunshine binary and supplemental files into rpmbuild/BUILD/
mkdir genrpm
mkdir genrpm/sunshine-@PROJECT_VERSION@
cp sunshine-@PROJECT_VERSION@ genrpm/sunshine-@PROJECT_VERSION@/sunshine
cp sunshine.service genrpm/sunshine-@PROJECT_VERSION@/sunshine.service
cp sunshine.desktop genrpm/sunshine-@PROJECT_VERSION@/sunshine.desktop
cp @CMAKE_CURRENT_SOURCE_DIR@/assets/sunshine.conf genrpm/sunshine-@PROJECT_VERSION@/sunshine.conf
cp @CMAKE_CURRENT_SOURCE_DIR@/assets/apps_linux.json genrpm/sunshine-@PROJECT_VERSION@/apps_linux.json
cp @CMAKE_CURRENT_SOURCE_DIR@/assets/85-sunshine-rules.rules genrpm/sunshine-@PROJECT_VERSION@/85-sunshine-rules.rules
cd genrpm
# tarball everything as if it was a source file for rpmbuild
tar --create --file sunshine-@PROJECT_VERSION@_bin.tar.gz sunshine-@PROJECT_VERSION@/
cp sunshine-@PROJECT_VERSION@_bin.tar.gz ~/rpmbuild/SOURCES
# Use rpmbuild to build the RPM package.
rpmbuild -bb $RPMSPEC/sunshine.spec
# Check if running in a CT
if [ "$DOCKERSTATUS" == "FALSE" ]; then
# Move the completed RPM into the cmake build folder
mv ~/rpmbuild/RPMS/x86_64/sunshine-@PROJECT_VERSION@-1.fc*.x86_64.rpm @CMAKE_CURRENT_BINARY_DIR@/
echo "Moving completed RPM package into CMake build folder."
elif [ "$DOCKERSTATUS" == "TRUE" ]; then
# Move into pickup location
mkdir -p /root/sunshine-build/package-rpm/
mv ~/rpmbuild/RPMS/x86_64/sunshine-@PROJECT_VERSION@-1.fc*.x86_64.rpm /root/sunshine-build/package-rpm/sunshine.rpm
echo "Moving completed RPM package for pickup."
fi
# Clean up; delete the rpmbuild folder we created and move back the original one
if [ "$RPMBUILDEXISTS" == "TRUE" ]; then
echo "Removing and replacing original rpmbuild folder."
rm -rf ~/rpmbuild
mv ~/rpmbuild.bkp ~/rpmbuild
fi
exit 0

View File

@ -35,4 +35,4 @@ RUN apt-get update -y && \
# Entrypoint
COPY build-private.sh /root/build.sh
ENTRYPOINT ["/root/build.sh"]
ENTRYPOINT ["/root/build.sh", "-deb"]

View File

@ -18,9 +18,10 @@ RUN dnf -y update && \
openssl-devel \
opus-devel \
pulseaudio-libs-devel \
rpm-build \
&& dnf clean all \
&& rm -rf /var/cache/yum
# Entrypoint
COPY build-private.sh /root/build.sh
ENTRYPOINT ["/root/build.sh"]
ENTRYPOINT ["/root/build.sh", "-rpm"]

View File

@ -23,9 +23,10 @@ RUN dnf -y update && \
openssl-devel \
opus-devel \
pulseaudio-libs-devel \
rpm-build \
&& dnf clean all \
&& rm -rf /var/cache/yum
# Entrypoint
COPY build-private.sh /root/build.sh
ENTRYPOINT ["/root/build.sh"]
ENTRYPOINT ["/root/build.sh", "-rpm"]

View File

@ -58,4 +58,4 @@ RUN cmake --version
# Entrypoint
COPY build-private.sh /root/build.sh
ENTRYPOINT ["/root/build.sh"]
ENTRYPOINT ["/root/build.sh", "-deb"]

View File

@ -41,4 +41,4 @@ RUN /root/cuda.run --silent --toolkit --toolkitpath=/usr --no-opengl-libs --no-m
# Entrypoint
COPY build-private.sh /root/build.sh
ENTRYPOINT ["/root/build.sh"]
ENTRYPOINT ["/root/build.sh", "-deb"]

View File

@ -34,4 +34,4 @@ RUN apt-get update -y && \
# Entrypoint
COPY build-private.sh /root/build.sh
ENTRYPOINT ["/root/build.sh"]
ENTRYPOINT ["/root/build.sh", "-deb"]

View File

@ -34,4 +34,4 @@ RUN apt-get update -y && \
# Entrypoint
COPY build-private.sh /root/build.sh
ENTRYPOINT ["/root/build.sh"]
ENTRYPOINT ["/root/build.sh", "-deb"]

View File

@ -32,4 +32,17 @@ cmake "-DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE" "-DSUNSHINE_EXECUTABLE_PATH=$SUNSHI
make -j ${nproc}
./gen-deb
# Get preferred package format
if [ "$1" == "-rpm" ]
then
echo "Packaging in .rpm format."
./gen-rpm -d
elif [ "$1" == "-deb" ]
then
echo "Packaging in .deb format."
./gen-deb
else
echo "Preferred packaging not specified."
echo "Use -deb or -rpm to specify preferred package format."
exit 1
fi

View File

@ -4,7 +4,8 @@ set -e
usage() {
echo "Usage: $0"
echo " -d: Generate a debug build"
echo " -p: Generate a debian package"
echo " -p: Generate a linux package"
echo " -e: Extension of package... i.e. 'deb', 'rpm' --> default [deb]"
echo " -u: The input device is not a TTY"
echo " -n name: Docker container name --> default [sunshine]"
echo " -s path/to/sources/sunshine: Use local sources instead of a git repository"
@ -26,13 +27,14 @@ absolute_path() {
CMAKE_BUILD_TYPE="-e CMAKE_BUILD_TYPE=Release"
SUNSHINE_PACKAGE_BUILD=OFF
SUNSHINE_PACKAGE_EXTENSION=deb
SUNSHINE_GIT_URL=https://github.com/sunshinestream/sunshine.git
CONTAINER_NAME=sunshine
# Docker will fail if ctrl+c is passed through and the input is not a tty
DOCKER_INTERACTIVE=-ti
while getopts ":dpuhc:s:n:" arg; do
while getopts ":dpuhc:e:s:n:" arg; do
case ${arg} in
u)
echo "Input device is not a TTY"
@ -49,6 +51,21 @@ while getopts ":dpuhc:s:n:" arg; do
SUNSHINE_ASSETS_DIR="-e SUNSHINE_ASSETS_DIR=/etc/sunshine"
SUNSHINE_EXECUTABLE_PATH="-e SUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine"
;;
e)
echo "Defining package extension: $OPTARG"
if [ "$OPTARG" == "deb" ]
then
SUNSHINE_PACKAGE_EXTENSION=$OPTARG
echo "Package extension: deb"
elif [ "$OPTARG" == "rpm" ]
then
SUNSHINE_PACKAGE_EXTENSION=$OPTARG
echo "Package extension: rpm"
else
echo "Package extension not supported: $OPTARG"
echo "Falling back to default package extension: $SUNSHINE_PACKAGE_EXTENSION"
fi
;;
s)
absolute_path "$OPTARG"
OPTARG="$RETURN"
@ -98,8 +115,8 @@ then
mkdir -p $BUILD_DIR
case $SUNSHINE_PACKAGE_BUILD in
ON)
echo "Downloading package to: $BUILD_DIR/$CONTAINER_NAME.deb"
docker cp $CONTAINER_NAME:/root/sunshine-build/package-deb/sunshine.deb "$BUILD_DIR/$CONTAINER_NAME.deb"
echo "Downloading package to: $BUILD_DIR/$CONTAINER_NAME.$SUNSHINE_PACKAGE_EXTENSION"
docker cp $CONTAINER_NAME:/root/sunshine-build/package-$SUNSHINE_PACKAGE_EXTENSION/sunshine.$SUNSHINE_PACKAGE_EXTENSION "$BUILD_DIR/$CONTAINER_NAME.$SUNSHINE_PACKAGE_EXTENSION"
;;
*)
echo "Downloading binary and assets to: $BUILD_DIR"