Skip to content

Commit 33c6c3e

Browse files
Merge pull request #2266 from LizardByte/nightly
v0.22.2
2 parents 00fbbc9 + bd5c500 commit 33c6c3e

File tree

5 files changed

+87
-46
lines changed

5 files changed

+87
-46
lines changed

.github/workflows/CI.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ jobs:
588588
echo "publish=${PUBLISH}" >> $GITHUB_OUTPUT
589589
590590
- name: Validate and Publish Homebrew Formula
591-
uses: LizardByte/homebrew-release-action@v2024.311.172824
591+
uses: LizardByte/homebrew-release-action@v2024.314.134529
592592
with:
593593
formula_file: ${{ github.workspace }}/homebrew/sunshine.rb
594594
git_email: ${{ secrets.GH_BOT_EMAIL }}

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## [0.22.2] - 2024-03-15
4+
**Fixed**
5+
- (Tray/Windows) Fix broken system tray icon on some systems
6+
- (Linux) Fix crash when XDG_CONFIG_HOME or CONFIGURATION_DIRECTORY are set
7+
- (Linux) Fix config migration across filesystems and with non-existent parent directories
8+
39
## [0.22.1] - 2024-03-13
410
**Breaking**
511
- (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
759765
[0.21.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.21.0
760766
[0.22.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.22.0
761767
[0.22.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.22.1
768+
[0.22.2]: https://github.com/LizardByte/Sunshine/releases/tag/v0.22.2

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.18)
33
# todo - set this conditionally
44

55
# todo - set version to 0.0.0 once confident in automated versioning
6-
project(Sunshine VERSION 0.22.1
6+
project(Sunshine VERSION 0.22.2
77
DESCRIPTION "Self-hosted game stream host for Moonlight"
88
HOMEPAGE_URL "https://app.lizardbyte.dev/Sunshine")
99

src/platform/linux/misc.cpp

Lines changed: 77 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
// standard includes
1212
#include <fstream>
13+
#include <iostream>
1314

1415
// lib includes
1516
#include <arpa/inet.h>
@@ -98,54 +99,87 @@ namespace platf {
9899
return ifaddr_t { p };
99100
}
100101

102+
/**
103+
* @brief Performs migration if necessary, then returns the appdata directory.
104+
* @details This is used for the log directory, so it cannot invoke Boost logging!
105+
* @return The path of the appdata directory that should be used.
106+
*/
101107
fs::path
102108
appdata() {
103-
bool found = false;
104-
bool migrate_config = true;
105-
const char *dir;
106-
const char *homedir;
107-
fs::path config_path;
108-
109-
// Get the home directory
110-
if ((homedir = getenv("HOME")) == nullptr || strlen(homedir) == 0) {
111-
// If HOME is empty or not set, use the current user's home directory
112-
homedir = getpwuid(geteuid())->pw_dir;
113-
}
114-
115-
// May be set if running under a systemd service with the ConfigurationDirectory= option set.
116-
if ((dir = getenv("CONFIGURATION_DIRECTORY")) != nullptr && strlen(dir) > 0) {
117-
found = true;
118-
config_path = fs::path(dir) / "sunshine"sv;
119-
}
120-
// Otherwise, follow the XDG base directory specification:
121-
// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
122-
if (!found && (dir = getenv("XDG_CONFIG_HOME")) != nullptr && strlen(dir) > 0) {
123-
found = true;
124-
config_path = fs::path(dir) / "sunshine"sv;
125-
}
126-
// As a last resort, use the home directory
127-
if (!found) {
128-
migrate_config = false;
129-
config_path = fs::path(homedir) / ".config/sunshine"sv;
130-
}
131-
132-
// migrate from the old config location if necessary
133-
if (migrate_config && found && getenv("SUNSHINE_MIGRATE_CONFIG") == "1"sv) {
134-
fs::path old_config_path = fs::path(homedir) / ".config/sunshine"sv;
135-
if (old_config_path != config_path && fs::exists(old_config_path)) {
136-
if (!fs::exists(config_path)) {
137-
BOOST_LOG(info) << "Migrating config from "sv << old_config_path << " to "sv << config_path;
138-
std::error_code ec;
139-
fs::rename(old_config_path, config_path, ec);
140-
if (ec) {
141-
return old_config_path;
109+
static std::once_flag migration_flag;
110+
static fs::path config_path;
111+
112+
// Ensure migration is only attempted once
113+
std::call_once(migration_flag, []() {
114+
bool found = false;
115+
bool migrate_config = true;
116+
const char *dir;
117+
const char *homedir;
118+
const char *migrate_envvar;
119+
120+
// Get the home directory
121+
if ((homedir = getenv("HOME")) == nullptr || strlen(homedir) == 0) {
122+
// If HOME is empty or not set, use the current user's home directory
123+
homedir = getpwuid(geteuid())->pw_dir;
124+
}
125+
126+
// May be set if running under a systemd service with the ConfigurationDirectory= option set.
127+
if ((dir = getenv("CONFIGURATION_DIRECTORY")) != nullptr && strlen(dir) > 0) {
128+
found = true;
129+
config_path = fs::path(dir) / "sunshine"sv;
130+
}
131+
// Otherwise, follow the XDG base directory specification:
132+
// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
133+
if (!found && (dir = getenv("XDG_CONFIG_HOME")) != nullptr && strlen(dir) > 0) {
134+
found = true;
135+
config_path = fs::path(dir) / "sunshine"sv;
136+
}
137+
// As a last resort, use the home directory
138+
if (!found) {
139+
migrate_config = false;
140+
config_path = fs::path(homedir) / ".config/sunshine"sv;
141+
}
142+
143+
// migrate from the old config location if necessary
144+
migrate_envvar = getenv("SUNSHINE_MIGRATE_CONFIG");
145+
if (migrate_config && found && migrate_envvar && strcmp(migrate_envvar, "1") == 0) {
146+
std::error_code ec;
147+
fs::path old_config_path = fs::path(homedir) / ".config/sunshine"sv;
148+
if (old_config_path != config_path && fs::exists(old_config_path, ec)) {
149+
if (!fs::exists(config_path, ec)) {
150+
std::cout << "Migrating config from "sv << old_config_path << " to "sv << config_path << std::endl;
151+
if (!ec) {
152+
// Create the new directory tree if it doesn't already exist
153+
fs::create_directories(config_path, ec);
154+
}
155+
if (!ec) {
156+
// Copy the old directory into the new location
157+
// NB: We use a copy instead of a move so that cross-volume migrations work
158+
fs::copy(old_config_path, config_path, fs::copy_options::recursive | fs::copy_options::copy_symlinks, ec);
159+
}
160+
if (!ec) {
161+
// If the copy was successful, delete the original directory
162+
fs::remove_all(old_config_path, ec);
163+
if (ec) {
164+
std::cerr << "Failed to clean up old config directory: " << ec.message() << std::endl;
165+
166+
// This is not fatal. Next time we start, we'll warn the user to delete the old one.
167+
ec.clear();
168+
}
169+
}
170+
if (ec) {
171+
std::cerr << "Migration failed: " << ec.message() << std::endl;
172+
config_path = old_config_path;
173+
}
174+
}
175+
else {
176+
// We cannot use Boost logging because it hasn't been initialized yet!
177+
std::cerr << "Config exists in both "sv << old_config_path << " and "sv << config_path << ". Using "sv << config_path << " for config" << std::endl;
178+
std::cerr << "It is recommended to remove "sv << old_config_path << std::endl;
142179
}
143-
}
144-
else {
145-
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;
146180
}
147181
}
148-
}
182+
});
149183

150184
return config_path;
151185
}

third-party/tray

0 commit comments

Comments
 (0)