kuroko2 0.2.3 → 0.3.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.
- 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
|