· 7 years ago · Mar 01, 2018, 06:14 AM
1#!/usr/bin/ruby
2
3require 'rubygems'
4require 'fileutils'
5require 'active_support'
6
7role :db, "192.168.2.2",
8 "192.168.3.2",
9 "192.168.4.2",
10 "192.168.5.2",
11 "192.168.7.2",
12 "192.168.9.2",
13 "192.168.10.2",
14 "192.168.11.2",
15 "192.168.12.2",
16 "192.168.13.2",
17 "192.168.14.2",
18 "192.168.15.2",
19 "192.168.16.2",
20 "192.168.17.2",
21 "192.168.18.2",
22 "192.168.19.2",
23 "192.168.20.2",
24 "192.168.21.2",
25 "192.168.22.2",
26 "192.168.23.2",
27 "192.168.24.2",
28 "192.168.1.2"
29
30role :flyspray, "192.168.1.3"
31
32# role :db, "192.168.1.12"
33
34set :user, "root"
35
36set :application, 'BTB'
37set :dbname, 'xxxxxxx'
38set :dbpass, 'xxxxxxx'
39set :date, Time.now.strftime('%Y-%m-%d.%A')
40
41set :sync_script, '/usr/local/bin/sync_backups'
42set :sync_script_error_log, '/tmp/sync_backups.err'
43set :sync_times, '0 22,23,0,1,2,3 * * *' # runs a few times at night
44
45set :backup_script, '/usr/local/bin/run_backups'
46set :backup_script_error_log, '/tmp/run_backups.err'
47set :backup_mysql_times, '0 1 * * *'
48set :backup_btb_times, '5 1 * * *'
49
50# set :backup_server, '192.168.253.2' # zeus
51set :backup_server, '192.168.253.3' # mercury
52set :backup_folder, '/backups'
53set :crontab_file, '/etc/crontab'
54set :crontab_user, 'root ' # NOTE: This must be set to 'root ' (notice the space) ONLY if using /etc/crontab
55
56# All this method does is log into the remote host and dump the database out to the /backups folder
57desc "Backup all of the databases"
58task :request_backups, :roles => :db do
59 filename = "#{backup_folder}/#{application}_#{date}.sql.bz2"
60
61 on_rollback { delete filename }
62
63 run "mysqldump -u#{dbname} -p#{dbpass} BTB | bzip2 -c > #{filename}" do |ch, stream, out|
64 ch.send_data "#{dbpass}\n" if out =~ /^Enter password:/
65 end
66end
67
68desc "Sets up backup environment AND enables it in cron"
69task :install_backups do
70 setup_backups
71 enable_backups
72end
73
74# This task will ensure the mirrored folder is working on all of the remote hosts, by making
75# the folder and creating the script that calls the rsync backup command and add crontab entry
76desc "Builds setup scripts"
77task :setup_backups do
78 run "mkdir -p #{backup_folder}"
79
80 put "Put files here to be copied up to the master backup server. (currently mercury)", "#{backup_folder}/README"
81
82 # This script will exit out if it is already running
83 file = <<-FILE
84 #!/bin/bash
85
86 PID_FILE=/var/run/`basename $0`.pid
87 BACKUP_SERVER=#{backup_server}
88
89 if [ -f $PID_FILE ]
90 then
91 LAST_PID=`cat $PID_FILE`
92 if kill -0 $LAST_PID 2> /dev/null
93 then
94 echo "Already running ($LAST_PID)"
95 exit 0
96 else
97 echo $$ > $PID_FILE
98 fi
99 else
100 echo $$ > $PID_FILE
101 fi
102
103 LOCAL_SERVER=`grep -m 1 'address' /etc/network/interfaces | cut -d ' ' -f 2`
104 if [ $LOCAL_SERVER ]
105 then
106 rsync -az -e ssh $1 --delete --partial #{backup_folder}/ #{backup_server}:#{backup_folder}/$LOCAL_SERVER
107 else
108 echo "Couldn't determine IP address"
109 rm $PID_FILE
110 exit 1
111 fi
112
113 rm $PID_FILE
114 FILE
115
116 put file, sync_script, :mode => 700
117
118 file = <<-FILE
119 #!/bin/bash
120
121 mkdir -p /backups/$1/weekly
122 mkdir -p /backups/$1/monthly
123 mkdir -p /backups/$1/daily
124
125 BACKUP_FOLDER="/backups/$1"
126 DBLOGIN="#{dbname}"
127 DBPASS="#{dbpass}"
128
129 # This will take a weekly backup every monday, but will still do it on tuesday if it misses it on monday for some reason
130 if ls -l --time-style='+%s' $BACKUP_FOLDER/weekly/ | gawk '{if ($6 > last_modified) exit 1}' last_modified=`date +%s -d 'last monday 0:00'`
131 then
132 NEEDS_WEEKLY=true
133 else
134 NEEDS_WEEKLY=false
135 fi
136
137 # Same here, it will take a backup on the first of the month, and continue trying on consecutive days until one is made
138 if ls -l --time-style='+%s' $BACKUP_FOLDER/monthly/ | gawk '{if ($6 > last_modified) exit 1}' last_modified=`date +%s -d "$(( 10\#$(date +%d) - 1 )) days ago 0:00"`
139 then
140 NEEDS_MONTHLY=true
141 else
142 NEEDS_MONTHLY=false
143 fi
144
145 MONTHLY_FILENAME="$1_`date '+%Y-%m-%d.%b'`.sql.bz2"
146 WEEKLY_FILENAME="$1_`date '+%Y-%m-%d.%V'`.sql.bz2"
147 DAILY_FILENAME="$1_`date '+%Y-%m-%d.%A'`.sql.bz2"
148
149 MYSQL_DUMP="mysqldump -u$DBLOGIN -p$DBPASS $1"
150
151 if $NEEDS_MONTHLY && $NEEDS_WEEKLY; then
152 # Put the real file in monthly, link to in weekly and daily
153 cd $BACKUP_FOLDER/monthly
154 $MYSQL_DUMP | bzip2 -c > $MONTHLY_FILENAME
155 cd $BACKUP_FOLDER/weekly
156 ln -s ../monthly/$MONTHLY_FILENAME ./$WEEKLY_FILENAME
157 cd $BACKUP_FOLDER/daily
158 ln -s ../monthly/$MONTHLY_FILENAME ./$DAILY_FILENAME
159 elif $NEEDS_MONTHLY; then
160 # Put the real file in monthly, link to in daily
161 cd $BACKUP_FOLDER/monthly
162 $MYSQL_DUMP | bzip2 -c > $MONTHLY_FILENAME
163 cd $BACKUP_FOLDER/daily
164 ln -s ../monthly/$MONTHLY_FILENAME ./$DAILY_FILENAME
165 elif $NEEDS_WEEKLY; then
166 # Put the real file in weekly, link to in daily
167 cd $BACKUP_FOLDER/weekly
168 $MYSQL_DUMP | bzip2 -c > $WEEKLY_FILENAME
169 cd $BACKUP_FOLDER/daily
170 ln -s ../weekly/$WEEKLY_FILENAME ./$DAILY_FILENAME
171 else
172 # Put the real file in daily
173 cd $BACKUP_FOLDER/daily
174 $MYSQL_DUMP | bzip2 -c > $DAILY_FILENAME
175 fi
176
177 # delete old files
178 # 1 year ago
179 find $BACKUP_FOLDER/monthly -daystart -mtime +365 -exec rm {} \\;
180 # 1 month ago
181 find $BACKUP_FOLDER/weekly -daystart -mtime +31 -exec rm {} \\;
182 # 7 days ago
183 find $BACKUP_FOLDER/daily -daystart -mtime +7 -exec rm {} \\;
184 FILE
185
186 put file, backup_script, :mode => 700
187end
188
189# This will disable syncing with the master server, backups may still be "requested" but no upload will occur
190task :disable_backups do
191 sync_script_file = sync_script.match(/[a-z\._]+$/)[0] # avoids backslashes
192
193 run <<-CMD
194 sed -i -e '/^.*#{sync_script_file}.*$/d' #{crontab_file}
195 CMD
196
197 backup_script_file = backup_script.match(/[a-z\._]+$/)[0] # avoids backslashes
198
199 run <<-CMD
200 sed -i -e '/^.*#{backup_script_file}.*$/d' #{crontab_file}
201 CMD
202end
203
204# Add's crontab entries
205task :enable_backups do
206 enable_btb_backups
207 enable_flyspray_backups
208end
209
210task :enable_btb_backups, :roles => :db do
211 run <<-CMD
212 echo "#{sync_times} #{crontab_user}#{sync_script} > #{sync_script_error_log} 2>&1" >> #{crontab_file}
213 CMD
214
215 run <<-CMD
216 echo "#{backup_btb_times} #{crontab_user}#{backup_script} BTB >> #{backup_script_error_log} 2>&1" >> #{crontab_file}
217 CMD
218
219 run <<-CMD
220 echo "#{backup_mysql_times} #{crontab_user}#{backup_script} mysql >> #{backup_script_error_log} 2>&1" >> #{crontab_file}
221 CMD
222end
223
224task :enable_flyspray_backups, :roles => :flyspray do
225 run <<-CMD
226 echo "#{sync_times} #{crontab_user}#{sync_script} > #{sync_script_error_log} 2>&1" >> #{crontab_file}
227 CMD
228
229 run <<-CMD
230 echo "#{backup_mysql_times} #{crontab_user}#{backup_script} mysql >> #{backup_script_error_log} 2>&1" >> #{crontab_file}
231 CMD
232
233 run <<-CMD
234 echo "#{backup_mysql_times} #{crontab_user}#{backup_script} flyspraynew >> #{backup_script_error_log} 2>&1" >> #{crontab_file}
235 CMD
236end
237
238task :show_addresses, :roles => :db do
239 run "grep 'address' /etc/network/interfaces | cut -d ' ' -f 2" do |ch,stream, out|
240 print "#{ch[:host]}: #{out.chomp}\n"
241 end
242end
243
244# Sometimes the backups get all clogged up
245task :kill_backups, :roles => :db do
246 run <<-CMD
247 killall rsync
248 CMD
249end
250
251task :test_restore, :roles => :db do
252 daily_dir = "#{backup_folder}/BTB/daily"
253 run "ls -ltrh #{daily_dir} | tail -n 1"
254end
255
256task :restore, :roles => :db do
257 daily_dir = "#{backup_folder}/BTB/daily"
258 run "ls -trw1 #{daily_dir} | tail -n 1"
259
260 print "Press any key to load these backup files. (WARNING! DATA MAY BE LOST!)"
261 STDIN.getc
262
263 run "bzcat #{daily_dir}/`ls -trw1 #{daily_dir} | tail -n 1` | mysql -u#{dbname} -p#{dbpass} BTB"
264end
265
266# This is a one-time task I use to tweak stuff
267task :fix_initialization, :roles => :db do
268# run 'rm /backups/*.sql.bz2'
269 run '/usr/local/bin/sync_backups -n' # will just output what WOULD be done
270# run 'ls -Rl /backups'
271
272# run "#{sync_script}" do |ch, stream, out|
273# run "ssh 192.168.253.3 'echo test'" do |ch, stream, out|
274# # Test if SSH is working, will return data for hosts that aren't set up with the RSA key
275# print "#{ch[:host]}: #{out.chomp}\n"
276# ch.send_data "yes\n" if out =~ /continue/i # Some just need mercury added to their known hosts
277# end
278end