capones_recipes 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Capfile ADDED
@@ -0,0 +1,7 @@
1
+ #
2
+ # Capfile for running base install recipe
3
+ #
4
+
5
+ load 'deploy' if respond_to?(:namespace) # cap2 differentiator
6
+
7
+ require 'capones_recipes'
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Roman Simecek
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,19 @@
1
+ = capones-recipes
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to capones-recipes
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
+ * Fork the project
10
+ * Start a feature/bugfix branch
11
+ * Commit and push until you are happy with your contribution
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2011 Roman Simecek. See LICENSE.txt for
18
+ further details.
19
+
@@ -0,0 +1,5 @@
1
+ require 'capistrano'
2
+ require 'capistrano/cli'
3
+ require 'capistrano_colors'
4
+
5
+ Dir.glob(File.join(File.dirname(__FILE__), '/recipes/*.rb')).sort.each { |f| load f }
@@ -0,0 +1,27 @@
1
+ Capistrano::Configuration.instance.load do
2
+ before "deploy:setup", :db
3
+ after "deploy:update_code", "db:symlink"
4
+
5
+ namespace :db do
6
+ desc "Create database yaml in capistrano shared path"
7
+ task :default do
8
+ run "mkdir -p #{shared_path}/config"
9
+ upload "config/database.yml.example", "#{shared_path}/config/database.yml", :via => :scp
10
+ end
11
+
12
+ desc "Make symlink for shared database yaml"
13
+ task :symlink do
14
+ run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
15
+ end
16
+
17
+ task :rake, :roles => :app do
18
+ run("cd #{deploy_to}/current && /usr/bin/env bundle exec rake #{rake_task} RAILS_ENV=#{rails_env}")
19
+ end
20
+
21
+ desc "Setup database"
22
+ task :setup, :roles => :app do
23
+ set :rake_task, 'db:setup'
24
+ rake
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ Capistrano::Configuration.instance.load do
2
+ namespace :webistrano do
3
+ namespace :mod_rails do
4
+ desc "start mod_rails & Apache"
5
+ task :start, :roles => :app, :except => { :no_release => true } do
6
+ as = fetch(:runner, "app")
7
+ invoke_command "#{apache_init_script} start", :via => run_method, :as => as
8
+ end
9
+
10
+ desc "stop mod_rails & Apache"
11
+ task :stop, :roles => :app, :except => { :no_release => true } do
12
+ as = fetch(:runner, "app")
13
+ invoke_command "#{apache_init_script} stop", :via => run_method, :as => as
14
+ end
15
+
16
+ desc "restart mod_rails"
17
+ task :restart, :roles => :app, :except => { :no_release => true } do
18
+ as = fetch(:runner, "app")
19
+ restart_file = fetch(:mod_rails_restart_file, "#{deploy_to}/current/tmp/restart.txt")
20
+ invoke_command "touch #{restart_file}", :via => run_method, :as => as
21
+ end
22
+ end
23
+ end
24
+
25
+ namespace :deploy do
26
+ task :restart, :roles => :app, :except => { :no_release => true } do
27
+ webistrano.mod_rails.restart
28
+ end
29
+
30
+ task :start, :roles => :app, :except => { :no_release => true } do
31
+ webistrano.mod_rails.start
32
+ end
33
+
34
+ task :stop, :roles => :app, :except => { :no_release => true } do
35
+ webistrano.mod_rails.stop
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,6 @@
1
+ Capistrano::Configuration.instance.load do
2
+ # Compile the assets in Rails 3.1
3
+ after 'deploy:migrate' do
4
+ run "cd #{release_path}; RAILS_ENV=production rake assets:precompile"
5
+ end
6
+ end
@@ -0,0 +1,29 @@
1
+ Capistrano::Configuration.instance.load do
2
+ before "deploy:setup", "sqlite:setup"
3
+ after "db:symlink", "sqlite:symlink"
4
+
5
+ namespace :sqlite do
6
+ desc "Setup Sqlite3 db"
7
+ task :setup do
8
+ run "mkdir -p #{shared_path}/db"
9
+ end
10
+
11
+ namespace :sync do
12
+ desc "Sync down the production sqlite database to local development sqlite"
13
+ task :down do
14
+ download "#{shared_path}/db/#{rails_env}.sqlite3", "db/development.sqlite3", :via => :scp
15
+ end
16
+
17
+ desc "Sync up the development sqlite database to production sqlite"
18
+ task :up do
19
+ run "mkdir -p #{shared_path}/db"
20
+ upload "db/development.sqlite3", "#{shared_path}/db/#{rails_env}.sqlite3", :via => :scp
21
+ end
22
+ end
23
+
24
+ desc "Make symlink for shared database"
25
+ task :symlink do
26
+ run "ln -nfs #{shared_path}/db/#{rails_env}.sqlite3 #{release_path}/db/#{rails_env}.sqlite3"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,214 @@
1
+ require 'yaml'
2
+ require 'pathname'
3
+
4
+ Capistrano::Configuration.instance.load do
5
+ #
6
+ # Capistrano sync.rb task for syncing databases and directories between the
7
+ # local development environment and different multi_stage environments. You
8
+ # cannot sync directly between two multi_stage environments, always use your
9
+ # local machine as loop way.
10
+ #
11
+ # Author: Michael Kessler aka netzpirat
12
+ # Gist: 111597
13
+ #
14
+ # Released under the MIT license.
15
+ # Kindly sponsored by Screen Concept, www.screenconcept.ch
16
+ #
17
+ namespace :sync do
18
+
19
+ after "deploy:setup", "sync:setup"
20
+
21
+ desc <<-DESC
22
+ Creates the sync dir in shared path. The sync directory is used to keep
23
+ backups of database dumps and archives from synced directories. This task will
24
+ be called on 'deploy:setup'
25
+ DESC
26
+ task :setup do
27
+ run "cd #{shared_path}; mkdir sync"
28
+ end
29
+
30
+ namespace :down do
31
+
32
+ desc <<-DESC
33
+ Syncs the database and declared directories from the selected multi_stage environment
34
+ to the local development environment. This task simply calls both the 'sync:down:db' and
35
+ 'sync:down:fs' tasks.
36
+ DESC
37
+ task :default do
38
+ db and fs
39
+ end
40
+
41
+ desc <<-DESC
42
+ Syncs database from the selected mutli_stage environement to the local develoment environment.
43
+ The database credentials will be read from your local config/database.yml file and a copy of the
44
+ dump will be kept within the shared sync directory. The amount of backups that will be kept is
45
+ declared in the sync_backups variable and defaults to 5.
46
+ DESC
47
+ task :db, :roles => :db, :only => { :primary => true } do
48
+ # Use production on non-multistage
49
+ stage ||= 'production'
50
+
51
+ filename = "database.#{stage}.#{Time.now.strftime '%Y-%m-%d_%H:%M:%S'}.sql.bz2"
52
+ on_rollback { delete "#{shared_path}/sync/#{filename}" }
53
+
54
+ # Remote DB dump
55
+ username, password, database, host = database_config(stage)
56
+ host_option = host ? "--host='#{host}'" : ""
57
+ run "mysqldump -u #{username} --password='#{password}' #{host_option} #{database} | bzip2 -9 > #{shared_path}/sync/#{filename}" do |channel, stream, data|
58
+ puts data
59
+ end
60
+ purge_old_backups "database"
61
+
62
+ # Download dump
63
+ download "#{shared_path}/sync/#{filename}", filename
64
+
65
+ # Local DB import
66
+ username, password, database, host = database_config('development')
67
+ system "bzip2 -d -c #{filename} | mysql -u #{username} --password='#{password}' #{database}; rm -f #{filename}"
68
+
69
+ logger.important "sync database from the stage '#{stage}' to local finished"
70
+ end
71
+
72
+ desc <<-DESC
73
+ Sync declared directories from the selected multi_stage environment to the local development
74
+ environment. The synced directories must be declared as an array of Strings with the sync_directories
75
+ variable. The path is relative to the rails root.
76
+ DESC
77
+ task :fs, :roles => :web, :once => true do
78
+ # Use production on non-multistage
79
+ stage ||= 'production'
80
+
81
+ server, port = host_and_port
82
+
83
+ Array(fetch(:sync_directories, [])).each do |syncdir|
84
+ unless File.directory? "#{syncdir}"
85
+ logger.info "create local '#{syncdir}' folder"
86
+ Dir.mkdir "#{syncdir}"
87
+ end
88
+ logger.info "sync #{syncdir} from #{server}:#{port} to local"
89
+ destination, base = Pathname.new(syncdir).split
90
+ system "rsync --verbose --archive --compress --copy-links --delete --stats --rsh='ssh -p #{port}' #{user}@#{server}:#{current_path}/#{syncdir} #{destination.to_s}"
91
+ end
92
+
93
+ logger.important "sync filesystem from the stage '#{stage}' to local finished"
94
+ end
95
+
96
+ end
97
+
98
+ namespace :up do
99
+
100
+ desc <<-DESC
101
+ Syncs the database and declared directories from the local development environment
102
+ to the selected multi_stage environment. This task simply calls both the 'sync:up:db' and
103
+ 'sync:up:fs' tasks.
104
+ DESC
105
+ task :default do
106
+ db and fs
107
+ end
108
+
109
+ desc <<-DESC
110
+ Syncs database from the local develoment environment to the selected mutli_stage environement.
111
+ The database credentials will be read from your local config/database.yml file and a copy of the
112
+ dump will be kept within the shared sync directory. The amount of backups that will be kept is
113
+ declared in the sync_backups variable and defaults to 5.
114
+ DESC
115
+ task :db, :roles => :db, :only => { :primary => true } do
116
+ # Use production on non-multistage
117
+ stage ||= 'production'
118
+
119
+ filename = "database.#{stage}.#{Time.now.strftime '%Y-%m-%d_%H:%M:%S'}.sql.bz2"
120
+
121
+ on_rollback do
122
+ delete "#{shared_path}/sync/#{filename}"
123
+ system "rm -f #{filename}"
124
+ end
125
+
126
+ # Make a backup before importing
127
+ username, password, database, host = database_config(stage)
128
+ host_option = host ? "--host='#{host}'" : ""
129
+ run "mysqldump -u #{username} --password='#{password}' #{host_option} #{database} | bzip2 -9 > #{shared_path}/sync/#{filename}" do |channel, stream, data|
130
+ puts data
131
+ end
132
+
133
+ # Local DB export
134
+ filename = "dump.local.#{Time.now.strftime '%Y-%m-%d_%H:%M:%S'}.sql.bz2"
135
+ username, password, database, host = database_config('development')
136
+ host_option = host ? "--host='#{host}'" : ""
137
+ system "mysqldump -u #{username} --password='#{password}' #{host_option} #{database} | bzip2 -9 > #{filename}"
138
+ upload filename, "#{shared_path}/sync/#{filename}"
139
+ system "rm -f #{filename}"
140
+
141
+ # Remote DB import
142
+ username, password, database, host = database_config(stage)
143
+ host_option = host ? "--host='#{host}'" : ""
144
+ run "bzip2 -d -c #{shared_path}/sync/#{filename} | mysql -u #{username} --password='#{password}' #{host_option} #{database}; rm -f #{shared_path}/sync/#{filename}"
145
+ purge_old_backups "database"
146
+
147
+ logger.important "sync database from local to the stage '#{stage}' finished"
148
+ end
149
+
150
+ desc <<-DESC
151
+ Sync declared directories from the local development environement to the selected multi_stage
152
+ environment. The synced directories must be declared as an array of Strings with the sync_directories
153
+ variable. The path is relative to the rails root.
154
+ DESC
155
+ task :fs, :roles => :web, :once => true do
156
+ # Use production on non-multistage
157
+ stage ||= 'production'
158
+
159
+ server, port = host_and_port
160
+ Array(fetch(:sync_directories, [])).each do |syncdir|
161
+ destination, base = Pathname.new(syncdir).split
162
+ if File.directory? "#{syncdir}"
163
+ # Make a backup
164
+ logger.info "backup #{syncdir}"
165
+ run "tar cjf #{shared_path}/sync/#{base}.#{Time.now.strftime '%Y-%m-%d_%H:%M:%S'}.tar.bz2 #{current_path}/#{syncdir}"
166
+ purge_old_backups "#{base}"
167
+ else
168
+ logger.info "Create '#{syncdir}' directory"
169
+ run "mkdir #{current_path}/#{syncdir}"
170
+ end
171
+
172
+ # Sync directory up
173
+ logger.info "sync #{syncdir} to #{server}:#{port} from local"
174
+ system "rsync --verbose --archive --compress --keep-dirlinks --delete --stats --rsh='ssh -p #{port}' #{syncdir} #{user}@#{server}:#{current_path}/#{destination.to_s}"
175
+ end
176
+ logger.important "sync filesystem from local to the stage '#{stage}' finished"
177
+ end
178
+
179
+ end
180
+
181
+ #
182
+ # Reads the database credentials from the local config/database.yml file
183
+ # +db+ the name of the environment to get the credentials for
184
+ # Returns username, password, database
185
+ #
186
+ def database_config(db)
187
+ database = YAML::load_file('config/database.yml')
188
+ return database["#{db}"]['username'], database["#{db}"]['password'], database["#{db}"]['database'], database["#{db}"]['host']
189
+ end
190
+
191
+ #
192
+ # Returns the actual host name to sync and port
193
+ #
194
+ def host_and_port
195
+ return roles[:web].servers.first.host, ssh_options[:port] || roles[:web].servers.first.port || 22
196
+ end
197
+
198
+ #
199
+ # Purge old backups within the shared sync directory
200
+ #
201
+ def purge_old_backups(base)
202
+ count = fetch(:sync_backups, 5).to_i
203
+ backup_files = capture("ls -xt #{shared_path}/sync/#{base}*").split.reverse
204
+ if count >= backup_files.length
205
+ logger.important "no old backups to clean up"
206
+ else
207
+ logger.info "keeping #{count} of #{backup_files.length} sync backups"
208
+ delete_backups = (backup_files - backup_files.last(count)).join(" ")
209
+ try_sudo "rm -rf #{delete_backups}"
210
+ end
211
+ end
212
+
213
+ end
214
+ end
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capones_recipes
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Roman Simecek
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-08-03 00:00:00 +02:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: capistrano
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: cap-recipes
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: capistrano
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :runtime
47
+ prerelease: false
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: capistrano_colors
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: shoulda
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: bundler
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ version: 1.0.0
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: *id006
82
+ - !ruby/object:Gem::Dependency
83
+ name: jeweler
84
+ requirement: &id007 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 1.6.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: *id007
93
+ - !ruby/object:Gem::Dependency
94
+ name: rcov
95
+ requirement: &id008 !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: "0"
101
+ type: :development
102
+ prerelease: false
103
+ version_requirements: *id008
104
+ description: just for fun
105
+ email: roman.simecek@cyt.ch
106
+ executables: []
107
+
108
+ extensions: []
109
+
110
+ extra_rdoc_files:
111
+ - LICENSE.txt
112
+ - README.rdoc
113
+ files:
114
+ - Capfile
115
+ - lib/capones_recipes.rb
116
+ - lib/recipes/database_yml.rb
117
+ - lib/recipes/mod_rails.rb
118
+ - lib/recipes/rails31.rb
119
+ - lib/recipes/sqlite.rb
120
+ - lib/recipes/sync.rb
121
+ - LICENSE.txt
122
+ - README.rdoc
123
+ has_rdoc: true
124
+ homepage: http://github.com/raskhadafi/capones-recipes
125
+ licenses:
126
+ - MIT
127
+ post_install_message:
128
+ rdoc_options: []
129
+
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ hash: -4253814855414718080
138
+ segments:
139
+ - 0
140
+ version: "0"
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ none: false
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: "0"
147
+ requirements: []
148
+
149
+ rubyforge_project:
150
+ rubygems_version: 1.6.2
151
+ signing_key:
152
+ specification_version: 3
153
+ summary: Some capistrano recipes for use.
154
+ test_files: []
155
+