capistrano-monit_runit 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 705f5e797d5a2516fb2900e85ae3252d732119bc
4
+ data.tar.gz: 0d0b76890fb55a86ab800ccd445c97ed28d78d1b
5
+ SHA512:
6
+ metadata.gz: 21406a6ee4f05b0df8bf3bd766eda7bd1fd052d73b3d6c82193ff353700a1ccf9839bedc41088513d564d0455aaa38c0bcf061bc3182679d8ebc32e97bacebca
7
+ data.tar.gz: 64b1200212abc514a4f7755aa07772e91b7d44c3701bcf43ec1c7949c55cf2881ab482965c003384f27bf8d55a33eb09515f20eb90811855f3c8dcd095b360b0
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'capistrano', '~> 3.4'
4
+ group :development do
5
+ gem 'bundler', '~> 1.7'
6
+ gem 'jeweler', '~> 2.0'
7
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,67 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.3.7)
5
+ builder (3.2.2)
6
+ capistrano (3.4.0)
7
+ i18n
8
+ rake (>= 10.0.0)
9
+ sshkit (~> 1.3)
10
+ colorize (0.7.5)
11
+ descendants_tracker (0.0.4)
12
+ thread_safe (~> 0.3, >= 0.3.1)
13
+ faraday (0.9.1)
14
+ multipart-post (>= 1.2, < 3)
15
+ git (1.2.9.1)
16
+ github_api (0.12.3)
17
+ addressable (~> 2.3)
18
+ descendants_tracker (~> 0.0.4)
19
+ faraday (~> 0.8, < 0.10)
20
+ hashie (>= 3.3)
21
+ multi_json (>= 1.7.5, < 2.0)
22
+ nokogiri (~> 1.6.3)
23
+ oauth2
24
+ hashie (3.4.0)
25
+ highline (1.7.1)
26
+ i18n (0.7.0)
27
+ jeweler (2.0.1)
28
+ builder
29
+ bundler (>= 1.0)
30
+ git (>= 1.2.5)
31
+ github_api
32
+ highline (>= 1.6.15)
33
+ nokogiri (>= 1.5.10)
34
+ rake
35
+ rdoc
36
+ jwt (1.4.1)
37
+ mini_portile (0.6.2)
38
+ multi_json (1.11.0)
39
+ multi_xml (0.5.5)
40
+ multipart-post (2.0.0)
41
+ net-scp (1.2.1)
42
+ net-ssh (>= 2.6.5)
43
+ net-ssh (2.9.2)
44
+ nokogiri (1.6.6.2)
45
+ mini_portile (~> 0.6.0)
46
+ oauth2 (1.0.0)
47
+ faraday (>= 0.8, < 0.10)
48
+ jwt (~> 1.0)
49
+ multi_json (~> 1.3)
50
+ multi_xml (~> 0.5)
51
+ rack (~> 1.2)
52
+ rack (1.6.0)
53
+ rake (10.4.2)
54
+ rdoc (4.2.0)
55
+ sshkit (1.7.1)
56
+ colorize (>= 0.7.0)
57
+ net-scp (>= 1.1.2)
58
+ net-ssh (>= 2.8.0)
59
+ thread_safe (0.3.5)
60
+
61
+ PLATFORMS
62
+ ruby
63
+
64
+ DEPENDENCIES
65
+ bundler (~> 1.7)
66
+ capistrano (~> 3.4)
67
+ jeweler (~> 2.0)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013-2015 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,133 @@
1
+ # Capistrano - Monit and Runit helpers
2
+
3
+ This libary is a helper library for capistrano tasks that setup [runit](smarden.org/runit/) and [monit](http://mmonit.com/monit) for various services.
4
+
5
+ Note: This has been updated to support Capistrano >= 3.4. If you still use Capistrano 2.x, see the capistrano2 branch
6
+
7
+ ## Versioning
8
+
9
+ This gem stays at 3.x for capistrano 3, as it seems logical.
10
+
11
+ ## Sudoing
12
+
13
+ The setup process requires sudo on some files and folders upon creation.
14
+
15
+ You must either do the job manually or add this to the sudoers file:
16
+
17
+ ```
18
+ Cmnd_Alias RUNITCAPISTRANO = ,
19
+ deploy ALL=NOPASSWD: /bin/chmod u+x /etc/sv/*
20
+ deploy ALL=NOPASSWD: /bin/chmod g+x /etc/sv/*
21
+ deploy ALL=NOPASSWD: /bin/chown deploy\:root /etc/sv/*
22
+ deploy ALL=NOPASSWD: /bin/chown -R deploy\:root /etc/sv/*
23
+ deploy ALL=NOPASSWD: /bin/chown -R deploy\:root /etc/service/*
24
+ deploy ALL=NOPASSWD: /bin/chown -R syslog\:syslog /var/log/service*
25
+ deploy ALL=NOPASSWD: /bin/mkdir -p /etc/service/*
26
+ deploy ALL=NOPASSWD: /bin/mkdir /etc/service/*
27
+ deploy ALL=NOPASSWD: /bin/mkdir -p /var/log/service*
28
+ deploy ALL=NOPASSWD: /bin/mkdir -p /etc/sv/*
29
+ deploy ALL=NOPASSWD: /bin/mkdir /etc/sv/*
30
+ deploy ALL=NOPASSWD: /bin/rm -rf /etc/service/*
31
+
32
+ ```
33
+ ,/bin/chown myuser:mygroup /var/www/html/*,/bin/chmod 755 /var/www/html2/myapp/*.txt
34
+
35
+
36
+ ## Services for Monit and Runit
37
+
38
+ Services created:
39
+
40
+ * _[capistrano-puma](https://github.com/leifcr/capistrano-puma)_ for [Puma](http://puma.io)
41
+ * _[capistrano-delayed_job](https://github.com/leifcr/capistrano-delayed_job)_ for [Delayed Job](https://github.com/collectiveidea/delayed_job)
42
+
43
+ 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.
44
+
45
+ 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.
46
+
47
+ ## Capistrano tasks
48
+
49
+ Tasks that work on your entire application and not just on a single service.
50
+
51
+ _Note: The tasks will not work unless you have installed any monit services_
52
+
53
+ ### Monit
54
+
55
+ All these tasks do monit tasks for all services setup with monit.
56
+
57
+ ```
58
+ cap monit:disable # Disable monit services for application
59
+ cap monit:enable # Enable monit services for application
60
+ cap monit:main_config # Setup main monit config file (/etc/monit/monitrc)
61
+ cap monit:monitor # Monitor the application
62
+ cap monit:purge # Purge/remove all monit configurations for the application
63
+ cap monit:reload # Reload monit config (global)
64
+ cap monit:restart # Restart monitoring the application
65
+ cap monit:setup # Setup monit folders and configuration
66
+ cap monit:start # Start monitoring the application permanent (Monit saves state)
67
+ cap monit:status # Status monit (global)
68
+ cap monit:stop # Stop monitoring the application permanent (Monit saves state)
69
+ ```
70
+
71
+ #### Setup in your deploy file
72
+
73
+ You can add this to deploy.rb or env.rb in order to automatically monitor/unmonitor tasks
74
+
75
+ It is important to unmonitor tasks while deploying as they can trigger stops/restarts to the app that monit thinks are "crashes"
76
+
77
+ ```ruby
78
+ before "deploy:started", "monit:unmonitor"
79
+ after "deploy:finished", "monit:monitor"
80
+ ```
81
+
82
+ If you want monit to automatically start/stop runit instead of triggering seperately
83
+
84
+ ```ruby
85
+ before "monit:unmonitor", "monit:stop"
86
+ after "monit:monitor", "monit:start"
87
+ ```
88
+
89
+ ### Runit
90
+
91
+ All these tasks do runit tasks for all services setup with runit.
92
+
93
+ ```
94
+ cap runit:disable # Disable runit services for application
95
+ cap runit:enable # Enable runit services for application
96
+ cap runit:once # Only start services once.
97
+ cap runit:purge # Purge/remove all runit configurations for the application
98
+ cap runit:setup # Setup runit for the application
99
+ cap runit:start # Start all runit services for current application
100
+ cap runit:stop # Stop all runit services for current application
101
+ ```
102
+
103
+ #### Setup in your deploy file
104
+
105
+ You can add this to deploy.rb or env.rb in order to automatically start/stop tasks
106
+
107
+ ```ruby
108
+ before "deploy", "runit:stop"
109
+ after "deploy", "runit:start"
110
+ ```
111
+
112
+ See each gem if you want to start/stop each service separate instead of together.
113
+
114
+ ## Assumptions
115
+
116
+ There are some assumptions when using this with capistrano.
117
+ The following variables must be set
118
+
119
+ * _:application_ - The application name
120
+ * _:user_ - The username which is running the deployed application (usually deploy..)
121
+ * _:group_ - The groupname which is running the deployed application (usually deploy..)
122
+
123
+ ## Contributing
124
+
125
+ * Fork the project
126
+ * Make a feature addition or bug fix
127
+ * Please test the feature or bug fix, or write tests for it
128
+ * Make a pull request
129
+
130
+ ## Copyright
131
+
132
+ (c) 2013-2015 Leif Ringstad. See LICENSE.txt for details
133
+
data/Rakefile ADDED
@@ -0,0 +1,39 @@
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-monit_runit'
18
+ gem.homepage = 'https://github.com/leifcr/capistrano-monit_runit'
19
+ gem.license = 'MIT'
20
+ gem.summary = 'Helpers for capistrano recipes using runit/monit'
21
+ gem.description = 'Helpers for capistrano recipes using runit/monit.'
22
+ gem.email = 'leifcr@gmail.com'
23
+ gem.authors = ['Leif Ringstad']
24
+ gem.files.exclude '.ruby-*'
25
+ gem.files.exclude '*.sublime-project'
26
+ gem.files.exclude '.rubocop.yml'
27
+ # dependencies defined in Gemfile
28
+ end
29
+ Jeweler::RubygemsDotOrgTasks.new
30
+
31
+ # require 'rdoc/task'
32
+ # Rake::RDocTask.new do |rdoc|
33
+ # version = File.exist?('VERSION') ? File.read('VERSION') : ""
34
+
35
+ # rdoc.rdoc_dir = 'rdoc'
36
+ # rdoc.title = "capistrano-empty #{version}"
37
+ # rdoc.rdoc_files.include('README*')
38
+ # rdoc.rdoc_files.include('lib/**/*.rb')
39
+ # end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 3.0.0
@@ -0,0 +1,70 @@
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
+ # stub: capistrano-monit_runit 3.0.0 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "capistrano-monit_runit"
9
+ s.version = "3.0.0"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
13
+ s.authors = ["Leif Ringstad"]
14
+ s.date = "2015-03-13"
15
+ s.description = "Helpers for capistrano recipes using runit/monit."
16
+ s.email = "leifcr@gmail.com"
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE",
25
+ "README.md",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "capistrano-monit_runit.gemspec",
29
+ "lib/capistrano/capistrano-monit_runit.rb",
30
+ "lib/capistrano/dsl/base_paths.rb",
31
+ "lib/capistrano/dsl/monit_paths.rb",
32
+ "lib/capistrano/dsl/runit_paths.rb",
33
+ "lib/capistrano/helpers/base.rb",
34
+ "lib/capistrano/helpers/monit.rb",
35
+ "lib/capistrano/helpers/runit.rb",
36
+ "lib/capistrano/monit.rb",
37
+ "lib/capistrano/runit.rb",
38
+ "lib/capistrano/tasks/base.rake",
39
+ "lib/capistrano/tasks/monit.rake",
40
+ "lib/capistrano/tasks/runit.rake",
41
+ "templates/monit/app_include.conf.erb",
42
+ "templates/monit/monitrc.erb",
43
+ "templates/runit/finish.erb",
44
+ "templates/runit/log_run.erb",
45
+ "templates/runit/run.erb"
46
+ ]
47
+ s.homepage = "https://github.com/leifcr/capistrano-monit_runit"
48
+ s.licenses = ["MIT"]
49
+ s.rubygems_version = "2.4.6"
50
+ s.summary = "Helpers for capistrano recipes using runit/monit"
51
+
52
+ if s.respond_to? :specification_version then
53
+ s.specification_version = 4
54
+
55
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
56
+ s.add_runtime_dependency(%q<capistrano>, ["~> 3.4"])
57
+ s.add_development_dependency(%q<bundler>, ["~> 1.7"])
58
+ s.add_development_dependency(%q<jeweler>, ["~> 2.0"])
59
+ else
60
+ s.add_dependency(%q<capistrano>, ["~> 3.4"])
61
+ s.add_dependency(%q<bundler>, ["~> 1.7"])
62
+ s.add_dependency(%q<jeweler>, ["~> 2.0"])
63
+ end
64
+ else
65
+ s.add_dependency(%q<capistrano>, ["~> 3.4"])
66
+ s.add_dependency(%q<bundler>, ["~> 1.7"])
67
+ s.add_dependency(%q<jeweler>, ["~> 2.0"])
68
+ end
69
+ end
70
+
File without changes
@@ -0,0 +1,18 @@
1
+ module Capistrano
2
+ module DSL
3
+ ##
4
+ # Base paths and filenames/folder names for both runit and monit
5
+ #
6
+ module BasePaths
7
+ # user_app_env_path in basehelper 0.x / capistrano 2.x version
8
+
9
+ def app_env_folder
10
+ "#{fetch(:application)}_#{environment}"
11
+ end
12
+
13
+ def user_app_env_file_name
14
+ "#{fetch(:user)}_#{fetch(:application)}_#{environment}"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ module Capistrano
2
+ module DSL
3
+ ##
4
+ # Paths and filenames for monit
5
+ module MonitPaths
6
+
7
+ # Folder should belong to root:root
8
+ def monit_etc_path
9
+ File.join("/etc", "monit")
10
+ end
11
+
12
+ # This folder must be writable by the user group deploy
13
+ # and ownership should be root:deploy
14
+ def monit_etc_conf_d_path
15
+ File.join(monit_etc_path, "conf.d")
16
+ end
17
+
18
+ # This file must have mode 0700 and belong to root!
19
+ def monit_monitrc_file
20
+ File.join(monit_etc_path, "monitrc")
21
+ end
22
+
23
+ # The symlink will belong to the deploy user
24
+ def monit_etc_app_symlink
25
+ File.join(monit_etc_conf_d_path, "#{user_app_env_file_name}.conf")
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,117 @@
1
+ module Capistrano
2
+ module DSL
3
+ ##
4
+ # Paths and filenames for runit
5
+ #
6
+ # Main app services are placed under
7
+ # /etc/sv/username/appname_env
8
+ #
9
+ # They are symlinked for enabling / disabling the entire app like this:
10
+ # /etc/service/username_appname_env --> /etc/sv/username/appname_env
11
+ #
12
+ # All services run/finish scripts e.g. puma/delayed job etc are located in
13
+ # 'shared_folder'/runit/service_name/
14
+ module RunitPaths
15
+ # /etc/sv
16
+ def runit_etc_sv_path
17
+ File.join('/etc', 'sv')
18
+ end
19
+
20
+ def runit_user_base_path
21
+ File.join(runit_etc_sv_path, fetch(:user))
22
+ end
23
+
24
+ def runit_base_path
25
+ File.join(runit_user_base_path, app_env_folder)
26
+ end
27
+
28
+ def runit_base_log_path
29
+ File.join(runit_base_path, 'log')
30
+ end
31
+
32
+ def runit_run_file
33
+ File.join(runit_base_path, 'run')
34
+ end
35
+
36
+ def runit_finish_file
37
+ File.join(runit_base_path, 'finish')
38
+ end
39
+
40
+ def runit_log_run_file
41
+ File.join(runit_base_log_path, 'run')
42
+ end
43
+
44
+ def runit_var_log_service_path
45
+ File.join('/var', 'log', 'service')
46
+ end
47
+
48
+ def runit_var_log_service_single_service_path(service_name)
49
+ File.join(runit_var_log_service_path, user_app_env_underscore, service_name)
50
+ end
51
+
52
+ # /var/log/service/'usr_app_env_folder'/runit
53
+ def runit_var_log_service_runit_path
54
+ runit_var_log_service_single_service_path('runit')
55
+ end
56
+
57
+ # /etc/service
58
+ def runit_etc_service_path
59
+ File.join('/etc', 'service')
60
+ end
61
+
62
+ def runit_etc_service_app_symlink_name
63
+ File.join('/etc', 'service', user_app_env_file_name)
64
+ end
65
+
66
+ # Paths and files in shared_folder
67
+ def runit_service_path(service_name)
68
+ File.join(fetch(:runit_dir), service_name)
69
+ end
70
+
71
+ def runit_service_log_path(service_name)
72
+ File.join(runit_service_path(service_name), 'log')
73
+ end
74
+
75
+ def runit_service_control_path(service_name)
76
+ File.join(runit_service_path(service_name), 'control')
77
+ end
78
+
79
+ def runit_service_control_file(service_name, control_letter)
80
+ File.join(runit_service_control_path(service_name), control_letter)
81
+ end
82
+
83
+ def runit_service_log_run_file(service_name)
84
+ File.join(runit_service_log_path(service_name), 'run')
85
+ end
86
+
87
+ def runit_service_run_file(service_name)
88
+ File.join(runit_service_path(service_name), 'run')
89
+ end
90
+
91
+ def runit_service_finish_file(service_name)
92
+ File.join(runit_service_path(service_name), 'finish')
93
+ end
94
+
95
+ def runit_service_run_config_file(service_name)
96
+ File.join(runit_service_path(service_name), "#{service_name}_run")
97
+ end
98
+
99
+ def runit_service_finish_config_file(service_name)
100
+ File.join(runit_service_path(service_name), "#{service_name}_finish")
101
+ end
102
+
103
+ def create_service_folders(service_name)
104
+ if test "[ -d #{runit_service_path(service_name)} ]"
105
+ execute :mkdir, "-p #{runit_service_path(service_name)}"
106
+ end
107
+ if test "[ -d #{runit_service_path(service_name)} ]"
108
+ execute :mkdir, "-p #{runit_service_path(service_name)}"
109
+ end
110
+ end
111
+
112
+ def service_pid(service_name)
113
+ File.join(runit_service_path(service_name), 'supervise', 'pid')
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,60 @@
1
+ module Capistrano
2
+ module Helpers
3
+ ##
4
+ # Helper functions for both runit and monit
5
+ module Base
6
+ def user_app_env_underscore
7
+ "#{fetch(:user)}_#{fetch(:application)}_#{environment}"
8
+ end
9
+
10
+ def user_app_env_underscore_short
11
+ "#{fetch(:user)[0...1]}_#{environment[0...1]}_#{fetch(:application)}"
12
+ end
13
+
14
+ def user_app_env_underscore_short_char_safe
15
+ user_app_env_underscore_short.gsub!('-', '_')
16
+ end
17
+
18
+ ##
19
+ # Automatically sets the environment based on presence of
20
+ # :stage (multistage)
21
+ # :rails_env
22
+ # RAILS_ENV variable;
23
+ #
24
+ # Defaults to "production" if not found
25
+ #
26
+ def environment # rubocop:disable Metrics/MethodLength
27
+ if !fetch(:rails_env).nil?
28
+ fetch(:rails_env)
29
+ elsif !fetch(:rack_env).nil?
30
+ fetch(:rack_env)
31
+ elsif !fetch(:stage).nil?
32
+ fetch(:stage)
33
+ else
34
+ info '---------------------------------------------------------------'
35
+ info '- Stage, rack or rails environment isn\'t set in -'
36
+ info '- :stage, :rails_env or :rack_env, defaulting to \'production\' -'
37
+ info '---------------------------------------------------------------'
38
+ 'production'
39
+ end
40
+ end
41
+
42
+ def template_to_s_io(template_file)
43
+ fail "Cannot find templte #{template_file}" unless File.exist?(template_file)
44
+ StringIO.new(ERB.new(File.read(template_file)).result(binding))
45
+ end
46
+
47
+ ##
48
+ # Execute a rake taske using the proper env.
49
+ # run_rake db:migrate
50
+ #
51
+ def run_rake(task)
52
+ within(current_path) do
53
+ with rails_env: fetch(:rails_env) do
54
+ execute :rake, "#{task}"
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,47 @@
1
+ module Capistrano
2
+ module Helpers
3
+ ##
4
+ # Helper functions for monit
5
+ #
6
+ module Monit
7
+ ##
8
+ # Control / Command monit with given arguments
9
+ def command_monit(command, arguments = '')
10
+ execute :sudo, :monit, "#{arguments} #{command}"
11
+ end
12
+
13
+ ##
14
+ # Control / Command a monit group
15
+ # namescheme: user_application_environment "#{user}_#{application}_#{environment}"
16
+ #
17
+ def command_monit_group(command, arguments = '')
18
+ command_monit(command, "-g #{fetch(:monit_application_group_name)} #{arguments}")
19
+ end
20
+
21
+ ##
22
+ # Command a single monit service
23
+ #
24
+ # The service name scheme is recommended to be
25
+ # "#{user}_#{application}_#{environment}_#{service}"
26
+ #
27
+ def command_monit_service(command, service_name, arguments = '')
28
+ execute :sudo, :monit, "#{arguments} #{command} #{service_name}"
29
+ end
30
+
31
+ ##
32
+ # The service name is the same as the conf file name for the service.
33
+ # E.g. puma.conf
34
+ #
35
+ # This will symlink the service to enabled service, but not start or reload monit configuration
36
+ #
37
+ def enable_service(service_conf_filename)
38
+ return unless test("[ -h #{File.join(c.fetch(:monit_enabled_path), service_conf_filename)} ]")
39
+ execute :ln, "-sf #{File.join(c.fetch(:monit_available_path), service_conf_filename)} #{File.join(c.fetch(:monit_enabled_path), service_conf_filename)}" # rubocop:disable Metrics/LineLength:
40
+ end
41
+
42
+ def disable_service(service_conf_filename)
43
+ execute :rm, "-f #{File.join(c.fetch(:monit_enabled_path), service_conf_filename)}"
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,79 @@
1
+ module Capistrano
2
+ module Helpers
3
+ module Runit
4
+ # Any command sent to this function controls _all_ services related to the app
5
+ def runit_app_services_control(command)
6
+ return unless test("[ ! -h #{runit_etc_service_app_symlink_name} ]")
7
+ execute :sudo, :sv, "#{command} #{runit_etc_service_app_symlink_name}"
8
+ end
9
+
10
+ # Begin - single service control functions
11
+
12
+ # def start_service_once(service_name)
13
+ # control_service(service_name, "once")
14
+ # end
15
+
16
+ # def start_service(service_name)
17
+ # control_service(service_name, "start")
18
+ # end
19
+
20
+ # def stop_service(service_name)
21
+ # control_service(service_name, "stop")
22
+ # end
23
+
24
+ # def restart_service(service_name)
25
+ # control_service(service_name, "restart")
26
+ # end
27
+
28
+ def control_service(service_name, command, arguments, _ignore_error = false)
29
+ return unless test "[ ! -h #{runit_service_path(service_name)}/run ]"
30
+ execute :sv, "#{arguments} #{command} #{runit_service_path(service_name)}"
31
+ end
32
+
33
+ # Will not check if the service exists before trying to force it down
34
+ def force_control_service(service_name, command, arguments, _ignore_error = false)
35
+ execute :sv, "#{arguments} #{command} #{runit_service_path(service_name)}"
36
+ end
37
+
38
+ def disable_service(service_name)
39
+ force_control_service(service_name, 'force-stop', '', true) # force-stop the service before disabling it
40
+ within(runit_service_path(service_name)) do
41
+ execute :rm, '-f ./run' if test '[ ! -h ./run ]'
42
+ execute :rm, '-f ./finish' if test '[ ! -h ./finish ]'
43
+ end
44
+ end
45
+
46
+ def enable_service(service_name)
47
+ within(runit_service_path(service_name)) do
48
+ execute :ln, "-sf #{runit_service_run_config_file} ./run" if test '[ -h ./run ]'
49
+ execute :ln, "-sf #{runit_service_finish_config_file} ./finish" if test '[ -h ./finish ]'
50
+ end
51
+ end
52
+
53
+ def purge_service(service_name)
54
+ execute :rm, "-rf #{runit_service_path(service_name)}"
55
+ end
56
+
57
+ def runit_set_executable_files(service_name) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
58
+ if test("[ -f '#{runit_service_run_config_file(service_name)}']")
59
+ execute :chmod, "775 #{runit_service_run_config_file(service_name)}"
60
+ end
61
+ if test("[ -f '#{runit_service_finish_config_file(service_name)}']")
62
+ execute :chmod, "775 #{runit_service_finish_config_file(service_name)}"
63
+ end
64
+
65
+ if test("[ -f '#{runit_service_log_run_file(service_name)}']")
66
+ execute :chmod, "775 #{runit_service_log_run_file(service_name)}"
67
+ end
68
+
69
+ if test("[ -d '#{runit_service_control_path(service_name)}']") # rubocop:disable Style/GuardClause
70
+ execute :chmod, "775 -R #{runit_service_control_path(service_name)}"
71
+ # execute :chmod, 'u+x -R runit_service_control_path(service_name)'
72
+ # execute :chmod, 'g+x -R runit_service_control_path(service_name)'
73
+ end
74
+ end
75
+
76
+ # End - single service control functions
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,12 @@
1
+ def try_require(library)
2
+ require "#{library}"
3
+ rescue LoadError => e
4
+ puts "Capistrano / Base Helper: Cannot load library: #{library} Error: #{e}"
5
+ end
6
+
7
+ try_require 'capistrano/dsl/base_paths'
8
+ try_require 'capistrano/dsl/monit_paths'
9
+ try_require 'capistrano/helpers/base'
10
+ try_require 'capistrano/helpers/monit'
11
+ load File.expand_path('../tasks/base.rake', __FILE__)
12
+ load File.expand_path('../tasks/monit.rake', __FILE__)
@@ -0,0 +1,12 @@
1
+ def try_require(library)
2
+ require "#{library}"
3
+ rescue LoadError => e
4
+ puts "Capistrano / Base Helper: Cannot load library: #{library} Error: #{e}"
5
+ end
6
+
7
+ try_require 'capistrano/dsl/base_paths'
8
+ try_require 'capistrano/dsl/runit_paths'
9
+ try_require 'capistrano/helpers/base'
10
+ try_require 'capistrano/helpers/runit'
11
+ load File.expand_path('../tasks/base.rake', __FILE__)
12
+ load File.expand_path('../tasks/runit.rake', __FILE__)
@@ -0,0 +1,6 @@
1
+ namespace :load do
2
+ task :defaults do
3
+ set :pids_path, proc { shared_path.join('pids') }
4
+ set :sockets_path, proc { shared_path.join('sockets') }
5
+ end
6
+ end
@@ -0,0 +1,223 @@
1
+ # Monit capistrano 3.x tasks
2
+ #
3
+ # Application config and tasks that apply to all services setup
4
+ # with monit for the application
5
+ #
6
+ # Recommendation:
7
+ # Let monit monitor any long-running processes to ensure they keep
8
+ # within the limits set by you.
9
+
10
+ include Capistrano::DSL::BasePaths
11
+ include Capistrano::DSL::MonitPaths
12
+ include Capistrano::Helpers::Base
13
+ include Capistrano::Helpers::Monit
14
+
15
+ namespace :load do
16
+ task :defaults do
17
+ set :monit_dir, proc { shared_path.join('monit') }
18
+ set :monit_available_path, proc { File.join(fetch(:monit_dir), 'available') }
19
+ set :monit_enabled_path, proc { File.join(fetch(:monit_dir), 'enabled') }
20
+ set :monit_application_group_name, proc { user_app_env_underscore }
21
+
22
+ set :monit_mailserver, 'localhost'
23
+ set :monit_mail_sender, 'monit@$HOST'
24
+ set :monit_mail_reciever, nil # if this is nil, alerts are disabled
25
+ set :monit_use_httpd, 'true'
26
+ set :monit_httpd_bind_address, 'localhost'
27
+ set :monit_httpd_allow_address, 'localhost'
28
+ set :monit_httpd_signature, 'enable' # or enable
29
+ set :monit_httpd_port, '2812'
30
+
31
+ set :monit_daemon_time, '60'
32
+ set :monit_start_delay, '60'
33
+
34
+ set :monit_monitrc_template, File.join(File.expand_path(File.join(File.dirname(__FILE__), '../../../templates', 'monit')), 'monitrc.erb') # rubocop:disable Metrics/LineLength:
35
+ set :monit_application_conf_template, File.join(File.expand_path(File.join(File.dirname(__FILE__), '../../../templates', 'monit')), 'app_include.conf.erb') # rubocop:disable Metrics/LineLength:
36
+
37
+ set :monit_application_conf_file, proc { File.join(fetch(:monit_dir), 'monit.conf') }
38
+ end
39
+ end
40
+
41
+ namespace :monit do
42
+ desc 'Setup monit for the application'
43
+ task :setup do
44
+ on roles(:app) do |host|
45
+ info "MONIT: Setting up initial monit configuration on #{host}"
46
+ if test "[ ! -d #{fetch(:monit_dir)} ]"
47
+ execute :mkdir, "-p #{fetch(:monit_dir)}"
48
+ end
49
+ if test "[ ! -d #{fetch(:monit_available_path)} ]"
50
+ execute :mkdir, "-p #{fetch(:monit_available_path)}"
51
+ end
52
+ if test "[ ! -d #{fetch(:monit_enabled_path)} ]"
53
+ execute :mkdir, "-p #{fetch(:monit_enabled_path)}"
54
+ end
55
+ end
56
+ end
57
+
58
+ desc 'Get the config needed to add to sudoers'
59
+ task :sudoers do
60
+ run_locally do
61
+ info '---------------ENTRIES FOR SUDOERS (Monit)---------------------'
62
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chmod 0700 #{monit_monitrc_file}"
63
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chmod 0775 #{monit_etc_path}"
64
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chmod 0700 #{monit_etc_path}"
65
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/mkdir -p #{monit_etc_conf_d_path}"
66
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chmod 6775 #{monit_etc_conf_d_path}"
67
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chown #{fetch(:user)}\\:root #{monit_etc_path}"
68
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chown #{fetch(:user)}\\:root #{monit_etc_conf_d_path}"
69
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chown #{fetch(:user)}\\:root #{monit_monitrc_file}"
70
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chown root\\:root #{monit_monitrc_file}"
71
+ puts "#{fetch(:user)} ALL=NOPASSWD: /usr/bin/monit *"
72
+ puts "#{fetch(:user)} ALL=NOPASSWD: /usr/sbin/service monit *"
73
+ info '---------------------------------------------------------------'
74
+ end
75
+ # info "#{fetch(:user)} ALL=NOPASSWD: /bin/chown deploy:root #{monit_monitrc_file}"
76
+ end
77
+
78
+ desc 'Setup main monit config file (/etc/monit/monitrc)'
79
+ task :main_config do
80
+ on roles(:app) do |host|
81
+ set :createmonitrc, ask("Create #{monit_monitrc_file} [Y/n]", 'Y')
82
+ if fetch(:createmonitrc) == 'Y'
83
+ info "MONIT: Creating #{monit_monitrc_file} on #{host}"
84
+ if test("[ ! -d #{monit_etc_conf_d_path} ]")
85
+ execute :sudo, :mkdir, "-p #{monit_etc_conf_d_path}"
86
+ execute :sudo, :chmod, "6775 #{monit_etc_conf_d_path}"
87
+ execute :sudo, :chown, "#{fetch(:user)}:root #{monit_etc_conf_d_path}"
88
+ end
89
+ execute :sudo, :chown, "#{fetch(:user)}:root #{monit_etc_path}"
90
+ execute :sudo, :chmod, "0775 #{monit_etc_path}"
91
+ execute :sudo, :chown, "#{fetch(:user)}:root #{monit_monitrc_file}"
92
+ upload! template_to_s_io(fetch(:monit_monitrc_template)), monit_monitrc_file
93
+ execute :sudo, :chmod, "0700 #{monit_monitrc_file}"
94
+ execute :sudo, :chown, "root:root #{monit_monitrc_file}"
95
+ execute :sudo, :service, 'monit restart'
96
+ info "MONIT: Sleeping for #{fetch(:monit_start_delay).to_i} seconds to wait for monit to be ready"
97
+ sleep(fetch(:monit_start_delay).to_i)
98
+ end
99
+ end
100
+ end
101
+
102
+ desc 'Enable monit services for application'
103
+ task :enable do
104
+ on roles(:app) do |host|
105
+ if test("[ ! -h #{monit_etc_app_symlink} ]")
106
+ info "MONIT: Enabling for #{fetch(:application)} on #{host}"
107
+ execute :ln, "-sf #{fetch(:monit_application_conf_file)} #{monit_etc_app_symlink}"
108
+ else
109
+ info "MONIT: Already enabled for #{fetch(:application)} on #{host}"
110
+ end
111
+ end
112
+ end
113
+
114
+ desc 'Disable monit services for application'
115
+ task :disable do
116
+ on roles(:app) do |host|
117
+ if test("[ -h #{monit_etc_app_symlink} ]")
118
+ info "MONIT: Disabling for #{fetch(:application)} on #{host}"
119
+ execute :rm, "-ff #{monit_etc_app_symlink}"
120
+ else
121
+ info "MONIT: Already disabled for #{fetch(:application)} on #{host}"
122
+ end
123
+ end
124
+ end
125
+
126
+ desc 'Purge/remove all monit configurations for the application'
127
+ task :purge do
128
+ on roles(:app) do |host|
129
+ info "MONIT: 'Purging config on #{host}"
130
+ execute :rm, "-rf #{fetch(:monit_dir)}" if test("[ -d #{fetch(:monit_dir)} ]")
131
+ execute :rm, "-f #{monit_etc_app_symlink}"
132
+ end
133
+ end
134
+
135
+ desc 'Monitor the application'
136
+ task :monitor do
137
+ on roles(:app) do |host|
138
+ info "MONIT: Application: Monitoring on #{host}"
139
+ command_monit_group('monitor')
140
+ end
141
+ end
142
+
143
+ desc 'Unmonitor the application'
144
+ task :unmonitor do
145
+ on roles(:app) do |host|
146
+ info "MONIT: Application: Unmonitoring on #{host}"
147
+ command_monit_group('unmonitor')
148
+ end
149
+ end
150
+
151
+ desc 'Stop monitoring the application permanent (Monit saves state)'
152
+ task :stop do
153
+ on roles(:app) do |host|
154
+ info "MONIT: Application: Stopping on #{host}"
155
+ command_monit_group('stop')
156
+ end
157
+ end
158
+
159
+ desc 'Start monitoring the application permanent (Monit saves state)'
160
+ task :start do
161
+ on roles(:app) do |host|
162
+ info "MONIT: Application: Starting on #{host}"
163
+ command_monit_group('start')
164
+ end
165
+ end
166
+
167
+ desc 'Restart monitoring the application'
168
+ task :restart do
169
+ on roles(:app) do |host|
170
+ info "MONIT: Application: Restarting on #{host}"
171
+ command_monit_group('restart')
172
+ end
173
+ end
174
+
175
+ desc 'Reload monit config (global)'
176
+ task :reload do
177
+ on roles(:app) do |host|
178
+ info "MONIT: Global: Reloading on #{host}"
179
+ command_monit('reload')
180
+ end
181
+ end
182
+
183
+ desc 'Status monit (global)'
184
+ task :status do
185
+ on roles(:app) do |host|
186
+ info "MONIT: Global: Status on #{host}"
187
+ command_monit('status')
188
+ end
189
+ end
190
+
191
+ desc 'Summary monit (global)'
192
+ task :summary do
193
+ on roles(:app) do |host|
194
+ info "MONIT: Global: Summary for #{host}"
195
+ command_monit('summary')
196
+ end
197
+ end
198
+
199
+ desc 'Validate monit (global)'
200
+ task :validate do
201
+ on roles(:app) do |host|
202
+ info "MONIT: Global: Validating config on #{host}"
203
+ command_monit('validate')
204
+ end
205
+ end
206
+ end
207
+
208
+ # after 'deploy:update', 'monit:enable'
209
+ # after 'deploy:setup', 'monit:setup'
210
+ before 'monit:setup', 'monit:main_config'
211
+ # after 'monit:setup', 'monit:enable'
212
+ after 'monit:enable', 'monit:reload'
213
+
214
+ # This should be done in the app, as the sequence of restarting services can be specific
215
+ # must trigger monitor after deploy
216
+ # after 'deploy', 'monit:monitor'
217
+ # must trigger unmonitor before deploy
218
+ # before 'deploy', 'monit:unmonitor'
219
+
220
+ before 'monit:disable', 'monit:unmonitor'
221
+ after 'monit:disable', 'monit:reload'
222
+
223
+ before 'monit:purge', 'monit:unmonitor'
@@ -0,0 +1,172 @@
1
+ # Runit capistrano 3.x tasks
2
+ #
3
+ # Application config and tasks that apply to all services setup
4
+ # with runit for the application
5
+ #
6
+ # Recommendation:
7
+ # Everything that should run as either a service or deamon,
8
+ # can and should use runit
9
+
10
+ require 'capistrano/dsl/base_paths'
11
+ require 'capistrano/dsl/runit_paths'
12
+ require 'capistrano/helpers/base'
13
+ require 'capistrano/helpers/runit'
14
+
15
+ include Capistrano::DSL::BasePaths
16
+ include Capistrano::DSL::RunitPaths
17
+ include Capistrano::Helpers::Base
18
+ include Capistrano::Helpers::Runit
19
+
20
+ namespace :load do
21
+ task :defaults do
22
+ set :runit_dir, proc { shared_path.join('runit') }
23
+ set :runit_run_template, File.join(File.expand_path(File.join(File.dirname(__FILE__), '../../../templates')), 'runit', 'run.erb') # rubocop:disable Metrics/LineLength:
24
+ set :runit_finish_template, File.join(File.expand_path(File.join(File.dirname(__FILE__), '../../../templates')), 'runit', 'finish.erb') # rubocop:disable Metrics/LineLength:
25
+ set :runit_log_run_template, File.join(File.expand_path(File.join(File.dirname(__FILE__), '../../../templates')), 'runit', 'log_run.erb') # rubocop:disable Metrics/LineLength:
26
+ set :runit_log_user, 'syslog'
27
+ set :runit_log_group, 'syslog'
28
+ set :runit_restart_interval, 10
29
+ set :runit_restart_count, 7
30
+ set :runit_autorestart_clear_interval, 90
31
+ end
32
+ end
33
+
34
+ namespace :runit do
35
+ desc 'Get the config needed to add to sudoers for all commands'
36
+ task :sudoers do
37
+ run_locally do
38
+ info '---------------ENTRIES FOR SUDOERS (Runit)---------------------'
39
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/mkdir -p #{runit_user_base_path}"
40
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chown #{fetch(:user)}\\:root #{runit_user_base_path}"
41
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chmod 6775 #{runit_user_base_path}"
42
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/mkdir -p #{runit_etc_service_path}"
43
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chown #{fetch(:user)}\\:root #{runit_etc_service_path}"
44
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chmod 6775 #{runit_etc_service_path}"
45
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/mkdir -p #{runit_var_log_service_path}"
46
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chown #{fetch(:user)}\\:root #{runit_var_log_service_path}"
47
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chown -R #{fetch(:user)}\\:#{fetch(:runit_log_group)} #{runit_var_log_service_path}" # rubocop:disable Metrics/LineLength:
48
+ puts "#{fetch(:user)} ALL=NOPASSWD: /bin/chmod 6775 #{runit_var_log_service_path}"
49
+ puts "#{fetch(:user)} ALL=NOPASSWD: /usr/bin/sv *"
50
+ info '---------------------------------------------------------------'
51
+ end
52
+ # info "#{fetch(:user)} ALL=NOPASSWD: /bin/chown deploy:root #{monit_monitrc_file}"
53
+ end
54
+
55
+ desc 'Setup runit for the application'
56
+ task :setup do
57
+ on roles(:app) do |host|
58
+ info "RUNIT: Setting up initial runit configuration on #{host}"
59
+ if test "[ ! -f #{fetch(:runit_dir)}/.env/HOME ]"
60
+ if test "[ ! -d #{fetch(:runit_dir)}/.env ]"
61
+ execute :mkdir, "-p '#{fetch(:runit_dir)}/.env'"
62
+ end
63
+ upload! StringIO.new('$HOME'), "#{File.join(fetch(:runit_dir), '.env', 'HOME')}"
64
+ end
65
+ end
66
+ end
67
+
68
+ namespace :setup do
69
+ # '[INTERNAL] create /etc/sv folders and upload base templates needed'
70
+ task :runit_create_app_services do
71
+ on roles(:app) do |host|
72
+ # set :pw, ask("Sudo password", '')
73
+ # execute :echo, "#{fetch(:pw)} | sudo -S ls /"
74
+ if test("[ ! -d '#{runit_user_base_path}' ]")
75
+ execute :sudo, :mkdir, "-p '#{runit_user_base_path}'"
76
+ execute :sudo, :chown, "#{fetch(:user)}:root '#{runit_user_base_path}'"
77
+ execute :sudo, :chmod, "6775 '#{runit_user_base_path}'"
78
+ end
79
+ if test("[ ! -d '#{runit_etc_service_path}' ]")
80
+ execute :sudo, :mkdir, "-p '#{runit_etc_service_path}'"
81
+ execute :sudo, :chown, "#{fetch(:user)}:root '#{runit_etc_service_path}'"
82
+ execute :sudo, :chmod, "6775 '#{runit_etc_service_path}'"
83
+ end
84
+ within("#{runit_user_base_path}") do
85
+ execute :mkdir, "-p #{app_env_folder}"
86
+ end
87
+
88
+ upload! template_to_s_io(fetch(:runit_run_template)), runit_run_file
89
+ upload! template_to_s_io(fetch(:runit_finish_template)), runit_finish_file
90
+
91
+ # Should now work without sudo... ?
92
+ execute :chmod, "0775 '#{runit_run_file}'"
93
+ execute :chmod, "0775 '#{runit_finish_file}'"
94
+ info "RUNIT: Created inital runit services in #{runit_base_path} for #{fetch(:application)} on #{host}"
95
+ end
96
+ end
97
+
98
+ # [Internal] create log service for app
99
+ task :runit_create_app_log_services do
100
+ on roles(:app) do |host|
101
+ within("#{runit_base_path}") do
102
+ execute :mkdir, '-p log'
103
+ end
104
+ upload! template_to_s_io(fetch(:runit_log_run_template)), runit_log_run_file
105
+ if test("[ ! -d #{runit_var_log_service_path} ]")
106
+ execute :sudo, :mkdir, "-p '#{runit_var_log_service_path}'"
107
+ execute :sudo, :chmod, "6775 '#{runit_var_log_service_path}'"
108
+ execute :sudo, :chown, "-R #{fetch(:user)}:#{fetch(:runit_log_group)} '#{runit_var_log_service_path}'" # rubocop:disable Metrics/LineLength:
109
+ end
110
+ execute :mkdir, "-p #{runit_var_log_service_runit_path}" if test("[ ! -d #{runit_var_log_service_runit_path} ]")
111
+ execute :chmod, "775 '#{runit_log_run_file}'"
112
+
113
+ info "RUNIT: Created inital runit log services in #{runit_base_log_path} for #{fetch(:application)} on #{host}"
114
+ end
115
+ end
116
+ end
117
+
118
+ desc 'Disable runit services for application'
119
+ task :disable do
120
+ on roles(:app) do |host|
121
+ if test "[ -h #{runit_etc_service_app_symlink_name} ]"
122
+ execute :rm, "-rf '#{runit_etc_service_app_symlink_name}'"
123
+ info "RUNIT disabling on '#{host}'"
124
+ else
125
+ info "RUNIT already disabled on '#{host}'"
126
+ end
127
+ end
128
+ end
129
+
130
+ desc 'Enable runit services for application'
131
+ task :enable do
132
+ on roles(:app) do |host|
133
+ if test "[ ! -h #{runit_etc_service_app_symlink_name} ]"
134
+ execute :ln, "-sf '#{runit_base_path}' '#{runit_etc_service_app_symlink_name}'"
135
+ info "RUNIT enabling on '#{host}'"
136
+ else
137
+ info "RUNIT already enabled on '#{host}'"
138
+ end
139
+ end
140
+ end
141
+
142
+ desc 'Purge/remove all runit configurations for the application'
143
+ task :purge do
144
+ on roles(:app) do |host|
145
+ execute :rm, "-rf #{runit_etc_service_app_symlink_name}"
146
+ execute :rm, "-rf #{runit_base_path}"
147
+ info "RUNIT purging config on '#{host}'"
148
+ end
149
+ end
150
+
151
+ desc 'Stop all runit services for current application'
152
+ task :stop do
153
+ runit_app_services_control('stop')
154
+ end
155
+
156
+ desc 'Start all runit services for current application'
157
+ task :start do
158
+ runit_app_services_control('start')
159
+ end
160
+
161
+ desc 'Only start services once. Will not restart if they fail.'
162
+ task :once do
163
+ runit_app_services_control('once')
164
+ end
165
+ end
166
+
167
+ before 'runit:purge', 'runit:stop'
168
+
169
+ after 'deploy:updated', 'runit:enable'
170
+ # after 'deploy:setup', 'runit:setup'
171
+ after 'runit:setup', 'runit:setup:runit_create_app_services'
172
+ after 'runit:setup:runit_create_app_services', 'runit:setup:runit_create_app_log_services'
@@ -0,0 +1 @@
1
+ include <%= fetch(:monit_enabled_path) %>/*.conf
@@ -0,0 +1,23 @@
1
+ set daemon <%= fetch(:monit_daemon_time) %>
2
+ with start delay <%= fetch(:monit_start_delay) %>
3
+
4
+ set logfile syslog facility log_daemon
5
+
6
+ set statefile /var/lib/monit/state
7
+
8
+ set idfile /var/lib/monit/id
9
+
10
+ set eventqueue
11
+ basedir /var/monit # set the base directory where events will be stored
12
+ slots 100 # optionaly limit the queue size
13
+
14
+ <%= fetch(:mail_alert_settings) %>
15
+
16
+ <% unless fetch(:monit_use_httpd) == "false" %>
17
+ set httpd port <%= fetch(:monit_httpd_port) %>
18
+ <%= "use address #{fetch(:monit_httpd_bind_address, "localhost")}" unless fetch(:monit_httpd_bind_address).nil? %>
19
+ <%= "allow #{fetch(:monit_httpd_allow_address)}" unless fetch(:monit_httpd_allow_address).nil? %>
20
+ <%= "signature #{fetch(:monit_httpd_signature)}" %>
21
+ <% end %>
22
+
23
+ include /etc/monit/conf.d/*.conf
@@ -0,0 +1,12 @@
1
+ #!/bin/sh
2
+ # Finish/quit services for <%= fetch(:application) %> as <%= fetch(:user) %> in env <%= environment %>
3
+ #
4
+ # Announce termination
5
+ #
6
+ echo "Stopping all services for <%= fetch(:application) %> running as <%= fetch(:user) %>"
7
+
8
+ # Force all services to stop
9
+ sv -w600 force-stop <%= fetch(:runit_dir) %>/*
10
+
11
+ # "Exit" all services
12
+ sv exit <%= fetch(:runit_dir) %>/*
@@ -0,0 +1,12 @@
1
+ #!/bin/sh
2
+ #
3
+ # Log output for <%= fetch(:application) %> as <%= fetch(:user) %> in environment <%= environment %>
4
+ #
5
+ # make sure the log directory exists
6
+ mkdir -p "<%= runit_var_log_service_runit_path %>"
7
+ # make sure the right owner is on the log directory
8
+ chown -R <%= "#{fetch(:user)}:#{fetch(:runit_log_group)}" %> "<%= runit_var_log_service_runit_path %>"
9
+ # change path to the log directory
10
+ cd "<%= runit_var_log_service_runit_path %>"
11
+ # start logging
12
+ exec chpst -u <%= fetch(:runit_log_user)%> svlogd -tt "<%= runit_var_log_service_runit_path %>"
@@ -0,0 +1,14 @@
1
+ #!/bin/sh -e
2
+ #
3
+ # Run services for <%= fetch(:application) %> as <%= fetch(:user) %> in env <%= environment %>
4
+ #
5
+
6
+ # Redirect stderr so everything ends up in the log file
7
+ exec 2>&1
8
+
9
+ # Announce startup
10
+ #
11
+ echo "Starting all services for <%= fetch(:application) %> running as <%= fetch(:user) %>"
12
+
13
+ # Start all services in folder <%= fetch(:runit_dir) %>
14
+ exec chpst -u <%= fetch(:user) %> runsvdir "<%= fetch(:runit_dir) %>"
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-monit_runit
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Leif Ringstad
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: jeweler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ description: Helpers for capistrano recipes using runit/monit.
56
+ email: leifcr@gmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files:
60
+ - LICENSE
61
+ - README.md
62
+ files:
63
+ - Gemfile
64
+ - Gemfile.lock
65
+ - LICENSE
66
+ - README.md
67
+ - Rakefile
68
+ - VERSION
69
+ - capistrano-monit_runit.gemspec
70
+ - lib/capistrano/capistrano-monit_runit.rb
71
+ - lib/capistrano/dsl/base_paths.rb
72
+ - lib/capistrano/dsl/monit_paths.rb
73
+ - lib/capistrano/dsl/runit_paths.rb
74
+ - lib/capistrano/helpers/base.rb
75
+ - lib/capistrano/helpers/monit.rb
76
+ - lib/capistrano/helpers/runit.rb
77
+ - lib/capistrano/monit.rb
78
+ - lib/capistrano/runit.rb
79
+ - lib/capistrano/tasks/base.rake
80
+ - lib/capistrano/tasks/monit.rake
81
+ - lib/capistrano/tasks/runit.rake
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-monit_runit
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.4.6
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: Helpers for capistrano recipes using runit/monit
111
+ test_files: []