-
Bob Mottram authoredBob Mottram authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
freedombone-app-babybuddy 14.85 KiB
#!/bin/bash
#
# _____ _ _
# | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
# | __| _| -_| -_| . | . | | . | . | | -_|
# |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
#
# Freedom in the Cloud
#
# License
# =======
#
# Copyright (C) 2018-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'
APP_CATEGORY=other
IN_DEFAULT_INSTALL=0
SHOW_ON_ABOUT=1
NOT_ON_ARM=1
REQUIRES_APP=
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
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."
BABYBUDDY_MOBILE_APP_URL=
babybuddy_variables=(ONION_ONLY
BABYBUDDY_DOMAIN_NAME
BABYBUDDY_CODE
DDNS_PROVIDER
MY_USERNAME)
function logging_on_babybuddy {
echo -n ''
}
function logging_off_babybuddy {
echo -n ''
}
function remove_user_babybuddy {
remove_username="$1"
# TODO: remove user
"${PROJECT_NAME}-pass" -u "$remove_username" --rmapp babybuddy
}
function add_user_babybuddy {
new_username="$1"
new_user_password="$2"
# TODO: add user
"${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
break
fi
case $selection in
1) # call some function for option 1
;;
2) # call some function for option 2
;;
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 ''
}
function restore_remote_babybuddy {
echo -n ''
}
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
if [ -f /etc/uwsgi/apps-available/babybuddy.ini ]; then
rm /etc/uwsgi/apps-available/babybuddy.ini
systemctl restart uwsgi
fi
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
$INSTALL_PACKAGES python3 python3-pip uwsgi uwsgi-plugin-python3 libopenjp2-7-dev
increment_app_install_progress
$INSTALL_PACKAGES python3-virtualenv python-virtualenv
increment_app_install_progress
$INSTALL_PACKAGES postgresql
increment_app_install_progress
$INSTALL_PACKAGES python-psycopg2
increment_app_install_progress
$INSTALL_PACKAGES libpq-dev
increment_app_install_progress
if [ ! -d /etc/uwsgi/apps-available ]; then
echo $'Directory not found /etc/uwsgi/apps-available'
exit 36
fi
install_nodejs babybuddy
if [ ! "$BABYBUDDY_DOMAIN_NAME" ]; then
echo $'No domain name was given for babybuddy'
exit 35
fi
increment_app_install_progress
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
if [ -d /repos/babybuddy ]; then
cp -r -p /repos/babybuddy/. "/var/www/$BABYBUDDY_DOMAIN_NAME/htdocs"
cd "/var/www/$BABYBUDDY_DOMAIN_NAME/htdocs" || exit 32
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 87
fi
increment_app_install_progress
cd "/var/www/$BABYBUDDY_DOMAIN_NAME/htdocs" || exit 36
git checkout "$BABYBUDDY_COMMIT" -b "$BABYBUDDY_COMMIT"
set_completion_param "babybuddy commit" "$BABYBUDDY_COMMIT"
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
export PYTHONPATH=/usr/lib/python3.5/dist-packages:/usr/local/lib/python3.5/dist-packages
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
pip3 install psycopg2
increment_app_install_progress
export TEMP=/tmp
rm -rf "$INSTALL_DIR/babybuddy"
if ! npm install -g gulp-cli; then
exit 34
fi
increment_app_install_progress
pipenv install --three --dev --skip-lock
if ! npm install; then
echo $'Failed to run npm install'
exit 56
fi
increment_app_install_progress
if ! gulp build; then
echo $'Failed to run gulp build'
exit 36
fi
increment_app_install_progress
if [ ! -f babybuddy/settings/production.example.py ]; then
echo $'File not found babybuddy/settings/production.example.py'
exit 36
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
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
if ! gulp collectstatic; then
echo $'gulp collectstatic failed'
exit 36
fi
increment_app_install_progress
gulp migrate
if [ ! -f "/var/www/$BABYBUDDY_DOMAIN_NAME/data/db.sqlite3" ]; then
echo $'db.sqlite3 not found'
exit 24
fi
increment_app_install_progress
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"
pipenv_value=$(pipenv --venv)
if [ ! "$pipenv_value" ]; then
echo $'No pipenv found'
exit 35
fi
increment_app_install_progress
mv "$pipenv_value" "/var/www/$BABYBUDDY_DOMAIN_NAME/base"
chown -R www-data:www-data "/var/www/$BABYBUDDY_DOMAIN_NAME/base"
{ echo '[uwsgi]';
echo 'plugins = python3';
echo 'project = babybuddy';
echo "base_dir = /var/www/$BABYBUDDY_DOMAIN_NAME";
echo '';
echo 'virtualenv = %(base_dir)/base';
echo 'chdir = %(base_dir)/htdocs';
echo 'module = %(project).wsgi:application';
echo 'env = DJANGO_SETTINGS_MODULE=%(project).settings.production';
echo 'env = PYTHONPATH=/usr/lib/python3.5/dist-packages:/usr/local/lib/python3.5/dist-packages';
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
babybuddy_nginx_site=/etc/nginx/sites-available/$BABYBUDDY_DOMAIN_NAME
if [[ "$ONION_ONLY" == "no" ]]; then
nginx_http_redirect "$BABYBUDDY_DOMAIN_NAME" "index index.html"
{ echo 'upstream babybuddy {';
echo ' server unix:///run/uwsgi/app/babybuddy/socket;';
echo '}';
echo '';
echo 'server {';
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"
nginx_robots "$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 '';
echo ' index index.html;';
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
{ echo 'upstream babybuddy {';
echo ' server unix:///run/uwsgi/app/babybuddy/socket;';
echo '}';
echo ''; } > "$babybuddy_nginx_site"
fi
{ echo 'server {';
echo " listen 127.0.0.1:$BABYBUDDY_ONION_PORT default_server;";
echo ' port_in_redirect off;';
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 '';
echo ' index index.html;';
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
"${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"