From 35bef65384de4514f8ac291b5df0aea48c881bb1 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Tue, 2 Jul 2024 19:42:37 -0400 Subject: [PATCH] ci(flatpak): add flatpak builder lint --- .github/workflows/CI.yml | 36 +++++++--- CMakeLists.txt | 6 +- cmake/packaging/linux.cmake | 38 ++++++++--- cmake/prep/init.cmake | 8 +++ .../prep/special_package_configuration.cmake | 6 +- docs/source/about/setup.rst | 16 ++--- docs/source/troubleshooting/general.rst | 2 +- packaging/linux/flatpak/apps.json | 11 ++++ .../dev.lizardbyte.app.Sunshine.metainfo.xml | 66 +++++++++++++++++++ ...ne.yml => dev.lizardbyte.app.Sunshine.yml} | 21 ++---- packaging/linux/flatpak/sunshine.desktop | 8 +-- packaging/linux/flatpak/sunshine_kms.desktop | 2 +- packaging/linux/sunshine.appdata.xml | 2 +- packaging/linux/sunshine.desktop | 2 +- packaging/linux/sunshine.service.in | 3 +- 15 files changed, 175 insertions(+), 52 deletions(-) create mode 100644 packaging/linux/flatpak/apps.json create mode 100644 packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.metainfo.xml rename packaging/linux/flatpak/{dev.lizardbyte.sunshine.yml => dev.lizardbyte.app.Sunshine.yml} (93%) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 45f0a71ae9d..1b64ab1a8de 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -72,6 +72,8 @@ jobs: matrix: ${{ steps.flatpak_matrix.outputs.matrix }} build_linux_flatpak: + env: + APP_ID: dev.lizardbyte.app.Sunshine name: Linux Flatpak runs-on: ubuntu-22.04 needs: [setup_release, setup_flatpak_matrix] @@ -157,20 +159,38 @@ jobs: -DSUNSHINE_CONFIGURE_ONLY=ON \ .. + - name: Debug Manifest + working-directory: build + run: | + cat ${APP_ID}.yml + - name: Build Linux Flatpak working-directory: build run: | - sudo su $(whoami) -c 'flatpak run org.flatpak.Builder --arch=${{ matrix.arch }} --repo=repo --force-clean \ - --stop-at=cuda build-sunshine dev.lizardbyte.sunshine.yml' + sudo su $(whoami) -c "flatpak run org.flatpak.Builder --arch=${{ matrix.arch }} --repo=repo --force-clean \ + --stop-at=cuda build-sunshine ${APP_ID}.yml" cp -r .flatpak-builder copy-of-flatpak-builder - sudo su $(whoami) -c 'flatpak run org.flatpak.Builder --arch=${{ matrix.arch }} --repo=repo --force-clean \ - build-sunshine dev.lizardbyte.sunshine.yml' + sudo su $(whoami) -c "flatpak run org.flatpak.Builder --arch=${{ matrix.arch }} --repo=repo --force-clean \ + build-sunshine ${APP_ID}.yml" rm -rf .flatpak-builder mv copy-of-flatpak-builder .flatpak-builder - sudo su $(whoami) -c 'flatpak build-bundle --arch=${{ matrix.arch }} ./repo \ - ../artifacts/sunshine_${{ matrix.arch }}.flatpak dev.lizardbyte.sunshine' - sudo su $(whoami) -c 'flatpak build-bundle --runtime --arch=${{ matrix.arch }} ./repo \ - ../artifacts/sunshine_debug_${{ matrix.arch }}.flatpak dev.lizardbyte.sunshine.Debug' + sudo su $(whoami) -c "flatpak build-bundle --arch=${{ matrix.arch }} ./repo \ + ../artifacts/sunshine_${{ matrix.arch }}.flatpak ${APP_ID}" + sudo su $(whoami) -c "flatpak build-bundle --runtime --arch=${{ matrix.arch }} ./repo \ + ../artifacts/sunshine_debug_${{ matrix.arch }}.flatpak ${APP_ID}.Debug" + + - name: Lint Flatpak + working-directory: build + run: | + echo "Linting flatpak manifest" + flatpak run --command=flatpak-builder-lint org.flatpak.Builder --exceptions manifest ${APP_ID}.yml + + echo "Linting flatpak repo" + # TODO: add arg + # --mirror-screenshots-url=https://dl.flathub.org/media \ + flatpak run --command=flatpak-builder-lint org.flatpak.Builder \ + --exceptions \ + repo repo - name: Upload Artifacts uses: actions/upload-artifact@v4 diff --git a/CMakeLists.txt b/CMakeLists.txt index fabe5938b30..90822a36ea0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,11 @@ project(Sunshine VERSION 0.0.0 DESCRIPTION "Self-hosted game stream host for Moonlight" HOMEPAGE_URL "https://app.lizardbyte.dev/Sunshine") -set(PROJECT_LICENSE "GPL-3.0") +set(PROJECT_LICENSE "GPL-3.0-only") + +set(PROJECT_FQDN "dev.lizardbyte.app.Sunshine") + +set(PROJECT_BRIEF_DESCRIPTION "GameStream host for Moonlight") # must be <= 35 characters set(PROJECT_LONG_DESCRIPTION "Offering low latency, cloud gaming server capabilities with support for AMD, Intel, \ and Nvidia GPUs for hardware encoding. Software encoding is also available. You can connect to Sunshine from any \ diff --git a/cmake/packaging/linux.cmake b/cmake/packaging/linux.cmake index 4e596917432..5fa6d2dfb7c 100644 --- a/cmake/packaging/linux.cmake +++ b/cmake/packaging/linux.cmake @@ -77,8 +77,14 @@ endif() set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF) # application icon -install(FILES "${CMAKE_SOURCE_DIR}/sunshine.svg" - DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps") +if(NOT ${SUNSHINE_BUILD_FLATPAK}) + install(FILES "${CMAKE_SOURCE_DIR}/sunshine.svg" + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps") +else() + install(FILES "${CMAKE_SOURCE_DIR}/sunshine.svg" + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps" + RENAME "${PROJECT_FQDN}.svg") +endif() # tray icon if(${SUNSHINE_TRAY} STREQUAL 1) @@ -103,18 +109,32 @@ endif() # desktop file # todo - validate desktop files with `desktop-file-validate` -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.desktop" - DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") -if(NOT ${SUNSHINE_BUILD_APPIMAGE}) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine_terminal.desktop" +if(NOT ${SUNSHINE_BUILD_FLATPAK}) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") +else() + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.desktop" + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications" + RENAME "${PROJECT_FQDN}.desktop") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine_kms.desktop" + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications" + RENAME "${PROJECT_FQDN}_kms.desktop") endif() if(${SUNSHINE_BUILD_FLATPAK}) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine_kms.desktop" + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine_terminal.desktop" + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications" + RENAME "${PROJECT_FQDN}_terminal.desktop") +elseif(NOT ${SUNSHINE_BUILD_APPIMAGE}) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine_terminal.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") endif() # metadata file # todo - validate file with `appstream-util validate-relax` -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.appdata.xml" - DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo") +if(NOT ${SUNSHINE_BUILD_FLATPAK}) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.appdata.xml" + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo") +else() + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_FQDN}.metainfo.xml" + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo") +endif() diff --git a/cmake/prep/init.cmake b/cmake/prep/init.cmake index 93e8b597721..ae15d9f2673 100644 --- a/cmake/prep/init.cmake +++ b/cmake/prep/init.cmake @@ -6,4 +6,12 @@ elseif (UNIX) if(NOT DEFINED SUNSHINE_EXECUTABLE_PATH) set(SUNSHINE_EXECUTABLE_PATH "sunshine") endif() + + if(SUNSHINE_BUILD_FLATPAK) + set(SUNSHINE_SERVICE_START_COMMAND "ExecStart=${PROJECT_FQDN}") + set(SUNSHINE_SERVICE_STOP_COMMAND "ExecStop=flatpak kill ${PROJECT_FQDN}") + else() + set(SUNSHINE_SERVICE_START_COMMAND "ExecStart=${SUNSHINE_EXECUTABLE_PATH}") + set(SUNSHINE_SERVICE_STOP_COMMAND "") + endif() endif () diff --git a/cmake/prep/special_package_configuration.cmake b/cmake/prep/special_package_configuration.cmake index 9551db02673..3e5c5d9c370 100644 --- a/cmake/prep/special_package_configuration.cmake +++ b/cmake/prep/special_package_configuration.cmake @@ -10,12 +10,16 @@ if(APPLE) endif() elseif(UNIX) # configure the .desktop file + set(SUNSHINE_DESKTOP_ICON "sunshine.svg") if(${SUNSHINE_BUILD_APPIMAGE}) configure_file(packaging/linux/AppImage/sunshine.desktop sunshine.desktop @ONLY) elseif(${SUNSHINE_BUILD_FLATPAK}) + set(SUNSHINE_DESKTOP_ICON "${PROJECT_FQDN}.svg") configure_file(packaging/linux/flatpak/sunshine.desktop sunshine.desktop @ONLY) configure_file(packaging/linux/flatpak/sunshine_kms.desktop sunshine_kms.desktop @ONLY) configure_file(packaging/linux/sunshine_terminal.desktop sunshine_terminal.desktop @ONLY) + configure_file(packaging/linux/flatpak/${PROJECT_FQDN}.metainfo.xml + ${PROJECT_FQDN}.metainfo.xml @ONLY) else() configure_file(packaging/linux/sunshine.desktop sunshine.desktop @ONLY) configure_file(packaging/linux/sunshine_terminal.desktop sunshine_terminal.desktop @ONLY) @@ -35,7 +39,7 @@ elseif(UNIX) # configure the flatpak manifest if(${SUNSHINE_CONFIGURE_FLATPAK_MAN}) - configure_file(packaging/linux/flatpak/dev.lizardbyte.sunshine.yml dev.lizardbyte.sunshine.yml @ONLY) + configure_file(packaging/linux/flatpak/${PROJECT_FQDN}.yml ${PROJECT_FQDN}.yml @ONLY) file(COPY packaging/linux/flatpak/deps/ DESTINATION ${CMAKE_BINARY_DIR}) file(COPY packaging/linux/flatpak/modules DESTINATION ${CMAKE_BINARY_DIR}) endif() diff --git a/docs/source/about/setup.rst b/docs/source/about/setup.rst index 0866a37a96e..f2e0d8bad54 100644 --- a/docs/source/about/setup.rst +++ b/docs/source/about/setup.rst @@ -148,25 +148,25 @@ Install Additional installation (required) .. code-block:: bash - flatpak run --command=additional-install.sh dev.lizardbyte.sunshine + flatpak run --command=additional-install.sh dev.lizardbyte.app.Sunshine Start: X11 and NVFBC capture (X11 Only) .. code-block:: bash - flatpak run dev.lizardbyte.sunshine + flatpak run dev.lizardbyte.app.Sunshine KMS capture (Wayland & X11) .. code-block:: bash sudo -i PULSE_SERVER=unix:$(pactl info | awk '/Server String/{print$3}') \ - flatpak run dev.lizardbyte.sunshine + flatpak run dev.lizardbyte.app.Sunshine Uninstall: .. code-block:: bash - flatpak run --command=remove-additional-install.sh dev.lizardbyte.sunshine - flatpak uninstall --delete-data dev.lizardbyte.sunshine + flatpak run --command=remove-additional-install.sh dev.lizardbyte.app.Sunshine + flatpak uninstall --delete-data dev.lizardbyte.app.Sunshine .. tab:: Homebrew @@ -253,7 +253,7 @@ Install Restart=on-failure RestartSec=5s #Flatpak Only - #ExecStop=flatpak kill dev.lizardbyte.sunshine + #ExecStop=flatpak kill dev.lizardbyte.app.Sunshine [Install] WantedBy=graphical-session.target @@ -268,7 +268,7 @@ Install deb /usr/bin/sunshine ✔ rpm /usr/bin/sunshine ✔ AppImage ~/sunshine.AppImage ✔ - Flatpak flatpak run dev.lizardbyte.sunshine ✔ + Flatpak flatpak run dev.lizardbyte.app.Sunshine ✔ ======== ============================================== =============== **Start once** @@ -504,7 +504,7 @@ To get a list of available arguments run the following: .. code-block:: bash - flatpak run --command=sunshine dev.lizardbyte.Sunshine --help + flatpak run --command=sunshine dev.lizardbyte.app.Sunshine --help Shortcuts --------- diff --git a/docs/source/troubleshooting/general.rst b/docs/source/troubleshooting/general.rst index 7b4c7f3c073..1cba738fd02 100644 --- a/docs/source/troubleshooting/general.rst +++ b/docs/source/troubleshooting/general.rst @@ -20,7 +20,7 @@ If you forgot your credentials to the web UI, try this. .. code-block:: bash - flatpak run --command=sunshine dev.lizardbyte.Sunshine --creds {new-username} {new-password} + flatpak run --command=sunshine dev.lizardbyte.app.Sunshine --creds {new-username} {new-password} Web UI Access diff --git a/packaging/linux/flatpak/apps.json b/packaging/linux/flatpak/apps.json new file mode 100644 index 00000000000..725bd7ef3cf --- /dev/null +++ b/packaging/linux/flatpak/apps.json @@ -0,0 +1,11 @@ +{ + "env": { + "PATH": "$(PATH):$(HOME)/.local/bin" + }, + "apps": [ + { + "name": "Desktop", + "image-path": "desktop.png" + } + ] +} diff --git a/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.metainfo.xml b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.metainfo.xml new file mode 100644 index 00000000000..8cbbd5a5aa4 --- /dev/null +++ b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.metainfo.xml @@ -0,0 +1,66 @@ + + + @PROJECT_FQDN@ + + @CMAKE_PROJECT_NAME@ + @PROJECT_BRIEF_DESCRIPTION@ + + CC0-1.0 + @PROJECT_LICENSE@ + + + pointing + keyboard + touch + gamepad + + + https://github.com/LizardByte/Sunshine/issues + @PROJECT_HOMEPAGE_URL@ + https://app.lizardbyte.dev/#Donate + https://app.lizardbyte.dev/support + https://translate.lizardbyte.dev + https://docs.lizardbyte.dev + https://github.com/LizardByte/Sunshine + + +

+ @PROJECT_LONG_DESCRIPTION@ +

+ +

NOTE: Allow Sunshine Virtual Input (Required)

+

sudo chown $USER /dev/uinput && echo 'KERNEL=="uinput", SUBSYSTEM=="misc", + OPTIONS+="static_node=uinput", TAG+="uaccess"' | sudo tee + /etc/udev/rules.d/60-sunshine-input.rules

+

NOTE: Sunshine uses a self-signed certificate. The web browser will report it as not secure, + but it is safe.

+

NOTE: KMS Grab (Optional)

+

sudo -i PULSE_SERVER=unix:$(pactl info | awk '/Server String/{print$3}') + flatpak run @PROJECT_FQDN@

+
+ + + + + + + + + + + + + LizardByte + + + https://app.lizardbyte.dev/Sunshine/assets/images/AdobeStock_305732536_1920x1280.jpg + Sunshine + + + + moderate + mild + mild + + @PROJECT_FQDN@.desktop +
diff --git a/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml similarity index 93% rename from packaging/linux/flatpak/dev.lizardbyte.sunshine.yml rename to packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml index f9f10eef8b7..b4c7dbce98d 100644 --- a/packaging/linux/flatpak/dev.lizardbyte.sunshine.yml +++ b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml @@ -1,5 +1,5 @@ --- -app-id: dev.lizardbyte.sunshine +app-id: "@PROJECT_FQDN@" runtime: org.freedesktop.Platform runtime-version: "22.08" sdk: org.freedesktop.Sdk @@ -17,7 +17,7 @@ finish-args: - --share=network # access network - --socket=pulseaudio # play sounds using pulseaudio - --socket=wayland # show windows using Wayland - - --socket=x11 # show windows using X11 + - --socket=fallback-x11 # show windows using X11 - --system-talk-name=org.freedesktop.Avahi # talk to avahi on the system bus - --talk-name=org.freedesktop.Flatpak # talk to flatpak on the session bus @@ -194,7 +194,7 @@ modules: stable-only: true - name: miniupnpc - buildsystem: cmake + buildsystem: cmake-ninja config-opts: - -DUPNPC_BUILD_SAMPLE=OFF - -DUPNPC_BUILD_SHARED=ON @@ -258,7 +258,7 @@ modules: - name: sunshine disabled: false - buildsystem: cmake + buildsystem: cmake-ninja no-make-install: false builddir: true build-options: @@ -277,7 +277,6 @@ modules: - -DBUILD_DOCS=OFF - -DBUILD_WERROR=ON - -DCMAKE_BUILD_TYPE=Release - - -DCMAKE_INSTALL_PREFIX=/app - -DCMAKE_CUDA_COMPILER=/app/cuda/bin/nvcc - -DSUNSHINE_ASSETS_DIR=share/sunshine - -DSUNSHINE_EXECUTABLE_PATH=/app/bin/sunshine @@ -289,20 +288,10 @@ modules: sources: - type: git url: "@GITHUB_CLONE_URL@" - branch: "@GITHUB_BRANCH@" commit: "@GITHUB_COMMIT@" post-install: - # use `sed` to update apps.json with prefixes required for flatpak - # -r (regex) - # -z (handle new lines) https://linuxhint.com/sed-replace-newline-with-space - # `/gm` global and multiline - - sed -r -z -i -e - 's/("((do)|(undo)|(cmd)|(detached))"\s*:\s*\[?\n*\s*")(.*")/\1flatpak-spawn --host \7/gm' - /app/share/sunshine/apps.json - - sed -i - 's%/app/bin/sunshine%flatpak run dev.lizardbyte.sunshine\nExecStop=flatpak kill dev.lizardbyte.sunshine%g' - /app/share/sunshine/systemd/user/sunshine.service - install -D $FLATPAK_BUILDER_BUILDDIR/packaging/linux/flatpak/scripts/* /app/bin + - install -D $FLATPAK_BUILDER_BUILDDIR/packaging/linux/flatpak/apps.json /app/share/sunshine/apps.json run-tests: true test-rule: "" # empty to disable test-commands: diff --git a/packaging/linux/flatpak/sunshine.desktop b/packaging/linux/flatpak/sunshine.desktop index 1c5fe13a409..f1753c9cdc3 100644 --- a/packaging/linux/flatpak/sunshine.desktop +++ b/packaging/linux/flatpak/sunshine.desktop @@ -1,10 +1,10 @@ [Desktop Entry] Type=Application Name=@PROJECT_NAME@ -Exec=flatpak run dev.lizardbyte.sunshine +Exec=@PROJECT_FQDN@ Version=1.0 Comment=@PROJECT_DESCRIPTION@ -Icon=sunshine +Icon=@SUNSHINE_DESKTOP_ICON@ Keywords=gamestream;stream;moonlight;remote play; Categories=AudioVideo;Network;RemoteAccess; Actions=RunInTerminal;KMS; @@ -12,9 +12,9 @@ Actions=RunInTerminal;KMS; [Desktop Action RunInTerminal] Name=Run in Terminal Icon=application-x-executable -Exec=gio launch @CMAKE_INSTALL_FULL_DATAROOTDIR@/applications/sunshine_terminal.desktop +Exec=gio launch @CMAKE_INSTALL_FULL_DATAROOTDIR@/applications/@PROJECT_FQDN@_terminal.desktop [Desktop Action KMS] Name=Run in Terminal (KMS) Icon=application-x-executable -Exec=gio launch @CMAKE_INSTALL_FULL_DATAROOTDIR@/applications/sunshine_kms.desktop +Exec=gio launch @CMAKE_INSTALL_FULL_DATAROOTDIR@/applications/@PROJECT_FQDN@_kms.desktop diff --git a/packaging/linux/flatpak/sunshine_kms.desktop b/packaging/linux/flatpak/sunshine_kms.desktop index 521f4b936ae..59d35d7168c 100644 --- a/packaging/linux/flatpak/sunshine_kms.desktop +++ b/packaging/linux/flatpak/sunshine_kms.desktop @@ -1,6 +1,6 @@ [Desktop Entry] Name=@PROJECT_NAME@ (KMS) -Exec=sudo -i PULSE_SERVER=unix:$(pactl info | awk '/Server String/{print$3}') flatpak run dev.lizardbyte.sunshine +Exec=sudo -i PULSE_SERVER=unix:$(pactl info | awk '/Server String/{print$3}') flatpak run @PROJECT_FQDN@ Terminal=true Type=Application NoDisplay=true diff --git a/packaging/linux/sunshine.appdata.xml b/packaging/linux/sunshine.appdata.xml index fdb6b029bb8..93757eb6c06 100644 --- a/packaging/linux/sunshine.appdata.xml +++ b/packaging/linux/sunshine.appdata.xml @@ -5,7 +5,7 @@ @PROJECT_LICENSE@ @PROJECT_NAME@ @CMAKE_PROJECT_HOMEPAGE_URL@ - @PROJECT_DESCRIPTION@ + @PROJECT_BRIEF_DESCRIPTION@

@PROJECT_LONG_DESCRIPTION@ diff --git a/packaging/linux/sunshine.desktop b/packaging/linux/sunshine.desktop index 719555301d5..bc8a995ca47 100644 --- a/packaging/linux/sunshine.desktop +++ b/packaging/linux/sunshine.desktop @@ -4,7 +4,7 @@ Name=@PROJECT_NAME@ Exec=/usr/bin/env systemctl start --u sunshine Version=1.0 Comment=@PROJECT_DESCRIPTION@ -Icon=sunshine +Icon=@SUNSHINE_DESKTOP_ICON@ Keywords=gamestream;stream;moonlight;remote play; Categories=AudioVideo;Network;RemoteAccess; Actions=RunInTerminal; diff --git a/packaging/linux/sunshine.service.in b/packaging/linux/sunshine.service.in index 008179a6114..df914ebff33 100644 --- a/packaging/linux/sunshine.service.in +++ b/packaging/linux/sunshine.service.in @@ -4,7 +4,8 @@ StartLimitIntervalSec=500 StartLimitBurst=5 [Service] -ExecStart=@SUNSHINE_EXECUTABLE_PATH@ +@SUNSHINE_SERVICE_START_COMMAND@ +@SUNSHINE_SERVICE_STOP_COMMAND@ Restart=on-failure RestartSec=5s