container_broker 1.0.1 → 1.1.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/README.md +11 -0
- data/app/controllers/tasks_controller.rb +1 -8
- data/app/jobs/add_task_tags_job.rb +1 -1
- data/app/jobs/run_task_job.rb +0 -3
- data/app/models/mongoid_serializable_model.rb +1 -0
- data/app/models/node.rb +2 -4
- data/app/models/task.rb +0 -1
- data/app/serializers/status_panel_task_serializer.rb +1 -1
- data/app/serializers/task_serializer.rb +1 -1
- data/app/services/friendly_name_nodes.rb +1 -1
- data/app/services/kubernetes_client.rb +3 -1
- data/app/services/lock_manager.rb +2 -1
- data/app/services/reschedule_tasks_for_missing_runners.rb +4 -4
- data/app/services/runners/kubernetes/create_execution_info.rb +10 -2
- data/config/initializers/docker_config.rb +1 -1
- data/lib/constants.rb +1 -1
- data/lib/container_broker.rb +0 -2
- data/lib/container_broker/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1d863ef7a79cf23d92d509e16473a5fb717afbb4327adf8a7c60ff0ac5483f6
|
4
|
+
data.tar.gz: 4afbefff24adf873548bfd36542d38ade60f6b8031f8a7de2274cc1820d9efbd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72276623eadee051da7078c9a203b1c5eb2ac4e82d826e1545deba5e8fba6273e6cd820b65507e76a2e34e4054701b5c893ddf9528c47079f5b790d6980973cf
|
7
|
+
data.tar.gz: 5222da3fcf97e5fb7bb962c337e21e661cd3c6922f1eeb560e6d4e40d1c90ef3b6878dc2ca2f9d14c4a02bb6fae5bdc81a64f49b597dc47e51857f56015c7e30
|
data/README.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Container Broker
|
2
2
|
|
3
|
+
## Key Features
|
4
|
+
- Run any Docker based task
|
5
|
+
- A Node only needs Docker HTTP API
|
6
|
+
- Separate Tasks by execution type
|
7
|
+
- Easily get Task logs
|
8
|
+
- Automatically retry jobs
|
9
|
+
- Enqueue tasks if no slots available
|
10
|
+
- Distribute load between Nodes
|
11
|
+
- If a node dies, tasks are automatically moved to another healthy Node (Failover)
|
12
|
+
- Support external volume mounts
|
13
|
+
|
3
14
|
## Installation
|
4
15
|
|
5
16
|
Add this line to your application's Gemfile:
|
@@ -66,14 +66,7 @@ class TasksController < ApplicationController
|
|
66
66
|
:execution_type,
|
67
67
|
storage_mounts: {},
|
68
68
|
tags: {}
|
69
|
-
)
|
70
|
-
# TODO: Remove after migrate encoder
|
71
|
-
if params.key?(:ingest_storage_mount) || params[:task].key?(:ingest_storage_mount)
|
72
|
-
permitted_params[:storage_mounts] = {
|
73
|
-
"ingest-nfs" => params[:ingest_storage_mount] || params.dig(:task, :ingest_storage_mount)
|
74
|
-
}
|
75
|
-
end
|
76
|
-
end
|
69
|
+
)
|
77
70
|
end
|
78
71
|
|
79
72
|
def set_request_id
|
data/app/jobs/run_task_job.rb
CHANGED
@@ -6,9 +6,6 @@ class RunTaskJob < ContainerBrokerBaseJob
|
|
6
6
|
queue_as :default
|
7
7
|
|
8
8
|
def perform(task:, slot:)
|
9
|
-
# TODO: remove after successful deploy
|
10
|
-
task.update!(storage_mounts: { "ingest-nfs" => task.attributes["ingest_storage_mount"] }) if task.attributes["ingest_storage_mount"] && task.storage_mounts.blank?
|
11
|
-
|
12
9
|
Rails.logger.debug("Performing RunTaskJob for #{task} #{slot}")
|
13
10
|
|
14
11
|
raise "Invalid task status - #{task}" unless task.starting?
|
data/app/models/node.rb
CHANGED
@@ -83,10 +83,8 @@ class Node
|
|
83
83
|
"Node #{name} #{uuid} #{runner_provider} (#{status}#{last_success})"
|
84
84
|
end
|
85
85
|
|
86
|
-
def run_with_lock_no_wait
|
87
|
-
LockManager.new(type: self.class.to_s, id: id, wait: false, expire: 5.minutes).lock
|
88
|
-
yield
|
89
|
-
end
|
86
|
+
def run_with_lock_no_wait(&block)
|
87
|
+
LockManager.new(type: self.class.to_s, id: id, wait: false, expire: 5.minutes).lock(&block)
|
90
88
|
end
|
91
89
|
|
92
90
|
private
|
data/app/models/task.rb
CHANGED
@@ -19,7 +19,6 @@ class Task
|
|
19
19
|
field :created_at, type: DateTime
|
20
20
|
field :started_at, type: DateTime
|
21
21
|
field :finished_at, type: DateTime
|
22
|
-
field :progress, type: String
|
23
22
|
field :try_count, type: Integer, default: 0
|
24
23
|
field :persist_logs, type: Boolean, default: false
|
25
24
|
field :tags, type: Hash, default: {}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
class StatusPanelTaskSerializer < ActiveModel::Serializer
|
4
4
|
attributes :uuid, :name, :image, :cmd, :status, :exit_code, :error, :try_count, :created_at,
|
5
|
-
:started_at, :finished_at, :
|
5
|
+
:started_at, :finished_at, :seconds_running, :tags, :runner_id,
|
6
6
|
:storage_mounts, :slot, :execution_type
|
7
7
|
|
8
8
|
def slot
|
@@ -3,7 +3,7 @@
|
|
3
3
|
class FriendlyNameNodes
|
4
4
|
def perform
|
5
5
|
Node.order(runner_provider: :desc, hostname: :asc, id: :asc).each_with_index do |node, index|
|
6
|
-
node.update(name:
|
6
|
+
node.update(name: format("n%<sequence>02d%<provider>s", sequence: (index + 1), provider: node.runner_provider.first))
|
7
7
|
FriendlyNameSlots.new(node: node).perform
|
8
8
|
end
|
9
9
|
end
|
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
class KubernetesClient
|
4
4
|
class PodNotFoundError < StandardError; end
|
5
|
+
|
5
6
|
class NetworkError < StandardError; end
|
7
|
+
|
6
8
|
class LogsNotFoundError < StandardError; end
|
7
9
|
|
8
10
|
LOG_UNAVAILABLE_HTTP_ERROR = 400
|
@@ -20,7 +22,7 @@ class KubernetesClient
|
|
20
22
|
end
|
21
23
|
|
22
24
|
# rubocop:disable Metrics/ParameterLists
|
23
|
-
def create_pod(pod_name:, image:, cmd:, internal_mounts: [], external_mounts: []
|
25
|
+
def create_pod(pod_name:, image:, cmd:, node_selector:, internal_mounts: [], external_mounts: [])
|
24
26
|
handle_exception do
|
25
27
|
pod = Kubeclient::Resource.new(
|
26
28
|
metadata: {
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
class LockManager
|
4
4
|
attr_reader :expire, :wait, :locked, :key
|
5
|
+
|
5
6
|
KEY_PREFIX = "lockmanager"
|
6
7
|
|
7
8
|
def initialize(type:, id:, expire:, wait: true)
|
@@ -13,7 +14,7 @@ class LockManager
|
|
13
14
|
def lock
|
14
15
|
if lock!
|
15
16
|
begin
|
16
|
-
yield(self)
|
17
|
+
yield(self) if block_given?
|
17
18
|
ensure
|
18
19
|
unlock!
|
19
20
|
end
|
@@ -11,7 +11,7 @@ class RescheduleTasksForMissingRunners
|
|
11
11
|
def perform
|
12
12
|
tasks_without_runner.each do |runner_id|
|
13
13
|
task = started_tasks_group_by_runner_id[runner_id]
|
14
|
-
message = "Task
|
14
|
+
message = "Task retried because runner is missing"
|
15
15
|
Rails.logger.debug(message)
|
16
16
|
|
17
17
|
report_event(message: message, task: task, runner_id: runner_id)
|
@@ -36,18 +36,18 @@ class RescheduleTasksForMissingRunners
|
|
36
36
|
runner: slot&.node&.runner_provider,
|
37
37
|
runner_id: runner_id,
|
38
38
|
slot: {
|
39
|
-
|
39
|
+
uuid: slot&.uuid,
|
40
40
|
name: slot&.name,
|
41
41
|
status: slot&.status,
|
42
42
|
runner_id: slot&.runner_id
|
43
43
|
},
|
44
44
|
node: {
|
45
|
-
|
45
|
+
uuid: node&.uuid,
|
46
46
|
name: node&.name,
|
47
47
|
status: node&.status
|
48
48
|
},
|
49
49
|
task: {
|
50
|
-
|
50
|
+
uuid: task.uuid,
|
51
51
|
name: task.name,
|
52
52
|
status: task.status
|
53
53
|
}
|
@@ -16,9 +16,9 @@ module Runners
|
|
16
16
|
Runners::ExecutionInfo.new(
|
17
17
|
id: pod&.metadata&.name,
|
18
18
|
status: status,
|
19
|
-
exit_code:
|
19
|
+
exit_code: exit_code,
|
20
20
|
started_at: started_at,
|
21
|
-
finished_at:
|
21
|
+
finished_at: finished_at,
|
22
22
|
error: error_message,
|
23
23
|
schedule_pending: schedule_pending?
|
24
24
|
)
|
@@ -54,6 +54,14 @@ module Runners
|
|
54
54
|
container_status&.state&.terminated&.exitCode&.zero?
|
55
55
|
end
|
56
56
|
|
57
|
+
def exit_code
|
58
|
+
container_status&.state&.terminated&.exitCode
|
59
|
+
end
|
60
|
+
|
61
|
+
def finished_at
|
62
|
+
container_status&.state&.terminated&.finishedAt
|
63
|
+
end
|
64
|
+
|
57
65
|
def reason_is_error?
|
58
66
|
waiting? && ERROR_REASONS.include?(reason[:reason])
|
59
67
|
end
|
data/lib/constants.rb
CHANGED
data/lib/container_broker.rb
CHANGED
@@ -12,7 +12,6 @@ require "current_thread_request_id"
|
|
12
12
|
require "config"
|
13
13
|
require "docker-api"
|
14
14
|
require "active_model_serializers"
|
15
|
-
require "config"
|
16
15
|
require "idempotent-request"
|
17
16
|
require "kubeclient"
|
18
17
|
require "mongoid/uuid"
|
@@ -22,7 +21,6 @@ require "sentry-raven"
|
|
22
21
|
require "sidekiq"
|
23
22
|
require "sidekiq-failures"
|
24
23
|
require "sidekiq-scheduler"
|
25
|
-
require "docker-api"
|
26
24
|
require "measures"
|
27
25
|
|
28
26
|
module ContainerBroker
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: container_broker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Douglas Lise
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2021-01-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
@@ -583,7 +583,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
583
583
|
- !ruby/object:Gem::Version
|
584
584
|
version: '0'
|
585
585
|
requirements: []
|
586
|
-
rubygems_version: 3.1.
|
586
|
+
rubygems_version: 3.1.4
|
587
587
|
signing_key:
|
588
588
|
specification_version: 4
|
589
589
|
summary: ContainerBroker
|