Skip to content
Snippets Groups Projects
freedombone-app-babybuddy 14.8 KiB
Newer Older
Bob Mottram's avatar
Bob Mottram committed
#!/bin/bash
#
#  _____               _           _
# |   __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
# |   __|  _| -_| -_| . | . |     | . | . |   | -_|
# |__|  |_| |___|___|___|___|_|_|_|___|___|_|_|___|
#
#                              Freedom in the Cloud
#
# License
# =======
#
# Copyright (C) 2018 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'

Bob Mottram's avatar
Bob Mottram committed
APP_CATEGORY=other

Bob Mottram's avatar
Bob Mottram committed
IN_DEFAULT_INSTALL=0
SHOW_ON_ABOUT=1
NOT_ON_ARM=1
Bob Mottram's avatar
Bob Mottram committed

BABYBUDDY_DOMAIN_NAME=
BABYBUDDY_CODE=
BABYBUDDY_ONION_PORT=9495
BABYBUDDY_REPO="https://github.com/cdubz/babybuddy"
BABYBUDDY_COMMIT='27c914228d9ec5ecc1dd39e6874c99364d1a63d9'

# These parameters are used by the FreedomBox mobile app
Bob Mottram's avatar
Bob Mottram committed
BABYBUDDY_SHORT_DESCRIPTION=$"Helps caregivers track sleep, feedings, diaper changes, and tummy time"
BABYBUDDY_DESCRIPTION=$"Helps caregivers track sleep, feedings, diaper changes, and tummy time to learn about and predict baby's needs without as much guess work."
Bob Mottram's avatar
Bob Mottram committed
BABYBUDDY_MOBILE_APP_URL=

babybuddy_variables=(ONION_ONLY
Bob Mottram's avatar
Bob Mottram committed
                     BABYBUDDY_DOMAIN_NAME
                     BABYBUDDY_CODE
                     DDNS_PROVIDER
                     MY_USERNAME)
Bob Mottram's avatar
Bob Mottram committed

function logging_on_babybuddy {
    echo -n ''
}

function logging_off_babybuddy {
    echo -n ''
}

function remove_user_babybuddy {
    remove_username="$1"

    "${PROJECT_NAME}-pass" -u "$remove_username" --rmapp babybuddy
}

function add_user_babybuddy {
    new_username="$1"
    new_user_password="$2"

    "${PROJECT_NAME}-pass" -u "$new_username" -a babybuddy -p "$new_user_password"
    echo '0'
}

function install_interactive_babybuddy {
    if [ ! "$ONION_ONLY" ]; then
        ONION_ONLY='no'
    fi

    if [[ "$ONION_ONLY" != "no" ]]; then
        BABYBUDDY_DOMAIN_NAME='babybuddy.local'
        write_config_param "BABYBUDDY_DOMAIN_NAME" "$BABYBUDDY_DOMAIN_NAME"
    else
        interactive_site_details "babybuddy" "BABYBUDDY_DOMAIN_NAME" "BABYBUDDY_CODE"
    fi
    APP_INSTALLED=1
}

function change_password_babybuddy {
    curr_username="$1"
    new_user_password="$2"

    read_config_param 'BABYBUDDY_DOMAIN_NAME'

    "${PROJECT_NAME}-pass" -u "$curr_username" -a babybuddy -p "$new_user_password"
}

function reconfigure_babybuddy {
    # This is used if you need to switch identity. Dump old keys and generate new ones
    echo -n ''
}

function configure_interactive_babybuddy {
    W=(1 $"Option 1"
       2 $"Option 2")

    while true
    do
        # shellcheck disable=SC2068
        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"babybuddy" --menu $"Choose an operation, or ESC for main menu:" 14 70 3 "${W[@]}" 3>&2 2>&1 1>&3)

        if [ ! "$selection" ]; then
Bob Mottram's avatar
Bob Mottram committed
            break
Bob Mottram's avatar
Bob Mottram committed
        fi
        case $selection in
            1) # call some function for option 1
Bob Mottram's avatar
Bob Mottram committed
            ;;
Bob Mottram's avatar
Bob Mottram committed
            2) # call some function for option 2
Bob Mottram's avatar
Bob Mottram committed
            ;;
Bob Mottram's avatar
Bob Mottram committed
        esac
    done
}

function upgrade_babybuddy {
    CURR_BABYBUDDY_COMMIT=$(get_completion_param "babybuddy commit")
    if [[ "$CURR_BABYBUDDY_COMMIT" == "$BABYBUDDY_COMMIT" ]]; then
        return
    fi

    if grep -q "babybuddy domain" "$COMPLETION_FILE"; then
        BABYBUDDY_DOMAIN_NAME=$(get_completion_param "babybuddy domain")
    fi

    # update to the next commit
    set_repo_commit "/var/www/$BABYBUDDY_DOMAIN_NAME/htdocs" "babybuddy commit" "$BABYBUDDY_COMMIT" "$BABYBUDDY_REPO"
    chown -R www-data:www-data "/var/www/${BABYBUDDY_DOMAIN_NAME}/htdocs"
}

function backup_local_babybuddy {
    BABYBUDDY_DOMAIN_NAME='babybuddy'
    if grep -q "babybuddy domain" "$COMPLETION_FILE"; then
        BABYBUDDY_DOMAIN_NAME=$(get_completion_param "babybuddy domain")
    fi

    source_directory=/var/www/${BABYBUDDY_DOMAIN_NAME}/data
    cp "/var/www/${BABYBUDDY_DOMAIN_NAME}/htdocs/babybuddy/settings/production.py" "$source_directory/production.py"

    suspend_site "${BABYBUDDY_DOMAIN_NAME}"

    dest_directory=babybuddy
    backup_directory_to_usb "$source_directory" $dest_directory

    rm "$source_directory/production.py"

    restart_site
}

function restore_local_babybuddy {
    if ! grep -q "babybuddy domain" "$COMPLETION_FILE"; then
        return
    fi
    BABYBUDDY_DOMAIN_NAME=$(get_completion_param "babybuddy domain")
    if [ ! "$BABYBUDDY_DOMAIN_NAME" ]; then
        return
    fi
    suspend_site "${BABYBUDDY_DOMAIN_NAME}"
    temp_restore_dir=/root/tempbabybuddy
    babybuddy_dir=/var/www/${BABYBUDDY_DOMAIN_NAME}/data

    restore_directory_from_usb $temp_restore_dir babybuddy
    if [ -d $temp_restore_dir ]; then
        if [ -d "$temp_restore_dir$babybuddy_dir" ]; then
            cp -rp "$temp_restore_dir$babybuddy_dir"/* "$babybuddy_dir"/
        else
            if [ ! -d "$babybuddy_dir" ]; then
                mkdir "$babybuddy_dir"
            fi
            cp -rp "$temp_restore_dir"/* "$babybuddy_dir"/
        fi
        babybuddy_secret_key=$(grep "SECRET_KEY" "$babybuddy_dir/production.py" | awk -F "'" '{print $2}')
        sed -i "s|SECRET_KEY.*|SECRET_KEY = '$babybuddy_secret_key'|g" "/var/www/${BABYBUDDY_DOMAIN_NAME}/htdocs/babybuddy/settings/production.py"
        rm "$babybuddy_dir/production.py"
        chown -R www-data:www-data "$babybuddy_dir"
        rm -rf $temp_restore_dir
    fi
    restart_site
}

function backup_remote_babybuddy {
    echo -n ''
Bob Mottram's avatar
Bob Mottram committed
}

function restore_remote_babybuddy {
    echo -n ''
Bob Mottram's avatar
Bob Mottram committed
}

function remove_babybuddy {
    nginx_dissite "$BABYBUDDY_DOMAIN_NAME"
    remove_certs "$BABYBUDDY_DOMAIN_NAME"

    remove_nodejs babybuddy

    if [ -d "/var/www/$BABYBUDDY_DOMAIN_NAME" ]; then
        rm -rf "/var/www/$BABYBUDDY_DOMAIN_NAME"
    fi
    if [ -f "/etc/nginx/sites-available/$BABYBUDDY_DOMAIN_NAME" ]; then
        rm "/etc/nginx/sites-available/$BABYBUDDY_DOMAIN_NAME"
    fi
Bob Mottram's avatar
Bob Mottram committed
    if [ -f /etc/uwsgi/apps-available/babybuddy.ini ]; then
        rm /etc/uwsgi/apps-available/babybuddy.ini
        systemctl restart uwsgi
    fi
Bob Mottram's avatar
Bob Mottram committed
    remove_onion_service babybuddy "${BABYBUDDY_ONION_PORT}"
    if grep -q "babybuddy" /etc/crontab; then
        sed -i "/babybuddy/d" /etc/crontab
    fi
    remove_app babybuddy
    remove_completion_param install_babybuddy
    sed -i '/babybuddy/d' "$COMPLETION_FILE"

    remove_ddns_domain "$BABYBUDDY_DOMAIN_NAME"
}

function install_babybuddy {
    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    $INSTALL_PACKAGES python3 python3-pip uwsgi uwsgi-plugin-python3 libopenjp2-7-dev

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    $INSTALL_PACKAGES python3-virtualenv python-virtualenv

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    $INSTALL_PACKAGES postgresql

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    $INSTALL_PACKAGES python-psycopg2

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    $INSTALL_PACKAGES libpq-dev
Bob Mottram's avatar
Bob Mottram committed

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    if [ ! -d /etc/uwsgi/apps-available ]; then
        echo $'Directory not found /etc/uwsgi/apps-available'
        exit 364876328
    fi

    install_nodejs babybuddy
    if [ ! "$BABYBUDDY_DOMAIN_NAME" ]; then
        echo $'No domain name was given'
        exit 3568356
    fi

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    if [ -d "/var/www/$BABYBUDDY_DOMAIN_NAME/htdocs" ]; then
        rm -rf "/var/www/$BABYBUDDY_DOMAIN_NAME/htdocs"
    fi
    mkdir -p "/var/www/$BABYBUDDY_DOMAIN_NAME/htdocs"
    if [ ! -d "/var/www/$BABYBUDDY_DOMAIN_NAME/data/media" ]; then
        mkdir -p "/var/www/$BABYBUDDY_DOMAIN_NAME/data/media"
    fi
Bob Mottram's avatar
Bob Mottram committed
    if [ -d /repos/babybuddy ]; then
        cp -r -p /repos/babybuddy/. "/var/www/$BABYBUDDY_DOMAIN_NAME/htdocs"
        cd "/var/www/$BABYBUDDY_DOMAIN_NAME/htdocs" || exit 324687356
        git pull
    else
        git_clone "$BABYBUDDY_REPO" "/var/www/$BABYBUDDY_DOMAIN_NAME/htdocs"
    fi

    if [ ! -d "/var/www/$BABYBUDDY_DOMAIN_NAME/htdocs" ]; then
        echo $'Unable to clone babybuddy repo'
        exit 87525
    fi

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    cd "/var/www/$BABYBUDDY_DOMAIN_NAME/htdocs" || exit 36587356
    git checkout "$BABYBUDDY_COMMIT" -b "$BABYBUDDY_COMMIT"
    set_completion_param "babybuddy commit" "$BABYBUDDY_COMMIT"

Bob Mottram's avatar
Bob Mottram committed
    if [ -d "$INSTALL_DIR/babybuddy" ]; then
        rm -rf "$INSTALL_DIR/babybuddy"
    fi
    mkdir -p "$INSTALL_DIR/babybuddy"
    export TEMP="$INSTALL_DIR/babybuddy"

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    export PYTHONPATH=/usr/lib/python3.5/dist-packages:/usr/local/lib/python3.5/dist-packages
Bob Mottram's avatar
Bob Mottram committed
    pip3 install \
         pipenv django djangorestframework django-filter \
         django-widget-tweaks plotly pandas faker \
         dj-database-url gunicorn whitenoise \
         easy-thumbnails python-dotenv \
         django-storages boto3 coveralls flake8 ipaddress

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    pip3 install psycopg2
    increment_app_install_progress

    export TEMP=/tmp
    rm -rf "$INSTALL_DIR/babybuddy"
Bob Mottram's avatar
Bob Mottram committed

    if ! npm install -g gulp-cli; then
        exit 3468365
    fi

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    pipenv install --three --dev --skip-lock
    if ! npm install; then
        echo $'Failed to run npm install'
        exit 56376832
    fi

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    if ! gulp build; then
        echo $'Failed to run gulp build'
        exit 36587356
    fi

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    if [ ! -f babybuddy/settings/production.example.py ]; then
        echo $'File not found babybuddy/settings/production.example.py'
        exit 36587365835
    fi
    cp babybuddy/settings/production.example.py babybuddy/settings/production.py

    BABYBUDDY_ONION_HOSTNAME=$(add_onion_service babybuddy 80 "${BABYBUDDY_ONION_PORT}")

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    babybuddy_secret_key="$(create_password "${MINIMUM_PASSWORD_LENGTH}")$(create_password "${MINIMUM_PASSWORD_LENGTH}")$(create_password "${MINIMUM_PASSWORD_LENGTH}")"
    sed -i "s|SECRET_KEY.*|SECRET_KEY = '$babybuddy_secret_key'|g" babybuddy/settings/production.py
    sed -i "s|ALLOWED_HOSTS.*|ALLOWED_HOSTS = ['$BABYBUDDY_DOMAIN_NAME', '$BABYBUDDY_ONION_HOSTNAME']|g" babybuddy/settings/production.py

    export DJANGO_SETTINGS_MODULE=babybuddy.settings.production
Bob Mottram's avatar
Bob Mottram committed
    if ! gulp collectstatic; then
        echo $'gulp collectstatic failed'
Bob Mottram's avatar
Bob Mottram committed
        exit 368262
Bob Mottram's avatar
Bob Mottram committed
    fi

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    gulp migrate

    if [ ! -f "/var/www/$BABYBUDDY_DOMAIN_NAME/data/db.sqlite3" ]; then
        echo $'db.sqlite3 not found'
        exit 24528746
    fi

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    chown -R www-data:www-data "/var/www/$BABYBUDDY_DOMAIN_NAME/data"
    chmod 640 "/var/www/$BABYBUDDY_DOMAIN_NAME/data/db.sqlite3"
    chmod 750 "/var/www/$BABYBUDDY_DOMAIN_NAME/data"

Bob Mottram's avatar
Bob Mottram committed
    pipenv_value=$(pipenv --venv)
    if [ ! "$pipenv_value" ]; then
        echo $'No pipenv found'
        exit 3568353
    fi

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    mv "$pipenv_value" "/var/www/$BABYBUDDY_DOMAIN_NAME/base"
    chown -R www-data:www-data "/var/www/$BABYBUDDY_DOMAIN_NAME/base"

Bob Mottram's avatar
Bob Mottram committed
    { echo '[uwsgi]';
      echo 'plugins = python3';
      echo 'project = babybuddy';
      echo "base_dir = /var/www/$BABYBUDDY_DOMAIN_NAME";
      echo '';
Bob Mottram's avatar
Bob Mottram committed
      echo 'virtualenv = %(base_dir)/base';
Bob Mottram's avatar
Bob Mottram committed
      echo 'chdir = %(base_dir)/htdocs';
      echo 'module =  %(project).wsgi:application';
      echo 'env = DJANGO_SETTINGS_MODULE=%(project).settings.production';
Bob Mottram's avatar
Bob Mottram committed
      echo 'env = PYTHONPATH=/usr/lib/python3.5/dist-packages:/usr/local/lib/python3.5/dist-packages';
Bob Mottram's avatar
Bob Mottram committed
      echo 'master = True';
      echo 'vacuum = True'; } > /etc/uwsgi/apps-available/babybuddy.ini

    ln -s /etc/uwsgi/apps-available/babybuddy.ini /etc/uwsgi/apps-enabled/babybuddy.ini
    systemctl restart uwsgi

    add_ddns_domain "$BABYBUDDY_DOMAIN_NAME"

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    babybuddy_nginx_site=/etc/nginx/sites-available/$BABYBUDDY_DOMAIN_NAME
    if [[ "$ONION_ONLY" == "no" ]]; then
        nginx_http_redirect "$BABYBUDDY_DOMAIN_NAME" "index index.html"
Bob Mottram's avatar
Bob Mottram committed
        { echo 'upstream babybuddy {';
Bob Mottram's avatar
Bob Mottram committed
          echo '    server unix:///run/uwsgi/app/babybuddy/socket;';
Bob Mottram's avatar
Bob Mottram committed
          echo '}';
          echo '';
          echo 'server {';
Bob Mottram's avatar
Bob Mottram committed
          echo '  listen 443 ssl;';
          echo '  #listen [::]:443 ssl;';
          echo "  server_name $BABYBUDDY_DOMAIN_NAME;";
          echo ''; } >> "$babybuddy_nginx_site"
        nginx_compress "$BABYBUDDY_DOMAIN_NAME"
        echo '' >> "$babybuddy_nginx_site"
        echo '  # Security' >> "$babybuddy_nginx_site"
        nginx_ssl "$BABYBUDDY_DOMAIN_NAME"

        nginx_security_options "$BABYBUDDY_DOMAIN_NAME"

        { echo '  add_header Strict-Transport-Security max-age=15768000;';
          echo '';
          echo '    access_log /dev/null;';
          echo '    error_log /dev/null;';
          echo '';
          echo "    root /var/www/$BABYBUDDY_DOMAIN_NAME/htdocs;";
          echo '';
Bob Mottram's avatar
Bob Mottram committed
          echo '  index index.html;';
Bob Mottram's avatar
Bob Mottram committed
          echo '  # Location';
          echo '  location / {'; } >> "$babybuddy_nginx_site"
        nginx_limits "$BABYBUDDY_DOMAIN_NAME" '15m'
        { echo '      uwsgi_pass babybuddy;';
          echo '      include uwsgi_params;';
          echo '  }';
          echo '}'; } >> "$babybuddy_nginx_site"
    else
Bob Mottram's avatar
Bob Mottram committed
        { echo 'upstream babybuddy {';
Bob Mottram's avatar
Bob Mottram committed
          echo '    server unix:///run/uwsgi/app/babybuddy/socket;';
Bob Mottram's avatar
Bob Mottram committed
          echo '}';
          echo ''; } > "$babybuddy_nginx_site"
Bob Mottram's avatar
Bob Mottram committed
    fi
    { echo 'server {';
      echo "    listen 127.0.0.1:$BABYBUDDY_ONION_PORT default_server;";
      echo '    port_in_redirect off;';
Bob Mottram's avatar
Bob Mottram committed
      echo "    server_name $BABYBUDDY_ONION_HOSTNAME;";
      echo ''; } >> "$babybuddy_nginx_site"
    nginx_compress "$BABYBUDDY_DOMAIN_NAME"
    echo '' >> "$babybuddy_nginx_site"
    nginx_security_options "$BABYBUDDY_DOMAIN_NAME"
    { echo '';
      echo '    access_log /dev/null;';
      echo '    error_log /dev/null;';
      echo '';
      echo "    root /var/www/$BABYBUDDY_DOMAIN_NAME/htdocs;";
      echo '';
Bob Mottram's avatar
Bob Mottram committed
      echo '  index index.html;';
Bob Mottram's avatar
Bob Mottram committed
      echo '  # Location';
      echo '  location / {'; } >> "$babybuddy_nginx_site"
    nginx_limits "$BABYBUDDY_DOMAIN_NAME" '15m'
    { echo '      uwsgi_pass babybuddy;';
      echo '      include uwsgi_params;';
      echo '  }';
      echo '}'; } >> "$babybuddy_nginx_site"

    create_site_certificate "$BABYBUDDY_DOMAIN_NAME" 'yes'

    nginx_ensite "$BABYBUDDY_DOMAIN_NAME"

    systemctl restart nginx

    increment_app_install_progress

Bob Mottram's avatar
Bob Mottram committed
    "${PROJECT_NAME}-pass" -u "$MY_USERNAME" -a babybuddy -p "$BABYBUDDY_ADMIN_PASSWORD"
    set_completion_param "babybuddy domain" "$BABYBUDDY_DOMAIN_NAME"

    APP_INSTALLED=1
}

# NOTE: deliberately there is no "exit 0"