hell 0.1.1 → 0.2.0
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.
- data/Gemfile +1 -0
- data/README.markdown +0 -14
- data/VERSION +1 -1
- data/bin/hell +1 -1
- data/bin/hell-pusher +11 -4
- data/bin/hell-runner +65 -0
- data/hell.gemspec +6 -2
- data/lib/hell/app.rb +2 -3
- data/lib/hell/lib/cli.rb +201 -108
- data/lib/hell/lib/helpers.rb +3 -2
- data/lib/hell/public/assets/css/bootstrap.css +2 -2
- data/lib/hell/public/assets/js/hell.js +3 -3
- metadata +20 -3
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -69,20 +69,6 @@ The following environment variables are available for your use:
|
|
69
69
|
- `HELL_BASE_DIR`: Base directory to use in web ui. Useful for subdirectories. Defaults to `/`.
|
70
70
|
- `HELL_SENTINEL_STRINGS`: Sentinel string used to denote the end of a task run. Defaults to `Hellish Task Completed`.
|
71
71
|
|
72
|
-
## TODO
|
73
|
-
|
74
|
-
* ~~Finish the execute task so that it sends output to the browser~~
|
75
|
-
* ~~Figure out where/how to store deploy logs on disk~~
|
76
|
-
* ~~Blacklist tasks from being displayed~~
|
77
|
-
* ~~Add support for environment variables~~
|
78
|
-
* ~~Add support for deployment environments~~
|
79
|
-
* ~~Add support for ad-hoc deploy callbacks~~
|
80
|
-
* Save favorite commands as buttons
|
81
|
-
* Save defaults in a cookie
|
82
|
-
* Use a slide-up element for task output
|
83
|
-
* Add optional task locking so that deploys cannot interfere with one-another
|
84
|
-
* Add ability to use pusher instead of sinatra streaming
|
85
|
-
|
86
72
|
## License
|
87
73
|
|
88
74
|
Copyright (c) 2012 Jose Diaz-Gonzalez
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/bin/hell
CHANGED
@@ -6,7 +6,7 @@ require 'hell/lib/cli'
|
|
6
6
|
ENV["RACK_ENV"] ||= "development"
|
7
7
|
|
8
8
|
unicorn_path = File.expand_path('../../unicorn', __FILE__)
|
9
|
-
options, op = Hell::CLI.
|
9
|
+
options, op = Hell::CLI.unicorn_option_parser(ARGV, unicorn_path)
|
10
10
|
|
11
11
|
unless File.directory? options[:log_path]
|
12
12
|
abort('Missing hell log path %s' % options[:log_path])
|
data/bin/hell-pusher
CHANGED
@@ -6,15 +6,22 @@ require 'hell/lib/helpers'
|
|
6
6
|
TASK_ID = ENV.fetch('HELL_TASK_ID', nil)
|
7
7
|
HELL_LOG_PATH = ENV.fetch('HELL_LOG_PATH', File.join(Dir.pwd, 'log'))
|
8
8
|
HELL_SENTINEL_STRINGS = ENV.fetch('HELL_SENTINEL_STRINGS', 'Hellish Task Completed').split(',')
|
9
|
+
HELL_PUSHER_APP_ID = ENV.fetch('HELL_PUSHER_APP_ID', nil)
|
10
|
+
HELL_PUSHER_KEY = ENV.fetch('HELL_PUSHER_KEY', nil)
|
11
|
+
HELL_PUSHER_SECRET = ENV.fetch('HELL_PUSHER_SECRET', nil)
|
12
|
+
|
9
13
|
abort('Missing hell task id') unless TASK_ID
|
14
|
+
abort('Missing pusher app id') unless HELL_PUSHER_APP_ID
|
15
|
+
abort('Missing pusher app key') unless HELL_PUSHER_KEY
|
16
|
+
abort('Missing pusher app secret') unless HELL_PUSHER_SECRET
|
17
|
+
|
18
|
+
Pusher.app_id = HELL_PUSHER_APP_ID
|
19
|
+
Pusher.key = HELL_PUSHER_KEY
|
20
|
+
Pusher.secret = HELL_PUSHER_SECRET
|
10
21
|
|
11
22
|
unless Hell::Helpers.valid_log(TASK_ID)
|
12
23
|
Hell::Helpers::pusher_error(TASK_ID, "log file '#{TASK_ID}' not found")
|
13
24
|
abort("log file '#{TASK_ID}' not found")
|
14
25
|
end
|
15
26
|
|
16
|
-
Pusher.app_id = ENV.fetch('HELL_PUSHER_APP_ID', nil)
|
17
|
-
Pusher.key = ENV.fetch('HELL_PUSHER_KEY', nil)
|
18
|
-
Pusher.secret = ENV.fetch('HELL_PUSHER_SECRET', nil)
|
19
|
-
|
20
27
|
Hell::Helpers::pusher_success(TASK_ID, "tail -n 1000 -f %s" % File.join(HELL_LOG_PATH, TASK_ID + ".log"))
|
data/bin/hell-runner
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/this/will/be/overwritten/or/wrapped/anyways/do/not/worry/ruby
|
2
|
+
# -*- encoding: binary -*-
|
3
|
+
require 'multi_json'
|
4
|
+
require 'optparse'
|
5
|
+
require 'rest_client'
|
6
|
+
require 'pusher-client'
|
7
|
+
|
8
|
+
require 'hell/lib/cli'
|
9
|
+
|
10
|
+
options, op = Hell::CLI.runner_option_parser(ARGV)
|
11
|
+
|
12
|
+
abort("Base hell url required, specify it using the -b flag") unless options[:base_url]
|
13
|
+
abort("Task name required, specify it using the -t flag") unless options[:task]
|
14
|
+
|
15
|
+
USE_PUSHER = !!(options[:pusher_app_id] && options[:pusher_key] && options[:pusher_secret])
|
16
|
+
|
17
|
+
# Create the command
|
18
|
+
command = []
|
19
|
+
command << options[:environment] unless options[:environment].nil?
|
20
|
+
command << options[:task] unless options[:task].nil?
|
21
|
+
command = command.join('+')
|
22
|
+
|
23
|
+
# Construct a url
|
24
|
+
url = options[:base_url] + '/tasks/' + command + '/background'
|
25
|
+
|
26
|
+
begin
|
27
|
+
response = RestClient.put(url, {:verbose => options[:verbose] ? "on" : "off"})
|
28
|
+
rescue Exception => e
|
29
|
+
abort("Error retrieving response: %s" % e)
|
30
|
+
end
|
31
|
+
|
32
|
+
abort("Invalid response from server") unless response.code == 200
|
33
|
+
|
34
|
+
body = MultiJson.load(response.body)
|
35
|
+
task_id = body["task_id"]
|
36
|
+
|
37
|
+
puts options
|
38
|
+
|
39
|
+
if USE_PUSHER
|
40
|
+
PusherClient.logger = Logger.new('/dev/null')
|
41
|
+
socket = PusherClient::Socket.new(options[:pusher_key], {
|
42
|
+
:secret => options[:pusher_secret]
|
43
|
+
})
|
44
|
+
|
45
|
+
socket.subscribe(task_id)
|
46
|
+
|
47
|
+
socket[task_id].bind('start') do |data|
|
48
|
+
PusherClient.logger.debug "Received the first response for " + command
|
49
|
+
end
|
50
|
+
|
51
|
+
socket[task_id].bind('message') do |data|
|
52
|
+
data = MultiJson.load(data)
|
53
|
+
puts data['message'].gsub(/~+$/, '')
|
54
|
+
end
|
55
|
+
|
56
|
+
socket[task_id].bind('end') do |data|
|
57
|
+
PusherClient.logger.debug "Received the last response " + command
|
58
|
+
socket.unsubscribe(task_id)
|
59
|
+
socket.disconnect
|
60
|
+
end
|
61
|
+
|
62
|
+
socket.connect
|
63
|
+
else
|
64
|
+
abort("EventSource not implemented yet")
|
65
|
+
end
|
data/hell.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "hell"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jose Diaz-Gonzalez"]
|
12
|
-
s.date = "2013-
|
12
|
+
s.date = "2013-03-11"
|
13
13
|
s.description = "Hell is an open source web interface that exposes a set of capistrano recipes as a json api, for usage within large teams"
|
14
14
|
s.email = "jose@seatgeek.com"
|
15
15
|
s.executables = ["hell", "hell-pusher"]
|
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
"VERSION",
|
27
27
|
"bin/hell",
|
28
28
|
"bin/hell-pusher",
|
29
|
+
"bin/hell-runner",
|
29
30
|
"config.ru",
|
30
31
|
"hell.gemspec",
|
31
32
|
"lib/hell.rb",
|
@@ -73,6 +74,7 @@ Gem::Specification.new do |s|
|
|
73
74
|
s.add_runtime_dependency(%q<capistrano>, [">= 0"])
|
74
75
|
s.add_runtime_dependency(%q<multi_json>, [">= 0"])
|
75
76
|
s.add_runtime_dependency(%q<pusher>, [">= 0"])
|
77
|
+
s.add_runtime_dependency(%q<pusher-client>, [">= 0"])
|
76
78
|
s.add_runtime_dependency(%q<sinatra>, [">= 0"])
|
77
79
|
s.add_runtime_dependency(%q<sinatra-contrib>, [">= 0"])
|
78
80
|
s.add_runtime_dependency(%q<sinatra-assetpack>, [">= 0"])
|
@@ -84,6 +86,7 @@ Gem::Specification.new do |s|
|
|
84
86
|
s.add_dependency(%q<capistrano>, [">= 0"])
|
85
87
|
s.add_dependency(%q<multi_json>, [">= 0"])
|
86
88
|
s.add_dependency(%q<pusher>, [">= 0"])
|
89
|
+
s.add_dependency(%q<pusher-client>, [">= 0"])
|
87
90
|
s.add_dependency(%q<sinatra>, [">= 0"])
|
88
91
|
s.add_dependency(%q<sinatra-contrib>, [">= 0"])
|
89
92
|
s.add_dependency(%q<sinatra-assetpack>, [">= 0"])
|
@@ -96,6 +99,7 @@ Gem::Specification.new do |s|
|
|
96
99
|
s.add_dependency(%q<capistrano>, [">= 0"])
|
97
100
|
s.add_dependency(%q<multi_json>, [">= 0"])
|
98
101
|
s.add_dependency(%q<pusher>, [">= 0"])
|
102
|
+
s.add_dependency(%q<pusher-client>, [">= 0"])
|
99
103
|
s.add_dependency(%q<sinatra>, [">= 0"])
|
100
104
|
s.add_dependency(%q<sinatra-contrib>, [">= 0"])
|
101
105
|
s.add_dependency(%q<sinatra-assetpack>, [">= 0"])
|
data/lib/hell/app.rb
CHANGED
@@ -115,8 +115,8 @@ module Hell
|
|
115
115
|
tail_in_background!(task_id) if USE_PUSHER
|
116
116
|
|
117
117
|
response = {}
|
118
|
-
response[:status] = tasks.empty? ? 404 : 200
|
119
|
-
response[:message] = tasks.empty? ? "Task not found" : "Running task in background"
|
118
|
+
response[:status] = tasks.empty? ? 404 : 200
|
119
|
+
response[:message] = tasks.empty? ? "Task not found" : "Running task in background"
|
120
120
|
response[:task_id] = task_id unless tasks.empty?
|
121
121
|
json response
|
122
122
|
end
|
@@ -174,6 +174,5 @@ module Hell
|
|
174
174
|
close_stream(out)
|
175
175
|
end
|
176
176
|
end
|
177
|
-
|
178
177
|
end
|
179
178
|
end
|
data/lib/hell/lib/cli.rb
CHANGED
@@ -25,153 +25,246 @@ module Hell
|
|
25
25
|
options
|
26
26
|
end
|
27
27
|
|
28
|
-
def self.
|
29
|
-
|
28
|
+
def self.generic_options(options, opts)
|
29
|
+
cmd = File.basename($0)
|
30
|
+
opts.banner = "Usage: #{cmd} " \
|
31
|
+
"[ruby options] [#{cmd} options] [rackup config file]"
|
32
|
+
opts.separator "Ruby options:"
|
33
|
+
|
34
|
+
lineno = 1
|
35
|
+
opts.on("-e", "--eval LINE", "evaluate a LINE of code") do |line|
|
36
|
+
eval line, TOPLEVEL_BINDING, "-e", lineno
|
37
|
+
lineno += 1
|
38
|
+
end
|
30
39
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
:require_env,
|
35
|
-
:sentinel,
|
36
|
-
:pusher_app_id,
|
37
|
-
:pusher_key,
|
38
|
-
:pusher_secret,
|
39
|
-
].each {|key| options.delete(key)}
|
40
|
+
opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") do
|
41
|
+
$DEBUG = true
|
42
|
+
end
|
40
43
|
|
41
|
-
|
44
|
+
opts.on("-w", "--warn", "turn warnings on for your script") do
|
45
|
+
$-w = true
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on("-I", "--include PATH",
|
49
|
+
"specify $LOAD_PATH (may be used more than once)") do |path|
|
50
|
+
$LOAD_PATH.unshift(*path.split(/:/))
|
51
|
+
end
|
52
|
+
|
53
|
+
opts.on("-r", "--require LIBRARY",
|
54
|
+
"require the library, before executing your script") do |library|
|
55
|
+
require library
|
56
|
+
end
|
57
|
+
|
58
|
+
[options, opts]
|
42
59
|
end
|
43
60
|
|
44
|
-
def self.
|
45
|
-
|
61
|
+
def self.runner_options(options, opts)
|
62
|
+
opts.separator "Runner options"
|
46
63
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
"[ruby options] [#{cmd} options] [rackup config file]"
|
51
|
-
opts.separator "Ruby options:"
|
52
|
-
|
53
|
-
lineno = 1
|
54
|
-
opts.on("-e", "--eval LINE", "evaluate a LINE of code") do |line|
|
55
|
-
eval line, TOPLEVEL_BINDING, "-e", lineno
|
56
|
-
lineno += 1
|
57
|
-
end
|
64
|
+
opts.on("--base-url BASE_URL", "base hell url") do |base_url|
|
65
|
+
options[:base_url] = base_url.gsub(/[\/]+$/, '') if base_url
|
66
|
+
end
|
58
67
|
|
59
|
-
|
60
|
-
|
61
|
-
|
68
|
+
opts.on("--environment ENVIRONMENT", "environment to run task in") do |environment|
|
69
|
+
options[:environment] = environment if environment
|
70
|
+
end
|
62
71
|
|
63
|
-
|
64
|
-
|
65
|
-
|
72
|
+
opts.on("--task TASK", "full task name to run") do |task|
|
73
|
+
options[:task] = task if task
|
74
|
+
end
|
66
75
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end
|
76
|
+
opts.on("--verbose", "run task in verbose mode") do |environment|
|
77
|
+
options[:verbose] = true if verbose
|
78
|
+
end
|
71
79
|
|
72
|
-
|
73
|
-
|
74
|
-
require library
|
75
|
-
end
|
80
|
+
[options, opts]
|
81
|
+
end
|
76
82
|
|
77
|
-
|
83
|
+
def self.server_options(options, opts)
|
84
|
+
# some of these switches exist for rackup command-line compatibility,
|
85
|
+
opts.separator "Server options"
|
78
86
|
|
79
|
-
|
87
|
+
opts.on("-o", "--host HOST",
|
88
|
+
"listen on HOST (default: 0.0.0.0)") do |h|
|
89
|
+
rackup_opts[:host] = h || '0.0.0.0'
|
90
|
+
rackup_opts[:set_listener] = true
|
91
|
+
end
|
80
92
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
93
|
+
opts.on("-p", "--port PORT",
|
94
|
+
"use PORT (default: 4567)") do |p|
|
95
|
+
rackup_opts[:port] = p || 4567
|
96
|
+
rackup_opts[:port] = rackup_opts[:port].to_i
|
97
|
+
rackup_opts[:set_listener] = true
|
98
|
+
end
|
86
99
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
rackup_opts[:set_listener] = true
|
92
|
-
end
|
100
|
+
opts.on("-E", "--env RACK_ENV",
|
101
|
+
"use RACK_ENV for defaults (default: development)") do |e|
|
102
|
+
ENV["RACK_ENV"] = e
|
103
|
+
end
|
93
104
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
end
|
105
|
+
opts.on("-D", "--daemonize", "run daemonized in the background") do |d|
|
106
|
+
rackup_opts[:daemonize] = !!d
|
107
|
+
end
|
98
108
|
|
99
|
-
|
100
|
-
|
101
|
-
|
109
|
+
opts.on("-P", "--pid FILE", "DEPRECATED") do |f|
|
110
|
+
warn %q{Use of --pid/-P is strongly discouraged}
|
111
|
+
warn %q{Use the 'pid' directive in the Unicorn config file instead}
|
112
|
+
options[:pid] = f
|
113
|
+
end
|
102
114
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
end
|
115
|
+
opts.on("-s", "--server SERVER",
|
116
|
+
"this flag only exists for compatibility") do |s|
|
117
|
+
warn "-s/--server only exists for compatibility with rackup"
|
118
|
+
end
|
108
119
|
|
109
|
-
|
110
|
-
|
111
|
-
warn "-s/--server only exists for compatibility with rackup"
|
112
|
-
end
|
120
|
+
[options, opts]
|
121
|
+
end
|
113
122
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
"this may be specified multiple times",
|
118
|
-
"(default: 0.0.0.0:4567)") do |address|
|
119
|
-
options[:listeners] << address || '0.0.0.0:4567'
|
120
|
-
end
|
123
|
+
def self.unicorn_options(options, opts)
|
124
|
+
# Unicorn-specific stuff
|
125
|
+
opts.separator "Unicorn options:"
|
121
126
|
|
122
|
-
|
123
|
-
|
124
|
-
|
127
|
+
opts.on("-l", "--listen {HOST:PORT|PATH}",
|
128
|
+
"listen on HOST:PORT or PATH",
|
129
|
+
"this may be specified multiple times",
|
130
|
+
"(default: 0.0.0.0:4567)") do |address|
|
131
|
+
options[:listeners] << address || '0.0.0.0:4567'
|
132
|
+
end
|
125
133
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
134
|
+
opts.on("-c", "--config-file FILE", "Unicorn-specific config file") do |f|
|
135
|
+
options[:config_file] = unicorn_path
|
136
|
+
end
|
137
|
+
|
138
|
+
[options, opts]
|
139
|
+
end
|
130
140
|
|
131
|
-
|
132
|
-
|
141
|
+
def self.common_options(options, opts)
|
142
|
+
opts.separator "Common options"
|
133
143
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
144
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
145
|
+
puts opts.to_s.gsub(/^.*DEPRECATED.*$/s, '')
|
146
|
+
exit
|
147
|
+
end
|
138
148
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
149
|
+
opts.on_tail("-v", "--version", "Show version") do
|
150
|
+
puts "#{cmd} v#{Unicorn::Const::UNICORN_VERSION}"
|
151
|
+
exit
|
152
|
+
end
|
143
153
|
|
144
|
-
|
145
|
-
|
154
|
+
opts.on('-a', '--app-root APP_ROOT', 'directory from which capistrano should run') do |app_root|
|
155
|
+
if app_root
|
156
|
+
options[:app_root] = app_root
|
157
|
+
ENV['HELL_APP_ROOT'] = app_root
|
146
158
|
end
|
159
|
+
end
|
147
160
|
|
148
|
-
|
149
|
-
|
161
|
+
opts.on('-b', '--base-path BASE_PATH', 'base directory path to use in the web ui') do |base_path|
|
162
|
+
if base_path
|
163
|
+
options[:base_path] = base_path
|
164
|
+
ENV['HELL_BASE_PATH'] = base_path
|
150
165
|
end
|
166
|
+
end
|
151
167
|
|
152
|
-
|
153
|
-
|
168
|
+
opts.on('-L', '--log-path LOG_PATH', 'directory path to hell logs') do |log_path|
|
169
|
+
if log_path
|
170
|
+
options[:log_path] = log_path
|
171
|
+
ENV['HELL_LOG_PATH'] = log_path
|
154
172
|
end
|
173
|
+
end
|
155
174
|
|
156
|
-
|
157
|
-
|
175
|
+
opts.on('-R', '--require-env REQUIRE_ENV', 'whether or not to require specifying an environment') do |require_env|
|
176
|
+
if require_env
|
177
|
+
options[:require_env] = !!require_env
|
178
|
+
ENV['HELL_REQUIRE_ENV'] = !!require_env
|
158
179
|
end
|
180
|
+
end
|
159
181
|
|
160
|
-
|
161
|
-
|
182
|
+
opts.on('-S', '--sentinel SENTINAL_PHRASE', 'sentinel phrase used to denote the end of a task run') do |sentinel|
|
183
|
+
if sentinel
|
184
|
+
options[:sentinel] = sentinel.split(',')
|
185
|
+
ENV['HELL_SENTINEL_STRINGS'] = sentinel.split(',')
|
162
186
|
end
|
187
|
+
end
|
163
188
|
|
164
|
-
|
165
|
-
|
189
|
+
opts.on('--pusher-app-id PUSHER_APP_ID', 'pusher app id') do |pusher_app_id|
|
190
|
+
if pusher_app_id
|
191
|
+
options[:pusher_app_id] = pusher_app_id
|
192
|
+
ENV['HELL_PUSHER_APP_ID'] = pusher_app_id
|
166
193
|
end
|
194
|
+
end
|
167
195
|
|
168
|
-
|
169
|
-
|
196
|
+
opts.on('--pusher-key PUSHER_KEY', 'pusher key') do |pusher_key|
|
197
|
+
if pusher_key
|
198
|
+
options[:pusher_key] = pusher_key
|
199
|
+
ENV['HELL_PUSHER_KEY'] = pusher_key
|
170
200
|
end
|
201
|
+
end
|
171
202
|
|
172
|
-
|
173
|
-
|
203
|
+
opts.on('--pusher-secret PUSHER_SECRET', 'pusher secret') do |pusher_secret|
|
204
|
+
if pusher_secret
|
205
|
+
options[:pusher_secret] = pusher_secret
|
206
|
+
ENV['HELL_PUSHER_SECRET'] = pusher_secret
|
174
207
|
end
|
208
|
+
end
|
209
|
+
|
210
|
+
[options, opts]
|
211
|
+
end
|
212
|
+
|
213
|
+
def self.runner_option_parser(args)
|
214
|
+
options = options = {
|
215
|
+
:environment => nil,
|
216
|
+
:task => nil,
|
217
|
+
:verbose => false,
|
218
|
+
:pusher_app_id => ENV.fetch('HELL_PUSHER_APP_ID', nil),
|
219
|
+
:pusher_key => ENV.fetch('HELL_PUSHER_KEY', nil),
|
220
|
+
:pusher_secret => ENV.fetch('HELL_PUSHER_SECRET', nil),
|
221
|
+
}
|
222
|
+
|
223
|
+
op = OptionParser.new("", 24, ' ') do |opts|
|
224
|
+
options, opts = Hell::CLI.generic_options(options, opts)
|
225
|
+
|
226
|
+
options, opts = Hell::CLI.runner_options(options, opts)
|
227
|
+
|
228
|
+
options, opts = Hell::CLI.common_options(options, opts)
|
229
|
+
|
230
|
+
opts.parse! args
|
231
|
+
end
|
232
|
+
|
233
|
+
[options, op]
|
234
|
+
end
|
235
|
+
|
236
|
+
def self.unicorn_option_parser(args, unicorn_path=nil)
|
237
|
+
options, op = Hell::CLI.option_parser(args, unicorn_path)
|
238
|
+
|
239
|
+
[
|
240
|
+
:app_root,
|
241
|
+
:base_path,
|
242
|
+
:require_env,
|
243
|
+
:sentinel,
|
244
|
+
:pusher_app_id,
|
245
|
+
:pusher_key,
|
246
|
+
:pusher_secret,
|
247
|
+
].each {|key| options.delete(key)}
|
248
|
+
|
249
|
+
[options, op]
|
250
|
+
end
|
251
|
+
|
252
|
+
def self.option_parser(args, unicorn_path=nil)
|
253
|
+
options = Hell::CLI.default_options(unicorn_path)
|
254
|
+
|
255
|
+
op = OptionParser.new("", 24, ' ') do |opts|
|
256
|
+
options, opts = Hell::CLI.generic_options(options, opts)
|
257
|
+
|
258
|
+
options, opts = Hell::CLI.server_options(options, opts)
|
259
|
+
|
260
|
+
options, opts = Hell::CLI.unicorn_options(options, opts)
|
261
|
+
|
262
|
+
# I'm avoiding Unicorn-specific config options on the command-line.
|
263
|
+
# IMNSHO, config options on the command-line are redundant given
|
264
|
+
# config files and make things unnecessarily complicated with multiple
|
265
|
+
# places to look for a config option.
|
266
|
+
|
267
|
+
options, opts = Hell::CLI.common_options(options, opts)
|
175
268
|
|
176
269
|
opts.parse! args
|
177
270
|
end
|
data/lib/hell/lib/helpers.rb
CHANGED
@@ -81,10 +81,11 @@ module Hell
|
|
81
81
|
|
82
82
|
def run_in_background!(background_cmd)
|
83
83
|
log_file = random_id
|
84
|
+
task_end = HELL_SENTINEL_STRINGS.first
|
84
85
|
cmd = [
|
85
86
|
"cd #{HELL_APP_ROOT} && echo '#{background_cmd}' >> #{HELL_LOG_PATH}/#{log_file}.log 2>&1",
|
86
87
|
"cd #{HELL_APP_ROOT} && #{background_cmd} >> #{HELL_LOG_PATH}/#{log_file}.log 2>&1",
|
87
|
-
"cd #{HELL_APP_ROOT} && echo '
|
88
|
+
"cd #{HELL_APP_ROOT} && echo '#{task_end}' >> #{HELL_LOG_PATH}/#{log_file}.log 2>&1",
|
88
89
|
].join(" ; ")
|
89
90
|
system("sh -c \"#{cmd}\" &")
|
90
91
|
|
@@ -100,7 +101,7 @@ module Hell
|
|
100
101
|
end
|
101
102
|
|
102
103
|
def tail_in_background!(task_id)
|
103
|
-
cmd = "cd #{HELL_LOG_PATH} && HELL_TASK_ID='#{task_id}' HELL_SENTINEL_STRINGS='#{HELL_SENTINEL_STRINGS.join(',')}'
|
104
|
+
cmd = "cd #{HELL_LOG_PATH} && HELL_TASK_ID='#{task_id}' HELL_SENTINEL_STRINGS='#{HELL_SENTINEL_STRINGS.join(',')}' bundle exec hell-pusher"
|
104
105
|
system("sh -c \"#{cmd}\" &")
|
105
106
|
end
|
106
107
|
|
@@ -2151,7 +2151,7 @@ table th[class*="span"],
|
|
2151
2151
|
*margin-right: .3em;
|
2152
2152
|
line-height: 14px;
|
2153
2153
|
vertical-align: text-top;
|
2154
|
-
background-image: url("
|
2154
|
+
background-image: url("./../img/glyphicons-halflings.png");
|
2155
2155
|
background-position: 14px 14px;
|
2156
2156
|
background-repeat: no-repeat;
|
2157
2157
|
}
|
@@ -2171,7 +2171,7 @@ table th[class*="span"],
|
|
2171
2171
|
.dropdown-menu > .active > a > [class*=" icon-"],
|
2172
2172
|
.dropdown-submenu:hover > a > [class^="icon-"],
|
2173
2173
|
.dropdown-submenu:hover > a > [class*=" icon-"] {
|
2174
|
-
background-image: url("
|
2174
|
+
background-image: url("./../img/glyphicons-halflings-white.png");
|
2175
2175
|
}
|
2176
2176
|
|
2177
2177
|
.icon-glass {
|
@@ -167,7 +167,7 @@ $(function() {
|
|
167
167
|
_executeEventsource: function(task_id) {
|
168
168
|
var that = this;
|
169
169
|
|
170
|
-
// Create new
|
170
|
+
// Create new EventSource
|
171
171
|
var src = new EventSource(HellApp.www_base_dir + 'logs/' + task_id + '/tail');
|
172
172
|
|
173
173
|
// Received the first response
|
@@ -176,7 +176,7 @@ $(function() {
|
|
176
176
|
that.setStatus("started");
|
177
177
|
});
|
178
178
|
|
179
|
-
// Close the
|
179
|
+
// Close the EventSource when there are no more events
|
180
180
|
src.addEventListener('end', function () {
|
181
181
|
HellApp.set_flash("Received the last response " + name, "info");
|
182
182
|
that.setStatus("finished");
|
@@ -194,7 +194,7 @@ $(function() {
|
|
194
194
|
view: function() {
|
195
195
|
HellApp.set_flash("Viewing a past task", "info");
|
196
196
|
|
197
|
-
// Close all
|
197
|
+
// Close all EventSource
|
198
198
|
HellApp.close_sockets(src);
|
199
199
|
HellApp.toggle_overlay();
|
200
200
|
window.location.hash = "#run";
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-03-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: capistrano
|
@@ -59,6 +59,22 @@ dependencies:
|
|
59
59
|
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: pusher-client
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
62
78
|
- !ruby/object:Gem::Dependency
|
63
79
|
name: sinatra
|
64
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -190,6 +206,7 @@ files:
|
|
190
206
|
- VERSION
|
191
207
|
- bin/hell
|
192
208
|
- bin/hell-pusher
|
209
|
+
- bin/hell-runner
|
193
210
|
- config.ru
|
194
211
|
- hell.gemspec
|
195
212
|
- lib/hell.rb
|
@@ -238,7 +255,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
238
255
|
version: '0'
|
239
256
|
segments:
|
240
257
|
- 0
|
241
|
-
hash: -
|
258
|
+
hash: -2087860351003938988
|
242
259
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
243
260
|
none: false
|
244
261
|
requirements:
|