diff --git a/override.conf b/override.conf index 6d52022..bf4279a 100644 --- a/override.conf +++ b/override.conf @@ -1,2 +1,7 @@ [Service] -ExtensionDirectories=/var/lib/extensions/tailscale +ExecStartPre= +ExecStartPre=/opt/tailscale/tailscaled --cleanup +ExecStart= +ExecStart=/opt/tailscale/tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock --port=${PORT} $FLAGS +ExecStopPost= +ExecStopPost=/opt/tailscale/tailscaled --cleanup diff --git a/readme.md b/readme.md index 57b1484..1e01419 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,8 @@ automatically on boot (no need to enter desktop mode). 1. Clone this repo to your Deck. 2. Run `sudo bash tailscale.sh` to install Tailscale (or update the existing installation). -3. Run `sudo tailscale up --qr --operator=deck --ssh` to have Tailscale generate +3. Run `source /etc/profile.d/tailscale.sh` to put the binaries in your path +4. Run `sudo tailscale up --qr --operator=deck --ssh` to have Tailscale generate a login QR code. Scan the code with your phone and authenticate with Tailscale to bring your Deck onto your network. @@ -29,48 +30,9 @@ If it doesn't, keep reading. 2. Run `sudo bash tailscale.sh` again. This process overwrites the existing binaries and service file, so it's not -recommended to tweak those files directly. The configuration files at -`/etc/default/tailscaled` and -`/etc/systemd/system/tailscaled.service.d/override.conf` are left alone, so feel -free to edit those. If something goes wrong, copy those files somewhere else and -re-run the install script to get back to a working state. - -## Changing the root filesystem after installing Tailscale - -This method for installing Tailscale uses -[`systemd` system extensions](https://man.archlinux.org/man/systemd-sysext.8.en) -to install files in the otherwise read-only Steam Deck filesystem. A side-effect -is that the `/usr` and `/opt` directories (and directories like `/bin`, `/lib`, -`/lib64`, `/mnt`, and `/sbin`, that typically link to `/usr` due to -[`/usr` merge](https://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/) -which SteamOS implements) are read-only while system extensions are active, -_even after running `steamos-readonly disable`_. - -If you need to modify files in these directories after installing Tailscale, run -the following commands: - -```bash -$ systemd-sysext unmerge -$ steamos-readonly disable -[ make your changes to the rootfs now ] -$ steamos-readonly enable -$ systemd-sysext merge -``` - -## On system update - -Unfortunately, because SteamOS doesn't include a `SYSEXT_LEVEL`, this -installation method breaks when the system version changes. Repair is simple: -Re-run the second step of the installation, and everything should come back up -as you had it. - -### Why this happens - -Extension images have to declare their compatibility using the OS ID and either -the SYSEXT_LEVEL or VERSION_ID, which have to match what the system declares. - -SteamOS doesn't declare a SYSEXT_LEVEL, and the VERSION_ID increments with every -system update, so there's no stable values to declare compatibility against. +recommended to tweak those files directly. The configuration file at +`/etc/default/tailscaled` is left alone. The configuration file at +`/etc/systemd/system/tailscaled.service.d/override.conf` is reset every time this script is run to ensure the path to the binary is correct, but the preexisting file will be backed up in that directory as `override.conf.bak`. If something goes wrong, copy those files somewhere else and re-run the install script to get back to a working state. ## Common issues @@ -82,10 +44,6 @@ Resolution: Delete `/etc/default/tailscaled` and re-run installer script. ## How it works -It uses the same system extension method as the official guide, but we put the -`tailscaled.service` file directly in `/etc/systemd/system/` because it's -actually safe to put things there. Changes in `/etc/` are preserved in -`/var/lib/overlays/etc/upper/` via an overlayfs, meaning that they survive -updates. +The Tailscale binaries `tailscale` and `tailscaled` are installed in `/opt/tailscale/`. The Tailscale systemd unit file is installed at `/etc/systemd/system/tailscale.service`. The override file to reconfigure the services `Exec` commands is installed at `/etc/systemd/system/tailscaled.service.d/override.conf`. The defaults file for the variables `PORT` and `FLAGS` is installed at `/etc/default/tailscaled` -[official-guide]: https://tailscale.com/blog/steam-deck/ +The service is then started and enabled via `systemctl`. diff --git a/tailscale.sh b/tailscale.sh index df9ebe1..1b26937 100644 --- a/tailscale.sh +++ b/tailscale.sh @@ -1,8 +1,5 @@ #!/usr/bin/env bash -# make system configuration vars available -source /etc/os-release - # set invocation settings for this script: # -e: Exit immediately if a command exits with a non-zero status. # -u: Treat unset variables as an error when substituting. @@ -31,6 +28,25 @@ curl -s "https://pkgs.tailscale.com/stable/${tarball}" -o tailscale.tgz echo "done." +echo -n "Removing Legacy Installations..." + +# Stop and disable the systemd service +if systemctl is-active --quiet tailscaled; then + systemctl stop tailscaled &>/dev/null || echo "ERROR: could not stop tailscaled" +fi +if systemctl is-enabled --quiet tailscaled; then + systemctl disable tailscaled &>/dev/null || echo "ERROR: could not disable tailscaled" +fi + +# Remove the systemd system extension +if [ $(systemd-sysext list 2>/dev/null | grep -c "/var/lib/extensions/tailscale") -ne 0 ]; then + systemd-sysext unmerge &>/dev/null || echo "ERROR: could not unmerge system extensions" + rm -rf /var/lib/extensions/tailscale + systemd-sysext merge &>/dev/null || echo "ERROR: could not merge system extensions" +fi + +echo "done." + echo -n "Installing..." # extract the tailscale binaries @@ -38,23 +54,21 @@ tar xzf tailscale.tgz tar_dir="$(echo ${tarball} | cut -d. -f1-3)" test -d $tar_dir -# create our target directory structure -mkdir -p tailscale/usr/{bin,sbin,lib/{systemd/system,extension-release.d}} +# Create binaries directory in home +mkdir -p /opt/tailscale -# pull things into the right place in the target dir structure -cp -rf $tar_dir/tailscale tailscale/usr/bin/tailscale -cp -rf $tar_dir/tailscaled tailscale/usr/sbin/tailscaled +# pull binaries +cp -rf $tar_dir/tailscale /opt/tailscale/tailscale +cp -rf $tar_dir/tailscaled /opt/tailscale/tailscaled -# write a systemd extension-release file -echo -e "ID=steamos\nVERSION_ID=${VERSION_ID}" >> tailscale/usr/lib/extension-release.d/extension-release.tailscale +# add binaries to path via profile.d +if ! test -f /etc/profile.d/tailscale.sh; then + echo 'PATH="$PATH:/opt/tailscale"' >> /etc/profile.d/tailscale.sh + source /etc/profile.d/tailscale.sh +fi -# create the system extension folder if it doesn't already exist, remove the old version of our tailscale extension, and install our new one -mkdir -p /var/lib/extensions -rm -rf /var/lib/extensions/tailscale -cp -rf tailscale /var/lib/extensions/ - -# copy the systemd files into place -cp -rf $tar_dir/systemd/tailscaled.service /etc/systemd/system +# copy the systemd file into place +cp -rf $tar_dir/systemd/tailscaled.service /etc/systemd/system/tailscaled.service # copy in the defaults file if it doesn't already exist if ! test -f /etc/default/tailscaled; then @@ -65,33 +79,52 @@ fi popd > /dev/null rm -rf "${dir}" -# copy in our overrides file if it doesn't already exist -if ! test -f /etc/systemd/system/tailscaled.service.d/override.conf; then - mkdir -p /etc/systemd/system/tailscaled.service.d - cp -rf override.conf /etc/systemd/system/tailscaled.service.d/override.conf +# if an override file already exists, back up and remove +if test -f /etc/systemd/system/tailscaled.service.d/override.conf; then + echo + echo + echo "Warning: An existing Tailscaled systemd override file was detected. It must be replaced." + echo "A backup of the existing file is being placed at /etc/systemd/system/tailscaled.service.d/override.conf.bak" + echo + cp -f /etc/systemd/system/tailscaled.service.d/override.conf /etc/systemd/system/tailscaled.service.d/override.conf.bak + rm /etc/systemd/system/tailscaled.service.d/override.conf fi +# copy our override file in +mkdir -p /etc/systemd/system/tailscaled.service.d +cp -f override.conf /etc/systemd/system/tailscaled.service.d/override.conf + +# capture the above override file in systemd +systemctl daemon-reload + echo "done." -echo "Starting required services..." - -# systemd-sysext - manages system extensions -if systemctl is-enabled --quiet systemd-sysext && systemctl is-active --quiet systemd-sysext; then - echo "systemd-sysext is already enabled and active" -else - systemctl enable systemd-sysext --now # this should be all we need in every case, but something breaks if it's already enabled/running. -fi -systemd-sysext refresh > /dev/null 2>&1 - -echo "Done." +echo -n "Starting required services..." # tailscaled - the tailscale daemon -systemctl enable tailscaled +# Note: enable and start/restart must be run because the legacy installation stops and disables +# any existing installations. +systemctl enable tailscaled &>/dev/null || echo "ERROR: Could not enable tailscaled service" if systemctl is-active --quiet tailscaled; then - echo "Upgrade complete. Restarting tailscaled..." + echo "Upgrade complete." + echo -n "Restarting tailscaled..." else - echo "Install complete. Starting tailscaled..." + echo "Install complete." + echo -n "Starting tailscaled..." fi -systemctl restart tailscaled # This needs to be the last thing we do in case the user's running this over Tailscale SSH. -echo "Done." +# This needs to be the last thing we do in case the user's running this over Tailscale SSH. +systemctl restart tailscaled &>/dev/null || echo "ERROR: Could not start tailscaled service" + +echo "done." + +if ! command -v tailscale &> /dev/null; then + echo + echo "Tailscale is installed and running but the binaries are not in your path yet." + echo "Restart your session or run the following command to add them:" + echo + echo "source /etc/profile.d/tailscale.sh" + echo +fi + +echo "Installation Complete." \ No newline at end of file diff --git a/uninstall.sh b/uninstall.sh new file mode 100644 index 0000000..bcb7670 --- /dev/null +++ b/uninstall.sh @@ -0,0 +1,6 @@ +systemctl stop tailscaled +systemctl disable tailscaled +rm /etc/systemd/system/tailscaled.service +rm /etc/default/tailscaled +rm /etc/profile.d/tailscale.sh +rm -rf /opt/tailscale/tailscale