upstart-exporter 2.1.2 → 2.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://secure.travis-ci.org/funbox/upstart-exporter.png)](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:
|