-
Notifications
You must be signed in to change notification settings - Fork 2
/
backup_websites
executable file
·173 lines (152 loc) · 7.7 KB
/
backup_websites
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/bin/bash
# websites Backup Script
# script to copy config, websites and db's of a webserver
# Copyright (C) 2014-2015 Alexander Swen <alex@swen.nu>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# croninfo:
# MAILTO=alex@swen.nu
# 0 1 * * * root /netwerk/scripts/backup_websites >> /var/log/backup_websites.log 2>&1
# Alexander Swen
# Private contact: alex@swen.nu
# CHANGELOG:
# 2010-10-21 A.Swen copied from backup_zimbra
# SETTINGS
date=$(date +%Y%m%d)
me=$(basename $0)
mydir=$(dirname $0)
mysql_user=root
MYSQLDUMP=`which mysqldump`
MYSQLSHOW=`which mysqlshow`
website_dir=/var/www
# bck_rot should be the mountpoint of a separate volume where we write backups to. I recommend to use some kind of remote volume for this (either NFS or ISCSI). That is to make sure that whenever you need to restore the complete install of your mailserver you don't have to care about this volume as long as it is not mounted and whenever you want to test a restore on some other box (which is HIGHLY recommended!!!) you simply umount and mount the iscsi volume or even simpler only mount the nfs volume on the testbox.
bck_root=/website_backups #Warning: keep this only one dir deep as I don't know how to tell awk to ignore more slashes in the search
# with the var below we create 7 daily backupdirs so we have can go back any day last week.
bck_dir=/${bck_root}/daily-$(date +%w)
# we create a tbz2 archive of the daily-6 dir every Saturday morning
bck_dir_2=/${bck_root}/weekly
# this long I want to keep versions of the complete weekly tarballs
keepdays=30
# ISCSI SETTINGS
# ISCSI and LVM config (I Used lvm on Iscsi to be able to attach and resize the volume while the mailserver keeps running)
# If you don't use ISCSI please set var ISCSI to something else then on. Otherwise this script fails trying to enable ISCSI
ISCSI=on
iscsi_volume="192.168.4.4:3260,1 cider:website.backups"
vgname=vg_website_backups
lvname=lv_website_backups
vol_label=website_backups
# remote RSYNC settings
remote_rsync=off
remote_rsync_host=
remote_rsync_port=
remote_rsync_user=root
remote_rsync_id_file=/root/.ssh/id_rsa
remote_rsync_dir=/data/backups/zimbra
# FUNCTIONS
die () {
rc=$1
shift
echo "========================================================================" >&2
echo "==== FATAL ERROR ====" >&2
echo "========================================================================" >&2
echo "" >&2
echo $@ >&2
exit $rc
}
# SCRIPT
echo $(date) started ${me}...
[ ${UID} -gt 0 ] && die 1 only root may do that
[ -d ${bck_dir} ] || install -dm 770 -o root -g root ${bck_dir}
[ -d ${bck_dir_2} ] || install -dm 770 -o root -g root ${bck_dir_2}
echo ""
echo "Since we have an external volume to write backups to we need to verify its mount status"
if [ "$(mount|grep "${bck_root}")" = "" ];then
echo "mountpoint ${bck_root} not mounted..."
if [ "${ISCSI}" = "on" ];then
echo "ISCSI seems to be turned on so we first check whether ISCSI volume is available"
[ "$(chkconfig --list|awk '/iscsid/ {print $5}')" != "3:on" ] && chkconfig iscsid on
[ "$(service iscsid status|awk '/iscsid/ && /running/ {print $5}')" != "running..." ] && service iscsi start
iscsiinfo="$(iscsiadm -m node show)"
[ "${iscsiinfo}" != "${iscsi_volume}" ] && die 2 "ISCSI volume not available"
echo "check ISCSI: ${isciinfo} OK"
fi
echo "checking LV state"
[ "$(lvscan|awk -v vg=${vgname} -v lv=${lvname} '/vg/ && /lv/ {print $1}')" != "ACTIVE" ] && lvchange -a y ${vgname} || echo "LVstate active"
[ "$(blkid|grep ${vol_label})" = "" ] && die 3 "After checking ISCSI and LVM there is still no volume available that has label ${vol_label}"
[ "$(awk -v mp=${bck_root} -v label=${vol_label} '/mp/ && /label/ {print}')" = "" ] && echo "LABEL=zimbra_backups /zimbra_backups ext3 defaults 0 0" >> /etc/fstab
echo "now we try to mount the bckroot ${bck_root}"
[ -d ${bck_root} ] && mount ${bck_root} || die 3 "Mount ${bck_root} failed"
echo "As above output might already suggested I tried to (re-)mount the iscsi volume. I did al I can. Hope it works, at least I continue this script now...."
else
echo "mountpoint ${bck_root} seems to be mounted OK..."
df -m ${bck_root}
fi
echo ""
echo "checking free disk space"
website_dir_sz=$(du -sm ${website_dir}|awk '{print $1}')
today_bck_sz=$([ -d ${bck_dir} ] && du -sm ${bck_dir}|awk '{print $1}' || echo 0)
bck_root_free=$(df -m ${bck_root}|awk '/\'$bck_root'/ {print $3} ' ) # vi doesn't always understand quotes and brackets )
if [ $(date +%w) -eq 6 ];then
# on Saturday we want the difference between last weeks backup and todays zimbra dir size + the size of the biggest weekly tarball (as we might expect we make one of at least that size) + 1024M margin for growth, free on the bckdir.
biggest_tbz2_sz=$(ls -lrS --block-size=1048576 ${bck_dir_2}/*.tbz2|tail -1|awk '{print $5}')
minimal_free=$((website_dir_sz-today_bck_sz+biggest_tbz2_sz+1024))
else
# The rest of the week we just accept a free space as big as the difference between last weeks backup and todays zimbra dir size
minimal_free=$((website_dir_sz-today_bck_sz))
fi
cat << EOF
Websitedir = ${website_dir_sz}Mb
Todays backupdirsize = ${today_bck_sz}Mb
minimal free = ${minimal_free}Mb
Backupdir ${bck_root} has ${bck_root_free}Mb free
EOF
[ ${minimal_free} -gt ${bck_root_free} ]&& die 4 not enough free diskspace on ${bck_root} to perform backup
# Outputs the time the backup started, for log/tracking purposes
before="$(date +%s)"
echo ""
echo $(date +%T) rsync backup started...
rsync -avzHK --delete --exclude=*.pid ${website_dir} ${bck_dir}
rsync -avzHK --delete --exclude=*.pid /etc ${bck_dir}
# create mysql backups
[ -d ${bck_dir}/mysql ] || install -dm 770 -o root -g root ${bck_dir}/mysql
${MYSQLSHOW} |egrep -v "Databases|\-\-\-\-\-\-\-|lost+found"|sed -e 's/|//g'|while read db;do
echo "backup ${db}..."
${MYSQLDUMP} -u ${mysql_user} ${db} > ${bck_root}/mysql/${date}-${db}.sql
done
echo "$(date +%T) Cleaning up daily mysqlbackups older than ${keepdays} days..."
find ${bck_root}/mysql -type f -mtime +${keepdays} -delete
# Create archive of backed-up directory for offsite transfer
if [ $(date +%w) -eq 6 ];then
echo ""
echo "$(date +%T) Creating weekly tbz2 ..."
tar jcf ${bck_dir_2}/${date}-$(hostname).tbz2 -C ${bck_dir} .
tar jcvf ${bck_dir_2}/${date}-ispconfig.tbz2 -C /usr/local ispconfig
echo "$(date +%T) Cleaning up weekly backups older than ${keepdays} days..."
find ${bck_dir_2} -type f -mtime +${keepdays} -delete
fi
# Transfer file to external backup server
if [ "${remote_rsync}" = "on" ];then
echo "rsync ${bck_dir} to ${remote_rsync_host}:${remote_rsync_dir}"
rsync -avzHK -e "ssh -p${remote_rsync_port} -l ${remote_rsync_user} -i ${remote_rsync_id_file}" --delete --exclude=*.pid ${bck_dir} ${remote_rsync_host}:${remote_rsync_dir}
fi
# Outputs the time the backup finished
echo ""
echo $(date +%T) Backup finished
# Calculates and outputs total time taken
after="$(date +%s)"
elapsed="$(expr $after - $before)"
hours=$(($elapsed / 3600))
elapsed=$(($elapsed - $hours * 3600))
minutes=$(($elapsed / 60))
seconds=$(($elapsed - $minutes * 60))
echo Time taken: "$hours hours $minutes minutes $seconds seconds"
# END