upstart-exporter 2.1.2 → 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/Gemfile +2 -2
- data/README.md +53 -31
- data/lib/upstart-exporter.rb +21 -6
- data/lib/upstart-exporter/expanded_exporter.rb +25 -27
- data/lib/upstart-exporter/hash_utils.rb +22 -0
- data/lib/upstart-exporter/options/command_line.rb +9 -6
- data/lib/upstart-exporter/options/global.rb +14 -9
- data/lib/upstart-exporter/options/validator.rb +78 -0
- data/lib/upstart-exporter/templates.rb +0 -6
- data/lib/upstart-exporter/version.rb +1 -1
- data/spec/lib/upstart-exporter/errors_spec.rb +2 -2
- data/spec/lib/upstart-exporter/expanded_exporter_spec.rb +48 -48
- data/spec/lib/upstart-exporter/options/command_line_spec.rb +16 -17
- data/spec/lib/upstart-exporter/options/global_spec.rb +6 -6
- data/spec/lib/upstart-exporter/options/validator_spec.rb +42 -0
- data/spec/lib/upstart-exporter/templates_spec.rb +5 -5
- data/spec/lib/upstart-exporter_spec.rb +44 -14
- metadata +35 -52
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: dee17e8ba6b4e4ab976d7ae3ecc16f171829c914
|
4
|
+
data.tar.gz: 732bf68bdcaded54a5daa625f93ebb1af8fdc7cf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f13d22de2f4d5e595be058ffefc448bd30514813114676c60e3ff44277432014d969d0f4065b36860e0460270b4fe796e325bbf418edd6795197cdfb83753d54
|
7
|
+
data.tar.gz: 708f2bab35e591f91697bd8512ab76a54c3cf9b8ccc878f81b68b6e4f15c81574cf756d345c9bcb655bb1481fd423ac3c0a45349c45141bf20dff976731a139c
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,16 +1,20 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
Safely generate Upstart jobs from Procfiles
|
2
|
+
===========================================
|
3
3
|
|
4
4
|
[](http://travis-ci.org/funbox/upstart-exporter)
|
5
5
|
|
6
6
|
Purpose
|
7
7
|
-------
|
8
8
|
|
9
|
-
It is often
|
9
|
+
It is often necessary to run some supporting background tasks for rails projects alongside with the web server.
|
10
|
+
One of the solutions is the use of Foreman gem, which allows exporting tasks as Upstart scripts.
|
11
|
+
This solution is dangerous, because it requires root privileges for foreman executable (in order to add scripts to `/etc/init`),
|
12
|
+
so it allows the exporting user to run any code as root (by placing appropriate script into `/etc/init`).
|
10
13
|
|
11
|
-
This gem is an attempt to provide a safe way for installing
|
14
|
+
This gem is an attempt to provide a safe way for installing background jobs, so that they run under some fixed user
|
15
|
+
without root privileges.
|
12
16
|
|
13
|
-
The only interface to the gem that should be used is the
|
17
|
+
The only interface to the gem that should be used is the `upstart-export` script it provides.
|
14
18
|
|
15
19
|
Installing
|
16
20
|
----------
|
@@ -21,14 +25,18 @@ Installing
|
|
21
25
|
Configuration
|
22
26
|
-------------
|
23
27
|
|
24
|
-
The export process is configured through the only config,
|
28
|
+
The export process is configured through the only config, `/etc/upstart-exporter.yaml`,
|
29
|
+
which is a simple YAML file of the following format:
|
25
30
|
|
26
31
|
---
|
27
32
|
run_user: www # The user under which all installed through upstart-exporter background jobs are run
|
28
33
|
run_group: www # The group of run_user
|
29
|
-
helper_dir: /var/helper_dir #
|
34
|
+
helper_dir: /var/helper_dir # Auxiliary directory for scripts incapsulating background jobs
|
30
35
|
upstart_dir: /var/upstart_dir # Directory where upstart scripts should be placed
|
31
36
|
prefix: 'myupstartjobs-' # Prefix added to app's log folders and upstart scripts
|
37
|
+
respawn: # Controls how often job can fail and be restarted, set to false to prohibit restart after failure
|
38
|
+
limit: 10 # Number of allowed restarts in given interval
|
39
|
+
interval: 10 # Interval in seconds
|
32
40
|
|
33
41
|
The config is not installed by default. If this config is absent, the default values are the following:
|
34
42
|
|
@@ -36,8 +44,11 @@ The config is not installed by default. If this config is absent, the default va
|
|
36
44
|
upstart_dir: /etc/init/
|
37
45
|
run_user: service
|
38
46
|
prefix: 'fb-'
|
47
|
+
respawn:
|
48
|
+
limit: 5
|
49
|
+
interval: 10
|
39
50
|
|
40
|
-
To give a certain user (i.e. deployuser) ability to use this script, you can place the following lines into sudoers file:
|
51
|
+
To give a certain user (i.e. `deployuser`) the ability to use this script, you can place the following lines into `sudoers` file:
|
41
52
|
|
42
53
|
# Commands required for manipulating jobs
|
43
54
|
Cmnd_Alias UPSTART = /sbin/start, /sbin/stop, /sbin/restart
|
@@ -57,19 +68,20 @@ To give a certain user (i.e. deployuser) ability to use this script, you can pla
|
|
57
68
|
Usage
|
58
69
|
-----
|
59
70
|
|
60
|
-
Gem is able to process two versions of
|
61
|
-
defined in the
|
71
|
+
Gem is able to process two versions of Procfiles, format of the Procfile is
|
72
|
+
defined in the `version` key. If the key is not present or is not equal to `2`
|
62
73
|
gem will try to parse it as Procfile v.1.
|
63
74
|
|
64
75
|
Procfile v.1
|
65
76
|
------------
|
66
77
|
|
67
|
-
After upstart-exporter is installed and configured, you may export background jobs
|
78
|
+
After upstart-exporter is installed and configured, you may export background jobs
|
79
|
+
from an arbitrary Procfile-like file of the following format:
|
68
80
|
|
69
81
|
cmdlabel1: cmd1
|
70
82
|
cmdlabel2: cmd2
|
71
83
|
|
72
|
-
i.e. a file
|
84
|
+
i.e. a file `./myprocfile` containing:
|
73
85
|
|
74
86
|
my_tail_cmd: /usr/bin/tail -F /var/log/messages
|
75
87
|
my_another_tail_cmd: /usr/bin/tail -F /var/log/messages
|
@@ -88,7 +100,7 @@ look like this:
|
|
88
100
|
env:
|
89
101
|
RAILS_ENV: production
|
90
102
|
TEST: true
|
91
|
-
working_directory: /srv/projects/
|
103
|
+
working_directory: /srv/projects/my_website/current
|
92
104
|
commands:
|
93
105
|
my_tail_cmd:
|
94
106
|
command: /usr/bin/tail -F /var/log/messages
|
@@ -100,58 +112,69 @@ look like this:
|
|
100
112
|
working_directory: '/var/...' # if needs to be redefined
|
101
113
|
my_another_tail_cmd:
|
102
114
|
command: /usr/bin/tail -F /var/log/messages
|
115
|
+
kill_timeout: 60
|
103
116
|
respawn: false # by default respawn option is enabled
|
104
117
|
my_one_another_tail_cmd:
|
105
118
|
command: /usr/bin/tail -F /var/log/messages
|
119
|
+
log: /var/log/messages_copy
|
106
120
|
my_multi_tail_cmd:
|
107
121
|
command: /usr/bin/tail -F /var/log/messages
|
108
122
|
count: 2
|
109
123
|
|
110
|
-
|
111
|
-
redefined. For more information on these options look into
|
124
|
+
`start_on_runlevel` and `stop_on_runlevel` are two global options that can't be
|
125
|
+
redefined. For more information on these options look into
|
126
|
+
[upstart scripts documentation](http://upstart.ubuntu.com/cookbook/#start-on).
|
112
127
|
|
113
|
-
|
128
|
+
`working_directory` will generate the following line:
|
114
129
|
|
115
130
|
cd 'your/working/directory' && your_command
|
116
131
|
|
117
|
-
|
118
|
-
you can't remove globally defined
|
119
|
-
For given earlier
|
132
|
+
`env` params can be redefined and extended in per-command options. Note that
|
133
|
+
you can't remove a globally defined `env` variable.
|
134
|
+
For Procfile example given earlier the generated command will look like:
|
120
135
|
|
121
136
|
env RAILS_ENV=staging TEST=true your_command
|
122
137
|
|
123
|
-
|
138
|
+
`log` option lets you override the default log location (`/var/log/fb-my_website/my_one_another_tail_cmd.log`).
|
139
|
+
|
140
|
+
`kill_timeout` option lets you override the default process kill timeout of 30 seconds.
|
141
|
+
|
142
|
+
`respawn` option controls restarting of scripts in case of their failure.
|
124
143
|
By default this option is enabled. For
|
125
|
-
more info look into [documentation](http://upstart.ubuntu.com/cookbook/#respawn)
|
144
|
+
more info look into [documentation](http://upstart.ubuntu.com/cookbook/#respawn).
|
126
145
|
|
127
|
-
|
128
|
-
often than
|
146
|
+
`respawn_limit` option controls how often the job can fail. If the job restarts more
|
147
|
+
often than `count` times in `interval`, it won't be restarted anymore. For more
|
129
148
|
info look into [documentation](http://upstart.ubuntu.com/cookbook/#respawn-limit).
|
130
149
|
|
131
|
-
Options
|
150
|
+
Options `working_directory`, `env`, `log`, `respawn` and `respawn_limit` can be
|
132
151
|
defined both as global and as per-command options.
|
133
152
|
|
134
153
|
Exporting
|
135
154
|
---------
|
136
155
|
|
137
|
-
To export Procfile you should run
|
156
|
+
To export a Procfile you should run
|
138
157
|
|
139
158
|
sudo upstart-export -p ./myprocfile -n myapp
|
140
159
|
|
141
|
-
where
|
160
|
+
where `myapp` is the application name.
|
161
|
+
This name only affects the names of generated files.
|
162
|
+
For security purposes, app name is also allowed to contain only letters, digits and underscores.
|
163
|
+
Assuming that default options are used, the following files and folders will be generated:
|
142
164
|
|
143
|
-
in
|
165
|
+
in `/etc/init/`:
|
144
166
|
|
145
167
|
fb-myapp-my_another_tail_cmd.conf
|
146
168
|
fb-myapp-my_tail_cmd.conf
|
147
169
|
fb-myapp.conf
|
148
170
|
|
149
|
-
in
|
171
|
+
in `/var/local/upstart_helpers/`:
|
150
172
|
|
151
173
|
fb-myapp-my_another_tail_cmd.sh
|
152
174
|
fb-myapp-my_tail_cmd.sh
|
153
175
|
|
154
|
-
Prefix
|
176
|
+
Prefix `fb-` (which can be customised through config) is added to avoid collisions with other upstart jobs.
|
177
|
+
After this `my_tail_cmd`, for example, will be able to be started as an Upstart job:
|
155
178
|
|
156
179
|
sudo start fb-myapp-my_tail_cmd
|
157
180
|
|
@@ -159,7 +182,7 @@ Prefix 'fb-' (which can be customised through config) is added to avoid collisio
|
|
159
182
|
|
160
183
|
sudo stop fb-myapp-my_tail_cmd
|
161
184
|
|
162
|
-
|
185
|
+
Its stdout/stderr will be redirected to `/var/log/fb-myapp/my_tail_cmd.log`.
|
163
186
|
|
164
187
|
To start/stop all application commands at once, you can run:
|
165
188
|
|
@@ -172,4 +195,3 @@ To remove upstart scripts and helpers for a particular application you can run
|
|
172
195
|
sudo upstart-export -c -n myapp
|
173
196
|
|
174
197
|
The logs are not cleared in this case. Also, all old application scripts are cleared before each export.
|
175
|
-
|
data/lib/upstart-exporter.rb
CHANGED
@@ -4,8 +4,10 @@ require 'upstart-exporter/errors'
|
|
4
4
|
require 'upstart-exporter/templates'
|
5
5
|
require 'upstart-exporter/exporter_helpers'
|
6
6
|
require 'upstart-exporter/expanded_exporter'
|
7
|
+
require 'upstart-exporter/hash_utils'
|
7
8
|
require 'upstart-exporter/options/global'
|
8
9
|
require 'upstart-exporter/options/command_line'
|
10
|
+
require 'upstart-exporter/options/validator'
|
9
11
|
|
10
12
|
module Upstart
|
11
13
|
class Exporter
|
@@ -17,17 +19,20 @@ module Upstart
|
|
17
19
|
def initialize(command_line_args)
|
18
20
|
global_options = Options::Global.new
|
19
21
|
command_line_options = Options::CommandLine.new(command_line_args)
|
22
|
+
|
20
23
|
@options = global_options.merge(command_line_options)
|
24
|
+
Upstart::Exporter::Options::Validator.new(@options).validate!
|
25
|
+
|
21
26
|
ensure_dirs
|
22
27
|
end
|
23
28
|
|
24
29
|
def export
|
25
30
|
clear
|
26
31
|
export_app
|
27
|
-
if options[:
|
32
|
+
if options[:procfile_commands][:version] && options[:procfile_commands][:version] == 2
|
28
33
|
ExpandedExporter.export(options)
|
29
34
|
else
|
30
|
-
options[:
|
35
|
+
options[:procfile_commands].each do |cmd_name, cmd|
|
31
36
|
export_command(cmd_name, cmd)
|
32
37
|
end
|
33
38
|
end
|
@@ -46,12 +51,12 @@ module Upstart
|
|
46
51
|
protected
|
47
52
|
|
48
53
|
def start_on_runlevel
|
49
|
-
lvl = options[:
|
54
|
+
lvl = options[:procfile_commands][:start_on_runlevel] || options[:start_on_runlevel]
|
50
55
|
"runlevel #{lvl}"
|
51
56
|
end
|
52
57
|
|
53
58
|
def stop_on_runlevel
|
54
|
-
lvl = options[:
|
59
|
+
lvl = options[:procfile_commands][:stop_on_runlevel] || options[:stop_on_runlevel]
|
55
60
|
"runlevel #{lvl}"
|
56
61
|
end
|
57
62
|
|
@@ -87,8 +92,8 @@ module Upstart
|
|
87
92
|
:app_name => app_name,
|
88
93
|
:start_on => "starting #{app_name}",
|
89
94
|
:stop_on => "stopping #{app_name}",
|
90
|
-
:respawn =>
|
91
|
-
:respawn_limit =>
|
95
|
+
:respawn => respawn,
|
96
|
+
:respawn_limit => respawn_limit,
|
92
97
|
:kill_timeout => options[:kill_timeout],
|
93
98
|
:run_user => options[:run_user],
|
94
99
|
:run_group => options[:run_group],
|
@@ -100,6 +105,16 @@ module Upstart
|
|
100
105
|
end
|
101
106
|
end
|
102
107
|
|
108
|
+
def respawn
|
109
|
+
options[:respawn] ? 'respawn' : ''
|
110
|
+
end
|
111
|
+
|
112
|
+
def respawn_limit
|
113
|
+
limits = options[:respawn]
|
114
|
+
return unless limits
|
115
|
+
"respawn limit #{limits[:count].to_i} #{limits[:interval].to_i}"
|
116
|
+
end
|
117
|
+
|
103
118
|
def export_command(cmd_name, cmd)
|
104
119
|
export_cmd_helper(cmd_name, cmd)
|
105
120
|
export_cmd_upstart_conf(cmd_name)
|
@@ -8,15 +8,15 @@ class Upstart::Exporter
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def initialize(options)
|
11
|
-
@config = options[:commands]
|
12
11
|
@options = options
|
13
|
-
@
|
14
|
-
@
|
12
|
+
@procfile_commands = options[:procfile_commands]
|
13
|
+
@commands = @procfile_commands[:commands]
|
14
|
+
@env = @procfile_commands[:env] || {}
|
15
15
|
end
|
16
16
|
|
17
17
|
def export
|
18
18
|
@commands.each do |command, cmd_options|
|
19
|
-
if count = cmd_options[
|
19
|
+
if count = cmd_options[:count]
|
20
20
|
count.times do |counter|
|
21
21
|
export_cmd("#{command}_#{counter}", cmd_options)
|
22
22
|
end
|
@@ -30,12 +30,12 @@ class Upstart::Exporter
|
|
30
30
|
|
31
31
|
def export_cmd(command, cmd_options)
|
32
32
|
cmd_options = {
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
:working_directory => working_directory(cmd_options),
|
34
|
+
:log => log(cmd_options),
|
35
|
+
:kill_timeout => kill_timeout(cmd_options)
|
36
36
|
}.merge(cmd_options)
|
37
37
|
|
38
|
-
script = cmd_options[
|
38
|
+
script = cmd_options[:command]
|
39
39
|
script = add_env_command(script, cmd_options)
|
40
40
|
script = add_dir_command(script, cmd_options)
|
41
41
|
script = add_log_command(script, cmd_options)
|
@@ -46,7 +46,7 @@ class Upstart::Exporter
|
|
46
46
|
|
47
47
|
def add_env_command(script, command)
|
48
48
|
vars = ''
|
49
|
-
env = @env.merge((command[
|
49
|
+
env = @env.merge((command[:env] || {}))
|
50
50
|
env.each do |var, val|
|
51
51
|
vars += "#{var}=#{val} "
|
52
52
|
end
|
@@ -58,7 +58,7 @@ class Upstart::Exporter
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def add_dir_command(script, command)
|
61
|
-
dir = command[
|
61
|
+
dir = command[:working_directory]
|
62
62
|
if dir.empty?
|
63
63
|
script
|
64
64
|
else
|
@@ -67,7 +67,7 @@ class Upstart::Exporter
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def add_log_command(script, command)
|
70
|
-
log = command[
|
70
|
+
log = command[:log]
|
71
71
|
if log.empty?
|
72
72
|
script
|
73
73
|
else
|
@@ -75,24 +75,14 @@ class Upstart::Exporter
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
-
def respawn_options(cmd_options)
|
79
|
-
if cmd_options.has_key?('respawn')
|
80
|
-
cmd_options['respawn']
|
81
|
-
elsif @config.has_key?('respawn')
|
82
|
-
@config['respawn']
|
83
|
-
else
|
84
|
-
{}
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
78
|
def respawn(cmd_options)
|
89
79
|
respawn_options(cmd_options) ? 'respawn' : ''
|
90
80
|
end
|
91
81
|
|
92
82
|
def respawn_limit(cmd_options)
|
93
83
|
limits = respawn_options(cmd_options)
|
94
|
-
return '' unless limits && limits[
|
95
|
-
"respawn limit #{limits[
|
84
|
+
return '' unless limits && limits[:count] && limits[:interval]
|
85
|
+
"respawn limit #{limits[:count].to_i} #{limits[:interval].to_i}"
|
96
86
|
end
|
97
87
|
|
98
88
|
def start_on
|
@@ -103,16 +93,20 @@ class Upstart::Exporter
|
|
103
93
|
"stopping #{app_name}"
|
104
94
|
end
|
105
95
|
|
96
|
+
def respawn_options(cmd_options)
|
97
|
+
command_option(cmd_options, :respawn)
|
98
|
+
end
|
99
|
+
|
106
100
|
def working_directory(cmd_options)
|
107
|
-
command_option(cmd_options,
|
101
|
+
command_option(cmd_options, :working_directory)
|
108
102
|
end
|
109
103
|
|
110
104
|
def log(cmd_options)
|
111
|
-
command_option(cmd_options,
|
105
|
+
command_option(cmd_options, :log)
|
112
106
|
end
|
113
107
|
|
114
108
|
def kill_timeout(cmd_options)
|
115
|
-
command_option(cmd_options,
|
109
|
+
command_option(cmd_options, :kill_timeout)
|
116
110
|
end
|
117
111
|
|
118
112
|
def export_cmd_upstart_conf(cmd_name, cmd_options)
|
@@ -136,7 +130,11 @@ class Upstart::Exporter
|
|
136
130
|
private
|
137
131
|
|
138
132
|
def command_option(cmd_options, key)
|
139
|
-
cmd_options[key
|
133
|
+
extract_options(cmd_options[key], @procfile_commands[key], @options[key], '')
|
134
|
+
end
|
135
|
+
|
136
|
+
def extract_options(*array)
|
137
|
+
array.find { |v| !v.nil? }
|
140
138
|
end
|
141
139
|
end
|
142
140
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Upstart
|
2
|
+
class Exporter
|
3
|
+
class HashUtils
|
4
|
+
|
5
|
+
def self.symbolize_keys(obj)
|
6
|
+
case obj
|
7
|
+
when Hash
|
8
|
+
Hash[
|
9
|
+
obj.map do |key, value|
|
10
|
+
[key.respond_to?(:to_sym) ? key.to_sym : key, symbolize_keys(value)]
|
11
|
+
end
|
12
|
+
]
|
13
|
+
when Array
|
14
|
+
obj.map {|value| symbolize_keys(value)}
|
15
|
+
else
|
16
|
+
obj
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -4,11 +4,11 @@ module Upstart::Exporter::Options
|
|
4
4
|
|
5
5
|
def initialize(command_line_args)
|
6
6
|
super
|
7
|
-
self[:
|
7
|
+
self[:procfile_commands] = if command_line_args[:clear]
|
8
8
|
{}
|
9
|
-
|
9
|
+
else
|
10
10
|
process_procfile(command_line_args[:procfile])
|
11
|
-
|
11
|
+
end
|
12
12
|
self[:app_name] = process_appname(command_line_args[:app_name])
|
13
13
|
end
|
14
14
|
|
@@ -32,9 +32,12 @@ module Upstart::Exporter::Options
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
if commands['version'] && commands['version'].strip == '2'
|
35
|
-
commands = YAML.load(content)
|
36
|
-
error('procfile should include "commands" key') unless commands[
|
37
|
-
|
35
|
+
commands = Upstart::Exporter::HashUtils::symbolize_keys(YAML.load(content))
|
36
|
+
error('procfile should include "commands" key') unless commands[:commands]
|
37
|
+
|
38
|
+
if invalid_name = commands[:commands].keys.find {|k| k.to_s !~ /\A[A-z\d_]*?\z/}
|
39
|
+
error("command name #{invalid_name} should include only letters and/or underscores")
|
40
|
+
end
|
38
41
|
end
|
39
42
|
commands
|
40
43
|
end
|
@@ -3,14 +3,18 @@ module Upstart::Exporter::Options
|
|
3
3
|
include Upstart::Exporter::Errors
|
4
4
|
|
5
5
|
DEFAULTS = {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
:helper_dir => '/var/local/upstart_helpers/',
|
7
|
+
:upstart_dir => '/etc/init/',
|
8
|
+
:run_user => 'service',
|
9
|
+
:run_group => 'service',
|
10
|
+
:prefix => 'fb-',
|
11
|
+
:start_on_runlevel => '[3]',
|
12
|
+
:stop_on_runlevel => '[3]',
|
13
|
+
:kill_timeout => 30,
|
14
|
+
:respawn => {
|
15
|
+
:count => 5,
|
16
|
+
:interval => 10
|
17
|
+
}
|
14
18
|
}
|
15
19
|
|
16
20
|
CONF = '/etc/upstart-exporter.yaml'
|
@@ -18,11 +22,12 @@ module Upstart::Exporter::Options
|
|
18
22
|
def initialize
|
19
23
|
super
|
20
24
|
config = if FileTest.file?(CONF)
|
21
|
-
YAML::load(File.read(CONF))
|
25
|
+
Upstart::Exporter::HashUtils.symbolize_keys(YAML::load(File.read(CONF)))
|
22
26
|
else
|
23
27
|
$stderr.puts "#{CONF} not found"
|
24
28
|
{}
|
25
29
|
end
|
30
|
+
|
26
31
|
error "#{CONF} is not a valid YAML config" unless config.is_a?(Hash)
|
27
32
|
DEFAULTS.keys.each do |param|
|
28
33
|
value = if config[param]
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Upstart::Exporter::Options
|
2
|
+
class Validator
|
3
|
+
|
4
|
+
include Upstart::Exporter::Errors
|
5
|
+
|
6
|
+
attr_reader :options
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate!
|
13
|
+
validate_path(options[:helper_dir])
|
14
|
+
validate_path(options[:upstart_dir])
|
15
|
+
|
16
|
+
reject_special_symbols(options[:run_user])
|
17
|
+
reject_special_symbols(options[:run_group])
|
18
|
+
reject_special_symbols(options[:prefix])
|
19
|
+
|
20
|
+
validate_runlevel(options[:start_on_runlevel])
|
21
|
+
validate_runlevel(options[:stop_on_runlevel])
|
22
|
+
|
23
|
+
validate_digits(options[:kill_timeout])
|
24
|
+
|
25
|
+
validate_respawn(options[:respawn])
|
26
|
+
|
27
|
+
if options[:procfile_commands][:version] == 2
|
28
|
+
validate_procfile_v2(options[:procfile_commands])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def validate_procfile_v2(config)
|
35
|
+
validate_command_params(config)
|
36
|
+
config[:commands].values.each {|cmd| validate_command_params(cmd)}
|
37
|
+
end
|
38
|
+
|
39
|
+
def validate_command_params(cmd)
|
40
|
+
validate_runlevel(cmd[:start_on_runlevel])
|
41
|
+
validate_runlevel(cmd[:stop_on_runlevel])
|
42
|
+
validate_path(cmd[:working_directory])
|
43
|
+
validate_respawn(cmd[:respawn])
|
44
|
+
end
|
45
|
+
|
46
|
+
def validate_respawn(options)
|
47
|
+
return unless options
|
48
|
+
validate_digits(options[:kill_timeout])
|
49
|
+
validate_digits(options[:interval])
|
50
|
+
end
|
51
|
+
|
52
|
+
def validate_path(val)
|
53
|
+
validate(val, /\A[A-Za-z0-9_\-.\/]+\z/)
|
54
|
+
end
|
55
|
+
|
56
|
+
def reject_special_symbols(val)
|
57
|
+
validate(val, /\A[A-Za-z0-9_\-]+\z/)
|
58
|
+
end
|
59
|
+
|
60
|
+
def validate_runlevel(val)
|
61
|
+
validate(val, /\A\[\d+\]\z/)
|
62
|
+
end
|
63
|
+
|
64
|
+
def validate_digits(val)
|
65
|
+
validate(val, /\A\d+\z/)
|
66
|
+
end
|
67
|
+
|
68
|
+
def validate(val, regexp)
|
69
|
+
val = val.to_s
|
70
|
+
return if val == ""
|
71
|
+
|
72
|
+
unless val =~ regexp
|
73
|
+
error("value #{val} is insecure and can't be accepted")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -8,16 +8,10 @@ module Upstart
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.app(binds)
|
11
|
-
if error_val = binds.find { |v| v =~ /\A[A-z0-9_\- ]*?\z/ }
|
12
|
-
error("value #{error_val} is insecure and can't be accepted")
|
13
|
-
end
|
14
11
|
interpolate(APP_TPL, binds)
|
15
12
|
end
|
16
13
|
|
17
14
|
def self.command(binds)
|
18
|
-
if error_val = binds.find { |v| v =~ /\A[A-z0-9_\- ]*?\z/ }
|
19
|
-
error("value #{error_val} is insecure and can't be accepted")
|
20
|
-
end
|
21
15
|
interpolate(COMMAND_TPL, binds)
|
22
16
|
end
|
23
17
|
|
@@ -7,7 +7,7 @@ describe Upstart::Exporter::Errors do
|
|
7
7
|
include Upstart::Exporter::Errors
|
8
8
|
end
|
9
9
|
|
10
|
-
Foo.new.
|
10
|
+
expect(Foo.new).to respond_to(:error)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -17,7 +17,7 @@ describe Upstart::Exporter::Errors do
|
|
17
17
|
include Upstart::Exporter::Errors
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
expect{ Foo.new.error("arrgh") }.to raise_exception(Upstart::Exporter::Error)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -7,21 +7,21 @@ describe Upstart::Exporter::ExpandedExporter do
|
|
7
7
|
@defaults[key.to_sym] = value
|
8
8
|
end
|
9
9
|
|
10
|
-
File.
|
10
|
+
allow(File).to receive(:open)
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'calls template render exact amount of times' do
|
14
|
-
Upstart::Exporter::Templates.
|
14
|
+
expect(Upstart::Exporter::Templates).to receive(:command).exactly(5).times
|
15
15
|
options = {
|
16
|
-
:
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
:procfile_commands => {
|
17
|
+
:commands => {
|
18
|
+
:ls => {
|
19
|
+
:command => 'ls',
|
20
|
+
:count => 3
|
21
21
|
},
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
:ls2 => {
|
23
|
+
:command => 'ls',
|
24
|
+
:count => 2
|
25
25
|
}
|
26
26
|
}
|
27
27
|
},
|
@@ -32,21 +32,21 @@ describe Upstart::Exporter::ExpandedExporter do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'merges env params in the right order' do
|
35
|
-
Upstart::Exporter::Templates.
|
36
|
-
options[:cmd].
|
37
|
-
options[:cmd].
|
35
|
+
expect(Upstart::Exporter::Templates).to receive(:helper) do |options|
|
36
|
+
expect(options[:cmd]).to include('B=b')
|
37
|
+
expect(options[:cmd]).to include('T=t')
|
38
38
|
end
|
39
39
|
options = {
|
40
|
-
:
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
:procfile_commands => {
|
41
|
+
:env => {
|
42
|
+
:T => 't',
|
43
|
+
:B => 'a'
|
44
44
|
},
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
:commands => {
|
46
|
+
:ls => {
|
47
|
+
:command => 'ls',
|
48
|
+
:env => {
|
49
|
+
:B => 'b'
|
50
50
|
}
|
51
51
|
}
|
52
52
|
}
|
@@ -63,38 +63,38 @@ describe Upstart::Exporter::ExpandedExporter do
|
|
63
63
|
:app_name => 'appname',
|
64
64
|
:working_directory => "/",
|
65
65
|
:log => "public.log",
|
66
|
-
:
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
66
|
+
:procfile_commands => {
|
67
|
+
:working_directory => '/var/log',
|
68
|
+
:commands => {
|
69
|
+
:rm1 => {
|
70
|
+
:command => 'rm *',
|
71
|
+
:log => 'private.log'
|
72
72
|
},
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
:rm2 => {
|
74
|
+
:command => 'rm -rf *',
|
75
|
+
:working_directory => '/home'
|
76
76
|
},
|
77
|
-
|
78
|
-
|
77
|
+
:rm3 => {
|
78
|
+
:command => 'rm -f vmlinuz',
|
79
79
|
}
|
80
80
|
}
|
81
81
|
}
|
82
82
|
}.merge(@defaults)
|
83
|
-
Upstart::Exporter::Templates.
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
Upstart::Exporter::Templates.
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
Upstart::Exporter::Templates.
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
83
|
+
expect(Upstart::Exporter::Templates).to receive(:helper).with(hash_including(
|
84
|
+
:working_directory => "/var/log",
|
85
|
+
:log => "private.log",
|
86
|
+
:cmd=> "cd '/var/log' && exec rm * >> private.log 2>&1"
|
87
|
+
))
|
88
|
+
expect(Upstart::Exporter::Templates).to receive(:helper).with(hash_including(
|
89
|
+
:working_directory =>"/home",
|
90
|
+
:log => "public.log",
|
91
|
+
:cmd => "cd '/home' && exec rm -rf * >> public.log 2>&1"
|
92
|
+
))
|
93
|
+
expect(Upstart::Exporter::Templates).to receive(:helper).with(hash_including(
|
94
|
+
:working_directory =>"/var/log",
|
95
|
+
:log => "public.log",
|
96
|
+
:cmd => "cd '/var/log' && exec rm -f vmlinuz >> public.log 2>&1"
|
97
|
+
))
|
98
98
|
described_class.export(options)
|
99
99
|
end
|
100
100
|
end
|
@@ -4,68 +4,67 @@ describe Upstart::Exporter::Options::CommandLine do
|
|
4
4
|
context "when correct options are given" do
|
5
5
|
it "should give access to options like a hash" do
|
6
6
|
make_procfile('Procfile', 'ls_cmd: ls')
|
7
|
-
described_class.new(:app_name => 'someappname', :procfile => 'Procfile').
|
7
|
+
expect(described_class.new(:app_name => 'someappname', :procfile => 'Procfile')).to respond_to('[]')
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should parse procfile" do
|
11
11
|
make_procfile('Procfile', 'ls_cmd: ls')
|
12
12
|
options = described_class.new(:app_name => 'someappname', :procfile => 'Procfile')
|
13
|
-
options[:
|
13
|
+
expect(options[:procfile_commands]).to eq({'ls_cmd' => ' ls'})
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should parse procfile v2' do
|
17
17
|
make_procfile('Procfile', "version: 2\ncommands:\n ls:\n command: ls -al")
|
18
18
|
options = described_class.new(:app_name => 'someappname', :procfile => 'Procfile')
|
19
|
-
options[:
|
20
|
-
options[:
|
19
|
+
expect(options[:procfile_commands]).to have_key(:commands)
|
20
|
+
expect(options[:procfile_commands][:commands]).to have_key(:ls)
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should skip empty and commented lines in a procfile" do
|
24
24
|
make_procfile('Procfile', "ls_cmd1: ls1\n\nls_cmd2: ls2\n # fooo baaar")
|
25
25
|
options = described_class.new(:app_name => 'someappname', :procfile => 'Procfile')
|
26
|
-
options[:
|
26
|
+
expect(options[:procfile_commands]).to eq({'ls_cmd1' => ' ls1', 'ls_cmd2' => ' ls2'})
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should store app_name" do
|
30
30
|
make_procfile('Procfile', "ls_cmd1: ls1\n\nls_cmd2: ls2\n # fooo baaar")
|
31
31
|
options = described_class.new(:app_name => 'someappname', :procfile => 'Procfile')
|
32
|
-
options[:app_name].
|
32
|
+
expect(options[:app_name]).to eq('someappname')
|
33
33
|
end
|
34
34
|
|
35
35
|
it "should not process procfile if :clear arg is present" do
|
36
36
|
make_procfile('Procfile', "bad procfile")
|
37
37
|
options = described_class.new(:app_name => 'someappname', :procfile => 'Procfile', :clear => true)
|
38
|
-
options[:app_name].
|
39
|
-
options[:
|
38
|
+
expect(options[:app_name]).to eq('someappname')
|
39
|
+
expect(options[:procfile_commands]).to eq({})
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
context "when bad app_name is passed" do
|
44
44
|
it "should raise exception" do
|
45
45
|
make_procfile('Procfile', 'ls_cmd: ls')
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
expect{ described_class.new(:app_name => 'some appname', :procfile => 'Procfile') }.to raise_exception
|
47
|
+
expect{ described_class.new(:app_name => '-someappname', :procfile => 'Procfile') }.to raise_exception
|
48
|
+
expect{ described_class.new(:procfile => 'Procfile') }.to raise_exception
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
52
|
context "when bad Procfile is passed" do
|
53
53
|
it "should raise exception" do
|
54
54
|
make_procfile('Procfile', 'ls cmd: ls')
|
55
|
-
|
55
|
+
expect{ described_class.new(:app_name => 'someappname', :procfile => 'Procfile') }.to raise_exception
|
56
56
|
|
57
57
|
make_procfile('Procfile', '-lscmd: ls')
|
58
|
-
|
58
|
+
expect{ described_class.new(:app_name => 'someappname', :procfile => 'Procfile') }.to raise_exception
|
59
59
|
|
60
|
-
|
60
|
+
expect{ described_class.new(:app_name => 'someappname', :procfile => '::') }.to raise_exception
|
61
61
|
|
62
62
|
make_procfile('Procfile', "version: 2\ncommands:\n ls cmd:\n command: ls")
|
63
|
-
|
63
|
+
expect{ described_class.new(:app_name => 'someappname', :procfile => 'Procfile') }.to raise_exception
|
64
64
|
|
65
|
-
|
65
|
+
expect{ described_class.new(:app_name => 'someappname') }.to raise_exception
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
|
70
69
|
end
|
71
70
|
|
@@ -7,7 +7,7 @@ describe Upstart::Exporter::Options::Global do
|
|
7
7
|
|
8
8
|
it "should give access to options like a hash" do
|
9
9
|
capture(:stderr) do
|
10
|
-
described_class.new.
|
10
|
+
expect(described_class.new).to respond_to('[]')
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -17,7 +17,7 @@ describe Upstart::Exporter::Options::Global do
|
|
17
17
|
capture(:stderr) do
|
18
18
|
options = described_class.new
|
19
19
|
defaults.each do |option, default_value|
|
20
|
-
options[option.to_sym].
|
20
|
+
expect(options[option.to_sym]).to eq(default_value)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -27,9 +27,9 @@ describe Upstart::Exporter::Options::Global do
|
|
27
27
|
context "when invalid config is given" do
|
28
28
|
it "should raise exception" do
|
29
29
|
make_global_config('zxc')
|
30
|
-
|
30
|
+
expect{described_class.new}.to raise_exception
|
31
31
|
make_global_config([123].to_yaml)
|
32
|
-
|
32
|
+
expect{described_class.new}.to raise_exception
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -37,14 +37,14 @@ describe Upstart::Exporter::Options::Global do
|
|
37
37
|
it "should override default values" do
|
38
38
|
capture(:stderr) do
|
39
39
|
make_global_config({'run_user' => 'wwwww'}.to_yaml)
|
40
|
-
described_class.new[:run_user].
|
40
|
+
expect(described_class.new[:run_user]).to eq('wwwww')
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should preserve default values for options not specified in the config" do
|
45
45
|
capture(:stderr) do
|
46
46
|
make_global_config({'run_user' => 'wwwww'}.to_yaml)
|
47
|
-
described_class.new[:prefix] == defaults[
|
47
|
+
described_class.new[:prefix] == defaults[:prefix]
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Upstart::Exporter::Options::Validator do
|
4
|
+
|
5
|
+
it "validates paths" do
|
6
|
+
validator = described_class.new(:helper_dir => "/some/dir;")
|
7
|
+
expect {validator.validate!}.to raise_error(Upstart::Exporter::Error)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "validates user names" do
|
11
|
+
validator = described_class.new(:run_user => "bad_user_name!")
|
12
|
+
expect {validator.validate!}.to raise_error(Upstart::Exporter::Error)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "validates runlevels" do
|
16
|
+
validator = described_class.new(:start_on_runlevel => "[not_a_digit]")
|
17
|
+
expect {validator.validate!}.to raise_error(Upstart::Exporter::Error)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "procfile v2" do
|
21
|
+
it "validates respawn" do
|
22
|
+
options = {:procfile_commands => {:version => 2, :respawn => {:kill_timeout => "10;"}}}
|
23
|
+
validator = described_class.new(options)
|
24
|
+
expect {validator.validate!}.to raise_error(Upstart::Exporter::Error)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "validates options for individual commands" do
|
28
|
+
options = {
|
29
|
+
:procfile_commands => {:version => 2,
|
30
|
+
:commands => {
|
31
|
+
:come_cmd => {
|
32
|
+
:working_directory => "!!!wrong_working-directory"
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
validator = described_class.new(options)
|
38
|
+
expect {validator.validate!}.to raise_error(Upstart::Exporter::Error)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -20,13 +20,13 @@ EOF
|
|
20
20
|
end script
|
21
21
|
HEREDOC
|
22
22
|
|
23
|
-
described_class.app(
|
23
|
+
expect(described_class.app(
|
24
24
|
:run_user => 'SOMEUSER',
|
25
25
|
:run_group => 'SOMEGROUP',
|
26
26
|
:app_name => 'SOMEAPP',
|
27
27
|
:start_on => '12',
|
28
28
|
:stop_on => '13'
|
29
|
-
).
|
29
|
+
)).to eq(conf)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -41,7 +41,7 @@ HEREDOC
|
|
41
41
|
SOME COMMAND
|
42
42
|
HEREDOC
|
43
43
|
|
44
|
-
described_class.helper('cmd' => 'SOME COMMAND').
|
44
|
+
expect(described_class.helper('cmd' => 'SOME COMMAND')).to eq(conf)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -65,7 +65,7 @@ script
|
|
65
65
|
end script
|
66
66
|
HEREDOC
|
67
67
|
|
68
|
-
described_class.command(:run_user => 'SOMEUSER',
|
68
|
+
expect(described_class.command(:run_user => 'SOMEUSER',
|
69
69
|
:run_group => 'SOMEGROUP',
|
70
70
|
:app_name => 'SOMEAPP',
|
71
71
|
:cmd_name => 'SOMECMD',
|
@@ -74,7 +74,7 @@ HEREDOC
|
|
74
74
|
:start_on => 'starting SOMEAPP',
|
75
75
|
:stop_on => 'stopping SOMEAPP',
|
76
76
|
:kill_timeout => 24,
|
77
|
-
:helper_cmd_conf => 'HELPERPATH').
|
77
|
+
:helper_cmd_conf => 'HELPERPATH')).to eq(conf)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
@@ -10,7 +10,11 @@ describe Upstart::Exporter do
|
|
10
10
|
'run_user' => 'u',
|
11
11
|
'run_group' => 'g',
|
12
12
|
'prefix' => 'p-',
|
13
|
-
'start_on_runlevel' => '[7]'
|
13
|
+
'start_on_runlevel' => '[7]',
|
14
|
+
'respawn' => {
|
15
|
+
'count' => 7,
|
16
|
+
'interval' => 14
|
17
|
+
}
|
14
18
|
}.to_yaml)
|
15
19
|
make_procfile('Procfile', 'ls_cmd: ls')
|
16
20
|
end
|
@@ -19,52 +23,78 @@ describe Upstart::Exporter do
|
|
19
23
|
exporter = described_class.new({:app_name => 'app', :procfile => 'Procfile'})
|
20
24
|
end
|
21
25
|
|
26
|
+
describe '#export v2' do
|
27
|
+
it 'should correctly set respawn option' do
|
28
|
+
|
29
|
+
yaml = <<-eos
|
30
|
+
version: 2
|
31
|
+
commands:
|
32
|
+
first_cmd:
|
33
|
+
command: ping 127.0.0.1
|
34
|
+
respawn:
|
35
|
+
count: 9
|
36
|
+
interval: 19
|
37
|
+
second_cmd:
|
38
|
+
command: ping 127.0.0.1
|
39
|
+
respawn: false
|
40
|
+
third_cmd:
|
41
|
+
command: ping 127.0.0.1
|
42
|
+
eos
|
43
|
+
make_procfile('Procfile', yaml)
|
44
|
+
|
45
|
+
exporter.export
|
46
|
+
expect(File.read('/u/p-app-first_cmd.conf')).to include("respawn\nrespawn limit 9 19")
|
47
|
+
expect(File.read('/u/p-app-second_cmd.conf')).not_to include("respawn")
|
48
|
+
expect(File.read('/u/p-app-third_cmd.conf')).to include("respawn\nrespawn limit 7 14")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
22
52
|
describe '#export' do
|
23
53
|
it 'should make cleanup before export' do
|
24
|
-
exporter.
|
54
|
+
expect(exporter).to receive(:clear)
|
25
55
|
exporter.export
|
26
56
|
end
|
27
57
|
|
28
58
|
it 'should create upstart scripts, folders and sh helpers' do
|
29
59
|
exporter.export
|
30
60
|
%w{/h/p-app-ls_cmd.sh /u/p-app.conf /u/p-app-ls_cmd.conf}.each do |f|
|
31
|
-
FileTest.file?(f).
|
61
|
+
expect(FileTest.file?(f)).to eq(true)
|
32
62
|
end
|
33
63
|
end
|
34
64
|
|
35
65
|
it 'created scripts, folders and sh helpers should have valid content' do
|
36
66
|
exporter.export
|
37
67
|
|
38
|
-
File.read('/h/p-app-ls_cmd.sh').
|
39
|
-
File.read('/u/p-app.conf').
|
68
|
+
expect(File.read('/h/p-app-ls_cmd.sh')).to eq(tpl.helper(:cmd => 'exec ls'))
|
69
|
+
expect(File.read('/u/p-app.conf')).to eq(tpl.app(:run_user => 'u',
|
40
70
|
:run_group => 'g',
|
41
71
|
:app_name => 'p-app',
|
42
72
|
:start_on => 'runlevel [7]',
|
43
|
-
:stop_on => 'runlevel [3]')
|
44
|
-
File.read('/u/p-app-ls_cmd.conf').
|
73
|
+
:stop_on => 'runlevel [3]'))
|
74
|
+
expect(File.read('/u/p-app-ls_cmd.conf')).to eq(tpl.command(:run_user => 'u',
|
45
75
|
:run_group => 'g',
|
46
76
|
:app_name => 'p-app',
|
47
77
|
:cmd_name => 'ls_cmd',
|
48
78
|
:start_on => 'starting p-app',
|
49
79
|
:stop_on => 'stopping p-app',
|
50
80
|
:respawn => 'respawn',
|
51
|
-
:respawn_limit => '',
|
81
|
+
:respawn_limit => 'respawn limit 7 14',
|
52
82
|
:kill_timeout => 30,
|
53
|
-
:helper_cmd_conf => '/h/p-app-ls_cmd.sh')
|
83
|
+
:helper_cmd_conf => '/h/p-app-ls_cmd.sh'))
|
54
84
|
end
|
55
85
|
|
56
86
|
it 'prepends with "env" command starts with env var assignment' do
|
57
87
|
make_procfile('Procfile', 'sidekiq: RAILS_ENV=production sidekiq')
|
58
88
|
exporter.export
|
59
89
|
|
60
|
-
File.read('/h/p-app-sidekiq.sh').
|
90
|
+
expect(File.read('/h/p-app-sidekiq.sh')).to eq(tpl.helper(:cmd => 'exec env RAILS_ENV=production sidekiq'))
|
61
91
|
end
|
62
92
|
|
63
93
|
it 'call to "env" will not appear twice' do
|
64
94
|
make_procfile('Procfile', 'sidekiq: env RAILS_ENV=production sidekiq')
|
65
95
|
exporter.export
|
66
96
|
|
67
|
-
File.read('/h/p-app-sidekiq.sh').
|
97
|
+
expect(File.read('/h/p-app-sidekiq.sh')).to eq(tpl.helper(:cmd => 'exec env RAILS_ENV=production sidekiq'))
|
68
98
|
end
|
69
99
|
end
|
70
100
|
|
@@ -72,8 +102,8 @@ describe Upstart::Exporter do
|
|
72
102
|
it 'should remove exported app helpers an scripts' do
|
73
103
|
exporter.export
|
74
104
|
exporter.clear
|
75
|
-
Dir['/h/*'].
|
76
|
-
Dir['/u/*'].
|
105
|
+
expect(Dir['/h/*']).to be_empty
|
106
|
+
expect(Dir['/u/*']).to be_empty
|
77
107
|
end
|
78
108
|
|
79
109
|
it 'should keep files of other apps' do
|
@@ -86,7 +116,7 @@ describe Upstart::Exporter do
|
|
86
116
|
exporter.clear
|
87
117
|
|
88
118
|
%w{/h/p-other_app-ls_cmd.sh /u/p-other_app.conf /u/p-other_app-ls_cmd.conf}.each do |f|
|
89
|
-
FileTest.file?(f).
|
119
|
+
expect(FileTest.file?(f)).to eql true
|
90
120
|
end
|
91
121
|
end
|
92
122
|
end
|
metadata
CHANGED
@@ -1,44 +1,33 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: upstart-exporter
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 2
|
8
|
-
- 1
|
9
|
-
- 2
|
10
|
-
version: 2.1.2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.1.3
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
6
|
+
authors:
|
13
7
|
- Ilya Averyanov
|
14
8
|
- Egor Blinov
|
15
9
|
autorequire:
|
16
10
|
bindir: bin
|
17
11
|
cert_chain: []
|
18
|
-
|
19
|
-
date: 2014-02-24 00:00:00 +04:00
|
20
|
-
default_executable:
|
12
|
+
date: 2016-02-04 00:00:00.000000000 Z
|
21
13
|
dependencies: []
|
22
|
-
|
23
14
|
description: Gem for converting extended Procfile-like files to upstart scripts
|
24
|
-
email:
|
15
|
+
email:
|
25
16
|
- ilya@averyanov.org
|
26
17
|
- monshq@gmail.com
|
27
|
-
executables:
|
18
|
+
executables:
|
28
19
|
- upstart-export
|
29
20
|
extensions: []
|
30
|
-
|
31
21
|
extra_rdoc_files: []
|
32
|
-
|
33
|
-
|
34
|
-
- .
|
35
|
-
- .
|
36
|
-
- .
|
37
|
-
- .
|
38
|
-
- .
|
39
|
-
- .yardoc/
|
40
|
-
- .yardoc/
|
41
|
-
- .yardoc/proxy_types
|
22
|
+
files:
|
23
|
+
- ".gitignore"
|
24
|
+
- ".rbenv-version"
|
25
|
+
- ".rspec"
|
26
|
+
- ".ruby-version"
|
27
|
+
- ".travis.yml"
|
28
|
+
- ".yardoc/checksums"
|
29
|
+
- ".yardoc/objects/root.dat"
|
30
|
+
- ".yardoc/proxy_types"
|
42
31
|
- Gemfile
|
43
32
|
- README.md
|
44
33
|
- Rakefile
|
@@ -70,14 +59,17 @@ files:
|
|
70
59
|
- lib/upstart-exporter/errors.rb
|
71
60
|
- lib/upstart-exporter/expanded_exporter.rb
|
72
61
|
- lib/upstart-exporter/exporter_helpers.rb
|
62
|
+
- lib/upstart-exporter/hash_utils.rb
|
73
63
|
- lib/upstart-exporter/options/command_line.rb
|
74
64
|
- lib/upstart-exporter/options/global.rb
|
65
|
+
- lib/upstart-exporter/options/validator.rb
|
75
66
|
- lib/upstart-exporter/templates.rb
|
76
67
|
- lib/upstart-exporter/version.rb
|
77
68
|
- spec/lib/upstart-exporter/errors_spec.rb
|
78
69
|
- spec/lib/upstart-exporter/expanded_exporter_spec.rb
|
79
70
|
- spec/lib/upstart-exporter/options/command_line_spec.rb
|
80
71
|
- spec/lib/upstart-exporter/options/global_spec.rb
|
72
|
+
- spec/lib/upstart-exporter/options/validator_spec.rb
|
81
73
|
- spec/lib/upstart-exporter/templates_spec.rb
|
82
74
|
- spec/lib/upstart-exporter_spec.rb
|
83
75
|
- spec/spec_helper.rb
|
@@ -85,48 +77,39 @@ files:
|
|
85
77
|
- spec/support/procfile.rb
|
86
78
|
- spec/support/streams.rb
|
87
79
|
- upstart-exporter.gemspec
|
88
|
-
|
89
|
-
homepage: ""
|
80
|
+
homepage: ''
|
90
81
|
licenses: []
|
91
|
-
|
82
|
+
metadata: {}
|
92
83
|
post_install_message:
|
93
84
|
rdoc_options: []
|
94
|
-
|
95
|
-
require_paths:
|
85
|
+
require_paths:
|
96
86
|
- lib
|
97
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
-
|
99
|
-
requirements:
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
100
89
|
- - ">="
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
version: "0"
|
106
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
-
none: false
|
108
|
-
requirements:
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
109
94
|
- - ">="
|
110
|
-
- !ruby/object:Gem::Version
|
111
|
-
|
112
|
-
segments:
|
113
|
-
- 0
|
114
|
-
version: "0"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
115
97
|
requirements: []
|
116
|
-
|
117
98
|
rubyforge_project:
|
118
|
-
rubygems_version:
|
99
|
+
rubygems_version: 2.4.5.1
|
119
100
|
signing_key:
|
120
|
-
specification_version:
|
101
|
+
specification_version: 4
|
121
102
|
summary: Gem for converting extended Procfile-like files to upstart scripts
|
122
|
-
test_files:
|
103
|
+
test_files:
|
123
104
|
- spec/lib/upstart-exporter/errors_spec.rb
|
124
105
|
- spec/lib/upstart-exporter/expanded_exporter_spec.rb
|
125
106
|
- spec/lib/upstart-exporter/options/command_line_spec.rb
|
126
107
|
- spec/lib/upstart-exporter/options/global_spec.rb
|
108
|
+
- spec/lib/upstart-exporter/options/validator_spec.rb
|
127
109
|
- spec/lib/upstart-exporter/templates_spec.rb
|
128
110
|
- spec/lib/upstart-exporter_spec.rb
|
129
111
|
- spec/spec_helper.rb
|
130
112
|
- spec/support/global_config.rb
|
131
113
|
- spec/support/procfile.rb
|
132
114
|
- spec/support/streams.rb
|
115
|
+
has_rdoc:
|