Skip to content

feat: add offline install script#937

Open
zdennisz wants to merge 4 commits into
SteamDeckHomebrew:mainfrom
zdennisz:feature/offline-install
Open

feat: add offline install script#937
zdennisz wants to merge 4 commits into
SteamDeckHomebrew:mainfrom
zdennisz:feature/offline-install

Conversation

@zdennisz

@zdennisz zdennisz commented Jul 6, 2026

Copy link
Copy Markdown

Summary

  • Adds dist/install_offline.sh — a self-contained offline installer for users with limited internet access
  • Adds "Offline Installation" section to README with 3-step instructions

Closes #924

Usage

sudo sh install_offline.sh ./PluginLoader

User downloads the PluginLoader binary from releases (via mirror, VPN, or patience), transfers it to the Steam Deck, and runs the script. No network required.

What the script does

  1. Resolves binary path to absolute (safe across sudo re-exec)
  2. Detects user home directory via $SUDO_USER
  3. Creates ~/homebrew/{services,plugins,settings} directory structure
  4. Copies binary (validates copy before stopping existing service)
  5. Handles SELinux if enforcing
  6. Installs systemd service from embedded template
  7. Enables and starts plugin_loader.service

Test plan

  • Run on SteamOS with a downloaded PluginLoader binary
  • Verify service starts and Decky is accessible in Gaming Mode
  • Run twice (idempotent — no errors on re-install)
  • Verify dist/uninstall.sh still works after offline install
  • Test with disk-full simulation (service should NOT be left stopped)

🤖 Generated with Claude Code

Dennis Zabolotny and others added 2 commits July 6, 2026 12:19
Closes SteamDeckHomebrew#924 — provides a self-contained install_offline.sh that deploys
a pre-downloaded PluginLoader binary without needing network access.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Resolve binary path to absolute before sudo re-exec
- Defer service stop until after binary copy succeeds (prevents
  leaving Decky stopped on disk-full failures)
- Quote ExecStart/WorkingDirectory in systemd heredoc for paths
  with spaces
- Add sync comment referencing plugin_loader-release.service

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Sakurainy

Copy link
Copy Markdown

Thanks for Implementing the offline installer.
I tested it on my ROG Ally running BazziteOS (I don't have a SteamDeck) .
The installation script completed, but it ended with:
Failed to start plugin_loader.service: Unit plugin_loader.service has a bad unit file setting.
Running systemctl status plugin_loader.service shows:
WorkingDirectory= path is not a directory
I'm not sure whether this is because I'm using BazziteOS instead of SteamOS. If that's the case, I completely understand, since this feature wasn't intended to support BazziteOS in the first place. As long as it works correctly on SteamOS, that's perfectly fine.
I'm not requesting BazziteOS support. I just wanted to share my test result in case it's useful.If there's any testing or additional information I can provide, I'd be happy to help.

@zdennisz

zdennisz commented Jul 7, 2026

Copy link
Copy Markdown
Author

Thanks for testing , I will look into it .

Systemd interprets quotes literally in unit file directives, causing
"path is not a directory" errors on service start.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@zdennisz

zdennisz commented Jul 7, 2026

Copy link
Copy Markdown
Author

@Sakurainy Good catch — the issue was that ExecStart= and WorkingDirectory= had double quotes around the paths in the generated systemd unit file. Systemd interprets those quotes literally (as part of the path), so it was looking for a directory with " characters in its name.

Just pushed a fix (4f281cb). If you get a chance to retest on your ROG Ally, that would be great — the script should now work on BazziteOS too since the home directory detection was already generic (getent passwd).

- Replace $UID (bashism) with $(id -u) for dash/ash compatibility
- Fix privilege escalation: keep binary root-owned instead of chown -R
- Validate USER_DIR is non-empty and exists before proceeding
- Always attempt path resolution regardless of file existence check
- Add rollback trap to restart service if install fails mid-way
- Validate binary is ELF before installing (rejects zips/tarballs)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Request] <title>Is there a offline install method?

2 participants