capistrano-base_helper 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem "capistrano", ">= 2.15.5"
4
+
5
+ group :development do
6
+ gem "bundler", ">= 1.3.0"
7
+ gem "jeweler", "~> 1.8.6"
8
+ # gem "rdoc", ">=2.4"
9
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,66 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.3.5)
5
+ builder (3.2.2)
6
+ capistrano (2.15.5)
7
+ highline
8
+ net-scp (>= 1.0.0)
9
+ net-sftp (>= 2.0.0)
10
+ net-ssh (>= 2.0.14)
11
+ net-ssh-gateway (>= 1.1.0)
12
+ faraday (0.8.7)
13
+ multipart-post (~> 1.1)
14
+ git (1.2.5)
15
+ github_api (0.10.1)
16
+ addressable
17
+ faraday (~> 0.8.1)
18
+ hashie (>= 1.2)
19
+ multi_json (~> 1.4)
20
+ nokogiri (~> 1.5.2)
21
+ oauth2
22
+ hashie (2.0.5)
23
+ highline (1.6.19)
24
+ httpauth (0.2.0)
25
+ jeweler (1.8.6)
26
+ builder
27
+ bundler (~> 1.0)
28
+ git (>= 1.2.5)
29
+ github_api (= 0.10.1)
30
+ highline (>= 1.6.15)
31
+ nokogiri (= 1.5.10)
32
+ rake
33
+ rdoc
34
+ json (1.8.0)
35
+ jwt (0.1.8)
36
+ multi_json (>= 1.5)
37
+ multi_json (1.7.7)
38
+ multi_xml (0.5.4)
39
+ multipart-post (1.2.0)
40
+ net-scp (1.1.1)
41
+ net-ssh (>= 2.6.5)
42
+ net-sftp (2.1.2)
43
+ net-ssh (>= 2.6.5)
44
+ net-ssh (2.6.7)
45
+ net-ssh-gateway (1.2.0)
46
+ net-ssh (>= 2.6.5)
47
+ nokogiri (1.5.10)
48
+ oauth2 (0.9.2)
49
+ faraday (~> 0.8)
50
+ httpauth (~> 0.2)
51
+ jwt (~> 0.1.4)
52
+ multi_json (~> 1.0)
53
+ multi_xml (~> 0.5)
54
+ rack (~> 1.2)
55
+ rack (1.5.2)
56
+ rake (10.1.0)
57
+ rdoc (4.0.1)
58
+ json (~> 1.4)
59
+
60
+ PLATFORMS
61
+ ruby
62
+
63
+ DEPENDENCIES
64
+ bundler (>= 1.3.0)
65
+ capistrano (>= 2.15.5)
66
+ jeweler (~> 1.8.6)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Leif Ringstad
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.md ADDED
@@ -0,0 +1,97 @@
1
+ # Capistrano - Base helpers
2
+
3
+ This libary is a helper library for capistrano tasks that setup monit/runit for various services.
4
+
5
+ ## Services for Monit and Runit
6
+
7
+ Services created:
8
+
9
+ * _[capistrano-puma](https://github.com/leifcr/capistrano-puma)_ for [Puma](http://puma.io)
10
+ * _[capistrano-delayed_job](https://github.com/leifcr/capistrano-delayed_job)_ for [Delayed Job](https://github.com/collectiveidea/delayed_job)
11
+
12
+ It is fairly easy to create new service. Fork/clone either capistrano-puma or capistrano-delayed_job and create a new service based on either.
13
+
14
+ All services should have their own repository, as it makes it easier when deploying to choose what services you need for the application you are deploying.
15
+
16
+ ## Capistrano tasks
17
+
18
+ Tasks that work on your entire application and not just on a single service.
19
+
20
+ _Note: The tasks will not work unless you have installed any monit services_
21
+
22
+ ### Monit
23
+
24
+ All these tasks do monit tasks for all services setup with monit.
25
+
26
+ ```ruby
27
+ cap monit:disable # Disable monit services for application
28
+ cap monit:enable # Enable monit services for application
29
+ cap monit:main_config # Setup main monit config file (/etc/monit/monitrc)
30
+ cap monit:monitor # Monitor the application
31
+ cap monit:purge # Purge/remove all monit configurations for the application
32
+ cap monit:reload # Reload monit config (global)
33
+ cap monit:restart # Restart monitoring the application
34
+ cap monit:setup # Setup monit folders and configuration
35
+ cap monit:start # Start monitoring the application permanent (Monit saves state)
36
+ cap monit:status # Status monit (global)
37
+ cap monit:stop # Stop monitoring the application permanent (Monit saves state)
38
+ ```
39
+
40
+ ### Runit
41
+
42
+ All these tasks do runit tasks for all services setup with runit.
43
+
44
+ ```ruby
45
+ cap runit:disable # Disable runit services for application
46
+ cap runit:enable # Enable runit services for application
47
+ cap runit:once # Only start services once.
48
+ cap runit:purge # Purge/remove all runit configurations for the application
49
+ cap runit:setup # Setup runit for the application
50
+ cap runit:start # Start all runit services for current application
51
+ cap runit:stop # Stop all runit services for current application
52
+ ```
53
+
54
+ ## Assumptions
55
+
56
+ There are some assumptions when using this with capistrano.
57
+ The following variables must be set
58
+
59
+ * _:application_ - The application name
60
+ * _:user_ - The username which is running the deployed application (usually deploy..)
61
+ * _:group_ - The groupname which is running the deployed application (usually deploy..)
62
+
63
+
64
+ ## Helpers
65
+
66
+ Upload a configuration file:
67
+
68
+ ```ruby
69
+ # Generate a config file by parsing an ERB template and uploading the file. Both paths should be absolute
70
+ Capistrano::BaseHelper::generate_and_upload_config(local_file, remote_file, use_sudo=false)
71
+ ```
72
+
73
+ Run a rake task:
74
+ ```ruby
75
+ # Execute a rake taske using bundle and the proper env.
76
+ Capistrano::BaseHelper::run_rake(task)
77
+ ```
78
+
79
+ Ask the user a message to agree/disagree
80
+ ```ruby
81
+ Capistrano::BaseHelper::ask(message)
82
+ ```
83
+
84
+ See base_helper/base_helper.rb for further documentation.
85
+ And for runit info, base_helper/runit_base.rb for further documentation.
86
+
87
+ ## Contributing
88
+
89
+ * Fork the project
90
+ * Make a feature addition or bug fix
91
+ * Please test the feature or bug fix, or write tests for it
92
+ * Make a pull request
93
+
94
+ ## Copyright
95
+
96
+ (c) 2013 Leif Ringstad. See LICENSE.txt for details
97
+
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "capistrano-base_helper"
18
+ gem.homepage = "https://github.com/leifcr/capistrano-base-helper"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Helpers for capistrano recipes using runit/monit}
21
+ gem.description = %Q{Helpers for capistrano recipes using runit/monit. Currently: capistrano-puma and capistrano-delayed_job}
22
+ gem.email = "leifcr@gmail.com"
23
+ gem.authors = ["Leif Ringstad"]
24
+ gem.files.exclude ".ruby-*"
25
+ # dependencies defined in Gemfile
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ # require 'rdoc/task'
30
+ # Rake::RDocTask.new do |rdoc|
31
+ # version = File.exist?('VERSION') ? File.read('VERSION') : ""
32
+
33
+ # rdoc.rdoc_dir = 'rdoc'
34
+ # rdoc.title = "capistrano-empty #{version}"
35
+ # rdoc.rdoc_files.include('README*')
36
+ # rdoc.rdoc_files.include('lib/**/*.rb')
37
+ # end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.3
@@ -0,0 +1,138 @@
1
+ Capistrano::Configuration.instance(true).load do
2
+ _cset :pids_path, File.join(fetch(:shared_path), "pids")
3
+ _cset :sockets_path, File.join(fetch(:shared_path), "sockets")
4
+ namespace :base_helper do
5
+ desc "[internal] set the capistrano instance in Capistrano::BaseHelper module"
6
+ task :set_capistrano_instance do
7
+ Capistrano::BaseHelper::set_capistrano_instance(self)
8
+ end
9
+ end
10
+
11
+ on :start, "base_helper:set_capistrano_instance"
12
+ end
13
+
14
+ module Capistrano
15
+ module BaseHelper
16
+ @@capistrano_instance
17
+ module_function
18
+
19
+ def set_capistrano_instance(cap_instance)
20
+ @@capistrano_instance = cap_instance
21
+ end
22
+
23
+ def get_capistrano_instance
24
+ @@capistrano_instance
25
+ end
26
+
27
+ def user_app_env_underscore
28
+ "#{get_capistrano_instance.fetch(:user)}_#{get_capistrano_instance.fetch(:application)}_#{environment}"
29
+ end
30
+
31
+ def user_app_env_path
32
+ File.join(get_capistrano_instance.fetch(:user), "#{get_capistrano_instance.fetch(:application)}_#{environment}")
33
+ end
34
+
35
+ ##
36
+ # Automatically sets the environment based on presence of
37
+ # :stage (multistage)
38
+ # :rails_env
39
+ # RAILS_ENV variable;
40
+ #
41
+ # Defaults to "production" if not found
42
+ #
43
+ def environment
44
+ if @@capistrano_instance.exists?(:rails_env)
45
+ @@capistrano_instance.fetch(:rails_env)
46
+ elsif @@capistrano_instance.exists?(:rack_env)
47
+ @@capistrano_instance.fetch(:rack_env)
48
+ elsif @@capistrano_instance.exists?(:stage)
49
+ @@capistrano_instance.fetch(:stage)
50
+ elsif(ENV['RAILS_ENV'])
51
+ ENV['RAILS_ENV']
52
+ else
53
+ puts "------------------------------------------------------------------"
54
+ puts "- Stage, rack or rails environment isn't set in -"
55
+ puts "- :stage or :rails_env or :rack_env, defaulting to 'production' -"
56
+ puts "------------------------------------------------------------------"
57
+ "production"
58
+ end
59
+ end
60
+
61
+ ##
62
+ # parse a erb template and return the result
63
+ #
64
+ def parse_config(file)
65
+ require 'erb' #render not available in Capistrano 2
66
+ template = File.read(file) # read it
67
+ returnval = ERB.new(template).result(binding) # parse it
68
+ return returnval
69
+ end
70
+
71
+ ##
72
+ # Prompts the user for a message to agree/decline
73
+ #
74
+ def ask(message, default=true)
75
+ Capistrano::CLI.ui.agree(message)
76
+ end
77
+
78
+ ##
79
+ # Generate a config file by parsing an ERB template and uploading the file
80
+ # Fetches local file and uploads it to remote_file
81
+ # Make sure your user has the right permissions.
82
+ #
83
+ # @local_file full path to local file
84
+ # @remote_file full path to remote file
85
+ # @use_sudo use sudo or not...
86
+ #
87
+ def generate_and_upload_config(local_file, remote_file, use_sudo=false)
88
+ temp_file = '/tmp/' + File.basename(local_file)
89
+ erb_buffer = Capistrano::BaseHelper::parse_config(local_file)
90
+ # write temp file
91
+ File.open(temp_file, 'w+') { |f| f << erb_buffer }
92
+ # upload temp file
93
+ @@capistrano_instance.upload temp_file, temp_file, :via => :scp
94
+ # create any folders required,
95
+ # move temporary file to remote file
96
+ @@capistrano_instance.run "#{use_sudo ? "sudo" : ""} mkdir -p #{Pathname.new(remote_file).dirname}; #{use_sudo ? "sudo" : ""} mv #{temp_file} #{remote_file}"
97
+ # remove temp file
98
+ `rm #{temp_file}`
99
+ end
100
+
101
+ ##
102
+ # Execute a rake taske using bundle and the proper env.
103
+ # run_rake db:migrate
104
+ #
105
+ def run_rake(task)
106
+ @@capistrano_instance.run "cd #{@@capistrano_instance.current_path} && RAILS_ENV=#{Capistrano::BaseHelper.environment} bundle exec rake #{task}"
107
+ end
108
+
109
+ ##
110
+ # Prepare a path with the given user and group name
111
+ # @path the path to prepare
112
+ # @user the user to chown the path
113
+ # @group the group to chown the path
114
+ # @use_sudo true/false for using sudo for all the commands
115
+
116
+ def prepare_path(path, user, group, use_sudo = false)
117
+ commands = []
118
+ commands << "#{use_sudo ? "sudo" : ""} mkdir -p #{path}"
119
+ commands << "#{use_sudo ? "sudo" : ""} chown #{user}:#{group} #{path} -R"
120
+ commands << "#{use_sudo ? "sudo" : ""} chmod +rw #{path}"
121
+ @@capistrano_instance.run commands.join(" &&")
122
+ end
123
+
124
+ ##
125
+ # Check for file existance
126
+ # See http://stackoverflow.com/questions/1661586/how-can-you-check-to-see-if-a-file-exists-on-the-remote-server-in-capistrano
127
+ # Credits: Patrick Reagen / Knocte
128
+ def remote_file_exists?(path)
129
+ results = []
130
+ @@capistrano_instance.invoke_command("if [ -e '#{path}' ]; then echo -n 'true'; fi") do |ch, stream, out|
131
+ results << (out == 'true')
132
+ end
133
+
134
+ results == [true]
135
+ end
136
+
137
+ end
138
+ end
@@ -0,0 +1,207 @@
1
+ # TODO: PLACE monit files like this
2
+ # shared_path/monit/available
3
+ # shared_path/monit/enabled
4
+ # shared_path/monit/application.conf <-- in this: include shared_path/monit/enabled
5
+ # files can then belong to user instead of root, and sudo is avoided for some apps
6
+
7
+ Capistrano::Configuration.instance(true).load do
8
+ _cset :monit_dir, defer { File.join(shared_path, "monit") }
9
+ _cset :monit_available_path, defer { File.join(monit_dir, "available") }
10
+ _cset :monit_enabled_path, defer { File.join(monit_dir, "enabled") }
11
+ _cset :monit_etc_path, File.join("/etc", "monit")
12
+ _cset :monit_etc_conf_d_path, defer { File.join(monit_etc_path, "conf.d") }
13
+ _cset :monit_application_group_name, defer { "#{fetch(:user)}_#{fetch(:application)}_#{Capistrano::BaseHelper.environment}" }
14
+
15
+ _cset :monit_mailserver, "localhost"
16
+ _cset :monit_mail_sender, "monit@$HOST"
17
+ _cset :monit_mail_reciever, nil # if this is nil, alerts are disabled
18
+ _cset :monit_use_httpd, "true"
19
+ _cset :monit_httpd_bind_address, "localhost"
20
+ _cset :monit_httpd_allow_address, "localhost"
21
+ _cset :monit_httpd_signature, "enable" # or enable
22
+ _cset :monit_httpd_port, "2812"
23
+
24
+ _cset :monit_daemon_time, "60"
25
+ _cset :monit_start_delay, "60"
26
+
27
+ #after "deploy:update", "monit:enable"
28
+ after "deploy:setup", "monit:setup"
29
+ before "monit:setup", "monit:main_config"
30
+
31
+ after "monit:setup", "monit:enable"
32
+ after "monit:enable", "monit:reload"
33
+
34
+ # must trigger monitor AFTER deploy
35
+ after "deploy", "monit:monitor"
36
+ # must trigger unmonitor BEFORE deploy
37
+ before "deploy", "monit:unmonitor"
38
+
39
+ before "monit:disable", "monit:unmonitor"
40
+ after "monit:disable", "monit:reload"
41
+
42
+ before "monit:purge", "monit:unmonitor"
43
+
44
+ namespace :monit do
45
+
46
+ desc "Setup monit folders and configuration"
47
+ task :setup, :roles => [:app, :db, :web] do
48
+ # conf file that will include application specific configurations will be placed here:
49
+ run "[ -d #{fetch(:monit_dir)} ] || mkdir -p #{fetch(:monit_dir)}"
50
+ # dir to store each services monit configs
51
+ run "[ -d #{fetch(:monit_available_path)} ] || mkdir -p #{fetch(:monit_available_path)}"
52
+ # dir for all symlinked enabled applications
53
+ run "[ -d #{fetch(:monit_enabled_path)} ] || mkdir -p #{fetch(:monit_enabled_path)}"
54
+
55
+ # create include configuration (used when booting the system)
56
+ local_config = File.join(File.expand_path(File.join(File.dirname(__FILE__),"../templates", "monit")), "app_include.conf.erb")
57
+ remote_config = File.join(fetch(:monit_dir), "monit.conf")
58
+
59
+ Capistrano::BaseHelper::generate_and_upload_config(local_config, remote_config)
60
+ end
61
+
62
+ desc "Setup main monit config file (/etc/monit/monitrc)"
63
+ task :main_config, :roles => [:app, :db, :web] do
64
+ if Capistrano::CLI.ui.agree("Setup /etc/monit/monitrc ?")
65
+ # create monitrc file
66
+ local_config = File.join(File.expand_path(File.join(File.dirname(__FILE__),"../templates", "monit")), "monitrc.erb")
67
+ remote_config = File.join("/etc","monit","monitrc")
68
+
69
+ Capistrano::BaseHelper::generate_and_upload_config(local_config, remote_config, true)
70
+
71
+ commands = []
72
+ commands << "sudo chmod 700 /etc/monit/monitrc"
73
+ commands << "sudo chown root:root /etc/monit/monitrc"
74
+ run commands.join(" && ")
75
+ # restart monit, as main config is now updated
76
+ run "sudo service monit restart"
77
+ puts "----------------------------------------"
78
+ puts "Sleeping for #{(fetch(:monit_daemon_time).to_i + fetch(:monit_start_delay).to_i + 2)} seconds to wait for monit to be ready"
79
+ puts "----------------------------------------"
80
+ sleep (fetch(:monit_daemon_time).to_i + fetch(:monit_start_delay).to_i + 2)
81
+ end
82
+ end
83
+
84
+ desc "Enable monit services for application"
85
+ task :enable, :roles => [:app, :db, :web] do
86
+ real_conf = File.join(fetch(:monit_dir), "monit.conf")
87
+ symlink = File.join(fetch(:monit_etc_conf_d_path), "#{Capistrano::BaseHelper.user_app_env_underscore}.conf")
88
+ # symlink to include file
89
+ run("[ -h #{symlink} ] || sudo ln -sf #{real_conf} #{symlink}")
90
+ end
91
+
92
+ desc "Disable monit services for application"
93
+ task :disable, :roles => [:app, :db, :web] do
94
+ symlink = File.join(fetch(:monit_etc_conf_d_path), "#{Capistrano::BaseHelper.user_app_env_underscore}.conf")
95
+ run("[ ! -h #{symlink} ] || sudo rm -f #{symlink}")
96
+ end
97
+
98
+ desc "Purge/remove all monit configurations for the application"
99
+ task :purge, :roles => [:app, :db, :web] do
100
+ symlink = File.join(fetch(:monit_etc_conf_d_path), "#{Capistrano::BaseHelper.user_app_env_underscore}.conf")
101
+ run("[ ! -h #{symlink} ] || sudo rm -f #{symlink}")
102
+ run("[ ! -d #{fetch(:monit_dir)} ] || sudo rm -f #{fetch(:monit_dir)}")
103
+ end
104
+
105
+ desc "Monitor the application"
106
+ task :monitor, :roles => [:app, :db, :web] do
107
+ Capistrano::MonitBase::Application::command_monit_group(fetch(:monit_application_group_name), "monitor")
108
+ end
109
+
110
+ desc "Unmonitor the application"
111
+ task :unmonitor, :roles => [:app, :db, :web] do
112
+ Capistrano::MonitBase::Application::command_monit_group(fetch(:monit_application_group_name), "unmonitor")
113
+ end
114
+
115
+ desc "Stop monitoring the application permanent (Monit saves state)"
116
+ task :stop, :roles => [:app, :db, :web] do
117
+ Capistrano::MonitBase::Application::command_monit_group(fetch(:monit_application_group_name), "stop")
118
+ end
119
+
120
+ desc "Start monitoring the application permanent (Monit saves state)"
121
+ task :start, :roles => [:app, :db, :web] do
122
+ Capistrano::MonitBase::Application::command_monit_group(fetch(:monit_application_group_name), "start")
123
+ end
124
+
125
+ desc "Restart monitoring the application"
126
+ task :restart, :roles => [:app, :db, :web] do
127
+ Capistrano::MonitBase::Application::command_monit_group(fetch(:monit_application_group_name), "restart")
128
+ end
129
+
130
+ desc "Reload monit config (global)"
131
+ task :reload, :roles => [:app, :db, :web] do
132
+ Capistrano::MonitBase::Application::command_monit("reload")
133
+ end
134
+
135
+ desc "Status monit (global)"
136
+ task :status, :roles => [:app, :db, :web], :on_error => :continue do
137
+ Capistrano::MonitBase::Application::command_monit("status")
138
+ end
139
+
140
+ desc "Summary monit (global)"
141
+ task :summary, :roles => [:app, :db, :web], :on_error => :continue do
142
+ Capistrano::MonitBase::Application::command_monit("summary")
143
+ end
144
+
145
+ desc "Validate monit (global)"
146
+ task :validate, :roles => [:app, :db, :web], :on_error => :continue do
147
+ Capistrano::MonitBase::Application::command_monit("validate")
148
+ end
149
+
150
+ end
151
+ end
152
+
153
+ module Capistrano
154
+ module MonitBase
155
+ module Application
156
+ module_function
157
+
158
+ ##
159
+ # Control / Command a monit group
160
+ # namescheme: user_application_environment "#{user}_#{application}_#{environment}"
161
+ #
162
+ def command_monit_group(application_group_name, command, arguments = "")
163
+ Capistrano::MonitBase::Application.command_monit(command, "-g #{application_group_name} #{arguments}")
164
+ end
165
+
166
+ ##
167
+ # Control / Command monit with given arguments
168
+ def command_monit(command, arguments="")
169
+ Capistrano::BaseHelper.get_capistrano_instance.run("sudo monit #{arguments} #{command}")
170
+ end
171
+
172
+ end
173
+
174
+ module Service
175
+ module_function
176
+
177
+ ##
178
+ # Command a single monit service
179
+ #
180
+ # The service name scheme is recommended to be
181
+ # "#{user}_#{application}_#{environment}_#{service}"
182
+ #
183
+ def command_monit(command, service_name="", arguments="")
184
+ c = Capistrano::BaseHelper.get_capistrano_instance
185
+ service_name = "#{c.fetch(:user)}_#{c.fetch(:application)}_#{c.fetch(:environment)}_#{c.fetch(:service)}" if service_name == ""
186
+ c.run("sudo monit #{arguments} #{command} #{service_name}")
187
+ end
188
+
189
+ ##
190
+ # The service name is the same as the conf file name for the service.
191
+ # E.g. puma.conf
192
+ #
193
+ # This will symlink the service to enabled service, but not start or reload monit configuration
194
+ #
195
+ def enable(service_conf_filename)
196
+ c = Capistrano::BaseHelper.get_capistrano_instance
197
+ c.run("[ -h #{File.join(c.fetch(:monit_enabled_path), service_conf_filename)} ] || ln -sf #{File.join(c.fetch(:monit_available_path), service_conf_filename)} #{File.join(c.fetch(:monit_enabled_path), service_conf_filename)}")
198
+ end
199
+
200
+ def disable(service_conf_filename)
201
+ c = Capistrano::BaseHelper.get_capistrano_instance
202
+ c.run("rm -f #{File.join(c.fetch(:monit_enabled_path), service_conf_filename)}")
203
+ end
204
+ end
205
+ end
206
+ end
207
+
@@ -0,0 +1,250 @@
1
+ Capistrano::Configuration.instance(true).load do
2
+ _cset :runit_dir, defer { "#{shared_path}/runit" }
3
+ _cset :runit_local_run, File.join(File.expand_path(File.join(File.dirname(__FILE__),"../templates")), "runit", "run.erb")
4
+ _cset :runit_local_finish, File.join(File.expand_path(File.join(File.dirname(__FILE__),"../templates")), "runit", "finish.erb")
5
+ _cset :runit_local_log_run, File.join(File.expand_path(File.join(File.dirname(__FILE__),"../templates")), "runit", "log_run.erb")
6
+ _cset :runit_remote_run, defer {File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "run")}
7
+ _cset :runit_remote_finish, defer {File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "finish")}
8
+ _cset :runit_remote_log_run, defer {File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "log", "run")}
9
+ _cset :runit_log_user, "syslog"
10
+ _cset :runit_log_group, "syslog"
11
+
12
+ after "deploy:update", "runit:enable"
13
+ after "deploy:setup", "runit:setup"
14
+
15
+ namespace :runit do
16
+ desc "Setup runit for the application"
17
+ task :setup, :roles => [:app, :db, :web] do
18
+ run "[ -d #{fetch(:runit_dir)}/.env ] || mkdir -p #{fetch(:runit_dir)}/.env"
19
+ run "echo $HOME > #{fetch(:runit_dir)}/.env/HOME"
20
+ # setup to run as user
21
+ Capistrano::RunitBase.app_services_create
22
+ end
23
+
24
+ desc "Disable runit services for application"
25
+ task :disable, :roles => [:app, :db, :web] do
26
+ Capistrano::BaseHelper.get_capistrano_instance.run("sudo sv force-stop #{user}_#{application}; true")
27
+ Capistrano::RunitBase.app_services_disable(fetch(:application), fetch(:user))
28
+ end
29
+
30
+ desc "Enable runit services for application"
31
+ task :enable, :roles => [:app, :db, :web] do
32
+ Capistrano::RunitBase.app_services_enable(fetch(:application), fetch(:user))
33
+ end
34
+
35
+ desc "Purge/remove all runit configurations for the application"
36
+ task :purge, :roles => [:app, :db, :web] do
37
+ Capistrano::BaseHelper.get_capistrano_instance.run("sudo sv force-stop #{user}_#{application}; true")
38
+ Capistrano::RunitBase.app_services_purge(fetch(:application), fetch(:user))
39
+ end
40
+
41
+ desc "Stop all runit services for current application"
42
+ task :stop, :roles => [:app, :db, :web] do
43
+ Capistrano::RunitBase.app_services_stop(fetch(:application), fetch(:user))
44
+ end
45
+
46
+ desc "Start all runit services for current application"
47
+ task :start, :roles => [:app, :db, :web] do
48
+ Capistrano::RunitBase.app_services_start(fetch(:application), fetch(:user))
49
+ end
50
+
51
+ desc "Only start services once. Will not restart if they fail."
52
+ task :once, :roles => [:app, :db, :web] do
53
+ Capistrano::RunitBase.app_services_once(fetch(:application), fetch(:user))
54
+ end
55
+
56
+ end
57
+ end
58
+
59
+ module Capistrano
60
+ module RunitBase
61
+ module_function
62
+
63
+ def service_path(service_name)
64
+ "#{Capistrano::BaseHelper.get_capistrano_instance.fetch(:runit_dir)}/#{service_name}"
65
+ end
66
+
67
+ def create_service_dir(service_name)
68
+ Capistrano::BaseHelper.get_capistrano_instance.run("[ -d #{service_path(service_name)} ] || mkdir -p #{service_path(service_name)}")
69
+ end
70
+
71
+ def service_pid(service_name)
72
+ File.join(service_path(service_name), "supervise", "pid")
73
+ end
74
+
75
+ # BEGIN - ALL services functions (functions that affects all services for the app)
76
+
77
+ def app_services_create_log_service
78
+ c = Capistrano::BaseHelper.get_capistrano_instance
79
+ commands = []
80
+ commands << "sudo mkdir -p #{File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "log")}"
81
+ commands << "sudo chown #{c.fetch(:user)}:root #{File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "log")}"
82
+ commands << "sudo mkdir -p '#{File.join("/var", "log", "service", Capistrano::BaseHelper.user_app_env_path, "runit")}'"
83
+ commands << "sudo chown -R #{c.fetch(:runit_log_user)}:#{c.fetch(:runit_log_group)} '#{File.join("/var", "log", "service", Capistrano::BaseHelper.user_app_env_path, "runit")}'"
84
+
85
+ c.run(commands.join(" && "))
86
+ Capistrano::BaseHelper.generate_and_upload_config( Capistrano::BaseHelper::get_capistrano_instance.fetch(:runit_local_log_run), Capistrano::BaseHelper::get_capistrano_instance.fetch(:runit_remote_log_run), true )
87
+ commands = []
88
+ commands << "sudo chmod u+x '#{File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "log", "run")}'"
89
+ commands << "sudo chmod g+x '#{File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "log", "run")}'"
90
+ commands << "sudo chown #{c.fetch(:user)}:root '#{File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "log", "run")}'"
91
+ c.run(commands.join(" && "))
92
+ end
93
+
94
+ ##
95
+ # application name should be "app-environment" or similar in case you deploy staging/production to same host
96
+ def app_services_create
97
+ # SEE http://off-the-stack.moorman.nu/posts/5-user-services-with-runit/ for info on scripts
98
+ c = Capistrano::BaseHelper.get_capistrano_instance
99
+ c.run("sudo mkdir -p '#{File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path)}'")
100
+
101
+ commands = []
102
+ commands << "sudo chown #{c.fetch(:user)}:root /etc/sv/#{c.fetch(:user)}"
103
+ commands << "sudo chown #{c.fetch(:user)}:root /etc/sv/#{Capistrano::BaseHelper.user_app_env_path}"
104
+ c.run(commands.join(" && "))
105
+ Capistrano::BaseHelper.generate_and_upload_config( Capistrano::BaseHelper::get_capistrano_instance.fetch(:runit_local_run), Capistrano::BaseHelper::get_capistrano_instance.fetch(:runit_remote_run), true )
106
+ Capistrano::BaseHelper.generate_and_upload_config( Capistrano::BaseHelper::get_capistrano_instance.fetch(:runit_local_finish), Capistrano::BaseHelper::get_capistrano_instance.fetch(:runit_remote_finish), true )
107
+
108
+ commands = []
109
+ commands << "sudo chmod u+x '#{File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "run")}'"
110
+ commands << "sudo chmod u+x '#{File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "finish")}'"
111
+ commands << "sudo chmod g+x '#{File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "run")}'"
112
+ commands << "sudo chmod g+x '#{File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "finish")}'"
113
+ commands << "sudo chown #{c.fetch(:user)}:root '#{File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "run")}'"
114
+ commands << "sudo chown #{c.fetch(:user)}:root '#{File.join("/etc", "sv", Capistrano::BaseHelper.user_app_env_path, "finish")}'"
115
+ c.run(commands.join(" && "))
116
+
117
+ Capistrano::RunitBase.app_services_create_log_service
118
+ end
119
+
120
+ def app_services_enable(application, user)
121
+ Capistrano::BaseHelper.get_capistrano_instance.run("[ -h /etc/service/#{user}_#{application}_#{Capistrano::BaseHelper.environment} ] || sudo ln -sf /etc/sv/#{Capistrano::BaseHelper.user_app_env_path} /etc/service/#{user}_#{application}_#{Capistrano::BaseHelper.environment}")
122
+ end
123
+
124
+ def app_services_disable(application, user)
125
+ Capistrano::BaseHelper.get_capistrano_instance.run("[ ! -h /etc/service/#{user}_#{application}_#{Capistrano::BaseHelper.environment} ] || sudo rm -f /etc/service/#{user}_#{application}_#{Capistrano::BaseHelper.environment}")
126
+ end
127
+
128
+ def app_services_purge(application, user)
129
+ # this should stop ALL services running for the given application
130
+ # true is appended to ignore any errors failing to stop the services
131
+ commands = []
132
+ commands << "sudo rm -f /etc/service/#{user}_#{application}_#{Capistrano::BaseHelper.environment}"
133
+ commands << "sudo rm -rf /etc/sv/#{Capistrano::BaseHelper.user_app_env_path}"
134
+ Capistrano::BaseHelper.get_capistrano_instance.run(commands.join(" && "))
135
+ end
136
+
137
+ def app_services_stop(application, user, ignore_error = false)
138
+ app_services_control(application, user, "stop", ignore_error)
139
+ end
140
+
141
+ def app_services_start(application, user, ignore_error = false)
142
+ app_services_control(application, user, "start", ignore_error)
143
+ end
144
+
145
+ def app_services_once(application, user, ignore_error = false)
146
+ app_services_control(application, user, "once", ignore_error)
147
+ end
148
+
149
+ def app_services_control(application, user, command, ignore_error = false)
150
+ Capistrano::BaseHelper.get_capistrano_instance.run("[ ! -h /etc/service/#{user}_#{application} ] || sudo sv #{command} #{user}_#{application}; #{"true" if ignore_error != false}")
151
+ end
152
+
153
+ # END - ALL services functions (functions that affects all services for the app)
154
+
155
+
156
+ # BEGIN - Single service functions (functions that affects a single given service)
157
+
158
+ def start_service_once(service_name)
159
+ control_service(service_name, "once")
160
+ end
161
+
162
+ def start_service(service_name)
163
+ control_service(service_name, "start")
164
+ end
165
+
166
+ def stop_service(service_name)
167
+ control_service(service_name, "stop")
168
+ end
169
+
170
+ def restart_service(service_name)
171
+ control_service(service_name, "restart")
172
+ end
173
+
174
+ def control_service(service_name, service_control_function, ignore_error = false, arguments = "")
175
+ Capistrano::BaseHelper.get_capistrano_instance.run("[ ! -h #{service_path(service_name)}/run ] || sv #{arguments} #{service_control_function} #{service_path(service_name)}")
176
+ end
177
+
178
+ # Will not check if the service exists before trying to force it down
179
+ def force_control_service(service_name, service_control_function, ignore_error = false)
180
+ Capistrano::BaseHelper.get_capistrano_instance.run("sv #{service_control_function} #{service_path(service_name)}; #{"true" if ignore_error != false}")
181
+ end
182
+
183
+ def disable_service(service_name)
184
+ force_control_service(service_name, "force-stop", true) # force-stop the service before disabling it
185
+ Capistrano::BaseHelper.get_capistrano_instance.run("[ ! -h #{service_path(service_name)}/run ] || rm -f #{service_path(service_name)}/run && rm -f #{service_path(service_name)}/finish")
186
+ end
187
+
188
+ def enable_service(service_name, symlink_finish = nil)
189
+ Capistrano::BaseHelper.get_capistrano_instance.run("cd #{service_path(service_name)} && [ -h ./run ] || ln -sf #{remote_run_config_path(service_name)} ./run")
190
+ Capistrano::BaseHelper.get_capistrano_instance.run("cd #{service_path(service_name)} && [ -h ./finish ] || ln -sf #{remote_finish_config_path(service_name)} ./finish") unless symlink_finish.nil?
191
+ end
192
+
193
+ def purge_service(service_name)
194
+ Capistrano::BaseHelper.get_capistrano_instance.run("rm -rf #{service_path(service_name)}")
195
+ end
196
+
197
+ def remote_run_config_path(service_name)
198
+ File.join(service_path(service_name), "#{service_name}_run")
199
+ end
200
+
201
+ def remote_finish_config_path(service_name)
202
+ File.join(service_path(service_name), "#{service_name}_finish")
203
+ end
204
+
205
+ def remote_control_path(service_name, control_letter)
206
+ File.join(remote_control_path_root(service_name), control_letter)
207
+ end
208
+
209
+ def remote_control_path_root(service_name)
210
+ File.join(service_path(service_name), "control")
211
+ end
212
+
213
+ def remote_service_log_run_path(service_name)
214
+ File.join(service_path(service_name), "log", "run")
215
+ end
216
+
217
+ def make_service_scripts_executeable(service_name)
218
+ commands = []
219
+ if Capistrano::BaseHelper::remote_file_exists?(Capistrano::RunitBase.remote_run_config_path(service_name))
220
+ commands << "chmod u+x #{Capistrano::RunitBase.remote_run_config_path(service_name)}"
221
+ commands << "chmod g+x #{Capistrano::RunitBase.remote_run_config_path(service_name)}"
222
+ end
223
+ if Capistrano::BaseHelper::remote_file_exists?(Capistrano::RunitBase.remote_service_log_run_path(service_name))
224
+ commands << "chmod u+x #{Capistrano::RunitBase.remote_service_log_run_path(service_name)}"
225
+ commands << "chmod g+x #{Capistrano::RunitBase.remote_service_log_run_path(service_name)}"
226
+ end
227
+ if Capistrano::BaseHelper::remote_file_exists?(Capistrano::RunitBase.remote_control_path_root(service_name))
228
+ commands << "chmod u+x -R #{Capistrano::RunitBase.remote_control_path_root(service_name)}"
229
+ commands << "chmod g+x -R #{Capistrano::RunitBase.remote_control_path_root(service_name)}"
230
+ end
231
+ Capistrano::BaseHelper.get_capistrano_instance.run commands.join(" ; ")
232
+ end
233
+
234
+ # note that the user running the runit service MUST be a member of the group or the same as the log user
235
+ # If not, the log service will not work
236
+ def create_and_permissions_on_path(log_path, user = nil, group = nil)
237
+ user = Capistrano::BaseHelper.get_capistrano_instance.fetch(:user) if user.nil?
238
+ group = "syslog" if group.nil?
239
+ # will use sudo
240
+ commands = []
241
+ commands << "sudo mkdir -p #{log_path}"
242
+ commands << "sudo chown -R #{user}:#{group} #{log_path}"
243
+ commands << "sudo chmod u+w #{log_path}"
244
+ commands << "sudo chmod g+w #{log_path}"
245
+ Capistrano::BaseHelper.get_capistrano_instance.run commands.join(" && ")
246
+ end
247
+
248
+ # END - Single service functions (functions that affects a single given service)
249
+ end
250
+ end
@@ -0,0 +1,61 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "capistrano-base_helper"
8
+ s.version = "0.0.3"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Leif Ringstad"]
12
+ s.date = "2013-07-05"
13
+ s.description = "Helpers for capistrano recipes using runit/monit. Currently: capistrano-puma and capistrano-delayed_job"
14
+ s.email = "leifcr@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "LICENSE",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "capistrano-base_helper.gemspec",
27
+ "capistrano-base_helper.rb",
28
+ "capistrano-base_helper/base_helper.rb",
29
+ "capistrano-base_helper/monit_base.rb",
30
+ "capistrano-base_helper/runit_base.rb",
31
+ "templates/monit/app_include.conf.erb",
32
+ "templates/monit/monitrc.erb",
33
+ "templates/runit/finish.erb",
34
+ "templates/runit/log_run.erb",
35
+ "templates/runit/run.erb"
36
+ ]
37
+ s.homepage = "https://github.com/leifcr/capistrano-base-helper"
38
+ s.licenses = ["MIT"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = "1.8.25"
41
+ s.summary = "Helpers for capistrano recipes using runit/monit"
42
+
43
+ if s.respond_to? :specification_version then
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ s.add_runtime_dependency(%q<capistrano>, [">= 2.15.5"])
48
+ s.add_development_dependency(%q<bundler>, [">= 1.3.0"])
49
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.6"])
50
+ else
51
+ s.add_dependency(%q<capistrano>, [">= 2.15.5"])
52
+ s.add_dependency(%q<bundler>, [">= 1.3.0"])
53
+ s.add_dependency(%q<jeweler>, ["~> 1.8.6"])
54
+ end
55
+ else
56
+ s.add_dependency(%q<capistrano>, [">= 2.15.5"])
57
+ s.add_dependency(%q<bundler>, [">= 1.3.0"])
58
+ s.add_dependency(%q<jeweler>, ["~> 1.8.6"])
59
+ end
60
+ end
61
+
@@ -0,0 +1,11 @@
1
+ def try_require(library)
2
+ begin
3
+ require "#{library}"
4
+ rescue LoadError => e
5
+ puts "Capistrano-Base Helper: Cannot load library: #{library} Error: #{e}"
6
+ end
7
+ end
8
+
9
+ try_require 'capistrano-base_helper/base_helper'
10
+ try_require 'capistrano-base_helper/runit_base'
11
+ try_require 'capistrano-base_helper/monit_base'
@@ -0,0 +1,2 @@
1
+ <% c = Capistrano::BaseHelper::get_capistrano_instance %>
2
+ include <%= c.fetch(:monit_enabled_path) %>/*.conf
@@ -0,0 +1,29 @@
1
+ <% c = Capistrano::BaseHelper::get_capistrano_instance %>
2
+ set daemon <%= c.fetch(:monit_daemon_time) %>
3
+ with start delay <%= c.fetch(:monit_start_delay) %>
4
+
5
+ set logfile syslog facility log_daemon
6
+
7
+ set mailserver <%= c.fetch(:monit_mailserver) %>
8
+
9
+ set eventqueue
10
+ basedir /var/monit # set the base directory where events will be stored
11
+ # slots 1000 # optionaly limit the queue size
12
+
13
+ set mail-format {
14
+ from: <%= c.fetch(:monit_mail_sender) %>
15
+ subject: $SERVICE $EVENT $HOST
16
+ message: Monit $ACTION $SERVICE at $DATE on $HOST: $DESCRIPTION.
17
+ }
18
+ <% unless c.fetch(:monit_mail_reciever).nil? %>
19
+ set alert <%= c.fetch(:monit_mail_reciever) %> NOT ON { action, instance, pid, ppid }
20
+ <% end %>
21
+
22
+ <% unless c.fetch(:monit_use_httpd) == "false" %>
23
+ set httpd port <%= c.fetch(:monit_httpd_port) %>
24
+ <%= "use address #{c.fetch(:monit_httpd_bind_address, "localhost")}" unless c.fetch(:monit_httpd_bind_address).nil? %>
25
+ <%= "allow #{c.fetch(:monit_httpd_allow_address)}" unless c.fetch(:monit_httpd_allow_address).nil? %>
26
+ <%= "signature #{c.fetch(:monit_httpd_signature)}" %>
27
+ <% end %>
28
+
29
+ include /etc/monit/conf.d/*.conf
@@ -0,0 +1,6 @@
1
+ #!/bin/sh
2
+ # <% c = Capistrano::BaseHelper::get_capistrano_instance %>
3
+ # Finish/quit services for <%= c.fetch(:application) %> as <%= c.fetch(:user) %> in env <%= Capistrano::BaseHelper.environment %>
4
+ #
5
+ sv -w600 force-stop '<%= c.fetch(:runit_dir) %>/*'
6
+ sv exit '<%= c.fetch(:runit_dir) %>/*'
@@ -0,0 +1,12 @@
1
+ #!/bin/sh
2
+ # <% c = Capistrano::BaseHelper::get_capistrano_instance %>
3
+ # Log output for <%= c.fetch(:application) %> as <%= c.fetch(:user) %> in env <%= Capistrano::BaseHelper.environment %>
4
+ #
5
+ # make sure the log directory exists
6
+ mkdir -p "<%= File.join("/var", "log", "service", Capistrano::BaseHelper.user_app_env_path, "runit") %>"
7
+ # make sure the right owner is on the log directory
8
+ chown -R <%= "#{c.fetch(:runit_log_user)}:#{c.fetch(:runit_log_group)}" %> "<%= File.join("/var", "log", "service", Capistrano::BaseHelper.user_app_env_path, "runit") %>"
9
+ # change path to the log directory
10
+ cd "<%= File.join("/var", "log", "service", Capistrano::BaseHelper.user_app_env_path, "runit") %>"
11
+ # start logging
12
+ exec chpst -u <%= c.fetch(:runit_log_user)%> svlogd -tt "<%= File.join("/var", "log", "service", Capistrano::BaseHelper.user_app_env_path, "runit") %>"
@@ -0,0 +1,6 @@
1
+ #!/bin/sh -e
2
+ # <% c = Capistrano::BaseHelper::get_capistrano_instance %>
3
+ # Run services for <%= c.fetch(:application) %> as <%= c.fetch(:user) %> in env <%= Capistrano::BaseHelper.environment %>
4
+ #
5
+ exec 2>&1
6
+ exec chpst -u <%= c.fetch(:user) %> runsvdir "<%= c.fetch(:runit_dir) %>"
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-base_helper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Leif Ringstad
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: capistrano
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 2.15.5
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 2.15.5
30
+ - !ruby/object:Gem::Dependency
31
+ name: bundler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 1.3.0
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 1.3.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: jeweler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.8.6
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.8.6
62
+ description: ! 'Helpers for capistrano recipes using runit/monit. Currently: capistrano-puma
63
+ and capistrano-delayed_job'
64
+ email: leifcr@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files:
68
+ - LICENSE
69
+ - README.md
70
+ files:
71
+ - Gemfile
72
+ - Gemfile.lock
73
+ - LICENSE
74
+ - README.md
75
+ - Rakefile
76
+ - VERSION
77
+ - capistrano-base_helper.gemspec
78
+ - capistrano-base_helper.rb
79
+ - capistrano-base_helper/base_helper.rb
80
+ - capistrano-base_helper/monit_base.rb
81
+ - capistrano-base_helper/runit_base.rb
82
+ - templates/monit/app_include.conf.erb
83
+ - templates/monit/monitrc.erb
84
+ - templates/runit/finish.erb
85
+ - templates/runit/log_run.erb
86
+ - templates/runit/run.erb
87
+ homepage: https://github.com/leifcr/capistrano-base-helper
88
+ licenses:
89
+ - MIT
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ segments:
101
+ - 0
102
+ hash: 2652667416411912074
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ! '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 1.8.25
112
+ signing_key:
113
+ specification_version: 3
114
+ summary: Helpers for capistrano recipes using runit/monit
115
+ test_files: []