capistrano-extensions 0.1.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.
data/History.txt ADDED
@@ -0,0 +1,22 @@
1
+ # Created 2008-08-20
2
+
3
+ === v0.1.3 / 2008-08-25
4
+ * 2008-08-25 : VERSION BUMP
5
+ Introduced a new property :shared_content, which is intended to completely replace :content_directories
6
+ eventually. All directories previously specified by :content_directories go through a simple transformation
7
+ to match the new hash construct that is :shared_content. Now, we can specify non-public directories (though
8
+ they are still limited to within RAILS_ROOT), e.g.
9
+
10
+ set(:shared_content) { "feeds" => "content" }
11
+
12
+ This will create a symlink whose source is #{shared_path}/feeds and whose target is RAILS_ROOT/content.
13
+ Then, on successive deployments, this symlink is just recreated, and all of our feeds are still accessible
14
+ (because they were stored outside of RAILS_ROOT and then symlinked in).
15
+
16
+ === v0.1.2 / 2008-07-20
17
+ 2008-08-20
18
+ * Fixed a mysql bug that was encountered in "sync" operations. When passing a password on the command-line
19
+ (e.g. mysqldump -uuser -ppass), $'s in the password need to be escaped. I also fixed the scenario where
20
+ there was no password (common for restoring to the development environment). Previously you would be
21
+ prompted for a password only in the case where there was no password required. This was a result of
22
+ the way the mysql commands were being built: "mysql -u#{user} -p#{password}" where password was nil or ""
data/Manifest.txt ADDED
@@ -0,0 +1,11 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/capistrano-extensions-sync-content
6
+ bin/capistrano-extensions-sync-db
7
+ lib/capistrano-extensions.rb
8
+ lib/capistrano-extensions/deploy.rb
9
+ lib/capistrano-extensions/geminstaller_dependency.rb
10
+ lib/capistrano-extensions/version.rb
11
+
data/README.txt ADDED
@@ -0,0 +1,217 @@
1
+ = capistrano-extensions
2
+
3
+ * http://github.com/jtrupiano/capistrano-extensions
4
+
5
+ == DESCRIPTION/FEATURES:
6
+
7
+ This gem provides a base set of Capistrano extensions including the following:
8
+ * a new :gemfile RemoteDependency type
9
+ * tasks/helpers for handling public asset folders (e.g. created by the file_column plugin)
10
+ * tasks/helpers for auto-syncing server gems (via integration with Chad Wooley's GemInstaller gem)
11
+ * helpers for dealing with multiple deployable environments (e.g. staging, prodtest, production)
12
+ * tasks for working with remote logfiles
13
+ * tasks for database/asset synchronization from production back to local environments
14
+
15
+ == INCOMPLETE:
16
+ * Missing a detailed sample config file
17
+ * Describe the shortcomings (or rather my dissatisfaction) with the remote syncing executables for
18
+ assets/db. It works fine for now, but is a little wasteful.
19
+ * Database synchronization _only_ works for MySQL. (not sure if I intend to change this any time soon)
20
+ * This has really only been tested on single-server deployments, so I'm not sure how well it will work
21
+ on more complex environments -- I'll personally be able to test that in the coming month or two, but
22
+ that will be dictated by necessity.
23
+ * Still no support for user-uploaded assets stored outside of the public/ directory
24
+ * Need to automate the generation of this document: the descriptions for each attribute/task
25
+ should mirror the description in the deploy script (in other words, I should only have to update the
26
+ the documentation in one place).
27
+
28
+ == CAPISTRANO CODE EXTENSIONS:
29
+ * new RemoteDependency type :gemfile
30
+
31
+ depend(:remote, :gemfile, "config/geminstaller.yml")
32
+
33
+ Aliases the depend method (with depend_without_gemfile). Proxies all calls with :type != :gemfile
34
+ to the aliased method. When :type == :gemfile, the gems file is parsed (using geminstaller
35
+ codebase) to iteratively call depend_without_gemfile with each gem found in the YAML file.
36
+
37
+ This is still really only suitable for single-server deployments. The idea would be to add new
38
+ options to the geminstaller.yml config syntax that would allow us to reference specific
39
+ capistrano roles for a given gem. For instance, the database server won't need all of our rails
40
+ gems. A separate ferret server may require it's own set of gems, etc.
41
+
42
+ == NEW RECIPE PROPERTIES --> DEFAULTS
43
+ # Provides a way to specify which uploadable asset directories (that live in public/)
44
+ # should be retrievable via the local:copy_production_content and local:copy_production
45
+ # tasks described below. Note that this parameter is also utilized by the
46
+ # passenger-recipes gem to keep these uploadable assets in the shared/ context.
47
+ :content_directories --> []
48
+
49
+ # This property is similar to :content_directories, except it doesn't assume that the symlinks
50
+ # exist in the public/ directory (the default location for FileColumn file storage).
51
+ #
52
+ # This property is a hash of remote => local mappings, e.g.
53
+ #
54
+ # "feeds" => "content" (or "uploaded_assets/meal" => "public/meal")
55
+ #
56
+ # These examples will effectively create the following symlinks in a deployable environment:
57
+ # ln -sf \#{shared_path}/feeds RAILS_ROOT/content
58
+ # ln -sf \#{shared_path}/uploaded_assets/meal RAILS_ROOT/public/meal
59
+ #
60
+ # Each key (the "remote" directory) must be a directory found in \#{shared_path} (in a deployable environment)
61
+ # Each value (the "local" directory) must be a directory found in RAILS_ROOT (in a local environment)
62
+ :shared_content --> {}
63
+
64
+ # Which environments are deployable-- for each environment specified in this array,
65
+ # a helper function by the same name is created that is executed only if RAILS_ENV
66
+ # is set to that value. See examples/sample_deploy.rb for a code sample.
67
+ :deployable_environments --> [:production]
68
+
69
+ # We at SLS use a different config structure than rails does out of the box.
70
+ # Setting this value to :sls will alter some of the expected paths. Normally,
71
+ # you will not have to set this variable. To see a discussion of the SLS config
72
+ # file structure, see http://blog.smartlogicsolutions.com/2008/06/02/better-setup-for-environments-in-rails/
73
+ :config_structure --> :rails
74
+
75
+ == NEW RECIPES:
76
+ * deploy:create_shared_file_column_dirs
77
+
78
+ Creates shared filecolumn directories and symbolic links to them by
79
+ reading the :content_directories property. Note that this task is not invoked by default,
80
+ but rather is exposed to you as a helper. To utilize, you'll want to override
81
+ deploy:default and invoke this yourself.
82
+
83
+ * deploy:gem_update
84
+
85
+ Invokes geminstaller to ensure that the proper gem set is installed on the target server.
86
+ Note that this task is not invoked by default, but rather is exposed to you as a helper.
87
+
88
+ * log:pull
89
+
90
+ Tarballs deployable environment's rails logfile (identified by
91
+ RAILS_ENV environment variable, which defaults to 'production') and copies it to the local
92
+ filesystem
93
+
94
+ * local:backup_db
95
+
96
+ Backs up deployable environment's database (identified by the
97
+ RAILS_ENV environment variable, which defaults to 'production') and copies it to the local machine
98
+
99
+ * local:restore_db
100
+
101
+ Untars the backup file downloaded from local:backup_db (specified via the FROM env
102
+ variable, which defalts to RAILS_ENV), and imports (via mysql command line tool) it back into the database
103
+ defined in the RAILS_ENV env variable.
104
+
105
+ ToDo: implement proper rollback: currently, if the mysql import succeeds, but the rm fails,
106
+ the database won't be rolled back. Not sure this is even all that important or necessary, since
107
+ it's a local database that doesn't demand integrity (in other words, you're still going to have to
108
+ fix it, but it's not mission critical).
109
+
110
+ * local:backup_content
111
+
112
+ Downloads a tarball of uploaded content (that lives in public/ directory, as specified by
113
+ the :content_directories property) from the production site back to the local filesystem
114
+
115
+ * local:restore_content
116
+
117
+ Restores the backed up content (evn var FROM specifies which environment was backed up,
118
+ defaults to RAILS_ENV) to the local development environment app
119
+
120
+ * local:sync_db
121
+
122
+ Wrapper for local:backup_db and local:restore_db
123
+
124
+ $> cap local:sync_db RAILS_ENV=production RESTORE_ENV=development
125
+
126
+ * local:sync_content
127
+
128
+ Wrapper for local:backup_content and local:restore_content
129
+
130
+ $> cap local:sync_content RAILS_ENV=production RESTORE_ENV=development
131
+
132
+ * local:sync
133
+
134
+ Wrapper for local:sync_db and local:sync_content
135
+
136
+ $> cap local:sync RAILS_ENV=production RESTORE_ENV=development
137
+
138
+ * remote:restore_db
139
+
140
+ Uploads the backup file downloaded from local:backup_db (specified via the FROM env variable),
141
+ copies it to the remove environment specified by RAILS_ENV, and imports (via mysql command line
142
+ tool) it back into the remote database.
143
+
144
+ * remote:sync_db
145
+
146
+ Backs up target deployable environment's database (identified by the FROM environment variable,
147
+ which defaults to 'production') and restores it to the remote database identified by the TO
148
+ environment variable, which defaults to "staging."
149
+
150
+ Because multiple capistrano configurations must be loaded, an external executable
151
+ (capistrano-extensions-sync_db) is invoked, which independently calls capistrano. See the
152
+ executable at $GEM_HOME/capistrano-extensions-0.1.3/bin/capistrano-extensions-sync_db
153
+
154
+ $> cap remote:sync_db FROM=production TO=staging
155
+
156
+ * remote:restore_content
157
+
158
+ Uploads the backup file downloaded from local:backup_content (specified via the FROM env variable),
159
+ copies it to the remote environment specified by RAILS_ENV, and unpacks it into the shared/
160
+ directory.
161
+
162
+ * remote:sync_content
163
+
164
+ Backs up target deployable environment's shared content (identified by the FROM environment
165
+ variable, which defaults to 'production') and restores it to the remote environment identified
166
+ by the TO envrionment variable, which defaults to "staging."
167
+
168
+ Because multiple capistrano configurations must be loaded, an external executable
169
+ (capistrano-extensions-sync_content) is invoked, which independently calls capistrano. See the
170
+ executable at $GEM_HOME/capistrano-extensions-0.1.2/bin/capistrano-extensions-sync_content
171
+
172
+ $> cap remote:sync_content FROM=production TO=staging
173
+
174
+ * remote:sync
175
+
176
+ Wrapper fro remote:sync_db and remote:sync_content.
177
+
178
+ $> cap remote:sync FROM=production TO=staging
179
+
180
+ == SYNOPSIS:
181
+
182
+ FIX (code sample of usage)
183
+
184
+ == REQUIREMENTS:
185
+
186
+ * Capistrano = 2.4.3
187
+ * GemInstaller = 0.4.3
188
+
189
+ == INSTALL:
190
+
191
+ * rake gem
192
+ * sudo gem install pkg/capistrano-extensions-0.1.3.gem --local
193
+
194
+ == LICENSE:
195
+
196
+ (The MIT License)
197
+
198
+ Copyright (c) 2008 FIX
199
+
200
+ Permission is hereby granted, free of charge, to any person obtaining
201
+ a copy of this software and associated documentation files (the
202
+ 'Software'), to deal in the Software without restriction, including
203
+ without limitation the rights to use, copy, modify, merge, publish,
204
+ distribute, sublicense, and/or sell copies of the Software, and to
205
+ permit persons to whom the Software is furnished to do so, subject to
206
+ the following conditions:
207
+
208
+ The above copyright notice and this permission notice shall be
209
+ included in all copies or substantial portions of the Software.
210
+
211
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
212
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
213
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
214
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
215
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
216
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
217
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ # GEM_SPEC = eval(File.read("#{File.dirname(__FILE__)}/#{PKG_NAME}.gemspec"))
2
+ #
3
+ # Rake::GemPackageTask.new(GEM_SPEC) do |p|
4
+ # p.gem_spec = GEM_SPEC
5
+ # p.need_tar = true
6
+ # p.need_zip = true
7
+ # end
8
+ #
9
+ # desc "Clean up generated directories and files"
10
+ # task :clean do
11
+ # rm_rf "pkg"
12
+ # end
13
+
14
+
15
+ # -*- ruby -*-
16
+
17
+ require 'rubygems'
18
+ require 'hoe'
19
+ require './lib/capistrano-extensions.rb'
20
+ require "./lib/capistrano-extensions/version"
21
+
22
+
23
+ PKG_NAME = "capistrano-extensions"
24
+ PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
25
+ PKG_VERSION = CapistranoExtensions::Version::STRING + PKG_BUILD
26
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
27
+
28
+
29
+ Hoe.new('capistrano-extensions', PKG_VERSION) do |p|
30
+ p.rubyforge_name = 'environmentaliz' # if different than lowercase project name
31
+ # p.developer('FIX', 'FIX@example.com')
32
+ p.name = "capistrano-extensions"
33
+ p.version = PKG_VERSION
34
+ #p.platform = Gem::Platform::RUBY
35
+ p.author = "John Trupiano"
36
+ p.email = "jtrupiano@gmail.com"
37
+ p.description = %q(A base set of Capistrano extensions-- aids with the file_column plugin, the GemInstaller gem, multiple deployable environments, logfile helpers, and database/asset synchronization from production to local environment)
38
+ p.summary = p.description # More details later??
39
+ p.remote_rdoc_dir = 'capistrano-extensions' # Release to /capistrano-extensions
40
+ # p.changes = p.paragraphs_of('CHANGELOG', 0..1).join("\n\n")
41
+ p.extra_deps << ["capistrano", ">= 2.4.3"]
42
+ p.extra_deps << ["geminstaller", ">= 0.4.3"]
43
+ p.need_zip = true
44
+ p.need_tar = false
45
+ end
46
+
47
+ # vim: syntax=Ruby
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if ARGV.size < 2
4
+ puts "Improper invocation: capistrano-extensions-copy-production-db backup_env restore_env"
5
+ exit 1
6
+ end
7
+
8
+ system("cap local:backup_content RAILS_ENV=#{ARGV[0]}")
9
+ system("cap remote:restore_content RAILS_ENV=#{ARGV[1]} FROM=#{ARGV[0]}")
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if ARGV.size < 2
4
+ puts "Improper invocation: capistrano-extensions-copy-production-db backup_env restore_env"
5
+ exit 1
6
+ end
7
+
8
+ system("cap local:backup_db RAILS_ENV=#{ARGV[0]}")
9
+ system("cap remote:restore_db RAILS_ENV=#{ARGV[1]} FROM=#{ARGV[0]}")
@@ -0,0 +1,2 @@
1
+ gem 'capistrano', '>= 2.4.3' # load v2.4.3 or higher
2
+ gem 'geminstaller', '>= 0.4.3' # load v0.4.3 or higher
@@ -0,0 +1,324 @@
1
+ require 'capistrano-extensions/geminstaller_dependency'
2
+ require 'capistrano/server_definition'
3
+
4
+ # Overrides the majority of recipes from Capistrano's deploy recipe set.
5
+ Capistrano::Configuration.instance(:must_exist).load do
6
+ # Add sls_recipes to the load path
7
+ @load_paths << File.expand_path(File.dirname(__FILE__))
8
+
9
+ # ========================================================================
10
+ # These variables MUST be set in the client capfiles. If they are not set,
11
+ # the deploy will fail with an error.
12
+ # ========================================================================
13
+
14
+
15
+ # =========================================================================
16
+ # These variables may be set in the client capfile if their default values
17
+ # are not sufficient.
18
+ # =========================================================================
19
+
20
+ _cset(:content_directories, []) # I'd like to eventually remove this...
21
+ _cset(:shared_content, {})
22
+ _cset(:rails_env) { ENV['RAILS_ENV'].nil? ? fetch(:deployable_environments).first : ENV['RAILS_ENV'] }
23
+
24
+ # =========================================================================
25
+ # These variables should NOT be changed unless you are very confident in
26
+ # what you are doing. Make sure you understand all the implications of your
27
+ # changes if you do decide to muck with these!
28
+ # =========================================================================
29
+
30
+ set(:use_sudo, false) # we don't want to use sudo-- we don't have to!
31
+ set(:deploy_via, :export) # we don't want our .svn folders on the server!
32
+ _cset(:deploy_to) { "/var/www/vhosts/#{application}" }
33
+ _cset(:deployable_environments, [:production])
34
+
35
+ _cset(:rails_config_path) { File.join(latest_release, 'config') }
36
+ _cset(:db_conf) {
37
+ fetch(:config_structure, :rails).to_sym == :sls ?
38
+ File.join(rails_config_path, rails_env, 'database.yml') :
39
+ File.join(rails_config_path, 'database.yml')
40
+ }
41
+
42
+ # Where uploaded content is stored
43
+ _cset(:content_dir, "content")
44
+ _cset(:content_path) { File.join(shared_path, content_dir) }
45
+ _cset(:public_path) { File.join(latest_release, 'public') }
46
+ _cset(:log_path) { "/var/log/#{application}" }
47
+
48
+ # Allow recipes to ask for a certain local environment
49
+ def local_db_conf(env = nil)
50
+ env ||= fetch(:rails_env)
51
+ fetch(:config_structure, :rails).to_sym == :sls ?
52
+ File.join('config', env, 'database.yml') :
53
+ File.join('config', 'database.yml')
54
+ end
55
+
56
+ # Read from the local machine-- BE CAREFUL!!!
57
+ set(:db) { YAML.load_file(local_db_conf)[rails_env] }
58
+
59
+ # Let's define helpers for our deployable environments
60
+ # Can we possibly just infer this from the config directory structure?
61
+ deployable_environments.each do |env|
62
+ src = <<-CODE
63
+ def #{env.to_s}(&block)
64
+ if rails_env.to_s == '#{env.to_s}'
65
+ puts "*** Deploying to the \033[1;41m #{env.to_s.capitalize} \033[0m server!"
66
+ yield
67
+ puts <<-DEBUG
68
+ rails_env: \#{rails_env}
69
+ deploy_to: \#{deploy_to}
70
+ content_directories: \#{content_directories.join(', ')}
71
+ shared_content: \#{shared_content.keys.join(', ')}
72
+ DEBUG
73
+ end
74
+ end
75
+ CODE
76
+ eval src
77
+ end
78
+
79
+ # Now, let's actually include our common recipes!
80
+ namespace :deploy do
81
+ desc <<-DESC
82
+ [capistrano-extensions] Creates shared directories and symbolic links to them by the
83
+ :content_directories and :shared_content properties. See the README for
84
+ further explanation.
85
+ DESC
86
+ task :create_shared_file_column_dirs, :roles => :app, :except => { :no_release => true } do
87
+ mappings = content_directories.inject(shared_content) { |hsh, dir| hsh.merge({"content/#{dir}" => "public/#{dir}"}) }
88
+ mappings.each_pair do |remote, local|
89
+ run <<-CMD
90
+ mkdir -p #{shared_path}/#{remote} &&
91
+ ln -sf #{shared_path}/#{remote} #{latest_release}/#{local} &&
92
+ chmod 755 -R #{shared_path}/#{remote}
93
+ CMD
94
+ end
95
+ end
96
+
97
+ desc <<-DESC
98
+ [capistrano-extensions]: Invokes geminstaller to ensure that the proper gem set is installed on
99
+ the target server. Note that this task is not invoked by default, but rather is exposed to you
100
+ as a helper.
101
+ DESC
102
+ task :gem_update, :roles => :app do
103
+ run <<-CMD
104
+ gem sources -u &&
105
+ #{sudo} geminstaller -e -c #{rails_config_path}/geminstaller.yml
106
+ CMD
107
+ end
108
+
109
+ end
110
+
111
+ namespace :log do
112
+ desc <<-DESC
113
+ [capistrano-extensions]: Tarballs deployable environment's rails logfile (identified by
114
+ RAILS_ENV environment variable, which defaults to 'production') and copies it to the local
115
+ filesystem
116
+ DESC
117
+ task :pull do
118
+ tmp_location = "#{shared_path}/#{rails_env}.log.gz"
119
+ run "cp #{log_path}/#{rails_env}.log #{shared_path}/ && gzip #{shared_path}/#{rails_env}.log"
120
+ get "#{tmp_location}", "#{application}-#{rails_env}.log.gz"
121
+ run "rm #{tmp_location}"
122
+ end
123
+ end
124
+
125
+ namespace :remote do
126
+ desc <<-DESC
127
+ [capistrano-extensions] Uploads the backup file downloaded from local:backup_db (specified via the FROM env variable),
128
+ copies it to the remove environment specified by RAILS_ENV, and imports (via mysql command line tool) it back into the
129
+ remote database.
130
+ DESC
131
+ task :restore_db, :roles => :db do
132
+ env = ENV['FROM'] || 'production'
133
+
134
+ puts "\033[1;41m Restoring database backup to #{rails_env} environment \033[0m"
135
+ if deployable_environments.include?(rails_env.to_sym)
136
+ # remote environment
137
+ local_backup_file = "#{application}-#{env}-db.sql.gz"
138
+ remote_file = "#{shared_path}/restore_db.sql"
139
+ if !File.exists?(local_backup_file)
140
+ puts "Could not find backup file: #{local_backup_file}"
141
+ exit 1
142
+ end
143
+ upload(local_backup_file, "#{remote_file}.gz")
144
+
145
+ pass_str = pluck_pass_str(db)
146
+ run "gunzip -f #{remote_file}.gz"
147
+ run "mysql -u#{db['username']} #{pass_str} #{db['database']} < #{remote_file}"
148
+ run "rm -f #{remote_file}"
149
+ end
150
+ end
151
+
152
+ desc <<-DESC
153
+ [capistrano-extensions]: Backs up target deployable environment's database (identified
154
+ by the FROM environment variable, which defaults to 'production') and restores it to
155
+ the remote database identified by the TO environment variable, which defaults to "staging."
156
+ DESC
157
+ task :sync_db do
158
+ system("capistrano-extensions-sync-db #{ENV['FROM'] || 'production'} #{ENV['TO'] || 'staging'}")
159
+ end
160
+
161
+ desc <<-DESC
162
+ [capistrano-extensions]: Uploads the backup file downloaded from local:backup_content (specified via the
163
+ FROM env variable), copies it to the remote environment specified by RAILS_ENV, and unpacks it into the
164
+ shared/ directory.
165
+ DESC
166
+ task :restore_content do
167
+ from = ENV['FROM'] || 'production'
168
+
169
+ if deployable_environments.include?(rails_env.to_sym)
170
+ local_backup_file = "#{application}-#{from}-content_backup.tar.gz"
171
+ remote_file = "#{shared_path}/content_backup.tar.gz"
172
+
173
+ if !File.exists?(local_backup_file)
174
+ puts "Could not find backup file: #{local_backup_file}"
175
+ exit 1
176
+ end
177
+
178
+ upload(local_backup_file, "#{remote_file}")
179
+ remote_dirs = ["content"] + shared_content.keys
180
+
181
+ run("cd #{shared_path} && rm -rf #{remote_dirs.join(' ')} && tar xzf #{remote_file} -C #{shared_path}/")
182
+ end
183
+ end
184
+
185
+ desc <<-DESC
186
+ [capistrano-extensions]: Backs up target deployable environment's shared content (identified by the FROM environment
187
+ variable, which defaults to 'production') and restores it to the remote environment identified
188
+ by the TO envrionment variable, which defaults to "staging."
189
+
190
+ Because multiple capistrano configurations must be loaded, an external executable
191
+ (capistrano-extensions-sync_content) is invoked, which independently calls capistrano. See the
192
+ executable at $GEM_HOME/capistrano-extensions-0.1.2/bin/capistrano-extensions-sync_content
193
+
194
+ $> cap remote:sync_content FROM=production TO=staging
195
+ DESC
196
+ task :sync_content do
197
+ system("capistrano-extensions-sync-content #{ENV['FROM'] || 'production'} #{ENV['TO'] || 'staging'}")
198
+ end
199
+
200
+ desc <<-DESC
201
+ [capistrano-extensions]: Wrapper fro remote:sync_db and remote:sync_content.
202
+ $> cap remote:sync FROM=production TO=staging
203
+ DESC
204
+ task :sync do
205
+ sync_db
206
+ sync_content
207
+ end
208
+ end
209
+
210
+ namespace :local do
211
+ desc <<-DESC
212
+ [capistrano-extensions]: Backs up deployable environment's database (identified by the
213
+ RAILS_ENV environment variable, which defaults to 'production') and copies it to the local machine
214
+ DESC
215
+ task :backup_db, :roles => :db do
216
+ pass_str = pluck_pass_str(db)
217
+
218
+ run "mysqldump -u#{db['username']} #{pass_str} #{db['database']} > #{shared_path}/db_backup.sql"
219
+ run "gzip #{shared_path}/db_backup.sql"
220
+ get "#{shared_path}/db_backup.sql.gz", "#{application}-#{rails_env}-db.sql.gz"
221
+ run "rm -f #{shared_path}/db_backup.sql.gz #{shared_path}/db_backup.sql"
222
+ end
223
+
224
+ desc <<-DESC
225
+ [capistrano-extensions] Untars the backup file downloaded from local:backup_db (specified via the FROM env
226
+ variable, which defalts to RAILS_ENV), and imports (via mysql command line tool) it back into the database
227
+ defined in the RAILS_ENV env variable.
228
+
229
+ ToDo: implement proper rollback: currently, if the mysql import succeeds, but the rm fails,
230
+ the database won't be rolled back. Not sure this is even all that important or necessary, since
231
+ it's a local database that doesn't demand integrity (in other words, you're still going to have to
232
+ fix it, but it's not mission critical).
233
+ DESC
234
+ task :restore_db, :roles => :db do
235
+ on_rollback { "gzip #{application}-#{from}-db.sql"}
236
+
237
+ from = ENV['FROM'] || rails_env
238
+
239
+ env = ENV['RESTORE_ENV'] || 'development'
240
+ y = YAML.load_file(local_db_conf(env))[env]
241
+ db, user = y['database'], (y['username'] || 'root') # update me!
242
+
243
+ pass_str = pluck_pass_str(y)
244
+
245
+ puts "\033[1;41m Restoring database backup to #{env} environment \033[0m"
246
+ # local
247
+ system <<-CMD
248
+ gunzip #{application}-#{from}-db.sql.gz &&
249
+ mysql -u#{user} #{pass_str} #{db} < #{application}-#{from}-db.sql
250
+ CMD
251
+ end
252
+
253
+ desc <<-DESC
254
+ [capistrano-extensions]: Downloads a tarball of uploaded content (that lives in public/
255
+ directory, as specified by the :content_directories property) from the production site
256
+ back to the local filesystem
257
+ DESC
258
+ task :backup_content do
259
+ folders = ["content"] + shared_content.keys
260
+
261
+ run "cd #{shared_path} && tar czf #{shared_path}/content_backup.tar.gz #{folders.join(' ')}"
262
+
263
+ #run "cd #{content_path} && tar czf #{shared_path}/content_backup.tar.gz *"
264
+ get "#{shared_path}/content_backup.tar.gz", "#{application}-#{rails_env}-content_backup.tar.gz"
265
+ run "rm -f #{shared_path}/content_backup.tar.gz"
266
+ end
267
+
268
+ desc <<-DESC
269
+ [capistrano-extensions]: Restores the backed up content (evn var FROM specifies which environment
270
+ was backed up, defaults to RAILS_ENV) to the local development environment app
271
+ DESC
272
+ task :restore_content do
273
+ from = ENV['FROM'] || rails_env
274
+
275
+ system "tar xzf #{application}-#{from}-content_backup.tar.gz -C public/"
276
+ system "rm -f #{application}-#{from}-content_backup.tar.gz"
277
+
278
+ shared_content.each_pair do |remote, local|
279
+ system "rm -rf #{local} && mv public/#{remote} #{local}"
280
+ end
281
+
282
+ end
283
+
284
+ desc <<-DESC
285
+ [capistrano-extensions]: Wrapper for local:backup_db and local:restore_db.
286
+ $> cap local:sync_db RAILS_ENV=production RESTORE_ENV=development
287
+ DESC
288
+ task :sync_db do
289
+ transaction do
290
+ backup_db
291
+ ENV['FROM'] = rails_env
292
+ restore_db
293
+ end
294
+ end
295
+
296
+ desc <<-DESC
297
+ [capistrano-extensions]: Wrapper for local:backup_content and local:restore_content
298
+ $> cap local:sync_content RAILS_ENV=production RESTORE_ENV=development
299
+ DESC
300
+ task :sync_content do
301
+ transaction do
302
+ backup_content
303
+ restore_content
304
+ end
305
+ end
306
+
307
+ desc <<-DESC
308
+ [capistrano-extensions]: Wrapper for local:sync_db and local:sync_content
309
+ $> cap local:sync RAILS_ENV=production RESTORE_ENV=development
310
+ DESC
311
+ task :sync do
312
+ sync_db
313
+ sync_content
314
+ end
315
+ end
316
+ end
317
+
318
+ def pluck_pass_str(db_config)
319
+ pass_str = db_config['password']
320
+ if !pass_str.nil?
321
+ pass_str = "-p#{pass_str.gsub('$', '\$')}"
322
+ end
323
+ pass_str || ''
324
+ end
@@ -0,0 +1,35 @@
1
+ require 'geminstaller'
2
+
3
+ Capistrano::Configuration.instance(:must_exist).load do
4
+
5
+ def pluck_accessor_hash(obj, attrs = [])
6
+ ret = {}
7
+ attrs.each do |attr|
8
+ ret[attr] = obj.send(attr)
9
+ end
10
+ ret
11
+ end
12
+
13
+ alias :depend_without_gemfile :depend
14
+
15
+ # Auxiliary helper method for the `deploy:check' task. Lets you set up your
16
+ # own dependencies.
17
+ def depend(location, type, *args)
18
+ if type == :gemfile
19
+ registry = GemInstaller::Registry.new
20
+ config_builder = registry.config_builder
21
+ path = args.pop
22
+ config_builder.config_file_paths = path
23
+ config = config_builder.build_config
24
+ gems = config.gems
25
+
26
+ gems.each do |agem|
27
+ # gem() function defined in Capistrano's RemoteDependency class
28
+ options = pluck_accessor_hash(agem, [:platform, :install_options, :check_for_upgrade, :no_autogem, :fix_dependencies])
29
+ depend_without_gemfile(location, :gem, agem.name, agem.version, options)
30
+ end
31
+ else
32
+ depend_without_gemfile(location, type, *args)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ module CapistranoExtensions
2
+ module Version #:nodoc:
3
+ # A method for comparing versions of required modules. It expects two
4
+ # arrays of integers as parameters, the first being the minimum version
5
+ # required, and the second being the actual version available. It returns
6
+ # true if the actual version is at least equal to the required version.
7
+ def self.check(required, actual) #:nodoc:
8
+ required = required.map { |v| "%06d" % v }.join(".")
9
+ actual = actual.map { |v| "%06d" % v }.join(".")
10
+ return actual >= required
11
+ end
12
+
13
+ MAJOR = 0
14
+ MINOR = 1
15
+ TINY = 3
16
+
17
+ STRING = [MAJOR, MINOR, TINY].join(".")
18
+ end
19
+ end
20
+
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-extensions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - John Trupiano
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-09-11 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: capistrano
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.4.3
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: geminstaller
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.4.3
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: hoe
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.7.0
44
+ version:
45
+ description: A base set of Capistrano extensions-- aids with the file_column plugin, the GemInstaller gem, multiple deployable environments, logfile helpers, and database/asset synchronization from production to local environment
46
+ email: jtrupiano@gmail.com
47
+ executables:
48
+ - capistrano-extensions-sync-content
49
+ - capistrano-extensions-sync-db
50
+ extensions: []
51
+
52
+ extra_rdoc_files:
53
+ - History.txt
54
+ - Manifest.txt
55
+ - README.txt
56
+ files:
57
+ - History.txt
58
+ - Manifest.txt
59
+ - README.txt
60
+ - Rakefile
61
+ - bin/capistrano-extensions-sync-content
62
+ - bin/capistrano-extensions-sync-db
63
+ - lib/capistrano-extensions.rb
64
+ - lib/capistrano-extensions/deploy.rb
65
+ - lib/capistrano-extensions/geminstaller_dependency.rb
66
+ - lib/capistrano-extensions/version.rb
67
+ has_rdoc: true
68
+ homepage: http://github.com/jtrupiano/capistrano-extensions
69
+ post_install_message:
70
+ rdoc_options:
71
+ - --main
72
+ - README.txt
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ version:
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: "0"
86
+ version:
87
+ requirements: []
88
+
89
+ rubyforge_project: environmentaliz
90
+ rubygems_version: 1.2.0
91
+ signing_key:
92
+ specification_version: 2
93
+ summary: A base set of Capistrano extensions-- aids with the file_column plugin, the GemInstaller gem, multiple deployable environments, logfile helpers, and database/asset synchronization from production to local environment
94
+ test_files: []
95
+