rocketjob_mission_control 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/rocket_job_mission_control/dirmon_entries.js.coffee +18 -0
- data/app/assets/stylesheets/rocket_job_mission_control/base.scss +33 -59
- data/app/assets/stylesheets/rocket_job_mission_control/bootstrap_and_overrides.scss +12 -0
- data/app/assets/stylesheets/rocket_job_mission_control/callout.scss +8 -0
- data/app/assets/stylesheets/rocket_job_mission_control/jobs.scss +35 -0
- data/app/controllers/rocket_job_mission_control/application_controller.rb +0 -2
- data/app/controllers/rocket_job_mission_control/dirmon_entries_controller.rb +125 -0
- data/app/controllers/rocket_job_mission_control/jobs/failures_controller.rb +31 -0
- data/app/helpers/rocket_job_mission_control/application_helper.rb +7 -0
- data/app/helpers/rocket_job_mission_control/jobs_helper.rb +18 -11
- data/app/helpers/rocket_job_mission_control/pagination_helper.rb +7 -0
- data/app/helpers/rocket_job_mission_control/slices_helper.rb +9 -0
- data/app/models/job_failures.rb +30 -0
- data/app/views/layouts/rocket_job_mission_control/application.html.haml +3 -1
- data/app/views/layouts/rocket_job_mission_control/partials/_header.html.haml +2 -2
- data/app/views/layouts/rocket_job_mission_control/partials/_sidebar.html.haml +4 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_form.html.haml +36 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_list.html.haml +31 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_properties.html.haml +8 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_status.html.haml +23 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/edit.html.haml +8 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/index.html.haml +11 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/new.html.haml +9 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/show.html.haml +26 -0
- data/app/views/rocket_job_mission_control/jobs/_list.html.haml +34 -30
- data/app/views/rocket_job_mission_control/jobs/failures/_pagination.html.haml +16 -0
- data/app/views/rocket_job_mission_control/jobs/failures/index.html.haml +32 -0
- data/app/views/rocket_job_mission_control/jobs/index.html.haml +10 -8
- data/app/views/rocket_job_mission_control/jobs/running.html.haml +1 -1
- data/app/views/rocket_job_mission_control/jobs/show.html.haml +39 -35
- data/app/views/rocket_job_mission_control/workers/_actions.html.haml +4 -4
- data/app/views/rocket_job_mission_control/workers/index.html.haml +50 -45
- data/config/locales/en.yml +23 -1
- data/config/routes.rb +8 -0
- data/lib/rocket_job_mission_control/version.rb +1 -1
- data/spec/controllers/dirmon_entries_controller_spec.rb +451 -0
- data/spec/controllers/jobs/failures_controller_spec.rb +60 -0
- data/spec/dummy/config/environments/test.rb +1 -1
- data/spec/dummy/config/mongo.yml +15 -0
- data/spec/dummy/log/development.log +2 -0
- data/spec/dummy/log/test.log +52763 -2015
- data/spec/helpers/jobs_helper_spec.rb +27 -0
- data/spec/helpers/pagination_helper_spec.rb +21 -0
- data/spec/helpers/slices_helper_spec.rb +33 -0
- data/spec/models/job_failures_spec.rb +14 -0
- data/spec/views/workers/index.html.haml_spec.rb +23 -0
- metadata +35 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8d7c96f03155c733cf07a5e81796020552dd378
|
4
|
+
data.tar.gz: cf0647850f7b019530b1f1c6d4a511dbcb5fcc5b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4639ef836e562dc597c5e0651571111ac84b3a217b3599da8f06807513375c73b44eb9a091517da37c57f6fa9d478fa2f23f75825ef6c8afad0e899f4892d67b
|
7
|
+
data.tar.gz: fe70a9fd5c6cbd029443dda89be419f9c08b6de28fe3a90f2908bccd753f3d4c5837fb239e9d970170e3849c7086e33d9ee5b38518298676b0844308298b9303
|
@@ -0,0 +1,18 @@
|
|
1
|
+
$(document).on 'ready', ->
|
2
|
+
$('.filter .state-toggle').on 'change', ->
|
3
|
+
active_states = $('.filter :checked')
|
4
|
+
param_string = "?"
|
5
|
+
active_states.each (_, state) ->
|
6
|
+
param_string += "states[]=" + $(state).attr('id') + "&"
|
7
|
+
window.location.href = window.location.href.replace( /[\?#].*|$/, param_string );
|
8
|
+
|
9
|
+
if $('#properties').length
|
10
|
+
$('#expand').on 'click', ->
|
11
|
+
$(this).hide()
|
12
|
+
$('#collapse').show()
|
13
|
+
$('#properties').show()
|
14
|
+
$('#collapse').on 'click', ->
|
15
|
+
$(this).hide()
|
16
|
+
$('#expand').show()
|
17
|
+
$('#properties').hide()
|
18
|
+
|
@@ -3,6 +3,13 @@
|
|
3
3
|
overflow: hidden;
|
4
4
|
}
|
5
5
|
|
6
|
+
.footer {
|
7
|
+
position: relative;
|
8
|
+
height: 100px;
|
9
|
+
clear:both;
|
10
|
+
padding-top:20px;
|
11
|
+
}
|
12
|
+
|
6
13
|
body.rocket_job {
|
7
14
|
padding: 0;
|
8
15
|
|
@@ -10,8 +17,8 @@ body.rocket_job {
|
|
10
17
|
|
11
18
|
.job-list {
|
12
19
|
height: 100%;
|
20
|
+
min-height: 768px;
|
13
21
|
border-right: 1px solid #ddd;
|
14
|
-
padding: 0;
|
15
22
|
}
|
16
23
|
|
17
24
|
.job-status {
|
@@ -41,7 +48,7 @@ body.rocket_job {
|
|
41
48
|
p { font-size: 16px; }
|
42
49
|
}
|
43
50
|
|
44
|
-
.job-
|
51
|
+
.job-actions {
|
45
52
|
float: left;
|
46
53
|
margin-top: 23px;
|
47
54
|
margin-left: 20px;
|
@@ -49,6 +56,12 @@ body.rocket_job {
|
|
49
56
|
.btn { padding: 2px 6px; }
|
50
57
|
}
|
51
58
|
|
59
|
+
.pagination-buttons {
|
60
|
+
float: left;
|
61
|
+
margin-top: 23px;
|
62
|
+
margin-left: 20px;
|
63
|
+
}
|
64
|
+
|
52
65
|
.job-state {
|
53
66
|
margin-left: 20px;
|
54
67
|
padding: 0;
|
@@ -75,10 +88,10 @@ body.rocket_job {
|
|
75
88
|
border-bottom-right-radius: 3px;
|
76
89
|
}
|
77
90
|
|
78
|
-
.queued { background-color: darkgrey; }
|
91
|
+
.queued, .pending { background-color: darkgrey; }
|
79
92
|
.running { background-color: #337ab7; }
|
80
|
-
.completed { background-color: green; }
|
81
|
-
.paused { background-color: orange; }
|
93
|
+
.completed, .enabled { background-color: green; }
|
94
|
+
.paused, .disabled { background-color: orange; }
|
82
95
|
.failed { background-color: red; }
|
83
96
|
.aborted { background-color: darkorange; }
|
84
97
|
}
|
@@ -125,11 +138,18 @@ body.rocket_job {
|
|
125
138
|
text-align: center;
|
126
139
|
|
127
140
|
a {
|
141
|
+
display: inline-block;
|
128
142
|
color: orange;
|
129
143
|
font-weight: bold;
|
144
|
+
|
130
145
|
}
|
131
146
|
|
132
|
-
|
147
|
+
a:hover, a:active {
|
148
|
+
text-decoration: none;
|
149
|
+
}
|
150
|
+
|
151
|
+
|
152
|
+
span {
|
133
153
|
display: inline-block;
|
134
154
|
position: relative;
|
135
155
|
left: -3px;
|
@@ -278,7 +298,7 @@ body.rocket_job {
|
|
278
298
|
a { display: block; }
|
279
299
|
|
280
300
|
.card:nth-child(1) { border-top: 1px solid #ddd; }
|
281
|
-
.card:nth-child(odd) { background-color: #fff; }
|
301
|
+
.card:nth-child(odd):not(.selected) { background-color: #fff; }
|
282
302
|
|
283
303
|
.card {
|
284
304
|
border-bottom: 1px solid #ddd;
|
@@ -305,6 +325,8 @@ body.rocket_job {
|
|
305
325
|
i.paused { color: orange; }
|
306
326
|
i.failed { color: red; }
|
307
327
|
i.aborted { color: darkorange; }
|
328
|
+
i.enabled { color: green; }
|
329
|
+
i.disabled { color: orange; }
|
308
330
|
|
309
331
|
h3 {
|
310
332
|
font-weight: bold;
|
@@ -336,9 +358,9 @@ body.rocket_job {
|
|
336
358
|
}
|
337
359
|
|
338
360
|
.selected {
|
339
|
-
border-bottom:
|
340
|
-
border-right:
|
341
|
-
border-top:
|
361
|
+
border-bottom: 1px solid blue;
|
362
|
+
border-right: 1px solid blue;
|
363
|
+
border-top: 1px solid blue;
|
342
364
|
background-color: lightcyan;
|
343
365
|
}
|
344
366
|
|
@@ -367,12 +389,6 @@ body.rocket_job {
|
|
367
389
|
position: relative;
|
368
390
|
text-align: center;
|
369
391
|
|
370
|
-
.icon {
|
371
|
-
color: #83ADFA;
|
372
|
-
text-align: center;
|
373
|
-
font-size: 50px;
|
374
|
-
}
|
375
|
-
|
376
392
|
.title, .state, .threads, .time { margin-bottom: 10px; }
|
377
393
|
|
378
394
|
.actions {
|
@@ -395,7 +411,7 @@ body.rocket_job {
|
|
395
411
|
}
|
396
412
|
}
|
397
413
|
|
398
|
-
.
|
414
|
+
.priority-group {
|
399
415
|
width: 67px;
|
400
416
|
margin: 0 auto;
|
401
417
|
|
@@ -436,51 +452,9 @@ body.rocket_job {
|
|
436
452
|
}
|
437
453
|
}
|
438
454
|
|
439
|
-
.green.signal {
|
440
|
-
-webkit-animation: greenPulse 2s infinite;
|
441
|
-
-moz-animation: greenPulse 2s infinite;
|
442
|
-
-o-animation: greenPulse 2s infinite;
|
443
|
-
animation: greenPulse 2s infinite;
|
444
|
-
margin: 0 5px 0 10px;
|
445
|
-
}
|
446
|
-
|
447
455
|
.code-block { margin-top: 25px; }
|
448
456
|
|
449
457
|
.status {
|
450
458
|
padding: 1em;
|
451
459
|
}
|
452
|
-
|
453
|
-
// Warnings & Notifications
|
454
|
-
|
455
|
-
.no-servers {
|
456
|
-
text-align: center;
|
457
|
-
font-size: 23px;
|
458
|
-
padding-top: 50px;
|
459
|
-
color: #777;
|
460
|
-
}
|
461
|
-
}
|
462
|
-
|
463
|
-
// Rocket Job Animations
|
464
|
-
@-webkit-keyframes greenPulse {
|
465
|
-
0% { color: #91bd09; -webkit-box-shadow: 0 0 9px #91bd09; border-radius: 30px; }
|
466
|
-
50% { color: rgb(107, 240, 123); -webkit-box-shadow: 0 0 18px rgb(107, 240, 123); border-radius: 30px; }
|
467
|
-
100% { color: #91bd09; -webkit-box-shadow: 0 0 9px #91bd09; border-radius: 30px; }
|
468
|
-
}
|
469
|
-
|
470
|
-
@-moz-keyframes greenPulse {
|
471
|
-
0% { background-color: #749a02; -moz-box-shadow: 0 0 9px #333; }
|
472
|
-
50% { background-color: lime; -moz-box-shadow: 0 0 18px #91bd09; }
|
473
|
-
100% { background-color: #749a02; -moz-box-shadow: 0 0 9px #333; }
|
474
|
-
}
|
475
|
-
|
476
|
-
@-o-keyframes greenPulse {
|
477
|
-
0% { background-color: #749a02; box-shadow: 0 0 9px #749a02; }
|
478
|
-
50% { background-color: #91bd09; box-shadow: 0 0 18px #91bd09; }
|
479
|
-
100% { background-color: #749a02; box-shadow: 0 0 9px #749a02; }
|
480
|
-
}
|
481
|
-
|
482
|
-
@keyframes greenPulse {
|
483
|
-
0% { background-color: #749a02; box-shadow: 0 0 9px #333; }
|
484
|
-
50% { background-color: #91bd09; box-shadow: 0 0 18px #91bd09; }
|
485
|
-
100% { background-color: #749a02; box-shadow: 0 0 9px #333; }
|
486
460
|
}
|
@@ -1,6 +1,18 @@
|
|
1
|
+
$border-radius-small: 2px;
|
2
|
+
$border-radius-base: 3px;
|
3
|
+
$border-radius-large: 4px;
|
4
|
+
|
1
5
|
@import "bootstrap-sprockets";
|
2
6
|
@import "bootstrap";
|
3
7
|
|
8
|
+
.alert {
|
9
|
+
margin-bottom: 0px;
|
10
|
+
}
|
11
|
+
|
4
12
|
.alert-notice {
|
5
13
|
@extend .alert-info
|
6
14
|
}
|
15
|
+
|
16
|
+
.alert-alert {
|
17
|
+
@extend .alert-danger
|
18
|
+
}
|
@@ -22,6 +22,14 @@
|
|
22
22
|
border-left-color: darkorange;
|
23
23
|
}
|
24
24
|
|
25
|
+
/* Used by Dirmon Entries */
|
26
|
+
.callout-enabled {
|
27
|
+
border-left-color: green;
|
28
|
+
}
|
29
|
+
.callout-disabled {
|
30
|
+
border-left-color: orange;
|
31
|
+
}
|
32
|
+
|
25
33
|
/* Used by Workers */
|
26
34
|
.callout-top {
|
27
35
|
border: 1px solid #eee;
|
@@ -1,4 +1,18 @@
|
|
1
1
|
.job-list {
|
2
|
+
.breadcrumb {
|
3
|
+
margin-bottom: 0px;
|
4
|
+
}
|
5
|
+
|
6
|
+
/*padding: 1px 1px 1px 1px;*/
|
7
|
+
|
8
|
+
.breadcrumb {
|
9
|
+
padding: 2px;
|
10
|
+
|
11
|
+
> li {
|
12
|
+
margin: 5px 0 0 5px;
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
2
16
|
.list {
|
3
17
|
.progress {
|
4
18
|
width: 16em;
|
@@ -14,3 +28,24 @@
|
|
14
28
|
}
|
15
29
|
}
|
16
30
|
}
|
31
|
+
|
32
|
+
.error {
|
33
|
+
pre {
|
34
|
+
margin: 0px 0px 0px 0px;
|
35
|
+
border-bottom: 0;
|
36
|
+
border-radius: 0;
|
37
|
+
word-wrap: normal;
|
38
|
+
}
|
39
|
+
|
40
|
+
pre:last-child {
|
41
|
+
border: 1px solid #cccccc;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
.pagination {
|
46
|
+
margin-top: 1em;
|
47
|
+
|
48
|
+
.btn {
|
49
|
+
border-radius: 0;
|
50
|
+
}
|
51
|
+
}
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module RocketJobMissionControl
|
2
|
+
class DirmonEntriesController < RocketJobMissionControl::ApplicationController
|
3
|
+
before_filter :find_entry_or_redirect, except: [:index, :new, :create]
|
4
|
+
before_filter :clean_values, only: [:create, :update]
|
5
|
+
before_action :load_entries, only: [:index, :show, :new, :edit]
|
6
|
+
|
7
|
+
def index
|
8
|
+
end
|
9
|
+
|
10
|
+
def show
|
11
|
+
end
|
12
|
+
|
13
|
+
def new
|
14
|
+
@dirmon_entry = RocketJob::DirmonEntry.new(arguments: nil)
|
15
|
+
end
|
16
|
+
|
17
|
+
def create
|
18
|
+
@dirmon_entry = RocketJob::DirmonEntry.new(dirmon_params)
|
19
|
+
|
20
|
+
parse_and_assign_arguments
|
21
|
+
|
22
|
+
if @dirmon_entry.errors.empty? && @dirmon_entry.save
|
23
|
+
flash[:success] = t(:success, scope: [:dirmon_entry, :create])
|
24
|
+
redirect_to(dirmon_entry_path(@dirmon_entry))
|
25
|
+
else
|
26
|
+
load_entries
|
27
|
+
render :new
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def destroy
|
32
|
+
@dirmon_entry.destroy
|
33
|
+
flash[:success] = t(:success, scope: [:dirmon_entry, :destroy])
|
34
|
+
|
35
|
+
redirect_to(dirmon_entries_path)
|
36
|
+
end
|
37
|
+
|
38
|
+
def edit
|
39
|
+
end
|
40
|
+
|
41
|
+
def update
|
42
|
+
parse_and_assign_arguments
|
43
|
+
if @dirmon_entry.errors.empty? && @dirmon_entry.update_attributes(dirmon_params)
|
44
|
+
flash[:success] = t(:success, scope: [:dirmon_entry, :update])
|
45
|
+
redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
|
46
|
+
else
|
47
|
+
load_entries
|
48
|
+
render :edit
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def enable
|
53
|
+
if @dirmon_entry.may_enable?
|
54
|
+
@dirmon_entry.enable!
|
55
|
+
flash[:success] = t(:success, scope: [:dirmon_entry, :enable])
|
56
|
+
redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
|
57
|
+
else
|
58
|
+
flash[:alert] = t(:failure, scope: [:dirmon_entry, :enable])
|
59
|
+
load_entries
|
60
|
+
render(:show)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def disable
|
65
|
+
if @dirmon_entry.may_disable?
|
66
|
+
@dirmon_entry.disable!
|
67
|
+
flash[:success] = t(:success, scope: [:dirmon_entry, :disable])
|
68
|
+
redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
|
69
|
+
else
|
70
|
+
flash[:alert] = t(:failure, scope: [:dirmon_entry, :disable])
|
71
|
+
load_entries
|
72
|
+
render(:show)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def parse_and_assign_arguments
|
79
|
+
if arguments = params[:rocket_job_dirmon_entry][:arguments]
|
80
|
+
begin
|
81
|
+
arguments = JSON.parse(arguments)
|
82
|
+
@dirmon_entry.arguments = arguments.kind_of?(Array) ? arguments : [arguments]
|
83
|
+
rescue JSON::ParserError => e
|
84
|
+
@dirmon_entry.errors.add(:arguments, e.message)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
def clean_values
|
91
|
+
params[:rocket_job_dirmon_entry].fetch(:properties, {}).each_pair do |param, value|
|
92
|
+
params[:rocket_job_dirmon_entry][:properties].delete(param) if value.blank?
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def load_entries
|
97
|
+
@states = dirmons_params
|
98
|
+
@dirmons = RocketJob::DirmonEntry.limit(1000).sort(created_at: :desc)
|
99
|
+
@dirmons = @dirmons.where(state: @states) unless @states.empty?
|
100
|
+
end
|
101
|
+
|
102
|
+
def find_entry_or_redirect
|
103
|
+
@dirmon_entry = RocketJob::DirmonEntry.find(params[:id])
|
104
|
+
|
105
|
+
if @dirmon_entry.nil?
|
106
|
+
flash[:alert] = t(:failure, scope: [:dirmon_entry, :find], id: params[:id])
|
107
|
+
|
108
|
+
redirect_to(dirmon_entries_path)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def dirmons_params
|
113
|
+
params.fetch(:states, [])
|
114
|
+
end
|
115
|
+
|
116
|
+
def dirmon_params
|
117
|
+
params
|
118
|
+
.require(:rocket_job_dirmon_entry)
|
119
|
+
.permit(:name, :archive_directory, :pattern, :job_class_name).tap do |whitelist|
|
120
|
+
whitelist[:properties] = params[:rocket_job_dirmon_entry][:properties] if params[:rocket_job_dirmon_entry][:properties]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module RocketJobMissionControl
|
2
|
+
module Jobs
|
3
|
+
class FailuresController < RocketJobMissionControl::ApplicationController
|
4
|
+
def index
|
5
|
+
job_failures = JobFailures.new(params[:job_id])
|
6
|
+
@job = job_failures.job
|
7
|
+
|
8
|
+
if @job && @job.failed?
|
9
|
+
@slice_errors = job_failures.list
|
10
|
+
@error_type = params[:error_type] || @slice_errors.first['_id']['error_class']
|
11
|
+
|
12
|
+
offset = params.fetch(:offset, 1).to_i
|
13
|
+
selected_exception = job_failures.for_error(@error_type, offset)
|
14
|
+
current_failure = selected_exception.first
|
15
|
+
|
16
|
+
@pagination = {
|
17
|
+
offset: offset,
|
18
|
+
total: (selected_exception.count - 1),
|
19
|
+
}
|
20
|
+
|
21
|
+
if current_failure.present?
|
22
|
+
@failure_exception = current_failure['exception']
|
23
|
+
end
|
24
|
+
|
25
|
+
else
|
26
|
+
redirect_to(job_path(params[:job_id]))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -12,5 +12,12 @@ module RocketJobMissionControl
|
|
12
12
|
def active_page(path)
|
13
13
|
'active' if current_page?(path)
|
14
14
|
end
|
15
|
+
|
16
|
+
def pretty_print_array_or_hash(arguments)
|
17
|
+
return arguments unless arguments.kind_of?(Array) || arguments.kind_of?(Hash)
|
18
|
+
json_string_options = { space: ' ', indent: ' ', array_nl: '<br />', object_nl: '<br />' }
|
19
|
+
JSON.generate(arguments, json_string_options).html_safe
|
20
|
+
end
|
21
|
+
|
15
22
|
end
|
16
23
|
end
|
@@ -1,13 +1,16 @@
|
|
1
1
|
module RocketJobMissionControl
|
2
2
|
module JobsHelper
|
3
3
|
STATE_ICON_MAP = {
|
4
|
-
|
4
|
+
aborted: 'fa-stop',
|
5
|
+
completed: 'fa-check',
|
6
|
+
disabled: 'fa-stop',
|
7
|
+
enabled: 'fa-check',
|
8
|
+
failed: 'fa-exclamation-triangle',
|
5
9
|
paused: 'fa-pause',
|
10
|
+
pending: 'fa-inbox',
|
11
|
+
queued: 'fa-inbox',
|
6
12
|
running: 'fa-play',
|
7
|
-
|
8
|
-
aborted: 'fa-stop',
|
9
|
-
failed: 'fa-times',
|
10
|
-
scheduled: 'fa-clock-o'
|
13
|
+
scheduled: 'fa-clock-o',
|
11
14
|
}
|
12
15
|
|
13
16
|
def job_state_icon(state)
|
@@ -25,14 +28,18 @@ module RocketJobMissionControl
|
|
25
28
|
job_state_icon(state)
|
26
29
|
end
|
27
30
|
|
28
|
-
def
|
29
|
-
|
31
|
+
def job_action_link(action, path, http_method=:get)
|
32
|
+
link_to(
|
33
|
+
action,
|
34
|
+
path,
|
35
|
+
method: http_method,
|
36
|
+
class: 'btn btn-default',
|
37
|
+
data: { confirm: t(:confirm, scope: [:job, :action], action: action)}
|
38
|
+
)
|
30
39
|
end
|
31
40
|
|
32
|
-
def
|
33
|
-
|
34
|
-
json_string_options = { space: ' ', indent: ' ', array_nl: '<br />', object_nl: '<br />' }
|
35
|
-
JSON.generate(arguments, json_string_options).html_safe
|
41
|
+
def job_states
|
42
|
+
@job_states ||= RocketJob::Job.aasm.states.map { |state| state.name.to_s }
|
36
43
|
end
|
37
44
|
|
38
45
|
def job_selected_class(job, selected_job)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class JobFailures
|
2
|
+
attr_reader :job_id
|
3
|
+
|
4
|
+
def initialize(job_id)
|
5
|
+
@job_id = job_id
|
6
|
+
end
|
7
|
+
|
8
|
+
def job
|
9
|
+
@job ||= RocketJob::Job.find(job_id)
|
10
|
+
end
|
11
|
+
|
12
|
+
def list
|
13
|
+
@slice_errors ||= job.input.collection.aggregate(
|
14
|
+
[
|
15
|
+
{
|
16
|
+
'$group' => {
|
17
|
+
_id: { error_class: '$exception.class_name' },
|
18
|
+
messages: { '$addToSet' => '$exception.message' },
|
19
|
+
count: { '$sum' => 1 }
|
20
|
+
},
|
21
|
+
}
|
22
|
+
]
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def for_error(error_type, page_offset=0)
|
27
|
+
query = { 'state' => 'failed', 'exception.class_name' => error_type }
|
28
|
+
@job.input.collection.find(query).limit(1).skip(page_offset)
|
29
|
+
end
|
30
|
+
end
|
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
= csrf_meta_tag
|
20
20
|
|
21
|
-
%link{href: "//maxcdn.bootstrapcdn.com/font-awesome/4.
|
21
|
+
%link{href: "//maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css", rel: "stylesheet"}/
|
22
22
|
|
23
23
|
%body.rocket_job
|
24
24
|
#wrapper.toggled
|
@@ -41,3 +41,5 @@
|
|
41
41
|
= msg.html_safe
|
42
42
|
|
43
43
|
= yield
|
44
|
+
|
45
|
+
%footer.footer
|
@@ -0,0 +1,36 @@
|
|
1
|
+
- action ||= :create
|
2
|
+
- if @dirmon_entry.errors.present?
|
3
|
+
.alert.alert-alert
|
4
|
+
Error saving entry!
|
5
|
+
- @dirmon_entry.errors.messages.each_pair do |field, message|
|
6
|
+
.message
|
7
|
+
= "#{field}: #{message}"
|
8
|
+
= form_for @dirmon_entry, url: {action: action} do |f|
|
9
|
+
.name.form-group
|
10
|
+
= f.label :name
|
11
|
+
= f.text_field :name, class: 'form-control'
|
12
|
+
.path.form-group
|
13
|
+
= f.label :pattern
|
14
|
+
= f.text_field :pattern, class: 'form-control'
|
15
|
+
.path.form-group
|
16
|
+
= f.label :archive_directory
|
17
|
+
= f.text_field :archive_directory, class: 'form-control'
|
18
|
+
.job.form-group
|
19
|
+
= f.label :job_class_name
|
20
|
+
= f.text_field :job_class_name, class: 'form-control'
|
21
|
+
.job_arguments.form-group
|
22
|
+
= f.label :arguments
|
23
|
+
= f.text_area :arguments,
|
24
|
+
value: @dirmon_entry.arguments.empty? ? nil : @dirmon_entry.arguments.to_json,
|
25
|
+
rows: 10,
|
26
|
+
placeholder: '{"argument1"":"value1", "argument2":"value2", "argument3":"value3"}',
|
27
|
+
class: 'form-control'
|
28
|
+
.row
|
29
|
+
.col-md-12#properties{ style: 'display:none;' }
|
30
|
+
= render partial: 'properties', locals: { f: f }
|
31
|
+
|
32
|
+
.buttons
|
33
|
+
= f.submit action, class: 'btn btn-primary'
|
34
|
+
= link_to 'cancel', :back, class: 'btn btn-default'
|
35
|
+
= button_tag 'properties',type: 'button', class: 'btn btn-default', id: 'expand'
|
36
|
+
= button_tag 'collapse',type: 'button', class: 'btn btn-default', id: 'collapse', style: 'display:none;'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
.col-md-4
|
2
|
+
.job-list
|
3
|
+
.filter
|
4
|
+
%ol.breadcrumb
|
5
|
+
%li.active Dirmon Entries
|
6
|
+
.pull-right
|
7
|
+
= link_to "Create", new_dirmon_entry_path, class: "btn btn-default"
|
8
|
+
.btn-group{ data: { toggle: 'buttons' } }
|
9
|
+
- RocketJob::DirmonEntry.aasm.states.map { |s| s.name.to_s }.each do |state|
|
10
|
+
- enabled = @states.include?(state.to_s) || @states.empty?
|
11
|
+
- title = enabled ? 'Hide' : 'Show'
|
12
|
+
%label.btn.btn-default.state-toggle{ class: ('active' if enabled), title: "#{title} #{state.to_s.capitalize}" }
|
13
|
+
= check_box_tag(state.to_s, state.to_s, enabled)
|
14
|
+
%i.fa{class: job_state_icon(state)}
|
15
|
+
.clearfix
|
16
|
+
.list
|
17
|
+
- if @dirmons.empty?
|
18
|
+
.card.inner
|
19
|
+
.title
|
20
|
+
.lead.text-center No Dirmon Entries Found.
|
21
|
+
- else
|
22
|
+
- @dirmons.each do |dirmon|
|
23
|
+
- state = dirmon.enabled? ? :enabled : :disabled
|
24
|
+
= link_to dirmon_entry_path(id: dirmon.id, states: @states), class: "card callout callout-#{dirmon.state} #{job_selected_class(dirmon, @dirmon_entry)}" do
|
25
|
+
.inner
|
26
|
+
.title
|
27
|
+
.lead
|
28
|
+
%i.fa{class: job_state_icon(dirmon.state), style: 'font-size: 75%;', title: dirmon.state}
|
29
|
+
= dirmon.name
|
30
|
+
|
31
|
+
.description= dirmon.pattern.try(:truncate, 80)
|
@@ -0,0 +1,8 @@
|
|
1
|
+
.arguments
|
2
|
+
= f.fields_for :properties do |properties|
|
3
|
+
.form-group
|
4
|
+
= properties.label :description
|
5
|
+
= properties.text_field :description, value: @dirmon_entry.properties[:description], placeholder: "max length: 128", class: 'form-control'
|
6
|
+
.form-group
|
7
|
+
= properties.label :priority
|
8
|
+
= properties.text_field :priority, value: @dirmon_entry.properties[:priority], placeholder: "e.g 1..100", class: 'form-control'
|