freedombone-utils-backup 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. #!/bin/bash
  2. #
  3. # .---. . .
  4. # | | |
  5. # |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
  6. # | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
  7. # ' ' --' --' -' - -' ' ' -' -' -' ' - --'
  8. #
  9. # Freedom in the Cloud
  10. #
  11. # Backup functions
  12. #
  13. # License
  14. # =======
  15. #
  16. # Copyright (C) 2014-2016 Bob Mottram <bob@freedombone.net>
  17. #
  18. # This program is free software: you can redistribute it and/or modify
  19. # it under the terms of the GNU Affero General Public License as published by
  20. # the Free Software Foundation, either version 3 of the License, or
  21. # (at your option) any later version.
  22. #
  23. # This program is distributed in the hope that it will be useful,
  24. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. # GNU Affero General Public License for more details.
  27. #
  28. # You should have received a copy of the GNU Affero General Public License
  29. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  30. # whether a given site is being suspended during backup
  31. SUSPENDED_SITE=
  32. function suspend_site {
  33. # suspends a given website
  34. SUSPENDED_SITE="$1"
  35. nginx_dissite $SUSPENDED_SITE
  36. systemctl reload nginx
  37. }
  38. function restart_site {
  39. # restarts a given website
  40. if [ ! $SUSPENDED_SITE ]; then
  41. return
  42. fi
  43. nginx_ensite $SUSPENDED_SITE
  44. systemctl reload nginx
  45. SUSPENDED_SITE=
  46. }
  47. function configure_backup_key {
  48. if [[ $(is_completed $FUNCNAME) == "1" ]]; then
  49. return
  50. fi
  51. apt-get -yq install gnupg
  52. BACKUP_KEY_EXISTS=$(gpg_key_exists "root" "$MY_NAME (backup key)")
  53. if [[ $BACKUP_KEY_EXISTS == "yes" ]]; then
  54. return
  55. fi
  56. # Generate a GPG key for backups
  57. BACKUP_KEY_EXISTS=$(gpg_key_exists "$MY_USERNAME" "$MY_NAME (backup key)")
  58. if [[ $BACKUP_KEY_EXISTS == "no" ]]; then
  59. echo 'Key-Type: 1' > /home/$MY_USERNAME/gpg-genkey.conf
  60. echo 'Key-Length: 4096' >> /home/$MY_USERNAME/gpg-genkey.conf
  61. echo 'Subkey-Type: 1' >> /home/$MY_USERNAME/gpg-genkey.conf
  62. echo 'Subkey-Length: 4096' >> /home/$MY_USERNAME/gpg-genkey.conf
  63. echo "Name-Real: $MY_NAME" >> /home/$MY_USERNAME/gpg-genkey.conf
  64. echo "Name-Email: $MY_EMAIL_ADDRESS" >> /home/$MY_USERNAME/gpg-genkey.conf
  65. echo "Name-Comment: backup key" >> /home/$MY_USERNAME/gpg-genkey.conf
  66. echo 'Expire-Date: 0' >> /home/$MY_USERNAME/gpg-genkey.conf
  67. chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/gpg-genkey.conf
  68. echo $'Backup key does not exist. Creating it.'
  69. su -m root -c "gpg --homedir /home/$MY_USERNAME/.gnupg --batch --passphrase '' --full-gen-key /home/$MY_USERNAME/gpg-genkey.conf" - $MY_USERNAME
  70. chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.gnupg
  71. shred -zu /home/$MY_USERNAME/gpg-genkey.conf
  72. echo $'Checking that the Backup key was created'
  73. BACKUP_KEY_EXISTS=$(gpg_key_exists "$MY_USERNAME" "$MY_NAME (backup key)")
  74. if [[ $BACKUP_KEY_EXISTS == "no" ]]; then
  75. echo $'Backup key could not be created'
  76. exit 43382
  77. fi
  78. fi
  79. MY_BACKUP_KEY_ID=$(su -c "gpg --list-keys \"$MY_NAME (backup key)\" | grep 'pub '" - $MY_USERNAME | awk -F ' ' '{print $2}' | awk -F '/' '{print $2}')
  80. echo "Backup key: $MY_BACKUP_KEY_ID"
  81. MY_BACKUP_KEY=/home/$MY_USERNAME/backup_key
  82. su -m root -c "gpg --homedir /home/$MY_USERNAME/.gnupg --output ${MY_BACKUP_KEY}_public.asc --armor --export $MY_BACKUP_KEY_ID" - $MY_USERNAME
  83. su -m root -c "gpg --homedir /home/$MY_USERNAME/.gnupg --output ${MY_BACKUP_KEY}_private.asc --armor --export-secret-key $MY_BACKUP_KEY_ID" - $MY_USERNAME
  84. if [ ! -f ${MY_BACKUP_KEY}_public.asc ]; then
  85. echo 'Public backup key could not be exported'
  86. exit 36829
  87. fi
  88. if [ ! -f ${MY_BACKUP_KEY}_private.asc ]; then
  89. echo 'Private backup key could not be exported'
  90. exit 29235
  91. fi
  92. # import backup key to root user
  93. gpg --import --import ${MY_BACKUP_KEY}_public.asc
  94. gpg --allow-secret-key-import --import ${MY_BACKUP_KEY}_private.asc
  95. shred -zu ${MY_BACKUP_KEY}_public.asc
  96. shred -zu ${MY_BACKUP_KEY}_private.asc
  97. mark_completed $FUNCNAME
  98. }
  99. function backup_to_friends_servers {
  100. # update crontab
  101. echo '#!/bin/bash' > /etc/cron.daily/backuptofriends
  102. echo "if [ -f /usr/local/bin/${PROJECT_NAME}-backup-remote ]; then" >> /etc/cron.daily/backuptofriends
  103. echo " /usr/local/bin/${PROJECT_NAME}-backup-remote" >> /etc/cron.daily/backuptofriends
  104. echo 'else' >> /etc/cron.daily/backuptofriends
  105. echo " /usr/bin/${PROJECT_NAME}-backup-remote" >> /etc/cron.daily/backuptofriends
  106. echo 'fi' >> /etc/cron.daily/backuptofriends
  107. chmod +x /etc/cron.daily/backuptofriends
  108. }
  109. function backup_mount_drive {
  110. if [ $1 ]; then
  111. if [[ "$1" == "/dev/"* ]]; then
  112. USB_DRIVE=$1
  113. else
  114. USB_DRIVE=/dev/${1}1
  115. fi
  116. fi
  117. # get the admin user
  118. ADMIN_USERNAME=$(get_completion_param "Admin user")
  119. if [ $2 ]; then
  120. ADMIN_USERNAME=$2
  121. fi
  122. ADMIN_NAME=$(getent passwd $ADMIN_USERNAME | cut -d: -f5 | cut -d, -f1)
  123. if [ $3 ]; then
  124. RESTORE_APP=$3
  125. fi
  126. # check that the backup destination is available
  127. if [ ! -b $USB_DRIVE ]; then
  128. echo $"Please attach a USB drive"
  129. exit 1
  130. fi
  131. # unmount if already mounted
  132. umount -f $USB_MOUNT
  133. if [ ! -d $USB_MOUNT ]; then
  134. mkdir $USB_MOUNT
  135. fi
  136. if [ -f /dev/mapper/encrypted_usb ]; then
  137. rm -rf /dev/mapper/encrypted_usb
  138. fi
  139. cryptsetup luksClose encrypted_usb
  140. # mount the encrypted backup drive
  141. cryptsetup luksOpen $USB_DRIVE encrypted_usb
  142. if [ "$?" = "0" ]; then
  143. USB_DRIVE=/dev/mapper/encrypted_usb
  144. fi
  145. mount $USB_DRIVE $USB_MOUNT
  146. if [ ! "$?" = "0" ]; then
  147. echo $"There was a problem mounting the USB drive to $USB_MOUNT"
  148. rm -rf $USB_MOUNT
  149. exit 783452
  150. fi
  151. }
  152. function backup_unmount_drive {
  153. if [ $1 ]; then
  154. USB_DRIVE=${1}
  155. if [ $2 ]; then
  156. USB_MOUNT=${2}
  157. fi
  158. fi
  159. sync
  160. umount $USB_MOUNT
  161. if [ ! "$?" = "0" ]; then
  162. echo $"Unable to unmount the drive."
  163. rm -rf $USB_MOUNT
  164. exit 9
  165. fi
  166. rm -rf $USB_MOUNT
  167. if [[ $USB_DRIVE == /dev/mapper/encrypted_usb ]]; then
  168. echo $"Unmount encrypted USB"
  169. cryptsetup luksClose encrypted_usb
  170. fi
  171. if [ -f /dev/mapper/encrypted_usb ]; then
  172. rm -rf /dev/mapper/encrypted_usb
  173. fi
  174. }
  175. function backup_database_local_usb {
  176. if [ ${#DATABASE_PASSWORD} -lt 2 ]; then
  177. echo $"No MariaDB password was given"
  178. function_check restart_site
  179. restart_site
  180. exit 10
  181. fi
  182. if [ ! -d $USB_MOUNT/backup/${1} ]; then
  183. mkdir -p $USB_MOUNT/backup/${1}
  184. fi
  185. if [ ! -d $USB_MOUNT/backup/${1}data ]; then
  186. mkdir -p $USB_MOUNT/backup/${1}data
  187. fi
  188. local_database_dir=/root/temp${1}data
  189. if [ ! -d ${local_database_dir} ]; then
  190. mkdir -p ${local_database_dir}
  191. fi
  192. echo $"Obtaining ${1} database backup"
  193. mysqldump --lock-tables --password="$DATABASE_PASSWORD" ${1} > ${local_database_dir}/${1}.sql
  194. if [ -f ${local_database_dir}/${1}.sql ]; then
  195. if [ ! -s ${local_database_dir}/${1}.sql ]; then
  196. echo $"${1} database could not be saved"
  197. shred -zu ${local_database_dir}/*
  198. rm -rf ${local_database_dir}
  199. umount $USB_MOUNT
  200. rm -rf $USB_MOUNT
  201. restart_site
  202. exit 6835872
  203. fi
  204. else
  205. echo $"${1} database could not be dumped"
  206. rm -rf ${local_database_dir}
  207. umount $USB_MOUNT
  208. rm -rf $USB_MOUNT
  209. restart_site
  210. exit 738653
  211. fi
  212. echo $"Database dump was created for ${1}"
  213. }
  214. function set_obnam_client_name {
  215. # obnam can backup multiple machines with different domain names to
  216. # a repository. To be able to restore directories from different
  217. # machines we need to enforce a single client name for all backups
  218. echo '[config]' > /etc/obnam.conf
  219. echo "client-name = ${PROJECT_NAME}" >> /etc/obnam.conf
  220. }
  221. function backup_directory_to_usb {
  222. if [ ! -d ${1} ]; then
  223. echo $"WARNING: directory does not exist: ${1}"
  224. else
  225. BACKUP_KEY_EXISTS=$(gpg --list-keys "$ADMIN_NAME (backup key)")
  226. if [ ! "$?" = "0" ]; then
  227. echo $"Backup key could not be found"
  228. function_check restart_site
  229. restart_site
  230. exit 6
  231. fi
  232. MY_BACKUP_KEY_ID=$(gpg --list-keys "$ADMIN_NAME (backup key)" | grep 'pub ' | awk -F ' ' '{print $2}' | awk -F '/' '{print $2}')
  233. if [ ! -d $USB_MOUNT/backup/${2} ]; then
  234. mkdir -p $USB_MOUNT/backup/${2}
  235. fi
  236. set_obnam_client_name
  237. obnam force-lock -r $USB_MOUNT/backup/${2} --encrypt-with $MY_BACKUP_KEY_ID ${1}
  238. obnam backup -r $USB_MOUNT/backup/${2} --encrypt-with $MY_BACKUP_KEY_ID ${1}
  239. if [[ $ENABLE_BACKUP_VERIFICATION == "yes" ]]; then
  240. obnam verify -r $USB_MOUNT/backup/${2} --encrypt-with $MY_BACKUP_KEY_ID ${1}
  241. if [ ! "$?" = "0" ]; then
  242. umount $USB_MOUNT
  243. rm -rf $USB_MOUNT
  244. if [[ ${1} == "/root/temp"* || ${1} == *"tempbackup" ]]; then
  245. shred -zu ${1}/*
  246. rm -rf ${1}
  247. fi
  248. function_check restart_site
  249. restart_site
  250. exit 683252
  251. fi
  252. fi
  253. obnam forget --keep=30d -r $USB_MOUNT/backup/${2} --encrypt-with $MY_BACKUP_KEY_ID
  254. if [ ! "$?" = "0" ]; then
  255. umount $USB_MOUNT
  256. rm -rf $USB_MOUNT
  257. if [[ ${1} == "/root/temp"* || ${1} == *"tempbackup" ]]; then
  258. shred -zu ${1}/*
  259. rm -rf ${1}
  260. fi
  261. function_check restart_site
  262. restart_site
  263. exit 7
  264. fi
  265. if [[ ${1} == "/root/temp"* || ${1} == *"tempbackup" ]]; then
  266. shred -zu ${1}/*
  267. rm -rf ${1}
  268. fi
  269. fi
  270. }
  271. function restore_directory_from_usb {
  272. if [ ! ${1} ]; then
  273. echo "obnam restore -r $USB_MOUNT/backup/${2} --to ${1}"
  274. echo $'No restore destination given'
  275. return
  276. fi
  277. if [ ! ${2} ]; then
  278. echo "obnam restore -r $USB_MOUNT/backup/${2} --to ${1}"
  279. echo $'No restore source given'
  280. return
  281. fi
  282. if [ ! -d ${1} ]; then
  283. mkdir ${1}
  284. fi
  285. set_obnam_client_name
  286. obnam restore -r $USB_MOUNT/backup/${2} --to ${1}
  287. }
  288. function restore_directory_from_friend {
  289. if [ ! ${1} ]; then
  290. echo "obnam restore -r $SERVER_DIRECTORY/backup/${2} --to ${1}"
  291. echo $'No restore destination given'
  292. return
  293. fi
  294. if [ ! ${2} ]; then
  295. echo "obnam restore -r $SERVER_DIRECTORY/backup/${2} --to ${1}"
  296. echo $'No restore source given'
  297. return
  298. fi
  299. if [ ! -d ${1} ]; then
  300. mkdir ${1}
  301. fi
  302. set_obnam_client_name
  303. obnam restore -r $SERVER_DIRECTORY/backup/${2} --to ${1}
  304. }
  305. function backup_database_to_usb {
  306. database_name=$1
  307. local_database_dir=/root/temp${1}data
  308. backup_database_local_usb ${database_name}
  309. if [ ! -f ${local_database_dir}/${1}.sql ]; then
  310. echo $"Error backing up ${1} database to ${local_database_dir}/${1}.sql"
  311. exit 62383
  312. fi
  313. backup_directory_to_usb ${local_database_dir} ${database_name}data
  314. }
  315. # after user files have been restored permissions may need to be set
  316. function set_user_permissions {
  317. echo $"Setting permissions"
  318. for d in /home/*/ ; do
  319. USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
  320. if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
  321. chown -R $USERNAME:$USERNAME /home/$USERNAME
  322. fi
  323. done
  324. }
  325. function backup_directory_to_friend {
  326. BACKUP_KEY_EXISTS=$(gpg --list-keys "$ADMIN_NAME (backup key)")
  327. if [ ! "$?" = "0" ]; then
  328. echo $"Backup key could not be found"
  329. function_check restart_site
  330. restart_site
  331. exit 43382
  332. fi
  333. ADMIN_BACKUP_KEY_ID=$(gpg --list-keys "$ADMIN_NAME (backup key)" | grep 'pub ' | awk -F ' ' '{print $2}' | awk -F '/' '{print $2}')
  334. if [ ! -d $SERVER_DIRECTORY/backup/${2} ]; then
  335. mkdir -p $SERVER_DIRECTORY/backup/${2}
  336. fi
  337. set_obnam_client_name
  338. obnam force-lock -r $SERVER_DIRECTORY/backup/${2} --encrypt-with ${ADMIN_BACKUP_KEY_ID} ${1}
  339. obnam backup -r $SERVER_DIRECTORY/backup/${2} --encrypt-with ${ADMIN_BACKUP_KEY_ID} ${1}
  340. if [[ $ENABLE_VERIFICATION == "yes" ]]; then
  341. obnam verify -r $SERVER_DIRECTORY/backup/${2} --encrypt-with ${ADMIN_BACKUP_KEY_ID} ${1}
  342. if [ ! "$?" = "0" ]; then
  343. if [[ ${1} == "/root/temp"* || ${1} == *"tempbackup" ]]; then
  344. shred -zu /root/temp${2}/*
  345. rm -rf /root/temp${2}
  346. fi
  347. # Send a warning email
  348. echo "Unable to verify ${2}" | mail -s "${PROJECT_NAME} backup to friends" ${ADMIN_EMAIL_ADDRESS}
  349. function_check restart_site
  350. restart_site
  351. exit 953
  352. fi
  353. fi
  354. obnam forget --keep=30d -r $SERVER_DIRECTORY/backup/${2} --encrypt-with ${ADMIN_BACKUP_KEY_ID}
  355. if [ ! "$?" = "0" ]; then
  356. if [[ ${1} == "/root/temp"* || ${1} == *"tempbackup" ]]; then
  357. shred -zu /root/temp${2}/*
  358. rm -rf /root/temp${2}
  359. fi
  360. # Send a warning email
  361. echo "Unable to backup ${2}" | mail -s "${PROJECT_NAME} backup to friends" ${ADMIN_EMAIL_ADDRESS}
  362. function_check restart_site
  363. restart_site
  364. exit 853
  365. fi
  366. if [[ ${1} == "/root/temp"* || ${1} == *"tempbackup" ]]; then
  367. shred -zu /root/temp${2}/*
  368. rm -rf /root/temp${2}
  369. fi
  370. }
  371. function backup_database_remote {
  372. if [ ${#DATABASE_PASSWORD} -lt 2 ]; then
  373. echo $"No MariaDB password was given"
  374. function_check restart_site
  375. restart_site
  376. exit 5783
  377. fi
  378. if [ ! -d $SERVER_DIRECTORY/backup/${1} ]; then
  379. mkdir -p $SERVER_DIRECTORY/backup/${1}
  380. fi
  381. if [ ! -d $SERVER_DIRECTORY/backup/${1}data ]; then
  382. mkdir -p $SERVER_DIRECTORY/backup/${1}data
  383. fi
  384. local_database_dir=/root/temp${1}data
  385. if [ ! -d ${local_database_dir} ]; then
  386. mkdir -p ${local_database_dir}
  387. fi
  388. echo "Obtaining ${1} database backup"
  389. mysqldump --password="$DATABASE_PASSWORD" ${1} > ${local_database_dir}/${1}.sql
  390. if [ -f ${local_database_dir}/${1}.sql ]; then
  391. if [ ! -s ${local_database_dir}/${1}.sql ]; then
  392. echo $"${1} database could not be saved"
  393. shred -zu ${local_database_dir}/*
  394. rm -rf ${local_database_dir}
  395. # Send a warning email
  396. echo $"Unable to export ${1} database" | mail -s $"${PROJECT_NAME} backup to friends" $ADMIN_EMAIL_ADDRESS
  397. function_check restart_site
  398. restart_site
  399. exit 5738
  400. fi
  401. else
  402. echo $"${1} database could not be dumped"
  403. rm -rf ${local_database_dir}
  404. # Send a warning email
  405. echo $"Unable to dump ${1} database" | mail -s $"${PROJECT_NAME} backup to friends" $ADMIN_EMAIL_ADDRESS
  406. function_check restart_site
  407. restart_site
  408. exit 3687
  409. fi
  410. }
  411. function backup_database_to_friend {
  412. database_name=$1
  413. backup_database_remote $database_name
  414. backup_directory_to_friend /root/temp${database_name}data ${database_name}data
  415. }
  416. function backup_apps {
  417. localremote=$1
  418. BACKUP_APPS_COMPLETED=()
  419. detect_installable_apps
  420. get_apps_installed_names
  421. for app_name in "${APPS_INSTALLED_NAMES[@]}"
  422. do
  423. echo $"Backup ${app_name}"
  424. app_load_variables ${app_name}
  425. function_check backup_${localremote}_${app_name}
  426. backup_${localremote}_${app_name}
  427. BACKUP_APPS_COMPLETED+=("${app_name}")
  428. echo $"Backup ${app_name} completed"
  429. done
  430. }
  431. function restore_apps {
  432. localremote=$1
  433. RESTORE_APP=$2
  434. RESTORE_APPS_COMPLETED=()
  435. detect_installable_apps
  436. get_apps_installed_names
  437. for app_name in "${APPS_INSTALLED_NAMES[@]}"
  438. do
  439. confirm_restore=
  440. if [ ! $2 ]; then
  441. confirm_restore=1
  442. else
  443. if [[ "$RESTORE_APP" == "$app_name" || "$RESTORE_APP" == "all" ]]; then
  444. confirm_restore=1
  445. fi
  446. fi
  447. if [ $confirm_restore ]; then
  448. echo $"Restoring ${app_name}"
  449. app_load_variables ${app_name}
  450. function_check restore_${localremote}_${app_name}
  451. restore_${localremote}_${app_name}
  452. RESTORE_APPS_COMPLETED+=("${app_name}")
  453. echo $"Restored ${app_name}"
  454. fi
  455. done
  456. }
  457. function restore_database_from_friend {
  458. DATABASE_PASSWORD=
  459. RESTORE_SUBDIR="root"
  460. if [ -d $SERVER_DIRECTORY/backup/${1} ]; then
  461. echo $"Restoring ${1} database"
  462. local_database_dir=/root/temp${1}data
  463. restore_directory_from_friend ${local_database_dir} ${1}data
  464. if [ ! -f ${local_database_dir}/${RESTORE_SUBDIR}/temp${1}data/${1}.sql ]; then
  465. echo $"Unable to restore ${1} database"
  466. rm -rf ${local_database_dir}
  467. exit 503
  468. fi
  469. mysqlsuccess=$(mysql -u root --password="$DATABASE_PASSWORD" ${1} -o < ${local_database_dir}/${RESTORE_SUBDIR}/temp${1}data/${1}.sql)
  470. if [ ! "$?" = "0" ]; then
  471. echo "$mysqlsuccess"
  472. exit 964
  473. fi
  474. shred -zu ${local_database_dir}/${RESTORE_SUBDIR}/temp${1}data/*
  475. rm -rf ${local_database_dir}
  476. echo $"Restoring ${1} installation"
  477. restore_directory_from_friend /root/temp${1} ${1}
  478. RESTORE_SUBDIR="var"
  479. if [ ${1} ]; then
  480. if [ ! -d /var/www/${2}/htdocs ]; then
  481. mkdir -p /var/www/${2}/htdocs
  482. chown www-data:www-data /var/www/${2}/htdocs
  483. fi
  484. if [ -d /var/www/${2}/htdocs ]; then
  485. if [ -d /root/temp${1}/${RESTORE_SUBDIR}/www/${2}/htdocs ]; then
  486. rm -rf /var/www/${2}/htdocs
  487. mv /root/temp${1}/${RESTORE_SUBDIR}/www/${2}/htdocs /var/www/${2}/
  488. if [ ! "$?" = "0" ]; then
  489. exit 683
  490. fi
  491. if [ -d /etc/letsencrypt/live/${2} ]; then
  492. ln -s /etc/letsencrypt/live/${2}/privkey.pem /etc/ssl/private/${2}.key
  493. ln -s /etc/letsencrypt/live/${2}/fullchain.pem /etc/ssl/certs/${2}.pem
  494. else
  495. # Ensure that the bundled SSL cert is being used
  496. if [ -f /etc/ssl/certs/${2}.bundle.crt ]; then
  497. sed -i "s|${2}.crt|${2}.bundle.crt|g" /etc/nginx/sites-available/${2}
  498. fi
  499. fi
  500. fi
  501. fi
  502. fi
  503. fi
  504. }
  505. function restore_database {
  506. RESTORE_SUBDIR="root"
  507. restore_app_name=$1
  508. restore_app_domain=$2
  509. if [ -d $USB_MOUNT/backup/${restore_app_name} ]; then
  510. echo $"Restoring ${restore_app_name} database"
  511. local_database_dir=/root/temp${restore_app_name}data
  512. function_check restore_directory_from_usb
  513. restore_directory_from_usb "${local_database_dir}" "${restore_app_name}data"
  514. if [ ! -f /root/temp${restore_app_name}data/${RESTORE_SUBDIR}/temp${restore_app_name}data/${restore_app_name}.sql ]; then
  515. echo $"Unable to restore ${restore_app_name} database"
  516. rm -rf ${local_database_dir}
  517. function_check set_user_permissions
  518. set_user_permissions
  519. function_check backup_unmount_drive
  520. backup_unmount_drive
  521. exit 503
  522. fi
  523. mysqlsuccess=$(mysql -u root --password="$DATABASE_PASSWORD" ${restore_app_name} -o < ${local_database_dir}/${RESTORE_SUBDIR}/temp${restore_app_name}data/${restore_app_name}.sql)
  524. if [ ! "$?" = "0" ]; then
  525. echo "$mysqlsuccess"
  526. function_check set_user_permissions
  527. set_user_permissions
  528. function_check set_user_permissions
  529. backup_unmount_drive
  530. exit 964
  531. fi
  532. shred -zu ${local_database_dir}/${RESTORE_SUBDIR}/temp${restore_app_name}data/*
  533. rm -rf ${local_database_dir}
  534. echo $"Restoring ${restore_app_name} installation"
  535. if [ ! -d /root/temp${restore_app_name} ]; then
  536. mkdir /root/temp${restore_app_name}
  537. fi
  538. function_check restore_directory_from_usb
  539. restore_directory_from_usb "/root/temp${restore_app_name}" "${restore_app_name}"
  540. RESTORE_SUBDIR="var"
  541. if [ ${restore_app_domain} ]; then
  542. if [ ! -d /var/www/${restore_app_domain}/htdocs ]; then
  543. mkdir -p /var/www/${restore_app_domain}/htdocs
  544. chown www-data:www-data /var/www/${restore_app_domain}/htdocs
  545. fi
  546. if [ -d /var/www/${restore_app_domain}/htdocs ]; then
  547. if [ -d /root/temp${restore_app_name}/${RESTORE_SUBDIR}/www/${restore_app_domain}/htdocs ]; then
  548. rm -rf /var/www/${restore_app_domain}/htdocs
  549. mv /root/temp${restore_app_name}/${RESTORE_SUBDIR}/www/${restore_app_domain}/htdocs /var/www/${restore_app_domain}/
  550. if [ ! "$?" = "0" ]; then
  551. set_user_permissions
  552. backup_unmount_drive
  553. exit 683
  554. fi
  555. if [ -d /etc/letsencrypt/live/${restore_app_domain} ]; then
  556. ln -s /etc/letsencrypt/live/${restore_app_domain}/privkey.pem /etc/ssl/private/${restore_app_domain}.key
  557. ln -s /etc/letsencrypt/live/${restore_app_domain}/fullchain.pem /etc/ssl/certs/${restore_app_domain}.pem
  558. else
  559. # Ensure that the bundled SSL cert is being used
  560. if [ -f /etc/ssl/certs/${restore_app_domain}.bundle.crt ]; then
  561. sed -i "s|${restore_app_domain}.crt|${restore_app_domain}.bundle.crt|g" /etc/nginx/sites-available/${restore_app_domain}
  562. fi
  563. fi
  564. fi
  565. fi
  566. fi
  567. fi
  568. }
  569. function valid_backup_destination {
  570. # used to check whether any additional backup directories clash with
  571. # exiting apps
  572. destination_dir="$1"
  573. is_valid="yes"
  574. available_variants_list=()
  575. available_system_variants
  576. item_in_array "${destination_dir}" "${available_variants_list[@]}"
  577. if [[ $? != 0 ]]; then
  578. is_valid="no"
  579. fi
  580. echo $is_valid
  581. }
  582. function backup_extra_directories {
  583. if [ ! -f $BACKUP_EXTRA_DIRECTORIES ]; then
  584. return
  585. fi
  586. backup_type="$1"
  587. echo $"Backing up some additional directories"
  588. while read backup_line
  589. do
  590. backup_dir=$(echo "$backup_line" | awk -F ',' '{print $1}' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
  591. if [ -d "$backup_dir" ]; then
  592. destination_dir=$(echo "$backup_line" | awk -F ',' '{print $2}' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
  593. if [[ $(valid_backup_destination "$destination_dir") == "yes" ]]; then
  594. if [[ $backup_type == "local" ]]; then
  595. backup_directory_to_usb "$backup_dir" "$destination_dir"
  596. else
  597. backup_directory_to_friend "$backup_dir" "$destination_dir"
  598. fi
  599. else
  600. echo $"WARNING: The backup directory $destination_dir is already used."
  601. echo $"Choose a different destination name for backing up $backup_dir"
  602. fi
  603. else
  604. echo $"WARNING: Directory $backup_dir does not exist"
  605. fi
  606. done <$BACKUP_EXTRA_DIRECTORIES
  607. }
  608. # NOTE: deliberately no exit 0