handy 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +3 -3
- data/Rakefile +8 -38
- data/lib/handy/backup.rb +19 -0
- data/lib/handy/db2db.rb +18 -0
- data/lib/handy/dump2s3.rb +9 -0
- data/lib/handy/railtie.rb +0 -1
- data/lib/handy/restore.rb +18 -0
- data/lib/handy/s3.rb +52 -0
- data/lib/handy/tasks.rb +22 -80
- data/lib/handy/util.rb +43 -0
- data/lib/handy/version.rb +1 -1
- data/lib/handy.rb +6 -0
- metadata +43 -6
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# handy provides follwing tools
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
##rake handy:db:restore file=xyz.sql.gz##
|
5
4
|
restores the data and structure from file
|
6
5
|
|
6
|
+
##rake handy:db:db2db##
|
7
|
+
restores the data from production database to staging database
|
7
8
|
|
8
|
-
* cap production handy:db:pull
|
9
9
|
|
10
10
|
|
11
11
|
Copyright (c) 2010 Neeraj Singh. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -4,13 +4,6 @@ require 'rake/testtask'
|
|
4
4
|
desc 'Default: run unit tests.'
|
5
5
|
task :default => :test
|
6
6
|
|
7
|
-
desc 'Test handy gem.'
|
8
|
-
Rake::TestTask.new(:test) do |t|
|
9
|
-
t.libs << 'lib' << 'test'
|
10
|
-
t.pattern = 'test/**/*_test.rb'
|
11
|
-
t.verbose = true
|
12
|
-
end
|
13
|
-
|
14
7
|
begin
|
15
8
|
require 'jeweler'
|
16
9
|
require './lib/handy/version'
|
@@ -23,42 +16,19 @@ begin
|
|
23
16
|
gem.homepage = "http://github.com/neerajdotname/handy"
|
24
17
|
gem.authors = ["Neeraj Singh"]
|
25
18
|
gem.files = FileList["[A-Z]*", "{lib,test}/**/*", 'init.rb']
|
19
|
+
|
20
|
+
gem.add_dependency('aws', '>= 2.3.21')
|
21
|
+
gem.add_dependency('capistrano', '>= 2.5.19')
|
26
22
|
end
|
27
23
|
Jeweler::GemcutterTasks.new
|
28
24
|
rescue LoadError
|
29
25
|
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
30
26
|
end
|
31
27
|
|
32
|
-
require 'rake/testtask'
|
33
|
-
Rake::TestTask.new(:test) do |test|
|
34
|
-
test.libs << 'lib' << 'test'
|
35
|
-
test.pattern = 'test/**/test_*.rb'
|
36
|
-
test.verbose = true
|
37
|
-
end
|
38
28
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
test.verbose = true
|
45
|
-
end
|
46
|
-
rescue LoadError
|
47
|
-
task :rcov do
|
48
|
-
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
task :test => :check_dependencies
|
53
|
-
|
54
|
-
task :default => :test
|
55
|
-
|
56
|
-
require 'rake/rdoctask'
|
57
|
-
Rake::RDocTask.new do |rdoc|
|
58
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
59
|
-
|
60
|
-
rdoc.rdoc_dir = 'rdoc'
|
61
|
-
rdoc.title = "handy #{version}"
|
62
|
-
rdoc.rdoc_files.include('README*')
|
63
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
29
|
+
desc 'Test handy gem.'
|
30
|
+
Rake::TestTask.new(:test) do |t|
|
31
|
+
t.libs << 'lib' << 'test'
|
32
|
+
t.pattern = 'test/**/*_test.rb'
|
33
|
+
t.verbose = true
|
64
34
|
end
|
data/lib/handy/backup.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Handy
|
2
|
+
|
3
|
+
class Backup
|
4
|
+
def self.run(env, file, backup_file)
|
5
|
+
util = Util.retrieve_db_info(env)
|
6
|
+
cmd = util.mysqldump_command
|
7
|
+
cmd << " --opt --skip-add-locks #{util.database} >> #{file}"
|
8
|
+
Util.execute_cmd(cmd)
|
9
|
+
|
10
|
+
#-c --stdout write on standard output, keep original files unchanged
|
11
|
+
#-q quite
|
12
|
+
#-9 best compression
|
13
|
+
Util.execute_cmd "gzip -q9 #{file}"
|
14
|
+
Util.execute_cmd "mv #{file}.gz #{backup_file}"
|
15
|
+
Util.pretty_msg "Backup done at #{File.expand_path(backup_file)}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/lib/handy/db2db.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Handy
|
2
|
+
class Db2db
|
3
|
+
def self.run(from_env, to_env, file)
|
4
|
+
from_params = "-Q --add-drop-table -O add-locks=FALSE -O lock-tables=FALSE"
|
5
|
+
from_util = Util.retrieve_db_info(from_env)
|
6
|
+
cmd = from_util.mysqldump_command
|
7
|
+
cmd << " #{from_params} #{from_util.database} > #{file} "
|
8
|
+
Util.execute_cmd(cmd)
|
9
|
+
|
10
|
+
to_util = Util.retrieve_db_info(to_env)
|
11
|
+
cmd = to_util.mysql_command
|
12
|
+
cmd << " < #{file}"
|
13
|
+
Util.execute_cmd(cmd)
|
14
|
+
|
15
|
+
Util.pretty_msg "#{to_env} database has been restored with #{from_env} database"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/handy/railtie.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Handy
|
2
|
+
class Restore
|
3
|
+
def self.run(file, env)
|
4
|
+
util = Util.retrieve_db_info(env)
|
5
|
+
|
6
|
+
if file =~ /\.gz/
|
7
|
+
puts "decompressing backup"
|
8
|
+
result = system("gzip -d #{file}" )
|
9
|
+
raise("backup decompression failed. msg: #{$?}" ) unless result
|
10
|
+
end
|
11
|
+
|
12
|
+
cmd = "#{util.mysql_command} < #{file.gsub('.gz','')}"
|
13
|
+
|
14
|
+
Util.execute_cmd(cmd)
|
15
|
+
Util.pretty_msg "database has been restored"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/handy/s3.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
module Handy
|
2
|
+
class S3
|
3
|
+
|
4
|
+
attr_accessor :bucket_name, :access_key_id, :secret_access_key
|
5
|
+
def initialize
|
6
|
+
config = YAML.load_file(Rails.root.join('config', 'amazon_s3.yml'))
|
7
|
+
unless File.exists?(config)
|
8
|
+
raise "file config/amazon_s3.yml was not found. Create a file as per http://gist.github.com/619432"
|
9
|
+
end
|
10
|
+
self.new(config[env]['username'], config[env]['password'], config[env]['database'])
|
11
|
+
@bucket_name = config[env]['bucket_name']
|
12
|
+
@access_key_id = config[env]['access_key_id']
|
13
|
+
@secret_access_key = config[env]['secret_access_key']
|
14
|
+
end
|
15
|
+
|
16
|
+
def connect
|
17
|
+
AWS::S3::Base.establish_connection!(access_key_id, secret_access_key)
|
18
|
+
AWS::S3::Bucket.create(bucket)
|
19
|
+
end
|
20
|
+
|
21
|
+
def store
|
22
|
+
connect
|
23
|
+
AWS::S3::S3Object.store(file_name, file, bucket)
|
24
|
+
end
|
25
|
+
|
26
|
+
def fetch(file_name)
|
27
|
+
connected
|
28
|
+
AWS::S3::S3Object.find(file_name, bucket)
|
29
|
+
|
30
|
+
file = Tempfile.new("dump")
|
31
|
+
open(file.path, 'w') do |f|
|
32
|
+
AWS::S3::S3Object.stream(file_name, bucket) do |chunk|
|
33
|
+
f.write chunk
|
34
|
+
end
|
35
|
+
end
|
36
|
+
file
|
37
|
+
end
|
38
|
+
|
39
|
+
def list
|
40
|
+
connect
|
41
|
+
AWS::S3::Bucket.find(bucket).objects.collect {|x| x.path }
|
42
|
+
end
|
43
|
+
|
44
|
+
def delete(file_name)
|
45
|
+
if object = AWS::S3::S3Object.find(file_name, bucket)
|
46
|
+
object.delete
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
data/lib/handy/tasks.rb
CHANGED
@@ -1,24 +1,3 @@
|
|
1
|
-
class Util
|
2
|
-
attr_accessor :username, :password, :database
|
3
|
-
def initialize(*args)
|
4
|
-
@username, @password, @database = *args
|
5
|
-
end
|
6
|
-
|
7
|
-
def self.retrieve_db_info(database_yml_file, env)
|
8
|
-
config = YAML.load_file(database_yml_file)
|
9
|
-
[ config[env]['database'], config[env]['user'], config[env]['password'] ]
|
10
|
-
end
|
11
|
-
|
12
|
-
def mysql_command
|
13
|
-
password.blank? ? "mysql -u #{user} #{database}" : "mysql -u #{user} -p'#{password}' #{database}"
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.execute_cmd(cmd)
|
17
|
-
puts cmd
|
18
|
-
system cmd
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
1
|
namespace :handy do
|
23
2
|
namespace :db do
|
24
3
|
|
@@ -27,53 +6,26 @@ namespace :handy do
|
|
27
6
|
puts "Usage: rake handy:db:restore file=xxxxxxxxx.sql[.gz]"
|
28
7
|
file_name = ENV['file']
|
29
8
|
raise "file was not supplied. Check Usage." unless file_name
|
30
|
-
|
31
|
-
raise "file was not found" unless File.exists?(
|
32
|
-
|
33
|
-
db_info = Util.retrieve_db_info("#{Rails.root}/config/database.yml", Rails.env)
|
34
|
-
database, user, password = db_info
|
35
|
-
util = Util.new(db_info)
|
36
|
-
|
37
|
-
if restore_file =~ /\.gz/
|
38
|
-
puts "decompressing backup"
|
39
|
-
result = system("gzip -d #{restore_file}" )
|
40
|
-
raise("backup decompression failed. msg: #{$?}" ) unless result
|
41
|
-
end
|
9
|
+
file = File.join(Rails.root, 'tmp', file_name)
|
10
|
+
raise "file was not found" unless File.exists?(file)
|
42
11
|
|
43
|
-
|
44
|
-
|
45
|
-
Util.execute_cmd(cmd)
|
46
|
-
puts "database has been restored"
|
12
|
+
Handy::Restore.run(file, Rails.env)
|
47
13
|
end
|
48
14
|
|
49
|
-
desc
|
15
|
+
desc <<-DESC
|
16
|
+
This task backups the database to a file. It will keep a maximum of 10 backed up copies.
|
17
|
+
The files are backed up at shared directory on remote server.
|
18
|
+
This task should be executed before any deploy to production.
|
19
|
+
Files are backed at Rails.root/../../shared/db_backups on the remote server
|
20
|
+
DESC
|
50
21
|
task :backup => [:environment] do
|
51
|
-
desc <<-DESC
|
52
|
-
This task backups the database to a file. It will keep a maximum of 10 backed up copies.
|
53
|
-
The files are backed up at shared directory on remote server.
|
54
|
-
This task should be executed before any deploy to production.
|
55
|
-
Files are backed at Rails.root/../../shared/db_backups on the remote server
|
56
|
-
DESC
|
57
|
-
|
58
22
|
timestamp = ENV['timestamp'] || Time.zone.now.strftime("%Y-%m-%d-%H-%M-%S")
|
59
|
-
|
23
|
+
file = "#{timestamp}.sql"
|
60
24
|
backup_dir = File.join (Rails.root, 'tmp')
|
61
|
-
|
62
|
-
backup_file = File.join(backup_dir, "#{file_name}.gz")
|
63
|
-
|
64
25
|
FileUtils.mkdir_p(backup_dir) unless File.exists?(backup_dir) && File.directory?(backup_dir)
|
26
|
+
backup_file = File.join(backup_dir, "#{file}.gz")
|
65
27
|
|
66
|
-
|
67
|
-
cmd = "mysqldump --opt --skip-add-locks -u#{user} -p#{password} #{database} >> #{file_name}"
|
68
|
-
Util.execute_cmd(cmd)
|
69
|
-
|
70
|
-
#-c --stdout write on standard output, keep original files unchanged
|
71
|
-
#-q quite
|
72
|
-
#-9 best compression
|
73
|
-
sh "gzip -q9 #{file_name}"
|
74
|
-
sh "mv #{file_name}.gz #{backup_file}"
|
75
|
-
puts "Backup done at #{File.expand_path(backup_file)}"
|
76
|
-
|
28
|
+
Handy::Backup.run(Rails.env, file, backup_file)
|
77
29
|
end
|
78
30
|
|
79
31
|
|
@@ -82,29 +34,19 @@ namespace :handy do
|
|
82
34
|
puts "Usage: handy:db:db2db from_env=production to_env=staging"
|
83
35
|
from_env = ENV['from_env'] || 'production'
|
84
36
|
to_env = ENV['to_env'] || 'staging'
|
85
|
-
|
86
|
-
config_file = "#{Rails.root}/config/database.yml"
|
87
|
-
|
88
|
-
db_config = YAML.load_file(config_file)
|
89
|
-
|
90
|
-
from_user = db_config[from_env]['username']
|
91
|
-
from_password = db_config[from_env]['password']
|
92
|
-
from_database = db_config[from_env]['database']
|
93
|
-
from_params = "-Q --add-drop-table -O add-locks=FALSE -O lock-tables=FALSE"
|
37
|
+
file = "#{Rails.root}/tmp/#{from_env}.data"
|
94
38
|
|
95
|
-
|
96
|
-
|
97
|
-
system cmd
|
98
|
-
|
99
|
-
to_username = db_config[to_env]['username']
|
100
|
-
to_password = db_config[to_env]['password']
|
101
|
-
to_database = db_config[to_env]['database']
|
39
|
+
Handy::Db2db.run(from_env, to_env, file)
|
40
|
+
end
|
102
41
|
|
103
|
-
|
104
|
-
|
105
|
-
|
42
|
+
desc "Copy database dump to s3"
|
43
|
+
task :dump2s3 => :environment do
|
44
|
+
timestamp = Time.zone.now.strftime("%Y-%m-%d-%H-%M-%S")
|
45
|
+
file = "#{timestamp}.sql.gz"
|
46
|
+
ENV['file'] = file
|
47
|
+
Rake::Task["handy:db:backup"].invoke
|
106
48
|
|
107
|
-
|
49
|
+
Handy::Dump2s3.run(Rails.env, file)
|
108
50
|
end
|
109
51
|
|
110
52
|
end
|
data/lib/handy/util.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Handy
|
2
|
+
|
3
|
+
class Util
|
4
|
+
attr_accessor :username, :password, :database
|
5
|
+
def initialize(*args)
|
6
|
+
@username, @password, @database = *args
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.retrieve_db_info(env)
|
10
|
+
config = YAML.load_file(Rails.root.join('config', 'database.yml'))
|
11
|
+
self.new(config[env]['username'], config[env]['password'], config[env]['database'])
|
12
|
+
end
|
13
|
+
|
14
|
+
def mysql_command
|
15
|
+
a = ['mysql']
|
16
|
+
a << "-u #{username}"
|
17
|
+
a << "-p'#{password}'" unless password.blank?
|
18
|
+
a << database
|
19
|
+
a.join(' ')
|
20
|
+
end
|
21
|
+
|
22
|
+
def mysqldump_command
|
23
|
+
a = ['mysqldump']
|
24
|
+
a << "-u #{username}"
|
25
|
+
a << "-p'#{password}'" unless password.blank?
|
26
|
+
a.join(' ')
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.execute_cmd(cmd)
|
30
|
+
puts "executing: #{cmd}"
|
31
|
+
system cmd
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.pretty_msg(msg)
|
35
|
+
puts ''
|
36
|
+
puts '*'*100
|
37
|
+
puts ('*' << ' '*5 << msg)
|
38
|
+
puts '*'*100
|
39
|
+
puts ''
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/lib/handy/version.rb
CHANGED
data/lib/handy.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: handy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Neeraj Singh
|
@@ -15,10 +15,41 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-10-
|
18
|
+
date: 2010-10-11 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: aws
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 41
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 3
|
33
|
+
- 21
|
34
|
+
version: 2.3.21
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: capistrano
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 61
|
46
|
+
segments:
|
47
|
+
- 2
|
48
|
+
- 5
|
49
|
+
- 19
|
50
|
+
version: 2.5.19
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
22
53
|
description: handy tools that gets job done
|
23
54
|
email: neerajdotname@gmail.com
|
24
55
|
executables: []
|
@@ -33,8 +64,14 @@ files:
|
|
33
64
|
- README.md
|
34
65
|
- Rakefile
|
35
66
|
- lib/handy.rb
|
67
|
+
- lib/handy/backup.rb
|
68
|
+
- lib/handy/db2db.rb
|
69
|
+
- lib/handy/dump2s3.rb
|
36
70
|
- lib/handy/railtie.rb
|
71
|
+
- lib/handy/restore.rb
|
72
|
+
- lib/handy/s3.rb
|
37
73
|
- lib/handy/tasks.rb
|
74
|
+
- lib/handy/util.rb
|
38
75
|
- lib/handy/version.rb
|
39
76
|
- test/helper.rb
|
40
77
|
- test/test_handy.rb
|