Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env ruby
- #
- # Written by Johan Eckerström <johan@jage.se>
- #
- !!# 2006-10-31 - Added syslog capabilities
- # 2006-08-06 - First version
- begin
- require 'fileutils'
- require 'syslog'
- require 'rubygems'
- require 'mysql'
- rescue LoadError
- $stderr.puts 'Could not load required libraries'; exit
- end
- $mysqldump = '/usr/local/bin/mysqldump'
- $gzip = '/usr/bin/gzip'
- $archive_dir = '/archive/mysqldump'
- $server = {
- :host => 'localhost',
- :user => 'root',
- :password => 'orly'
- }
- $database_options = {
- :saftkalas => { :owner => :dentarg },
- :zomg => { :owner => :dentarg },
- :bsdnexus => { :owner => :jage },
- }
- $global_options = {
- :lock => false,
- :owner => 'root',
- :group => 'wheel',
- :charset => 'latin1',
- :map_owner => true
- }
- $users = []
- IO.foreach('/etc/passwd') do |line|
- $users << /(^[\w]+)/.match(line).to_s.strip
- end
- module MySQL
- class Databases
- attr_reader :list
- def initialize
- @list = databases.collect {|name| Database.new(name) }
- end
- def failed
- @list.select {|i| i.fail }
- end
- def skipped
- @list.select {|i| i.skip }
- end
- def successes
- @list.select {|i| i.success }
- end
- private
- def databases
- list = []
- connection = Mysql.real_connect($server[:host],
- $server[:user],
- $server[:password])
- result = connection.query('SHOW DATABASES')
- result.each {|db| list << db.to_s }
- result.free
- list
- rescue Mysql::Error => error
- $stderr.puts error.message; exit 1
- end
- end
- class Database
- attr_reader :name, :lock, :owner, :group, :charset, :skip
- attr_accessor :success
- def initialize(name)
- @options = $database_options[name.to_sym] ||= Hash.new
- @name = name
- @lock = option_for(:lock)
- @owner = option_for(:owner)
- @group = option_for(:group)
- @charset = option_for(:charset)
- @skip = option_for(:skip)
- # Would be better if the database specific owner could override this
- if option_for(:map_owner) and match = /^(([a-z]+)[_]|([a-z]+))/.match(@name)
- match = match[2] || match[1]
- @owner = match if $users.include? match
- end
- end
- def to_s
- name
- end
- def path
- "#{$archive_dir}/#{self}.sql.gz"
- end
- def fail
- !success && !skip
- end
- private
- def option_for(key)
- @options[key] || $global_options[key] || false
- end
- end
- class Dump
- def initialize(databases)
- @databases = databases
- unless mysqldump_working?
- failure("Could not execute #{$mysqldump}"); exit 1
- end
- unless File.directory?($archive_dir)
- failure("Could not save in #{$archive_dir}"); exit 1
- end
- end
- def execute
- Syslog.open(ident='rmysqldump', facility=Syslog::LOG_DAEMON)
- @databases.list.each do |database|
- unless database.skip
- `#{$mysqldump} #{parameters_for(database)} #{database} | #{$gzip} > #{database.path}`
- failure("Could not dump #{database}") unless $?.success?
- begin
- FileUtils.chown database.owner, database.group, database.path
- FileUtils.chmod 0660, database.path
- database.success = true if $?.success?
- rescue => error
- failure("Could not set permissions: #{error.message}")
- end
- end
- end
- Syslog.info("#{@databases.successes.length} databases dumped successfully")
- Syslog.info("#{@databases.skipped.length} databases skipped") if @databases.skipped.length > 0
- Syslog.err("#{@databases.failed.length} databases failed") if @databases.failed.length > 0
- Syslog.close
- end
- private
- def failure(message)
- $stderr.puts message
- Syslog.error(message) if Syslog.opened?
- end
- def mysqldump_working?
- File.readable?($mysqldump) and File.executable?($mysqldump)
- end
- def parameters_for(database)
- params = "--default-character-set=#{database.charset} \
- --user #{$server[:user]} \
- --password=#{$server[:password]} \
- --host #{$server[:host]}"
- params += " --lock-tables" if database.lock
- params
- end
- end
- end
- MySQL::Dump.new(MySQL::Databases.new).execute
Add Comment
Please, Sign In to add comment