Skip to content
Snippets Groups Projects
freedombone-app-syncthing 16.2 KiB
Newer Older
Bob Mottram's avatar
Bob Mottram committed
#!/bin/bash
Bob Mottram's avatar
Bob Mottram committed
#  _____               _           _
# |   __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
# |   __|  _| -_| -_| . | . |     | . | . |   | -_|
# |__|  |_| |___|___|___|___|_|_|_|___|___|_|_|___|
Bob Mottram's avatar
Bob Mottram committed
#
Bob Mottram's avatar
Bob Mottram committed
#                              Freedom in the Cloud
Bob Mottram's avatar
Bob Mottram committed
#
# Syncthing application
#
# License
# =======
#
# Copyright (C) 2014-2018 Bob Mottram <bob@freedombone.net>
Bob Mottram's avatar
Bob Mottram committed
#
# 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'
Bob Mottram's avatar
Bob Mottram committed
APP_CATEGORY=sync

NOT_ON_HOMEPAGE=1
Bob Mottram's avatar
Bob Mottram committed
SYNCTHING_ID=
SYNCTHING_CONFIG_PATH=/root/.config/syncthing
SYNCTHING_CONFIG_FILE=$SYNCTHING_CONFIG_PATH/config.xml
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'

Bob Mottram's avatar
Bob Mottram committed
SYNCTHING_SHORT_DESCRIPTION=$'File synchronization'
SYNCTHING_DESCRIPTION=$'File synchronization'
SYNCTHING_MOBILE_APP_URL='https://f-droid.org/packages/com.nutomic.syncthingandroid'

Bob Mottram's avatar
Bob Mottram committed
syncthing_variables=(SYNCTHING_ID
                     SYNCTHING_CONFIG_PATH
                     SYNCTHING_CONFIG_FILE
                     SYNCTHING_RELAY_SERVER
                     SYNCTHING_RELEASES
                     SYNCTHING_PORT
                     SYNCTHING_SHARED_DATA
                     USB_MOUNT)

Bob Mottram's avatar
Bob Mottram committed
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_CONFIG_FILE ]; then
Bob Mottram's avatar
Bob Mottram committed
        { 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_CONFIG_FILE
    fi
}

function syncthing_manual_edit {
    if [ ! -f ~/.syncthing-server-id ]; then
        return
    fi
    syncthing_create_ids_file
    editor $SYNCTHING_CONFIG_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" \
Bob Mottram's avatar
Bob Mottram committed
           --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
Bob Mottram's avatar
Bob Mottram committed
    clear
    echo $'Your Syncthing ID code'
    echo ''
    echo -n "$SYNCTHING_ID" | qrencode -t UTF8
Bob Mottram's avatar
Bob Mottram committed
    # 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

Bob Mottram's avatar
Bob Mottram committed
    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 \
Bob Mottram's avatar
Bob Mottram committed
           2> "$data"
    sel=$?
    case $sel in
Bob Mottram's avatar
Bob Mottram committed
        1) rm -f "$data"
           return;;
        255) rm -f "$data"
             return;;
Bob Mottram's avatar
Bob Mottram committed
    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_CONFIG_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_CONFIG_FILE
    fi
    echo "$SYNCTHING_DEVICE_ID" >> $SYNCTHING_CONFIG_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

Bob Mottram's avatar
Bob Mottram committed
    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 \
Bob Mottram's avatar
Bob Mottram committed
           2> "$data"
    sel=$?
    case $sel in
Bob Mottram's avatar
Bob Mottram committed
        1) rm -f "$data"
           return;;
        255) rm -f "$data"
             return;;
Bob Mottram's avatar
Bob Mottram committed
    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_CONFIG_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_CONFIG_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_CONFIG_FILE=~/.syncthingids
    SYNCTHING_ID=$(cat ~/.syncthing-server-id)

Bob Mottram's avatar
Bob Mottram committed
    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")

Bob Mottram's avatar
Bob Mottram committed
        # 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 ''
function reconfigure_syncthing {
function upgrade_syncthing {
Bob Mottram's avatar
Bob Mottram committed
function backup_local_syncthing {
Bob Mottram's avatar
Bob Mottram committed
    if [ -d $SYNCTHING_SHARED_DATA ]; then
        function_check backup_directory_to_usb
Bob Mottram's avatar
Bob Mottram committed
        backup_directory_to_usb $SYNCTHING_SHARED_DATA syncthingshared
Bob Mottram's avatar
Bob Mottram committed
        backup_directory_to_usb $SYNCTHING_CONFIG_PATH syncthingconfig

    for d in /home/*/ ; do
        USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
        if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
Bob Mottram's avatar
Bob Mottram committed
            if [ -d "/home/$USERNAME/Sync" ]; then
                echo $"Backing up syncthing files for $USERNAME"
Bob Mottram's avatar
Bob Mottram committed
                backup_directory_to_usb "/home/$USERNAME/Sync" "syncthing/$USERNAME"
                # ensure that device IDs will be backed up as part of user config settings
Bob Mottram's avatar
Bob Mottram committed
                if [ ! -d "/home/$USERNAME/.config/syncthing" ]; then
                    mkdir -p "/home/$USERNAME/.config/syncthing"
                    chown -R "$USERNAME":"$USERNAME" "/home/$USERNAME/.config"
Bob Mottram's avatar
Bob Mottram committed
                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"
Bob Mottram's avatar
Bob Mottram committed
                if [ -f "/home/$USERNAME/.syncthingids" ]; then
                    cp "/home/$USERNAME/.syncthingids" "/home/$USERNAME/.config/syncthing"
                    chown -R "$USERNAME":"$USERNAME" "/home/$USERNAME/.config"
function restore_local_syncthing {
    if [ -f /etc/systemd/system/syncthing.service ]; then
        systemctl stop syncthing
        systemctl stop cron
    fi

    temp_restore_dir=/root/tempsyncthing
Bob Mottram's avatar
Bob Mottram committed
    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/* /

Bob Mottram's avatar
Bob Mottram committed
        if [ ! -d $SYNCTHING_CONFIG_PATH ]; then
            mkdir -p $SYNCTHING_CONFIG_PATH
Bob Mottram's avatar
Bob Mottram committed
        if ! cp -r ${temp_restore_dir}config/* $SYNCTHING_CONFIG_PATH/; then
            set_user_permissions
            backup_unmount_drive
            systemctl start syncthing
            systemctl start cron
            exit 6833
        fi
        rm -rf ${temp_restore_dir}config
    fi

Bob Mottram's avatar
Bob Mottram committed
    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/* /

Bob Mottram's avatar
Bob Mottram committed
        if [ ! -d $SYNCTHING_SHARED_DATA ]; then
            mkdir -p $SYNCTHING_SHARED_DATA
Bob Mottram's avatar
Bob Mottram committed
        cp -r ${temp_restore_dir}shared/* $SYNCTHING_SHARED_DATA/
        rm -rf ${temp_restore_dir}shared
    fi

Bob Mottram's avatar
Bob Mottram committed
    if [ -d "$USB_MOUNT/backup/syncthing" ]; then
        for d in $USB_MOUNT/backup/syncthing/*/ ; do
            USERNAME=$(echo "$d" | awk -F '/' '{print $6}')
Bob Mottram's avatar
Bob Mottram committed
            if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
Bob Mottram's avatar
Bob Mottram committed
                if [ ! -d "/home/$USERNAME" ]; then
                    "${PROJECT_NAME}-adduser" "$USERNAME"
                fi
                echo $"Restoring syncthing files for $USERNAME"
Bob Mottram's avatar
Bob Mottram committed
                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/"
Bob Mottram's avatar
Bob Mottram committed
                    if [ ! -d "/home/$USERNAME/Sync" ]; then
                        mkdir "/home/$USERNAME/Sync"
Bob Mottram's avatar
Bob Mottram committed
                    if [ -d /root/Sync ]; then
Bob Mottram's avatar
Bob Mottram committed
                        cp -r /root/Sync/* "/home/$USERNAME/Sync/"
Bob Mottram's avatar
Bob Mottram committed
                        rm -rf /root/Sync
                    else
Bob Mottram's avatar
Bob Mottram committed
                        cp -r "${temp_restore_dir}/"* "/home/$USERNAME/Sync/"
Bob Mottram's avatar
Bob Mottram committed
                # shellcheck disable=SC2181
                if [ ! "$?" = "0" ]; then
                    rm -rf ${temp_restore_dir}
                    set_user_permissions
                    backup_unmount_drive
                    systemctl start syncthing
                    systemctl start cron
                    exit 68438
                fi
                rm -rf ${temp_restore_dir}

                # restore device IDs from config settings
Bob Mottram's avatar
Bob Mottram committed
                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"
Bob Mottram's avatar
Bob Mottram committed
                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
Bob Mottram's avatar
Bob Mottram committed
function backup_remote_syncthing {
    echo -n ''
function restore_remote_syncthing {
    echo -n ''
function remove_syncthing {
Bob Mottram's avatar
Bob Mottram committed
    firewall_remove ${SYNCTHING_PORT}
    systemctl stop syncthing
    systemctl disable syncthing
    rm /etc/systemd/system/syncthing.service
Bob Mottram's avatar
Bob Mottram committed
    systemctl daemon-reload
    $REMOVE_PACKAGES_PURGE syncthing
    sed -i "/${PROJECT_NAME}-syncthing/d" /etc/crontab
Bob Mottram's avatar
Bob Mottram committed
    remove_completion_param install_syncthing
    remove_completion_param configure_firewall_for_syncthing
    systemctl restart cron
    webadmin_remove_settings syncthing
function configure_firewall_for_syncthing {
Bob Mottram's avatar
Bob Mottram committed
    if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
Bob Mottram's avatar
Bob Mottram committed
    firewall_add Syncthing ${SYNCTHING_PORT}
Bob Mottram's avatar
Bob Mottram committed
    mark_completed "${FUNCNAME[0]}"
Bob Mottram's avatar
Bob Mottram committed
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
Bob Mottram's avatar
Bob Mottram committed
    $UPDATE_PACKAGES
Bob Mottram's avatar
Bob Mottram committed
}

function install_syncthing {
    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    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
Bob Mottram's avatar
Bob Mottram committed
}

# NOTE: deliberately no exit 0