Advertisement
Guest User

Untitled

a guest
Oct 20th, 2019
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.04 KB | None | 0 0
  1. #!/usr/bin/env ruby
  2.  
  3. # Cleans up backup files transferred to a remote directory.
  4. # Place this file in the root of your backup account and it will clean up all
  5. # subdirectories. You may prevent or customize action by a config file.
  6.  
  7. class Directory
  8.  
  9. # The script will keep 24 hourly backups by default. So up to 24 files will
  10. # be kept that get stored on the server within one day.
  11. # After that, the latest of the hourly backups will be kept as daily backup.
  12. # 7 daily backups will be kept and on the 8th day, the backup of the 7th day
  13. # will be kept as backup for the week.
  14. # Same logic applies to weekly and monthly backups.
  15.  
  16. CONFIG = {
  17. 'hourly' => 24, # Number of hourly backups to keep
  18. 'daily' => 7, # Number of daily backups to keep
  19. 'weekly' => 4, # Number of weekly backups to keep
  20. 'monthly' => 6, # Number of monthly backups to keep
  21. 'forever' => 5, # Number of backups to keep forever
  22. 'pattern' => '*.tar.gz', # Pattern to find files
  23. 'cleanup' => 'yes' # To prevent action, set 'no' (will affect all subdirs)
  24. }
  25.  
  26. # Each default can be overwritten in a file .bakrm like this:
  27. # hourly: 4
  28. # daily: 2
  29. # weekly: 0
  30. # monthly: 0
  31. # forever: 4
  32.  
  33. CONFIG_FILE = '.bakrm'
  34.  
  35. def initialize(path)
  36. @path = path
  37. end
  38.  
  39. # Returns folders
  40. def folders
  41. @folders ||= Dir.chdir(@path) do
  42. Dir.glob('*').
  43. select { |f| File.directory?(f) }.
  44. map { |f| File.join(@path, f) }
  45. end
  46. end
  47.  
  48. # Returns files, sorted by date
  49. def files
  50. @files ||= Dir.chdir(@path) do
  51. Dir[pattern].
  52. reject { |f| %[bakrm.rb #{CONFIG_FILE}].include?(f) }.
  53. select { |f| File.file?(f) }.
  54. sort_by { |f| File.mtime(f) }.
  55. map { |f| File.join(@path, f) }.
  56. reverse
  57. end
  58. end
  59.  
  60. def reload_files
  61. @files = nil
  62. files
  63. end
  64.  
  65. # Returns config
  66. def config
  67. @config ||= begin
  68. path = File.join(@path, CONFIG_FILE)
  69. if File.exists?(path)
  70. text = File.read(path)
  71. values = text.scan(/(.+):\s*(.+)/)
  72. Hash[values]
  73. end
  74. end
  75. end
  76.  
  77. def cleanup
  78. if cleanup?
  79. cleanup_files
  80. cleanup_folders
  81. end
  82. end
  83.  
  84. private
  85.  
  86. def cleanup_files
  87. reject_empty_files
  88. keep = keep_files
  89. delete = reload_files - keep
  90. # puts "keep: #{keep.count}; delete: #{delete.count}"
  91. delete.each { |f| File.delete(f) }
  92. end
  93.  
  94. def cleanup_folders
  95. folders.each do |dir|
  96. Directory.new(dir).cleanup
  97. end
  98. end
  99.  
  100. def config_value(key)
  101. value = config && config[key]
  102. value || CONFIG[key]
  103. end
  104.  
  105. def cleanup?
  106. config_value('cleanup') == 'yes'
  107. end
  108.  
  109. def pattern
  110. config_value('pattern')
  111. end
  112.  
  113. def hourly
  114. config_value('hourly').to_i
  115. end
  116.  
  117. def daily
  118. config_value('daily').to_i
  119. end
  120.  
  121. def weekly
  122. config_value('weekly').to_i
  123. end
  124.  
  125. def monthly
  126. config_value('monthly').to_i
  127. end
  128.  
  129. def forever
  130. config_value('forever')
  131. end
  132.  
  133. def keep_files
  134. keep = []
  135. keep += hourly_files if hourly > 0
  136. keep += daily_files if daily > 0
  137. keep += weekly_files if weekly > 0
  138. keep += monthly_files if monthly > 0
  139. keep.uniq!
  140. if keep.length < forever
  141. if files.length < forever
  142. keep = files
  143. else
  144. keep = files[0, forever]
  145. end
  146. end
  147. keep
  148. end
  149.  
  150. def hourly_files
  151. pick_files(hourly, 3600)
  152. end
  153.  
  154. def daily_files
  155. pick_files(daily, 3600*24)
  156. end
  157.  
  158. def weekly_files
  159. pick_files(weekly, 3600*24*7)
  160. end
  161.  
  162. def monthly_files
  163. pick_files(monthly, 3600*24*30)
  164. end
  165.  
  166. # Remove empty files from list
  167. def reject_empty_files
  168. files.reject! { |f| File.size(f) == 0 }
  169. end
  170.  
  171. # Pick files matching given time interval.
  172. def pick_files(counter, increment)
  173. picked = []
  174. range_start = now
  175. counter.times do
  176. range_end = range_start - increment
  177. files.each do |f|
  178. mtime = File.mtime(f)
  179. if mtime < range_start && mtime >= range_end
  180. picked << f
  181. break
  182. end
  183. end
  184. range_start = range_end
  185. end
  186. picked
  187. end
  188.  
  189. def now
  190. @now ||= Time.now
  191. end
  192. end
  193.  
  194. def run
  195. Directory.new(Dir.pwd).cleanup
  196. end
  197.  
  198. run
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement