poise-service 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.kitchen.yml +1 -1
- data/CHANGELOG.md +8 -1
- data/README.md +1 -0
- data/chef/templates/default/dummy.json.erb +7 -0
- data/chef/templates/default/sysvinit.sh.erb +31 -24
- data/chef/templates/default/upstart.conf.erb +1 -1
- data/lib/poise_service/resources/poise_service_test.rb +14 -0
- data/lib/poise_service/service_providers/dummy.rb +35 -4
- data/lib/poise_service/service_providers/systemd.rb +21 -1
- data/lib/poise_service/service_providers/upstart.rb +11 -0
- data/lib/poise_service/version.rb +1 -1
- data/test/cookbooks/poise-service_test/recipes/default.rb +7 -3
- data/test/spec/service_providers/sysvinit_spec.rb +7 -4
- data/test/spec/service_providers/upstart_spec.rb +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9083e6c7faa81f26cb75ba512932747ca7d78505
|
4
|
+
data.tar.gz: 1cf6379abe8c39cafb38b7d7b5812db1fa24c9d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 475915c90a841a1f8ebadfbf48074440dc2b202a0902c8b50cd362bf2dd523feec27f60d010d9fdc46d6b60079343b53b4d56aa3f96243c1d4c7806c644f370e
|
7
|
+
data.tar.gz: 8ee09393fc20251559c2c275e7bc7cb56b12dc0d091e85ec66c7f6983f263c9a4490a9c888a1b856dfe7b56e54247846f85565d7ef0d23bd47a6afbd88ce2995
|
data/.kitchen.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
|
-
# Changelog
|
1
|
+
# Poise-Service Changelog
|
2
|
+
|
3
|
+
## v1.0.3
|
4
|
+
|
5
|
+
* [#10](https://github.com/poise/poise-service/pull/10) Fixes for ensuring services are restarted when their command or user changes.
|
6
|
+
* [#11](https://github.com/poise/poise-service/pull/11) Revamp the `sysvinit` provider for non-Debian platforms to be more stable.
|
7
|
+
* [#12](https://github.com/poise/poise-service/pull/12) Improve the `dummy` provider to handle dropping privs correctly.
|
2
8
|
|
3
9
|
## v1.0.2
|
10
|
+
|
4
11
|
* Fix a potential infinite loop when starting a service with the dummy provider.
|
5
12
|
* [#2](https://github.com/poise/poise-service/pull/2) Remove usage of root
|
6
13
|
default files so uploading with Berkshelf works (for now).
|
data/README.md
CHANGED
@@ -315,6 +315,7 @@ end
|
|
315
315
|
* `user` – Override the service user.
|
316
316
|
* `never_restart` – Never try to restart the service.
|
317
317
|
* `never_reload` – Never try to reload the service.
|
318
|
+
* `auto_reload` – Run `systemctl daemon-reload` after changes to the unit file. *(default: true)*
|
318
319
|
|
319
320
|
## ServiceMixin
|
320
321
|
|
@@ -11,10 +11,6 @@
|
|
11
11
|
# Description: Init script for <%= @name %>
|
12
12
|
### END INIT INFO
|
13
13
|
|
14
|
-
<%- @environment.each do |key, val| -%>
|
15
|
-
export <%= key %>="<%= val %>"
|
16
|
-
<%- end -%>
|
17
|
-
|
18
14
|
<%- if @platform_family == 'debian' -%>
|
19
15
|
. /lib/lsb/init-functions
|
20
16
|
|
@@ -37,32 +33,42 @@ _reload() {
|
|
37
33
|
start-stop-daemon --stop --quiet --pidfile "<%= @pid_file %>" --user "<%= @user %>" --signal "<%= @reload_signal %>"
|
38
34
|
}
|
39
35
|
|
40
|
-
<%-
|
41
|
-
. /etc/rc.d/init.d/functions
|
42
|
-
|
43
|
-
_pid () {
|
44
|
-
pidof -s -o $$ -o $PPID -o %PPID -x "$1" || pidof -s -o $$ -o $PPID -o %PPID -x "${1##*/}"
|
45
|
-
}
|
46
|
-
|
36
|
+
<%- else -%>
|
47
37
|
_start() {
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
38
|
+
<%# Implementing this using RedHat's bash helpers is too painful. Sorry. %>
|
39
|
+
<%# See dummy.rb for a more commented version of this code. %>
|
40
|
+
/opt/chef/embedded/bin/ruby <<EOH
|
41
|
+
pid_file = <%= @pid_file.inspect %>
|
42
|
+
File.unlink(pid_file) if File.exist?(pid_file)
|
43
|
+
if Process.fork
|
44
|
+
sleep(1) until File.exist?(pid_file)
|
45
|
+
else
|
46
|
+
Process.daemon(true)
|
47
|
+
Dir.chdir(<%= @directory.inspect %>)
|
48
|
+
<%- unless @pid_file_external -%>
|
49
|
+
IO.write(pid_file, Process.pid)
|
50
|
+
<%- end -%>
|
51
|
+
Process::UID.change_privilege(<%= @user.inspect %>)
|
52
|
+
Kernel.exec(*<%= Shellwords.split(@command).inspect %>)
|
53
|
+
exit!
|
54
|
+
end
|
55
|
+
EOH
|
54
56
|
}
|
55
57
|
|
56
58
|
_stop() {
|
57
59
|
if [ -r "<%= @pid_file %>" ]; then
|
58
60
|
kill -<%= @stop_signal%> "$(cat "<%= @pid_file %>")"
|
59
61
|
else
|
60
|
-
|
62
|
+
return 0
|
61
63
|
fi
|
62
64
|
}
|
63
65
|
|
64
66
|
_status() {
|
65
|
-
|
67
|
+
if [ -r "<%= @pid_file %>" ]; then
|
68
|
+
kill -0 "$(cat "<%= @pid_file %>")"
|
69
|
+
else
|
70
|
+
return 1
|
71
|
+
fi
|
66
72
|
}
|
67
73
|
|
68
74
|
_reload() {
|
@@ -73,7 +79,7 @@ _reload() {
|
|
73
79
|
fi
|
74
80
|
}
|
75
81
|
|
76
|
-
|
82
|
+
<%# Some functions to match LSB %>
|
77
83
|
|
78
84
|
log_daemon_msg() {
|
79
85
|
echo -n "$1"
|
@@ -93,13 +99,11 @@ log_failure_msg() {
|
|
93
99
|
|
94
100
|
log_end_msg() {
|
95
101
|
if [ "$1" = 0 ]; then
|
96
|
-
|
102
|
+
echo " [ OK ]"
|
97
103
|
else
|
98
|
-
|
104
|
+
echo " [FAILED]"
|
99
105
|
fi
|
100
106
|
}
|
101
|
-
<%- else -%>
|
102
|
-
<%- raise "Platform family #{@platform_family} is not supported" -%>
|
103
107
|
<%- end -%>
|
104
108
|
|
105
109
|
set -e
|
@@ -124,6 +128,9 @@ start() {
|
|
124
128
|
fi
|
125
129
|
}
|
126
130
|
|
131
|
+
<%- @environment.each do |key, val| -%>
|
132
|
+
export <%= key %>="<%= val %>"
|
133
|
+
<%- end -%>
|
127
134
|
export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
|
128
135
|
|
129
136
|
case "$1" in
|
@@ -25,7 +25,7 @@ reload signal <%= @reload_signal %>
|
|
25
25
|
<%- if @upstart_features[:setuid] -%>
|
26
26
|
exec <%= @command %>
|
27
27
|
<%- else -%>
|
28
|
-
exec /opt/chef/embedded/bin/ruby -e 'Process.
|
28
|
+
exec /opt/chef/embedded/bin/ruby -e 'Process::UID.change_privilege("<%= @user %>"); ENV["HOME"] = Dir.home("<%= @user %>") rescue nil; exec(*<%= Shellwords.split(@command).inspect %>)'
|
29
29
|
<%- end -%>
|
30
30
|
<%- if !@upstart_features[:kill_signal] && @stop_signal != 'TERM' -%>
|
31
31
|
pre-stop script
|
@@ -187,12 +187,26 @@ EOH
|
|
187
187
|
end
|
188
188
|
end
|
189
189
|
|
190
|
+
# Test the #pid accessor.
|
190
191
|
ruby_block "/tmp/poise_test_#{new_resource.name}_pid" do
|
191
192
|
block do
|
192
193
|
pid = resources("poise_service[poise_test_#{new_resource.name}]").pid
|
193
194
|
IO.write("/tmp/poise_test_#{new_resource.name}_pid", pid.to_s)
|
194
195
|
end
|
195
196
|
end
|
197
|
+
|
198
|
+
# Test changing the service definition itself.
|
199
|
+
poise_service "poise_test_#{new_resource.name}_change" do
|
200
|
+
provider new_resource.service_provider if new_resource.service_provider
|
201
|
+
command "/usr/bin/poise_test #{new_resource.base_port + 5}"
|
202
|
+
end
|
203
|
+
|
204
|
+
poise_service "poise_test_#{new_resource.name}_change_second" do
|
205
|
+
service_name "poise_test_#{new_resource.name}_change"
|
206
|
+
provider new_resource.service_provider if new_resource.service_provider
|
207
|
+
command "/usr/bin/poise_test #{new_resource.base_port + 6}"
|
208
|
+
end
|
209
|
+
|
196
210
|
end
|
197
211
|
end
|
198
212
|
end
|
@@ -14,6 +14,8 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
|
17
|
+
require 'shellwords'
|
18
|
+
|
17
19
|
require 'poise_service/service_providers/base'
|
18
20
|
|
19
21
|
|
@@ -29,9 +31,16 @@ module PoiseService
|
|
29
31
|
::File.unlink(pid_file) if ::File.exist?(pid_file)
|
30
32
|
if Process.fork
|
31
33
|
# Parent, wait for the final child to write the pid file.
|
34
|
+
now = Time.now
|
32
35
|
until ::File.exist?(pid_file)
|
33
36
|
sleep(1)
|
34
|
-
|
37
|
+
# After 30 seconds, show output at a higher level to avoid too much
|
38
|
+
# confusing on failed process launches.
|
39
|
+
if Time.now - now <= 30
|
40
|
+
Chef::Log.debug("[#{new_resource}] Waiting for PID file")
|
41
|
+
else
|
42
|
+
Chef::Log.warning("[#{new_resource}] Waiting for PID file at #{pid_file} to be created")
|
43
|
+
end
|
35
44
|
end
|
36
45
|
else
|
37
46
|
# :nocov:
|
@@ -42,14 +51,17 @@ module PoiseService
|
|
42
51
|
# Daemonized, set up process environment.
|
43
52
|
Dir.chdir(new_resource.directory)
|
44
53
|
Chef::Log.debug("[#{new_resource}] Directory changed to #{new_resource.directory}")
|
54
|
+
ENV['HOME'] = Dir.home(new_resource.user)
|
45
55
|
new_resource.environment.each do |key, val|
|
46
56
|
ENV[key.to_s] = val.to_s
|
47
57
|
end
|
48
|
-
Process.uid = new_resource.user
|
49
58
|
Chef::Log.debug("[#{new_resource}] Process environment configured")
|
50
59
|
IO.write(pid_file, Process.pid)
|
51
|
-
Chef::Log.debug("[#{new_resource}] PID written to #{pid_file}, execing
|
52
|
-
|
60
|
+
Chef::Log.debug("[#{new_resource}] PID written to #{pid_file}, dropping privs and execing")
|
61
|
+
Process::UID.change_privilege(new_resource.user)
|
62
|
+
# Split the command so we don't get an extra sh -c.
|
63
|
+
Chef::Log.debug("[#{new_resource}] Execing #{new_resource.command}")
|
64
|
+
Kernel.exec(*Shellwords.split(new_resource.command))
|
53
65
|
# Just in case, bail out.
|
54
66
|
exit!
|
55
67
|
# :nocov:
|
@@ -94,15 +106,34 @@ module PoiseService
|
|
94
106
|
def enable_service
|
95
107
|
end
|
96
108
|
|
109
|
+
# Write all major service parameters to a file so that if they change, we
|
110
|
+
# can restart the service. This also makes debuggin a bit easier so you
|
111
|
+
# can still see what it thinks it was starting without sifting through
|
112
|
+
# piles of debug output.
|
97
113
|
def create_service
|
114
|
+
service_template(run_file, 'dummy.json.erb')
|
98
115
|
end
|
99
116
|
|
100
117
|
def disable_service
|
101
118
|
end
|
102
119
|
|
120
|
+
# Delete the tracking file.
|
103
121
|
def destroy_service
|
122
|
+
file run_file do
|
123
|
+
action :delete
|
124
|
+
end
|
125
|
+
|
126
|
+
file pid_file do
|
127
|
+
action :delete
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Path to the run parameters tracking file.
|
132
|
+
def run_file
|
133
|
+
"/var/run/#{new_resource.service_name}.json"
|
104
134
|
end
|
105
135
|
|
136
|
+
# Path to the PID file.
|
106
137
|
def pid_file
|
107
138
|
"/var/run/#{new_resource.service_name}.pid"
|
108
139
|
end
|
@@ -25,12 +25,21 @@ module PoiseService
|
|
25
25
|
include Chef::Mixin::ShellOut
|
26
26
|
provides(:systemd)
|
27
27
|
|
28
|
+
# @api private
|
28
29
|
def self.provides_auto?(node, resource)
|
29
30
|
# Don't allow systemd under docker, it won't work in most cases.
|
30
31
|
return false if node['virtualization'] && %w{docker lxc}.include?(node['virtualization']['system'])
|
31
32
|
service_resource_hints.include?(:systemd)
|
32
33
|
end
|
33
34
|
|
35
|
+
# @api private
|
36
|
+
def self.default_inversion_options(node, resource)
|
37
|
+
super.merge({
|
38
|
+
# Automatically reload systemd on changes.
|
39
|
+
auto_reload: true,
|
40
|
+
})
|
41
|
+
end
|
42
|
+
|
34
43
|
def pid
|
35
44
|
cmd = shell_out(%w{systemctl status} + [new_resource.service_name])
|
36
45
|
if !cmd.error? && cmd.stdout.include?('Active: active (running)') && md = cmd.stdout.match(/Main PID: (\d+)/)
|
@@ -48,8 +57,19 @@ module PoiseService
|
|
48
57
|
end
|
49
58
|
end
|
50
59
|
|
60
|
+
def systemctl_daemon_reload
|
61
|
+
execute 'systemctl daemon-reload' do
|
62
|
+
action :nothing
|
63
|
+
user 'root'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
51
67
|
def create_service
|
52
|
-
|
68
|
+
reloader = systemctl_daemon_reload
|
69
|
+
service_template("/etc/systemd/system/#{new_resource.service_name}.service", 'systemd.service.erb') do
|
70
|
+
notifies :run, reloader, :immediately if options['auto_reload']
|
71
|
+
variables.update(auto_reload: options['auto_reload'])
|
72
|
+
end
|
53
73
|
end
|
54
74
|
|
55
75
|
def destroy_service
|
@@ -35,6 +35,17 @@ module PoiseService
|
|
35
35
|
service_resource_hints.include?(:upstart)
|
36
36
|
end
|
37
37
|
|
38
|
+
# True restart in Upstart preserves the original config data, we want the
|
39
|
+
# more obvious behavior like everything else in the world that restart
|
40
|
+
# would re-read the updated config file. Use stop+start to get this
|
41
|
+
# behavior. http://manpages.ubuntu.com/manpages/raring/man8/initctl.8.html
|
42
|
+
def action_restart
|
43
|
+
return if options['never_restart']
|
44
|
+
action_stop
|
45
|
+
action_start
|
46
|
+
end
|
47
|
+
|
48
|
+
# Shim out reload if we have a version that predates reload support.
|
38
49
|
def action_reload
|
39
50
|
return if options['never_reload']
|
40
51
|
if !upstart_features[:reload_signal] && new_resource.reload_signal != 'HUP'
|
@@ -37,9 +37,13 @@ else
|
|
37
37
|
base_port 6000
|
38
38
|
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
if node['platform_family'] == 'rhel' && node['platform_version'].start_with?('5')
|
41
|
+
file '/no_upstart'
|
42
|
+
else
|
43
|
+
poise_service_test 'upstart' do
|
44
|
+
service_provider :upstart
|
45
|
+
base_port 7000
|
46
|
+
end
|
43
47
|
end
|
44
48
|
end
|
45
49
|
|
@@ -54,9 +54,10 @@ EOH
|
|
54
54
|
let(:chefspec_options) { { platform: 'centos', version: '7.0'} }
|
55
55
|
|
56
56
|
it { is_expected.to render_file('/etc/init.d/test').with_content(<<-EOH) }
|
57
|
-
(
|
58
|
-
|
59
|
-
|
57
|
+
Dir.chdir("/")
|
58
|
+
IO.write(pid_file, Process.pid)
|
59
|
+
Process::UID.change_privilege("root")
|
60
|
+
Kernel.exec(*["myapp", "--serve"])
|
60
61
|
EOH
|
61
62
|
|
62
63
|
context 'with an external PID file' do
|
@@ -66,7 +67,9 @@ EOH
|
|
66
67
|
end
|
67
68
|
|
68
69
|
it { is_expected.to render_file('/etc/init.d/test').with_content(<<-EOH) }
|
69
|
-
(
|
70
|
+
Dir.chdir("/")
|
71
|
+
Process::UID.change_privilege("root")
|
72
|
+
Kernel.exec(*["myapp", "--serve"])
|
70
73
|
EOH
|
71
74
|
end # /context with an external PID file
|
72
75
|
end # /context on CentOS
|
@@ -45,7 +45,7 @@ respawn limit 10 5
|
|
45
45
|
umask 022
|
46
46
|
chdir /
|
47
47
|
|
48
|
-
exec /opt/chef/embedded/bin/ruby -e 'Process.
|
48
|
+
exec /opt/chef/embedded/bin/ruby -e 'Process::UID.change_privilege("root"); ENV["HOME"] = Dir.home("root") rescue nil; exec(*["myapp", "--serve"])'
|
49
49
|
EOH
|
50
50
|
|
51
51
|
context 'with a stop signal' do
|
@@ -69,7 +69,7 @@ respawn limit 10 5
|
|
69
69
|
umask 022
|
70
70
|
chdir /
|
71
71
|
|
72
|
-
exec /opt/chef/embedded/bin/ruby -e 'Process.
|
72
|
+
exec /opt/chef/embedded/bin/ruby -e 'Process::UID.change_privilege("root"); ENV["HOME"] = Dir.home("root") rescue nil; exec(*["myapp", "--serve"])'
|
73
73
|
pre-stop script
|
74
74
|
PID=`initctl status test | sed 's/^.*process \\([0-9]*\\)$/\\1/'`
|
75
75
|
if [ -n "$PID" ]; then
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poise-service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Noah Kantrowitz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: halite
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- README.md
|
86
86
|
- Rakefile
|
87
87
|
- chef/attributes/default.rb
|
88
|
+
- chef/templates/default/dummy.json.erb
|
88
89
|
- chef/templates/default/systemd.service.erb
|
89
90
|
- chef/templates/default/sysvinit.sh.erb
|
90
91
|
- chef/templates/default/upstart.conf.erb
|