rosie 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *~
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create ruby-1.9.2-p0@rosie
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rosie.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,26 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rosie (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.2)
10
+ rake (0.9.2)
11
+ rspec (2.6.0)
12
+ rspec-core (~> 2.6.0)
13
+ rspec-expectations (~> 2.6.0)
14
+ rspec-mocks (~> 2.6.0)
15
+ rspec-core (2.6.4)
16
+ rspec-expectations (2.6.0)
17
+ diff-lcs (~> 1.1.2)
18
+ rspec-mocks (2.6.0)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ rake (~> 0.9)
25
+ rosie!
26
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Rogers Yun Enterprises LLC (2RYE)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # Rosie
2
+
3
+ ## Intro
4
+
5
+ Backup and restore your MySQL db and dependent local assets (e.g. PaperClip uploads)
6
+
7
+ Named after Rosie, the maid from the Jetsons (http://en.wikipedia.org/wiki/Rosie_the_Robot_Maid#Rosie). The gem provides two rake tasks which will backup or restore a MySQL database along with any dependent file system assets (like uploaded files from PaperClip) into a single timestamped file.
8
+
9
+ ## Requirements
10
+
11
+ * Rails3
12
+ * MySQL > 5 with commandline tools (mysql, mysqladmin, mysqldump)
13
+ * Unix(ish) system shell with tar
14
+
15
+ ## Installation
16
+
17
+ Add rosie to your Gemfile:
18
+
19
+ <pre>
20
+ gem 'rosie'
21
+ </pre>
22
+
23
+ Use bundler to install it:
24
+
25
+ <pre>
26
+ bundle install
27
+ </pre>
28
+
29
+ ## Configuration
30
+
31
+ Configuration values can be set by placing a rosie.yml file in your config directory. Default keys and values are as follows:
32
+
33
+ <pre>
34
+ # sample rosie.yml
35
+ #
36
+ backup_dir:backups
37
+ assets_dir:public/system
38
+ mysql_bin_dir:
39
+
40
+ </pre>
41
+
42
+ * `backup_dir`: This should be specified relative to your Rails root. This setting would give you `#{Rails.root}/backups`.
43
+ * `assets_dir`: This should be specified relative to your Rails root. This directory is the one that is holding any system assets you'd like to have backed up along side the database dump.
44
+ * `mysql_bin_dir`: If mysql and mysqldump are not on the path of the user running this rake task, you may need to specify the directory where those commandline applications live. This should be an absolute path. By default, Rosie will try to find these in the user's PATH.
45
+
46
+ ## Validation
47
+
48
+ Tested on OSX 10.6/Ubuntu 11
49
+
50
+ ## Usage
51
+
52
+ ## TODO
53
+ * add ability to backup remote databases (not on localhost)
54
+ * make Rails2.3.x compatible
55
+ * add alternate database support
56
+
57
+ ## Credits
58
+ Developed by Jon Rogers and Jeremy Yun @ 2rye.com
@@ -0,0 +1,3 @@
1
+ module Rosie
2
+ VERSION = '0.0.1'
3
+ end
data/lib/rosie.rb ADDED
@@ -0,0 +1,41 @@
1
+ rootpath = File.join(File.dirname(__FILE__),'..')
2
+ require File.join(rootpath, 'lib/rosie/version')
3
+
4
+ Dir[File.join(rootpath, "lib/tasks/**/*.rake")].each { |ext| load ext } if defined?(Rake)
5
+
6
+ module Rosie
7
+ class Config
8
+ @@allowed_attributes = [:backup_dir, :assets_dir, :mysql_bin_dir, :config_file]
9
+
10
+ attr_accessor *@@allowed_attributes
11
+
12
+ def initialize
13
+ _config = {"backup_dir"=>"backups", "assets_dir"=>"public/system", "mysql_bin_dir"=>nil}
14
+ self.config_file = File.join(Rails.root, 'config/rosie.yml')
15
+ if File.exists? self.config_file
16
+ _config.merge!(YAML.load(File.open(self.config_file)))
17
+ end
18
+ _config.keys.each do |attr|
19
+ self.send(attr+"=",_config[attr]) if @@allowed_attributes.include? attr.to_sym
20
+ end
21
+ end
22
+
23
+ def backup_dir
24
+ File.join(Rails.root, @backup_dir)
25
+ end
26
+
27
+ def assets_dir
28
+ File.join(Rails.root, @assets_dir)
29
+ end
30
+
31
+ def mysql_cmd
32
+ mysql_bin_dir.present? ? File.join(mysql_bin_dir, 'mysql') : 'mysql'
33
+ end
34
+
35
+ def mysqldump_cmd
36
+ mysql_bin_dir.present? ? File.join(mysql_bin_dir, 'mysqldump') : 'mysqldump'
37
+ end
38
+ end
39
+
40
+ end
41
+
@@ -0,0 +1,102 @@
1
+ require 'find'
2
+ require 'fileutils'
3
+ require 'tmpdir'
4
+ require 'yaml'
5
+
6
+ rosie = nil
7
+ ts = nil
8
+
9
+ def get_db_config
10
+ alldbconf = YAML.load_file( File.join( [Rails.root, 'config','database.yml' ] ))
11
+ env = Rails.env
12
+ alldbconf[env]
13
+ end
14
+
15
+ def get_db_cmdline_args
16
+ dbcnf = get_db_config
17
+ args = []
18
+ # NOTE: Assuming that database is running on localhost
19
+ # TODO - if you use other args like :socket, or ? they are ignored
20
+ # we could add host, port etc to make this more flexible
21
+ [['--user=','username'], ['--password=','password']].each do |entry|
22
+ if dbcnf[entry[1]].present?
23
+ args << "#{entry[0]}#{dbcnf[entry[1]]}"
24
+ end
25
+ end
26
+ args
27
+ end
28
+
29
+ namespace :rosie do
30
+ task :init do
31
+ rosie = Rosie::Config.new
32
+ end
33
+
34
+ desc "show config"
35
+ task :dump_config => :init do
36
+ puts "Rosie Config: read from #{rosie.config_file}"
37
+ puts "mysql: #{rosie.mysql_cmd}"
38
+ puts "mysqldump: #{rosie.mysqldump_cmd}"
39
+ puts "backup dir: #{rosie.backup_dir}"
40
+ puts "assets dir: #{rosie.assets_dir}"
41
+ end
42
+
43
+ desc "restore data from backup tarball"
44
+ task :restore => :init do
45
+ puts "Restoring data..."
46
+ tarball = ENV["datafile"]
47
+ if tarball.present?
48
+ tarball = File.absolute_path(tarball)
49
+ tmp = File.join(Dir.tmpdir, "rosie-restore")
50
+ FileUtils.remove_dir(tmp, true)
51
+ FileUtils.mkdir_p(tmp)
52
+ if !Dir.exists?(tmp)
53
+ msg = "Unable to create a temporary directory. Please check your file permissions.\nAttempted to create #{tmp}"
54
+ raise msg
55
+ end
56
+ files_before = Dir.entries(tmp)
57
+ sh "cd #{tmp} && tar -xzf #{tarball}"
58
+ ts = Dir.entries(tmp).reject{ |f| files_before.include? f }.first
59
+ unless ts.present?
60
+ puts "*** Something went wrong while trying to unpack the datafile."
61
+ exit 1
62
+ end
63
+ dbcnf = get_db_config
64
+ data_dir = File.join(tmp, ts)
65
+ image_tarball = File.join(data_dir, Dir.entries(data_dir).select{|f| f =~ /#{ts}.*\.tar/}.first)
66
+ sql_dump = File.join(data_dir, Dir.entries(data_dir).select{|f| f =~ /#{ts}.*\.sql/}.first)
67
+ args = get_db_cmdline_args
68
+ sh "tar -C #{rosie.assets_dir} -xf #{image_tarball} && #{rosie.mysql_cmd} #{args.join(' ')} #{dbcnf['database']} < #{sql_dump}"
69
+
70
+ else
71
+ puts "*** You must specify the datafile from which to restore"
72
+ puts "*** e.g. % datafile=/home/me/2011010101.tgz rake rosie:restore"
73
+ exit 1
74
+ end
75
+ end
76
+
77
+ desc "backup all data"
78
+ task :backup => ["rosie:backups:db", "rosie:backups:assets"] do
79
+ sh "cd #{rosie.backup_dir}/#{ts}/../ && tar -czvf #{ts}.tgz ./#{ts} && rm -rf #{ts}"
80
+ end
81
+
82
+ namespace :backups do
83
+ task :init => 'rosie:init' do
84
+ ts = Time.now.strftime('%Y%m%d%H%m%S')
85
+ end
86
+
87
+ task :db => :init do
88
+ dbcnf = get_db_config
89
+ db_file = "#{dbcnf['database']}-#{ts}.backup.sql"
90
+ path = File.join(rosie.backup_dir, ts, db_file)
91
+ args = get_db_cmdline_args
92
+ sh "mkdir -p #{rosie.backup_dir}/#{ts} && #{rosie.mysqldump_cmd} #{args.join(' ')} --single-transaction #{dbcnf['database']} > #{path}"
93
+ end
94
+
95
+ task :assets => :init do
96
+ sh "tar -C #{rosie.assets_dir} -cvf #{rosie.backup_dir}/#{ts}/rosie_backup_#{Rails.env}_#{ts}.tar ."
97
+ end
98
+
99
+ end
100
+
101
+ end
102
+
data/rosie.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require "rosie/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "rosie"
6
+ s.version = Rosie::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Jon Rogers", "Jeremy Yun"]
9
+ s.email = ["j@2rye.com"]
10
+ s.homepage = "http://github.com/2rye/rosie"
11
+ s.summary = "rosie-#{Rosie::VERSION}"
12
+ s.description = %q{Backup/Restore MySQL database and dependent filesystem assets via rake tasks.}
13
+
14
+ s.rubyforge_project = "rosie"
15
+
16
+ s.add_development_dependency('rspec')
17
+ s.add_development_dependency('rake', '~>0.9')
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rosie
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Jon Rogers
9
+ - Jeremy Yun
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2011-08-19 00:00:00 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rspec
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :development
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: "0.9"
36
+ type: :development
37
+ version_requirements: *id002
38
+ description: Backup/Restore MySQL database and dependent filesystem assets via rake tasks.
39
+ email:
40
+ - j@2rye.com
41
+ executables: []
42
+
43
+ extensions: []
44
+
45
+ extra_rdoc_files: []
46
+
47
+ files:
48
+ - .gitignore
49
+ - .rvmrc
50
+ - Gemfile
51
+ - Gemfile.lock
52
+ - LICENSE
53
+ - README.md
54
+ - lib/rosie.rb
55
+ - lib/rosie/version.rb
56
+ - lib/tasks/rosie.rake
57
+ - rosie.gemspec
58
+ homepage: http://github.com/2rye/rosie
59
+ licenses: []
60
+
61
+ post_install_message:
62
+ rdoc_options: []
63
+
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ requirements: []
79
+
80
+ rubyforge_project: rosie
81
+ rubygems_version: 1.8.8
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: rosie-0.0.1
85
+ test_files: []
86
+