From c27d0fab55d6a9ecd45a3c00d3ca8850b990c3dd Mon Sep 17 00:00:00 2001 From: Benjamin Pannell Date: Tue, 28 Mar 2023 23:45:16 +0100 Subject: [PATCH 01/10] feat: Add support for automatically installing Tailscale after a firmware upgrade --- package/manage.sh | 11 +++++++++-- package/unios_1.x.sh | 8 ++++++++ package/unios_2.x.sh | 28 +++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/package/manage.sh b/package/manage.sh index 14c8772..c09109f 100755 --- a/package/manage.sh +++ b/package/manage.sh @@ -22,7 +22,10 @@ else fi tailscale_status() { - if _tailscale_is_running; then + if ! _tailscale_is_installed; then + echo "Tailscale is not installed" + exit 1 + elif _tailscale_is_running; then echo "Tailscaled is running" $TAILSCALE --version else @@ -112,8 +115,12 @@ case $1 in fi ;; "on-boot") + if ! _tailscale_is_installed; then + tailscale_install + fi + # shellcheck source=package/tailscale-env - . "${TAILSCALE_ROOT}/tailscale-env" + . "${PACKAGE_ROOT}/tailscale-env" if [ "${TAILSCALE_AUTOUPDATE}" = "true" ]; then tailscale_has_update && tailscale_update || echo "Not updated" diff --git a/package/unios_1.x.sh b/package/unios_1.x.sh index 03f4ab5..2cb0ddd 100644 --- a/package/unios_1.x.sh +++ b/package/unios_1.x.sh @@ -12,6 +12,14 @@ _tailscale_is_running() { fi } +_tailscale_is_installed() { + if [ -e "${TAILSCALE}" ] && [ -e "${TAILSCALED}" ]; then + return 0 + else + return 1 + fi +} + _tailscale_start() { # shellcheck source=package/tailscale-env . "${TAILSCALE_ROOT}/tailscale-env" diff --git a/package/unios_2.x.sh b/package/unios_2.x.sh index 9f01be2..49c74e5 100644 --- a/package/unios_2.x.sh +++ b/package/unios_2.x.sh @@ -6,6 +6,10 @@ _tailscale_is_running() { systemctl is-active --quiet tailscaled } +_tailscale_is_installed() { + command -v tailscale >/dev/null 2>&1 +} + _tailscale_start() { systemctl start tailscaled @@ -67,7 +71,29 @@ _tailscale_install() { echo "You can enable it manually using 'systemctl enable tailscaled'." exit 1 } - + + if [ ! -f "/lib/systemd/system/tailscale-install.service" ]; then + echo "Installing pre-start script to install Tailscale on firmware updates." + cat >/lib/systemd/system/tailscale-install.service < Date: Tue, 28 Mar 2023 23:52:37 +0100 Subject: [PATCH 02/10] test: Update tests for new UniFi OS 2.x install process --- package/unios_2.x.sh | 2 +- tests/install.1.x.test.sh | 0 tests/install.2.x.test.sh | 1 + tests/status.1.x.test.sh | 0 tests/update.1.x.test.sh | 0 5 files changed, 2 insertions(+), 1 deletion(-) mode change 100644 => 100755 tests/install.1.x.test.sh mode change 100644 => 100755 tests/install.2.x.test.sh mode change 100644 => 100755 tests/status.1.x.test.sh mode change 100644 => 100755 tests/update.1.x.test.sh diff --git a/package/unios_2.x.sh b/package/unios_2.x.sh index 49c74e5..2838357 100644 --- a/package/unios_2.x.sh +++ b/package/unios_2.x.sh @@ -74,7 +74,7 @@ _tailscale_install() { if [ ! -f "/lib/systemd/system/tailscale-install.service" ]; then echo "Installing pre-start script to install Tailscale on firmware updates." - cat >/lib/systemd/system/tailscale-install.service </dev/null < Date: Tue, 28 Mar 2023 23:55:03 +0100 Subject: [PATCH 03/10] test: Improve testing for new UniFi OS 2.x install procedure --- package/unios_2.x.sh | 4 ++-- tests/install.2.x.test.sh | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/package/unios_2.x.sh b/package/unios_2.x.sh index 2838357..fc56927 100644 --- a/package/unios_2.x.sh +++ b/package/unios_2.x.sh @@ -59,14 +59,14 @@ _tailscale_install() { } echo "Restarting Tailscale daemon to detect new configuration..." - systemctl restart tailscaled || { + systemctl restart tailscaled.service || { echo "Failed to restart Tailscale daemon" echo "The daemon might not be running with userspace networking enabled, you can restart it manually using 'systemctl restart tailscaled'." exit 1 } echo "Enabling Tailscale to start on boot..." - systemctl enable tailscaled || { + systemctl enable tailscaled.service || { echo "Failed to enable Tailscale to start on boot" echo "You can enable it manually using 'systemctl enable tailscaled'." exit 1 diff --git a/tests/install.2.x.test.sh b/tests/install.2.x.test.sh index 365440d..19216de 100755 --- a/tests/install.2.x.test.sh +++ b/tests/install.2.x.test.sh @@ -35,8 +35,12 @@ case "\$1" in exit 1 ;; "enable") - echo "--## systemctl enable ##--" - touch "${WORKDIR}/tailscaled.enabled" + echo "--## systemctl enable \$2 ##--" + touch "${WORKDIR}/\$2.enabled" + ;; + "daemon-reload") + echo "--## systemctl daemon-reload ##--" + touch "${WORKDIR}/systemctl.daemon-reload" ;; "restart") echo "--## systemctl restart ##--" @@ -58,4 +62,6 @@ assert_contains "$(head -n 1 "${WORKDIR}/apt.args")" "update" "The apt command s assert_contains "$(head -n 2 "${WORKDIR}/apt.args" | tail -n 1)" "install -y tailscale" "The apt command should be called with the command to install tailscale file" assert_contains "$(cat "${WORKDIR}/sed.args")" "--tun userspace-networking" "The defaults should be updated with userspace networking" [[ -f "${WORKDIR}/tailscaled.restarted" ]]; assert "tailscaled should have been restarted" -[[ -f "${WORKDIR}/tailscaled.enabled" ]]; assert "tailscaled unit should be enabled" +[[ -f "${WORKDIR}/tailscaled.service.enabled" ]]; assert "tailscaled unit should be enabled" +[[ -f "${WORKDIR}/systemctl.daemon-reload" ]]; assert "systemctl should have been reloaded" +[[ -f "${WORKDIR}/tailscale-install.service.enabled" ]]; assert "tailscale-install unit should be enabled" From 2aefcdcd309eb4b7da7e783beecc1f42e4372591 Mon Sep 17 00:00:00 2001 From: Benjamin Pannell Date: Tue, 28 Mar 2023 23:58:18 +0100 Subject: [PATCH 04/10] test: Improve tests for the status commands --- tests/status.1.x.test.sh | 5 ++++- tests/status.2.x.test.sh | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/status.1.x.test.sh b/tests/status.1.x.test.sh index 48b9ece..762897a 100755 --- a/tests/status.1.x.test.sh +++ b/tests/status.1.x.test.sh @@ -14,8 +14,11 @@ export TAILSCALED_SOCK="${WORKDIR}/tailscaled.sock" export PATH="${WORKDIR}:${PATH}" mock "${WORKDIR}/ubnt-device-info" "1.0.0" -mock "${WORKDIR}/tailscale" "0.0.0" +assert_eq "$("${ROOT}/package/manage.sh" status)" "Tailscaled is not installed" + +mock "${WORKDIR}/tailscale" "0.0.0" +mock "${WORKDIR}/tailscaled" "0.0.0" assert_eq "$("${ROOT}/package/manage.sh" status)" "Tailscaled is not running" "Tailscaled should be reported as not running" touch "${TAILSCALED_SOCK}"; assert "The tailscale socket should be created" diff --git a/tests/status.2.x.test.sh b/tests/status.2.x.test.sh index 516173f..8e61634 100755 --- a/tests/status.2.x.test.sh +++ b/tests/status.2.x.test.sh @@ -14,6 +14,9 @@ export TAILSCALED_SOCK="${WORKDIR}/tailscaled.sock" export PATH="${WORKDIR}:${PATH}" mock "${WORKDIR}/ubnt-device-info" "2.0.0" + +assert_eq "$("${ROOT}/package/manage.sh" status)" "Tailscaled is not installed" + mock "${WORKDIR}/tailscale" "0.0.0" mock "${WORKDIR}/systemctl" "" 1 From 49b4a62ac163498d04dd4fef9d8bba4f829021a5 Mon Sep 17 00:00:00 2001 From: Benjamin Pannell Date: Tue, 28 Mar 2023 23:59:19 +0100 Subject: [PATCH 05/10] test: Update test assertions --- tests/status.1.x.test.sh | 2 +- tests/status.2.x.test.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/status.1.x.test.sh b/tests/status.1.x.test.sh index 762897a..361725c 100755 --- a/tests/status.1.x.test.sh +++ b/tests/status.1.x.test.sh @@ -15,7 +15,7 @@ export TAILSCALED_SOCK="${WORKDIR}/tailscaled.sock" export PATH="${WORKDIR}:${PATH}" mock "${WORKDIR}/ubnt-device-info" "1.0.0" -assert_eq "$("${ROOT}/package/manage.sh" status)" "Tailscaled is not installed" +assert_eq "$("${ROOT}/package/manage.sh" status)" "Tailscaled is not installed" "Tailscaled should be reported as not installed" mock "${WORKDIR}/tailscale" "0.0.0" mock "${WORKDIR}/tailscaled" "0.0.0" diff --git a/tests/status.2.x.test.sh b/tests/status.2.x.test.sh index 8e61634..d89e4a7 100755 --- a/tests/status.2.x.test.sh +++ b/tests/status.2.x.test.sh @@ -15,7 +15,7 @@ export TAILSCALED_SOCK="${WORKDIR}/tailscaled.sock" export PATH="${WORKDIR}:${PATH}" mock "${WORKDIR}/ubnt-device-info" "2.0.0" -assert_eq "$("${ROOT}/package/manage.sh" status)" "Tailscaled is not installed" +assert_eq "$("${ROOT}/package/manage.sh" status)" "Tailscaled is not installed" "Tailscaled should be reported as not installed" mock "${WORKDIR}/tailscale" "0.0.0" From c221f990c4b59988f8d1cb549d2efab8dd6071bf Mon Sep 17 00:00:00 2001 From: Benjamin Pannell Date: Wed, 29 Mar 2023 00:00:00 +0100 Subject: [PATCH 06/10] test: Update status command output assertions --- tests/status.1.x.test.sh | 2 +- tests/status.2.x.test.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/status.1.x.test.sh b/tests/status.1.x.test.sh index 361725c..7df9b9b 100755 --- a/tests/status.1.x.test.sh +++ b/tests/status.1.x.test.sh @@ -15,7 +15,7 @@ export TAILSCALED_SOCK="${WORKDIR}/tailscaled.sock" export PATH="${WORKDIR}:${PATH}" mock "${WORKDIR}/ubnt-device-info" "1.0.0" -assert_eq "$("${ROOT}/package/manage.sh" status)" "Tailscaled is not installed" "Tailscaled should be reported as not installed" +assert_eq "$("${ROOT}/package/manage.sh" status)" "Tailscale is not installed" "Tailscaled should be reported as not installed" mock "${WORKDIR}/tailscale" "0.0.0" mock "${WORKDIR}/tailscaled" "0.0.0" diff --git a/tests/status.2.x.test.sh b/tests/status.2.x.test.sh index d89e4a7..37d4f57 100755 --- a/tests/status.2.x.test.sh +++ b/tests/status.2.x.test.sh @@ -15,7 +15,7 @@ export TAILSCALED_SOCK="${WORKDIR}/tailscaled.sock" export PATH="${WORKDIR}:${PATH}" mock "${WORKDIR}/ubnt-device-info" "2.0.0" -assert_eq "$("${ROOT}/package/manage.sh" status)" "Tailscaled is not installed" "Tailscaled should be reported as not installed" +assert_eq "$("${ROOT}/package/manage.sh" status)" "Tailscale is not installed" "Tailscaled should be reported as not installed" mock "${WORKDIR}/tailscale" "0.0.0" From b93ee1139569fb79fdb72f6e1eff42a09b51c6db Mon Sep 17 00:00:00 2001 From: Benjamin Pannell Date: Wed, 29 Mar 2023 00:08:27 +0100 Subject: [PATCH 07/10] fix: Ensure that we cleanup the tailscale-install script when uninstalling --- package/unios_2.x.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package/unios_2.x.sh b/package/unios_2.x.sh index fc56927..5e929cf 100644 --- a/package/unios_2.x.sh +++ b/package/unios_2.x.sh @@ -98,6 +98,9 @@ EOF } _tailscale_uninstall() { - apt remove tailscale + apt remove -y tailscale rm -f /etc/apt/sources.list.d/tailscale.list || true + + systemctl disable tailscale-install.service || true + rm -f /lib/systemd/system/tailscale-install.service || true } From 21bd7f4b8c7a64ef20647ae848ec6bdb8e7c4620 Mon Sep 17 00:00:00 2001 From: Benjamin Pannell Date: Wed, 29 Mar 2023 12:13:00 +0100 Subject: [PATCH 08/10] feat: Make it easier to re-install Tailscale if it is already present --- package/manage.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/package/manage.sh b/package/manage.sh index c09109f..98b7f98 100755 --- a/package/manage.sh +++ b/package/manage.sh @@ -85,10 +85,14 @@ case $1 in ;; "install") if _tailscale_is_running; then - echo "Tailscale is already installed, if you wish to update it, run '$0 update'" + echo "Tailscale is already installed and running, if you wish to update it, run '$0 update'" + echo "If you wish to force a reinstall, run '$0 install!'" exit 0 fi + tailscale_install "$2" + ;; + "install!") tailscale_install "$2" ;; "uninstall") From ea5c902adcd535f374c60360b3f37b99841a1fa3 Mon Sep 17 00:00:00 2001 From: Benjamin Pannell Date: Sat, 1 Apr 2023 23:47:00 +0100 Subject: [PATCH 09/10] tweak: Make changes to ensure that we don't lose the tailscale-install service after a firmware upgrade --- build/package.sh | 1 + package/tailscale-install.service | 13 +++++++++++++ package/unios_2.x.sh | 18 ++---------------- tests/install.2.x.test.sh | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) create mode 100644 package/tailscale-install.service diff --git a/build/package.sh b/build/package.sh index 54f3bcc..f42fd56 100755 --- a/build/package.sh +++ b/build/package.sh @@ -12,6 +12,7 @@ cp "${SOURCE}/package/on-boot.sh" "${WORKDIR}/on_boot.d/10-tailscaled.sh" cp "${SOURCE}/package/manage.sh" "${WORKDIR}/tailscale/manage.sh" cp "${SOURCE}/package/unios_"*".sh" "${WORKDIR}/tailscale/" cp "${SOURCE}/package/tailscale-env" "${WORKDIR}/tailscale/tailscale-env" +cp "${SOURCE}/package/tailscale-install.service" "${WORKDIR}/tailscale/tailscale-install.service" cp "${SOURCE}/LICENSE" "${WORKDIR}/tailscale/LICENSE" echo "Building tailscale-udm package" diff --git a/package/tailscale-install.service b/package/tailscale-install.service new file mode 100644 index 0000000..bba4f7c --- /dev/null +++ b/package/tailscale-install.service @@ -0,0 +1,13 @@ +[Unit] +Description=Ensure that Tailscale is installed on your device +Before=tailscaled.service +After=network.target + +[Service] +Type=oneshot +RemainAfterExit=yes +Restart=no +ExecStart=/bin/bash /data/tailscale/manage.sh install + +[Install] +WantedBy=tailscaled.service multi-user.target \ No newline at end of file diff --git a/package/unios_2.x.sh b/package/unios_2.x.sh index 5e929cf..0afc0bd 100644 --- a/package/unios_2.x.sh +++ b/package/unios_2.x.sh @@ -72,23 +72,9 @@ _tailscale_install() { exit 1 } - if [ ! -f "/lib/systemd/system/tailscale-install.service" ]; then + if [ ! -e "/etc/systemd/system/tailscale-install.service" ]; then echo "Installing pre-start script to install Tailscale on firmware updates." - tee /lib/systemd/system/tailscale-install.service >/dev/null < Date: Sun, 2 Apr 2023 22:32:00 +0100 Subject: [PATCH 10/10] fix: Resolve hang on setup, and needing some time after boot before network becomes available to install Tailscale --- package/tailscale-install.service | 9 ++++++--- package/unios_2.x.sh | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/package/tailscale-install.service b/package/tailscale-install.service index bba4f7c..2bb21bd 100644 --- a/package/tailscale-install.service +++ b/package/tailscale-install.service @@ -1,13 +1,16 @@ [Unit] Description=Ensure that Tailscale is installed on your device -Before=tailscaled.service After=network.target [Service] Type=oneshot RemainAfterExit=yes Restart=no -ExecStart=/bin/bash /data/tailscale/manage.sh install +Environment=DEBIAN_FRONTEND=noninteractive + +# Wait 30 seconds after booting before attempting to install Tailscale +ExecStartPre=/bin/bash -c 'sleep 30' +ExecStart=/bin/bash /data/tailscale/manage.sh on-boot [Install] -WantedBy=tailscaled.service multi-user.target \ No newline at end of file +WantedBy=multi-user.target \ No newline at end of file diff --git a/package/unios_2.x.sh b/package/unios_2.x.sh index 0afc0bd..80d3698 100644 --- a/package/unios_2.x.sh +++ b/package/unios_2.x.sh @@ -12,7 +12,7 @@ _tailscale_is_installed() { _tailscale_start() { systemctl start tailscaled - + # Wait a few seconds for the daemon to start sleep 5