From 476141d740bc5ae622967db6c57ccf156b2a6483 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 21:13:55 -0400 Subject: [PATCH 1/7] build(deps): bump LizardByte/homebrew-release-action from 2024.311.172824 to 2024.314.134529 (#2264) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 80c309ca052..09a0aaeae66 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -588,7 +588,7 @@ jobs: echo "publish=${PUBLISH}" >> $GITHUB_OUTPUT - name: Validate and Publish Homebrew Formula - uses: LizardByte/homebrew-release-action@v2024.311.172824 + uses: LizardByte/homebrew-release-action@v2024.314.134529 with: formula_file: ${{ github.workspace }}/homebrew/sunshine.rb git_email: ${{ secrets.GH_BOT_EMAIL }} From b523945f48ba5542dc5a3fd1d3897ba726092723 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 14 Mar 2024 18:11:27 -0500 Subject: [PATCH 2/7] Update tray submodule to fix broken tray icon on some systems --- third-party/tray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third-party/tray b/third-party/tray index a08c1025c3f..4d8b798cafd 160000 --- a/third-party/tray +++ b/third-party/tray @@ -1 +1 @@ -Subproject commit a08c1025c3f158d6b6c4b9bcf0ab770291d26896 +Subproject commit 4d8b798cafdd11285af9409c16b5f792968e0045 From f66a7d5da65a00d5b8cb8aed79169b67be9c1076 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 14 Mar 2024 18:37:00 -0500 Subject: [PATCH 3/7] Fix dereferencing a null pointer if SUNSHINE_MIGRATE_CONFIG doesn't exist --- src/platform/linux/misc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index 884c0e9047a..b4de6005d13 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -104,6 +104,7 @@ namespace platf { bool migrate_config = true; const char *dir; const char *homedir; + const char *migrate_envvar; fs::path config_path; // Get the home directory @@ -130,7 +131,8 @@ namespace platf { } // migrate from the old config location if necessary - if (migrate_config && found && getenv("SUNSHINE_MIGRATE_CONFIG") == "1"sv) { + migrate_envvar = getenv("SUNSHINE_MIGRATE_CONFIG"); + if (migrate_config && found && migrate_envvar && strcmp(migrate_envvar, "1") == 0) { fs::path old_config_path = fs::path(homedir) / ".config/sunshine"sv; if (old_config_path != config_path && fs::exists(old_config_path)) { if (!fs::exists(config_path)) { From aa1985dec84fcf26b941a2bde4998351bbb2f2a9 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 15 Mar 2024 00:11:02 -0500 Subject: [PATCH 4/7] Avoid calling Boost logging functions in appdata() The app data directory is needed prior to logging initialization. --- src/platform/linux/misc.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index b4de6005d13..b4e3d1aec9b 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -10,6 +10,7 @@ // standard includes #include +#include // lib includes #include @@ -98,6 +99,11 @@ namespace platf { return ifaddr_t { p }; } + /** + * @brief Performs migration if necessary, then returns the appdata directory. + * @details This is used for the log directory, so it cannot invoke Boost logging! + * @return The path of the appdata directory that should be used. + */ fs::path appdata() { bool found = false; @@ -136,15 +142,18 @@ namespace platf { fs::path old_config_path = fs::path(homedir) / ".config/sunshine"sv; if (old_config_path != config_path && fs::exists(old_config_path)) { if (!fs::exists(config_path)) { - BOOST_LOG(info) << "Migrating config from "sv << old_config_path << " to "sv << config_path; + std::cout << "Migrating config from "sv << old_config_path << " to "sv << config_path << std::endl; std::error_code ec; fs::rename(old_config_path, config_path, ec); if (ec) { + std::cerr << "Migration failed: " << ec.message() << std::endl; return old_config_path; } } else { - BOOST_LOG(warning) << "Config exists in both "sv << old_config_path << " and "sv << config_path << ", using "sv << config_path << "... it is recommended to remove "sv << old_config_path; + // We cannot use Boost logging because it hasn't been initialized yet! + std::cerr << "Config exists in both "sv << old_config_path << " and "sv << config_path << ". Using "sv << config_path << " for config" << std::endl; + std::cerr << "It is recommended to remove "sv << old_config_path << std::endl; } } } From 8c9e14e3356ee05b1f48f777e44cbfde9e74a083 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 15 Mar 2024 00:15:55 -0500 Subject: [PATCH 5/7] Only attempt a config migration once per launch --- src/platform/linux/misc.cpp | 101 +++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 48 deletions(-) diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index b4e3d1aec9b..092c5607983 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -106,57 +106,62 @@ namespace platf { */ fs::path appdata() { - bool found = false; - bool migrate_config = true; - const char *dir; - const char *homedir; - const char *migrate_envvar; - fs::path config_path; - - // Get the home directory - if ((homedir = getenv("HOME")) == nullptr || strlen(homedir) == 0) { - // If HOME is empty or not set, use the current user's home directory - homedir = getpwuid(geteuid())->pw_dir; - } - - // May be set if running under a systemd service with the ConfigurationDirectory= option set. - if ((dir = getenv("CONFIGURATION_DIRECTORY")) != nullptr && strlen(dir) > 0) { - found = true; - config_path = fs::path(dir) / "sunshine"sv; - } - // Otherwise, follow the XDG base directory specification: - // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html - if (!found && (dir = getenv("XDG_CONFIG_HOME")) != nullptr && strlen(dir) > 0) { - found = true; - config_path = fs::path(dir) / "sunshine"sv; - } - // As a last resort, use the home directory - if (!found) { - migrate_config = false; - config_path = fs::path(homedir) / ".config/sunshine"sv; - } - - // migrate from the old config location if necessary - migrate_envvar = getenv("SUNSHINE_MIGRATE_CONFIG"); - if (migrate_config && found && migrate_envvar && strcmp(migrate_envvar, "1") == 0) { - fs::path old_config_path = fs::path(homedir) / ".config/sunshine"sv; - if (old_config_path != config_path && fs::exists(old_config_path)) { - if (!fs::exists(config_path)) { - std::cout << "Migrating config from "sv << old_config_path << " to "sv << config_path << std::endl; - std::error_code ec; - fs::rename(old_config_path, config_path, ec); - if (ec) { - std::cerr << "Migration failed: " << ec.message() << std::endl; - return old_config_path; + static std::once_flag migration_flag; + static fs::path config_path; + + // Ensure migration is only attempted once + std::call_once(migration_flag, []() { + bool found = false; + bool migrate_config = true; + const char *dir; + const char *homedir; + const char *migrate_envvar; + + // Get the home directory + if ((homedir = getenv("HOME")) == nullptr || strlen(homedir) == 0) { + // If HOME is empty or not set, use the current user's home directory + homedir = getpwuid(geteuid())->pw_dir; + } + + // May be set if running under a systemd service with the ConfigurationDirectory= option set. + if ((dir = getenv("CONFIGURATION_DIRECTORY")) != nullptr && strlen(dir) > 0) { + found = true; + config_path = fs::path(dir) / "sunshine"sv; + } + // Otherwise, follow the XDG base directory specification: + // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html + if (!found && (dir = getenv("XDG_CONFIG_HOME")) != nullptr && strlen(dir) > 0) { + found = true; + config_path = fs::path(dir) / "sunshine"sv; + } + // As a last resort, use the home directory + if (!found) { + migrate_config = false; + config_path = fs::path(homedir) / ".config/sunshine"sv; + } + + // migrate from the old config location if necessary + migrate_envvar = getenv("SUNSHINE_MIGRATE_CONFIG"); + if (migrate_config && found && migrate_envvar && strcmp(migrate_envvar, "1") == 0) { + fs::path old_config_path = fs::path(homedir) / ".config/sunshine"sv; + if (old_config_path != config_path && fs::exists(old_config_path)) { + if (!fs::exists(config_path)) { + std::cout << "Migrating config from "sv << old_config_path << " to "sv << config_path << std::endl; + std::error_code ec; + fs::rename(old_config_path, config_path, ec); + if (ec) { + std::cerr << "Migration failed: " << ec.message() << std::endl; + config_path = old_config_path; + } + } + else { + // We cannot use Boost logging because it hasn't been initialized yet! + std::cerr << "Config exists in both "sv << old_config_path << " and "sv << config_path << ". Using "sv << config_path << " for config" << std::endl; + std::cerr << "It is recommended to remove "sv << old_config_path << std::endl; } - } - else { - // We cannot use Boost logging because it hasn't been initialized yet! - std::cerr << "Config exists in both "sv << old_config_path << " and "sv << config_path << ". Using "sv << config_path << " for config" << std::endl; - std::cerr << "It is recommended to remove "sv << old_config_path << std::endl; } } - } + }); return config_path; } From 15c5e76ed4d994439322812df36e25f7b26c1814 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 15 Mar 2024 00:44:53 -0500 Subject: [PATCH 6/7] Use a copy+delete instead of a move operation for config migration This can handle migration across filesystems. --- src/platform/linux/misc.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index 092c5607983..980c0804858 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -143,12 +143,30 @@ namespace platf { // migrate from the old config location if necessary migrate_envvar = getenv("SUNSHINE_MIGRATE_CONFIG"); if (migrate_config && found && migrate_envvar && strcmp(migrate_envvar, "1") == 0) { + std::error_code ec; fs::path old_config_path = fs::path(homedir) / ".config/sunshine"sv; - if (old_config_path != config_path && fs::exists(old_config_path)) { - if (!fs::exists(config_path)) { + if (old_config_path != config_path && fs::exists(old_config_path, ec)) { + if (!fs::exists(config_path, ec)) { std::cout << "Migrating config from "sv << old_config_path << " to "sv << config_path << std::endl; - std::error_code ec; - fs::rename(old_config_path, config_path, ec); + if (!ec) { + // Create the new directory tree if it doesn't already exist + fs::create_directories(config_path, ec); + } + if (!ec) { + // Copy the old directory into the new location + // NB: We use a copy instead of a move so that cross-volume migrations work + fs::copy(old_config_path, config_path, fs::copy_options::recursive | fs::copy_options::copy_symlinks, ec); + } + if (!ec) { + // If the copy was successful, delete the original directory + fs::remove_all(old_config_path, ec); + if (ec) { + std::cerr << "Failed to clean up old config directory: " << ec.message() << std::endl; + + // This is not fatal. Next time we start, we'll warn the user to delete the old one. + ec.clear(); + } + } if (ec) { std::cerr << "Migration failed: " << ec.message() << std::endl; config_path = old_config_path; From bd5c50041cc020f648a45f8130ed421f2c8fc901 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 14 Mar 2024 18:37:27 -0500 Subject: [PATCH 7/7] Update changelog and bump version to v0.22.2 --- CHANGELOG.md | 7 +++++++ CMakeLists.txt | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1c67c68c3f..d4fbff3a4ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [0.22.2] - 2024-03-15 +**Fixed** +- (Tray/Windows) Fix broken system tray icon on some systems +- (Linux) Fix crash when XDG_CONFIG_HOME or CONFIGURATION_DIRECTORY are set +- (Linux) Fix config migration across filesystems and with non-existent parent directories + ## [0.22.1] - 2024-03-13 **Breaking** - (ArchLinux) Drop support for standalone PKGBUILD files. Use the binary Arch package or install via AUR instead. @@ -759,3 +765,4 @@ settings. In v0.17.0, games now run under your user account without elevated pri [0.21.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.21.0 [0.22.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.22.0 [0.22.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.22.1 +[0.22.2]: https://github.com/LizardByte/Sunshine/releases/tag/v0.22.2 diff --git a/CMakeLists.txt b/CMakeLists.txt index fce20cd2bb7..ebff395abbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.18) # todo - set this conditionally # todo - set version to 0.0.0 once confident in automated versioning -project(Sunshine VERSION 0.22.1 +project(Sunshine VERSION 0.22.2 DESCRIPTION "Self-hosted game stream host for Moonlight" HOMEPAGE_URL "https://app.lizardbyte.dev/Sunshine")