rmybackup 0.3.0 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
data/Readme.md CHANGED
@@ -12,6 +12,11 @@ The gem will install an rmybackup binary. RMyBackup will read its configuration
12
12
  To generate a sample config file, use the --instal-config option. Default location is /etc/rmybackup.conf, or if we can't write to /etc, ~/.rmybacukp.conf.
13
13
 
14
14
  # rmybackup --install-config [/config/location]
15
+
16
+ Rmybackup --edit and --list will edit and list the config file respectively. Edit will use the EDITOR environment variable, or search for vim.
17
+
18
+ # rmybackup --edit
19
+ # rmybackup --list
15
20
 
16
21
  If use_mycnf_credentials is set to true in the config file, mysqldump will not be passed --user, --password, or --host based on the values in the config file. The script will rely on your [mysqldump] configuration in either /etc/my.cnf or the user's ~/.my.cnf. This is more secure if running on a shared server.
17
22
 
@@ -20,7 +25,11 @@ If use_mycnf_credentials is set to true in the config file, mysqldump will not b
20
25
  [mysqldump]
21
26
  user = root
22
27
  password = roots_password
23
-
28
+
29
+ RMyBackup will also use rsync to sync to URIs listed in the push configuration file option. For example, if you set push: user@server:/remote/path, after the backups were completed, rmybackup would run rsync -rz /local/backup/path/ user@server:/remote/path/. Push can either be a list or URIs or a single URI.
30
+
31
+ push: [ "username@server:/directory/for/backups",
32
+ "another_user@another_server:/directory/for/backups" ]
24
33
 
25
34
  Once everything is set up, simply run the rmybackup command. It will connect to the mysql server using the values in your config file and back up your databases.
26
35
 
@@ -33,31 +42,39 @@ The default location for the configuration file is /etc/rmybackup.conf then ~/.r
33
42
 
34
43
  ---
35
44
  backup_dir: /Users/username/mysql_backups/
36
-
45
+
37
46
  #Pruning. Remove_after is evaluated first, then only_keep
38
47
 
39
48
  #Remove after x days
40
- remove_after: 7
49
+ #remove_after: 7
41
50
 
42
51
  #Only keep x number
43
- only_keep: 5
52
+ #only_keep: 5
44
53
 
45
54
  #Database
46
55
  username: root
47
56
  password: password
48
57
  host: localhost
49
58
 
50
- #If this is set to true, no --user --password or --host switches will be passed to
51
- #mysqldump. You will need to have credentials within /etc/my.cnf or ~/.my.cnf
59
+ #If use_mycnf_credentials is set to true, no --user --password or --host switches will be passed to mysqldump
52
60
  use_mycnf_credentials: false
53
61
 
54
62
  #Databases to back up
55
63
  skip_databases: [ mysql, test, information_schema ]
56
64
 
65
+
66
+ #RMyBackup will use Rsync to push to the Rsync compatible URI's listed in push:. This can be a single value or a list.
67
+
68
+ #push: [ "username@server:/directory/for/backups",
69
+ # "another_user@another_server:/directory/for/backups" ]
70
+
71
+
57
72
  #Command Locations
58
- #You can override where to find the needed system commands, default locations are prefixed with /usr/bin/
73
+ #You may override where to find the needed system commands
74
+ #RMyBackup will try to locate these files if they are not specified here
59
75
 
60
76
  #mysqldump_command: /usr/local/mysql/bin/mysqldump
61
77
  #gzip_command: /usr/bin/gzip
62
-
63
- If mysqldump_command, or gzip_command are left out, they will default to finding the applications in /usr/bin
78
+
79
+ #Rsync, only needed if you designate pushes
80
+ #rsync_command: /usr/bin/rsync
data/bin/rmybackup CHANGED
@@ -5,7 +5,6 @@ require 'rubygems'
5
5
  require 'rmybackup'
6
6
  require 'optparse'
7
7
 
8
- #GLOBALS
9
8
  #Default to local config file if it exists
10
9
  if File.exists?(File.expand_path("~/.rmybackup.conf"))
11
10
  options = { :config_file => File.expand_path("~/.rmybackup.conf") }
@@ -13,6 +12,10 @@ else
13
12
  options = { :config_file => "/etc/rmybackup.conf" }
14
13
  end
15
14
 
15
+ #Default edit or list options to false
16
+ options[:edit] = false
17
+ options[:list] = false
18
+
16
19
  gem_version = RMyBackup::GEM_VERSION
17
20
 
18
21
  #Process the command line arguments
@@ -32,14 +35,35 @@ ARGV.options do |opts|
32
35
  exit 0
33
36
  end
34
37
 
38
+ opts.on("-l","--list","Lists the configuration file") {
39
+ #Set the list option to true
40
+ options[:list] = true
41
+ }
42
+
43
+ opts.on("-e","--edit","Edit the configuration file in vim, or the editor defined by the system variable $EDITOR") {
44
+ #Set the list option to true
45
+ options[:edit] = true
46
+ }
47
+
35
48
  opts.parse!
36
49
  end
37
50
 
38
- #If the config file doesn't exist, warn and exit
39
- if not File.exists? options[:config_file]
40
- puts "Unable to read the configuration file - #{options[:config_file]}"
41
- exit
51
+ #The first remaining ARGV, we'll take as a command
52
+ command = ARGV.shift
53
+
54
+ #Load up the config file. This will exit 1 if the config file can't be found
55
+ RMyBackup::Base.load_config(options[:config_file])
56
+
57
+ #Evaluate edit or list options
58
+ if options[:list]
59
+ RMyBackup.list_config_file
60
+ exit 0
61
+ end
62
+
63
+ if options[:edit]
64
+ RMyBackup.edit_config_file
65
+ exit 0
42
66
  end
43
67
 
44
- #Run
45
- RMyBackup::Base.new(options[:config_file])
68
+ #Run the backups
69
+ RMyBackup::Backup.run
data/lib/rmybackup.rb CHANGED
@@ -2,114 +2,14 @@ require 'yaml'
2
2
  require 'time'
3
3
  require 'mysql'
4
4
 
5
+ #Load our libraries
5
6
  require File.expand_path('../rmybackup/install_config',__FILE__)
6
7
  require File.expand_path('../rmybackup/purge_files',__FILE__)
8
+ require File.expand_path('../rmybackup/base',__FILE__)
9
+ require File.expand_path('../rmybackup/backup',__FILE__)
10
+ require File.expand_path('../rmybackup/push',__FILE__)
7
11
 
12
+ #Set the version
8
13
  module RMyBackup
9
-
10
- GEM_VERSION = "0.3.0"
11
-
12
- class Base
13
- def initialize(config_file)
14
- @config_file = config_file
15
- #if the config file passes, run the backups
16
- run_backups if parse_config
17
- end
18
-
19
- private
20
- #Run the backups, we should have proper validation at this point
21
- def run_backups
22
-
23
- #Grab some config variables
24
- mysql_dump = @config['mysqldump_command']
25
- backup_root = @config['backup_dir']
26
- gzip = @config['gzip_command']
27
- date_string = Time.now.strftime "%m_%d_%Y_%H_%M"
28
-
29
-
30
- #Cycle through databases to backup
31
- get_databases.each do |db|
32
- backup_dir = File.expand_path("#{backup_root}/#{db}")
33
- Dir.mkdir(backup_dir) if not File.exists?(backup_dir)
34
-
35
- #Decide if we use my.cnf or creds on cli
36
- if @config['use_mycnf_credentials']
37
- cred_string = ''
38
- else
39
- cred_string = " --user=#{@config['username']} --password=#{@config['password']} --host=#{@config['host']}"
40
- end
41
-
42
- puts "Backing up #{db}\n"
43
- system "#{mysql_dump}#{cred_string} #{db} |#{gzip} > #{backup_dir}/#{db}_#{date_string}.sql.gz"
44
-
45
- #Purge after x days
46
- RMyBackup.purge_days(backup_dir,@config['remove_after'])
47
- RMyBackup.purge_number(backup_dir,@config['only_keep'])
48
- end
49
- end
50
-
51
- #Get Databases from MySQL
52
- def get_databases
53
- dbc = Mysql.real_connect(@config['host'],@config['username'],@config['password'])
54
- res = dbc.query('SHOW DATABASES;')
55
- databases = []
56
- res.each_hash do |db|
57
- databases << db['Database']
58
- end
59
- return databases - @config['skip_databases']
60
- rescue
61
- puts "There was a problem connecting to the mysql server"
62
- exit 0
63
- end
64
-
65
- #Parse the config YAML file
66
- def parse_config
67
- @config = YAML::load(File.open(@config_file))
68
-
69
- #Initialize error array
70
- @error = Array.new
71
-
72
- #Defaults
73
- @config['gzip_command'] = "/usr/bin/gzip" if @config['gzip_command'].nil?
74
- @config['mysqldump_command'] = "/usr/bin/mysqldump" if @config['mysqldump_command'].nil?
75
- @config['find_command'] = "/usr/bin/find" if @config['find_command'].nil?
76
- @config['remove_after'] = @config['remove_after'] || false
77
- @config['only_keep'] = @config['only_keep'] || false
78
-
79
- @config['use_mycnf_credentials'] = @config['use_mycnf_credentials'] ? true : false
80
-
81
- #Database Config
82
- @config['username'] = @config['username'] || false
83
- @config['password'] = @config['password'] || false
84
- @config['host'] = @config['host'] || false
85
-
86
- #Backup dir validation
87
- if not File.directory? @config['backup_dir']
88
- @error << "No Such Backup Directory #{@config['backup_dir']}"
89
- else
90
- @config['backup_dir'] = File.expand_path @config['backup_dir']
91
- if not File.writable? @config['backup_dir']
92
- @error << "Can't write to the backup directory - #{@config['backup_dir']}"
93
- end
94
- end
95
-
96
- #Check Commands
97
- @error << "Can't locate find command: #{@config['find_command']}" unless File.exists? @config['find_command']
98
- @error << "Can't locate gzip command: #{@config['gzip_command']}" unless File.exists? @config['gzip_command']
99
- @error << "Can't locate mysqldump command: #{@config['mysqldump_command']}" unless File.exists? @config['mysqldump_command']
100
-
101
- #See if we've created any errors, if so, display them and exit
102
- if @error.empty?
103
- return true
104
- else
105
- @error.each {|e| puts "#{e}\n" }
106
- exit 1
107
- end
108
- #Rescue anything by displaying errors if we have them and exiting 1
109
- rescue
110
- @error.each {|e| puts "#{e}\n" }
111
- exit 1
112
- return false
113
- end
114
- end
115
- end
14
+ GEM_VERSION = "0.3.5"
15
+ end
@@ -0,0 +1,54 @@
1
+ module RMyBackup
2
+ class Backup
3
+ def self.run
4
+
5
+ #This will exit out if RMyBackup::Base.load_config(file) hasn't been loaded with a config file yet
6
+ @config = RMyBackup::Base.get_config
7
+
8
+ #Grab some config variables
9
+ mysql_dump = @config['mysqldump_command']
10
+ backup_root = @config['backup_dir']
11
+ gzip = @config['gzip_command']
12
+ date_string = Time.now.strftime "%m_%d_%Y_%H_%M"
13
+
14
+
15
+ #Cycle through databases to backup
16
+ get_databases.each do |db|
17
+ backup_dir = File.expand_path("#{backup_root}/#{db}")
18
+ Dir.mkdir(backup_dir) if not File.exists?(backup_dir)
19
+
20
+ #Decide if we use my.cnf or creds on cli
21
+ if @config['use_mycnf_credentials']
22
+ cred_string = ''
23
+ else
24
+ cred_string = " --user=#{@config['username']} --password=#{@config['password']} --host=#{@config['host']}"
25
+ end
26
+
27
+ puts "Backing up #{db}\n"
28
+ system "#{mysql_dump}#{cred_string} #{db} |#{gzip} > #{backup_dir}/#{db}_#{date_string}.sql.gz"
29
+
30
+ #Purge after x days
31
+ RMyBackup.purge_days(backup_dir,@config['remove_after'])
32
+ RMyBackup.purge_number(backup_dir,@config['only_keep'])
33
+ end
34
+
35
+ #If we need to push the dir, push it here
36
+ RMyBackup::Push.run if @config['push']
37
+ end
38
+
39
+ #Get Databases from MySQL
40
+ def self.get_databases
41
+ dbc = Mysql.real_connect(@config['host'],@config['username'],@config['password'])
42
+ res = dbc.query('SHOW DATABASES;')
43
+ databases = []
44
+ res.each_hash do |db|
45
+ databases << db['Database']
46
+ end
47
+ return databases - @config['skip_databases']
48
+ rescue
49
+ puts "There was a problem connecting to the mysql server"
50
+ exit 0
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,106 @@
1
+ module RMyBackup
2
+ class Base
3
+ class << self
4
+ #Load the configuration from the file
5
+ def load_config(file)
6
+
7
+ #Expand the file path
8
+ file = File.expand_path(file)
9
+
10
+ if not File.exists? file
11
+ puts "Can't load config file: #{file}"
12
+ exit 1
13
+ end
14
+
15
+ #Load the YAML file
16
+ @config = YAML::load(File.open(file))
17
+
18
+ #Cache the expanded file we read
19
+ @config['file'] = file
20
+
21
+ #Initialize error array
22
+ @error = Array.new
23
+
24
+ #Command locations
25
+ if @config['gzip_command'].nil?
26
+ @config['gzip_command'] = `which gzip`.chop
27
+ end
28
+
29
+ if @config['mysqldump_command'].nil?
30
+ @config['mysqldump_command'] = `which mysqldump`.chop
31
+ end
32
+
33
+
34
+ #Sanitize and check our PUSH options
35
+ if not @config['push'].nil?
36
+ #Turn this into an array, even if there is only one in the config file
37
+ @config['push'] = Array.new << @config['push'] if not @config['push'].kind_of? Array
38
+
39
+ #Because we have a push defined, lets find the rsync command
40
+ if @config['rsync_command'].nil?
41
+ @config['rsync_command'] = `which rsync`.chop
42
+ end
43
+
44
+ @error << "Can't locate rsync command: #{@config['rsync_command']}" unless File.exists? @config['rsync_command']
45
+ else
46
+ @config['push'] = false
47
+ end
48
+
49
+ #Check that commands exist
50
+ @error << "Can't locate gzip command: #{@config['gzip_command']}" unless File.exists? @config['gzip_command']
51
+ @error << "Can't locate mysqldump command: #{@config['mysqldump_command']}" unless File.exists? @config['mysqldump_command']
52
+
53
+
54
+ #Default the purge settings
55
+ @config['remove_after'] = @config['remove_after'] || false
56
+ @config['only_keep'] = @config['only_keep'] || false
57
+
58
+
59
+ #Default .my.cnf usage
60
+ @config['use_mycnf_credentials'] = @config['use_mycnf_credentials'] ? true : false
61
+
62
+ #Database Config
63
+ @config['username'] = @config['username'] || false
64
+ @config['password'] = @config['password'] || false
65
+ @config['host'] = @config['host'] || false
66
+
67
+
68
+ #Backup dir validation
69
+ @config['backup_dir'] = File.expand_path @config['backup_dir']
70
+
71
+ if not File.directory? @config['backup_dir']
72
+ @error << "No Such Backup Directory #{@config['backup_dir']}"
73
+ else
74
+ if not File.writable? @config['backup_dir']
75
+ @error << "Can't write to the backup directory - #{@config['backup_dir']}"
76
+ end
77
+ end
78
+
79
+ #See if we've created any errors, if so, display them and exit
80
+ if @error.empty?
81
+ return true
82
+ else
83
+ @error.each {|e| puts "#{e}\n" }
84
+ exit 1
85
+ end
86
+
87
+ end
88
+
89
+ def config_set?
90
+ return true if @config
91
+ false
92
+ end
93
+
94
+ def get_config
95
+
96
+ #Check to make sure the configuration file has already been loaded
97
+ if not @config
98
+ puts 'No config file has been loaded.'
99
+ exit
100
+ end
101
+
102
+ @config
103
+ end
104
+ end
105
+ end
106
+ end
@@ -14,13 +14,24 @@ username: root
14
14
  password: password
15
15
  host: localhost
16
16
 
17
+ #If use_mycnf_credentials is set to true, no --user --password or --host switches will be passed to mysqldump
17
18
  use_mycnf_credentials: false
18
19
 
19
20
  #Databases to back up
20
21
  skip_databases: [ mysql, test, information_schema ]
21
22
 
23
+
24
+ #RMyBackup will use Rsync to push to the Rsync compatible URI's listed in push:. This can be a single value or a list.
25
+
26
+ #push: [ "username@server:/directory/for/backups", "another_user@another_server:/directory/for/backups" ]
27
+
28
+
22
29
  #Command Locations
23
- #You can override where to find the needed system commands, default locations are prefixed with /usr/bin/
30
+ #You may override where to find the needed system commands
31
+ #RMyBackup will locate these files if they are not specified here
24
32
 
25
33
  #mysqldump_command: /usr/local/mysql/bin/mysqldump
26
- #gzip_command: /usr/bin/gzip
34
+ #gzip_command: /usr/bin/gzip
35
+
36
+ #Rsync, only needed if you designate pushes
37
+ #rsync_command: /usr/bin/rsync
@@ -31,4 +31,44 @@ module RMyBackup
31
31
  end
32
32
  exit 0
33
33
  end
34
+
35
+ #Edit config Options
36
+ def self.editor
37
+ if ENV['EDITOR'].nil?
38
+ vim = `which vim`.chop
39
+ if vim.empty?
40
+ return false
41
+ else
42
+ return vim
43
+ end
44
+ else
45
+ return ENV['EDITOR']
46
+ end
47
+ end
48
+
49
+ def self.list_config_file
50
+ if editor
51
+ config = RMyBackup::Base.get_config
52
+ file = config['file']
53
+ puts "Showing config file - #{file}:\n"
54
+ File.open(file, "r") do |infile|
55
+ while(line = infile.gets)
56
+ puts line
57
+ end
58
+ end
59
+ else
60
+ puts "Can't locate vim and $EDITOR isn't set"
61
+ exit 1
62
+ end
63
+ end
64
+
65
+ def self.edit_config_file
66
+ config = RMyBackup::Base.get_config
67
+ if editor
68
+ exec "#{editor} #{config['file']}"
69
+ else
70
+ puts "Can't locate vim and $EDITOR isn't set"
71
+ exit 1
72
+ end
73
+ end
34
74
  end
@@ -0,0 +1,23 @@
1
+ module RMyBackup
2
+ class Push
3
+ class << self
4
+ def run
5
+ #Load the config options
6
+ @config = RMyBackup::Base.get_config
7
+
8
+ #Iterrate through the pushes in the @config options
9
+ @config['push'].each do |push|
10
+ #Define the rsync_command from the @config option
11
+ rsync_command = @config['rsync_command']
12
+
13
+ #Add a trailing slash if not present
14
+ push += "/" if push[-1,1] != "/"
15
+
16
+ puts "\nPushing to : #{push} -->\n\n"
17
+ system "#{rsync_command} -rz --delete #{@config['backup_dir']}/ #{push}"
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 0
9
- version: 0.3.0
8
+ - 5
9
+ version: 0.3.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - Bryan Shelton
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-13 00:00:00 -06:00
17
+ date: 2010-07-13 00:00:00 -06:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -30,6 +30,19 @@ dependencies:
30
30
  version: "0"
31
31
  type: :runtime
32
32
  version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :development
45
+ version_requirements: *id002
33
46
  description: Ruby mysql backup script, the script uses mysqldump from the system
34
47
  email: bryan@sheltonopensolutions.com
35
48
  executables:
@@ -39,11 +52,14 @@ extensions: []
39
52
  extra_rdoc_files: []
40
53
 
41
54
  files:
42
- - lib/rmybackup.rb
43
55
  - Readme.md
56
+ - lib/rmybackup/backup.rb
57
+ - lib/rmybackup/base.rb
44
58
  - lib/rmybackup/config_file.txt
45
59
  - lib/rmybackup/install_config.rb
46
60
  - lib/rmybackup/purge_files.rb
61
+ - lib/rmybackup/push.rb
62
+ - lib/rmybackup.rb
47
63
  - bin/rmybackup
48
64
  has_rdoc: true
49
65
  homepage: http://github.com/bshelton229/rmybackup/
@@ -60,16 +76,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
60
76
  - - ">="
61
77
  - !ruby/object:Gem::Version
62
78
  segments:
63
- - 0
64
- version: "0"
79
+ - 1
80
+ - 8
81
+ - 7
82
+ version: 1.8.7
65
83
  required_rubygems_version: !ruby/object:Gem::Requirement
66
84
  none: false
67
85
  requirements:
68
86
  - - ">="
69
87
  - !ruby/object:Gem::Version
70
88
  segments:
71
- - 0
72
- version: "0"
89
+ - 1
90
+ - 3
91
+ - 6
92
+ version: 1.3.6
73
93
  requirements: []
74
94
 
75
95
  rubyforge_project: