Class: OodCore::Job::Adapters::Coder::Batch
- Inherits:
-
Object
- Object
- OodCore::Job::Adapters::Coder::Batch
- Defined in:
- lib/ood_core/job/adapters/coder/batch.rb
Overview
Utility class for the Coder adapter to interact with the Coders API.
Defined Under Namespace
Classes: Error
Instance Method Summary collapse
- #api_call(method, endpoint, headers, body = nil) ⇒ Object
- #build_coder_job_info(json_data, status) ⇒ Object
- #coder_state_to_ood_status(coder_state) ⇒ Object
- #delete(id) ⇒ Object
- #end_time(json_data, status) ⇒ Object
- #get_headers(coder_token) ⇒ Object
- #get_rich_parameters(coder_parameters, project_id, app_credentials) ⇒ Object
- #info(id) ⇒ Object
-
#initialize(config, credentials) ⇒ Batch
constructor
A new instance of Batch.
- #start_time(json_data) ⇒ Object
- #submit(script) ⇒ Object
- #username ⇒ Object
- #wait_for_workspace_deletion(id) ⇒ Object
- #wallclock_time(json_data, status) ⇒ Object
- #workspace_info_from_json(json_data) ⇒ Object
- #workspace_json(id) ⇒ Object
Constructor Details
#initialize(config, credentials) ⇒ Batch
Returns a new instance of Batch.
9 10 11 12 13 14 15 16 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 9 def initialize(config, credentials) @host = config[:host] @token = config[:token] @service_user = config[:service_user] @credential_deletion_max_attempts = config[:credential_deletion_max_attempts] || 5 @credential_deletion_timeout_interval = config[:credential_deletion_timeout_interval] || 10 @credentials = credentials end |
Instance Method Details
#api_call(method, endpoint, headers, body = nil) ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 162 def api_call(method, endpoint, headers, body = nil) uri = URI(endpoint) case method.downcase when 'get' request = Net::HTTP::Get.new(uri, headers) when 'post' request = Net::HTTP::Post.new(uri, headers) when 'delete' request = Net::HTTP::Delete.new(uri, headers) else raise ArgumentError, "Invalid HTTP method: #{method}" end request.body = body.to_json if body response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http| http.request(request) end case response when Net::HTTPSuccess JSON.parse(response.body) else raise Error, "HTTP Error: #{response.code} #{response.} for request #{endpoint} and body #{body}" end end |
#build_coder_job_info(json_data, status) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 117 def build_coder_job_info(json_data, status) = json_data["latest_build"]["resources"] &.find { |resource| resource["name"] == "coder_output" } &.dig("metadata") coder_output_hash = &.map { || [["key"].to_sym, ["value"]] }&.to_h || {} OodCore::Job::Adapters::Coder::CoderJobInfo.new(**{ id: json_data["id"], job_name: json_data["workspace_name"], status: OodCore::Job::Status.new(state: status), job_owner: json_data["workspace_owner_name"], submission_time: json_data["created_at"], dispatch_time: json_data.dig("updated_at"), wallclock_time: wallclock_time(json_data, status), ood_connection_info: { host: coder_output_hash[:floating_ip], port: 80 }, native: coder_output_hash }) end |
#coder_state_to_ood_status(coder_state) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 100 def coder_state_to_ood_status(coder_state) case coder_state when "starting" "queued" when "failed" "suspended" when "running" "running" when "deleted" "completed" when "stopped" "completed" else "undetermined" end end |
#delete(id) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 61 def delete(id) endpoint = "#{@host}/api/v2/workspaces/#{id}/builds" headers = get_headers(@token) body = { 'orphan' => false, 'transition' => 'delete' } api_call('post', endpoint, headers, body) credentials = @credentials.load_credentials(id, username) wait_for_workspace_deletion(id) do |attempt| puts "#{Time.now.inspect} Deleting workspace (attempt #{attempt + 1}/#{5})" end @credentials.destroy_credentials(credentials, workspace_json(id).dig("latest_build", "status"), id, username) end |
#end_time(json_data, status) ⇒ Object
146 147 148 149 150 151 152 153 154 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 146 def end_time(json_data, status) if status == 'deleted' end_time_string = json_data["latest_build"].dig("updated_at") et = DateTime.parse(end_time_string).to_time.to_i else et = DateTime.now.to_time.to_i end et end |
#get_headers(coder_token) ⇒ Object
33 34 35 36 37 38 39 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 33 def get_headers(coder_token) { 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Coder-Session-Token' => coder_token } end |
#get_rich_parameters(coder_parameters, project_id, app_credentials) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 18 def get_rich_parameters(coder_parameters, project_id, app_credentials) rich_parameter_values = [ { name: "application_credential_name", value: app_credentials[:name] }, { name: "application_credential_id", value: app_credentials[:id] }, { name: "application_credential_secret", value: app_credentials[:secret] }, {name: "project_id", value: project_id } ] if coder_parameters coder_parameters.each do |key, value| rich_parameter_values << { name: key, value: value.to_s} end end rich_parameter_values end |
#info(id) ⇒ Object
96 97 98 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 96 def info(id) workspace_info_from_json(workspace_json(id)) end |
#start_time(json_data) ⇒ Object
141 142 143 144 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 141 def start_time(json_data) start_time_string = json_data.dig("updated_at") DateTime.parse(start_time_string).to_time.to_i end |
#submit(script) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 41 def submit(script) org_id = script.native[:org_id] project_id = script.native[:project_id] coder_parameters = script.native[:coder_parameters] endpoint = "#{@host}/api/v2/organizations/#{org_id}/members/#{@service_user}/workspaces" app_credentials = @credentials.generate_credentials(project_id, username) headers = get_headers(@token) workspace_name = "#{username}-#{script.native[:workspace_name]}-#{rand(2_821_109_907_456).to_s(36)}" body = { template_version_id: script.native[:template_version_id], name: workspace_name, rich_parameter_values: get_rich_parameters(coder_parameters, project_id, app_credentials), } resp = api_call('post', endpoint, headers, body) @credentials.save_credentials(resp["id"], username, app_credentials) resp["id"] end |
#username ⇒ Object
187 188 189 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 187 def username @username ||= Etc.getlogin end |
#wait_for_workspace_deletion(id) ⇒ Object
79 80 81 82 83 84 85 86 87 88 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 79 def wait_for_workspace_deletion(id) max_attempts = @credential_deletion_max_attempts timeout_interval = @credential_deletion_timeout_interval max_attempts.times do |attempt| break unless workspace_json(id) && workspace_json(id).dig("latest_build", "status") == "deleting" yield(attempt + 1) sleep(timeout_interval) end end |
#wallclock_time(json_data, status) ⇒ Object
135 136 137 138 139 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 135 def wallclock_time(json_data, status) start_time = start_time(json_data) end_time = end_time(json_data, status) end_time - start_time end |
#workspace_info_from_json(json_data) ⇒ Object
156 157 158 159 160 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 156 def workspace_info_from_json(json_data) state = json_data.dig("latest_build", "status") || json_data.dig("latest_build", "job", "status") status = coder_state_to_ood_status(state) build_coder_job_info(json_data, status) end |
#workspace_json(id) ⇒ Object
90 91 92 93 94 |
# File 'lib/ood_core/job/adapters/coder/batch.rb', line 90 def workspace_json(id) endpoint = "#{@host}/api/v2/workspaces/#{id}?include_deleted=true" headers = get_headers(@token) api_call('get', endpoint, headers) end |