Guest User

Untitled

a guest
Feb 21st, 2018
294
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.44 KB | None | 0 0
  1. #!/usr/bin/env ruby
  2.  
  3. #
  4. # Written by Johan Eckerström <johan@jage.se>
  5. #
  6. !!# 2006-10-31 - Added syslog capabilities
  7. # 2006-08-06 - First version
  8.  
  9. begin
  10. require 'fileutils'
  11. require 'syslog'
  12. require 'rubygems'
  13. require 'mysql'
  14. rescue LoadError
  15. $stderr.puts 'Could not load required libraries'; exit
  16. end
  17.  
  18. $mysqldump = '/usr/local/bin/mysqldump'
  19. $gzip = '/usr/bin/gzip'
  20. $archive_dir = '/archive/mysqldump'
  21.  
  22. $server = {
  23. :host => 'localhost',
  24. :user => 'root',
  25. :password => 'orly'
  26. }
  27.  
  28. $database_options = {
  29. :saftkalas => { :owner => :dentarg },
  30. :zomg => { :owner => :dentarg },
  31. :bsdnexus => { :owner => :jage },
  32. }
  33.  
  34. $global_options = {
  35. :lock => false,
  36. :owner => 'root',
  37. :group => 'wheel',
  38. :charset => 'latin1',
  39. :map_owner => true
  40. }
  41.  
  42. $users = []
  43. IO.foreach('/etc/passwd') do |line|
  44. $users << /(^[\w]+)/.match(line).to_s.strip
  45. end
  46.  
  47. module MySQL
  48. class Databases
  49.  
  50. attr_reader :list
  51.  
  52. def initialize
  53. @list = databases.collect {|name| Database.new(name) }
  54. end
  55.  
  56. def failed
  57. @list.select {|i| i.fail }
  58. end
  59.  
  60. def skipped
  61. @list.select {|i| i.skip }
  62. end
  63.  
  64. def successes
  65. @list.select {|i| i.success }
  66. end
  67.  
  68. private
  69.  
  70. def databases
  71. list = []
  72. connection = Mysql.real_connect($server[:host],
  73. $server[:user],
  74. $server[:password])
  75. result = connection.query('SHOW DATABASES')
  76. result.each {|db| list << db.to_s }
  77. result.free
  78. list
  79. rescue Mysql::Error => error
  80. $stderr.puts error.message; exit 1
  81. end
  82. end
  83.  
  84. class Database
  85.  
  86. attr_reader :name, :lock, :owner, :group, :charset, :skip
  87. attr_accessor :success
  88.  
  89. def initialize(name)
  90. @options = $database_options[name.to_sym] ||= Hash.new
  91.  
  92. @name = name
  93. @lock = option_for(:lock)
  94. @owner = option_for(:owner)
  95. @group = option_for(:group)
  96. @charset = option_for(:charset)
  97. @skip = option_for(:skip)
  98. # Would be better if the database specific owner could override this
  99. if option_for(:map_owner) and match = /^(([a-z]+)[_]|([a-z]+))/.match(@name)
  100. match = match[2] || match[1]
  101. @owner = match if $users.include? match
  102. end
  103. end
  104.  
  105. def to_s
  106. name
  107. end
  108.  
  109. def path
  110. "#{$archive_dir}/#{self}.sql.gz"
  111. end
  112.  
  113. def fail
  114. !success && !skip
  115. end
  116.  
  117. private
  118.  
  119. def option_for(key)
  120. @options[key] || $global_options[key] || false
  121. end
  122. end
  123.  
  124. class Dump
  125. def initialize(databases)
  126. @databases = databases
  127.  
  128. unless mysqldump_working?
  129. failure("Could not execute #{$mysqldump}"); exit 1
  130. end
  131.  
  132. unless File.directory?($archive_dir)
  133. failure("Could not save in #{$archive_dir}"); exit 1
  134. end
  135. end
  136.  
  137. def execute
  138. Syslog.open(ident='rmysqldump', facility=Syslog::LOG_DAEMON)
  139. @databases.list.each do |database|
  140. unless database.skip
  141. `#{$mysqldump} #{parameters_for(database)} #{database} | #{$gzip} > #{database.path}`
  142. failure("Could not dump #{database}") unless $?.success?
  143. begin
  144. FileUtils.chown database.owner, database.group, database.path
  145. FileUtils.chmod 0660, database.path
  146. database.success = true if $?.success?
  147. rescue => error
  148. failure("Could not set permissions: #{error.message}")
  149. end
  150. end
  151. end
  152. Syslog.info("#{@databases.successes.length} databases dumped successfully")
  153. Syslog.info("#{@databases.skipped.length} databases skipped") if @databases.skipped.length > 0
  154. Syslog.err("#{@databases.failed.length} databases failed") if @databases.failed.length > 0
  155. Syslog.close
  156. end
  157.  
  158. private
  159.  
  160. def failure(message)
  161. $stderr.puts message
  162. Syslog.error(message) if Syslog.opened?
  163. end
  164.  
  165. def mysqldump_working?
  166. File.readable?($mysqldump) and File.executable?($mysqldump)
  167. end
  168.  
  169. def parameters_for(database)
  170. params = "--default-character-set=#{database.charset} \
  171. --user #{$server[:user]} \
  172. --password=#{$server[:password]} \
  173. --host #{$server[:host]}"
  174. params += " --lock-tables" if database.lock
  175. params
  176. end
  177. end
  178. end
  179.  
  180. MySQL::Dump.new(MySQL::Databases.new).execute
Add Comment
Please, Sign In to add comment