capistrano-base_helper 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []