gat 0.2.8 → 0.2.11

Sign up to get free protection for your applications and to get access to all the features.
data/lib/gat/version.rb CHANGED
@@ -1,20 +1,22 @@
1
1
  =begin
2
2
  This file is part of GAT: http://gat.rubyforge.org
3
-
3
+
4
4
  (c) 2008-2009 A.C. Gnoxys info@gnoxys.net
5
-
5
+
6
6
  GAT (Gnoxys Administration Tools) is released under the GPL License 3 or higher.
7
7
  You can get a copy of the license easily at http://www.gnu.org/licenses/gpl.html.
8
-
8
+
9
9
  THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
10
10
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11
11
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
12
12
  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
13
13
  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
14
14
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
15
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
16
  =end
17
17
 
18
18
  module Gat
19
- VERSION = '0.2.8'
19
+
20
+ VERSION = '0.2.11'
21
+
20
22
  end
@@ -16,38 +16,38 @@
16
16
  =end
17
17
 
18
18
  require 'gat'
19
+ require 'gatgets/dar_backup/system_backup'
19
20
 
20
21
  GATGET_DAR_BACKUP_ROOT = File.expand_path(File.dirname(__FILE__))
21
22
 
22
23
  class GatgetDarBackup < Gat::Base
23
24
 
25
+ ####################
26
+ ## Gatget Helpers ##
27
+ ####################
24
28
 
25
- # helpers
26
29
  def set_flag_mysql_dumps
27
30
  set_flag("active_mysql_dumps", get_dependence_value("static", "mysql_dumps"))
28
31
  end
29
32
 
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
33
+ # get all the system backups
38
34
  def get_all_backups
39
- get_system_backups
40
- get_catalog_backups
35
+ backups_path = get_dependence_value("folders", "backups_folder_data_local")
36
+ set_dependence_variable("system_backups", SystemBackup.find(:all, backups_path))
41
37
  end
42
38
 
43
39
  # We are going to set the backups variables. Which ones must be deleted and the name of the current backup
44
40
  def set_do_backup_variables
45
- # if we dont have a backup
46
- if not get_current_complete_backup
41
+
42
+ backups_path = get_dependence_value("folders", "backups_folder_data_local")
43
+ last_complet_backup = SystemBackup.find(:last, backups_path, { :current => true, :type => 'complet'})
44
+
45
+
46
+ if not last_complet_backup
47
47
 
48
48
  # * perform a complet backup
49
49
  # * set the minimum space required at 1 kb
50
- # * mark backups to delete, if nothing to delete,system will get it
50
+ # * mark backups to delete, if nothing to delete, system will get it
51
51
  # * create new dir and link it to current through new_link_current flag
52
52
 
53
53
  set_variables_to_complete_backup
@@ -98,12 +98,13 @@ class GatgetDarBackup < Gat::Base
98
98
 
99
99
  end
100
100
 
101
- # ruby methods
102
- def list_backups_data
103
- end
101
+ ################################
102
+ ## Gatget RubyMethods Actions ##
103
+ ################################
104
104
 
105
- def show_nice_search
106
- get_catalog_backups
105
+
106
+ # list_backups_data is empty. SystemBackup.find(:all) is launched at required helper get_all_backups
107
+ def list_backups_data
107
108
  end
108
109
 
109
110
  # We need to have enough space to do backup
@@ -111,13 +112,56 @@ class GatgetDarBackup < Gat::Base
111
112
 
112
113
  last_backup_size = get_dependence_variable("last_backup_size")
113
114
  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
+ thresold = get_dependence_value("static", "space_thresold").to_i * 1024 * 1024 # to Bytes
115
116
  # check it
116
117
  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
118
  raise Gat::GatgetProcessException.new("System doesnt have enough space", "check_enough_space_for_backup")
118
119
  end
119
120
  end
120
121
 
122
+ def search_in_backups
123
+
124
+ backup_folder = get_dependence_value("folders", "backups_folder_data_local")
125
+ all_backups = get_dependence_variable("system_backups")
126
+ search_what = get_dependence_value("arguments", "search_pattern")
127
+
128
+ something_found = false
129
+
130
+ all_backups.each do |backup|
131
+
132
+ # do we have already the dumped content??
133
+ unless backup.dump
134
+ self.logger.log("warning", "process_action", "Backup #{ backup.name } doesnt have a valid dump content. Dumping content")
135
+ backup_path = "#{ backup_folder }/#{ backup.folder }/#{ backup.name }"
136
+ set_dependence_variable("backup_path", backup_path)
137
+
138
+ dumping_action = Gat::Action::ShellCommand.new('dump_backup_content_to_file', get_element_config('actions', 'dump_backup_content_to_file'), self.operation)
139
+
140
+ begin
141
+ dumping_action.execute
142
+ rescue => error
143
+ raise Gat::GatgetProcessException.new("Unable to dump content for backup #{ backup_path}", "search_in_backups")
144
+ end
145
+ end
146
+
147
+ # now, search in backup the patern
148
+ results_for_backup = backup.search_pattern(search_what)
149
+
150
+ if results_for_backup.blank?
151
+ self.logger.log("trace", "process_action", "Backup #{ backup.name } doesnt contain pattern #{ search_what }")
152
+ else
153
+ something_found = true
154
+ self.logger.log("direct", "process_action", "\n\nBackup #{ backup.name } contain pattern '#{ search_what }'\n")
155
+ self.logger.log("direct", "process_action", "#{ results_for_backup.gsub(/^\[/, " » [") }")
156
+ end
157
+ end
158
+
159
+ unless something_found
160
+ self.logger.log("direct", "process_action", "\n Sorry. Pattern #{ search_what } not found in stored backups.\n Try to simplify search, for example, seach 'bin' instead of 'bin/ls'\n\n")
161
+ end
162
+ end
163
+
164
+
121
165
  # failed action launch_backup_rescue callback
122
166
  # Dar, when the backup is so big, usually end with a 2 status, that means some files changed during backup operations. That
123
167
  # is normal while is working over logs, mysql, etc...
@@ -154,7 +198,7 @@ class GatgetDarBackup < Gat::Base
154
198
  def onfail
155
199
 
156
200
  unless self.config['email_config']
157
- raise Gat::GatgetConfigException.new("Default email config is empty at gatget.config['email_config']", "run_output_email")
201
+ raise Gat::GatgetConfigException.new("Default email config is empty at gatget.config['email_config']", "dar_backup:onfail")
158
202
  end
159
203
 
160
204
  email_subject = "[GAT] [#{ self.class.name }] [#{ self.operation.name.camelize }] [FAILED]"
@@ -170,82 +214,16 @@ class GatgetDarBackup < Gat::Base
170
214
 
171
215
  end
172
216
 
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
217
  def print_status
179
218
  if check_i_am_running
180
219
  ret = "running"
181
220
  else
182
221
  ret = "not running"
183
222
  end
184
- puts ret
185
223
  Gat::Action::Base.get_current_action.output = ret
186
224
  end
187
225
 
188
226
  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
227
  def set_variables_to_complete_backup
250
228
  backups_folder = get_dependence_value("folders", "backups_folder_data_local")
251
229
  backup_folder = "#{ Date.today }"
@@ -258,62 +236,43 @@ class GatgetDarBackup < Gat::Base
258
236
  set_dependence_variable("backup_path", backup_path)
259
237
  end
260
238
 
239
+
261
240
  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") }"
241
+ backups_path = get_dependence_value("folders", "backups_folder_data_local")
242
+ complete_backup = SystemBackup.find(:last, backups_path, { :current => true, :type => 'complet'})
243
+ diff_backup_name = "#{ Date.today }_#{ self.config['server_name'] || 'backup' }_diff"
244
+ diff_backup_path = "#{ backups_path }/#{ complete_backup.folder }/#{ diff_backup_name }"
267
245
  # 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)
246
+ set_dependence_variable("backup_launch_argument", "-c #{ diff_backup_path } -A #{ complete_backup.full_dar_path }")
247
+ set_dependence_variable("backup_folder", complete_backup.folder)
248
+ set_dependence_variable("backup_name", diff_backup_name)
249
+ set_dependence_variable("backup_path", diff_backup_path)
272
250
  end
273
251
 
274
252
  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?)
253
+ number_stored_backups = get_dependence_value("static", "number_backup_stored")
254
+ backups_folder = get_dependence_value("folders", "backups_folder_data_local")
292
255
 
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?)
256
+ # get all complete folders backups, in reverse order, olders as first
257
+ complete_backup_folders = SystemBackup.find(:all, backups_folder, { :type => 'complet' }).map(&:folder).sort.reverse || []
297
258
 
259
+ if complete_backup_folders.any?
260
+ delete_complete_folders = complete_backup_folders[number_stored_backups..complete_backup_folders.count] || []
261
+ set_dependence_variable("backup_folders_to_delete", delete_complete_folders)
262
+ set_flag("delete_system_backups_if_any", delete_complete_folders.any?)
263
+ else
264
+ set_dependence_variable("backup_folders_to_delete", [])
265
+ set_flag("delete_system_backups_if_any", false)
266
+ end
298
267
  end
299
268
 
300
269
  def get_last_backup_size(backup_type)
301
270
  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
271
+ backups_folder = get_dependence_value("folders", "backups_folder_data_local")
272
+ last_backup = SystemBackup.find(:last, backups_folder, { :type => backup_type })
273
+
274
+ if last_backup
275
+ size = last_backup.size
317
276
  end
318
277
  size
319
278
  end
@@ -355,7 +314,7 @@ module Gat
355
314
  status = 99 if status == 0
356
315
  add_next_line = true
357
316
  else
358
- ret_output = line + "\n"
317
+ ret_output << line + "\n"
359
318
  end
360
319
  end
361
320
  return ret_output, ret_error.join(". \n"), status
@@ -113,6 +113,9 @@ parameters:
113
113
  backups_folder_restore:
114
114
  type: dependence
115
115
  value: folders/backups_folder_restore
116
+ backup_name:
117
+ type: dependence
118
+ value: variable/backup_name
116
119
  backup_path:
117
120
  type: dependence
118
121
  value: variable/backup_path
@@ -120,13 +123,9 @@ parameters:
120
123
  type: dependence
121
124
  value: variable/system_backups
122
125
  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:
126
+ catalog_folder:
127
127
  type: dependence
128
- value: variable/catalog_backups
129
- array_method: "map{|b| '1' }"
128
+ value: folders/backups_folder_catalog
130
129
  complete_folder:
131
130
  type: dependence
132
131
  value: variable/backup_folder
@@ -190,9 +189,6 @@ parameters:
190
189
  pattern_to_restore:
191
190
  type: dependence
192
191
  value: arguments/pattern_to_restore
193
- old_backups_at_catalog_ids:
194
- type: dependence
195
- value: variable/backup_catalog_to_delete
196
192
  old_system_backups:
197
193
  type: dependence
198
194
  value: variable/backup_folders_to_delete
@@ -229,11 +225,6 @@ actions:
229
225
  flags: [ delete_old_backups, delete_system_backups_if_any ]
230
226
  syntax: 'rm -rf {{backups_folder_data_local}}/{{old_system_backups}}'
231
227
  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
228
  remove_old_current_link:
238
229
  type: shell_command
239
230
  flags: [ delete_current_link ]
@@ -258,34 +249,8 @@ actions:
258
249
  create_isolation_file:
259
250
  type: shell_command
260
251
  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
252
  list_backups_data:
273
253
  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
254
  show_nice_search:
290
255
  type: ruby_method
291
256
  show_backup_content:
@@ -309,6 +274,11 @@ actions:
309
274
  onfail_message: 'I am already running, I will exit now'
310
275
  print_status:
311
276
  type: ruby_method
277
+ dump_backup_content_to_file:
278
+ type: shell_command
279
+ syntax: "{{dar_program}} -l {{backup_path}} -K {{dar_decrypt_password}} 1> {{backup_path}}_dump"
280
+ search_in_backups:
281
+ type: ruby_method
312
282
 
313
283
  operations:
314
284
  do_backup:
@@ -317,46 +287,35 @@ operations:
317
287
  programs: [ dar, dar_manager, mysql, mysqldump, gzip ]
318
288
  arguments: [ ]
319
289
  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 ]
290
+ helpers: [ exit_if_i_am_running, set_flag_mysql_dumps, get_all_backups, set_do_backup_variables ]
321
291
  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,
292
+ remove_old_system_backups, remove_old_current_link,
323
293
  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: [ ]
294
+ launch_backup, test_backup, create_isolation_file, dump_backup_content_to_file ]
295
+ outputs: [ email ]
327
296
 
328
297
  list_backups:
329
- description: 'List avalaible backups at System && Catalog'
298
+ description: 'List avalaible backups at System'
330
299
  users: [ root ]
331
300
  programs: [ dar_manager ]
332
301
  arguments: [ ]
333
302
  folders: [ backups_folder ]
334
- helpers: [ set_flag_catalog_exists, get_all_backups ]
303
+ helpers: [ get_all_backups ]
335
304
  conditions: [ ]
336
305
  actions: [ list_backups_data ]
337
306
  onfail: [ ]
338
307
  outputs: [ template ]
339
308
 
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
309
  search:
351
310
  description: 'Search files to restore in backups'
352
311
  users: [ root ]
353
- programs: [ dar_manager ]
312
+ programs: [ dar ]
354
313
  arguments: [ search_pattern ]
355
314
  folders: [ backups_folder ]
356
- helpers: [ set_flag_catalog_exists ]
357
- outputs: [ template, yml ]
315
+ helpers: [ get_all_backups ]
316
+ outputs: [ ]
358
317
  conditions: [ ]
359
- actions: [ search_simple, show_nice_search ]
318
+ actions: [ search_in_backups ]
360
319
 
361
320
  show_backup_content:
362
321
  description: 'Show all the backup contents. Redirect to a file if your backup content has many information'