app-deployer 0.0.3
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.
- checksums.yaml +15 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +174 -0
- data/Rakefile +2 -0
- data/app-deployer.gemspec +19 -0
- data/lib/app-deployer.rb +11 -0
- data/lib/app-deployer/compass.rb +8 -0
- data/lib/app-deployer/composer.rb +68 -0
- data/lib/app-deployer/framework/cakephp/cakephp.rb +215 -0
- data/lib/app-deployer/framework/cakephp/templates/database.php.erb +14 -0
- data/lib/app-deployer/framework/lithium/lithium.rb +213 -0
- data/lib/app-deployer/framework/lithium/templates/connections.php.erb +64 -0
- data/lib/app-deployer/helpers.rb +142 -0
- data/lib/app-deployer/mysql/mysql.rb +42 -0
- data/lib/app-deployer/mysql/templates/create_database.sql.erb +7 -0
- data/lib/app-deployer/railsless-deploy.rb +399 -0
- data/lib/app-deployer/server/apache/apache.rb +59 -0
- data/lib/app-deployer/server/apache/templates/apache-vhost.erb +17 -0
- data/lib/app-deployer/server/apache/templates/maintenance.rhtml +52 -0
- data/lib/app-deployer/server/php-fpm.rb +10 -0
- data/lib/app-deployer/version.rb +5 -0
- metadata +94 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
class DATABASE_CONFIG {
|
|
3
|
+
public $default = array(
|
|
4
|
+
'datasource' => '<%= datasource %>',
|
|
5
|
+
'persistent' => '<%= persistent %>',
|
|
6
|
+
'host' => '<%= host %>',
|
|
7
|
+
'login' => '<%= login %>',
|
|
8
|
+
'password' => '<%= password %>',
|
|
9
|
+
'database' => '<%= database %>',
|
|
10
|
+
'prefix' => '<%= prefix %>',
|
|
11
|
+
'encoding' => '<%= encoding %>'
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
?>
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
|
2
|
+
|
|
3
|
+
require 'erb'
|
|
4
|
+
|
|
5
|
+
# =========================================================================
|
|
6
|
+
# Settings
|
|
7
|
+
# =========================================================================
|
|
8
|
+
|
|
9
|
+
_cset :shared_app_dirs, []
|
|
10
|
+
_cset(:lithium_repo) { "https://github.com/UnionOfRAD/lithium.git" }
|
|
11
|
+
_cset(:lithium_branch) { "master" }
|
|
12
|
+
_cset :shared_children, %w(libraries tmp)
|
|
13
|
+
_cset :tmp_children, %w(cache logs tests)
|
|
14
|
+
_cset :cache_children, %w(templates)
|
|
15
|
+
_cset :logs_files, %w(debug error)
|
|
16
|
+
_cset(:database_folder) { File.join(shared_path, "config/bootstrap") }
|
|
17
|
+
_cset(:database_path) { File.join("#{database_folder}", "connections.php") }
|
|
18
|
+
_cset(:tmp_path) { File.join(shared_path, "tmp") }
|
|
19
|
+
_cset(:cache_path) { File.join(tmp_path, "cache") }
|
|
20
|
+
_cset(:logs_path) { File.join(tmp_path, "logs") }
|
|
21
|
+
|
|
22
|
+
# =========================================================================
|
|
23
|
+
# Hooks
|
|
24
|
+
# =========================================================================
|
|
25
|
+
|
|
26
|
+
after('deploy:setup', 'lithium:setup')
|
|
27
|
+
after('deploy:create_symlink', 'lithium:create_symlink')
|
|
28
|
+
|
|
29
|
+
["composer:install", "composer:update"].each do |action|
|
|
30
|
+
before action do
|
|
31
|
+
if copy_vendors
|
|
32
|
+
composer.copy_vendors
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
after "deploy:finalize_update" do
|
|
38
|
+
if use_composer
|
|
39
|
+
if update_vendors
|
|
40
|
+
composer.update
|
|
41
|
+
else
|
|
42
|
+
composer.install
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
if clear_cache
|
|
46
|
+
lithium.cache.clear
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# =========================================================================
|
|
51
|
+
# Tasks
|
|
52
|
+
# =========================================================================
|
|
53
|
+
|
|
54
|
+
namespace :lithium do
|
|
55
|
+
|
|
56
|
+
desc <<-DESC
|
|
57
|
+
Prepares server for deployment of a lithium application. \
|
|
58
|
+
|
|
59
|
+
By default, it will create a shallow clone of the lithium repository \
|
|
60
|
+
inside #{shared_path}/libraries/lithium and run deploy:lithium:update.
|
|
61
|
+
DESC
|
|
62
|
+
task :setup do
|
|
63
|
+
transaction do
|
|
64
|
+
unless use_composer
|
|
65
|
+
run "cd #{shared_path}/libraries && git clone --depth 1 #{lithium_repo} lithium"
|
|
66
|
+
checkout
|
|
67
|
+
end
|
|
68
|
+
connections.setup
|
|
69
|
+
shared.setup
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
desc <<-DESC
|
|
74
|
+
Force lithium installation to checkout a new branch/tag.
|
|
75
|
+
DESC
|
|
76
|
+
task :checkout do
|
|
77
|
+
on_rollback { run "rm -rf #{shared_path}/lithium; true" }
|
|
78
|
+
stream "cd #{shared_path}/lithium && git checkout -q #{lithium_branch}"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
desc <<-DESC
|
|
82
|
+
Update the lithium repository to the latest version.
|
|
83
|
+
DESC
|
|
84
|
+
task :update do
|
|
85
|
+
stream "cd #{shared_path}/libraries/lithium && git pull"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
desc <<-DESC
|
|
89
|
+
This is a task that will get called from the deploy:create_symlink task
|
|
90
|
+
It runs just before the release is symlinked to the current directory
|
|
91
|
+
|
|
92
|
+
You should use it to create symlinks to things like your database config \
|
|
93
|
+
and any shared directories or files that your app uses
|
|
94
|
+
DESC
|
|
95
|
+
task :create_symlink do
|
|
96
|
+
transaction do
|
|
97
|
+
connections.create_symlink
|
|
98
|
+
shared.create_symlink
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Framework specific tasks
|
|
103
|
+
|
|
104
|
+
# Caching
|
|
105
|
+
namespace :cache do
|
|
106
|
+
desc <<-DESC
|
|
107
|
+
Clears cache and sub-directories.
|
|
108
|
+
|
|
109
|
+
Recursively finds all files in :cache_path and runs `rm -f` on each. If a file \
|
|
110
|
+
is renamed/removed after it was found but before it removes it, no error \
|
|
111
|
+
will prompt (-ignore_readdir_race). If symlinks are found, they will not be followed
|
|
112
|
+
|
|
113
|
+
You will rarely need to call this task directly; instead, use the `deploy' \
|
|
114
|
+
task (which performs a complete deploy, including `lithium:cache:clear')
|
|
115
|
+
DESC
|
|
116
|
+
task :clear, :roles => :web, :except => { :no_release => true } do
|
|
117
|
+
run "#{try_sudo} find -P #{cache_path} -ignore_readdir_race -type f -name '*' -exec rm -f {} \\;"
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Connections config
|
|
122
|
+
namespace :connections do
|
|
123
|
+
desc <<-DESC
|
|
124
|
+
Generates lithium connections file in #{shared_path}/config/bootstrap/ \
|
|
125
|
+
and symlinks #{current_path}/config/bootstrap/connections.php to it
|
|
126
|
+
DESC
|
|
127
|
+
task :setup, :roles => :web, :except => { :no_release => true } do
|
|
128
|
+
on_rollback { run "rm -f #{database_path}; true" }
|
|
129
|
+
puts "Connections setup"
|
|
130
|
+
|
|
131
|
+
prompt_with_default(:type, "database|MongoDb|http")
|
|
132
|
+
case type
|
|
133
|
+
when 'database'
|
|
134
|
+
prompt_with_default(:login, user)
|
|
135
|
+
set :password, Capistrano::CLI.password_prompt("password:")
|
|
136
|
+
prompt_with_default(:encoding, 'UTF-8')
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
prompt_with_default(:host, "127.0.0.1")
|
|
140
|
+
prompt_with_default(:database, application)
|
|
141
|
+
|
|
142
|
+
template = File.read(File.join(File.dirname(__FILE__), "templates", "connections.php.erb"))
|
|
143
|
+
result = ERB.new(template).result(binding)
|
|
144
|
+
|
|
145
|
+
run "#{try_sudo} mkdir -p #{database_folder}"
|
|
146
|
+
put(result, "#{database_path}", :mode => 0644, :via => :scp)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
desc <<-DESC
|
|
150
|
+
Symlinks the connections file.
|
|
151
|
+
DESC
|
|
152
|
+
task :create_symlink, :roles => :web, :except => { :no_release => true } do
|
|
153
|
+
run "#{try_sudo} ln -s #{database_path} #{current_path}/config/bootstrap/connections.php"
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Shared directories and files
|
|
158
|
+
namespace :shared do
|
|
159
|
+
desc <<-DESC
|
|
160
|
+
Creates shared folders on the server
|
|
161
|
+
DESC
|
|
162
|
+
task :setup do
|
|
163
|
+
dirs = [deploy_to, releases_path, shared_path]
|
|
164
|
+
dirs += shared_children.map { |d| File.join(shared_path, d) }
|
|
165
|
+
tmp_dirs = tmp_children.map { |d| File.join(tmp_path, d) }
|
|
166
|
+
tmp_dirs += cache_children.map { |d| File.join(cache_path, d) }
|
|
167
|
+
run "echo #{dirs} && #{try_sudo} mkdir -p #{(dirs + tmp_dirs).join(' ')} && #{try_sudo} chmod -R 777 #{tmp_path}" if (!user.empty?)
|
|
168
|
+
|
|
169
|
+
if shared_app_dirs
|
|
170
|
+
shared_app_dirs.each { | link | run "#{try_sudo} mkdir -p #{shared_path}/#{link}" }
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
desc <<-DESC
|
|
175
|
+
Symlinks all shared files and folders
|
|
176
|
+
DESC
|
|
177
|
+
task :create_symlink do
|
|
178
|
+
run "ln -s #{shared_path}/tmp #{latest_release}/resources/tmp";
|
|
179
|
+
if shared_app_dirs
|
|
180
|
+
shared_app_dirs.each { | link | run "ln -nfs #{shared_path}/#{link} #{current_path}/#{link}" }
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Logs
|
|
186
|
+
namespace :log do
|
|
187
|
+
desc <<-DESC
|
|
188
|
+
Clears logs and sub-directories
|
|
189
|
+
|
|
190
|
+
Recursively finds all files in :logs_path and runs `rm -f` on each. If a file \
|
|
191
|
+
is renamed/removed after it was found but before it removes it, no error \
|
|
192
|
+
will prompt (-ignore_readdir_race). If symlinks are found, they will not be followed
|
|
193
|
+
DESC
|
|
194
|
+
task :clear, :roles => :web, :except => { :no_release => true } do
|
|
195
|
+
run "#{try_sudo} find -P #{logs_path} -ignore_readdir_race -type f -name '*' -exec rm -f {} \\;"
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
desc <<-DESC
|
|
199
|
+
Streams the result of `tail -f` on all :logs_files \
|
|
200
|
+
|
|
201
|
+
By default, the files are `debug` and `error`. You can add your own \
|
|
202
|
+
in config/deploy.rb
|
|
203
|
+
|
|
204
|
+
set :logs_files %w(debug error my_log_file)
|
|
205
|
+
DESC
|
|
206
|
+
task :tail, :roles => :web, :except => { :no_release => true } do
|
|
207
|
+
files = logs_files.map { |d| File.join(logs_path, d) }
|
|
208
|
+
stream "#{try_sudo} tail -f #{files.join(' ')}"
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
end
|
|
213
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* Lithium: the most rad php framework
|
|
4
|
+
*
|
|
5
|
+
* @copyright Copyright 2012, Union of RAD (http://union-of-rad.org)
|
|
6
|
+
* @license http://opensource.org/licenses/bsd-license.php The BSD License
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* ### Configuring backend database connections
|
|
11
|
+
*
|
|
12
|
+
* Lithium supports a wide variety relational and non-relational databases, and is designed to allow
|
|
13
|
+
* and encourage you to take advantage of multiple database technologies, choosing the most optimal
|
|
14
|
+
* one for each task.
|
|
15
|
+
*
|
|
16
|
+
* As with other `Adaptable`-based configurations, each database configuration is defined by a name,
|
|
17
|
+
* and an array of information detailing what database adapter to use, and how to connect to the
|
|
18
|
+
* database server. Unlike when configuring other classes, `Connections` uses two keys to determine
|
|
19
|
+
* which class to select. First is the `'type'` key, which specifies the type of backend to
|
|
20
|
+
* connect to. For relational databases, the type is set to `'database'`. For HTTP-based backends,
|
|
21
|
+
* like CouchDB, the type is `'http'`. Some backends have no type grouping, like MongoDB, which is
|
|
22
|
+
* unique and connects via a custom PECL extension. In this case, the type is set to `'MongoDb'`,
|
|
23
|
+
* and no `'adapter'` key is specified. In other cases, the `'adapter'` key identifies the unique
|
|
24
|
+
* adapter of the given type, i.e. `'MySql'` for the `'database'` type, or `'CouchDb'` for the
|
|
25
|
+
* `'http'` type. Note that while adapters are always specified in CamelCase form, types are
|
|
26
|
+
* specified either in CamelCase form, or in underscored form, depending on whether an `'adapter'`
|
|
27
|
+
* key is specified. See the examples below for more details.
|
|
28
|
+
*
|
|
29
|
+
* ### Multiple environments
|
|
30
|
+
*
|
|
31
|
+
* As with other `Adaptable` classes, `Connections` supports optionally specifying different
|
|
32
|
+
* configurations per named connection, depending on the current environment. For information on
|
|
33
|
+
* specifying environment-based configurations, see the `Environment` class.
|
|
34
|
+
*
|
|
35
|
+
* @see lithium\core\Adaptable
|
|
36
|
+
* @see lithium\core\Environment
|
|
37
|
+
*/
|
|
38
|
+
use lithium\data\Connections;
|
|
39
|
+
<% case type
|
|
40
|
+
when 'database' %>
|
|
41
|
+
Connections::add('default', array(
|
|
42
|
+
'type' => 'database',
|
|
43
|
+
'adapter' => 'MySql',
|
|
44
|
+
'host' => '<%= host %>',
|
|
45
|
+
'login' => '<%= login %>',
|
|
46
|
+
'password' => '<%= password %>',
|
|
47
|
+
'database' => '<%= database %>',
|
|
48
|
+
'encoding' => '<%= encoding %>'
|
|
49
|
+
));
|
|
50
|
+
<% when 'http' %>
|
|
51
|
+
Connections::add('default', array(
|
|
52
|
+
'type' => 'http',
|
|
53
|
+
'adapter' => 'CouchDb',
|
|
54
|
+
'host' => '<%= host %>',
|
|
55
|
+
'database' => '<%= database %>'
|
|
56
|
+
));
|
|
57
|
+
<% else %>
|
|
58
|
+
Connections::add('default', array(
|
|
59
|
+
'type' => 'MongoDb',
|
|
60
|
+
'host' => '<%= host %>',
|
|
61
|
+
'database' => '<%= database %>'
|
|
62
|
+
));
|
|
63
|
+
<% end %>
|
|
64
|
+
?>
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
|
3
|
+
# =========================================================================
|
|
4
|
+
# These are helper methods that will be available to your recipes.
|
|
5
|
+
# =========================================================================
|
|
6
|
+
|
|
7
|
+
def _cset(name, *args, &block)
|
|
8
|
+
unless exists?(name)
|
|
9
|
+
set(name, *args, &block)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Asks the shell for a response or else uses the default if nothing
|
|
14
|
+
# is entered
|
|
15
|
+
def prompt_with_default(var, default, &block)
|
|
16
|
+
set(var) do
|
|
17
|
+
Capistrano::CLI.ui.ask("#{var} [#{default}] : ", &block)
|
|
18
|
+
end
|
|
19
|
+
set var, default if eval("#{var.to_s}.empty?")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Check to see if a file exists
|
|
23
|
+
def remote_file_exists?(full_path)
|
|
24
|
+
'true' == capture("if [ -e #{full_path} ]; then echo 'true'; fi").strip
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Auxiliary helper method for the `deploy:check' task. Lets you set up your
|
|
28
|
+
# own dependencies.
|
|
29
|
+
def depend(location, type, *args)
|
|
30
|
+
deps = fetch(:dependencies, {})
|
|
31
|
+
deps[location] ||= {}
|
|
32
|
+
deps[location][type] ||= []
|
|
33
|
+
deps[location][type] << args
|
|
34
|
+
set :dependencies, deps
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Temporarily sets an environment variable, yields to a block, and restores
|
|
38
|
+
# the value when it is done.
|
|
39
|
+
def with_env(name, value)
|
|
40
|
+
saved, ENV[name] = ENV[name], value
|
|
41
|
+
yield
|
|
42
|
+
ensure
|
|
43
|
+
ENV[name] = saved
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# logs the command then executes it locally.
|
|
47
|
+
# returns the command output as a string
|
|
48
|
+
def run_locally(cmd)
|
|
49
|
+
logger.trace "executing locally: #{cmd.inspect}" if logger
|
|
50
|
+
output_on_stdout = nil
|
|
51
|
+
elapsed = Benchmark.realtime do
|
|
52
|
+
output_on_stdout = `#{cmd}`
|
|
53
|
+
end
|
|
54
|
+
if $?.to_i > 0 # $? is command exit code (posix style)
|
|
55
|
+
raise Capistrano::LocalArgumentError, "Command #{cmd} returned status code #{$?}"
|
|
56
|
+
end
|
|
57
|
+
logger.trace "command finished in #{(elapsed * 1000).round}ms" if logger
|
|
58
|
+
output_on_stdout
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# If a command is given, this will try to execute the given command, as
|
|
62
|
+
# described below. Otherwise, it will return a string for use in embedding in
|
|
63
|
+
# another command, for executing that command as described below.
|
|
64
|
+
#
|
|
65
|
+
# If :run_method is :sudo (or :use_sudo is true), this executes the given command
|
|
66
|
+
# via +sudo+. Otherwise is uses +run+. If :as is given as a key, it will be
|
|
67
|
+
# passed as the user to sudo as, if using sudo. If the :as key is not given,
|
|
68
|
+
# it will default to whatever the value of the :admin_runner variable is,
|
|
69
|
+
# which (by default) is unset.
|
|
70
|
+
#
|
|
71
|
+
# THUS, if you want to try to run something via sudo, and what to use the
|
|
72
|
+
# root user, you'd just to try_sudo('something'). If you wanted to try_sudo as
|
|
73
|
+
# someone else, you'd just do try_sudo('something', :as => "bob"). If you
|
|
74
|
+
# always wanted sudo to run as a particular user, you could do
|
|
75
|
+
# set(:admin_runner, "bob").
|
|
76
|
+
def try_sudo(*args)
|
|
77
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
|
78
|
+
command = args.shift
|
|
79
|
+
raise ArgumentError, "too many arguments" if args.any?
|
|
80
|
+
|
|
81
|
+
as = options.fetch(:as, fetch(:admin_runner, nil))
|
|
82
|
+
via = fetch(:run_method, :sudo)
|
|
83
|
+
if command
|
|
84
|
+
invoke_command(command, :via => via, :as => as)
|
|
85
|
+
elsif via == :sudo
|
|
86
|
+
sudo(:as => as)
|
|
87
|
+
else
|
|
88
|
+
""
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Same as sudo, but tries sudo with :as set to the value of the :runner
|
|
93
|
+
# variable (which defaults to "app").
|
|
94
|
+
def try_runner(*args)
|
|
95
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
|
96
|
+
args << options.merge(:as => fetch(:runner, "app"))
|
|
97
|
+
try_sudo(*args)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def pretty_print(msg)
|
|
102
|
+
if logger.level == Capistrano::Logger::IMPORTANT
|
|
103
|
+
pretty_errors
|
|
104
|
+
|
|
105
|
+
msg = msg.slice(0, 57)
|
|
106
|
+
msg << '.' * (60 - msg.size)
|
|
107
|
+
print msg
|
|
108
|
+
else
|
|
109
|
+
puts msg.green
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def puts_ok
|
|
114
|
+
if logger.level == Capistrano::Logger::IMPORTANT && !$error
|
|
115
|
+
puts '✔'.green
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
$error = false
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def pretty_errors
|
|
122
|
+
if !$pretty_errors_defined
|
|
123
|
+
$pretty_errors_defined = true
|
|
124
|
+
|
|
125
|
+
class << $stderr
|
|
126
|
+
@@firstLine = true
|
|
127
|
+
alias _write write
|
|
128
|
+
|
|
129
|
+
def write(s)
|
|
130
|
+
if @@firstLine
|
|
131
|
+
s = '✘' << "\n" << s
|
|
132
|
+
@@firstLine = false
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
_write(s.red)
|
|
136
|
+
$error = true
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
|
2
|
+
namespace :mysql do
|
|
3
|
+
desc <<-DESC
|
|
4
|
+
Creates MySQL database, database user and grants permissions on DB servers
|
|
5
|
+
DESC
|
|
6
|
+
task :create, :roles => :db, :except => { :no_releases => true } do
|
|
7
|
+
require 'erb'
|
|
8
|
+
prompt_with_default(:mysql_admin_user, 'root')
|
|
9
|
+
_cset :mysql_admin_password, Capistrano::CLI.password_prompt("password:")
|
|
10
|
+
prompt_with_default(:mysql_grant_priv_type, 'ALL')
|
|
11
|
+
prompt_with_default(:mysql_grant_locations, 'localhost')
|
|
12
|
+
prompt_with_default(:db_login, user)
|
|
13
|
+
_cset :db_password, Capistrano::CLI.password_prompt("password:")
|
|
14
|
+
prompt_with_default(:db_name, application)
|
|
15
|
+
prompt_with_default(:db_encoding, 'utf8')
|
|
16
|
+
|
|
17
|
+
set :tmp_filename, File.join(shared_path, "config/create_db_#{db_name}.sql")
|
|
18
|
+
|
|
19
|
+
template = File.read(File.join(File.dirname(__FILE__), "../templates", "create_database.sql.erb"))
|
|
20
|
+
result = ERB.new(template).result(binding)
|
|
21
|
+
|
|
22
|
+
put(result, "#{tmp_filename}", :mode => 0644, :via => :scp)
|
|
23
|
+
|
|
24
|
+
run "mysql -u #{mysql_admin_user} -p#{mysql_admin_password} < #{tmp_filename}"
|
|
25
|
+
run "#{try_sudo} rm #{tmp_filename}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
desc <<-DESC
|
|
29
|
+
Exports MySQL database and copies it to the shared directory
|
|
30
|
+
DESC
|
|
31
|
+
task :export, :roles => :db, :except => { :no_releases => true } do
|
|
32
|
+
prompt_with_default(:mysql_admin_user, 'root')
|
|
33
|
+
_cset :mysql_admin_password, Capistrano::CLI.password_prompt("password:")
|
|
34
|
+
database = Capistrano::CLI.ui.ask("Which database should we export: ")
|
|
35
|
+
timestamp = Time.now.utc.strftime("%Y%m%d%H%M%S")
|
|
36
|
+
run "mysqldump -u #{mysql_admin_user} -p #{mysql_admin_password} > #{database}-#{timestamp}.sql"
|
|
37
|
+
download "#{database}-#{timestamp}.sql", "~/#{database}-#{timestamp}.sql"
|
|
38
|
+
logger.info "Database dump has been downloaded to ~/#{database}-#{timestamp}.sql"
|
|
39
|
+
run "rm #{database}-#{timestamp}.sql"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|