Files
unraid-tailscale-cli/tailscale-cli.plg

242 lines
9.4 KiB
XML

<?xml version='1.0' standalone='yes'?>
<!DOCTYPE PLUGIN [
<!ENTITY name "tailscale-cli">
<!ENTITY author "ich777">
<!ENTITY version "2025.04.24">
<!ENTITY gitURL "https://raw.githubusercontent.com/&author;/unraid-&name;/master">
<!ENTITY pluginURL "&gitURL;/&name;.plg">
<!ENTITY plugin "/boot/config/plugins/&name;">
<!ENTITY emhttp "/usr/local/emhttp/plugins/&name;">
]>
<PLUGIN name="&name;" author="&author;" version="&version;" pluginURL="&pluginURL;" min="6.12.0">
<CHANGES>
###2025.04.24
- Make sure to put tailscaled and tailscale binaries into /usr/local/sbin/
###2025.04.23a
- Move tailscale state directory on removal to: /boot/config/.tailscale_cli_state and make sure to restore it from that location on new install
###2025.04.23
- Add Tailscale icon to Unraid header to show if Tailscale is connected or not
###2025.04.20
- Add entry to settings.cfg to disable auto updates
###2025.04.19a
- Add daily cron job at 5:30 to check for new Tailscale versions
###2025.04.18a
- Initial Release
</CHANGES>
<FILE Name="&emhttp;/README.md">
<INLINE>
**Tailscale CLI**
This plugin installs Tailscale on your Unraid server, no GUI only CLI, just plain Tailscale.
</INLINE>
</FILE>
<FILE Run="/bin/bash">
<INLINE>
echo
#Create folders if not found
if [ ! -d "&plugin;" ]; then
mkdir -p &plugin;/{state,tailscale-package}
fi
#Create settings file if not found and try to get Headscale container name
if [ ! -f "&plugin;/settings.cfg" ]; then
echo 'TAILSCALE_ENABLED=true
TAILSCALE_UPDATE_CHECK=true
TAILSCALED_PARAMS=' > "&plugin;/settings.cfg"
fi
#Add missing setting if not found
if ! grep -q "TAILSCALE_UPDATE_CHECK=" &plugin;/settings.cfg; then
sed -i '$ a\TAILSCALE_UPDATE_CHECK=true' &plugin;/settings.cfg
fi
#Move previous state directory back to plugin directory if found
if [ -d /boot/config/.tailscale_cli_state ]; then
echo "Found previous Tailscale state directory, restoring..."
cp -R /boot/config/.tailscale_cli_state/* &plugin;/state/
rm -rf /boot/config/.tailscale_cli_state
fi
#Get/set variables
SETTINGS="$(cat &plugin;/settings.cfg)"
NEWPACKAGE="false"
#Get latest and local version from Tailscale
TAILSCALE_AVAIL_VERSION="$(ls -1 &plugin;/tailscale-package/ 2&gt;/dev/null | cut -d '_' -f2 | sort -V | tail -1)"
if [ "$(echo "${SETTINGS}" | grep "TAILSCALE_UPDATE_CHECK=" | cut -d '=' -f2-)" == "true" ]; then
TAILSCALE_VERSION="$(wget -qO- 'https://pkgs.tailscale.com/stable/?mode=json' | jq -r '.TarballsVersion')"
else
echo "WARNING: Auto updates from Tailscale disabled"
TAILSCALE_VERSION="${TAILSCALE_AVAIL_VERSION}"
fi
if [ -z "${TAILSCALE_VERSION}" ]; then
if [ -z "${TAILSCALE_AVAIL_VERSION}" ]; then
echo "ERROR: Can't get latest version and found no local version from Tailscale"
rm -rf &plugin;
exit 1
else
TAILSCALE_VERSION="${TAILSCALE_AVAIL_VERSION}"
echo "WARNING: Can't get latest version from Tailscale, falling back to local version: ${TAILSCALE_VERSION}"
fi
fi
#Version Check
if [ -z "${TAILSCALE_AVAIL_VERSION}" ]; then
echo "Tailscale not found, downloading version: ${TAILSCALE_VERSION}"
if wget -q -nc -O &plugin;/tailscale-package/tailscale_${TAILSCALE_VERSION}_amd64.tgz "https://pkgs.tailscale.com/stable/tailscale_${TAILSCALE_VERSION}_amd64.tgz" ; then
echo "Download from Tailscale version ${TAILSCALE_VERSION} successful"
else
echo "ERROR: Download from Tailscale version ${TAILSCALE_VERSION} failed"
rm -rf &plugin;
exit 1
fi
elif [ "${TAILSCALE_VERSION}" != "${TAILSCALE_AVAIL_VERSION}" ]; then
if wget -q -nc -O &plugin;/tailscale-package/tailscale_${TAILSCALE_VERSION}_amd64.tgz "https://pkgs.tailscale.com/stable/tailscale_${TAILSCALE_VERSION}_amd64.tgz" ; then
echo "Download from Tailscale version ${TAILSCALE_VERSION} successful"
NEWPACKAGE="true"
else
echo "ERROR: Download from Tailscale version ${TAILSCALE_VERSION} failed"
echo " Falling back to local available Tailscale version: ${TAILSCALE_AVAIL_VERSION}"
rm -rf &plugin;/tailscale-package/tailscale_${TAILSCALE_VERSION}_amd64.tgz
TAILSCALE_VERSION="${TAILSCALE_AVAIL_VERSION}"
fi
else
echo "Tailscale version: ${TAILSCALE_AVAIL_VERSION} up-to-date"
fi
#Remove old Tailscale Packages
rm -f $(ls &plugin;/tailscale-package/tailscale_*.tgz 2&gt;/dev/null | grep -v "${TAILSCALE_VERSION}")
#Install/Update Tailsale
if [ ! -f /usr/local/sbin/tailscaled ]; then
echo "Installing Tailscale"
tar -C /usr/local/sbin --strip-components=1 -xf &plugin;/tailscale-package/tailscale_${TAILSCALE_VERSION}_amd64.tgz tailscale_${TAILSCALE_VERSION}_amd64/tailscaled tailscale_${TAILSCALE_VERSION}_amd64/tailscale
else
if [ "${NEWPACKAGE}" == "true" ] ; then
echo "Found new Tailscale version: ${TAILSCALE_VERSION}, installing..."
if [ ! -z "$(pgrep --ns $$ tailscaled)" ]; then
echo "Stopping Tailscale"
tailscale down 2&gt;/dev/null
kill -SIGTERM $(pgrep --ns $$ tailscaled) 2&gt;/dev/null
fi
tar -C /usr/local/sbin --strip-components=1 -xf &plugin;/tailscale-package/tailscale_${TAILSCALE_VERSION}_amd64.tgz tailscale_${TAILSCALE_VERSION}_amd64/tailscaled tailscale_${TAILSCALE_VERSION}_amd64/tailscale
fi
fi
#Start Tailscale if enabled
if [ "$(echo "${SETTINGS}" | grep "TAILSCALE_ENABLED=" | cut -d '=' -f2-)" == "true" ] &amp;&amp; [ -z "$(pgrep --ns $$ tailscaled)" ]; then
TSD_PARAMS="$(echo "${SETTINGS}" | grep "TAILSCALED_params=" | cut -d '=' -f2-)"
if [ ! -z "${TSD_PARAMS}" ]; then
TSD_PARAMS=" ${TSD_PARAMS}"
fi
echo "Starting Tailscale"
echo "/usr/local/sbin/tailscaled -statedir=&plugin;/state${TSD_PARAMS} &gt;/dev/null 2&gt;&amp;1" | at now -M &gt;/dev/null 2&gt;&amp;1
elif [ "$(echo "${SETTINGS}" | grep "TAILSCALE_ENABLED=" | cut -d '=' -f2-)" == "true" ] &amp;&amp; [ ! -z "$(pgrep --ns $$ tailscaled)" ]; then
echo "Tailscale already started"
else
echo "WARNING: Tailscale disabled"
fi
#Install icons
if [ ! -d /usr/local/emhttp/plugins/&name;/images ]; then
mkdir -p /usr/local/emhttp/plugins/&name;/images
fi
if [ ! -f &plugin;/&name;.png ]; then
wget -q -O &plugin;/&name;.png "https://raw.githubusercontent.com/ich777/docker-templates/master/ich777/images/tailscale.png"
fi
if [ ! -f /usr/local/emhttp/plugins/&name;/images/&name;.png ]; then
cp &plugin;/&name;.png /usr/local/emhttp/plugins/&name;/images/&name;.png
fi
if [ ! -f &plugin;/&name;-offline.png ]; then
wget -q -O &plugin;/&name;-offline.png "https://raw.githubusercontent.com/ich777/unraid-tailscale-cli/master/offline.png"
fi
if [ ! -f /usr/local/emhttp/plugins/&name;/images/offline.png ]; then
cp &plugin;/&name;-offline.png /usr/local/emhttp/plugins/&name;/images/offline.png
fi
#Install update script
if [ ! -d /usr/local/emhttp/plugins/&name;/scripts ]; then
mkdir -p /usr/local/emhttp/plugins/&name;/scripts
fi
if [ ! -f &plugin;/tailscale-check.sh ]; then
wget -q -O &plugin;/tailscale-check.sh "https://raw.githubusercontent.com/ich777/unraid-tailscale-cli/master/tailscale-check.sh"
fi
if [ ! -f /usr/local/emhttp/plugins/&name;/scripts/tailscale-check.sh ]; then
cp &plugin;/tailscale-check.sh /usr/local/emhttp/plugins/&name;/scripts/tailscale-check.sh
chmod +x /usr/local/emhttp/plugins/&name;/scripts/tailscale-check.sh
fi
#Install header page
if [ ! -f &plugin;/tailscale-cli-header.page ]; then
wget -q -O &plugin;/tailscale-cli-header.page "https://raw.githubusercontent.com/ich777/unraid-tailscale-cli/refs/heads/master/tailscale-cli-header.page"
fi
if [ ! -f /usr/local/emhttp/plugins/&name;/tailscale-cli-header.page ]; then
cp &plugin;/tailscale-cli-header.page /usr/local/emhttp/plugins/&name;/tailscale-cli-header.page
fi
#Create cron job
if [ "$(echo "${SETTINGS}" | grep "TAILSCALE_UPDATE_CHECK=" | cut -d '=' -f2-)" == "true" ]; then
if [ ! -f &plugin;/tailscale.cron ]; then
echo -e "# Tailscale CLI Plugin cron job:\n30 5 * * * /usr/local/emhttp/plugins/&name;/scripts/tailscale-check.sh &gt;/dev/null 2&gt;&amp;1\n\n" > &plugin;/tailscale.cron
fi
else
if [ -f &plugin;/tailscale.cron ]; then
rm -f &plugin;/tailscale.cron
fi
fi
if [ "$(echo "${SETTINGS}" | grep "TAILSCALE_UPDATE_CHECK=" | cut -d '=' -f2-)" == "true" ] &amp;&amp; [ ! "$(cat /etc/cron.d/root 2&gt;>/dev/null | grep -q "# Tailscale CLI Plugin cron job:")" ]; then
#Workaround for update cron
if [ ! -f /boot/config/plugins/&name;.plg ]; then
touch /var/log/plugins/&name;.plg
/usr/local/sbin/update_cron
rm -f /var/log/plugins/&name;.plg
else
/usr/local/sbin/update_cron
fi
fi
echo "Tailscale CLI plugin installation done"
echo
</INLINE>
</FILE>
<FILE Run="/bin/bash" Method="remove">
<INLINE>
echo
echo "---------------------------------------"
echo "---Uninstalling Tailscale CLI plugin---"
echo "---------------------------------------"
#Stop Tailscale
if [ ! -z "$(pgrep --ns $$ tailscaled)" ]; then
echo "Stopping Tailscale"
tailscale down 2&gt;/dev/null
kill -SIGTERM $(pgrep --ns $$ tailscaled) 2&gt;/dev/null
fi
#Create backup from state directory in /boot/config/.tailscale_cli_state
echo "Creating backup from Tailscale state directory in: /boot/config/.tailscale_cli_state"
mv &plugin;/state /boot/config/.tailscale_cli_state
#Remove plugin related files
rm -rf /usr/local/emhttp/plugins/&name; &plugin; /usr/local/sbin/tailscaled /usr/local/sbin/tailscale
#No need to run update_cron since the remove method already does that
echo "----------------------------------------------"
echo "------Tailscale CLI plugin uninstalled!-------"
echo "----------------------------------------------"
echo
</INLINE>
</FILE>
</PLUGIN>