barbeque 0.0.1 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -3
  3. data/Rakefile +2 -6
  4. data/app/assets/javascripts/barbeque/application.js +5 -0
  5. data/app/assets/javascripts/barbeque/job_definitions.coffee +10 -0
  6. data/app/assets/stylesheets/barbeque/application.scss +7 -0
  7. data/app/assets/stylesheets/barbeque/common.scss +22 -0
  8. data/app/assets/stylesheets/barbeque/job_definitions.scss +21 -0
  9. data/app/controllers/barbeque/api/application_controller.rb +22 -0
  10. data/app/controllers/barbeque/api/job_executions_controller.rb +35 -0
  11. data/app/controllers/barbeque/api/job_retries_controller.rb +28 -0
  12. data/app/controllers/barbeque/api/revision_locks_controller.rb +34 -0
  13. data/app/controllers/barbeque/apps_controller.rb +43 -0
  14. data/app/controllers/barbeque/job_definitions_controller.rb +86 -0
  15. data/app/controllers/barbeque/job_executions_controller.rb +19 -0
  16. data/app/controllers/barbeque/job_queues_controller.rb +59 -0
  17. data/app/controllers/barbeque/job_retries_controller.rb +10 -0
  18. data/app/helpers/barbeque/job_definitions_helper.rb +14 -0
  19. data/app/helpers/barbeque/job_executions_helper.rb +18 -0
  20. data/app/models/{api → barbeque/api}/application_resource.rb +3 -1
  21. data/app/models/{api → barbeque/api}/job_execution_resource.rb +1 -1
  22. data/app/models/{api → barbeque/api}/job_retry_resource.rb +1 -1
  23. data/app/models/barbeque/api/revision_lock_resource.rb +7 -0
  24. data/app/models/{app.rb → barbeque/app.rb} +1 -1
  25. data/app/models/barbeque/job_definition.rb +26 -0
  26. data/app/models/{job_execution.rb → barbeque/job_execution.rb} +7 -4
  27. data/app/models/{job_queue.rb → barbeque/job_queue.rb} +1 -1
  28. data/app/models/{job_retry.rb → barbeque/job_retry.rb} +7 -2
  29. data/app/models/{slack_notification.rb → barbeque/slack_notification.rb} +1 -1
  30. data/app/services/barbeque/message_enqueuing_service.rb +41 -0
  31. data/app/services/barbeque/message_retrying_service.rb +32 -0
  32. data/app/views/barbeque/apps/_form.html.haml +34 -0
  33. data/app/views/barbeque/apps/edit.html.haml +3 -0
  34. data/app/views/barbeque/apps/index.html.haml +24 -0
  35. data/app/views/barbeque/apps/new.html.haml +3 -0
  36. data/app/views/barbeque/apps/show.html.haml +47 -0
  37. data/app/views/barbeque/job_definitions/_form.html.haml +45 -0
  38. data/app/views/barbeque/job_definitions/_slack_notification_field.html.haml +35 -0
  39. data/app/views/barbeque/job_definitions/edit.html.haml +3 -0
  40. data/app/views/barbeque/job_definitions/index.html.haml +24 -0
  41. data/app/views/barbeque/job_definitions/new.html.haml +3 -0
  42. data/app/views/barbeque/job_definitions/show.html.haml +90 -0
  43. data/app/views/barbeque/job_definitions/stats.html.haml +52 -0
  44. data/app/views/barbeque/job_executions/show.html.haml +92 -0
  45. data/app/views/barbeque/job_queues/_form.html.haml +29 -0
  46. data/app/views/barbeque/job_queues/edit.html.haml +3 -0
  47. data/app/views/barbeque/job_queues/index.html.haml +22 -0
  48. data/app/views/barbeque/job_queues/new.html.haml +3 -0
  49. data/app/views/barbeque/job_queues/show.html.haml +22 -0
  50. data/app/views/barbeque/job_retries/show.html.haml +59 -0
  51. data/app/views/layouts/barbeque/_header.html.haml +10 -0
  52. data/app/views/layouts/barbeque/_sidebar.html.haml +16 -0
  53. data/app/views/layouts/barbeque/application.html.haml +24 -0
  54. data/app/views/layouts/barbeque/apps.html.haml +6 -0
  55. data/app/views/layouts/barbeque/job_definitions.html.haml +6 -0
  56. data/app/views/layouts/barbeque/job_executions.html.haml +5 -0
  57. data/app/views/layouts/barbeque/job_queues.html.haml +6 -0
  58. data/config/initializers/garage.rb +4 -0
  59. data/config/routes.rb +32 -0
  60. data/db/migrate/20160829023237_prefix_barbeque_to_tables.rb +10 -0
  61. data/lib/barbeque.rb +3 -5
  62. data/lib/barbeque/configuration.rb +19 -0
  63. data/lib/barbeque/docker_image.rb +20 -0
  64. data/lib/barbeque/engine.rb +11 -0
  65. data/lib/barbeque/execution_log.rb +51 -0
  66. data/lib/barbeque/message.rb +28 -0
  67. data/lib/barbeque/message/base.rb +29 -0
  68. data/lib/barbeque/message/invalid_message.rb +11 -0
  69. data/lib/barbeque/message/job_execution.rb +20 -0
  70. data/lib/barbeque/message/job_retry.rb +16 -0
  71. data/lib/barbeque/message_handler.rb +8 -0
  72. data/lib/barbeque/message_handler/job_execution.rb +86 -0
  73. data/lib/barbeque/message_handler/job_retry.rb +83 -0
  74. data/lib/barbeque/message_queue.rb +66 -0
  75. data/lib/barbeque/runner.rb +12 -0
  76. data/lib/barbeque/runner/docker.rb +34 -0
  77. data/lib/barbeque/slack_client.rb +48 -0
  78. data/lib/barbeque/version.rb +1 -1
  79. data/lib/barbeque/worker.rb +58 -0
  80. data/lib/tasks/barbeque_tasks.rake +9 -4
  81. metadata +272 -18
  82. data/app/assets/stylesheets/barbeque/application.css +0 -15
  83. data/app/models/application_record.rb +0 -3
  84. data/app/models/job_definition.rb +0 -14
  85. data/app/views/layouts/barbeque/application.html.erb +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e46d5b56b2da9d6dd1f8a969884b89d9279e45c6
4
- data.tar.gz: 7cd2c731b320400a63b45b709599b73c8801199b
3
+ metadata.gz: f577ecaa96a85f7b40832305df8d0283e833f542
4
+ data.tar.gz: 72ec989120b97cf6efeada1a158d359002c0970c
5
5
  SHA512:
6
- metadata.gz: 43b4573b33bdfc1178a034fa6e88e3ad016db86cd360d6789095579716641bceb5cac6703de07ac3ad521fa9fb34df579d15381b877bc0d166dfafd213ed96e7
7
- data.tar.gz: 7e5f93abd4464bfbac2d6c52051c9ca38eefb89d9ea2e1f83f8b13e4ddde596b1bc77ff8c5838a8131a540c7f281b6010ed3a16808fdd662ea826b7ecfbc6618
6
+ metadata.gz: 86aab750c582060510dd9107bc8566357df56113a98b46f64109875cadf5524b8b01612b3b362d1d1a886a403c0556caf00f2fa649cb075cfd69432e128a7512
7
+ data.tar.gz: f7facf66c24eec3c1dab88c7947f3a2dcf1b5befbb60780c52caa60e2eb4b1ce6c16a8e1b7545d0f2736794a06573a816efadd2b8e1f8d6630537b6f9070d31c
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # Barbeque
2
- Short description and motivation.
3
2
 
4
- ## Usage
5
- How to use my plugin.
3
+ ## Status
4
+ Currently we are migrating from closed-source version to open-source version and writing documentation.
6
5
 
7
6
  ## Installation
8
7
  Add this line to your application's Gemfile:
data/Rakefile CHANGED
@@ -14,11 +14,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
17
-
18
-
19
- load 'rails/tasks/statistics.rake'
20
-
21
-
22
-
23
17
  require 'bundler/gem_tasks'
18
+ require File.expand_path('../spec/dummy/config/application', __FILE__)
24
19
 
20
+ Rails.application.load_tasks
@@ -10,4 +10,9 @@
10
10
  // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
11
  // about supported directives.
12
12
  //
13
+ //= require jquery
14
+ //= require bootstrap-sprockets
15
+ //= require jquery_ujs
16
+ //= require app
17
+ //= require plotly-basic
13
18
  //= require_tree .
@@ -0,0 +1,10 @@
1
+ jQuery ($) ->
2
+ return if $('.job_definitions_controller').length == 0
3
+
4
+ $('.use_slack_notification').bind('change', (event) ->
5
+ enabledField = $('.slack_notification_field')
6
+ if event.target.value == 'true'
7
+ enabledField.removeClass('active')
8
+ else
9
+ enabledField.addClass('active')
10
+ )
@@ -0,0 +1,7 @@
1
+ @import "bootstrap-sprockets";
2
+ @import "bootstrap";
3
+ @import "AdminLTE/AdminLTE";
4
+ @import "AdminLTE/skins/skin-blue";
5
+
6
+ @import "barbeque/common";
7
+ @import "barbeque/job_definitions";
@@ -0,0 +1,22 @@
1
+ $border_color: #ececec;
2
+
3
+ .box-body {
4
+ padding: 12px;
5
+ }
6
+
7
+ .box-header {
8
+ .box-title.with_padding {
9
+ padding: 6px;
10
+ font-size: 22px;
11
+ }
12
+ }
13
+
14
+ .table.table-bordered {
15
+ margin-bottom: 12px;
16
+ border-color: $border_color;
17
+
18
+ td,
19
+ th {
20
+ border-color: $border_color;
21
+ }
22
+ }
@@ -0,0 +1,21 @@
1
+ .job_definitions_controller {
2
+ .use_slack_notification_wrapper label {
3
+ font-weight: normal;
4
+ }
5
+
6
+ .use_slack_notification {
7
+ margin: 0 2px 0 8px;
8
+ }
9
+
10
+ .slack_notification_field {
11
+ display: none;
12
+
13
+ label {
14
+ font-weight: normal;
15
+ }
16
+
17
+ &.active {
18
+ display: block;
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,22 @@
1
+ require 'garage'
2
+
3
+ class Barbeque::Api::ApplicationController < ActionController::Base
4
+ include Garage::ControllerHelper
5
+
6
+ rescue_from ActiveRecord::RecordNotFound do |exception|
7
+ respond_with_error(404, 'record_not_found', exception.message)
8
+ end
9
+
10
+ rescue_from WeakParameters::ValidationError do |exception|
11
+ respond_with_error(400, 'invalid_parameter', exception.message)
12
+ end
13
+
14
+ private
15
+
16
+ # @param [Integer] status_code HTTP status code
17
+ # @param [String] error_code Must be unique
18
+ # @param [String] message Error message for API client, not for end user.
19
+ def respond_with_error(status_code, error_code, message)
20
+ render json: { status_code: status_code, error_code: error_code, message: message }, status: status_code
21
+ end
22
+ end
@@ -0,0 +1,35 @@
1
+ class Barbeque::Api::JobExecutionsController < Barbeque::Api::ApplicationController
2
+ include Garage::RestfulActions
3
+
4
+ validates :create do
5
+ string :application, required: true, description: 'Application name of the job'
6
+ string :job, required: true, description: 'Class of Job to be enqueued'
7
+ string :queue, required: true, description: 'Queue name to enqueue a job'
8
+ any :message, required: true, description: 'Free-format JSON'
9
+ end
10
+
11
+ private
12
+
13
+ def require_resources
14
+ protect_resource_as Barbeque::Api::JobExecutionResource
15
+ end
16
+
17
+ def require_resource
18
+ @resource = Barbeque::JobExecution.find_or_initialize_by(message_id: params[:message_id])
19
+ end
20
+
21
+ def create_resource
22
+ message_id = enqueue_message
23
+ Barbeque::JobExecution.new(message_id: message_id).to_resource
24
+ end
25
+
26
+ # @return [String] id of a message queued to SQS.
27
+ def enqueue_message
28
+ Barbeque::MessageEnqueuingService.new(
29
+ application: params[:application],
30
+ job: params[:job],
31
+ queue: params[:queue],
32
+ message: params[:message],
33
+ ).run
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ class Barbeque::Api::JobRetriesController < Barbeque::Api::ApplicationController
2
+ include Garage::RestfulActions
3
+
4
+ # http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html
5
+ SQS_MAX_DELAY_SECONDS = 900
6
+
7
+ validates :create do
8
+ integer :delay_seconds, only: 0..SQS_MAX_DELAY_SECONDS
9
+ end
10
+
11
+ private
12
+
13
+ def require_resources
14
+ protect_resource_as Barbeque::Api::JobRetryResource
15
+ end
16
+
17
+ def create_resource
18
+ result = retry_message
19
+ Barbeque::JobRetry.new(message_id: result.message_id).to_resource
20
+ end
21
+
22
+ def retry_message
23
+ Barbeque::MessageRetryingService.new(
24
+ message_id: params[:job_execution_message_id],
25
+ delay_seconds: params[:delay_seconds].to_i,
26
+ ).run
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ class Barbeque::Api::RevisionLocksController < Barbeque::Api::ApplicationController
2
+ include Garage::RestfulActions
3
+
4
+ validates :create do
5
+ string :revision, required: true, description: 'Docker image revision to lock'
6
+ end
7
+
8
+ private
9
+
10
+ def require_resources
11
+ protect_resource_as Barbeque::Api::RevisionLockResource
12
+ end
13
+
14
+ def require_resource
15
+ @resource = Barbeque::App.find_by!(name: params[:app_name])
16
+ end
17
+
18
+ def create_resource
19
+ app = Barbeque::App.find_by!(name: params[:app_name])
20
+ image = Barbeque::DockerImage.new(app.docker_image)
21
+ image.tag = params[:revision]
22
+ app.update!(docker_image: image.to_s)
23
+
24
+ Barbeque::Api::RevisionLockResource.new(app)
25
+ end
26
+
27
+ def destroy_resource
28
+ image = Barbeque::DockerImage.new(@resource.docker_image)
29
+ image.tag = 'latest'
30
+ @resource.update!(docker_image: image.to_s)
31
+
32
+ Barbeque::Api::RevisionLockResource.new(@resource)
33
+ end
34
+ end
@@ -0,0 +1,43 @@
1
+ class Barbeque::AppsController < Barbeque::ApplicationController
2
+ def index
3
+ @apps = Barbeque::App.all
4
+ end
5
+
6
+ def show
7
+ @app = Barbeque::App.find(params[:id])
8
+ end
9
+
10
+ def new
11
+ @app = Barbeque::App.new
12
+ end
13
+
14
+ def edit
15
+ @app = Barbeque::App.find(params[:id])
16
+ end
17
+
18
+ def create
19
+ @app = Barbeque::App.new(params.require(:app).permit(:name, :docker_image, :description))
20
+
21
+ if @app.save
22
+ redirect_to @app, notice: 'App was successfully created.'
23
+ else
24
+ render :new
25
+ end
26
+ end
27
+
28
+ def update
29
+ @app = Barbeque::App.find(params[:id])
30
+ # Name can't be changed after it's created.
31
+ if @app.update(params.require(:app).permit(:docker_image, :description))
32
+ redirect_to @app, notice: 'App was successfully updated.'
33
+ else
34
+ render :edit
35
+ end
36
+ end
37
+
38
+ def destroy
39
+ @app = Barbeque::App.find(params[:id])
40
+ @app.destroy
41
+ redirect_to root_path, notice: 'App was successfully destroyed.'
42
+ end
43
+ end
@@ -0,0 +1,86 @@
1
+ class Barbeque::JobDefinitionsController < Barbeque::ApplicationController
2
+ def index
3
+ @job_definitions = Barbeque::JobDefinition.all
4
+ end
5
+
6
+ def show
7
+ @job_definition = Barbeque::JobDefinition.find(params[:id])
8
+ @job_executions = @job_definition.job_executions.order(id: :desc).page(params[:page])
9
+ end
10
+
11
+ def new
12
+ @job_definition = Barbeque::JobDefinition.new
13
+ @job_definition.build_slack_notification
14
+ if params[:job_definition]
15
+ @job_definition.assign_attributes(new_job_definition_params)
16
+ end
17
+ end
18
+
19
+ def edit
20
+ @job_definition = Barbeque::JobDefinition.find(params[:id])
21
+ if @job_definition.slack_notification.nil?
22
+ @job_definition.build_slack_notification
23
+ end
24
+ end
25
+
26
+ def create
27
+ attributes = new_job_definition_params.merge(command: command_array)
28
+ @job_definition = Barbeque::JobDefinition.new(attributes)
29
+
30
+ if @job_definition.save
31
+ redirect_to @job_definition, notice: 'Job definition was successfully created.'
32
+ else
33
+ render :new
34
+ end
35
+ end
36
+
37
+ def update
38
+ @job_definition = Barbeque::JobDefinition.find(params[:id])
39
+ attributes = params.require(:job_definition).permit(
40
+ :description,
41
+ slack_notification_attributes: slack_notification_params,
42
+ ).merge(command: command_array)
43
+ if @job_definition.update(attributes)
44
+ redirect_to @job_definition, notice: 'Job definition was successfully updated.'
45
+ else
46
+ render :edit
47
+ end
48
+ end
49
+
50
+ def destroy
51
+ @job_definition = Barbeque::JobDefinition.find(params[:id])
52
+ @job_definition.destroy
53
+ redirect_to job_definitions_url, notice: 'Job definition was successfully destroyed.'
54
+ end
55
+
56
+ def stats
57
+ @job_definition = Barbeque::JobDefinition.find(params[:job_definition_id])
58
+ @days = (params[:days] || 3).to_i
59
+ end
60
+
61
+ def execution_stats
62
+ job_definition = Barbeque::JobDefinition.find(params[:job_definition_id])
63
+ days = (params[:days] || 3).to_i
64
+ now = Time.zone.now
65
+ render json: job_definition.execution_stats(days.days.ago(now), now)
66
+ end
67
+
68
+ private
69
+
70
+ def slack_notification_params
71
+ %i[id channel notify_success failure_notification_text _destroy]
72
+ end
73
+
74
+ def command_array
75
+ Shellwords.split(params.require(:job_definition)[:command])
76
+ end
77
+
78
+ def new_job_definition_params
79
+ params.require(:job_definition).permit(
80
+ :job,
81
+ :app_id,
82
+ :description,
83
+ slack_notification_attributes: slack_notification_params,
84
+ )
85
+ end
86
+ end
@@ -0,0 +1,19 @@
1
+ class Barbeque::JobExecutionsController < Barbeque::ApplicationController
2
+ def show
3
+ @job_execution = Barbeque::JobExecution.find(params[:id])
4
+ log = @job_execution.execution_log
5
+ @message = log['message']
6
+ @stdout = log['stdout']
7
+ @stderr = log['stderr']
8
+ end
9
+
10
+ def retry
11
+ @job_execution = Barbeque::JobExecution.find(params[:job_execution_id])
12
+ raise ActionController::BadRequest unless @job_execution.failed?
13
+
14
+ result = Barbeque::MessageRetryingService.new(message_id: @job_execution.message_id).run
15
+ @job_execution.retried!
16
+
17
+ redirect_to @job_execution, notice: "Succeed to retry (message_id=#{result.message_id})"
18
+ end
19
+ end
@@ -0,0 +1,59 @@
1
+ class Barbeque::JobQueuesController < Barbeque::ApplicationController
2
+ def index
3
+ @job_queues = Barbeque::JobQueue.all
4
+ end
5
+
6
+ def show
7
+ @job_queue = Barbeque::JobQueue.find(params[:id])
8
+ end
9
+
10
+ def new
11
+ @job_queue = Barbeque::JobQueue.new
12
+ end
13
+
14
+ def edit
15
+ @job_queue = Barbeque::JobQueue.find(params[:id])
16
+ end
17
+
18
+ def create
19
+ @job_queue = Barbeque::JobQueue.new(params.require(:job_queue).permit(:name, :description))
20
+ @job_queue.queue_url = create_queue(@job_queue).queue_url if @job_queue.valid?
21
+
22
+ if @job_queue.save
23
+ redirect_to @job_queue, notice: 'Job queue was successfully created.'
24
+ else
25
+ render :new
26
+ end
27
+ end
28
+
29
+ def update
30
+ @job_queue = Barbeque::JobQueue.find(params[:id])
31
+ # Name can't be changed after it's created.
32
+ if @job_queue.update(params.require(:job_queue).permit(:description))
33
+ redirect_to @job_queue, notice: 'Job queue was successfully updated.'
34
+ else
35
+ render :edit
36
+ end
37
+ end
38
+
39
+ def destroy
40
+ @job_queue = Barbeque::JobQueue.find(params[:id])
41
+ @job_queue.destroy
42
+ redirect_to job_queues_url, notice: 'Job queue was successfully destroyed.'
43
+ end
44
+
45
+ private
46
+
47
+ # @return [Aws::SQS::Types::CreateQueueResult] A struct which has only queue_url.
48
+ def create_queue(job_queue)
49
+ Aws::SQS::Client.new.create_queue(
50
+ queue_name: job_queue.sqs_queue_name,
51
+ attributes: {
52
+ # All SQS queues' "ReceiveMessageWaitTimeSeconds" are configured to be 20s (maximum).
53
+ # This should be as large as possible to reduce API-calling cost by long polling.
54
+ # http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_CreateQueue.html#API_CreateQueue_RequestParameters
55
+ 'ReceiveMessageWaitTimeSeconds' => Barbeque::JobQueue::SQS_RECEIVE_MESSAGE_WAIT_TIME.to_s,
56
+ },
57
+ )
58
+ end
59
+ end