capistrano-monit_runit 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +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: []
|