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 +7 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +67 -0
- data/LICENSE +20 -0
- data/README.md +133 -0
- data/Rakefile +39 -0
- data/VERSION +1 -0
- data/capistrano-monit_runit.gemspec +70 -0
- data/lib/capistrano/capistrano-monit_runit.rb +0 -0
- data/lib/capistrano/dsl/base_paths.rb +18 -0
- data/lib/capistrano/dsl/monit_paths.rb +29 -0
- data/lib/capistrano/dsl/runit_paths.rb +117 -0
- data/lib/capistrano/helpers/base.rb +60 -0
- data/lib/capistrano/helpers/monit.rb +47 -0
- data/lib/capistrano/helpers/runit.rb +79 -0
- data/lib/capistrano/monit.rb +12 -0
- data/lib/capistrano/runit.rb +12 -0
- data/lib/capistrano/tasks/base.rake +6 -0
- data/lib/capistrano/tasks/monit.rake +223 -0
- data/lib/capistrano/tasks/runit.rake +172 -0
- data/templates/monit/app_include.conf.erb +1 -0
- data/templates/monit/monitrc.erb +23 -0
- data/templates/runit/finish.erb +12 -0
- data/templates/runit/log_run.erb +12 -0
- data/templates/runit/run.erb +14 -0
- metadata +111 -0
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
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,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: []
|