barbeque 0.0.1 → 0.0.10

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.
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