pleaserun 0.0.24 → 0.0.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -3
- data/README.md +11 -0
- data/lib/pleaserun/cli.rb +6 -5
- data/lib/pleaserun/configurable.rb +3 -2
- data/lib/pleaserun/platform/base.rb +71 -14
- data/lib/pleaserun/platform/systemd-user.rb +15 -7
- data/lib/pleaserun/platform/systemd.rb +1 -0
- data/lib/pleaserun/platform/upstart.rb +1 -0
- data/pleaserun.gemspec +6 -2
- data/spec/pleaserun/platform/base_spec.rb +87 -10
- data/spec/pleaserun/platform/sysv_spec.rb +2 -1
- data/spec/pleaserun/user/base_spec.rb +1 -1
- data/templates/launchd/default/program.plist +9 -2
- data/templates/runit/log +1 -1
- data/templates/runit/run +2 -1
- data/templates/systemd-user/default/program.service +1 -0
- data/templates/systemd/default/default +3 -0
- data/templates/systemd/default/program.service +6 -3
- data/templates/sysv/default/default +3 -19
- data/templates/sysv/default/init.sh +27 -10
- data/templates/upstart/0.6.5/default +3 -0
- data/templates/upstart/0.6.5/init.conf +10 -5
- data/templates/upstart/default/default +3 -0
- data/templates/upstart/default/init.conf +5 -2
- metadata +22 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 069a73c404991697c3c33c062fadb72a8c3c4478
|
4
|
+
data.tar.gz: fa15c05f36673959b42cc7a4f3201be9644dac54
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b421de562aa82af6f4e5b611664ded71cab2b3f8ce200d0da6113d9ccdb6b3d72c72edff7b203f9cbea3fd77690d58ea0f88aa32186e49f331d3c4fae334859
|
7
|
+
data.tar.gz: e9e1c9123108d24565d568f0799685602ab7545f630b2b2bbfe64570304fec8836f42936953868a76f5af0723c94deada495513a620ee781badf3cb0ee49175d
|
data/Gemfile.lock
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
pleaserun (0.0.
|
4
|
+
pleaserun (0.0.24)
|
5
5
|
cabin (> 0)
|
6
6
|
clamp
|
7
|
+
dotenv
|
7
8
|
insist
|
8
|
-
mustache (= 0.
|
9
|
+
mustache (= 1.0.3)
|
9
10
|
stud
|
10
11
|
|
11
12
|
GEM
|
@@ -17,6 +18,7 @@ GEM
|
|
17
18
|
clamp (1.0.0)
|
18
19
|
coderay (1.1.0)
|
19
20
|
diff-lcs (1.2.5)
|
21
|
+
dotenv (2.1.1)
|
20
22
|
ffi (1.9.6)
|
21
23
|
ffi (1.9.6-java)
|
22
24
|
ffi-yajl (2.1.0)
|
@@ -56,7 +58,7 @@ GEM
|
|
56
58
|
mixlib-config (2.1.0)
|
57
59
|
mixlib-log (1.6.0)
|
58
60
|
mixlib-shellout (2.0.1)
|
59
|
-
mustache (0.
|
61
|
+
mustache (1.0.3)
|
60
62
|
nenv (0.2.0)
|
61
63
|
net-ssh (2.9.2)
|
62
64
|
notiffany (0.0.6)
|
data/README.md
CHANGED
@@ -133,6 +133,17 @@ A silly example:
|
|
133
133
|
UID PID PPID C STIME TTY TIME CMD
|
134
134
|
root 50473 1 0 22:36 pts/7 00:00:00 /bin/sleep 60
|
135
135
|
|
136
|
+
# Hacking
|
137
|
+
|
138
|
+
If you want to work on pleaserun, here's what you need to do:
|
139
|
+
|
140
|
+
1. Get a decent version of Ruby. [rvm](https://rvm.io/) is good for this.
|
141
|
+
2. Install bundler: `gem install bundler`
|
142
|
+
3. Install dependencies: `bundle install`
|
143
|
+
4. Make your changes!
|
144
|
+
5. Run tests: `bundle exec rspec`
|
145
|
+
6. Make a pull request!
|
146
|
+
|
136
147
|
# One last thing!
|
137
148
|
|
138
149
|
Please enjoy running things! If you are not enjoying this program, then something is wrong, and we can fix it together :)
|
data/lib/pleaserun/cli.rb
CHANGED
@@ -44,9 +44,10 @@ class PleaseRun::CLI < Clamp::Command # rubocop:disable ClassLength
|
|
44
44
|
|
45
45
|
# Turn the attribute name into a flag.
|
46
46
|
option "--#{facet.name.to_s.gsub("_", "-")}", facet.name.to_s.upcase, facet.description,
|
47
|
-
:attribute_name => facet.name
|
47
|
+
:attribute_name => facet.name,
|
48
|
+
:multivalued => facet.options.fetch(:multivalued, false)
|
48
49
|
end
|
49
|
-
|
50
|
+
|
50
51
|
# Load the 'program' attribute from the Base class and use it as the first
|
51
52
|
# cli parameter.
|
52
53
|
program = base.attributes.find { |f| f.name == :program }
|
@@ -73,11 +74,11 @@ For example, let's run elasticsearch:
|
|
73
74
|
The above will automatically detect what platform you are running on
|
74
75
|
and try to use the most sensible init system. For Ubuntu, this means
|
75
76
|
Upstart. For Debian, this means sysv init scripts. For Fedora, this
|
76
|
-
means systemd.
|
77
|
+
means systemd.
|
77
78
|
|
78
79
|
You can tune the running environment and settings for your runner with various
|
79
80
|
flags. By way of example, let's make our elasticsearch service run as the
|
80
|
-
'elasticsearch' user!
|
81
|
+
'elasticsearch' user!
|
81
82
|
|
82
83
|
% pleaserun --user elasticsearch /opt/elasticsearch/bin/elasticsearch
|
83
84
|
|
@@ -196,7 +197,7 @@ are made. If it fails, nagios will not start. Yay!
|
|
196
197
|
if log
|
197
198
|
logfile = File.new(log, "a")
|
198
199
|
@logger.subscribe(logfile)
|
199
|
-
STDERR.puts "Sending all logs to #{log}" if STDERR.tty?
|
200
|
+
#STDERR.puts "Sending all logs to #{log}" if STDERR.tty?
|
200
201
|
else
|
201
202
|
@logger.subscribe(STDERR)
|
202
203
|
end
|
@@ -94,7 +94,7 @@ module PleaseRun::Configurable
|
|
94
94
|
end # def ClassMixin
|
95
95
|
|
96
96
|
# A DSL for describing a facet.
|
97
|
-
#
|
97
|
+
#
|
98
98
|
# For example:
|
99
99
|
#
|
100
100
|
# Facet.new(:temperature, "The temperature value") do
|
@@ -142,13 +142,14 @@ module PleaseRun::Configurable
|
|
142
142
|
class Facet
|
143
143
|
attr_reader :name
|
144
144
|
attr_reader :description
|
145
|
+
attr_reader :options
|
145
146
|
attr_writer :validator, :munger
|
146
147
|
|
147
148
|
def initialize(name, description, options = {}, &facet_dsl)
|
148
149
|
insist { name }.is_a?(Symbol)
|
149
150
|
insist { description }.is_a?(String)
|
150
151
|
insist { options }.is_a?(Hash)
|
151
|
-
|
152
|
+
|
152
153
|
@name = name
|
153
154
|
@description = description
|
154
155
|
@options = options
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require "dotenv/parser"
|
1
2
|
require "pleaserun/namespace"
|
2
3
|
require "pleaserun/configurable"
|
3
4
|
require "pleaserun/mustache_methods"
|
@@ -27,7 +28,7 @@ class PleaseRun::Platform::Base
|
|
27
28
|
attribute :program, "The program to execute. This can be a full path, like " \
|
28
29
|
"/usr/bin/cat, or a shorter name like 'cat' if you wish to search $PATH." do
|
29
30
|
validate do |program|
|
30
|
-
insist { program.is_a?(String) }
|
31
|
+
insist { program.is_a?(String) }
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
@@ -57,7 +58,7 @@ class PleaseRun::Platform::Base
|
|
57
58
|
insist { version.is_a?(String) }
|
58
59
|
end
|
59
60
|
end
|
60
|
-
|
61
|
+
|
61
62
|
attribute :description, "The human-readable description of your program",
|
62
63
|
:default => "no description given" do
|
63
64
|
validate do |description|
|
@@ -85,6 +86,27 @@ class PleaseRun::Platform::Base
|
|
85
86
|
end
|
86
87
|
end
|
87
88
|
|
89
|
+
attribute :environment_file, "A file containing environment variables to export for your application" do
|
90
|
+
validate do |env|
|
91
|
+
insist { env }.is_a?(File)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
attribute :environment_variables, "Env key/value pairs to insert into your sourced_env_file", :multivalued => true do
|
96
|
+
munge do |environment_variables|
|
97
|
+
if environment_variables.is_a?(String)
|
98
|
+
environment_variables = [environment_variables]
|
99
|
+
end
|
100
|
+
if environment_variables.is_a?(Array)
|
101
|
+
environment_variables = Hash[environment_variables.map { |e| e.split('=', 2) }]
|
102
|
+
end
|
103
|
+
environment_variables
|
104
|
+
end
|
105
|
+
validate do |environment_variables|
|
106
|
+
insist { environment_variables }.is_a?(Hash)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
88
110
|
attribute :nice, "The nice level to add to this program before running" do
|
89
111
|
validate do |nice|
|
90
112
|
insist { nice }.is_a?(Fixnum)
|
@@ -130,10 +152,14 @@ class PleaseRun::Platform::Base
|
|
130
152
|
validate { |v| v == "ulimited" || v.to_i > 0 }
|
131
153
|
end
|
132
154
|
|
133
|
-
|
134
|
-
|
135
|
-
:default => "/var/log/"
|
155
|
+
attribute :log_directory, "The destination for log output",
|
156
|
+
:default => "/var/log"
|
136
157
|
|
158
|
+
attribute :log_file_stderr, "Name of log file for stderr. Will default to NAME-stderr.log",
|
159
|
+
:default => nil
|
160
|
+
|
161
|
+
attribute :log_file_stdout, "Name of log file for stdout. Will default to NAME-stderr.log",
|
162
|
+
:default => nil
|
137
163
|
|
138
164
|
attribute :prestart, "A command to execute before starting and restarting. A failure of this command will cause the start/restart to abort. This is useful for health checks, config tests, or similar operations."
|
139
165
|
|
@@ -154,7 +180,7 @@ class PleaseRun::Platform::Base
|
|
154
180
|
end # def template_path
|
155
181
|
|
156
182
|
def render_template(name)
|
157
|
-
possibilities = [
|
183
|
+
possibilities = [
|
158
184
|
File.join(template_path, target_version, name),
|
159
185
|
File.join(template_path, "default", name),
|
160
186
|
File.join(template_path, name)
|
@@ -191,15 +217,46 @@ class PleaseRun::Platform::Base
|
|
191
217
|
return []
|
192
218
|
end # def install_actions
|
193
219
|
|
194
|
-
def
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
220
|
+
def log_path
|
221
|
+
File.join(log_directory.chomp("/"), name)
|
222
|
+
end
|
223
|
+
|
224
|
+
def log_path_stderr
|
225
|
+
filename = "#{name}-stderr.log"
|
226
|
+
filename = log_file_stderr unless log_file_stderr.nil?
|
227
|
+
File.join(log_directory.chomp("/"), filename)
|
228
|
+
end
|
229
|
+
|
230
|
+
def log_path_stdout
|
231
|
+
filename = "#{name}-stdout.log"
|
232
|
+
filename = log_file_stdout unless log_file_stdout.nil?
|
233
|
+
File.join(log_directory.chomp("/"), filename)
|
234
|
+
end
|
235
|
+
|
236
|
+
def parsed_environment_variables
|
237
|
+
return {} if environment_file.nil?
|
238
|
+
return {} unless File.exist?(environment_file)
|
239
|
+
Dotenv::Parser.call(File.open(environment_file, "rb:bom|utf-8", &:read))
|
240
|
+
end
|
241
|
+
|
242
|
+
def all_environment_variables
|
243
|
+
parsed_env_vars = {}
|
244
|
+
parsed_env_vars = parsed_environment_variables unless parsed_environment_variables.nil?
|
245
|
+
flag_env_vars = {}
|
246
|
+
flag_env_vars = environment_variables unless environment_variables.nil?
|
247
|
+
|
248
|
+
variables = parsed_env_vars.merge(flag_env_vars)
|
249
|
+
return nil if variables.empty?
|
250
|
+
result = []
|
251
|
+
variables.each {|k, v| result << {'key' => k, 'value' => v} }
|
252
|
+
result
|
253
|
+
end
|
254
|
+
|
255
|
+
def default_file
|
256
|
+
"/etc/default/#{name}"
|
200
257
|
end
|
201
258
|
|
202
|
-
def
|
203
|
-
|
259
|
+
def sysconfig_file
|
260
|
+
"/etc/sysconfig/#{name}"
|
204
261
|
end
|
205
262
|
end # class PleaseRun::Base
|
@@ -3,6 +3,14 @@ require "pleaserun/platform/base"
|
|
3
3
|
|
4
4
|
# The platform implementation for systemd user services.
|
5
5
|
class PleaseRun::Platform::SystemdUser < PleaseRun::Platform::Base
|
6
|
+
def home
|
7
|
+
@home ||= ENV["HOME"]
|
8
|
+
if @home.nil? || @home.empty?
|
9
|
+
raise PleaseRun::Configurable::ValidationError, "As a normal user (not root), I need to know where your home directory is, but the HOME environment variable seems to be not set."
|
10
|
+
end
|
11
|
+
@home
|
12
|
+
end
|
13
|
+
|
6
14
|
def files
|
7
15
|
begin
|
8
16
|
# TODO(sissel): Make it easy for subclasses to extend validation on attributes.
|
@@ -11,21 +19,21 @@ class PleaseRun::Platform::SystemdUser < PleaseRun::Platform::Base
|
|
11
19
|
raise PleaseRun::Configurable::ValidationError, "In systemd, the program must be a full path. You gave '#{program}'."
|
12
20
|
end
|
13
21
|
|
14
|
-
home = ENV["HOME"]
|
15
|
-
if home.nil? || home.empty?
|
16
|
-
raise PleaseRun::Configurable::ValidationError, "As a normal user (not root), I need to know where your home directory is, but the HOME environment variable seems to be not set."
|
17
|
-
end
|
18
|
-
|
19
22
|
if !File.directory?(home)
|
20
23
|
raise PleaseRun::Configurable::ValidationError, "HOME (#{home}) is not a directory. Cannot continue."
|
21
24
|
end
|
22
25
|
|
23
26
|
return Enumerator::Generator.new do |enum|
|
24
|
-
enum.yield(safe_filename("
|
25
|
-
enum.yield(safe_filename("
|
27
|
+
enum.yield(safe_filename("{{{home}}}/.config/systemd/user/{{{ name }}}.environment"), environment_data)
|
28
|
+
enum.yield(safe_filename("{{{home}}}/.config/systemd/user/{{{ name }}}.service"), render_template("program.service"))
|
29
|
+
enum.yield(safe_filename("{{{home}}}/.config/systemd/user/{{{ name }}}-prestart.sh"), render_template("prestart.sh"), 0755) if prestart
|
26
30
|
end
|
27
31
|
end # def files
|
28
32
|
|
33
|
+
def environment_data
|
34
|
+
ENV.collect { |k,v| "#{k}=#{v}" }.join("\n")
|
35
|
+
end
|
36
|
+
|
29
37
|
def install_actions
|
30
38
|
return ["systemctl --user daemon-reload"]
|
31
39
|
end
|
@@ -21,6 +21,7 @@ class PleaseRun::Platform::Systemd < PleaseRun::Platform::Base
|
|
21
21
|
end
|
22
22
|
|
23
23
|
return Enumerator::Generator.new do |enum|
|
24
|
+
enum.yield(safe_filename("/etc/default/{{ name }}"), render_template("default"))
|
24
25
|
enum.yield(safe_filename("{{{ unit_path }}}/{{{ name }}}.service"), render_template("program.service"))
|
25
26
|
|
26
27
|
# TODO(sissel): This is probably not the best place to put this. Ahh well :)
|
@@ -7,6 +7,7 @@ class PleaseRun::Platform::Upstart < PleaseRun::Platform::Base
|
|
7
7
|
def files
|
8
8
|
return Enumerator::Generator.new do |out|
|
9
9
|
out.yield(safe_filename("/etc/init/{{ name }}.conf"), render_template("init.conf"))
|
10
|
+
out.yield(safe_filename("/etc/default/{{ name }}"), render_template("default"))
|
10
11
|
end
|
11
12
|
end
|
12
13
|
end
|
data/pleaserun.gemspec
CHANGED
@@ -2,7 +2,7 @@ Gem::Specification.new do |spec|
|
|
2
2
|
files = File.read(__FILE__)[/^__END__$.*/m].split("\n")[1..-1]
|
3
3
|
|
4
4
|
spec.name = "pleaserun"
|
5
|
-
spec.version = "0.0.
|
5
|
+
spec.version = "0.0.25"
|
6
6
|
spec.summary = "pleaserun"
|
7
7
|
spec.description = "pleaserun"
|
8
8
|
spec.license = "Apache 2.0"
|
@@ -10,8 +10,9 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.add_dependency "cabin", ">0" # for logging. apache 2 license
|
11
11
|
spec.add_dependency "clamp"
|
12
12
|
spec.add_dependency "stud"
|
13
|
-
spec.add_dependency "mustache", "0.
|
13
|
+
spec.add_dependency "mustache", "1.0.3"
|
14
14
|
spec.add_dependency "insist"
|
15
|
+
spec.add_dependency "dotenv"
|
15
16
|
#spec.add_dependency "ohai", "~> 6.20" # used for host detection
|
16
17
|
|
17
18
|
spec.files = files
|
@@ -70,12 +71,15 @@ templates/runit/log
|
|
70
71
|
templates/runit/run
|
71
72
|
templates/systemd-user/default/prestart.sh
|
72
73
|
templates/systemd-user/default/program.service
|
74
|
+
templates/systemd/default/default
|
73
75
|
templates/systemd/default/prestart.sh
|
74
76
|
templates/systemd/default/program.service
|
75
77
|
templates/sysv/default/default
|
76
78
|
templates/sysv/default/init.sh
|
79
|
+
templates/upstart/0.6.5/default
|
77
80
|
templates/upstart/0.6.5/init.conf
|
78
81
|
templates/upstart/0.6.5/init.d.sh
|
82
|
+
templates/upstart/default/default
|
79
83
|
templates/upstart/default/init.conf
|
80
84
|
templates/upstart/default/init.d.sh
|
81
85
|
templates/user/linux/default/installer.sh
|
@@ -25,28 +25,105 @@ describe PleaseRun::Platform::Base do
|
|
25
25
|
insist { subject.group } == "root"
|
26
26
|
end
|
27
27
|
|
28
|
-
|
28
|
+
it "#log_directory should be /var/log" do
|
29
|
+
insist { subject.log_directory } == "/var/log"
|
30
|
+
end
|
31
|
+
|
32
|
+
context "#log_path" do
|
29
33
|
let(:name) { "fancy" }
|
30
34
|
before { subject.name = name }
|
31
35
|
|
32
36
|
context "default" do
|
33
37
|
it "should be in /var/log" do
|
34
|
-
expect(subject.
|
38
|
+
expect(subject.log_path).to(be == "/var/log/#{name}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when given a directory without trailing slash" do
|
43
|
+
let(:path) { "/tmp" }
|
44
|
+
before { subject.log_directory = path }
|
45
|
+
it "should be <path>/<name>" do
|
46
|
+
expect(subject.log_path).to(be == File.join(path, name))
|
35
47
|
end
|
36
48
|
end
|
37
49
|
|
38
|
-
context "when given a directory" do
|
50
|
+
context "when given a directory with trailing slash" do
|
39
51
|
let(:path) { "/tmp/" }
|
40
|
-
before { subject.
|
52
|
+
before { subject.log_directory = path }
|
41
53
|
it "should be <path>/<name>" do
|
42
|
-
expect(subject.
|
54
|
+
expect(subject.log_path).to(be == File.join(path, name))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "#log_path_stderr" do
|
60
|
+
let(:name) { "fancy" }
|
61
|
+
before { subject.name = name }
|
62
|
+
|
63
|
+
context "default" do
|
64
|
+
it "should be in /var/log" do
|
65
|
+
expect(subject.log_path_stderr).to(be == "/var/log/#{name}-stderr.log")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when given a directory without trailing slash" do
|
70
|
+
let(:path) { "/tmp" }
|
71
|
+
before { subject.log_directory = path }
|
72
|
+
it "should be <path>/<name>-stderr.log" do
|
73
|
+
expect(subject.log_path_stderr).to(be == File.join(path, "#{name}-stderr.log"))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when given a directory with trailing slash" do
|
78
|
+
let(:path) { "/tmp/" }
|
79
|
+
before { subject.log_directory = path }
|
80
|
+
it "should be <path>/<name>-stderr.log" do
|
81
|
+
expect(subject.log_path_stderr).to(be == File.join(path, "#{name}-stderr.log"))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "when specified as an argument it should use the name" do
|
86
|
+
let(:path) { "/var/log" }
|
87
|
+
let(:log_file_stderr) { "#{name}-stderr" }
|
88
|
+
before { subject.log_file_stderr = log_file_stderr }
|
89
|
+
it "should be <path>/<name>-stderr" do
|
90
|
+
expect(subject.log_path_stderr).to(be == File.join(path, log_file_stderr))
|
43
91
|
end
|
44
92
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
93
|
+
end
|
94
|
+
|
95
|
+
context "#log_path_stdout" do
|
96
|
+
let(:name) { "fancy" }
|
97
|
+
before { subject.name = name }
|
98
|
+
|
99
|
+
context "default" do
|
100
|
+
it "should be in /var/log" do
|
101
|
+
expect(subject.log_path_stdout).to(be == "/var/log/#{name}-stdout.log")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when given a directory without trailing slash" do
|
106
|
+
let(:path) { "/tmp" }
|
107
|
+
before { subject.log_directory = path }
|
108
|
+
it "should be <path>/<name>-stdout.log" do
|
109
|
+
expect(subject.log_path_stdout).to(be == File.join(path, "#{name}-stdout.log"))
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "when given a directory with trailing slash" do
|
114
|
+
let(:path) { "/tmp/" }
|
115
|
+
before { subject.log_directory = path }
|
116
|
+
it "should be <path>/<name>-stdout.log" do
|
117
|
+
expect(subject.log_path_stdout).to(be == File.join(path, "#{name}-stdout.log"))
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "when specified as an argument it should use the name" do
|
122
|
+
let(:path) { "/var/log" }
|
123
|
+
let(:log_file_stdout) { "#{name}-stdout" }
|
124
|
+
before { subject.log_file_stdout = log_file_stdout }
|
125
|
+
it "should be <path>/<name>-stdout" do
|
126
|
+
expect(subject.log_path_stdout).to(be == File.join(path, log_file_stdout))
|
50
127
|
end
|
51
128
|
end
|
52
129
|
end
|
@@ -7,7 +7,8 @@ describe PleaseRun::Platform::SYSV do
|
|
7
7
|
let(:version) { PleaseRun::Detector.detect[1] }
|
8
8
|
|
9
9
|
context "deployment", :sysv => true do
|
10
|
-
etc_initd_writable = File.
|
10
|
+
etc_initd_writable = File.stat("/etc/init.d").writable? rescue false
|
11
|
+
p :WRIT => etc_initd_writable
|
11
12
|
if !etc_initd_writable
|
12
13
|
it "cannot write to /etc/init.d, so there's no deployment test to do. To run these tests, you'll need to run this as root, and preferrably in a vm or other temporary system"
|
13
14
|
else
|
@@ -10,8 +10,15 @@
|
|
10
10
|
{{{xml_args}}}
|
11
11
|
</array>
|
12
12
|
<key>KeepAlive</key> <true/>
|
13
|
-
<key>StandardOutPath</key> <string
|
14
|
-
<key>StandardErrorPath</key> <string
|
13
|
+
<key>StandardOutPath</key> <string>{{ log_path_stdout }}</string>
|
14
|
+
<key>StandardErrorPath</key> <string>{{ log_path_stderr }}</string>
|
15
|
+
<key>EnvironmentVariables</key>
|
16
|
+
<dict>
|
17
|
+
{{#all_environment_variables}}
|
18
|
+
<key>{{key}}</key>
|
19
|
+
<string>{{#shell_quote}}{{value}}{{/shell_quote}}</string>
|
20
|
+
{{/all_environment_variables}}
|
21
|
+
</dict>
|
15
22
|
<!-- Things to implement eventually.
|
16
23
|
<key>UserName</key><string>{{{ user }}}</string>
|
17
24
|
<key>GroupName</key><string>{{{ group }}}</string>
|
data/templates/runit/log
CHANGED
data/templates/runit/run
CHANGED
@@ -8,7 +8,8 @@ PROGRAM={{#quoted}}{{{PROGRAM}}}{{/quoted}}
|
|
8
8
|
set -- {{{shell_args}}}
|
9
9
|
|
10
10
|
{{#shell_continuation}}
|
11
|
-
exec
|
11
|
+
exec env {{#all_environment_variables}}{{key}}={{#shell_quote}}{{value}}{{/shell_quote}}{{/all_environment_variables}} \
|
12
|
+
chpst \
|
12
13
|
-u {{#quoted}}{{{user}}}:{{{group}}}{{/quoted}}
|
13
14
|
{{#chroot}} -/ {{#quoted}}{{{chroot}}}{{/quoted}} {{/chroot}}
|
14
15
|
{{#nice}} -n {{#quoted}}{{{nice}}}{{/quoted}} {{/nice}}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
{{#description}}
|
3
3
|
Description={{{ description }}}
|
4
4
|
{{/description}}
|
5
|
-
|
5
|
+
|
6
6
|
[Service]
|
7
7
|
Type=simple
|
8
8
|
User={{{ user }}}
|
@@ -10,14 +10,17 @@ Group={{{ group }}}
|
|
10
10
|
# Load env vars from /etc/default/ and /etc/sysconfig/ if they exist.
|
11
11
|
# Prefixing the path with '-' makes it try to load, but if the file doesn't
|
12
12
|
# exist, it continues onward.
|
13
|
-
EnvironmentFile
|
14
|
-
EnvironmentFile
|
13
|
+
EnvironmentFile=-{{{default_file}}}
|
14
|
+
EnvironmentFile=-{{{sysconfig_file}}}
|
15
15
|
ExecStart={{{program}}} {{{shell_args}}}
|
16
16
|
{{#prestart}}
|
17
17
|
ExecStartPre={{{unit_path}}}/{{{name}}}-prestart.sh
|
18
18
|
{{/prestart}}
|
19
19
|
Restart=always
|
20
20
|
WorkingDirectory={{{chdir}}}
|
21
|
+
{{#nice}}Nice={{{nice}}}
|
22
|
+
{{/nice}}{{#limit_open_files}}LimitNOFILE={{{limit_open_files}}}
|
23
|
+
{{/limit_open_files}}
|
21
24
|
|
22
25
|
[Install]
|
23
26
|
WantedBy=multi-user.target
|
@@ -1,19 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
chdir="{{{chdir}}}"
|
5
|
-
nice="{{{nice}}}"
|
6
|
-
{{#limit_coredump}}limit_coredump="{{{limit_coredump}}}"
|
7
|
-
{{/limit_coredump}}{{#limit_cputime}}limit_cputime="{{{limit_cputime}}}"
|
8
|
-
{{/limit_cputime}}{{#limit_data}}limit_data="{{{limit_data}}}"
|
9
|
-
{{/limit_data}}{{#limit_file_size}}limit_file_size="{{{limit_file_size}}}"
|
10
|
-
{{/limit_file_size}}{{#limit_locked_memory}}limit_locked_memory="{{{limit_locked_memory}}}"
|
11
|
-
{{/limit_locked_memory}}{{#limit_open_files}}limit_open_files="{{{limit_open_files}}}"
|
12
|
-
{{/limit_open_files}}{{#limit_user_processes}}limit_user_processes="{{{limit_user_processes}}}"
|
13
|
-
{{/limit_user_processes}}{{#limit_physical_memory}}limit_physical_memory="{{{limit_physical_memory}}}"
|
14
|
-
{{/limit_physical_memory}}{{#limit_stack_size}}limit_stack_size="{{{limit_stack_size}}}"{{/limit_stack_size}}
|
15
|
-
|
16
|
-
# If this is set to 1, then when `stop` is called, if the process has
|
17
|
-
# not exited within a reasonable time, SIGKILL will be sent next.
|
18
|
-
# The default behavior is to simply log a message "program stop failed; still running"
|
19
|
-
KILL_ON_STOP_TIMEOUT=0
|
1
|
+
{{#all_environment_variables}}
|
2
|
+
export {{key}}={{#shell_quote}}{{value}}{{/shell_quote}}
|
3
|
+
{{/all_environment_variables}}
|
@@ -22,9 +22,28 @@ name={{#escaped}}{{#safe_filename}}{{{ name }}}{{/safe_filename}}{{/escaped}}
|
|
22
22
|
program={{#escaped}}{{{ program }}}{{/escaped}}
|
23
23
|
args={{{ escaped_args }}}
|
24
24
|
pidfile="/var/run/$name.pid"
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
user="{{{user}}}"
|
26
|
+
group="{{{group}}}"
|
27
|
+
chroot="{{{chroot}}}"
|
28
|
+
chdir="{{{chdir}}}"
|
29
|
+
nice="{{{nice}}}"
|
30
|
+
{{#limit_coredump}}limit_coredump="{{{limit_coredump}}}"
|
31
|
+
{{/limit_coredump}}{{#limit_cputime}}limit_cputime="{{{limit_cputime}}}"
|
32
|
+
{{/limit_cputime}}{{#limit_data}}limit_data="{{{limit_data}}}"
|
33
|
+
{{/limit_data}}{{#limit_file_size}}limit_file_size="{{{limit_file_size}}}"
|
34
|
+
{{/limit_file_size}}{{#limit_locked_memory}}limit_locked_memory="{{{limit_locked_memory}}}"
|
35
|
+
{{/limit_locked_memory}}{{#limit_open_files}}limit_open_files="{{{limit_open_files}}}"
|
36
|
+
{{/limit_open_files}}{{#limit_user_processes}}limit_user_processes="{{{limit_user_processes}}}"
|
37
|
+
{{/limit_user_processes}}{{#limit_physical_memory}}limit_physical_memory="{{{limit_physical_memory}}}"
|
38
|
+
{{/limit_physical_memory}}{{#limit_stack_size}}limit_stack_size="{{{limit_stack_size}}}"{{/limit_stack_size}}
|
39
|
+
|
40
|
+
# If this is set to 1, then when `stop` is called, if the process has
|
41
|
+
# not exited within a reasonable time, SIGKILL will be sent next.
|
42
|
+
# The default behavior is to simply log a message "program stop failed; still running"
|
43
|
+
KILL_ON_STOP_TIMEOUT=0
|
44
|
+
|
45
|
+
[ -r {{{default_file}}} ] && . {{{default_file}}}
|
46
|
+
[ -r {{{sysconfig_file}}} ] && . {{{sysconfig_file}}}
|
28
47
|
|
29
48
|
[ -z "$nice" ] && nice=0
|
30
49
|
|
@@ -38,17 +57,15 @@ emit() {
|
|
38
57
|
}
|
39
58
|
|
40
59
|
start() {
|
41
|
-
{{! I
|
60
|
+
{{! I do not use 'su' here to run as a different user because the process 'su'
|
42
61
|
stays as the parent, causing our pidfile to contain the pid of 'su' not the
|
43
62
|
program we intended to run. Luckily, the 'chroot' program on OSX, FreeBSD, and Linux
|
44
63
|
all support switching users and it invokes execve immediately after chrooting. }}
|
45
64
|
|
46
|
-
{{#sysv_log_directory?}}
|
47
65
|
# Ensure the log directory is setup correctly.
|
48
|
-
[ ! -d "{{{
|
49
|
-
chown "$user":"$group" "{{{
|
50
|
-
chmod 755 "{{{
|
51
|
-
{{/sysv_log_directory?}}
|
66
|
+
[ ! -d "{{{ log_directory }}}" ] && mkdir "{{{ log_directory }}}"
|
67
|
+
chown "$user":"$group" "{{{ log_directory }}}"
|
68
|
+
chmod 755 "{{{ log_directory }}}"
|
52
69
|
|
53
70
|
{{#prestart}}
|
54
71
|
if [ "$PRESTART" != "no" ] ; then
|
@@ -66,7 +83,7 @@ start() {
|
|
66
83
|
{{{ulimit_shell}}}
|
67
84
|
cd \"$chdir\"
|
68
85
|
exec \"$program\" $args
|
69
|
-
" >> {{{
|
86
|
+
" >> {{{ log_path_stdout }}} 2>> {{{ log_path_stderr }}} &
|
70
87
|
|
71
88
|
# Generate the pidfile from here. If we instead made the forked process
|
72
89
|
# generate it there will be a race condition between the pidfile writing
|
@@ -4,9 +4,11 @@ stop on runlevel [!2345]
|
|
4
4
|
|
5
5
|
respawn
|
6
6
|
umask {{{umask}}}
|
7
|
-
#nice {{{nice}}}
|
8
|
-
#
|
9
|
-
|
7
|
+
{{#nice}}nice {{{nice}}}
|
8
|
+
{{/nice}}{{#limit_open_files}}limit nofile {{{limit_open_files}}} {{{limit_open_files}}}
|
9
|
+
{{/limit_open_files}}chroot {{{chroot}}}
|
10
|
+
chdir {{{chdir}}}
|
11
|
+
|
10
12
|
#limit core <softlimit> <hardlimit>
|
11
13
|
#limit cpu <softlimit> <hardlimit>
|
12
14
|
#limit data <softlimit> <hardlimit>
|
@@ -35,5 +37,8 @@ pre-start script
|
|
35
37
|
end script
|
36
38
|
{{/prestart}}
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
+
script
|
41
|
+
[ -r "{{{default_file}}}" ] && . "{{{default_file}}}"
|
42
|
+
[ -r "{{{sysconfig_file}}}" ] && . "{{{sysconfig_file}}}"
|
43
|
+
exec chroot --userspec {{{user}}}:{{{group}}} {{{chroot}}} {{{program}}} {{{shell_args}}} >> {{ log_path_stdout }} 2>> {{ log_path_stderr }}
|
44
|
+
end script
|
@@ -44,7 +44,6 @@ limit stack {{{limit_stack_size}}} {{{limit_stack_size}}}
|
|
44
44
|
{{/limit_stack_size}}
|
45
45
|
setuid {{{user}}}
|
46
46
|
setgid {{{group}}}
|
47
|
-
console log # log stdout/stderr to /var/log/upstart/
|
48
47
|
|
49
48
|
{{#prestart}}
|
50
49
|
pre-start script
|
@@ -60,4 +59,8 @@ pre-start script
|
|
60
59
|
end script
|
61
60
|
{{/prestart}}
|
62
61
|
|
63
|
-
|
62
|
+
script
|
63
|
+
[ -r {{{default_file}}} ] && . {{{default_file}}}
|
64
|
+
[ -r {{{sysconfig_file}}} ] && . {{{sysconfig_file}}}
|
65
|
+
exec chroot --userspec {{{user}}}:{{{group}}} {{{chroot}}} {{{program}}} {{{shell_args}}} >> {{ log_path_stdout }} 2>> {{ log_path_stderr }}
|
66
|
+
end script
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pleaserun
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.25
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Sissel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cabin
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
61
|
+
version: 1.0.3
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
68
|
+
version: 1.0.3
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: insist
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: dotenv
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
description: pleaserun
|
84
98
|
email:
|
85
99
|
- jls@semicomplete.com
|
@@ -133,12 +147,15 @@ files:
|
|
133
147
|
- templates/runit/run
|
134
148
|
- templates/systemd-user/default/prestart.sh
|
135
149
|
- templates/systemd-user/default/program.service
|
150
|
+
- templates/systemd/default/default
|
136
151
|
- templates/systemd/default/prestart.sh
|
137
152
|
- templates/systemd/default/program.service
|
138
153
|
- templates/sysv/default/default
|
139
154
|
- templates/sysv/default/init.sh
|
155
|
+
- templates/upstart/0.6.5/default
|
140
156
|
- templates/upstart/0.6.5/init.conf
|
141
157
|
- templates/upstart/0.6.5/init.d.sh
|
158
|
+
- templates/upstart/default/default
|
142
159
|
- templates/upstart/default/init.conf
|
143
160
|
- templates/upstart/default/init.d.sh
|
144
161
|
- templates/user/linux/default/installer.sh
|
@@ -169,3 +186,4 @@ signing_key:
|
|
169
186
|
specification_version: 4
|
170
187
|
summary: pleaserun
|
171
188
|
test_files: []
|
189
|
+
has_rdoc:
|