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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9996a6b80713eaaee8e724f2db15d03e077d83a0
4
- data.tar.gz: 81f91ba1f891d4f5e84a81a7a146bb892abddcbd
3
+ metadata.gz: 069a73c404991697c3c33c062fadb72a8c3c4478
4
+ data.tar.gz: fa15c05f36673959b42cc7a4f3201be9644dac54
5
5
  SHA512:
6
- metadata.gz: 60d7e5dd2cad19f79b5ad2cfd5e61bda17885f4320ca37a6097cf563e2451162f4b00fca3e6bec3291f49883e309fbff2309a2db6077224cb4402ac075467ff4
7
- data.tar.gz: ac733fa77a7d954f4d50c7595298125b431d5abeb0c1a52c56524e8af4a7787b5c7ce5fef1a859d3a4ea35f459fb9a717aa5f80e2af6146e20d69cf60796e9de
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.23)
4
+ pleaserun (0.0.24)
5
5
  cabin (> 0)
6
6
  clamp
7
+ dotenv
7
8
  insist
8
- mustache (= 0.99.8)
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.99.8)
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
- # TODO(sissel): Move this into the sysv platform
134
- attribute :sysv_log_path, "The destination for log output. If ending with a trailing / is treated like a directory with path/<name>.log. This setting only currently works with the sysv platform. This flag may go away at any time because I'm not sure we can easily abstract the logging feature across different service managers. Upstart and systemd don't even have this concept.",
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 sysv_log
195
- if sysv_log_directory?
196
- File.join(sysv_log_path, name)
197
- else
198
- sysv_log_path
199
- end
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 sysv_log_directory?
203
- return sysv_log_path.end_with?("/")
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("#{home}/.config/systemd/user/{{{ name }}}.service"), render_template("program.service"))
25
- enum.yield(safe_filename("#{home}/.config/systemd/user/{{{ name }}}-prestart.sh"), render_template("prestart.sh"), 0755) if prestart
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.24"
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.99.8"
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
- context "#sysv_log" do
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.sysv_log).to(be == "/var/log/#{name}")
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.sysv_log_path = path }
52
+ before { subject.log_directory = path }
41
53
  it "should be <path>/<name>" do
42
- expect(subject.sysv_log).to(be == File.join(path, subject.name))
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
- context "when given a path" do
46
- let(:path) { "/some/path" }
47
- before { subject.sysv_log_path = path }
48
- it "should be exactly the path given" do
49
- expect(subject.sysv_log).to(be == path)
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.lstat("/etc/init.d").writable? rescue false
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
@@ -67,7 +67,7 @@ describe PleaseRun::User::Base do
67
67
  end
68
68
  end
69
69
 
70
- describe "integration" do
70
+ describe "integration", :if => superuser? do
71
71
  let(:platform) { "linux" }
72
72
  let(:name) { "example" }
73
73
  let(:installer) { Stud::Temporary.pathname }
@@ -10,8 +10,15 @@
10
10
  {{{xml_args}}}
11
11
  </array>
12
12
  <key>KeepAlive</key> <true/>
13
- <key>StandardOutPath</key> <string>/var/log/{{name}}.out</string>
14
- <key>StandardErrorPath</key> <string>/var/log/{{name}}.err</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
@@ -1,4 +1,4 @@
1
1
  #! /bin/sh
2
2
 
3
- exec svlogd -tt /var/log/{{ name }}
3
+ exec svlogd -tt {{ log_path }}
4
4
 
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 chpst
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}}
@@ -5,6 +5,7 @@ Description={{{ description }}}
5
5
 
6
6
  [Service]
7
7
  Type=simple
8
+ EnvironmentFile={{{home}}}/.config/systemd/user/{{{name}}}.environment
8
9
  ExecStart={{{program}}} {{{shell_args}}}
9
10
  Restart=always
10
11
  WorkingDirectory={{{chdir}}}
@@ -0,0 +1,3 @@
1
+ {{#all_environment_variables}}
2
+ {{key}}={{#shell_quote}}{{value}}{{/shell_quote}}
3
+ {{/all_environment_variables}}
@@ -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=-/etc/default/{{{name}}}
14
- EnvironmentFile=-/etc/sysconfig/{{{name}}}
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
- user="{{{user}}}"
2
- group="{{{group}}}"
3
- chroot="{{{chroot}}}"
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
- [ -r /etc/default/$name ] && . /etc/default/$name
27
- [ -r /etc/sysconfig/$name ] && . /etc/sysconfig/$name
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 don't use 'su' here to run as a different user because the process 'su'
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 "{{{sysv_log_path}}}" ] && mkdir "{{{sysv_log_path}}}"
49
- chown "$user":"$group" "{{{sysv_log_path}}}"
50
- chmod 755 "{{{sysv_log_path}}}"
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
- " >> {{{ sysv_log }}}.stdout 2>> {{{ sysv_log }}}.stderr &
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
@@ -0,0 +1,3 @@
1
+ {{#all_environment_variables}}
2
+ export {{key}}={{#shell_quote}}{{value}}{{/shell_quote}}
3
+ {{/all_environment_variables}}
@@ -4,9 +4,11 @@ stop on runlevel [!2345]
4
4
 
5
5
  respawn
6
6
  umask {{{umask}}}
7
- #nice {{{nice}}}
8
- #chroot {{{chroot}}}
9
- #chdir {{{chdir}}}
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
- {{! TODO(sissel): Support logging }}
39
- exec chroot --userspec {{{user}}}:{{{group}}} {{{chroot}}} {{{program}}} {{{shell_args}}}
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
@@ -0,0 +1,3 @@
1
+ {{#all_environment_variables}}
2
+ export {{key}}={{#shell_quote}}{{value}}{{/shell_quote}}
3
+ {{/all_environment_variables}}
@@ -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
- exec {{{program}}} {{{shell_args}}}
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.24
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-05-20 00:00:00.000000000 Z
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.99.8
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.99.8
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: