pleaserun 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +72 -40
- data/lib/pleaserun/cli.rb +29 -61
- data/lib/pleaserun/detector.rb +29 -12
- data/lib/pleaserun/errors.rb +7 -0
- data/lib/pleaserun/installer.rb +64 -0
- data/lib/pleaserun/platform/base.rb +1 -1
- data/lib/pleaserun/platform/sysv.rb +1 -1
- data/pleaserun.gemspec +1 -1
- data/spec/pleaserun/platform/base_spec.rb +2 -0
- data/spec/pleaserun/platform/launchd_spec.rb +12 -61
- data/spec/pleaserun/platform/systemd_spec.rb +12 -83
- data/spec/pleaserun/platform/sysv_spec.rb +11 -108
- data/spec/pleaserun/platform/upstart_spec.rb +13 -78
- data/spec/shared_examples.rb +87 -0
- data/spec/testenv.rb +17 -2
- data/templates/launchd/{10.9 → default}/program.plist +0 -0
- data/templates/sysv/lsb-3.1/{init.d → init.sh} +0 -0
- data/templates/upstart/0.6.5/init.conf +39 -0
- data/templates/upstart/1.5/init.conf +1 -1
- data/test/helpers.rb +5 -1
- data/test/test.rb +7 -5
- data/test/vagrant/Vagrantfile +21 -0
- data/test/vagrant/fedora-18/provision.sh +13 -3
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d316c9bf03f4fe179bbdbab74c1f1a85c55df584
|
4
|
+
data.tar.gz: 6cf4c7bd5e7e48c6618ddfffe576125ffd9c393c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a20035fe0b854e1c87720d7392acf9c50267a29cccec027da48486f1ae549e8267bef074a27e4d2fb803b51bb7135e3ce4b44bde00c58399d8f2836a84b93d9f
|
7
|
+
data.tar.gz: cb819dc5499a68a6469201beb3b75a2a9f50a0f7eaa58bcb2aa3d7bbf9f29e96e3a8b6f22a1ed42c4b7f0a0cdcb738b3b6ad5f66dd9cf56c473fd979a1b5b744
|
data/README.md
CHANGED
@@ -21,9 +21,7 @@ Want more? It's easy to add things. [File an issue](issues/) and ask away!
|
|
21
21
|
|
22
22
|
## Installation
|
23
23
|
|
24
|
-
|
25
|
-
gem install pleaserun
|
26
|
-
```
|
24
|
+
gem install pleaserun
|
27
25
|
|
28
26
|
## Your First Process
|
29
27
|
|
@@ -36,20 +34,16 @@ simulate the same workflow you would normally go through in production: acquire
|
|
36
34
|
software, deploy it, run it. Pleaserun helps you with the 'run it' part, but
|
37
35
|
first let's get redis and build it.
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
make
|
44
|
-
make install PREFIX=/tmp/redis
|
45
|
-
```
|
37
|
+
wget http://download.redis.io/releases/redis-2.8.6.tar.gz
|
38
|
+
tar -zxf redis-2.8.6.tar.gz
|
39
|
+
cd redis-2.8.6
|
40
|
+
make -j4
|
41
|
+
make install PREFIX=/tmp/redis
|
46
42
|
|
47
43
|
Assuming the above succeeds (it did for me!), we now have redis installed to `/tmp/redis`:
|
48
44
|
|
49
|
-
|
50
|
-
|
51
|
-
redis-benchmark redis-check-aof redis-check-dump redis-cli redis-server
|
52
|
-
```
|
45
|
+
% ls /tmp/redis/bin
|
46
|
+
redis-benchmark redis-check-aof redis-check-dump redis-cli redis-server
|
53
47
|
|
54
48
|
You might be thinking - why /tmp? This is just a demo! That's why! :)
|
55
49
|
|
@@ -60,15 +54,13 @@ can never remember.
|
|
60
54
|
|
61
55
|
Luckily, pleaserun remembers.
|
62
56
|
|
63
|
-
|
64
|
-
#
|
65
|
-
|
66
|
-
|
67
|
-
No
|
68
|
-
|
69
|
-
Writing file {:destination=>"/etc/init/redis-server
|
70
|
-
Writing file {:destination=>"/etc/init.d/redis-server"}
|
71
|
-
```
|
57
|
+
# Run as root so pleaserun has permissions to write to
|
58
|
+
# any files required to install this as a service!
|
59
|
+
% sudo pleaserun --install /tmp/redis/bin/redis-server
|
60
|
+
No platform selected. Autodetecting... {:platform=>"upstart", :version=>"1.5", :level=>:warn}
|
61
|
+
No name given, setting reasonable default {:name=>"redis-server", :level=>:warn}
|
62
|
+
Writing file {:destination=>"/etc/init/redis-server.conf"}
|
63
|
+
Writing file {:destination=>"/etc/init.d/redis-server"}
|
72
64
|
|
73
65
|
Note: The `--install` flag above tells pleaserun to install it on this current system. The
|
74
66
|
default behavior without this flag is to install it in a temp directory so you can copy
|
@@ -77,28 +69,26 @@ it elsewhere if desired.
|
|
77
69
|
Now what? You can see above it automatically detected that "Upstart 1.5" was
|
78
70
|
the right process runner to target. Let's try using it!
|
79
71
|
|
80
|
-
|
81
|
-
|
82
|
-
redis-server stop/waiting
|
72
|
+
% status redis-server
|
73
|
+
redis-server stop/waiting
|
83
74
|
|
84
|
-
% sudo start redis-server
|
85
|
-
redis-server start/running, process 395
|
75
|
+
% sudo start redis-server
|
76
|
+
redis-server start/running, process 395
|
86
77
|
|
87
|
-
% status redis-server
|
88
|
-
redis-server start/running, process 395
|
78
|
+
% status redis-server
|
79
|
+
redis-server start/running, process 395
|
89
80
|
|
90
|
-
% ps -fwwp 395
|
91
|
-
UID PID PPID C STIME TTY TIME CMD
|
92
|
-
root 395 1 0 06:27 ? 00:00:00 /tmp/redis/bin/redis-server *:6379
|
81
|
+
% ps -fwwp 395
|
82
|
+
UID PID PPID C STIME TTY TIME CMD
|
83
|
+
root 395 1 0 06:27 ? 00:00:00 /tmp/redis/bin/redis-server *:6379
|
93
84
|
|
94
|
-
# Is it running? Let's check with redis-cli
|
95
|
-
% redis-cli
|
96
|
-
127.0.0.1:6379> ping
|
97
|
-
PONG
|
85
|
+
# Is it running? Let's check with redis-cli
|
86
|
+
% redis-cli
|
87
|
+
127.0.0.1:6379> ping
|
88
|
+
PONG
|
98
89
|
|
99
|
-
% sudo stop redis-server
|
100
|
-
redis-server stop/waiting
|
101
|
-
```
|
90
|
+
% sudo stop redis-server
|
91
|
+
redis-server stop/waiting
|
102
92
|
|
103
93
|
Bam. Pretty easy, right? Let's recap!
|
104
94
|
|
@@ -108,3 +98,45 @@ Bam. Pretty easy, right? Let's recap!
|
|
108
98
|
* Pleaserun detected the platform as Upstart 1.5
|
109
99
|
* You didn't have to write an init script.
|
110
100
|
* You didn't have to know how to write an Upstart config.
|
101
|
+
|
102
|
+
### Overview
|
103
|
+
|
104
|
+
See `pleaserun --help` for a list of flags. Basics:
|
105
|
+
|
106
|
+
* `-p` lets you set the platform to target. If not specified, this is
|
107
|
+
automatically detected based on your current system/environment.
|
108
|
+
* `-v` lets you set the version of the platform to target. Useful in cases
|
109
|
+
where things like Upstart 0.6.5 differ wildly in configuration from Upstart
|
110
|
+
1.5
|
111
|
+
* `--name` the name of the process. This shows up as
|
112
|
+
/etc/init.d/the-name-you-give for sysv, or the name you use to reference the
|
113
|
+
service with upstart, systemd, or launchd, etc!
|
114
|
+
* `--prestart` lets you run a command *before* starting the main program. This
|
115
|
+
can be used to do config or validation checks before you start a program. If
|
116
|
+
the prestart exits nonzero, the start of the process will be aborted.
|
117
|
+
|
118
|
+
A silly example:
|
119
|
+
|
120
|
+
# Generate a LSB 3.1-compliant SYSV-style init script
|
121
|
+
% pleaserun --install -p sysv -v lsb-3.1 --name sleeper /bin/sleep 60
|
122
|
+
Writing file {:destination=>"/etc/init.d/sleeper"}
|
123
|
+
Writing file {:destination=>"/etc/default/sleeper"}
|
124
|
+
|
125
|
+
# Try it!
|
126
|
+
% /etc/init.d/sleeper status
|
127
|
+
sleeper is not running
|
128
|
+
|
129
|
+
% sudo /etc/init.d/sleeper start
|
130
|
+
sleeper started.
|
131
|
+
|
132
|
+
% ps -fwp $(cat /var/run/sleeper.pid)
|
133
|
+
UID PID PPID C STIME TTY TIME CMD
|
134
|
+
root 50473 1 0 22:36 pts/7 00:00:00 /bin/sleep 60
|
135
|
+
|
136
|
+
# One last thing!
|
137
|
+
|
138
|
+
Please enjoy running things! If you are not enjoying this program, then something is wrong, and we can fix it together :)
|
139
|
+
|
140
|
+
If you are having a bad time, it is a bug!
|
141
|
+
|
142
|
+
All contributions welcome (bug reports, feature requests, bug fixes, new features, etc!)
|
data/lib/pleaserun/cli.rb
CHANGED
@@ -5,20 +5,19 @@ require "cabin"
|
|
5
5
|
require "stud/temporary"
|
6
6
|
|
7
7
|
require "pleaserun/platform/base"
|
8
|
+
require "pleaserun/installer"
|
9
|
+
require "pleaserun/errors"
|
8
10
|
|
9
11
|
# The CLI interface to pleaserun.
|
10
12
|
#
|
11
13
|
# This is invoked by `bin/pleaserun`.
|
12
14
|
class PleaseRun::CLI < Clamp::Command # rubocop:disable ClassLength
|
13
|
-
class Error < StandardError; end
|
14
|
-
class ConfigurationError < Error; end
|
15
|
-
class PlatformLoadError < Error; end
|
16
|
-
class FileWritingFailure < Error; end
|
17
15
|
|
18
16
|
option ["-p", "--platform"], "PLATFORM", "The name of the platform to target, such as sysv, upstart, etc"
|
19
17
|
option ["-v", "--version"], "VERSION", "The version of the platform to target, such as 'lsb-3.1' for sysv or '1.5' for upstart",
|
20
18
|
:default => "default", :attribute_name => :target_version
|
21
19
|
|
20
|
+
option "--overwrite", :flag, "Overwrite any files that already exist when installing."
|
22
21
|
option "--log", "LOGFILE", "The path to use for writing pleaserun logs."
|
23
22
|
option "--json", :flag, "Output a result in JSON. Intended to be consumed by other programs. This will emit the file contents and install actions as a JSON object."
|
24
23
|
|
@@ -104,18 +103,7 @@ are made. If it fails, nagios will not start. Yay!
|
|
104
103
|
|
105
104
|
def execute
|
106
105
|
setup_logger
|
107
|
-
|
108
|
-
# Provide any dynamic defaults if necessary
|
109
|
-
if platform.nil?
|
110
|
-
require "pleaserun/detector"
|
111
|
-
self.platform, self.target_version = PleaseRun::Detector.detect
|
112
|
-
@logger.warn("No platform selected. Autodetecting...", :platform => platform, :version => target_version)
|
113
|
-
end
|
114
|
-
|
115
|
-
if name.nil?
|
116
|
-
self.name = File.basename(program)
|
117
|
-
@logger.warn("No name given, setting reasonable default", :name => name)
|
118
|
-
end
|
106
|
+
setup_defaults
|
119
107
|
|
120
108
|
# Load the platform implementation
|
121
109
|
platform_klass = load_platform(platform)
|
@@ -139,11 +127,25 @@ are made. If it fails, nagios will not start. Yay!
|
|
139
127
|
return run_human(runner)
|
140
128
|
end
|
141
129
|
return 0
|
142
|
-
rescue Error => e
|
130
|
+
rescue PleaseRun::Error => e
|
143
131
|
@logger.error("An error occurred: #{e}")
|
144
132
|
return 1
|
145
133
|
end # def execute
|
146
134
|
|
135
|
+
def setup_defaults
|
136
|
+
# Provide any dynamic defaults if necessary
|
137
|
+
if platform.nil?
|
138
|
+
require "pleaserun/detector"
|
139
|
+
self.platform, self.target_version = PleaseRun::Detector.detect
|
140
|
+
@logger.warn("No platform selected. Autodetecting...", :platform => platform, :version => target_version)
|
141
|
+
end
|
142
|
+
|
143
|
+
if name.nil?
|
144
|
+
self.name = File.basename(program)
|
145
|
+
@logger.warn("No name given, setting reasonable default based on the executable", :name => name)
|
146
|
+
end
|
147
|
+
end # def setup_defaults
|
148
|
+
|
147
149
|
def run_json(runner)
|
148
150
|
require "json"
|
149
151
|
|
@@ -164,54 +166,20 @@ are made. If it fails, nagios will not start. Yay!
|
|
164
166
|
end # def run_json
|
165
167
|
|
166
168
|
def run_human(runner)
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
errors << fullpath unless success
|
169
|
+
if install?
|
170
|
+
PleaseRun::Installer.install_files(runner, "/", overwrite?)
|
171
|
+
PleaseRun::Installer.install_actions(runner)
|
172
|
+
else
|
173
|
+
tmp = Stud::Temporary.directory
|
174
|
+
actions_script = File.join(tmp, "install_actions.sh")
|
175
|
+
PleaseRun::Installer.install_files(runner, tmp)
|
176
|
+
PleaseRun::Installer.write_actions(runner, actions_script)
|
176
177
|
end
|
177
|
-
|
178
|
-
raise FileWritingFailure, "Errors occurred while writing files" if errors.any?
|
179
|
-
|
180
|
-
# TODO(sissel): Refactor this to be less lines of code or put into methods.
|
181
|
-
if runner.install_actions.any?
|
182
|
-
if install?
|
183
|
-
runner.install_actions.each do |action|
|
184
|
-
@logger.info("Running install action", :action => action)
|
185
|
-
system(action)
|
186
|
-
@logger.warn("Install action failed", :action => action, :code => $CHILD_STATUS.exitstatus) unless $CHILD_STATUS.success?
|
187
|
-
end # each install action
|
188
|
-
else
|
189
|
-
path = File.join(tmp, "install_actions.sh")
|
190
|
-
@logger.log("Writing install actions. You will want to run this script to properly activate your service on the target host", :path => path)
|
191
|
-
File.open(path, "w") do |fd|
|
192
|
-
runner.install_actions.each do |action|
|
193
|
-
fd.puts(action)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end # if runner.install_actions.any?
|
198
178
|
return 0
|
199
179
|
end # def run_human
|
200
180
|
|
201
|
-
def write(fullpath, content, perms)
|
202
|
-
@logger.log("Writing file", :destination => fullpath)
|
203
|
-
FileUtils.mkdir_p(File.dirname(fullpath))
|
204
|
-
File.write(fullpath, content)
|
205
|
-
@logger.debug("Setting permissions", :destination => fullpath, :perms => perms)
|
206
|
-
File.chmod(perms, fullpath) if perms
|
207
|
-
return true
|
208
|
-
rescue Errno::EACCES
|
209
|
-
@logger.error("Access denied in writing a file. Maybe we need to be root?", :path => fullpath)
|
210
|
-
return false
|
211
|
-
end
|
212
|
-
|
213
181
|
def setup_logger
|
214
|
-
@logger = Cabin::Channel.
|
182
|
+
@logger = Cabin::Channel.get
|
215
183
|
if quiet?
|
216
184
|
@logger.level = :error
|
217
185
|
elsif verbose?
|
@@ -223,7 +191,7 @@ are made. If it fails, nagios will not start. Yay!
|
|
223
191
|
end
|
224
192
|
|
225
193
|
if log
|
226
|
-
logfile = File.new(
|
194
|
+
logfile = File.new(log, "a")
|
227
195
|
@logger.subscribe(logfile)
|
228
196
|
STDERR.puts "Sending all logs to #{log}" if STDERR.tty?
|
229
197
|
else
|
data/lib/pleaserun/detector.rb
CHANGED
@@ -8,19 +8,26 @@ class PleaseRun::Detector
|
|
8
8
|
|
9
9
|
# A mapping of of [os, version] => [runner, version]
|
10
10
|
MAPPING = {
|
11
|
-
["
|
12
|
-
["
|
13
|
-
["
|
14
|
-
["
|
15
|
-
["debian", "7"] => ["sysv", "lsb-3.1"],
|
11
|
+
["arch", "rolling"] => ["systemd", "default"],
|
12
|
+
["centos", "5"] => ["sysv", "lsb-3.1"],
|
13
|
+
["centos", "6"] => ["upstart", "0.6.5"],
|
14
|
+
["centos", "7"] => ["systemd", "default"],
|
16
15
|
["debian", "6"] => ["sysv", "lsb-3.1"],
|
16
|
+
["debian", "7"] => ["sysv", "lsb-3.1"],
|
17
17
|
["fedora", "18"] => ["systemd", "default"],
|
18
18
|
["fedora", "19"] => ["systemd", "default"],
|
19
19
|
["fedora", "20"] => ["systemd", "default"],
|
20
|
-
["mac_os_x", "10.9"] => [
|
20
|
+
["mac_os_x", "10.9"] => ["launchd", "10.9"],
|
21
|
+
["mac_os_x", "10.9"] => ["launchd", "10.9"],
|
22
|
+
["ubuntu", "12.04"] => ["upstart", "1.5"],
|
23
|
+
["ubuntu", "12.10"] => ["upstart", "1.5"],
|
24
|
+
["ubuntu", "13.04"] => ["upstart", "1.5"],
|
25
|
+
["ubuntu", "13.10"] => ["upstart", "1.5"]
|
21
26
|
}
|
22
27
|
|
23
28
|
def self.detect
|
29
|
+
return @system unless @system.nil?
|
30
|
+
|
24
31
|
@logger ||= Cabin::Channel.get
|
25
32
|
begin
|
26
33
|
platform, version = detect_ohai
|
@@ -33,9 +40,9 @@ class PleaseRun::Detector
|
|
33
40
|
end
|
34
41
|
end
|
35
42
|
|
36
|
-
system = lookup([platform, version])
|
37
|
-
raise UnknownSystem if system.nil?
|
38
|
-
return system
|
43
|
+
@system = lookup([platform, version])
|
44
|
+
raise UnknownSystem if @system.nil?
|
45
|
+
return @system
|
39
46
|
end # def self.detect
|
40
47
|
|
41
48
|
def self.lookup(platform_and_version)
|
@@ -55,14 +62,24 @@ class PleaseRun::Detector
|
|
55
62
|
return platform, normalize_version(platform, version)
|
56
63
|
end # def detect_ohai
|
57
64
|
|
65
|
+
def self.detect_facter
|
66
|
+
require "facter"
|
67
|
+
|
68
|
+
platform = Facter.fact["operatingsystem"]
|
69
|
+
version = Facter.fact["operatingsystemrelease"]
|
70
|
+
return platform, normalize_version(platform, version)
|
71
|
+
end # def detect_facter
|
72
|
+
|
58
73
|
def self.normalize_version(platform, version)
|
59
74
|
case platform
|
60
75
|
# Take '6.0.8' and make it just '6' since debian never makes major
|
61
76
|
# changes in a minor release
|
62
|
-
when "debian"
|
63
|
-
return version[/^[0-9]+/]
|
77
|
+
when "debian", "centos"
|
78
|
+
return version[/^[0-9]+/] # First digit is the 'major' version
|
64
79
|
when "mac_os_x"
|
65
|
-
return version[/^[0-9]+\.[0-9]+/]
|
80
|
+
return version[/^[0-9]+\.[0-9]+/] # 10.x
|
81
|
+
when "arch"
|
82
|
+
return "rolling"
|
66
83
|
# TODO(sissel): Any other edge cases?
|
67
84
|
end
|
68
85
|
return version
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "pleaserun/namespace"
|
2
|
+
require "pleaserun/errors"
|
3
|
+
|
4
|
+
# Some helpful methods for installing a runner.
|
5
|
+
module PleaseRun::Installer
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def install(runner)
|
9
|
+
install_files(runner)
|
10
|
+
install_actions(runner)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Install files provided by a runner.
|
14
|
+
#
|
15
|
+
# If overwrite is false and any file already exists, then this method will fail.
|
16
|
+
def install_files(runner, root = "/", overwrite = false)
|
17
|
+
errors = 0
|
18
|
+
runner.files.each do |path, content, perms|
|
19
|
+
# TODO(sissel): Force-set default file permissions if not provided?
|
20
|
+
# perms ||= (0666 ^ File.umask)
|
21
|
+
fullpath = File.join(root, path)
|
22
|
+
raise PleaseRun::FileWritingFailure, "File already exists: #{fullpath}" if !overwrite && File.file?(fullpath)
|
23
|
+
success = write(fullpath, content, perms)
|
24
|
+
errors += 1 unless success
|
25
|
+
end
|
26
|
+
raise PleaseRun::FileWritingFailure, "Errors occurred while writing files" if errors > 0
|
27
|
+
end
|
28
|
+
|
29
|
+
def write(fullpath, content, perms)
|
30
|
+
logger.log("Writing file", :destination => fullpath)
|
31
|
+
FileUtils.mkdir_p(File.dirname(fullpath))
|
32
|
+
File.write(fullpath, content)
|
33
|
+
logger.debug("Setting permissions", :destination => fullpath, :perms => perms)
|
34
|
+
File.chmod(perms, fullpath) if perms
|
35
|
+
return true
|
36
|
+
rescue Errno::EACCES
|
37
|
+
logger.error("Access denied in writing a file. Maybe we need to be root?", :path => fullpath)
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
|
41
|
+
def install_actions(runner)
|
42
|
+
return if runner.install_actions.empty?
|
43
|
+
# TODO(sissel): Refactor this to be less lines of code or put into methods.
|
44
|
+
runner.install_actions.each do |action|
|
45
|
+
logger.info("Running install action", :action => action)
|
46
|
+
system(action)
|
47
|
+
logger.warn("Install action failed", :action => action, :code => $CHILD_STATUS.exitstatus) unless $CHILD_STATUS.success?
|
48
|
+
end # each install action
|
49
|
+
end
|
50
|
+
|
51
|
+
def write_actions(runner, path)
|
52
|
+
return if runner.install_actions.empty?
|
53
|
+
logger.log("Writing install actions. You will want to run this script to properly activate your service on the target host", :path => path)
|
54
|
+
File.open(path, "w") do |fd|
|
55
|
+
runner.install_actions.each do |action|
|
56
|
+
fd.puts(action)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def logger
|
62
|
+
return @logger ||= Cabin::Channel.get
|
63
|
+
end
|
64
|
+
end # module PleaseRun::Installer
|
@@ -79,7 +79,7 @@ class PleaseRun::Platform::Base
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
attribute :chdir, "The directory to chdir to before running" do
|
82
|
+
attribute :chdir, "The directory to chdir to before running", :default => "/" do
|
83
83
|
validate do |chdir|
|
84
84
|
insist { chdir }.is_a?(String)
|
85
85
|
end
|
@@ -7,7 +7,7 @@ require "pleaserun/namespace"
|
|
7
7
|
class PleaseRun::Platform::SYSV < PleaseRun::Platform::Base
|
8
8
|
def files
|
9
9
|
return Enumerator::Generator.new do |out|
|
10
|
-
out.yield(safe_filename("/etc/init.d/{{ name }}"), render_template("init.
|
10
|
+
out.yield(safe_filename("/etc/init.d/{{ name }}"), render_template("init.sh"), 0755)
|
11
11
|
out.yield(safe_filename("/etc/default/{{ name }}"), render_template("default"))
|
12
12
|
end
|
13
13
|
end
|
data/pleaserun.gemspec
CHANGED
@@ -4,6 +4,7 @@ require "pleaserun/platform/base"
|
|
4
4
|
describe PleaseRun::Platform::Base do
|
5
5
|
context "default" do
|
6
6
|
subject { PleaseRun::Platform::Base.new("example") }
|
7
|
+
|
7
8
|
it "#name should be nil" do
|
8
9
|
insist { subject.name }.nil?
|
9
10
|
end
|
@@ -25,3 +26,4 @@ describe PleaseRun::Platform::Base do
|
|
25
26
|
end
|
26
27
|
end
|
27
28
|
end
|
29
|
+
|
@@ -1,10 +1,20 @@
|
|
1
1
|
require "English" # for $CHILD_STATUS
|
2
2
|
require "testenv"
|
3
3
|
require "pleaserun/platform/launchd"
|
4
|
+
require "pleaserun/detector"
|
4
5
|
|
5
6
|
describe PleaseRun::Platform::Launchd do
|
6
|
-
|
7
|
-
|
7
|
+
let(:platform) { PleaseRun::Detector.detect[0] }
|
8
|
+
let(:version) { PleaseRun::Detector.detect[1] }
|
9
|
+
|
10
|
+
context "deployment", :launchd => true do
|
11
|
+
it_behaves_like PleaseRun::Platform do
|
12
|
+
let(:start) { "launchctl start #{subject.name}" }
|
13
|
+
let(:stop) { "launchctl stop #{subject.name}" }
|
14
|
+
let(:status) { "launchctl list | awk '$3 == \"#{subject.name}\" { exit($1 == \"-\") }'" }
|
15
|
+
let(:restart) { "launchctl restart #{subject.name}" }
|
16
|
+
end
|
17
|
+
|
8
18
|
end
|
9
19
|
|
10
20
|
context "#files" do
|
@@ -32,63 +42,4 @@ describe PleaseRun::Platform::Launchd do
|
|
32
42
|
insist { subject.install_actions }.include?("launchctl load /Library/LaunchDaemons/fancypants.plist")
|
33
43
|
end
|
34
44
|
end
|
35
|
-
|
36
|
-
context "deployment" do
|
37
|
-
partytime = (superuser? && platform?("darwin"))
|
38
|
-
it "cannot be attempted", :if => !partytime do
|
39
|
-
pending("we are not the superuser") unless superuser?
|
40
|
-
pending("platform is not darwin") unless platform?("darwin")
|
41
|
-
end
|
42
|
-
|
43
|
-
context "as the super user", :if => partytime do
|
44
|
-
subject { PleaseRun::Platform::Launchd.new("10.9") }
|
45
|
-
|
46
|
-
before do
|
47
|
-
subject.name = "example"
|
48
|
-
subject.user = "root"
|
49
|
-
subject.program = "/bin/sh"
|
50
|
-
subject.args = ["-c", "echo hello world; sleep 5"]
|
51
|
-
|
52
|
-
subject.files.each do |path, content|
|
53
|
-
File.write(path, content)
|
54
|
-
end
|
55
|
-
subject.install_actions.each do |command|
|
56
|
-
system(command)
|
57
|
-
raise "Command failed: #{command}" unless $CHILD_STATUS.success?
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
after do
|
62
|
-
system_quiet("launchctl stop #{subject.name}")
|
63
|
-
system_quiet("launchctl unload /Library/LaunchDaemons/#{subject.name}.plist")
|
64
|
-
subject.files.each do |path, content|
|
65
|
-
File.unlink(path) if File.exist?(path)
|
66
|
-
end
|
67
|
-
|
68
|
-
# Remove the logs, too.
|
69
|
-
["/var/log/#{subject.name}.out", "/var/log/#{subject.name}.err"].each do |log|
|
70
|
-
File.unlink(log) if File.exist?(log)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
it "should install" do
|
75
|
-
system_quiet("launchctl list #{subject.name}")
|
76
|
-
insist { $CHILD_STATUS }.success?
|
77
|
-
end
|
78
|
-
|
79
|
-
it "should start" do
|
80
|
-
system_quiet("launchctl start #{subject.name}")
|
81
|
-
insist { $CHILD_STATUS }.success?
|
82
|
-
system_quiet("launchctl list #{subject.name}")
|
83
|
-
insist { $CHILD_STATUS }.success?
|
84
|
-
end
|
85
|
-
|
86
|
-
it "should stop" do
|
87
|
-
system_quiet("launchctl start #{subject.name}")
|
88
|
-
insist { $CHILD_STATUS }.success?
|
89
|
-
system_quiet("launchctl stop #{subject.name}")
|
90
|
-
insist { $CHILD_STATUS }.success?
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end # real tests
|
94
45
|
end
|
@@ -2,18 +2,21 @@ require "testenv"
|
|
2
2
|
require "pleaserun/platform/systemd"
|
3
3
|
|
4
4
|
describe PleaseRun::Platform::Systemd do
|
5
|
-
let(:
|
6
|
-
let(:
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
let(:platform) { PleaseRun::Detector.detect[0] }
|
6
|
+
let(:version) { PleaseRun::Detector.detect[1] }
|
7
|
+
|
8
|
+
context "deployment", :systemd => true do
|
9
|
+
it_behaves_like PleaseRun::Platform do
|
10
|
+
let(:start) { "systemctl start #{subject.name}.service" }
|
11
|
+
let(:stop) { "systemctl stop #{subject.name}.service" }
|
12
|
+
let(:status) { "systemctl show #{subject.name} | grep -q SubState=running" }
|
13
|
+
let(:restart) { "systemctl restart #{subject.name}.service" }
|
14
|
+
end
|
12
15
|
end
|
13
16
|
|
14
17
|
context "#files" do
|
15
18
|
subject do
|
16
|
-
runner =
|
19
|
+
runner = described_class.new(version)
|
17
20
|
runner.name = "fancypants"
|
18
21
|
runner.program = "/bin/true"
|
19
22
|
next runner
|
@@ -28,7 +31,7 @@ describe PleaseRun::Platform::Systemd do
|
|
28
31
|
|
29
32
|
context "#install_actions" do
|
30
33
|
subject do
|
31
|
-
runner =
|
34
|
+
runner = described_class.new(version)
|
32
35
|
runner.name = "fancypants"
|
33
36
|
next runner
|
34
37
|
end
|
@@ -37,78 +40,4 @@ describe PleaseRun::Platform::Systemd do
|
|
37
40
|
insist { subject.install_actions }.include?("systemctl --system daemon-reload")
|
38
41
|
end
|
39
42
|
end
|
40
|
-
|
41
|
-
context "deployment" do
|
42
|
-
partytime = (superuser? && platform?("linux") && program?("systemctl") && File.directory?("/lib/systemd"))
|
43
|
-
it "cannot be attempted", :if => !partytime do
|
44
|
-
pending("we are not the superuser") unless superuser?
|
45
|
-
pending("platform is not linux") unless platform?("linux")
|
46
|
-
pending("no 'systemctl' program found") unless program?("systemctl")
|
47
|
-
pending("missing /lib/systemd directory") unless File.directory?("/lib/systemd")
|
48
|
-
end
|
49
|
-
|
50
|
-
context "as the super user", :if => partytime do
|
51
|
-
subject { PleaseRun::Platform::Systemd.new("default") }
|
52
|
-
|
53
|
-
before do
|
54
|
-
subject.name = "hurray"
|
55
|
-
subject.user = "root"
|
56
|
-
subject.program = "/bin/sh"
|
57
|
-
subject.args = ["-c", "echo hello world; sleep 5"]
|
58
|
-
activate(subject)
|
59
|
-
|
60
|
-
# monkeypatch StartLimitInterval=0 into the .service file to avoid
|
61
|
-
# being throttled by systemd during these tests.
|
62
|
-
# Fixes https://github.com/jordansissel/pleaserun/issues/11
|
63
|
-
path = "/lib/systemd/system/#{subject.name}.service"
|
64
|
-
File.write(path, File.read(path).sub(/^\[Service\]$/, "[Service]\nStartLimitInterval=0"))
|
65
|
-
end
|
66
|
-
|
67
|
-
after do
|
68
|
-
system_quiet("systemctl stop #{subject.name}")
|
69
|
-
subject.files.each do |path, content|
|
70
|
-
File.unlink(path) if File.exist?(path)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
it "should start" do
|
75
|
-
starts
|
76
|
-
status_running
|
77
|
-
end
|
78
|
-
|
79
|
-
it "should stop" do
|
80
|
-
starts
|
81
|
-
stops
|
82
|
-
end
|
83
|
-
|
84
|
-
it "should start and stop" do
|
85
|
-
5.times do
|
86
|
-
starts
|
87
|
-
stops
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
context "with failing prestart" do
|
92
|
-
before do
|
93
|
-
subject.prestart = "#!/bin/sh\nfalse\n"
|
94
|
-
activate(subject)
|
95
|
-
end
|
96
|
-
|
97
|
-
it "should fail to start" do
|
98
|
-
insist { starts }.fails
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
context "with successful prestart" do
|
103
|
-
before do
|
104
|
-
subject.prestart = "true"
|
105
|
-
activate(subject)
|
106
|
-
end
|
107
|
-
|
108
|
-
it "should start" do
|
109
|
-
starts
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end # as the super user
|
113
|
-
end # real tests
|
114
43
|
end
|
@@ -1,14 +1,18 @@
|
|
1
1
|
require "testenv"
|
2
2
|
require "pleaserun/platform/sysv"
|
3
|
+
require "pleaserun/detector"
|
3
4
|
|
4
5
|
describe PleaseRun::Platform::SYSV do
|
5
|
-
let(:
|
6
|
-
let(:
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
let(:platform) { PleaseRun::Detector.detect[0] }
|
7
|
+
let(:version) { PleaseRun::Detector.detect[1] }
|
8
|
+
|
9
|
+
context "deployment", :sysv => true do
|
10
|
+
it_behaves_like PleaseRun::Platform do
|
11
|
+
let(:start) { "/etc/init.d/#{subject.name} start" }
|
12
|
+
let(:stop) { "/etc/init.d/#{subject.name} stop" }
|
13
|
+
let(:status) { "/etc/init.d/#{subject.name} status" }
|
14
|
+
let(:restart) { "/etc/init.d/#{subject.name} restart" }
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
context "#files" do
|
@@ -27,105 +31,4 @@ describe PleaseRun::Platform::SYSV do
|
|
27
31
|
insist { files }.include?("/etc/default/fancypants")
|
28
32
|
end
|
29
33
|
end
|
30
|
-
|
31
|
-
context "deployment" do
|
32
|
-
partytime = superuser? && File.directory?("/etc/init.d")
|
33
|
-
it "cannot be attempted", :if => !partytime do
|
34
|
-
pending("we are not the superuser") unless superuser?
|
35
|
-
pending("no /etc/init.d/ directory found") unless File.directory?("/etc/init.d")
|
36
|
-
end
|
37
|
-
|
38
|
-
context "as the super user", :if => partytime do
|
39
|
-
subject { PleaseRun::Platform::SYSV.new("ubuntu-12.04") }
|
40
|
-
|
41
|
-
before do
|
42
|
-
subject.name = "example"
|
43
|
-
subject.user = "root"
|
44
|
-
subject.program = "/bin/ping"
|
45
|
-
subject.args = ["127.0.0.1"]
|
46
|
-
|
47
|
-
activate(subject)
|
48
|
-
end
|
49
|
-
|
50
|
-
after do
|
51
|
-
system_quiet("/etc/init.d/#{subject.name} stop")
|
52
|
-
subject.files.each do |path, content|
|
53
|
-
File.unlink(path) if File.exist?(path)
|
54
|
-
end
|
55
|
-
|
56
|
-
# TODO(sissel): Remove the logs, too.
|
57
|
-
end
|
58
|
-
|
59
|
-
it "should install" do
|
60
|
-
insist { File }.exist?("/etc/init.d/#{subject.name}")
|
61
|
-
end
|
62
|
-
|
63
|
-
it "should start" do
|
64
|
-
# Status should fail before starting
|
65
|
-
status_stopped
|
66
|
-
starts
|
67
|
-
end
|
68
|
-
|
69
|
-
it "should stop" do
|
70
|
-
status_stopped
|
71
|
-
starts
|
72
|
-
stops
|
73
|
-
end
|
74
|
-
|
75
|
-
context "with failing prestart" do
|
76
|
-
before do
|
77
|
-
subject.prestart = "false"
|
78
|
-
activate(subject)
|
79
|
-
end
|
80
|
-
|
81
|
-
it "should fail to start" do
|
82
|
-
insist { starts }.fails
|
83
|
-
end
|
84
|
-
|
85
|
-
context "with PRESTART=no" do
|
86
|
-
before { ENV["PRESTART"] = "no" }
|
87
|
-
after { ENV["PRESTART"] = nil }
|
88
|
-
it "should start" do
|
89
|
-
starts
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
it "should stop" do
|
94
|
-
# Force a start
|
95
|
-
ENV["PRESTART"] = "no"
|
96
|
-
starts
|
97
|
-
ENV["PRESTART"] = nil
|
98
|
-
stops
|
99
|
-
end
|
100
|
-
|
101
|
-
it "should fail to restart" do
|
102
|
-
ENV["PRESTART"] = "no"
|
103
|
-
starts
|
104
|
-
ENV["PRESTART"] = nil
|
105
|
-
insist { restarts }.fails
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
context "with a successful prestart" do
|
110
|
-
before do
|
111
|
-
subject.prestart = "echo hello world"
|
112
|
-
activate(subject)
|
113
|
-
end
|
114
|
-
|
115
|
-
it "should start" do
|
116
|
-
starts
|
117
|
-
end
|
118
|
-
|
119
|
-
it "should restart" do
|
120
|
-
# Force start
|
121
|
-
ENV["PRESTART"] = "no"
|
122
|
-
starts
|
123
|
-
ENV["PRESTART"] = nil
|
124
|
-
|
125
|
-
# Restart should succeed
|
126
|
-
restarts
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end # as the super user
|
130
|
-
end # real tests
|
131
34
|
end
|
@@ -1,19 +1,23 @@
|
|
1
1
|
require "testenv"
|
2
2
|
require "pleaserun/platform/upstart"
|
3
|
+
require "pleaserun/detector"
|
3
4
|
|
4
5
|
describe PleaseRun::Platform::Upstart do
|
5
|
-
let(:
|
6
|
-
let(:
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
let(:platform) { PleaseRun::Detector.detect[0] }
|
7
|
+
let(:version) { PleaseRun::Detector.detect[1] }
|
8
|
+
|
9
|
+
context "deployment", :upstart=> true do
|
10
|
+
it_behaves_like PleaseRun::Platform do
|
11
|
+
let(:start) { "initctl start #{subject.name}" }
|
12
|
+
let(:stop) { "initctl stop #{subject.name}" }
|
13
|
+
let(:status) { "initctl status #{subject.name} | egrep -v '#{subject.name} stop/'" }
|
14
|
+
let(:restart) { "initctl restart #{subject.name}" }
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
context "#files" do
|
15
19
|
subject do
|
16
|
-
runner = PleaseRun::Platform::Upstart.new(
|
20
|
+
runner = PleaseRun::Platform::Upstart.new(version)
|
17
21
|
runner.name = "fancypants"
|
18
22
|
next runner
|
19
23
|
end
|
@@ -31,7 +35,7 @@ describe PleaseRun::Platform::Upstart do
|
|
31
35
|
|
32
36
|
context "#install_actions" do
|
33
37
|
subject do
|
34
|
-
runner = PleaseRun::Platform::Upstart.new(
|
38
|
+
runner = PleaseRun::Platform::Upstart.new(version)
|
35
39
|
runner.name = "fancypants"
|
36
40
|
next runner
|
37
41
|
end
|
@@ -40,73 +44,4 @@ describe PleaseRun::Platform::Upstart do
|
|
40
44
|
insist { subject.install_actions }.empty?
|
41
45
|
end
|
42
46
|
end
|
43
|
-
|
44
|
-
context "deployment" do
|
45
|
-
partytime = (superuser? && platform?("linux") && program?("initctl") && File.directory?("/etc/init"))
|
46
|
-
it "cannot be attempted", :if => !partytime do
|
47
|
-
pending("we are not the superuser") unless superuser?
|
48
|
-
pending("platform is not linux") unless platform?("linux")
|
49
|
-
pending("no 'initctl' program found") unless program?("initctl")
|
50
|
-
pending("missing /etc/init/ directory") unless File.directory?("/etc/init")
|
51
|
-
end
|
52
|
-
|
53
|
-
context "as the super user", :if => partytime do
|
54
|
-
subject { PleaseRun::Platform::Upstart.new("1.10") }
|
55
|
-
|
56
|
-
before do
|
57
|
-
subject.name = "example"
|
58
|
-
subject.user = "root"
|
59
|
-
subject.program = "/bin/sh"
|
60
|
-
subject.args = ["-c", "echo hello world; sleep 5"]
|
61
|
-
activate(subject)
|
62
|
-
end
|
63
|
-
|
64
|
-
after do
|
65
|
-
system_quiet("initctl stop #{subject.name}")
|
66
|
-
subject.files.each do |path, content|
|
67
|
-
File.unlink(path) if File.exist?(path)
|
68
|
-
end
|
69
|
-
|
70
|
-
# Remove the logs, too.
|
71
|
-
log = "/var/log/upstart/example.log"
|
72
|
-
File.unlink(log) if File.exist?(log)
|
73
|
-
end
|
74
|
-
|
75
|
-
it "should start" do
|
76
|
-
starts
|
77
|
-
|
78
|
-
# Starting an already-started job will fail
|
79
|
-
insist { starts }.fails
|
80
|
-
|
81
|
-
status_running
|
82
|
-
end
|
83
|
-
|
84
|
-
it "should stop" do
|
85
|
-
starts
|
86
|
-
stops
|
87
|
-
end
|
88
|
-
|
89
|
-
context "with failing prestart" do
|
90
|
-
before do
|
91
|
-
subject.prestart = "false"
|
92
|
-
activate(subject)
|
93
|
-
end
|
94
|
-
|
95
|
-
it "should fail to start" do
|
96
|
-
insist { starts }.fails
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
context "with successful prestart" do
|
101
|
-
before do
|
102
|
-
subject.prestart = "true"
|
103
|
-
activate(subject)
|
104
|
-
end
|
105
|
-
|
106
|
-
it "should start" do
|
107
|
-
starts
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end # as the super user
|
111
|
-
end # real tests
|
112
47
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "pleaserun/platform/base"
|
2
|
+
require "insist"
|
3
|
+
|
4
|
+
shared_examples_for PleaseRun::Platform do
|
5
|
+
it "inherits correctly" do
|
6
|
+
insist { described_class.ancestors }.include?(PleaseRun::Platform::Base)
|
7
|
+
end
|
8
|
+
|
9
|
+
context "activation" do
|
10
|
+
subject { described_class.new(version) }
|
11
|
+
|
12
|
+
before do
|
13
|
+
subject.name = "hurray-#{rand(1000)}"
|
14
|
+
subject.user = "root"
|
15
|
+
subject.program = "/bin/sh"
|
16
|
+
subject.args = ["-c", "echo hello world; sleep 5"]
|
17
|
+
activate(subject)
|
18
|
+
|
19
|
+
# Hack...
|
20
|
+
case described_class.name
|
21
|
+
when "PleaseRun::Platform::Systemd"
|
22
|
+
# monkeypatch StartLimitInterval=0 into the .service file to avoid
|
23
|
+
# being throttled by systemd during these tests.
|
24
|
+
# Fixes https://github.com/jordansissel/pleaserun/issues/11
|
25
|
+
path = "/lib/systemd/system/#{subject.name}.service"
|
26
|
+
File.write(path, File.read(path).sub(/^\[Service\]$/, "[Service]\nStartLimitInterval=0"))
|
27
|
+
when "PleaseRun::Platform::Launchd"
|
28
|
+
# Avoid being throttled during our tests.
|
29
|
+
path = subject.daemons_path
|
30
|
+
File.write(path, File.read(path).sub(/^<plist>$/, "<plist><key>ThrottleInterval</key><integer>0</integer>"))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
after do
|
35
|
+
system_quiet(stop)
|
36
|
+
case described_class.name
|
37
|
+
when "PleaseRun::Platform::Launchd"
|
38
|
+
system_quiet("launchctl unload #{subject.daemons_path}")
|
39
|
+
system_quiet("launchctl remove #{subject.name}")
|
40
|
+
end
|
41
|
+
subject.files.each do |path, content|
|
42
|
+
File.unlink(path) if File.exist?(path)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should start" do
|
47
|
+
starts
|
48
|
+
status_running
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should stop" do
|
52
|
+
starts
|
53
|
+
stops
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should start and stop", :flapper => true do
|
57
|
+
5.times do
|
58
|
+
starts
|
59
|
+
stops
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "with prestart", :prestart => true do
|
64
|
+
context "that is failing" do
|
65
|
+
before do
|
66
|
+
subject.prestart = "#!/bin/sh\nfalse\n"
|
67
|
+
activate(subject)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should fail to start" do
|
71
|
+
insist { starts }.fails
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "that succeeds" do
|
76
|
+
before do
|
77
|
+
subject.prestart = "true"
|
78
|
+
activate(subject)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should start" do
|
82
|
+
starts
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end # as the super user
|
87
|
+
end
|
data/spec/testenv.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "English" # for $CHILD_STATUS
|
2
2
|
require "pleaserun/namespace"
|
3
3
|
require "insist"
|
4
|
+
require "shared_examples"
|
4
5
|
|
5
6
|
def superuser?
|
6
7
|
return Process::UID.eid == 0
|
@@ -70,6 +71,20 @@ module Helpers
|
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
73
|
-
RSpec.configure do |
|
74
|
-
|
74
|
+
RSpec.configure do |config|
|
75
|
+
config.include Helpers
|
76
|
+
|
77
|
+
config.filter_run_excluding(
|
78
|
+
:systemd => !(superuser? && platform?("linux") && program?("systemctl") && File.directory?("/lib/systemd")),
|
79
|
+
:upstart => !(superuser? && platform?("linux") && program?("initctl") && File.directory?("/etc/init")),
|
80
|
+
:launchd => !(superuser? && platform?("darwin"))
|
81
|
+
)
|
82
|
+
|
83
|
+
if !config.exclusion_filter[:launchd]
|
84
|
+
# Skip prestart tests because launchd doesn't have such a feature.
|
85
|
+
config.filter_run_excluding(:prestart => true)
|
86
|
+
# Skip flapper tests because launchd's minimum restart-throttle is 5 seconds.
|
87
|
+
# I'm not waiting for that crap.
|
88
|
+
config.filter_run_excluding(:flapper => true)
|
89
|
+
end
|
75
90
|
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,39 @@
|
|
1
|
+
description "{{{ description }}}"
|
2
|
+
start on filesystem or runlevel [2345]
|
3
|
+
stop on runlevel [!2345]
|
4
|
+
|
5
|
+
respawn
|
6
|
+
umask {{{umask}}}
|
7
|
+
#nice {{{nice}}}
|
8
|
+
#chroot {{{chroot}}}
|
9
|
+
#chdir {{{chdir}}}
|
10
|
+
#limit core <softlimit> <hardlimit>
|
11
|
+
#limit cpu <softlimit> <hardlimit>
|
12
|
+
#limit data <softlimit> <hardlimit>
|
13
|
+
#limit fsize <softlimit> <hardlimit>
|
14
|
+
#limit memlock <softlimit> <hardlimit>
|
15
|
+
#limit msgqueue <softlimit> <hardlimit>
|
16
|
+
#limit nice <softlimit> <hardlimit>
|
17
|
+
#limit nofile <softlimit> <hardlimit>
|
18
|
+
#limit nproc <softlimit> <hardlimit>
|
19
|
+
#limit rss <softlimit> <hardlimit>
|
20
|
+
#limit rtprio <softlimit> <hardlimit>
|
21
|
+
#limit sigpending <softlimit> <hardlimit>
|
22
|
+
#limit stack <softlimit> <hardlimit>
|
23
|
+
|
24
|
+
{{#prestart}}
|
25
|
+
pre-start script
|
26
|
+
{{{ prestart }}}
|
27
|
+
|
28
|
+
status=$?
|
29
|
+
if [ "$status" -gt 0 ] ; then
|
30
|
+
echo "Prestart command failed with code $status."
|
31
|
+
|
32
|
+
# Per init(5) docs, simply calling 'stop' will abort this start.
|
33
|
+
stop
|
34
|
+
fi
|
35
|
+
end script
|
36
|
+
{{/prestart}}
|
37
|
+
|
38
|
+
{{! TODO(sissel): Support logging }}
|
39
|
+
exec chroot --userspec {{{user}}}:{{{group}}} {{{chroot}}} {{{program}}} {{{shell_args}}}
|
data/test/helpers.rb
CHANGED
@@ -9,7 +9,11 @@ def test_in_container(tag, commands, outfile, errfile)
|
|
9
9
|
insist { $? }.success?
|
10
10
|
|
11
11
|
commands.each do |command|
|
12
|
-
|
12
|
+
cmd = "cd #{chdir}; vagrant ssh #{tag} -- bash -l >> #{outfile} 2>> #{errfile}"
|
13
|
+
IO.popen(cmd, "w") do |io|
|
14
|
+
io.puts(". /etc/profile")
|
15
|
+
io.puts(". ./.bashrc")
|
16
|
+
io.puts(". ./.bash_profile")
|
13
17
|
io.puts(command)
|
14
18
|
io.puts("exit $?")
|
15
19
|
io.close_write
|
data/test/test.rb
CHANGED
@@ -22,8 +22,12 @@ ARGV.each do |tag|
|
|
22
22
|
err = Stud::Temporary.pathname
|
23
23
|
begin
|
24
24
|
status = test_in_container(tag, [
|
25
|
-
|
26
|
-
"
|
25
|
+
# TODO(sissel): Test other ruby versions
|
26
|
+
"cd /pleaserun; rvm use 1.9.3; bundle install",
|
27
|
+
|
28
|
+
# Run rspec as root to make pleaserun's real deployment tests run.
|
29
|
+
"cd /pleaserun; rvm use 1.9.3; sudo -E `which ruby` `which rspec` --format json",
|
30
|
+
#"cd /pleaserun; rvm use 1.9.3; rspec --format json",
|
27
31
|
], out, err)
|
28
32
|
rescue Insist::Failure
|
29
33
|
status = false
|
@@ -36,11 +40,9 @@ results = ARGV.collect { tag, success, out, err = queue.pop }
|
|
36
40
|
successes = results.count { |tag, success, out, err| success }
|
37
41
|
failures = results.count { |tag, success, out, err| !success }
|
38
42
|
tests = results.collect { |tag, success, out, err|
|
39
|
-
#require "pry"
|
40
|
-
#binding.pry
|
41
43
|
begin
|
42
44
|
JSON.parse(File.read(out).split("\n").last[/{.*$/])["examples"].each { |r| r["tag"] = tag }
|
43
|
-
rescue TypeError
|
45
|
+
rescue TypeError, NoMethodError
|
44
46
|
puts "Failed to parse json"
|
45
47
|
puts :out => File.read(out)
|
46
48
|
puts :err => File.read(err)
|
data/test/vagrant/Vagrantfile
CHANGED
@@ -36,5 +36,26 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|
36
36
|
c.vm.box_url = "http://puppet-vagrant-boxes.puppetlabs.com/fedora-18-x64-vbox4210-nocm.box"
|
37
37
|
c.vm.provider "virtualbox"
|
38
38
|
c.vm.provision "shell", :path => "fedora-18/provision.sh"
|
39
|
+
c.vm.network :forwarded_port, guest: 22, host: 2223
|
40
|
+
c.vm.provider :virtualbox do |vb|
|
41
|
+
vb.customize ["modifyvm", :id, "--cpus", "4"]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Centos
|
46
|
+
# I would use docker, but I can't figure out how to get centos 6 w/ upstart working and there
|
47
|
+
# are plenty of quality CentOS vagrant boxes around :)
|
48
|
+
config.vm.define "centos-6.5" do |c|
|
49
|
+
c.vm.box = "centos-6.5"
|
50
|
+
c.vm.box_url = "http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-puppet.box"
|
51
|
+
c.vm.provider "virtualbox"
|
52
|
+
c.vm.provision "shell", :path => "fedora-18/provision.sh"
|
53
|
+
end
|
54
|
+
|
55
|
+
# Solaris/Illumos/OmniOS
|
56
|
+
config.vm.define "omnios" do |c|
|
57
|
+
c.vm.box = "omnios"
|
58
|
+
c.vm.box_url = "http://omnios.omniti.com/media/omnios-latest.box"
|
59
|
+
c.vm.provider "virtualbox"
|
39
60
|
end
|
40
61
|
end
|
@@ -1,10 +1,20 @@
|
|
1
1
|
#!/bin/bash
|
2
2
|
|
3
|
-
|
3
|
+
# Make sure we install rvm as the vagrant user because I generally want
|
4
|
+
# to test things as non-root. I'll escalate with sudo if I need privileges.
|
5
|
+
[ `whoami` != "vagrant" ] && exec chroot --userspec=vagrant / bash -l "$0" "$@"
|
4
6
|
|
5
7
|
export USER=`whoami`
|
6
8
|
export HOME=/home/vagrant
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
+
case $USER in
|
11
|
+
root)
|
12
|
+
[ ! -f "/etc/profile.d/rvm.sh" ] && curl -sSL https://get.rvm.io | bash -s stable
|
13
|
+
. ". /etc/profile.d/rvm.sh"
|
14
|
+
;;
|
15
|
+
*)
|
16
|
+
[ ! -f "$HOME/.rvm/scripts/rvm" ] && curl -sSL https://get.rvm.io | bash -s stable
|
17
|
+
. "$HOME/.rvm/scripts/rvm"
|
18
|
+
;;
|
19
|
+
esac
|
10
20
|
rvm list | grep -q 'No rvm rubies' && rvm install 1.9.3
|
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.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Sissel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cabin
|
@@ -130,6 +130,8 @@ files:
|
|
130
130
|
- lib/pleaserun/cli.rb
|
131
131
|
- lib/pleaserun/configurable.rb
|
132
132
|
- lib/pleaserun/detector.rb
|
133
|
+
- lib/pleaserun/errors.rb
|
134
|
+
- lib/pleaserun/installer.rb
|
133
135
|
- lib/pleaserun/mustache_methods.rb
|
134
136
|
- lib/pleaserun/namespace.rb
|
135
137
|
- lib/pleaserun/platform/base.rb
|
@@ -146,14 +148,16 @@ files:
|
|
146
148
|
- spec/pleaserun/platform/systemd_spec.rb
|
147
149
|
- spec/pleaserun/platform/sysv_spec.rb
|
148
150
|
- spec/pleaserun/platform/upstart_spec.rb
|
151
|
+
- spec/shared_examples.rb
|
149
152
|
- spec/testenv.rb
|
150
|
-
- templates/launchd/
|
153
|
+
- templates/launchd/default/program.plist
|
151
154
|
- templates/runit/log
|
152
155
|
- templates/runit/run
|
153
156
|
- templates/systemd/default/prestart.sh
|
154
157
|
- templates/systemd/default/program.service
|
155
158
|
- templates/sysv/lsb-3.1/default
|
156
|
-
- templates/sysv/lsb-3.1/init.
|
159
|
+
- templates/sysv/lsb-3.1/init.sh
|
160
|
+
- templates/upstart/0.6.5/init.conf
|
157
161
|
- templates/upstart/1.5/init.conf
|
158
162
|
- templates/upstart/1.5/init.d.sh
|
159
163
|
- test.rb
|