kuroko2 0.2.3 → 0.3.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/kuroko2/definition_linker.js +1 -1
- data/app/assets/stylesheets/kuroko2/application.scss +4 -0
- data/app/controllers/kuroko2/api/job_instances_controller.rb +3 -2
- data/app/controllers/kuroko2/dashboard_controller.rb +1 -1
- data/app/controllers/kuroko2/job_definitions_controller.rb +2 -2
- data/app/controllers/kuroko2/job_instances_controller.rb +8 -18
- data/app/controllers/kuroko2/tokens_controller.rb +3 -3
- data/app/controllers/kuroko2/users_controller.rb +17 -1
- data/app/models/kuroko2/job_definition.rb +11 -0
- data/app/models/kuroko2/job_instance.rb +19 -2
- data/app/models/kuroko2/job_schedule.rb +3 -6
- data/app/models/kuroko2/job_suspend_schedule.rb +1 -1
- data/app/models/kuroko2/token.rb +8 -0
- data/app/views/kuroko2/execution_logs/index.json.jbuilder +1 -1
- data/app/views/kuroko2/job_definitions/_form.html.slim +6 -1
- data/app/views/kuroko2/job_definitions/_list.html.slim +12 -5
- data/app/views/kuroko2/job_definitions/_search_results.html.slim +10 -3
- data/app/views/kuroko2/job_definitions/show.html.slim +5 -3
- data/app/views/kuroko2/job_timelines/dataset.json.jbuilder +1 -1
- data/app/views/kuroko2/logs/index.html.slim +6 -6
- data/app/views/kuroko2/tokens/index.html.slim +2 -2
- data/app/views/kuroko2/users/edit.html.slim +37 -0
- data/app/views/kuroko2/users/show.html.slim +8 -4
- data/db/migrate/026_add_webhook_url_to_job_definitions.rb +5 -0
- data/lib/autoload/kuroko2/workflow/engine.rb +4 -6
- data/lib/autoload/kuroko2/workflow/notifier/concerns/chat_message_builder.rb +12 -0
- data/lib/autoload/kuroko2/workflow/notifier/hipchat.rb +30 -4
- data/lib/autoload/kuroko2/workflow/notifier/mail.rb +9 -1
- data/lib/autoload/kuroko2/workflow/notifier/slack.rb +31 -4
- data/lib/autoload/kuroko2/workflow/notifier/webhook.rb +173 -0
- data/lib/autoload/kuroko2/workflow/task/queue.rb +2 -2
- data/lib/autoload/kuroko2/workflow/task/sub_process.rb +2 -4
- data/lib/kuroko2/version.rb +1 -1
- data/spec/controllers/users_controller_spec.rb +51 -2
- data/spec/dummy/config/kuroko2.yml +2 -0
- data/spec/dummy/db/schema.rb +76 -92
- data/spec/dummy/log/development.log +1143 -0
- data/spec/dummy/log/test.log +271238 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-Q/-QhKaYdB1JJGAsq6Ih7uQZJD46XkY5Gw0-38DBDVg3Y.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-h/-h4P8jVHGGfJVwG36J8kBUkHFa3HHGNiJQz0936uaxg.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/24/24laeo7m53bkbst3Gxu4hlJY-EbnK-rQxH-DA4ujzwY.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/2e/2eEFzw4UUZHJizptl3nT5jVv3IL25_RdYImr3lAVlJ4.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/2z/2z8OmZrK1FFsPb8zq9RFli2IVM0gOna92hieZ4cK36c.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4K/4Ky9Fg4qo8d_i8bJF6NOhDpxHuJ5kIX8n0w6C8wdHDU.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Di/Di9ZEIp2OLO96tkqFN21AWfdoAhc0OCBOJb3o8RUk1I.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ex/ExgjnrLZM8Hc_uT_sWVaQSNR26tGYCGUsbJDXs9GYO0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/FJ/FJW4oZDLKhsjg_UHdycQAY88BFtnMeeLCuArx6HIMdM.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Iq/IqSpSELRWrOQtOK8F6mGZFPvfafM4yn8gB_VquH9E50.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/JJ/JJ2dvNSAjiGkZZs_1Dz2TMWDJs4HypQ95b26cHN13I0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/LJ/LJsVKu6GCC14s20BfJEDXwajK6-xWF72ANX5ONOTX1w.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/LL/LLCxb9El_km568UsA8DDOe8Vh3pPKE8IU6ZNww9ie8s.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Pq/pqeS6zqHUdv-_25W2PSQMm31ql_cIpaK1iqEcfiNyUQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Q9/Q9TwXzoqqs8Dm9v25gjZxYIkZW1UKm2X8g2koo5aYhQ.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/QJ/QJNiKbGgll2T_0mhQus6ZL9a2SM4Xqz7vs2V2KbELPw.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/QV/QVVeFw88kC-7HfzOk_dCVoFBnz9W_7-gmJFYh-Xlh-0.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Qs/QsTn160WUaI8_u8tE8rz37XiSV9qLvSxiXAR-tCtV3Y.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/V2/V2QhbjrEGa7in5Uj1P-3E1Ziw2AGno_ADefUhPNHw_A.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Vj/VjICw6h8uQ_278ekFlu1znnPR8Gz1vWF_mRgy0KjZXs.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/dH/dHFrKzzqtF3aoKs2wAI8z0CNHZoNuytfiHur9Zgz9z0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fE/fEFAQG1Uqt2e58VitSFoPsjVjntfPtgL9RKoKHUTS9U.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fM/FMdA_jabowoG5SAWE93G7Hu8A-5GhfzC9Gjy3EJp1Ts.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/hI/hIIciXZzgFWXdW0lamhs4r5zFFr4hnXvWAuOihCS5qI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/hW/hWOkA9ZbQJy1YfEXThjYPOiXRDVRgAeW8TmLm-uQCYk.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/iv/ivrIChCv2olhH20VXJQTJgVWlx3t9ncsYxV0QfLT0Bs.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/k3/k31T18tx4gR2rhpmDMYMLUa8KPDt7QRIR_qRK56LOdE.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oB/oB0c7AuqQVdgqJDgphXXOHw3SXqbDUYfZWxxm9-v_is.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ou/ouMQatdL-PPhPVPw5o0xm5EBkVeVWLti06EUEVmfOBo.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/qM/qMZbagtANt1BI7qOJXWEpzxx1qa-IKMkyOy6EKEIIbE.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/rc/rcceqGk009vh5_tK6Y-i1dvbYQwuUtRF888xZcnZrj8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sJ/sJOLo6McRe1YhfgIaGhcDaAoulIdYY7Rs07TAKmrSoY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sh/shGRyWpXjqxMTGB3As4Vibs8VGS0bZHHd4s0qabhwXI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sr/SRfo3vCtDVy0qd-OB9dv5a-xIVTHkJZDn8XwY_ymy7g.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/vV/vV3Loym0NolgPoXFEVPOr5rDgB_Q5kvUA3InuEEvEvQ.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wK/wK5S37PPHfwFm-4mrLMMPdOZ29-H75zo1T2gmErWjLI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wm/wm_qI7_LCxbnH6p7BK1Pqcocl-6TcULzTERICGZIdL0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zC/zCYIl3BglB_fMHME2oqK30CF97CBUG09R0ICLpE-pIM.cache +0 -0
- data/spec/features/dashborad_spec.rb +10 -3
- data/spec/features/users_spec.rb +20 -4
- data/spec/models/job_instance_spec.rb +1 -1
- data/spec/models/token_spec.rb +38 -0
- data/spec/workflow/notifier/hipchat_spec.rb +91 -0
- data/spec/workflow/notifier/mail_spec.rb +18 -2
- data/spec/workflow/notifier/slack_spec.rb +85 -0
- data/spec/workflow/notifier/webhook_spec.rb +187 -0
- data/spec/workflow/task/queue_spec.rb +11 -0
- metadata +93 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05a36b6a990355277232fb05c8fee73420178657
|
4
|
+
data.tar.gz: ff0313b72bea3ff95c7961f92193ae7350cbee68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94d255d97eed6354e37040ebff9c4bd2e4692c44f79bf3b7a9596a6ac5a12cd3c7b0585f3550b647b8453454a9b3d8352bc16427373576e03815761424b6df75
|
7
|
+
data.tar.gz: 9069f81f985f8b57b9885230be1eecfa6561f3fd0987afcfa041e4826f46560b89feb4817ea7b3832fbc90351cb84ab431cd115fbc1004f5edda3d4344feabdf
|
@@ -1,6 +1,6 @@
|
|
1
1
|
jQuery(function ($) {
|
2
2
|
function setDeifinitionLink(script) {
|
3
|
-
script = script.replace(/sub_process:\s+(\d+)\s
|
3
|
+
script = script.replace(/sub_process:\s+(\d+)\s*$/gm, function(match, jobId) {
|
4
4
|
return '<a href="/definitions/' + jobId + '">' + match + '</a>';
|
5
5
|
});
|
6
6
|
|
@@ -19,10 +19,11 @@ class Kuroko2::Api::JobInstancesController < Kuroko2::Api::ApplicationController
|
|
19
19
|
raise HTTP::Forbidden.new("#{definition.name} is not allowed to be executed via API")
|
20
20
|
end
|
21
21
|
|
22
|
-
instance = definition.
|
22
|
+
instance = definition.create_instance(
|
23
23
|
script: definition.script.prepend(env_script),
|
24
|
+
launched_by: "instances API (#{basic_user_name})"
|
24
25
|
)
|
25
|
-
|
26
|
+
|
26
27
|
Kuroko2::Api::JobInstanceResource.new(instance)
|
27
28
|
end
|
28
29
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Kuroko2::DashboardController < Kuroko2::ApplicationController
|
2
2
|
def index
|
3
|
-
@definitions = current_user.job_definitions
|
3
|
+
@definitions = current_user.job_definitions.includes(:tags, :job_instances, :job_schedules)
|
4
4
|
|
5
5
|
@input_tags = params[:tag] || []
|
6
6
|
if @input_tags.present?
|
@@ -2,7 +2,7 @@ class Kuroko2::JobDefinitionsController < Kuroko2::ApplicationController
|
|
2
2
|
before_action :set_definition, only: [:show, :edit, :update, :destroy]
|
3
3
|
|
4
4
|
def index
|
5
|
-
rel = Kuroko2::JobDefinition
|
5
|
+
rel = Kuroko2::JobDefinition.joins(:admins).includes(:tags, :job_instances, :job_schedules, :admins)
|
6
6
|
query = query_params[:q]
|
7
7
|
|
8
8
|
if query.present?
|
@@ -83,7 +83,7 @@ class Kuroko2::JobDefinitionsController < Kuroko2::ApplicationController
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def definition_params
|
86
|
-
params.require(:job_definition).permit(:name, :description, :script, :notify_cancellation, :hipchat_room, :hipchat_notify_finished, :suspended, :prevent_multi, :prevent_multi_on_failure, :hipchat_additional_text, :text_tags, :api_allowed, :slack_channel)
|
86
|
+
params.require(:job_definition).permit(:name, :description, :script, :notify_cancellation, :hipchat_room, :hipchat_notify_finished, :suspended, :prevent_multi, :prevent_multi_on_failure, :hipchat_additional_text, :text_tags, :api_allowed, :slack_channel, :webhook_url)
|
87
87
|
end
|
88
88
|
|
89
89
|
def query_params
|
@@ -9,24 +9,18 @@ class Kuroko2::JobInstancesController < Kuroko2::ApplicationController
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def create
|
12
|
+
creation_params = { launched_by: current_user.name }
|
12
13
|
if params[:job_definition].present?
|
13
|
-
|
14
|
-
else
|
15
|
-
@instance = @definition.job_instances.create
|
14
|
+
creation_params.merge!(params.require(:job_definition).permit(:script).to_h.symbolize_keys)
|
16
15
|
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
redirect_to job_definition_job_instance_path(@definition, @instance)
|
22
|
-
else
|
23
|
-
raise HTTP::BadRequest
|
24
|
-
end
|
17
|
+
@instance = @definition.create_instance(creation_params)
|
18
|
+
redirect_to job_definition_job_instance_path(@definition, @instance)
|
25
19
|
end
|
26
20
|
|
27
21
|
def show
|
28
|
-
@logs = @instance.logs
|
29
|
-
@tokens = @instance.tokens
|
22
|
+
@logs = @instance.logs.order(:id)
|
23
|
+
@tokens = @instance.tokens.order(:id)
|
30
24
|
|
31
25
|
if params[:mode] == :naked
|
32
26
|
render partial: 'instance', layout: false
|
@@ -37,11 +31,7 @@ class Kuroko2::JobInstancesController < Kuroko2::ApplicationController
|
|
37
31
|
|
38
32
|
def destroy
|
39
33
|
if @instance.cancelable?
|
40
|
-
ActiveRecord::Base.transaction { @instance.cancel }
|
41
|
-
|
42
|
-
message = "This job was canceled by #{current_user.name}."
|
43
|
-
@instance.logs.warn(message)
|
44
|
-
Kuroko2.logger.warn(message)
|
34
|
+
ActiveRecord::Base.transaction { @instance.cancel(by: current_user.name) }
|
45
35
|
end
|
46
36
|
|
47
37
|
redirect_to job_definition_job_instance_path(@definition, @instance)
|
@@ -54,7 +44,7 @@ class Kuroko2::JobInstancesController < Kuroko2::ApplicationController
|
|
54
44
|
execution.update_column(:execution_id, nil) if execution
|
55
45
|
end
|
56
46
|
|
57
|
-
@instance.cancel
|
47
|
+
@instance.cancel(by: current_user.name)
|
58
48
|
end
|
59
49
|
|
60
50
|
message = "Force canceled by #{current_user.name}."
|
@@ -14,12 +14,12 @@ class Kuroko2::TokensController < Kuroko2::ApplicationController
|
|
14
14
|
def update
|
15
15
|
@instance = @token.job_instance
|
16
16
|
|
17
|
-
case
|
18
|
-
when 'skip'
|
17
|
+
case
|
18
|
+
when params[:invoke] == 'skip' && @token.skippable?
|
19
19
|
@instance.logs.info("Skipped by #{current_user.name}.")
|
20
20
|
|
21
21
|
@engine.skip(@token)
|
22
|
-
when 'retry'
|
22
|
+
when params[:invoke] == 'retry' && @token.retryable?
|
23
23
|
@instance.logs.info("Retry by #{current_user.name}.")
|
24
24
|
|
25
25
|
@engine.retry(@token)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class Kuroko2::UsersController < Kuroko2::ApplicationController
|
2
|
-
before_action :set_user, only: [:destroy]
|
2
|
+
before_action :set_user, only: [:edit, :update, :destroy]
|
3
|
+
before_action :require_group_user, only: [:edit, :update, :destroy]
|
3
4
|
|
4
5
|
def index
|
5
6
|
@user = Kuroko2::User.new
|
@@ -23,6 +24,17 @@ class Kuroko2::UsersController < Kuroko2::ApplicationController
|
|
23
24
|
@related_tags = @definitions.includes(:tags).map(&:tags).flatten.uniq
|
24
25
|
end
|
25
26
|
|
27
|
+
def edit
|
28
|
+
end
|
29
|
+
|
30
|
+
def update
|
31
|
+
if @user.update(user_params)
|
32
|
+
redirect_to user_path(@user)
|
33
|
+
else
|
34
|
+
render action: :edit
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
26
38
|
def create
|
27
39
|
@user = Kuroko2::User.new(user_params)
|
28
40
|
@user.provider = Kuroko2::User::GROUP_PROVIDER
|
@@ -59,4 +71,8 @@ class Kuroko2::UsersController < Kuroko2::ApplicationController
|
|
59
71
|
def page_params
|
60
72
|
params.permit(:page)
|
61
73
|
end
|
74
|
+
|
75
|
+
def require_group_user
|
76
|
+
head :bad_request if @user.google_account?
|
77
|
+
end
|
62
78
|
end
|
@@ -77,6 +77,7 @@ class Kuroko2::JobDefinition < Kuroko2::ApplicationRecord
|
|
77
77
|
with: /\A#[^\.\s]+\z/, allow_blank: true,
|
78
78
|
message: ' must start with # and must not include any dots or spaces'
|
79
79
|
}
|
80
|
+
validates :webhook_url, format: { with: /\A#{URI::regexp(%w(http https))}\z/, allow_blank: true }
|
80
81
|
|
81
82
|
def proceed_multi_instance?
|
82
83
|
tokens = Kuroko2::Token.where(job_definition_id: self.id)
|
@@ -93,6 +94,16 @@ class Kuroko2::JobDefinition < Kuroko2::ApplicationRecord
|
|
93
94
|
end
|
94
95
|
end
|
95
96
|
|
97
|
+
def create_instance(script: nil, launched_by:, token: nil )
|
98
|
+
message = "Launched by #{launched_by}"
|
99
|
+
|
100
|
+
if token.present?
|
101
|
+
message = "(token #{token.uuid}) #{message}"
|
102
|
+
end
|
103
|
+
|
104
|
+
job_instances.create!(script: script, log_message: message)
|
105
|
+
end
|
106
|
+
|
96
107
|
private
|
97
108
|
|
98
109
|
def confirm_active_instances
|
@@ -3,6 +3,8 @@ class Kuroko2::JobInstance < Kuroko2::ApplicationRecord
|
|
3
3
|
|
4
4
|
belongs_to :job_definition
|
5
5
|
|
6
|
+
attr_accessor :log_message
|
7
|
+
|
6
8
|
has_many :logs, dependent: :delete_all do
|
7
9
|
def info(message)
|
8
10
|
add('INFO', message)
|
@@ -26,6 +28,7 @@ class Kuroko2::JobInstance < Kuroko2::ApplicationRecord
|
|
26
28
|
has_one :memory_consumption_log, dependent: :destroy
|
27
29
|
|
28
30
|
before_create :copy_script
|
31
|
+
after_create :notify_launch
|
29
32
|
after_create :generate_token
|
30
33
|
|
31
34
|
scope :working, -> { where(finished_at: nil, canceled_at: nil) }
|
@@ -43,10 +46,16 @@ class Kuroko2::JobInstance < Kuroko2::ApplicationRecord
|
|
43
46
|
tokens.first.try(:cancelable?)
|
44
47
|
end
|
45
48
|
|
46
|
-
def cancel
|
49
|
+
def cancel(by:)
|
47
50
|
self.tokens.destroy(*self.tokens)
|
48
51
|
self.executions.destroy(*self.executions)
|
49
52
|
self.touch(:canceled_at)
|
53
|
+
|
54
|
+
message = "This job was canceled by #{by}."
|
55
|
+
self.logs.warn(message)
|
56
|
+
Kuroko2.logger.warn(message)
|
57
|
+
|
58
|
+
Kuroko2::Workflow::Notifier.notify(:cancellation, self) if job_definition.hipchat_notify_finished?
|
50
59
|
end
|
51
60
|
|
52
61
|
# Log given value if it is greater than stored one.
|
@@ -84,6 +93,14 @@ class Kuroko2::JobInstance < Kuroko2::ApplicationRecord
|
|
84
93
|
self.script = job_definition.try(:script) if self.script.blank?
|
85
94
|
end
|
86
95
|
|
96
|
+
def notify_launch
|
97
|
+
if log_message
|
98
|
+
Kuroko2.logger.info(log_message)
|
99
|
+
self.logs.info(log_message)
|
100
|
+
Kuroko2::Workflow::Notifier.notify(:launch, self)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
87
104
|
def generate_token
|
88
105
|
unless self.job_definition
|
89
106
|
raise 'No parent association is found'
|
@@ -112,7 +129,7 @@ class Kuroko2::JobInstance < Kuroko2::ApplicationRecord
|
|
112
129
|
self.logs.warn(message)
|
113
130
|
Kuroko2.logger.warn(message)
|
114
131
|
|
115
|
-
Kuroko2::Workflow::Notifier.notify(:cancellation, self)
|
132
|
+
Kuroko2::Workflow::Notifier.notify(:cancellation, self) if job_definition.notify_cancellation
|
116
133
|
end
|
117
134
|
end
|
118
135
|
end
|
@@ -47,7 +47,7 @@ class Kuroko2::JobSchedule < Kuroko2::ApplicationRecord
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
scheduled_times
|
50
|
+
scheduled_times.map(&:in_time_zone)
|
51
51
|
end
|
52
52
|
|
53
53
|
def suspend_times(time_from, time_to)
|
@@ -81,11 +81,8 @@ class Kuroko2::JobSchedule < Kuroko2::ApplicationRecord
|
|
81
81
|
elsif suspend_times.include?(time)
|
82
82
|
Kuroko2.logger.info("Skipped schedule suspended \"##{definition.id} #{definition.name}\" that is scheduled at #{I18n.l(time, format: :short)} by `#{schedule.cron}`")
|
83
83
|
else
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
instance = definition.job_instances.create
|
88
|
-
instance.logs.info(message)
|
84
|
+
launched_by = "\"##{definition.id} #{definition.name}\" that is scheduled at #{I18n.l(time, format: :short)} by `#{schedule.cron}`"
|
85
|
+
definition.create_instance(launched_by: launched_by)
|
89
86
|
end
|
90
87
|
end
|
91
88
|
end
|
data/app/models/kuroko2/token.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
json.token @response.next_forward_token
|
2
2
|
json.events do
|
3
3
|
json.array! @response.events do |event|
|
4
|
-
json.timestamp
|
4
|
+
json.timestamp Time.at(event.timestamp/1000).in_time_zone
|
5
5
|
begin
|
6
6
|
log = JSON.parse(event.message)
|
7
7
|
json.message rinku_auto_link(html_escape(log['message']), :urls)
|
@@ -32,14 +32,19 @@
|
|
32
32
|
|
33
33
|
label Notification
|
34
34
|
.form-group
|
35
|
+
label Hipchat Room Name
|
35
36
|
= form.text_field :hipchat_room, class: 'form-control', placeholder: 'Hipchat Room name'
|
36
37
|
.form-group
|
38
|
+
label Slack Channel
|
37
39
|
= form.text_field :slack_channel, class: 'form-control', placeholder: '#slack-channel'
|
40
|
+
.form-group
|
41
|
+
label Webhook URL
|
42
|
+
= form.text_field :webhook_url, class: 'form-control', placeholder: 'http://example.com/webhook/endpoint'
|
38
43
|
|
39
44
|
.checkbox
|
40
45
|
label
|
41
46
|
= form.check_box :hipchat_notify_finished
|
42
|
-
' Notify
|
47
|
+
' Notify all event to Slack/Hipchat/Webhook
|
43
48
|
|
44
49
|
.checkbox
|
45
50
|
label
|
@@ -4,9 +4,9 @@
|
|
4
4
|
tr
|
5
5
|
th #
|
6
6
|
th.col-md-3 Name
|
7
|
-
th.col-md-
|
8
|
-
th.col-md-
|
9
|
-
th.col-md-
|
7
|
+
th.col-md-2 Next Job
|
8
|
+
th.col-md-1 Latest Status
|
9
|
+
th.col-md-5 data-defaultsort='disabled' Tags / Description
|
10
10
|
th.col-md-1 data-defaultsort='disabled'
|
11
11
|
tbody
|
12
12
|
- for definition in definitions
|
@@ -19,8 +19,15 @@
|
|
19
19
|
- else
|
20
20
|
td data-value="9999999999" --
|
21
21
|
td= labeled_status(definition.job_instances.take)
|
22
|
-
td= first_line(definition.description)
|
23
22
|
td
|
24
|
-
|
23
|
+
- definition.tags.each do |tag|
|
24
|
+
=link_to tag.name, { 'tag': [tag.name] }, class: 'label label-default spacer-right-3'
|
25
|
+
= first_line(definition.description)
|
26
|
+
td
|
27
|
+
= link_to definition, class: 'btn btn-sm btn-default' do
|
28
|
+
i class="fa fa-chevron-right"
|
29
|
+
|
|
30
|
+
span class="small" View Details
|
31
|
+
|
25
32
|
- else
|
26
33
|
.text-muted.well.well-sm.no-shadow There are no favorite job definitions.
|
@@ -26,7 +26,7 @@
|
|
26
26
|
th #
|
27
27
|
th.col-md-3 Name
|
28
28
|
th.col-md-3 Administrators
|
29
|
-
th.col-md-5 Description
|
29
|
+
th.col-md-5 Tags / Description
|
30
30
|
th.col-md-1
|
31
31
|
- for definition in definitions
|
32
32
|
tr
|
@@ -39,9 +39,16 @@
|
|
39
39
|
- definition.admins.each do |user|
|
40
40
|
= link_to user.name, user_path(user)
|
41
41
|
br
|
42
|
-
td= first_line(definition.description)
|
43
42
|
td
|
44
|
-
|
43
|
+
- definition.tags.each do |tag|
|
44
|
+
=link_to tag.name, job_definitions_path('tag': [tag.name]), class: 'label label-default spacer-right-3'
|
45
|
+
= first_line(definition.description)
|
46
|
+
td
|
47
|
+
= link_to definition, class: 'btn btn-sm btn-default' do
|
48
|
+
i class="fa fa-chevron-right"
|
49
|
+
|
|
50
|
+
span class="small" View Details
|
51
|
+
|
45
52
|
- else
|
46
53
|
- if params[:q].present?
|
47
54
|
.text-muted.well.well-sm.no-shadow No results found for the query.
|
@@ -19,7 +19,7 @@
|
|
19
19
|
|
20
20
|
h4= 'Tags'
|
21
21
|
- for tag in @definition.tags
|
22
|
-
=link_to tag.name, job_definitions_path(tag: [tag.name]), class: '
|
22
|
+
=link_to tag.name, job_definitions_path(tag: [tag.name]), class: 'label label-default spacer-right-3'
|
23
23
|
|
24
24
|
h3= 'Administrator'.pluralize(@definition.admins.count)
|
25
25
|
ul.media-list
|
@@ -43,16 +43,18 @@
|
|
43
43
|
- if @definition.hipchat_room.present? || @definition.slack_channel.present?
|
44
44
|
- if @definition.hipchat_notify_finished?
|
45
45
|
li
|
46
|
-
'Notify all event to Slack/Hipchat
|
46
|
+
'Notify all event to Slack/Hipchat/Webhook
|
47
47
|
ul
|
48
|
+
li webhook url: #{@definition.webhook_url}
|
48
49
|
li hipchat room: #{@definition.hipchat_room}
|
49
50
|
li slack channel: #{@definition.slack_channel}
|
50
51
|
- if @definition.hipchat_additional_text
|
51
52
|
li Failure notification text: #{@definition.hipchat_additional_text}
|
52
53
|
- else
|
53
54
|
li
|
54
|
-
'Notify failure event to Slack/Hipchat
|
55
|
+
'Notify failure event to Slack/Hipchat/Webhook
|
55
56
|
ul
|
57
|
+
li webhook url: #{@definition.webhook_url}
|
56
58
|
li hipchat room: #{@definition.hipchat_room}
|
57
59
|
li slack channel: #{@definition.slack_channel}
|
58
60
|
- if @definition.hipchat_additional_text
|
@@ -5,7 +5,7 @@ json.data do
|
|
5
5
|
json.id instance.id
|
6
6
|
json.content "<a href='#{job_definition_job_instance_path(instance.job_definition, instance)}'>##{instance.job_definition.id} #{instance.job_definition.name}</a>"
|
7
7
|
json.start instance.created_at.strftime('%Y-%m-%d %H:%M:%S')
|
8
|
-
json.end (instance.error_at || instance.canceled_at || instance.finished_at).try!(:strftime, '%Y-%m-%d %H:%M:%S')
|
8
|
+
json.end (instance.error_at || instance.canceled_at || instance.finished_at || Time.current).try!(:strftime, '%Y-%m-%d %H:%M:%S')
|
9
9
|
json.group instance.job_definition.id
|
10
10
|
end
|
11
11
|
end
|