-
Bob Mottram authored
Some apps may require others to already be installed
Bob Mottram authoredSome apps may require others to already be installed
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
freedombone-app-syncthing 19.06 KiB
#!/bin/bash
# _____ _ _
# | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
# | __| _| -_| -_| . | . | | . | . | | -_|
# |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
#
# Freedom in the Cloud
#
# Syncthing application
#
# License
# =======
#
# Copyright (C) 2014-2019 Bob Mottram <bob@freedombone.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
VARIANTS='full full-vim cloud'
APP_CATEGORY=sync
IN_DEFAULT_INSTALL=0
SHOW_ON_ABOUT=0
SHOW_DOMAIN_IN_ADD_WEBADMIN=0
NOT_ON_HOMEPAGE=1
REQUIRES_APP=
SYNCTHING_ID=
SYNCTHING_CONFIG_PATH=/root/.config/syncthing
SYNCTHING_CONFIG_FILE=$SYNCTHING_CONFIG_PATH/config.xml
SYNCTHING_IDS_FILE=~/.syncthingids
SYNCTHING_RELAY_SERVER='https://relays.syncthing.net/endpoint'
SYNCTHING_RELEASES='https://api.github.com/repos/syncthing/syncthing/releases?per_page=30'
SYNCTHING_PORT=22000
SYNCTHING_SHARED_DATA=/var/lib/syncthing/SyncShared
SYNCTHING_USER_IDS_FILE='.syncthingids'
SYNCTHING_MIN_DISK_SPACE_FREE_PERCENT=20
SYNCTHING_SHORT_DESCRIPTION=$'File synchronization'
SYNCTHING_DESCRIPTION=$'File synchronization'
SYNCTHING_MOBILE_APP_URL='https://f-droid.org/packages/com.nutomic.syncthingandroid'
syncthing_variables=(SYNCTHING_ID
SYNCTHING_RELAY_SERVER
SYNCTHING_RELEASES
SYNCTHING_PORT
SYNCTHING_SHARED_DATA
USB_MOUNT)
function syncthing_update_settings_template {
# Creates the syncthing settings screen within webadmin
# shellcheck disable=SC2154
app_settings_screen_template="$webadmin_install_dir/settings_syncthing_template.html"
app_settings_screen="$webadmin_install_dir/settings_syncthing.html"
cp "$app_settings_screen_template" "$app_settings_screen"
read_config_param MY_USERNAME
if [ ! -f "/home/$MY_USERNAME/.syncthingids" ]; then
touch "/home/$MY_USERNAME/.syncthingids"
chown "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/.syncthingids"
fi
syncthinglist=$(sed 's@[/\&]@\\&@g;s/$/\\/' "/home/$MY_USERNAME/.syncthingids"; echo .)
syncthinglist=${syncthinglist%.}
sed -i "s|SYNCTHINGIDS|$syncthinglist|g" "$app_settings_screen"
chown www-data:www-data "$app_settings_screen"
}
function logging_on_syncthing {
echo -n ''
}
function logging_off_syncthing {
echo -n ''
}
function syncthing_create_ids_file {
if [ ! -f ~/.syncthing-server-id ]; then
return
fi
SYNCTHING_ID=$(cat ~/.syncthing-server-id)
if [ ! -f $SYNCTHING_IDS_FILE ]; then
{ echo $'# Your syncthing configuration file';
echo '#';
echo $"# The ${PROJECT_NAME} syncthing ID is: $SYNCTHING_ID";
echo '#';
echo '# Paste the IDs of your devices below';
echo '#'; } > $SYNCTHING_IDS_FILE
fi
}
function syncthing_manual_edit {
if [ ! -f ~/.syncthing-server-id ]; then
return
fi
syncthing_create_ids_file
editor $SYNCTHING_IDS_FILE
# force an update of the configuration
touch ~/.syncthing-update
}
function syncthing_show_id {
if [ ! -f ~/.syncthing-server-id ]; then
return
fi
SYNCTHING_ID=$(cat ~/.syncthing-server-id)
dialog --title $"Device ID for ${PROJECT_NAME}" \
--backtitle $"Freedombone User Control Panel" \
--msgbox $"In a desktop terminal press shift and select the ID below,\\nthen right click and copy.\\n\\nWithin Connectbot select Menu/Copy and then highlight the ID below\\n\\n$SYNCTHING_ID\\n\\nAlternatively press Enter to display a QR code which can be scanned." 13 78
clear
echo $'Your Syncthing ID code'
echo ''
echo -n "$SYNCTHING_ID" | qrencode -t UTF8
echo ''
# shellcheck disable=SC2034
read -n1 -rsp $"Press any key to continue..." key
}
function syncthing_add_id {
if [ ! -f ~/.syncthing-server-id ]; then
return
fi
syncthing_create_ids_file
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone User Control Panel" \
--title $"Add a Syncthing device ID" \
--form $"Paste the device ID for your laptop/desktop/netbook/phone/tablet below" 9 80 2 \
$"Device ID:" 1 1 "" 1 26 80 80 \
$"Description (optional):" 2 1 "" 2 26 80 80 \
2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
return;;
255) rm -f "$data"
return;;
esac
SYNCTHING_DEVICE_ID=$(sed -n 1p < "$data")
SYNCTHING_DESCRIPTION=$(sed -n 2p < "$data")
rm -f "$data"
if [ ${#SYNCTHING_DEVICE_ID} -lt 10 ]; then
return
fi
if [[ $SYNCTHING_DEVICE_ID == *"#"* || $SYNCTHING_DEVICE_ID == *"*"* || $SYNCTHING_DEVICE_ID == *'/'* || $SYNCTHING_DEVICE_ID != *"-"* ]]; then
dialog --title $"Add a Syncthing device ID" \
--backtitle $"Freedombone User Control Panel" \
--msgbox $"That doesn't look like a device ID" 6 50
return
fi
if grep -q "$SYNCTHING_DEVICE_ID" $SYNCTHING_IDS_FILE; then
dialog --title $"Add a Syncthing device ID" \
--backtitle $"Freedombone User Control Panel" \
--msgbox $"That ID has already been added" 6 50
return
fi
if [ ${#SYNCTHING_DESCRIPTION} -gt 0 ]; then
echo "# $SYNCTHING_DESCRIPTION" >> $SYNCTHING_IDS_FILE
fi
echo "$SYNCTHING_DEVICE_ID" >> $SYNCTHING_IDS_FILE
# force an update of the configuration
touch ~/.syncthing-update
dialog --title $"Add a Syncthing device ID" \
--backtitle $"Freedombone User Control Panel" \
--msgbox $"The ID was added" 6 50
}
function syncthing_remove_id {
if [ ! -f ~/.syncthing-server-id ]; then
return
fi
syncthing_create_ids_file
data=$(mktemp 2>/dev/null)
dialog --backtitle $"Freedombone User Control Panel" \
--title $"Remove a Syncthing device ID" \
--form $"Paste the device ID which is to be removed below" 8 80 1 \
$"Device ID:" 1 1 "" 1 14 80 80 \
2> "$data"
sel=$?
case $sel in
1) rm -f "$data"
return;;
255) rm -f "$data"
return;;
esac
SYNCTHING_DEVICE_ID=$(sed -n 1p < "$data")
rm -f "$data"
if [ ${#SYNCTHING_DEVICE_ID} -lt 10 ]; then
return
fi
if [[ $SYNCTHING_DEVICE_ID == *"#"* || $SYNCTHING_DEVICE_ID == *"*"* || $SYNCTHING_DEVICE_ID == *'/'* || $SYNCTHING_DEVICE_ID != *"-"* ]]; then
dialog --title $"Remove a Syncthing device ID" \
--backtitle $"Freedombone User Control Panel" \
--msgbox $"That doesn't look like a device ID" 6 50
return
fi
if ! grep -q "$SYNCTHING_DEVICE_ID" $SYNCTHING_IDS_FILE; then
dialog --title $"Remove a Syncthing device ID" \
--backtitle $"Freedombone User Control Panel" \
--msgbox $"That ID wasn't registered anyway" 6 50
return
fi
sed -i "/$SYNCTHING_DEVICE_ID/d" $SYNCTHING_IDS_FILE
# force an update of the configuration
touch ~/.syncthing-update
dialog --title $"Remove a Syncthing device ID" \
--backtitle $"Freedombone User Control Panel" \
--msgbox $"The ID was removed" 6 50
}
function run_client_syncthing {
SYNCTHING_IDS_FILE=~/.syncthingids
SYNCTHING_ID=$(cat ~/.syncthing-server-id)
W=(1 $"Show device ID for ${PROJECT_NAME}"
2 $"Add an ID for another machine or device"
3 $"Remove an ID for another machine or device"
4 $"Manually edit device IDs")
while true
do
# shellcheck disable=SC2068
selection=$(dialog --backtitle $"Freedombone User Control Panel" --title $"File Synchronization" --menu $"Choose an operation, or ESC for main menu:" 12 70 6 "${W[@]}" 3>&2 2>&1 1>&3)
if [ ! "$selection" ]; then
break
fi
case $selection in
1) syncthing_show_id;;
2) syncthing_add_id;;
3) syncthing_remove_id;;
4) syncthing_manual_edit;;
esac
done
}
function install_interactive_syncthing {
echo -n ''
APP_INSTALLED=1
}
function reconfigure_syncthing {
echo -n ''
}
function upgrade_syncthing {
syncthing_users_changed=
if [ -f /root/.config/syncthing/config.xml ]; then
if grep -q 'minDiskFree unit' /root/.config/syncthing/config.xml; then
if ! grep -q "minDiskFree unit=\"%\">$SYNCTHING_MIN_DISK_SPACE_FREE_PERCENT<" /root/.config/syncthing/config.xml; then
sed -i "s|minDiskFree unit=.*|minDiskFree unit=\"%\">$SYNCTHING_MIN_DISK_SPACE_FREE_PERCENT</minDiskFree>|g" /root/.config/syncthing/config.xml
syncthing_users_changed=1
fi
fi
if grep -q '<minDiskFreePct>' /root/.config/syncthing/config.xml; then
sed -i "s|<minDiskFreePct>.*|<minDiskFreePct>$SYNCTHING_MIN_DISK_SPACE_FREE_PERCENT</minDiskFreePct>|g" /root/.config/syncthing/config.xml
syncthing_users_changed=1
fi
fi
# configurations for each user
for d in /home/*/ ; do
USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
if [ -f "/home/$USERNAME/.config/syncthing/config.xml" ]; then
if grep -q 'minDiskFree unit' "/home/$USERNAME/.config/syncthing/config.xml"; then
if ! grep -q "minDiskFree unit=\"%\">$SYNCTHING_MIN_DISK_SPACE_FREE_PERCENT<" "/home/$USERNAME/.config/syncthing/config.xml"; then
sed -i "s|minDiskFree unit=.*|minDiskFree unit=\"%\">$SYNCTHING_MIN_DISK_SPACE_FREE_PERCENT</minDiskFree>|g" "/home/$USERNAME/.config/syncthing/config.xml"
syncthing_users_changed=1
fi
fi
if grep -q '<minDiskFreePct>' "/home/$USERNAME/.config/syncthing/config.xml"; then
sed -i "s|<minDiskFreePct>.*|<minDiskFreePct>$SYNCTHING_MIN_DISK_SPACE_FREE_PERCENT</minDiskFreePct>|g" "/home/$USERNAME/.config/syncthing/config.xml"
syncthing_users_changed=1
fi
fi
done
if [ $syncthing_users_changed ]; then
systemctl restart syncthing
fi
}
function backup_local_syncthing {
if [ -d $SYNCTHING_SHARED_DATA ]; then
function_check backup_directory_to_usb
backup_directory_to_usb $SYNCTHING_SHARED_DATA syncthingshared
backup_directory_to_usb $SYNCTHING_CONFIG_PATH syncthingconfig
fi
for d in /home/*/ ; do
USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
if [ -d "/home/$USERNAME/Sync" ]; then
echo $"Backing up syncthing files for $USERNAME"
backup_directory_to_usb "/home/$USERNAME/Sync" "syncthing/$USERNAME"
# ensure that device IDs will be backed up as part of user config settings
if [ ! -d "/home/$USERNAME/.config/syncthing" ]; then
mkdir -p "/home/$USERNAME/.config/syncthing"
chown -R "$USERNAME":"$USERNAME" "/home/$USERNAME/.config"
fi
if [ -f "/home/$USERNAME/.syncthing-server-id" ]; then
cp "/home/$USERNAME/.syncthing-server-id" "/home/$USERNAME/.config/syncthing"
chown -R "$USERNAME":"$USERNAME" "/home/$USERNAME/.config"
fi
if [ -f "/home/$USERNAME/.syncthingids" ]; then
cp "/home/$USERNAME/.syncthingids" "/home/$USERNAME/.config/syncthing"
chown -R "$USERNAME":"$USERNAME" "/home/$USERNAME/.config"
fi
fi
fi
done
}
function restore_local_syncthing {
if [ -f /etc/systemd/system/syncthing.service ]; then
systemctl stop syncthing
systemctl stop cron
fi
temp_restore_dir=/root/tempsyncthing
if [ -d "$USB_MOUNT/backup/syncthingconfig" ]; then
echo $"Restoring syncthing configuration"
function_check restore_directory_from_usb
restore_directory_from_usb ${temp_restore_dir}config syncthingconfig
#cp -r ${temp_restore_dir}config/* /
if [ ! -d $SYNCTHING_CONFIG_PATH ]; then
mkdir -p $SYNCTHING_CONFIG_PATH
fi
if ! cp -r ${temp_restore_dir}config/* $SYNCTHING_CONFIG_PATH/; then
set_user_permissions
backup_unmount_drive
systemctl start syncthing
systemctl start cron
exit 68
fi
rm -rf ${temp_restore_dir}config
fi
if [ -d "$USB_MOUNT/backup/syncthingshared" ]; then
echo $"Restoring syncthing shared files"
restore_directory_from_usb ${temp_restore_dir}shared syncthingshared
#cp -r ${temp_restore_dir}shared/* /
if [ ! -d $SYNCTHING_SHARED_DATA ]; then
mkdir -p $SYNCTHING_SHARED_DATA
fi
cp -r ${temp_restore_dir}shared/* $SYNCTHING_SHARED_DATA/
rm -rf ${temp_restore_dir}shared
fi
if [ -d "$USB_MOUNT/backup/syncthing" ]; then
for d in $USB_MOUNT/backup/syncthing/*/ ; do
USERNAME=$(echo "$d" | awk -F '/' '{print $6}')
if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
if [ ! -d "/home/$USERNAME" ]; then
"${PROJECT_NAME}-adduser" "$USERNAME"
fi
echo $"Restoring syncthing files for $USERNAME"
restore_directory_from_usb "${temp_restore_dir}" "syncthing/$USERNAME"
if [ -d "${temp_restore_dir}/home/$USERNAME/Sync" ]; then
cp -r "${temp_restore_dir}/home/$USERNAME/Sync" "/home/$USERNAME/"
else
if [ ! -d "/home/$USERNAME/Sync" ]; then
mkdir "/home/$USERNAME/Sync"
fi
if [ -d /root/Sync ]; then
cp -r /root/Sync/* "/home/$USERNAME/Sync/"
rm -rf /root/Sync
else
cp -r "${temp_restore_dir}/"* "/home/$USERNAME/Sync/"
fi
fi
# shellcheck disable=SC2181
if [ ! "$?" = "0" ]; then
rm -rf ${temp_restore_dir}
set_user_permissions
backup_unmount_drive
systemctl start syncthing
systemctl start cron
exit 68
fi
rm -rf ${temp_restore_dir}
# restore device IDs from config settings
if [ -f "/home/$USERNAME/.config/syncthing/.syncthing-server-id" ]; then
cp "/home/$USERNAME/.config/syncthing/.syncthing-server-id" "/home/$USERNAME/.syncthing-server-id"
chown "$USERNAME":"$USERNAME" "/home/$USERNAME/.syncthing-server-id"
fi
if [ -f "/home/$USERNAME/.config/syncthing/.syncthingids" ]; then
cp "/home/$USERNAME/.config/syncthing/.syncthingids" "/home/$USERNAME/.syncthingids"
chown "$USERNAME":"$USERNAME" "/home/$USERNAME/.syncthingids"
fi
fi
done
fi
if [ -f /etc/systemd/system/syncthing.service ]; then
systemctl start syncthing
systemctl start cron
fi
}
function backup_remote_syncthing {
echo -n ''
}
function restore_remote_syncthing {
echo -n ''
}
function remove_syncthing {
firewall_remove ${SYNCTHING_PORT}
systemctl stop syncthing
systemctl disable syncthing
rm /etc/systemd/system/syncthing.service
systemctl daemon-reload
$REMOVE_PACKAGES_PURGE syncthing
sed -i "/${PROJECT_NAME}-syncthing/d" /etc/crontab
remove_completion_param install_syncthing
remove_completion_param configure_firewall_for_syncthing
systemctl restart cron
if [ -f $SYNCTHING_IDS_FILE ]; then
rm $SYNCTHING_IDS_FILE
fi
for d in /home/*/ ; do
USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
if [ -d "/home/$USERNAME/.config/syncthing" ]; then
rm -rf "/home/$USERNAME/.config/syncthing"
fi
if [ -f "/home/$USERNAME/.syncthingids" ]; then
rm "/home/$USERNAME/.syncthingids"
fi
if [ -f "/home/$USERNAME/.syncthingids.backup" ]; then
rm "/home/$USERNAME/.syncthingids.backup"
fi
if [ -f "/home/$USERNAME/.syncthing-server-id" ]; then
rm "/home/$USERNAME/.syncthing-server-id"
fi
if [ -f "/home/$USERNAME/.syncthing-update" ]; then
rm "/home/$USERNAME/.syncthing-update"
fi
done
webadmin_remove_settings syncthing
}
function configure_firewall_for_syncthing {
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
return
fi
firewall_add Syncthing ${SYNCTHING_PORT}
mark_completed "${FUNCNAME[0]}"
}
function install_syncthing_repo {
if [ -f /etc/apt/sources.list.d/syncthing.list ]; then
return
fi
$INSTALL_PACKAGES curl
curl -s https://syncthing.net/release-key.txt | apt-key add -
echo "deb http://apt.syncthing.net/ syncthing release" | tee /etc/apt/sources.list.d/syncthing.list
$UPDATE_PACKAGES
}
function install_syncthing {
increment_app_install_progress
install_syncthing_repo
increment_app_install_progress
$INSTALL_PACKAGES syncthing
increment_app_install_progress
# This probably does need to run as root so that it can access the Sync directories
# in each user's home directory
{ echo '[Unit]';
echo 'Description=Syncthing - Open Source Continuous File Synchronization';
echo 'Documentation=man:syncthing(1)';
echo 'After=network.target';
echo 'Wants=syncthing-inotify@.service';
echo '';
echo '[Service]';
echo 'User=root';
echo "Environment='all_proxy=socks5://localhost:9050'";
echo 'ExecStart=/usr/bin/syncthing -no-browser -no-restart -logflags=0';
echo 'Restart=on-failure';
echo 'SuccessExitStatus=3 4';
echo 'RestartForceExitStatus=3 4';
echo '';
echo '[Install]';
echo 'WantedBy=multi-user.target'; } > /etc/systemd/system/syncthing.service
systemctl enable syncthing
systemctl daemon-reload
systemctl start syncthing
increment_app_install_progress
function_check cron_add_mins
cron_add_mins 1 "/usr/local/bin/${PROJECT_NAME}-syncthing > /dev/null"
increment_app_install_progress
function_check configure_firewall_for_syncthing
configure_firewall_for_syncthing
if [ -f /root/.config/syncthing/config.xml ]; then
sed -i "s|minDiskFree unit=.*|minDiskFree unit=\"%\">$SYNCTHING_MIN_DISK_SPACE_FREE_PERCENT</minDiskFree>|g" /root/.config/syncthing/config.xml
fi
APP_INSTALLED=1
}
# NOTE: deliberately no exit 0