capistrano-database 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/capistrano-database.gemspec +6 -6
- data/lib/capistrano/ext/database.rb +149 -0
- data/lib/capistrano/ext/mysql.rb +135 -0
- metadata +7 -5
data/capistrano-database.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
3
|
Gem::Specification.new do |gem|
|
4
|
-
gem.authors = [
|
5
|
-
gem.email = [
|
4
|
+
gem.authors = ['Wael M. Nasreddine']
|
5
|
+
gem.email = ['wael.nasreddine@gmail.com']
|
6
6
|
gem.description = 'Capistrano recipes for database server management'
|
7
7
|
gem.summary = gem.description
|
8
8
|
gem.homepage = 'http://technogate.github.com/contao'
|
@@ -11,12 +11,12 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.files = `git ls-files`.split($\)
|
12
12
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
13
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
-
gem.name =
|
15
|
-
gem.require_paths = [
|
16
|
-
gem.version = '0.0.
|
14
|
+
gem.name = 'capistrano-database'
|
15
|
+
gem.require_paths = ['lib']
|
16
|
+
gem.version = '0.0.2'
|
17
17
|
|
18
18
|
# Runtime dependencies
|
19
19
|
gem.add_dependency 'rake'
|
20
|
-
gem.add_dependency 'capistrano'
|
21
20
|
gem.add_dependency 'activesupport'
|
21
|
+
gem.add_dependency 'capistrano-utils'
|
22
22
|
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'capistrano/ext/helpers'
|
2
|
+
require 'capistrano/ext/mysql'
|
3
|
+
|
4
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
5
|
+
abort "capistrano/ext/database requires Capistrano 2"
|
6
|
+
end
|
7
|
+
|
8
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
9
|
+
namespace :db do
|
10
|
+
desc 'Backup the database'
|
11
|
+
task :backup, :roles => :db do
|
12
|
+
set :latest_backup,
|
13
|
+
"#{fetch :backup_path}/#{fetch :db_database_name}_#{Time.now.strftime('%d-%m-%Y_%H-%M-%S')}.sql"
|
14
|
+
transaction do
|
15
|
+
find_and_execute_db_task :backup
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'Export the database'
|
20
|
+
task :export, :roles => :db do
|
21
|
+
transaction do
|
22
|
+
backup
|
23
|
+
download_backup
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'Import the database'
|
28
|
+
task :import, :roles => :db do
|
29
|
+
transaction do
|
30
|
+
backup
|
31
|
+
backup_skiped_tables if exists_and_not_empty? :skip_tables_on_import
|
32
|
+
find_and_execute_db_task :import
|
33
|
+
restore_skiped_tables if exists_and_not_empty? :skip_tables_on_import
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
[:credentials, :root_credentials].each do |method|
|
38
|
+
desc "[internal] Print the database server #{method}"
|
39
|
+
task "print_#{method}", :roles => :app do
|
40
|
+
logger.trace format_credentials(fetch "db_#{method}".to_sym)
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "[internal] Load the database server #{method}"
|
44
|
+
task method, :roles => :app do
|
45
|
+
unless exists?("db_#{method}".to_sym)
|
46
|
+
if remote_file_exists?(fetch("db_#{method}_file".to_sym), use_sudo: method == :root_credentials)
|
47
|
+
send "read_#{method}"
|
48
|
+
else
|
49
|
+
send "generate_#{method}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "[internal] Read the database server #{method}"
|
55
|
+
task "read_#{method}", :roles => :app do
|
56
|
+
read(fetch("db_#{method}_file".to_sym), use_sudo: method == :root_credentials).tap do |content|
|
57
|
+
set "db_#{method}".to_sym, {
|
58
|
+
hostname: match_from_content(content, 'host'),
|
59
|
+
port: match_from_content(content, 'port'),
|
60
|
+
username: match_from_content(content, 'user'),
|
61
|
+
password: match_from_content(content, 'pass'),
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
desc "[internal] Generate the database server #{method}"
|
67
|
+
task "generate_#{method}", :roles => :app do
|
68
|
+
set "db_#{method}".to_sym, {
|
69
|
+
hostname: ask('What is the hostname used to access the database',
|
70
|
+
default: 'localhost',
|
71
|
+
validate: /.+/),
|
72
|
+
port: ask('What is the port used to access the database',
|
73
|
+
default: '',
|
74
|
+
validate: /\A[0-9]*\Z/),
|
75
|
+
username: ask('What is the username used to access the database',
|
76
|
+
default: (method == :credentials) ? fetch(:db_username) : 'root',
|
77
|
+
validate: /.+/),
|
78
|
+
password: ask('What is the password used to access the database',
|
79
|
+
default: gen_pass(8),
|
80
|
+
validate: /.+/,
|
81
|
+
echo: false),
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
desc "[internal] Write the database server #{method}"
|
86
|
+
task "write_#{method}", :roles => :app do
|
87
|
+
on_rollback { run "rm -f #{fetch("db_#{method}_file".to_sym)}" }
|
88
|
+
|
89
|
+
write format_credentials(fetch "db_#{method}".to_sym),
|
90
|
+
fetch("db_#{method}_file".to_sym),
|
91
|
+
use_sudo: method == :root_credentials
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
desc '[internal] Create the database user'
|
96
|
+
task :create_db_user, :roles => :db do
|
97
|
+
transaction do
|
98
|
+
find_and_execute_db_task :create_db_user
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
desc '[internal] Create the database'
|
103
|
+
task :create_database, :roles => :db do
|
104
|
+
transaction do
|
105
|
+
find_and_execute_db_task :create_database
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
desc '[internal] Download the db backup file'
|
110
|
+
task :download_backup, :roles => :db do
|
111
|
+
fn = "#{random_tmp_file}.sql.bz2"
|
112
|
+
on_rollback { `rm -f #{fn}` }
|
113
|
+
download "#{fetch :latest_backup}.bz2", fn
|
114
|
+
logger.important "The backup has been downloaded to #{fn}"
|
115
|
+
end
|
116
|
+
|
117
|
+
desc '[internal] Backup skiped tables'
|
118
|
+
task :backup_skiped_tables, :roles => :db do
|
119
|
+
set :backuped_skiped_tables_file, random_tmp_file
|
120
|
+
on_rollback { run "rm -f #{fetch :backuped_skiped_tables_file}" }
|
121
|
+
find_and_execute_db_task :backup_skiped_tables
|
122
|
+
end
|
123
|
+
|
124
|
+
desc '[internal] Restore skiped tables'
|
125
|
+
task :restore_skiped_tables, :roles => :db do
|
126
|
+
on_rollback { run "rm -f #{fetch :backuped_skiped_tables_file}" }
|
127
|
+
find_and_execute_db_task :restore_skiped_tables
|
128
|
+
run "rm -f #{fetch :backuped_skiped_tables_file}"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Internal Dependencies
|
133
|
+
before 'db:print_credentials', 'db:credentials'
|
134
|
+
before 'db:print_root_credentials', 'db:root_credentials'
|
135
|
+
before 'db:create_db_user', 'db:root_credentials'
|
136
|
+
before 'db:create_db_user', 'db:credentials'
|
137
|
+
before 'db:create_database', 'db:credentials'
|
138
|
+
before 'db:backup', 'db:credentials'
|
139
|
+
before 'db:import', 'db:credentials'
|
140
|
+
|
141
|
+
['credentials', 'root_credentials'].each do |method|
|
142
|
+
after "db:generate_#{method}", "db:write_#{method}"
|
143
|
+
end
|
144
|
+
|
145
|
+
# External Dependencies
|
146
|
+
before 'deploy:server:setup', 'db:create_db_user'
|
147
|
+
after 'deploy:server:setup', 'db:create_database'
|
148
|
+
before 'db:write_credentials', 'deploy:setup_if_needed'
|
149
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
2
|
+
abort "capistrano/ext/database requires Capistrano 2"
|
3
|
+
end
|
4
|
+
|
5
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
6
|
+
namespace :db do
|
7
|
+
namespace :mysql do
|
8
|
+
desc '[internal] Create the database user'
|
9
|
+
task :create_db_user, :roles => :db do
|
10
|
+
auth = fetch :db_credentials
|
11
|
+
sauth = fetch :db_root_credentials
|
12
|
+
|
13
|
+
script_file = write(<<-EOS)
|
14
|
+
CREATE USER '#{auth[:username]}'@'%' IDENTIFIED BY '#{auth[:password]}';
|
15
|
+
GRANT ALL ON `#{fetch :application}\_%`.* TO '#{auth[:username]}'@'%';
|
16
|
+
FLUSH PRIVILEGES;
|
17
|
+
EOS
|
18
|
+
|
19
|
+
begin
|
20
|
+
run <<-CMD
|
21
|
+
mysql \
|
22
|
+
--host='#{sauth[:hostname]}' \
|
23
|
+
--user='#{sauth[:username]}' \
|
24
|
+
--password='#{sauth[:password]}' \
|
25
|
+
--default-character-set=utf8 < \
|
26
|
+
#{script_file}; \
|
27
|
+
rm -f #{script_file}
|
28
|
+
CMD
|
29
|
+
rescue Capistrano::CommandError
|
30
|
+
logger.important 'ERROR: Could not create the user used to access the database.'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
desc '[internal] Create the database'
|
35
|
+
task :create_database, :roles => :db do
|
36
|
+
auth = fetch :db_credentials
|
37
|
+
|
38
|
+
begin
|
39
|
+
run <<-CMD
|
40
|
+
mysqladmin \
|
41
|
+
--host='#{auth[:hostname]}' \
|
42
|
+
--user='#{auth[:username]}' \
|
43
|
+
--password='#{auth[:password]}' \
|
44
|
+
create '#{fetch :db_database_name}'
|
45
|
+
CMD
|
46
|
+
rescue Capistrano::CommandError
|
47
|
+
logger.info 'ERROR: Could not create the database'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
desc '[internal] Backup mysql database'
|
52
|
+
task :backup, :roles => :db do
|
53
|
+
latest_backup = fetch :latest_backup
|
54
|
+
on_rollback { run "rm -f #{latest_backup}" }
|
55
|
+
auth = fetch :db_credentials
|
56
|
+
|
57
|
+
begin
|
58
|
+
run <<-CMD
|
59
|
+
#{try_sudo} mysqldump \
|
60
|
+
--host='#{auth[:hostname]}' \
|
61
|
+
--user='#{auth[:username]}' \
|
62
|
+
--password='#{auth[:password]}' \
|
63
|
+
--default-character-set=utf8 \
|
64
|
+
'#{fetch :db_database_name}' > \
|
65
|
+
'#{latest_backup}' &&
|
66
|
+
#{try_sudo} bzip2 -9 '#{latest_backup}'
|
67
|
+
CMD
|
68
|
+
rescue Capistrano::CommandError
|
69
|
+
abort 'Not able to backup the database'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
desc '[internal] Import a dump to the mysql database'
|
74
|
+
task :import, :roles => :db do
|
75
|
+
tmp_file = write File.read(arguments)
|
76
|
+
auth = fetch :db_credentials
|
77
|
+
|
78
|
+
begin
|
79
|
+
run <<-CMD
|
80
|
+
#{try_sudo} mysql \
|
81
|
+
--host='#{auth[:hostname]}' \
|
82
|
+
--user='#{auth[:username]}' \
|
83
|
+
--password='#{auth[:password]}' \
|
84
|
+
--default-character-set=utf8 \
|
85
|
+
'#{fetch :db_database_name}' < \
|
86
|
+
'#{tmp_file}' &&
|
87
|
+
rm -f '#{tmp_file}'
|
88
|
+
CMD
|
89
|
+
rescue Capistrano::CommandError
|
90
|
+
abort 'Failed to import the database'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
desc '[internal] Backup skiped tables from the mysql database'
|
95
|
+
task :backup_skiped_tables, :roles => :db do
|
96
|
+
auth = fetch :db_credentials
|
97
|
+
|
98
|
+
fetch(:skip_tables_on_import, []).each do |t|
|
99
|
+
begin
|
100
|
+
run <<-CMD
|
101
|
+
#{try_sudo} mysqldump \
|
102
|
+
--host='#{auth[:hostname]}' \
|
103
|
+
--user='#{auth[:username]}' \
|
104
|
+
--password='#{auth[:password]}' \
|
105
|
+
--default-character-set=utf8 \
|
106
|
+
'#{fetch :db_database_name}' '#{t}' >> \
|
107
|
+
'#{fetch :backuped_skiped_tables_file}'
|
108
|
+
CMD
|
109
|
+
rescue Capistrano::CommandError
|
110
|
+
logger.info "WARNING: It seems the database does not have the table '#{t}', skipping it."
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
desc '[internal] Restore skiped tables to the mysql database'
|
115
|
+
task :restore_skiped_tables, :roles => :db do
|
116
|
+
auth = fetch :db_credentials
|
117
|
+
|
118
|
+
begin
|
119
|
+
run <<-CMD
|
120
|
+
mysql \
|
121
|
+
--host='#{auth[:hostname]}' \
|
122
|
+
--user='#{auth[:username]}' \
|
123
|
+
--password='#{auth[:password]}' \
|
124
|
+
--default-character-set=utf8 \
|
125
|
+
'#{fetch :db_database_name}' < \
|
126
|
+
#{fetch :backuped_skiped_tables_file}
|
127
|
+
CMD
|
128
|
+
rescue
|
129
|
+
abort 'ERROR: I could not restore the tables defined in skip_tables_on_import'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-database
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -28,7 +28,7 @@ dependencies:
|
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
31
|
+
name: activesupport
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
47
|
+
name: capistrano-utils
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
@@ -72,6 +72,8 @@ files:
|
|
72
72
|
- README.md
|
73
73
|
- Rakefile
|
74
74
|
- capistrano-database.gemspec
|
75
|
+
- lib/capistrano/ext/database.rb
|
76
|
+
- lib/capistrano/ext/mysql.rb
|
75
77
|
homepage: http://technogate.github.com/contao
|
76
78
|
licenses: []
|
77
79
|
post_install_message:
|
@@ -92,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
94
|
version: '0'
|
93
95
|
segments:
|
94
96
|
- 0
|
95
|
-
hash:
|
97
|
+
hash: -1917011579952684110
|
96
98
|
requirements: []
|
97
99
|
rubyforge_project:
|
98
100
|
rubygems_version: 1.8.23
|