gat 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. data/History.txt +84 -0
  2. data/PostInstall.txt +22 -0
  3. data/README.txt +49 -0
  4. data/Rakefile +12 -0
  5. data/bin/gat +15 -0
  6. data/lib/gat.rb +323 -0
  7. data/lib/gat/action/base.rb +197 -0
  8. data/lib/gat/action/ruby_method.rb +35 -0
  9. data/lib/gat/action/shell_command.rb +185 -0
  10. data/lib/gat/boot.rb +63 -0
  11. data/lib/gat/checks.rb +136 -0
  12. data/lib/gat/debug.rb +29 -0
  13. data/lib/gat/dependence/argument.rb +62 -0
  14. data/lib/gat/dependence/base.rb +54 -0
  15. data/lib/gat/dependence/folder.rb +104 -0
  16. data/lib/gat/dependence/program.rb +36 -0
  17. data/lib/gat/email.rb +80 -0
  18. data/lib/gat/exceptions.rb +163 -0
  19. data/lib/gat/extends.rb +102 -0
  20. data/lib/gat/help.rb +79 -0
  21. data/lib/gat/interpreter.rb +93 -0
  22. data/lib/gat/launcher.rb +100 -0
  23. data/lib/gat/logger.rb +331 -0
  24. data/lib/gat/operation.rb +253 -0
  25. data/lib/gat/version.rb +20 -0
  26. data/lib/gatgets/dar_backup/dar_backup.rb +367 -0
  27. data/lib/gatgets/dar_backup/dar_backup.yml +387 -0
  28. data/lib/gatgets/dar_backup/launcher.rb +44 -0
  29. data/lib/gatgets/dar_backup/templates/list_backups.erb +31 -0
  30. data/lib/gatgets/dar_backup/templates/search.erb +33 -0
  31. data/lib/gatgets/gatgets_manager/gatgets_manager.rb +65 -0
  32. data/lib/gatgets/gatgets_manager/gatgets_manager.yml +71 -0
  33. data/lib/gatgets/gatgets_manager/templates/list.erb +9 -0
  34. data/lib/gatgets/synchronization/README +26 -0
  35. data/lib/gatgets/synchronization/launcher.rb +20 -0
  36. data/lib/gatgets/synchronization/launcher_cron.sh +69 -0
  37. data/lib/gatgets/synchronization/synchronization.rb +123 -0
  38. data/lib/gatgets/synchronization/synchronization.yml +144 -0
  39. data/test/test_gat.rb +36 -0
  40. data/test/test_helper.rb +3 -0
  41. metadata +131 -0
@@ -0,0 +1,20 @@
1
+ =begin
2
+ This file is part of GAT: http://gat.rubyforge.org
3
+
4
+ (c) 2008-2009 A.C. Gnoxys info@gnoxys.net
5
+
6
+ GAT (Gnoxys Administration Tools) is released under the GPL License 3 or higher.
7
+ You can get a copy of the license easily at http://www.gnu.org/licenses/gpl.html.
8
+
9
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
10
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
12
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
13
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
14
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
15
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
+ =end
17
+
18
+ module Gat
19
+ VERSION = '0.2.8'
20
+ end
@@ -0,0 +1,367 @@
1
+ =begin
2
+ This file is part of GAT: http://gat.rubyforge.org
3
+
4
+ (c) 2008-2009 A.C. Gnoxys info@gnoxys.net
5
+
6
+ GAT (Gnoxys Administration Tools) is released under the GPL License 3 or higher.
7
+ You can get a copy of the license easily at http://www.gnu.org/licenses/gpl.html.
8
+
9
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
10
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
12
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
13
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
14
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
15
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
+ =end
17
+
18
+ require 'gat'
19
+
20
+ GATGET_DAR_BACKUP_ROOT = File.expand_path(File.dirname(__FILE__))
21
+
22
+ class GatgetDarBackup < Gat::Base
23
+
24
+
25
+ # helpers
26
+ def set_flag_mysql_dumps
27
+ set_flag("active_mysql_dumps", get_dependence_value("static", "mysql_dumps"))
28
+ end
29
+
30
+ def set_flag_catalog_exists
31
+ catalog_name = "bbdd_#{ self.config['server_name'] || 'backup' }"
32
+ set_dependence_variable("catalog_name", catalog_name)
33
+ set_dependence_variable("catalog_path", "#{ get_dependence_value("folders", "backups_folder_catalog") }/#{ catalog_name }")
34
+ set_flag("catalog_exists", File.exists?(get_dependence_variable("catalog_path")))
35
+ end
36
+
37
+ # get all the system backups and catalogs backups
38
+ def get_all_backups
39
+ get_system_backups
40
+ get_catalog_backups
41
+ end
42
+
43
+ # We are going to set the backups variables. Which ones must be deleted and the name of the current backup
44
+ def set_do_backup_variables
45
+ # if we dont have a backup
46
+ if not get_current_complete_backup
47
+
48
+ # * perform a complet backup
49
+ # * set the minimum space required at 1 kb
50
+ # * mark backups to delete, if nothing to delete,system will get it
51
+ # * create new dir and link it to current through new_link_current flag
52
+
53
+ set_variables_to_complete_backup
54
+ set_dependence_variable("last_backup_size", 1)
55
+ set_backups_to_delete
56
+ set_flag("delete_old_backups", true)
57
+ set_flag("new_complete_folder", true)
58
+
59
+ # if we have a complet backup but today is complet
60
+ elsif get_dependence_value("static", "complet_backup_days").include?(Date.today.wday)
61
+
62
+ # * perform a complet backup
63
+ # * get the last size of complet backup
64
+ # * identify backups to delete and mark delete flag
65
+ # * mark delete current link
66
+ # * create new dir and link it to current through new_link_current flag
67
+
68
+ set_variables_to_complete_backup
69
+ set_dependence_variable("last_backup_size", get_last_backup_size('complet'))
70
+ set_backups_to_delete
71
+ set_flag("delete_old_backups", true)
72
+ set_flag("delete_current_link", true)
73
+ set_flag("new_complete_folder", true)
74
+
75
+ # else, we must do a diff backup, do
76
+ else
77
+ # * perform diff backup
78
+ # * dont care about delete or new dirs... etc..
79
+ # * get the last size of diff backup
80
+ set_variables_to_diff_backup
81
+ set_dependence_variable("last_backup_size", get_last_backup_size('diff'))
82
+ end
83
+ end
84
+
85
+ def exists_backup_file
86
+ get_system_backups
87
+ backup_folder = get_dependence_value("folders", "backups_folder_data_local")
88
+ backup_dar_name = get_dependence_value("arguments", "backup_dar_name")
89
+ backups_with_dar_name = get_dependence_variable("system_backups").select { |b| b['dar_name'] == backup_dar_name }
90
+ if backups_with_dar_name.empty?
91
+ self.logger.log("direct", "action_result", "\n ERROR: Backup dar name #{ backup_dar_name } not found\n\n Type $> #{ $0 } list_backups to see avalaibles backups\n\n")
92
+ set_flag("exists_backup_file", false)
93
+ else
94
+ backup = backups_with_dar_name.first
95
+ set_dependence_variable("backup_to_show_content", "#{ backup['folder'] }/#{ backup['dar_name']}")
96
+ set_flag("exists_backup_file", true)
97
+ end
98
+
99
+ end
100
+
101
+ # ruby methods
102
+ def list_backups_data
103
+ end
104
+
105
+ def show_nice_search
106
+ get_catalog_backups
107
+ end
108
+
109
+ # We need to have enough space to do backup
110
+ def check_enough_space_for_backup
111
+
112
+ last_backup_size = get_dependence_variable("last_backup_size")
113
+ backup_folder = get_dependence_value("folders", "backups_folder_data_local")
114
+ thresold = get_dependence_value("static", "space_thresold").to_i * 1024 * 1024 # to Bytes
115
+ # check it
116
+ if not check_enough_space({'where' => backup_folder, 'space_needed' => last_backup_size}) and not check_enough_space({'where' => backup_folder, 'space_needed' => thresold})
117
+ raise Gat::GatgetProcessException.new("System doesnt have enough space", "check_enough_space_for_backup")
118
+ end
119
+ end
120
+
121
+ # failed action launch_backup_rescue callback
122
+ # Dar, when the backup is so big, usually end with a 2 status, that means some files changed during backup operations. That
123
+ # is normal while is working over logs, mysql, etc...
124
+ # So, we have to discriminate what the non zero exit status means.
125
+ def launch_backup_rescue
126
+ # get the backup action
127
+ launch_backup = Gat::Action::Base.get_current_action
128
+
129
+ # Exit level 4 but with callback to delete backup
130
+ if launch_backup.exit_level == 4 and launch_backup.output.include?('No space left on device, you have the opportunity to make room now')
131
+ # disk is full, mark bad backup flag that will delete current backup
132
+ self.logger.log('trace', 'onfail_launch_backup_rescue', 'Disk is full, delete current backup')
133
+
134
+ delete_action = Gat::Action::ShellCommand.new('delete_bad_backup', get_element_config('actions', 'delete_bad_backup'), self.operation)
135
+ delete_action.execute
136
+
137
+ if delete_action.exit_level == 0
138
+ launch_backup.onfail_message = "Dar backup collapse disk, but backup was deleted"
139
+ else
140
+ launch_backup.onfail_message = "Dar backup collapse disk and backup WASNT DELETED."
141
+ end
142
+
143
+ # mark action to abort
144
+ launch_backup.onfail = 'abort'
145
+
146
+ # 4 exit level always means problems
147
+ elsif launch_backup.exit_level == 4 or launch_backup.exit_level == 2
148
+ # mark action to abort
149
+ launch_backup.onfail = 'abort'
150
+ end
151
+ end
152
+
153
+ # send rescue email will send a email for notification errors at do_backup operation
154
+ def onfail
155
+
156
+ unless self.config['email_config']
157
+ raise Gat::GatgetConfigException.new("Default email config is empty at gatget.config['email_config']", "run_output_email")
158
+ end
159
+
160
+ email_subject = "[GAT] [#{ self.class.name }] [#{ self.operation.name.camelize }] [FAILED]"
161
+
162
+
163
+ email_body = "Gatget #{ self.class.name } was stopped by raising of #{ self.onfail_error.class } at #{ Time.now }\n\n"
164
+ email_body << "#{ onfail_error.exit_error }"
165
+ email_body << "\n\n Errors log: \n\n #{self.logger.entries.select{ |e| e.global_type == 'error' }.map{ |e| e.inspect }.join("\n") }\n\n"
166
+ email_body << "\n\n Warning log: \n\n #{self.logger.entries.select{ |e| e.global_type == 'warning' }.map{ |e| e.inspect }.join("\n") }\n\n"
167
+ email_body << "\n\n Whole log: \n\n #{self.logger.entries.map{ |e| e.inspect }.join("\n") }"
168
+
169
+ self.create_and_deliver_email(self.config['email_config']['send_to'], { 'subject' => email_subject, 'body' => email_body }, self.config['email_config'])
170
+
171
+ end
172
+
173
+ # nothing to delete if catalog is empty
174
+ def catalog_is_empty
175
+ set_flag("catalog_is_not_empty", get_dependence_variable("catalog_backups").any?)
176
+ end
177
+
178
+ def print_status
179
+ if check_i_am_running
180
+ ret = "running"
181
+ else
182
+ ret = "not running"
183
+ end
184
+ puts ret
185
+ Gat::Action::Base.get_current_action.output = ret
186
+ end
187
+
188
+ private
189
+ def get_system_backups
190
+ backup_entries = []
191
+ local_data_folder = get_dependence_value("folders", "backups_folder_data_local")
192
+
193
+ # get the current folder
194
+ current_folder = nil
195
+ if File.exists?("#{ local_data_folder }/current")
196
+ # on some S.O, readlink return folder with last slash. remove it anyway.
197
+ current_folder = File.readlink("#{ local_data_folder }/current").gsub(/\//,'')
198
+ end
199
+
200
+ (Dir.entries(local_data_folder) - ['current', '.', '..']).each do |backup_folder|
201
+ backup_folder_path = "#{ local_data_folder }/#{ backup_folder }"
202
+ (Dir.entries(backup_folder_path) - ['..', '.' ]).each do |backup_file|
203
+ backup_entries << { 'type' => backup_file.include?('complet') ? 'complet' : 'diff',
204
+ 'name' => backup_file,
205
+ 'path' => "#{ local_data_folder }/#{ backup_folder }/#{ backup_file }",
206
+ 'dar_name'=> backup_file.split('.').first,
207
+ 'isolate' => backup_file.include?('isolate'),
208
+ 'folder' => backup_folder,
209
+ 'current' => backup_folder == current_folder }
210
+ end
211
+ end
212
+ set_dependence_variable("system_backups", backup_entries)
213
+ end
214
+
215
+ def get_catalog_backups
216
+ backup_entries = []
217
+ # define a new action to get all the catalogs in database
218
+ action = Gat::Action::ShellCommand.new('identify_all_backups_in_catalog', get_element_config('actions', 'identify_backups_in_catalog'), self.operation)
219
+ action.execute
220
+
221
+ backup_in_catalog = action.output
222
+ backup_in_catalog.each_line do |line|
223
+ if line.include?('complet') or line.include?('diff')
224
+ line = line.strip
225
+ backup_entries << { 'type' => line.include?('complet') ? 'complet' : 'diff',
226
+ 'dar_name'=> line.split(' ')[2],
227
+ 'id' => line.split(' ')[0],
228
+ 'folder' => line.split(' ')[1] }
229
+ end
230
+ end
231
+ set_dependence_variable("catalog_backups", backup_entries)
232
+ end
233
+
234
+ def get_current_complete_backup
235
+ stored_backups = get_dependence_variable("system_backups")
236
+
237
+ # select complete and current
238
+ complet_and_current = stored_backups.select { |backup| backup['type'] == 'complet' and backup['current'] and !backup['isolate']}
239
+ if complet_and_current.empty?
240
+ complet_backup_file = false
241
+ else
242
+ set_dependence_variable("backup_complet_folder", complet_and_current.first['folder'] )
243
+ set_dependence_variable("backup_complet_file", complet_and_current.first['name'].split('.').first)
244
+ complet_backup_file = true
245
+ end
246
+ complet_backup_file
247
+ end
248
+
249
+ def set_variables_to_complete_backup
250
+ backups_folder = get_dependence_value("folders", "backups_folder_data_local")
251
+ backup_folder = "#{ Date.today }"
252
+ backup_name = "#{ Date.today }_#{ self.config['server_name'] || 'backup' }_complet"
253
+ backup_path = "#{ backups_folder }/#{ backup_folder }/#{ backup_name }"
254
+ # set the variables
255
+ set_dependence_variable("backup_launch_argument", "-c #{ backup_path }")
256
+ set_dependence_variable("backup_folder", backup_folder)
257
+ set_dependence_variable("backup_name", backup_name)
258
+ set_dependence_variable("backup_path", backup_path)
259
+ end
260
+
261
+ def set_variables_to_diff_backup
262
+ backups_folder = get_dependence_value("folders", "backups_folder_data_local")
263
+ backup_folder = get_dependence_variable("backup_complet_folder")
264
+ backup_name = "#{ Date.today }_#{ self.config['server_name'] || 'backup' }_diff"
265
+ backup_path = "#{ backups_folder }/#{ backup_folder }/#{ backup_name }"
266
+ backup_complet = "#{ backups_folder }/#{ backup_folder }/#{ get_dependence_variable("backup_complet_file") }"
267
+ # set the variables
268
+ set_dependence_variable("backup_launch_argument", "-c #{ backup_path } -A #{ backup_complet }")
269
+ set_dependence_variable("backup_folder", backup_folder)
270
+ set_dependence_variable("backup_name", backup_name)
271
+ set_dependence_variable("backup_path", backup_path)
272
+ end
273
+
274
+ def set_backups_to_delete
275
+ folders_backups_to_delete = []
276
+ catalog_backups_to_delete = []
277
+ number_stored_backups = get_dependence_value("static", "number_backup_stored")
278
+ stored_entries = Dir.entries(get_dependence_value("folders", "backups_folder_data_local")) - [".","..","current"]
279
+ catalog_backups = get_dependence_variable("catalog_backups")
280
+ (stored_entries.sort.reverse[number_stored_backups..stored_entries.size] || []).each do |backup|
281
+ folders_backups_to_delete << backup
282
+ cbtd = catalog_backups.select { |b| b['folder'] == "#{ get_dependence_value("folders", "backups_folder_data_local") }/#{ backup }" }
283
+ if cbtd.any?
284
+ catalog_backups_to_delete << cbtd
285
+ end
286
+ end
287
+ # set dependence_variable to delete system folders
288
+ set_dependence_variable("backup_folders_to_delete", folders_backups_to_delete)
289
+
290
+ # anyway, need to delete?
291
+ set_flag("delete_system_backups_if_any", folders_backups_to_delete.any?)
292
+
293
+ # set depedendece variable to delete catalog files
294
+ set_dependence_variable("backup_catalog_to_delete", catalog_backups_to_delete.flatten.uniq.map{ |b| '1' })
295
+ # any way, need to delete?
296
+ set_flag("delete_catalog_backups_if_any", catalog_backups_to_delete.any?)
297
+
298
+ end
299
+
300
+ def get_last_backup_size(backup_type)
301
+ size = 0
302
+ system_backups = get_dependence_variable("system_backups")
303
+ if backup_type == 'complet'
304
+ complet_and_current = system_backups.select { |backup| backup['type'] == 'complet' and backup['current']}
305
+ complet_and_current.each do |backup_entry|
306
+ size += File.size("#{ get_dependence_value("folders","backups_folder_data_local") }/current/#{ backup_entry['name'] }")
307
+ end
308
+ elsif backup_type == 'diff'
309
+ # get the last diff backups
310
+ last_diff_backups = system_backups.select{ |backup| backup['type'] == 'diff' and not backup['isolate'] }
311
+ # select all the backup files with the same dar_name and calculate size if we have a last_diff_backup
312
+ if last_diff_backups and last_diff_backups.any?
313
+ system_backups.select { |backup| backup['dar_name'] == last_diff_backups.last['dar_name'] }.each do |backup_entry|
314
+ size += File.size("#{ get_dependence_value("folders","backups_folder_data_local") }/#{ backup_entry ['folder'] }/#{ backup_entry['name'] }")
315
+ end
316
+ end
317
+ end
318
+ size
319
+ end
320
+ end
321
+
322
+
323
+ module Gat
324
+
325
+ module Action
326
+
327
+ class ShellCommand < Base
328
+
329
+ # dar mixes a little bit its stdout and stderr outputs
330
+ def reinterpret_output_and_error(output, error, status)
331
+ all_errors = error.split("\n")
332
+ all_outputs = output.split("\n")
333
+ ret_error = Array.new
334
+ ret_output = ""
335
+ all_errors.each do |line|
336
+ if line != ""
337
+ if line == "No terminal found for user interaction. All questions will be assumed a negative answer (less destructive choice), which most of the time will abort the program."
338
+ status = 0 if status == 5
339
+ else
340
+ ret_error << line
341
+ end
342
+ end
343
+ end
344
+ add_next_line = false
345
+ all_outputs.each do |line|
346
+ if add_next_line
347
+ ret_error << line
348
+ add_next_line = false
349
+ elsif line.index("FATAL error") == 0
350
+ ret_error << line
351
+ status = 99 if status == 0
352
+ add_next_line = true
353
+ elsif line.index("Error") != nil
354
+ ret_error << line
355
+ status = 99 if status == 0
356
+ add_next_line = true
357
+ else
358
+ ret_output = line + "\n"
359
+ end
360
+ end
361
+ return ret_output, ret_error.join(". \n"), status
362
+ end
363
+ end
364
+
365
+ end
366
+
367
+ end
@@ -0,0 +1,387 @@
1
+ # Gatget Config Script for DarBackup Gatget
2
+ # -----------------------------------------
3
+
4
+ description: 'Gatget backup manager with DAR'
5
+
6
+ static:
7
+ complet_backup_days: [ 0 ]
8
+ number_backup_stored: 1
9
+ # mysql dumps options
10
+ mysql_dumps: false
11
+ mysql_user: root
12
+ mysql_password: ''
13
+
14
+ # space limit to perform backup, in megas
15
+ space_thresold: 3000M
16
+
17
+ # dar tunned options
18
+ # enable compression. nil disable
19
+ dar_compression: 256
20
+ # size of division each file
21
+ dar_file_size: 3500M
22
+ # enable backup empty folders
23
+ dar_enable_empty_folders: true
24
+ # root folder from backup
25
+ dar_root_backup: '/'
26
+ # password to encrypt backups
27
+ dar_encrypt_passwd: 'none'
28
+ # password to decrypt backups
29
+ dar_decrypt_passwd: 'none'
30
+ # exclude foolders
31
+ exclude_folders:
32
+ - boot
33
+ - dev
34
+ - lib64
35
+ - media
36
+ - opt
37
+ - root
38
+ - selinux
39
+ - sys
40
+ - usr
41
+ - cdrom
42
+ - lib
43
+ - lost+found
44
+ - mnt
45
+ - proc
46
+ - sbin
47
+ - srv
48
+ - tmp
49
+ - home
50
+ - var
51
+ - etc
52
+ # exclude files
53
+ exclude_files:
54
+ - *.dar
55
+ - /initrd.img.old
56
+ - /vmlinuz
57
+ - /initrd.img
58
+ - /vmlinuz.old
59
+ exclude_to_compress:
60
+ - *.gz
61
+ - *.bz2
62
+ - *.zip
63
+ - *.png
64
+
65
+ arguments:
66
+ search_pattern:
67
+ description: File or Folder pattern to search in catalog
68
+ backup_dar_name:
69
+ description: "Backup Dar name (for example: 2009_08_01_your_machine_complet)"
70
+ backup_id:
71
+ description: "Backup Dar catalog ID from data will be restored"
72
+ pattern_to_restore:
73
+ description: "Pattern to restore. It will be restored all the files or folder that match with pattern, even they are folders, subfolders, or files"
74
+
75
+ folders:
76
+ backups_folder:
77
+ path: /tmp/backups
78
+ tree:
79
+ - data
80
+ - data/local
81
+ - data/external
82
+ - catalog
83
+ - extras
84
+ - extras/mysql
85
+ - restore
86
+
87
+ programs:
88
+ dar:
89
+ description: Disk Linux Archive
90
+ dar_manager:
91
+ description: Dar manager for backups
92
+ mysql:
93
+ description: MySQl client
94
+ mysqldump:
95
+ description: Mysql Dumper
96
+ gzip:
97
+ description: Compressor
98
+
99
+
100
+ parameters:
101
+ backup_id:
102
+ type: dependence
103
+ value: arguments/backup_id
104
+ backup_files:
105
+ type: dependence
106
+ value: variable/backup_launch_argument
107
+ backups_folder_mysql:
108
+ type: dependence
109
+ value: folders/backups_folder_extras_mysql
110
+ backups_folder_data_local:
111
+ type: dependence
112
+ value: folders/backups_folder_data_local
113
+ backups_folder_restore:
114
+ type: dependence
115
+ value: folders/backups_folder_restore
116
+ backup_path:
117
+ type: dependence
118
+ value: variable/backup_path
119
+ backups_path_for_dar:
120
+ type: dependence
121
+ value: variable/system_backups
122
+ array_method: "select{|b| b['isolate'] }.map{|b| b['folder'] + '/' + b['dar_name'].gsub(/_isolate$/,'') }"
123
+ catalog_path:
124
+ type: dependence
125
+ value: variable/catalog_path
126
+ catalog_entries:
127
+ type: dependence
128
+ value: variable/catalog_backups
129
+ array_method: "map{|b| '1' }"
130
+ complete_folder:
131
+ type: dependence
132
+ value: variable/backup_folder
133
+ current_date:
134
+ type: eval
135
+ value: "Date.today"
136
+ dar_compression:
137
+ type: dependence
138
+ value: static/dar_compression
139
+ dar_encrypt_password:
140
+ type: dependence
141
+ value: static/dar_encrypt_passwd
142
+ dar_decrypt_password:
143
+ type: dependence
144
+ value: static/dar_decrypt_passwd
145
+ dar_file_size:
146
+ type: dependence
147
+ value: static/dar_file_size
148
+ dar_manager_program:
149
+ type: dependence
150
+ value: programs/dar_manager
151
+ dar_program:
152
+ type: dependence
153
+ value: programs/dar
154
+ dar_root_backup:
155
+ type: dependence
156
+ value: static/dar_root_backup
157
+ exclude_to_compress:
158
+ type: dependence
159
+ value: static/exclude_to_compress
160
+ join: "' -Z '"
161
+ exclude_folders:
162
+ type: dependence
163
+ value: static/exclude_folders
164
+ join: "' -P '"
165
+ gzip_program:
166
+ type: dependence
167
+ value: programs/gzip
168
+ last_backup_size:
169
+ type: dependence
170
+ value: variable/last_backup_size
171
+ mysql_databases:
172
+ type: dependence
173
+ value: action_output/get_mysql_databases
174
+ array_method: 'split("\n")'
175
+ mysql_dump_program:
176
+ type: dependence
177
+ value: programs/mysqldump
178
+ mysql_password:
179
+ type: dependence
180
+ value: static/mysql_password
181
+ mysql_program:
182
+ type: dependence
183
+ value: programs/mysql
184
+ mysql_user:
185
+ type: dependence
186
+ value: static/mysql_user
187
+ pattern_simple_for_search:
188
+ type: dependence
189
+ value: arguments/search_pattern
190
+ pattern_to_restore:
191
+ type: dependence
192
+ value: arguments/pattern_to_restore
193
+ old_backups_at_catalog_ids:
194
+ type: dependence
195
+ value: variable/backup_catalog_to_delete
196
+ old_system_backups:
197
+ type: dependence
198
+ value: variable/backup_folders_to_delete
199
+ server_name:
200
+ type: dependence
201
+ value: static/server_name
202
+ show_backup_path:
203
+ type: dependence
204
+ value: variable/backup_to_show_content
205
+
206
+ actions:
207
+ delete_old_mysql_dumps:
208
+ type: shell_command
209
+ flags: [ active_mysql_dumps ]
210
+ syntax: rm -f {{backups_folder_mysql}}/*.sql.gz {{backups_folder_mysql}}/*.sql
211
+ onfail: continue
212
+ get_mysql_databases:
213
+ type: shell_command
214
+ flags: [ active_mysql_dumps ]
215
+ syntax: "{{mysql_program}} -u {{mysql_user}} -p'{{mysql_password}}' -NBse 'Show databases'"
216
+ onfail: continue
217
+ do_mysql_dumps:
218
+ type: shell_command
219
+ flags: [ active_mysql_dumps ]
220
+ syntax: "cd {{backups_folder_mysql}}; {{mysql_dump_program}} -u {{mysql_user}} -p'{{mysql_password}}' {{mysql_databases}} -r mysqldump_{{mysql_databases}}_{{current_date}}.sql"
221
+ multiple: [ mysql_databases ]
222
+ compress_mysql_dumps:
223
+ type: shell_command
224
+ flags: [ active_mysql_dumps ]
225
+ syntax: "cd {{backups_folder_mysql}}; {{gzip_program}} -9 mysqldump_{{mysql_databases}}_{{current_date}}.sql"
226
+ multiple: [ mysql_databases ]
227
+ remove_old_system_backups:
228
+ type: shell_command
229
+ flags: [ delete_old_backups, delete_system_backups_if_any ]
230
+ syntax: 'rm -rf {{backups_folder_data_local}}/{{old_system_backups}}'
231
+ multiple: [ old_system_backups ]
232
+ remove_old_catalog_backups:
233
+ type: shell_command
234
+ flags: [ delete_old_backups, catalog_exists, delete_catalog_backups_if_any ]
235
+ syntax: '{{dar_manager_program}} -B {{catalog_path}} -D {{old_backups_at_catalog_ids}}'
236
+ multiple: [ old_backups_at_catalog_ids ]
237
+ remove_old_current_link:
238
+ type: shell_command
239
+ flags: [ delete_current_link ]
240
+ syntax: 'rm {{backups_folder_data_local}}/current'
241
+ onfail: continue
242
+ create_new_complet_folder:
243
+ type: shell_command
244
+ flags: [ new_complete_folder ]
245
+ syntax: 'mkdir -p {{backups_folder_data_local}}/{{complete_folder}}'
246
+ set_new_current_link:
247
+ type: shell_command
248
+ flags: [ new_complete_folder ]
249
+ syntax: 'cd {{backups_folder_data_local}} ; ln -sf {{complete_folder}} current'
250
+ launch_backup:
251
+ type: shell_command
252
+ syntax: "cd {{backups_folder_data_local}}; {{dar_program}} -w -m {{dar_compression}} -y -s {{dar_file_size}} -D -Q -R {{dar_root_backup}} -Z '{{exclude_to_compress}}' -P '{{exclude_folders}}' -X '*.dar' -J {{dar_encrypt_password}} -K {{dar_decrypt_password}} {{backup_files}}"
253
+ onfail: continue
254
+ onfail_callback: launch_backup_rescue
255
+ test_backup:
256
+ type: shell_command
257
+ syntax: "{{dar_program}} -Q -t {{backup_path}} -K {{dar_decrypt_password}}"
258
+ create_isolation_file:
259
+ type: shell_command
260
+ syntax: "{{dar_program}} -w -Q -C '{{backup_path}}_isolate' -A '{{backup_path}}' -J {{dar_decrypt_password}}"
261
+ identify_backups_in_catalog:
262
+ type: shell_command
263
+ flags: [ catalog_exists ]
264
+ syntax: '{{dar_manager_program}} -B {{catalog_path}} -l'
265
+ create_catalog:
266
+ type: shell_command
267
+ flags: [ '!catalog_exists' ]
268
+ syntax: '{{dar_manager_program}} -C {{catalog_path}}'
269
+ insert_in_catalog:
270
+ type: shell_command
271
+ syntax: "{{dar_manager_program}} -Q -B {{catalog_path}} -A '{{backup_path}}_isolate' '{{backup_path}}'"
272
+ list_backups_data:
273
+ type: ruby_method
274
+ delete_all_backups_at_catalog:
275
+ type: shell_command
276
+ flags: [ catalog_exists, catalog_is_not_empty ]
277
+ syntax: '{{dar_manager_program}} -B {{catalog_path}} -D {{catalog_entries}}'
278
+ multiple: [ catalog_entries ]
279
+ insert_all_backups_at_catalog:
280
+ type: shell_command
281
+ flags: [ catalog_exists ]
282
+ syntax: "{{dar_manager_program}} -Q -B {{catalog_path}} -A '{{backups_folder_data_local}}/{{backups_path_for_dar}}_isolate' '{{backups_folder_data_local}}/{{backups_path_for_dar}}'"
283
+ multiple: [ backups_path_for_dar ]
284
+ search_simple:
285
+ type: shell_command
286
+ flags: [ catalog_exists ]
287
+ syntax: "{{dar_manager_program}} -B {{catalog_path}} -f {{pattern_simple_for_search}}"
288
+ onfail: continue
289
+ show_nice_search:
290
+ type: ruby_method
291
+ show_backup_content:
292
+ type: shell_command
293
+ syntax: "{{dar_program}} -l {{backups_folder_data_local}}/{{show_backup_path}} -K {{dar_decrypt_password}}"
294
+ flags: [ exists_backup_file ]
295
+ output: true
296
+ restore_pattern:
297
+ type: shell_command
298
+ flags: [ exists_backup_file ]
299
+ syntax: "{{dar_program}} -x {{backups_folder_data_local}}/{{show_backup_path}} -R {{backups_folder_restore}} -K {{dar_decrypt_password}} -v -g '{{pattern_to_restore}}' -O"
300
+ output: true
301
+ delete_bad_backup:
302
+ type: shell_command
303
+ syntax: "rm -rf {{backup_path}}*.dar"
304
+ check_enough_space_for_backup:
305
+ type: ruby_method
306
+ onfail_message: 'System does not have enough space'
307
+ exit_if_i_am_running:
308
+ type: ruby_method
309
+ onfail_message: 'I am already running, I will exit now'
310
+ print_status:
311
+ type: ruby_method
312
+
313
+ operations:
314
+ do_backup:
315
+ description: 'Perform a Backup with DAR. Backups can be tuned by config'
316
+ users: [ root ]
317
+ programs: [ dar, dar_manager, mysql, mysqldump, gzip ]
318
+ arguments: [ ]
319
+ folders: [ backups_folder ]
320
+ helpers: [ exit_if_i_am_running, set_flag_mysql_dumps, set_flag_catalog_exists, get_all_backups, set_do_backup_variables ]
321
+ actions: [ delete_old_mysql_dumps, get_mysql_databases, do_mysql_dumps, compress_mysql_dumps,
322
+ remove_old_catalog_backups, remove_old_system_backups, remove_old_current_link,
323
+ check_enough_space_for_backup, create_new_complet_folder, set_new_current_link,
324
+ launch_backup, test_backup,
325
+ create_isolation_file, create_catalog, insert_in_catalog ]
326
+ outputs: [ ]
327
+
328
+ list_backups:
329
+ description: 'List avalaible backups at System && Catalog'
330
+ users: [ root ]
331
+ programs: [ dar_manager ]
332
+ arguments: [ ]
333
+ folders: [ backups_folder ]
334
+ helpers: [ set_flag_catalog_exists, get_all_backups ]
335
+ conditions: [ ]
336
+ actions: [ list_backups_data ]
337
+ onfail: [ ]
338
+ outputs: [ template ]
339
+
340
+ syncronize_backups:
341
+ description: 'Syncronize catalog with avalaible system backups'
342
+ users: [ root ]
343
+ programs: [ dar_manager ]
344
+ arguments: [ ]
345
+ folders: [ backups_folder ]
346
+ helpers: [ exit_if_i_am_running, set_flag_catalog_exists, get_all_backups, catalog_is_empty ]
347
+ conditions: [ ]
348
+ actions: [ delete_all_backups_at_catalog, insert_all_backups_at_catalog ]
349
+
350
+ search:
351
+ description: 'Search files to restore in backups'
352
+ users: [ root ]
353
+ programs: [ dar_manager ]
354
+ arguments: [ search_pattern ]
355
+ folders: [ backups_folder ]
356
+ helpers: [ set_flag_catalog_exists ]
357
+ outputs: [ template, yml ]
358
+ conditions: [ ]
359
+ actions: [ search_simple, show_nice_search ]
360
+
361
+ show_backup_content:
362
+ description: 'Show all the backup contents. Redirect to a file if your backup content has many information'
363
+ users: [ root ]
364
+ programs: [ dar ]
365
+ arguments: [ backup_dar_name ]
366
+ folders: [ backups_folder ]
367
+ helpers: [ exists_backup_file]
368
+ conditions: [ ]
369
+ actions: [ show_backup_content ]
370
+
371
+ restore:
372
+ description: 'Allow to restore files || directory from backups, files will be restored under <your backup folder>/restore'
373
+ users: [ root ]
374
+ programs: [ dar ]
375
+ arguments: [ pattern_to_restore, backup_dar_name ]
376
+ folders: [ backups_folder ]
377
+ helpers: [ exists_backup_file ]
378
+ conditions: [ ]
379
+ actions: [ restore_pattern ]
380
+
381
+ status:
382
+ description: 'Checks whether the backup script is running'
383
+ users: [ root ]
384
+ actions: [ print_status ]
385
+
386
+
387
+