capistrano-monit_runit 3.0.0

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.
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: []