Newer
Older
#!/bin/bash
#
# .---. . .
# | | |
# |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
# | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
# ' ' --' --' -' - -' ' ' -' -' -' ' - --'
#
# Freedom in the Cloud
#
# Database functions
#
# License
# =======
#
# Copyright (C) 2014-2016 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/>.
# default MariaDB password
MARIADB_PASSWORD=
# Used to indicate whether the backup contains MariaDB databases or not
BACKUP_INCLUDES_DATABASES="no"
function remove_backup_database_local {
database_name=$1
sed -i "/# Backup the ${database_name} database/,/# End of ${database_name} database backup/d" /usr/bin/backupdatabases
sed -i "/# Backup ${database_name}/,/# End of backup for ${database_name}/d" /etc/cron.weekly/backupdatabasesweekly
sed -i "/# Backup ${database_name}/,/# End of backup for ${database_name}/d" /etc/cron.monthly/backupdatabasesmonthly
sed -i "/${database_name}/d" /etc/cron.hourly/repair
}
function backup_database_local {
# Makes local backups of databases which can then be automatically rolled
# back if corruption is detected
database_name=$1
backup_databases_script=/usr/bin/backupdatabases
if ! grep -q "# Backup the ${database_name} database" $backup_databases_script; then
echo "# Backup the ${database_name} database" >> $backup_databases_script
echo "TEMPFILE=/root/${database_name}.sql" >> $backup_databases_script
echo 'DAILYFILE=/var/backups/${database_name}_daily.sql' >> $backup_databases_script
echo "mysqldump --password=\"\$MYSQL_PASSWORD\" ${database_name} > \$TEMPFILE" >> $backup_databases_script
echo 'FILESIZE=$(stat -c%s $TEMPFILE)' >> $backup_databases_script
echo 'if [ "$FILESIZE" -eq "0" ]; then' >> $backup_databases_script
echo ' if [ -f $DAILYFILE ]; then' >> $backup_databases_script
echo ' cp $DAILYFILE $TEMPFILE' >> $backup_databases_script
echo '' >> $backup_databases_script
echo ' # try to restore yesterdays database' >> $backup_databases_script
echo " mysql -u root --password=\"\$MYSQL_PASSWORD\" ${database_name} -o < \$DAILYFILE" >> $backup_databases_script
echo '' >> $backup_databases_script
echo ' # Send a warning email' >> $backup_databases_script
echo " echo \"Unable to create a backup of the ${database_name} database. Attempted to restore from yesterdays backup\" | mail -s \"${database_name} backup\" \$EMAIL" >> $backup_databases_script
echo ' else' >> $backup_databases_script
echo ' # Send a warning email' >> $backup_databases_script
echo " echo \"Unable to create a backup of the ${database_name} database.\" | mail -s \"${database_name} backup\" \$EMAIL" >> $backup_databases_script
echo ' fi' >> $backup_databases_script
echo 'else' >> $backup_databases_script
echo ' chmod 600 $TEMPFILE' >> $backup_databases_script
echo ' mv $TEMPFILE $DAILYFILE' >> $backup_databases_script
echo '' >> $backup_databases_script
echo ' # Make the backup readable only by root' >> $backup_databases_script
echo ' chmod 600 $DAILYFILE' >> $backup_databases_script
echo 'fi' >> $backup_databases_script
echo "# End of ${database_name} database backup" >> $backup_databases_script
fi
weekly_backup_script=/etc/cron.weekly/backupdatabasesweekly
if ! grep -q "Backup ${database_name}" ${weekly_backup_script}; then
echo "# Backup ${database_name}" >> ${weekly_backup_script}
echo "if [ -f /var/backups/${database_name}_weekly.sql ]; then" >> ${weekly_backup_script}
echo " cp -f /var/backups/${database_name}_weekly.sql /var/backups/${database_name}_2weekly.sql" >> ${weekly_backup_script}
echo 'fi' >> ${weekly_backup_script}
echo "if [ -f /var/backups/${database_name}_daily.sql ]; then" >> ${weekly_backup_script}
echo " cp -f /var/backups/${database_name}_daily.sql /var/backups/${database_name}_weekly.sql" >> ${weekly_backup_script}
echo 'fi' >> ${weekly_backup_script}
echo "# End of backup for ${database_name}" >> ${weekly_backup_script}
fi
monthly_backup_script=/etc/cron.monthly/backupdatabasesmonthly
if ! grep -q "Backup ${database_name}" ${monthly_backup_script}; then
echo "# Backup ${database_name}" >> ${monthly_backup_script}
echo "if [ -f /var/backups/${database_name}_monthly.sql ]; then" >> ${monthly_backup_script}
echo " cp -f /var/backups/${database_name}_monthly.sql /var/backups/${database_name}_2monthly.sql" >> ${monthly_backup_script}
echo 'fi' >> ${monthly_backup_script}
echo "if [ -f /var/backups/${database_name}_weekly.sql ]; then" >> ${monthly_backup_script}
echo " cp -f /var/backups/${database_name}_weekly.sql /var/backups/${database_name}_monthly.sql" >> ${monthly_backup_script}
echo 'fi' >> ${monthly_backup_script}
echo "# End of backup for ${database_name}" >> ${monthly_backup_script}
fi
if ! grep -q "${database_name}" /etc/cron.hourly/repair; then
echo "${PROJECT_NAME}-repair-database ${database_name}" >> /etc/cron.hourly/repair
# remove legacy stuff
sed -i 's|/usr/bin/repairdatabase redmatrix||g' /etc/cron.hourly/repair
fi
}
function get_mariadb_password {
# migrate from database password file to using the password store
DATABASE_PASSWORD_FILE=/root/dbpass
if [ -f $DATABASE_PASSWORD_FILE ]; then
MARIADB_PASSWORD=$(cat $DATABASE_PASSWORD_FILE)
${PROJECT_NAME}-pass -u root -a mariadb -p "$MARIADB_PASSWORD"
stored_password=$(${PROJECT_NAME}-pass -u root -a mariadb)
if [[ "$stored_password" == "$MARIADB_PASSWORD" ]]; then
shred -zu $DATABASE_PASSWORD_FILE
echo $'MariaDB password moved into password store'
return
fi
MARIADB_PASSWORD=$(${PROJECT_NAME}-pass -u root -a mariadb)
}
function install_mariadb {
apt-get -yq install software-properties-common debconf-utils
function_check get_mariadb_password
get_mariadb_password
if [ ! $MARIADB_PASSWORD ]; then
if [ -f $IMAGE_PASSWORD_FILE ]; then
MARIADB_PASSWORD="$(printf `cat $IMAGE_PASSWORD_FILE`)"
else
MARIADB_PASSWORD="$(openssl rand -base64 32 | cut -c1-${MINIMUM_PASSWORD_LENGTH})"
fi
fi
${PROJECT_NAME}-pass -u root -a mariadb -p "$MARIADB_PASSWORD"
debconf-set-selections <<< "mariadb-server mariadb-server/root_password password $MARIADB_PASSWORD"
debconf-set-selections <<< "mariadb-server mariadb-server/root_password_again password $MARIADB_PASSWORD"
if [ -d /etc/apache2 ]; then
rm -rf /etc/apache2
echo $'Removed Apache installation after MariaDB install'
fi
if [ ! -d /etc/mysql ]; then
echo $"ERROR: mariadb-server does not appear to have installed. $CHECK_MESSAGE"
exit 54
fi
if [ ! -f /usr/bin/mysql ]; then
echo $"ERROR: mariadb-server does not appear to have installed. $CHECK_MESSAGE"
exit 34672
fi
sed -i 's|ExecStart=/usr/sbin/mysqld|ExecStart=/usr/sbin/mysqld --skip-grant-tables|g' /lib/systemd/system/mariadb.service
systemctl daemon-reload
# See http://www.pontikis.net/blog/debian-9-stretch-rc3-web-server-setup-php7-mariadb
# https://mariadb.com/kb/en/mariadb/unix_socket-authentication-plugin
run_query_root mysql "update mysql.user set plugin = '' where User='root'; flush privileges;"
run_query_root mysql "UPDATE user SET Password=PASSWORD('$MARIADB_PASSWORD') where USER='root'; flush privileges;"
sed -i 's| --skip-grant-tables||g' /lib/systemd/system/mariadb.service
systemctl daemon-reload
systemctl restart mariadb
}
function backup_databases_script_header {
if [ ! -f /usr/bin/backupdatabases ]; then
# daily
echo '#!/bin/sh' > /usr/bin/backupdatabases
echo '' >> /usr/bin/backupdatabases
echo "EMAIL='$MY_EMAIL_ADDRESS'" >> /usr/bin/backupdatabases
echo '' >> /usr/bin/backupdatabases
echo "MYSQL_PASSWORD=\$(${PROJECT_NAME}-pass -u root -a mariadb)" >> /usr/bin/backupdatabases
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
echo 'umask 0077' >> /usr/bin/backupdatabases
echo '' >> /usr/bin/backupdatabases
echo '# exit if we are backing up to friends servers' >> /usr/bin/backupdatabases
echo "if [ -f $FRIENDS_SERVERS_LIST ]; then" >> /usr/bin/backupdatabases
echo ' exit 1' >> /usr/bin/backupdatabases
echo 'fi' >> /usr/bin/backupdatabases
chmod 600 /usr/bin/backupdatabases
chmod +x /usr/bin/backupdatabases
echo '#!/bin/sh' > /etc/cron.daily/backupdatabasesdaily
echo '/usr/bin/backupdatabases' >> /etc/cron.daily/backupdatabasesdaily
chmod 600 /etc/cron.daily/backupdatabasesdaily
chmod +x /etc/cron.daily/backupdatabasesdaily
# weekly
echo '#!/bin/sh' > /etc/cron.weekly/backupdatabasesweekly
echo '' >> /etc/cron.weekly/backupdatabasesweekly
echo 'umask 0077' >> /etc/cron.weekly/backupdatabasesweekly
chmod 600 /etc/cron.weekly/backupdatabasesweekly
chmod +x /etc/cron.weekly/backupdatabasesweekly
# monthly
echo '#!/bin/sh' > /etc/cron.monthly/backupdatabasesmonthly
echo '' >> /etc/cron.monthly/backupdatabasesmonthly
echo 'umask 0077' >> /etc/cron.monthly/backupdatabasesmonthly
chmod 600 /etc/cron.monthly/backupdatabasesmonthly
chmod +x /etc/cron.monthly/backupdatabasesmonthly
fi
}
function repair_databases_script {
if [ -f /etc/cron.hourly/repair ]; then
sed -i "s|/usr/bin/repairdatabase|${PROJECT_NAME}-repair-database|g" /etc/cron.hourly/repair
fi
db_pass=$(${PROJECT_NAME}-pass -u root -p mariadb)
if [[ "$db_pass" == 'Error:'* ]]; then
echo '#!/bin/bash' > /etc/cron.hourly/repair
echo '' >> /etc/cron.hourly/repair
chmod 600 /etc/cron.hourly/repair
chmod +x /etc/cron.hourly/repair
}
function remove_database {
app_name="$1"
if [ ! -d $INSTALL_DIR ]; then
mkdir $INSTALL_DIR
fi
echo "drop database ${app_name};
quit" > $INSTALL_DIR/batch.sql
chmod 600 $INSTALL_DIR/batch.sql
mysql -u root --password="$MARIADB_PASSWORD" < $INSTALL_DIR/batch.sql
shred -zu $INSTALL_DIR/batch.sql
}
function create_database {
app_name="$1"
app_admin_password="$2"
app_admin_username=$3
if [ ! -d $INSTALL_DIR ]; then
mkdir $INSTALL_DIR
fi
if [ ! $app_admin_username ]; then
app_admin_username=${app_name}admin
fi
echo "create database ${app_name};
CREATE USER '$app_admin_username@localhost' IDENTIFIED BY '${app_admin_password}';
GRANT ALL PRIVILEGES ON ${app_name}.* TO '$app_admin_username@localhost';
quit" > $INSTALL_DIR/batch.sql
chmod 600 $INSTALL_DIR/batch.sql
mysql -u root --password="$MARIADB_PASSWORD" < $INSTALL_DIR/batch.sql
shred -zu $INSTALL_DIR/batch.sql
database_name=$1
database_file=$2
mysql -u root --password="$MARIADB_PASSWORD" -D $database_name < $database_file
if [ ! "$?" = "0" ]; then
exit 62952
fi
database_name=$1
database_query=$2
mysql -u root --password="$MARIADB_PASSWORD" -e "$database_query" $database_name
function run_query_root {
database_name=$1
database_query=$2
mysql -e "$database_query" $database_name
}
function run_query_with_output {
database_name=$1
database_query=$2
output=$(mysql -u root --password="$MARIADB_PASSWORD" << EOF
use $database_name;
$database_query
EOF
)
echo "$output"
}
database_name=$1
get_mariadb_password
mysqladmin -uroot -p"$MARIADB_PASSWORD" -f drop $database_name
function database_reinstall {
sed -i '/mariadb/d' ~/${PROJECT_NAME}-completed.txt
install_mariadb
function install_rethinkdb {
if [ ! -d $INSTALL_DIR ]; then
mkdir -p $INSTALL_DIR
fi
cd $INSTALL_DIR
echo "deb http://download.rethinkdb.com/apt `lsb_release -cs` main" | tee /etc/apt/sources.list.d/rethinkdb.list
wget -qO- https://download.rethinkdb.com/apt/pubkey.gpg | apt-key add -
apt-get update
apt-get -yq install rethinkdb
echo 'runuser=rethinkdb' > /etc/rethinkdb/instances.d/default.conf
echo 'rungroup=rethinkdb' >> /etc/rethinkdb/instances.d/default.conf
echo '# pid-file=/var/run/rethinkdb/rethinkdb.pid' >> /etc/rethinkdb/instances.d/default.conf
echo '# directory=/var/lib/rethinkdb/default' >> /etc/rethinkdb/instances.d/default.conf
echo '# log-file=/var/log/rethinkdb' >> /etc/rethinkdb/instances.d/default.conf
echo 'bind=127.0.0.1' >> /etc/rethinkdb/instances.d/default.conf
echo '# canonical-address=' >> /etc/rethinkdb/instances.d/default.conf
echo '# driver-port=28015' >> /etc/rethinkdb/instances.d/default.conf
echo '# cluster-port=29015' >> /etc/rethinkdb/instances.d/default.conf
echo '# join=example.com:29015' >> /etc/rethinkdb/instances.d/default.conf
echo '# port-offset=0' >> /etc/rethinkdb/instances.d/default.conf
echo '# reql-http-proxy=socks5://example.com:1080' >> /etc/rethinkdb/instances.d/default.conf
echo '# http-port=8091' >> /etc/rethinkdb/instances.d/default.conf
echo '# no-http-admin' >> /etc/rethinkdb/instances.d/default.conf
echo '# cores=2' >> /etc/rethinkdb/instances.d/default.conf
echo '# cache-size=1024' >> /etc/rethinkdb/instances.d/default.conf
echo '# io-threads=64' >> /etc/rethinkdb/instances.d/default.conf
echo '# direct-io' >> /etc/rethinkdb/instances.d/default.conf
echo '# server-name=server1' >> /etc/rethinkdb/instances.d/default.conf
systemctl restart rethinkdb
}
function remove_rethinkdb {
if [ ! -d /etc/rethinkdb ]; then
return
fi
apt-get -yq remove rethinkdb
if [ -d /etc/rethinkdb ]; then
rm -rf /etc/rethinkdb
fi
if [ -f /etc/apt/sources.list.d/rethinkdb.list ]; then
rm /etc/apt/sources.list.d/rethinkdb.list
apt-get update
fi
}
# NOTE: deliberately there is no "exit 0"