cap_sync 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +12 -32
- data/cap_sync.gemspec +2 -2
- data/lib/cap_sync/capistrano.rb +14 -0
- data/lib/cap_sync/data.rb +45 -0
- data/lib/cap_sync/db.rb +79 -0
- metadata +8 -8
- data/lib/cap_sync.rb +0 -81
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= Capistrano Sync Recipes
|
1
|
+
= Capistrano Db & Data Sync Recipes
|
2
2
|
|
3
3
|
Recipes to clone database & public data from production server to developement machine.
|
4
4
|
|
@@ -7,51 +7,31 @@ Recipes to clone database & public data from production server to developement m
|
|
7
7
|
Add this to your Gemfile
|
8
8
|
|
9
9
|
group :development do
|
10
|
-
gem 'cap_sync'
|
10
|
+
gem 'cap_sync'
|
11
11
|
end
|
12
12
|
|
13
|
-
Add following line to your
|
13
|
+
Add following line to your deploy.rb:
|
14
14
|
|
15
|
-
require 'cap_sync'
|
15
|
+
require 'cap_sync/capistrano'
|
16
16
|
|
17
17
|
= Syncing database
|
18
18
|
|
19
|
-
> cap sync:db
|
19
|
+
> bundle exec cap sync:db
|
20
20
|
|
21
|
-
|
22
|
-
1. Accesses production server.
|
23
|
-
2. Dumps database to app's tmp.
|
24
|
-
3. Downloads dump to local app's tmp.
|
25
|
-
4. Imports dump to local app's development database.
|
21
|
+
See lib/cap_sync/db.rb for list of available options.
|
26
22
|
|
27
|
-
|
28
|
-
|
29
|
-
Available variables and defaults:
|
30
|
-
:sync_local_env => 'development', # Local environment key in database.yml
|
31
|
-
:sync_remote_env => 'production', # Remote environment key in database.yml
|
32
|
-
:sync_remote_dump_cmd => 'mysqldump', # Remote mysqldump command
|
33
|
-
:sync_local_load_cmd => 'mysql', # Local mysqldump command
|
34
|
-
:sync_keep_dumps => false, # Keep downloaded dump in app's tmp after syncing
|
35
|
-
|
36
|
-
You can modify it in your deploy.rb as follows:
|
37
|
-
|
38
|
-
set :sync_local_cmd, '/usr/local/bin/mysql/bin'
|
23
|
+
You can set: local & remote environment, mysql dump/client command & flags, turn compression on/off, etc.
|
39
24
|
|
40
25
|
= Syncing data
|
41
26
|
|
42
|
-
> cap sync:data
|
27
|
+
> bundle exec cap sync:data
|
43
28
|
|
44
|
-
Rsync's local and remote folders. By default, does incremental implicit synchronization.
|
29
|
+
Rsync's local and remote folders. By default, does incremental implicit synchronization with rsync.
|
45
30
|
|
46
|
-
|
47
|
-
:sync_method => :rsync, # :rsync - sync with rsync, :cap - sync with capistrano
|
48
|
-
:sync_folders => {"#{shared_path}/system" => "public/system"}, # Folders to sync remote => local
|
49
|
-
:rsync_cmd => "rsync", # rsync command
|
50
|
-
:rsync_flags => "-rv --stats --delete" # rsync flags
|
31
|
+
See lib/cap_sync/data.rb for list of available options.
|
51
32
|
|
52
33
|
= Todo
|
53
34
|
|
54
35
|
1. Correctly handle multiple servers (database).
|
55
|
-
2.
|
56
|
-
3.
|
57
|
-
4. Sync up and down.
|
36
|
+
2. Envflags to modify options on the fly.
|
37
|
+
3. Win32 compability.
|
data/cap_sync.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "cap_sync"
|
6
|
-
s.version = '0.0.
|
6
|
+
s.version = '0.0.8'
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.author = "Victor Sokolov"
|
9
9
|
s.email = "gzigzigzeo@gmail.com"
|
@@ -15,4 +15,4 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
16
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
17
|
s.require_path = 'lib'
|
18
|
-
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
4
|
+
Capistrano::Configuration.instance(:must_exist) :
|
5
|
+
Capistrano.configuration(:must_exist)
|
6
|
+
|
7
|
+
configuration.load do
|
8
|
+
|
9
|
+
_cset(:app_name) { abort('Set the application name before loading "cap_sync"') }
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'cap_sync/db'
|
14
|
+
require 'cap_sync/data'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
4
|
+
Capistrano::Configuration.instance(:must_exist) :
|
5
|
+
Capistrano.configuration(:must_exist)
|
6
|
+
|
7
|
+
configuration.load do
|
8
|
+
|
9
|
+
_cset(:sync_folders, {"#{shared_path}/system" => "public/system"})
|
10
|
+
_cset(:sync_rsync_cmd, "rsync -rv --stats --delete --compress --skip-compress=jpg,gif,png,mp4")
|
11
|
+
|
12
|
+
# :sync for rsync, :cap for capistrano (used when rsync is not installed remotely)
|
13
|
+
_cset(:sync_method, :rsync)
|
14
|
+
|
15
|
+
namespace :sync do
|
16
|
+
desc "Sync remote production data with local development machine"
|
17
|
+
task :data do
|
18
|
+
folders_to_sync = sync_folders
|
19
|
+
|
20
|
+
if sync_method == :rsync
|
21
|
+
folders_to_sync.each do |remote, local|
|
22
|
+
host = find_servers(:roles => :web).first.host
|
23
|
+
system("#{sync_rsync_cmd} #{user}@#{host}:#{remote}/. #{local}")
|
24
|
+
end
|
25
|
+
elsif sync_method == :cap
|
26
|
+
folders_to_sync.each do |remote, local|
|
27
|
+
::FileUtils.rm_rf(local, :verbose => true)
|
28
|
+
download(remote, local, :recursive => true) do |event, downloader, *args|
|
29
|
+
case event
|
30
|
+
when :close then
|
31
|
+
puts "finished with #{args[0].remote}"
|
32
|
+
when :mkdir then
|
33
|
+
puts "creating directory #{args[0]}"
|
34
|
+
when :finish then
|
35
|
+
puts "all done!"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
else
|
40
|
+
raise ArgumentError, "Unknown sync method: should be :cap or :sync"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/lib/cap_sync/db.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
6
|
+
Capistrano::Configuration.instance(:must_exist) :
|
7
|
+
Capistrano.configuration(:must_exist)
|
8
|
+
|
9
|
+
configuration.load do
|
10
|
+
|
11
|
+
_cset(:sync_local_env, 'development')
|
12
|
+
_cset(:sync_remote_env, 'production')
|
13
|
+
_cset(:sync_local_load_cmd, 'mysql')
|
14
|
+
_cset(:sync_remote_dump_cmd, 'mysqldump')
|
15
|
+
_cset(:sync_local_tmp_path, 'tmp')
|
16
|
+
_cset(:sync_remote_tmp_path, "#{shared_path}/tmp")
|
17
|
+
_cset(:sync_local_keep_dumps, false)
|
18
|
+
_cset(:sync_remote_keep_dumps, false)
|
19
|
+
_cset(:sync_compress, true)
|
20
|
+
_cset(:sync_compress_cmd, 'gzip -c') # gzip -c #{dump} #{gzipped_dump}
|
21
|
+
|
22
|
+
# File should be kept after decompression if local_keep_dumps is on
|
23
|
+
_cset(:sync_uncompress_cmd, 'gunzip -c') # gunzip -c #{gzipped_dump} > #{dump}
|
24
|
+
|
25
|
+
namespace :sync do
|
26
|
+
desc "Sync remote production database with local development database"
|
27
|
+
task :db do
|
28
|
+
# Get the dump of remote database
|
29
|
+
username, password, database, host, port = remote_database_config(sync_remote_env)
|
30
|
+
dump = "sync-#{Time.now.to_i}.sql"
|
31
|
+
run "#{sync_remote_dump_cmd} -u #{username} --password=\"#{password}\" -h #{host} --port #{port} #{database} > #{sync_remote_tmp_path}/#{dump}"
|
32
|
+
|
33
|
+
# Compress and download it
|
34
|
+
if sync_compress
|
35
|
+
run "#{sync_compress_cmd} #{sync_remote_tmp_path}/#{dump} > #{sync_remote_tmp_path}/#{dump}.gz"
|
36
|
+
get "#{sync_remote_tmp_path}/#{dump}.gz", "#{sync_local_tmp_path}/#{dump}.gz"
|
37
|
+
system("#{sync_uncompress_cmd} -c #{sync_local_tmp_path}/#{dump}.gz > #{sync_local_tmp_path}/#{dump}")
|
38
|
+
else
|
39
|
+
get "#{sync_remote_tmp_path}/#{dump}", "#{sync_local_tmp_path}/#{dump}"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Load dump into local database
|
43
|
+
username, password, database, host, port = local_database_config(sync_local_env)
|
44
|
+
system("#{sync_local_load_cmd} #{database} -u#{username} --password=\"#{password}\" < #{sync_local_tmp_path}/#{dump}")
|
45
|
+
|
46
|
+
# Remove temporary files
|
47
|
+
unless sync_local_keep_dumps
|
48
|
+
FileUtils.rm("#{sync_local_tmp_path}/#{dump}")
|
49
|
+
FileUtils.rm("#{sync_local_tmp_path}/#{dump}.gz") if sync_compress
|
50
|
+
else
|
51
|
+
# If compression is on, keeps only gzipped dump
|
52
|
+
FileUtils.rm("#{sync_local_tmp_path}/#{dump}") if sync_compress
|
53
|
+
end
|
54
|
+
|
55
|
+
unless sync_remote_keep_dumps
|
56
|
+
run "rm #{sync_remote_tmp_path}/#{dump}"
|
57
|
+
run "rm #{sync_remote_tmp_path}/#{dump}.gz" if sync_compress
|
58
|
+
else
|
59
|
+
run "rm #{sync_remote_tmp_path}/#{dump}" if sync_compress
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
def local_database_config(env)
|
67
|
+
db = File.open("config/database.yml") { |yf| YAML::load(yf) }
|
68
|
+
defaults_config(db[env.to_s])
|
69
|
+
end
|
70
|
+
|
71
|
+
def remote_database_config(env)
|
72
|
+
remote_config = capture("cat #{current_path}/config/database.yml")
|
73
|
+
db = YAML::load(remote_config)
|
74
|
+
defaults_config(db[env.to_s])
|
75
|
+
end
|
76
|
+
|
77
|
+
def defaults_config(db)
|
78
|
+
return db['username'], db['password'], db['database'], (db['host'] || '127.0.0.1'), (db['port'] || 3306)
|
79
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cap_sync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 8
|
10
|
+
version: 0.0.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Victor Sokolov
|
@@ -15,8 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
19
|
-
default_executable:
|
18
|
+
date: 2011-12-15 00:00:00 Z
|
20
19
|
dependencies: []
|
21
20
|
|
22
21
|
description: Recipes to clone database & public data from production server to developement machine
|
@@ -33,8 +32,9 @@ files:
|
|
33
32
|
- README.rdoc
|
34
33
|
- Rakefile
|
35
34
|
- cap_sync.gemspec
|
36
|
-
- lib/cap_sync.rb
|
37
|
-
|
35
|
+
- lib/cap_sync/capistrano.rb
|
36
|
+
- lib/cap_sync/data.rb
|
37
|
+
- lib/cap_sync/db.rb
|
38
38
|
homepage: http://github.com/gzigzigzeo/cap_sync
|
39
39
|
licenses: []
|
40
40
|
|
@@ -64,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements: []
|
65
65
|
|
66
66
|
rubyforge_project:
|
67
|
-
rubygems_version: 1.
|
67
|
+
rubygems_version: 1.8.10
|
68
68
|
signing_key:
|
69
69
|
specification_version: 3
|
70
70
|
summary: Recipes to clone database & public data from production server to developement machine
|
data/lib/cap_sync.rb
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
require 'fileutils'
|
4
|
-
|
5
|
-
Capistrano::Configuration.instance(:must_exist).load do
|
6
|
-
{
|
7
|
-
:sync_local_env => 'development', # Local environment key in database.yml
|
8
|
-
:sync_remote_env => 'production', # Remote environment key in database.yml
|
9
|
-
:sync_remote_dump_cmd => 'mysqldump', # Remote mysqldump command
|
10
|
-
:sync_local_load_cmd => 'mysql', # Local mysqldump command
|
11
|
-
:sync_keep_dumps => false, # Keep downloaded dump in app's tmp after syncing
|
12
|
-
|
13
|
-
:sync_folders => {"#{shared_path}/system" => "public/system"}, # Folders to sync remote => local
|
14
|
-
:rsync_cmd => "rsync", # rsync command
|
15
|
-
:rsync_flags => "-rv --stats --delete", # rsync flags
|
16
|
-
:sync_method => :rsync # :rsync or :cap
|
17
|
-
}.each do |var, value|
|
18
|
-
self.set(var, value) unless exists?(var)
|
19
|
-
end
|
20
|
-
|
21
|
-
namespace :sync do
|
22
|
-
desc "Sync remote production database with local development machine"
|
23
|
-
task :db do
|
24
|
-
username, password, database, host, port = remote_database_config(sync_remote_env)
|
25
|
-
|
26
|
-
temp = "sync-#{Time.now.to_i}.sql"
|
27
|
-
run "#{sync_remote_dump_cmd} -u #{username} --password=\"#{password}\" -h #{host} --port #{port} #{database} > #{shared_path}/#{temp}"
|
28
|
-
get "#{shared_path}/#{temp}", "tmp/#{temp}"
|
29
|
-
|
30
|
-
username, password, database, host, port = local_database_config(sync_local_env)
|
31
|
-
|
32
|
-
system("#{sync_local_load_cmd} #{database} -u#{username} --password=\"#{password}\" < tmp/#{temp}")
|
33
|
-
FileUtils.rm("tmp/#{temp}") unless sync_keep_dumps
|
34
|
-
run "rm #{shared_path}/#{temp}"
|
35
|
-
end
|
36
|
-
|
37
|
-
desc "Sync remote production data with local development machine"
|
38
|
-
task :data do
|
39
|
-
folders_to_sync = Hash[*ENV['FOLDERS'].split(',')] unless ENV['FOLDERS'].nil?
|
40
|
-
folders_to_sync ||= sync_folders
|
41
|
-
|
42
|
-
if sync_method == :rsync
|
43
|
-
folders_to_sync.each do |remote, local|
|
44
|
-
host = find_servers(:roles => :web).first.host
|
45
|
-
system("#{rsync_cmd} #{rsync_flags} #{user}@#{host}:#{remote}/. #{local}")
|
46
|
-
end
|
47
|
-
elsif sync_method == :cap
|
48
|
-
folders_to_sync.each do |remote, local|
|
49
|
-
::FileUtils.rm_rf(local, :verbose => true)
|
50
|
-
download(remote, local, :recursive => true) do |event, downloader, *args|
|
51
|
-
case event
|
52
|
-
when :close then
|
53
|
-
puts "finished with #{args[0].remote}"
|
54
|
-
when :mkdir then
|
55
|
-
puts "creating directory #{args[0]}"
|
56
|
-
when :finish then
|
57
|
-
puts "all done!"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
else
|
62
|
-
raise ArgumentError, "Unknown sync method: should be :cap or :sync"
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def local_database_config(env)
|
68
|
-
db = File.open("config/database.yml") { |yf| YAML::load(yf) }
|
69
|
-
defaults_config(db[env.to_s])
|
70
|
-
end
|
71
|
-
|
72
|
-
def remote_database_config(env)
|
73
|
-
remote_config = capture("cat #{current_path}/config/database.yml")
|
74
|
-
db = YAML::load(remote_config)
|
75
|
-
defaults_config(db[env.to_s])
|
76
|
-
end
|
77
|
-
|
78
|
-
def defaults_config(db)
|
79
|
-
return db['username'], db['password'], db['database'], db['host'], (db['port'] || 3306)
|
80
|
-
end
|
81
|
-
end
|