diff --git a/src/freedombone-app-ghost b/src/freedombone-app-ghost new file mode 100755 index 00000000..12a2bff3 --- /dev/null +++ b/src/freedombone-app-ghost @@ -0,0 +1,435 @@ +#!/bin/bash +# +# .---. . . +# | | | +# |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-. +# | | (.-' (.-' ( | ( )| | | | )( )| | (.-' +# ' ' --' --' -' - -' ' ' -' -' -' ' - --' +# +# Freedom in the Cloud +# +# Ghost blog +# +# License +# ======= +# +# Copyright (C) 2016 Bob Mottram +# +# 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 . + +VARIANTS="full full-vim writer" + +IN_DEFAULT_INSTALL=0 +SHOW_ON_ABOUT=1 + +GHOST_DOMAIN_NAME= +GHOST_CODE= +GHOST_ONION_PORT=8104 +GHOST_VERSION='0.11.3' +GHOST_PORT=2368 + +ghost_variables=(GHOST_VERSION + GHOST_DOMAIN_NAME + GHOST_CODE + GHOST_ADMIN_PASSWORD + ONION_ONLY + DDNS_PROVIDER + MY_USERNAME) + +function remove_user_ghost { + remove_username="$1" +} + +function add_user_ghost { + if [[ $(app_is_installed ghost) == "0" ]]; then + echo '0' + return + fi + + new_username="$1" + new_user_password="$2" + + echo '0' +} + +function install_interactive_ghost { + if [ ! $ONION_ONLY ]; then + ONION_ONLY='no' + fi + + if [[ $ONION_ONLY != "no" ]]; then + GHOST_DOMAIN_NAME='ghost.local' + write_config_param "GHOST_DOMAIN_NAME" "$GHOST_DOMAIN_NAME" + else + function_check interactive_site_details + interactive_site_details "ghost" "GHOST_DOMAIN_NAME" "GHOST_CODE" + fi + APP_INSTALLED=1 +} + +function change_password_ghost { + set_completion_param "ghost domain" "$GHOST_DOMAIN_NAME" + GHOST_DOMAIN_NAME=$(get_completion_param "ghost domain") + + GHOST_USERNAME="$1" + GHOST_PASSWORD="$2" + if [ ${#GHOST_PASSWORD} -lt 8 ]; then + echo $'Ghost password is too short' + return + fi +} + +function reconfigure_ghost { + echo -n '' +} + +function upgrade_ghost { + read_config_param "GHOST_DOMAIN_NAME" + +} + +function backup_local_ghost { + GHOST_DOMAIN_NAME='ghost.local' + if grep -q "ghost domain" $COMPLETION_FILE; then + GHOST_DOMAIN_NAME=$(get_completion_param "ghost domain") + fi + + ghost_path=/var/www/${GHOST_DOMAIN_NAME}/htdocs + if [ -d $ghost_path ]; then + function_check backup_database_to_usb + backup_database_to_usb ghost + + backup_directory_to_usb $ghost_path ghost + restart_site + fi +} + +function restore_local_ghost { + GHOST_DOMAIN_NAME='ghost.local' + if grep -q "ghost domain" $COMPLETION_FILE; then + GHOST_DOMAIN_NAME=$(get_completion_param "ghost domain") + fi + if [ $GHOST_DOMAIN_NAME ]; then + function_check ghost_create_database + ghost_create_database + + function_check restore_database + restore_database ghost ${GHOST_DOMAIN_NAME} + fi +} + +function backup_remote_ghost { + GHOST_DOMAIN_NAME='ghost.local' + if grep -q "ghost domain" $COMPLETION_FILE; then + GHOST_DOMAIN_NAME=$(get_completion_param "ghost domain") + fi + + temp_backup_dir=/var/www/${GHOST_DOMAIN_NAME}/htdocs + if [ -d $temp_backup_dir ]; then + suspend_site ${GHOST_DOMAIN_NAME} + backup_database_to_friend ghost + backup_directory_to_friend $temp_backup_dir ghost + restart_site + else + echo $"Ghost domain specified but not found in /var/www/${GHOST_DOMAIN_NAME}" + exit 2578 + fi +} + +function restore_remote_ghost { + GHOST_DOMAIN_NAME='ghost.local' + if grep -q "ghost domain" $COMPLETION_FILE; then + GHOST_DOMAIN_NAME=$(get_completion_param "ghost domain") + fi + + function_check restore_database_from_friend + + function_check ghost_create_database + ghost_create_database + + restore_database_from_friend ghost ${GHOST_DOMAIN_NAME} + restart_site + chown -R ghost: /var/www/$GHOST_DOMAIN_NAME/htdocs/ +} + +function remove_ghost { + if [ ${#GHOST_DOMAIN_NAME} -eq 0 ]; then + return + fi + + systemctl stop ghost + systemctl disable ghost + rm /etc/systemd/system/ghost.service + + function_check remove_nodejs + remove_nodejs ghost + + drop_database ghost + remove_backup_database_local ghost + + read_config_param "GHOST_DOMAIN_NAME" + nginx_dissite $GHOST_DOMAIN_NAME + remove_certs ${GHOST_DOMAIN_NAME} + deluser -r ghost + if [ -f /etc/nginx/sites-available/$GHOST_DOMAIN_NAME ]; then + rm -f /etc/nginx/sites-available/$GHOST_DOMAIN_NAME + fi + if [ -d /var/www/$GHOST_DOMAIN_NAME ]; then + rm -rf /var/www/$GHOST_DOMAIN_NAME + fi + remove_config_param GHOST_DOMAIN_NAME + remove_config_param GHOST_CODE + function_check remove_onion_service + remove_onion_service ghost ${GHOST_ONION_PORT} + remove_completion_param "install_ghost" + sed -i '/Ghost/d' $COMPLETION_FILE + sed -i '/ghost/d' $COMPLETION_FILE + sed -i '/ghost/d' /home/$MY_USERNAME/README + sed -i '/Ghost/d' /home/$MY_USERNAME/README + + function_check remove_ddns_domain + remove_ddns_domain $GHOST_DOMAIN_NAME +} + +function get_ghost_admin_password { + if [ -f /home/$MY_USERNAME/README ]; then + if grep -q "Your ghost password is" /home/$MY_USERNAME/README; then + GHOST_ADMIN_PASSWORD=$(cat /home/$MY_USERNAME/README | grep "Your ghost password is" | awk -F ':' '{print $2}' | sed 's/^ *//') + fi + fi +} + +function ghost_create_config { + ghost_config=/var/www/${GHOST_DOMAIN_NAME}/htdocs/config.js + + echo "var path = require('path')," > $ghost_config + echo ' config;' >> $ghost_config + echo '' >> $ghost_config + echo 'config = {' >> $ghost_config + echo ' production: {' >> $ghost_config + if [[ $ONION_ONLY == 'no' ]]; then + echo " url: 'https://${GHOST_DOMAIN_NAME}'," >> $ghost_config + else + echo " url: 'http://${GHOST_DOMAIN_NAME}'," >> $ghost_config + fi + echo ' mail: {' >> $ghost_config + echo " transport: 'SMTP'," >> $ghost_config + echo ' options: {' >> $ghost_config + echo " service: 'Sendmail'," >> $ghost_config + echo ' }' >> $ghost_config + echo ' },' >> $ghost_config + echo ' database: {' >> $ghost_config + echo " client: 'mysql'," >> $ghost_config + echo ' connection: {' >> $ghost_config + echo " host : '127.0.0.1'," >> $ghost_config + echo " user : 'root'," >> $ghost_config + echo " password : '${MARIADB_PASSWORD}'," >> $ghost_config + echo " database : 'ghost'," >> $ghost_config + echo " charset : 'utf8'" >> $ghost_config + echo ' }' >> $ghost_config + echo ' },' >> $ghost_config + echo '' >> $ghost_config + echo ' server: {' >> $ghost_config + echo " host: '127.0.0.1'," >> $ghost_config + echo " port: '${GHOST_PORT}'" >> $ghost_config + echo ' },' >> $ghost_config + echo ' logging: false' >> $ghost_config + echo ' }' >> $ghost_config + echo '};' >> $ghost_config + echo '' >> $ghost_config + echo 'module.exports = config;' >> $ghost_config + chmod 700 $ghost_config +} + +function ghost_create_database { + function_check get_mariadb_git_admin_password + get_mariadb_git_admin_password + + if [ ! ${GIT_ADMIN_PASSWORD} ]; then + if [ -f ${IMAGE_PASSWORD_FILE} ]; then + GIT_ADMIN_PASSWORD="$(printf `cat $IMAGE_PASSWORD_FILE`)" + else + GIT_ADMIN_PASSWORD="$(create_password ${MINIMUM_PASSWORD_LENGTH})" + fi + fi + if [ ! $GIT_ADMIN_PASSWORD ]; then + return + fi + + function_check create_database + create_database ghost "$GHOST_ADMIN_PASSWORD" +} + +function install_ghost { + if [ ! $ONION_ONLY ]; then + ONION_ONLY='no' + fi + + if [ ! $GHOST_DOMAIN_NAME ]; then + echo $'The ghost domain name was not specified' + exit 5062 + fi + + # for the avatar changing command + apt-get -yq install unzip wget + + function_check install_nodejs + install_nodejs ghost + + if [ ! -d /var/www/$GHOST_DOMAIN_NAME/htdocs ]; then + mkdir -p /var/www/$GHOST_DOMAIN_NAME/htdocs + fi + cd /var/www/$GHOST_DOMAIN_NAME/htdocs + wget https://ghost.org/zip/ghost-${GHOST_VERSION}.zip + if [ ! -f ghost-${GHOST_VERSION}.zip ]; then + echo $'Unable to download ghost' + exit 63892 + fi + unzip ghost-${GHOST_VERSION}.zip + if [ ! -f /var/www/${GHOST_DOMAIN_NAME}/htdocs/index.js ]; then + echo $'ghost failed to unzip' + exit 63835 + fi + npm install --production + + function_check install_mariadb + install_mariadb + + function_check get_mariadb_password + get_mariadb_password + + function_check ghost_create_database + ghost_create_database + ghost_create_config + + adduser --system --home=/var/www/$GHOST_DOMAIN_NAME/htdocs/ --group ghost + chown -R ghost: /var/www/$GHOST_DOMAIN_NAME/htdocs/ + + echo '[Unit]' > /etc/systemd/system/ghost.service + echo 'Description=Ghost Blog' >> /etc/systemd/system/ghost.service + echo 'After=syslog.target' >> /etc/systemd/system/ghost.service + echo 'After=network.target' >> /etc/systemd/system/ghost.service + echo 'After=mysqld.service' >> /etc/systemd/system/ghost.service + echo '' >> /etc/systemd/system/ghost.service + echo '[Service]' >> /etc/systemd/system/ghost.service + echo 'Type=simple' >> /etc/systemd/system/ghost.service + echo 'User=ghost' >> /etc/systemd/system/ghost.service + echo 'Group=ghost' >> /etc/systemd/system/ghost.service + echo "WorkingDirectory=/var/www/${GHOST_DOMAIN_NAME}/htdocs" >> /etc/systemd/system/ghost.service + echo "ExecStart=/usr/bin/node /var/www/${GHOST_DOMAIN_NAME}/htdocs/index.js" >> /etc/systemd/system/ghost.service + echo 'Restart=always' >> /etc/systemd/system/ghost.service + echo 'RestartSec=60' >> /etc/systemd/system/ghost.service + echo "Environment=NODE_ENV=production PORT=${GHOST_PORT}" >> /etc/systemd/system/ghost.service + echo '' >> /etc/systemd/system/ghost.service + echo '[Install]' >> /etc/systemd/system/ghost.service + echo 'WantedBy=multi-user.target' >> /etc/systemd/system/ghost.service + + systemctl enable ghost + systemctl daemon-reload + systemctl start ghost + + if [[ ${ONION_ONLY} == "no" ]]; then + function_check nginx_http_redirect + nginx_http_redirect ${GHOST_DOMAIN_NAME} + echo 'server {' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' listen 443 ssl;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo " root /var/www/${GHOST_DOMAIN_NAME}/htdocs;" >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo " server_name ${GHOST_DOMAIN_NAME};" >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' access_log off;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo " error_log /var/log/nginx/${GHOST_DOMAIN_NAME}_error.log ${WEBSERVER_LOG_LEVEL};" >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo '' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + function_check nginx_ssl + nginx_ssl ${GHOST_DOMAIN_NAME} + function_check nginx_disable_sniffing + nginx_disable_sniffing ${GHOST_DOMAIN_NAME} + echo ' add_header Strict-Transport-Security max-age=0;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo '' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' location / {' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + function_check nginx_limits + nginx_limits ${GHOST_DOMAIN_NAME} '10G' + echo " proxy_pass http://localhost:${GHOST_PORT};" >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' }' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo '' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' fastcgi_buffers 64 4K;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo '' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' error_page 403 /core/templates/403.php;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' error_page 404 /core/templates/404.php;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo '' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' location = /robots.txt {' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' allow all;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' log_not_found off;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' access_log off;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' }' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo '}' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo '' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + else + echo -n '' > /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + fi + echo 'server {' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo " listen 127.0.0.1:${GHOST_ONION_PORT} default_server;" >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo " root /var/www/$GHOST_DOMAIN_NAME/htdocs;" >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo " server_name $GHOST_DOMAIN_NAME;" >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' access_log off;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo " error_log /var/log/nginx/${GHOST_DOMAIN_NAME}_error.log ${WEBSERVER_LOG_LEVEL};" >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo '' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + function_check nginx_disable_sniffing + nginx_disable_sniffing ${GHOST_DOMAIN_NAME} + echo ' add_header Strict-Transport-Security max-age=0;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo '' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' location / {' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + function_check nginx_limits + nginx_limits ${GHOST_DOMAIN_NAME} '10G' + echo " proxy_pass http://localhost:${GHOST_PORT};" >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' }' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo '' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' fastcgi_buffers 64 4K;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo '' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' error_page 403 /core/templates/403.php;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' error_page 404 /core/templates/404.php;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo '' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' location = /robots.txt {' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' allow all;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' log_not_found off;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' access_log off;' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo ' }' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + echo '}' >> /etc/nginx/sites-available/${GHOST_DOMAIN_NAME} + + function_check create_site_certificate + create_site_certificate $GHOST_DOMAIN_NAME 'yes' + + function_check configure_php + configure_php + + GHOST_ONION_HOSTNAME=$(add_onion_service ghost 80 ${GHOST_ONION_PORT}) + + function_check nginx_ensite + nginx_ensite $GHOST_DOMAIN_NAME + + systemctl restart nginx + + if ! grep -q "Ghost onion domain" /home/$MY_USERNAME/README; then + echo $"Ghost onion domain: ${GHOST_ONION_HOSTNAME}" >> /home/$MY_USERNAME/README + echo '' >> /home/$MY_USERNAME/README + chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/README + chmod 600 /home/$MY_USERNAME/README + fi + + function_check add_ddns_domain + add_ddns_domain $GHOST_DOMAIN_NAME + + set_completion_param "ghost domain" "$GHOST_DOMAIN_NAME" + APP_INSTALLED=1 +} + +# NOTE: deliberately no exit 0 diff --git a/src/freedombone-app-htmly b/src/freedombone-app-htmly index 9f078e99..8d421ab2 100755 --- a/src/freedombone-app-htmly +++ b/src/freedombone-app-htmly @@ -195,7 +195,7 @@ function upgrade_htmly { } function backup_local_htmly { - HTMLY_DOMAIN_NAME='htmly' + HTMLY_DOMAIN_NAME='htmly.local' if grep -q "htmly domain" $COMPLETION_FILE; then HTMLY_DOMAIN_NAME=$(get_completion_param "htmly domain") fi @@ -215,7 +215,7 @@ function backup_local_htmly { } function restore_local_htmly { - HTMLY_DOMAIN_NAME='htmly' + HTMLY_DOMAIN_NAME='htmly.local' if grep -q "htmly domain" $COMPLETION_FILE; then HTMLY_DOMAIN_NAME=$(get_completion_param "htmly domain") fi