Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions shard.lock
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ shards:

git-repository:
git: https://github.com/place-labs/git-repository.git
version: 1.5.0
version: 1.6.0

google:
git: https://github.com/placeos/google.git
Expand Down Expand Up @@ -167,7 +167,7 @@ shards:

place_calendar:
git: https://github.com/placeos/calendar.git
version: 4.26.0
version: 4.28.0

placeos-core-client:
git: https://github.com/placeos/core-client.git
Expand All @@ -183,7 +183,7 @@ shards:

placeos-models:
git: https://github.com/placeos/models.git
version: 9.72.3
version: 9.74.0

placeos-resource:
git: https://github.com/place-labs/resource.git
Expand Down
18 changes: 18 additions & 0 deletions spec/api/build_monitor_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
require "../helper"

module PlaceOS::Core::Api
describe BuildMonitor, tags: "api" do
client = AC::SpecHelper.client

describe "GET /api/core/v1/build" do
it "monitor job status" do
response = client.get("/api/core/v1/build/monitor")
response.status_code.should eq 200
end
it "monitor job status" do
response = client.get("/api/core/v1/build/cancel/asdfasfasfasd")
response.status_code.should eq 404
end
end
end
end
31 changes: 31 additions & 0 deletions src/api/build_monitor.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require "./application"

module PlaceOS::Core::Api
class BuildMonitor < Application
base "/api/core/v1/build/"

protected getter store = DriverStore.new

@[AC::Route::GET("/monitor")]
def monitor(
@[AC::Param::Info(name: "state", description: "state of job to return. One of [pending,running,cancelled error,done]. Defaults to 'pending'", example: "pending")]
state : DriverStore::State = DriverStore::State::Pending,
) : Array(DriverStore::TaskStatus) | String
result = store.monitor_jobs(state)
if result[:success]
render json: result[:output]
else
render status: result[:code], text: result[:output]
end
end

@[AC::Route::DELETE("/cancel/:job")]
def cancel(
@[AC::Param::Info(name: "job", description: "ID of previously submitted compilation job")]
job : String,
) : DriverStore::CancelStatus
result = store.cancel_job(job)
render status: result[:code], json: result[:output]
end
end
end
22 changes: 22 additions & 0 deletions src/placeos-core/driver_manager/build_api.cr
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,27 @@ module PlaceOS::Core
end
end
end

def self.monitor(state : String)
host = URI.parse(Core.build_host)
ConnectProxy::HTTPClient.new(host) do |client|
path = "#{BUILD_API_BASE}/monitor"
params = URI::Params.encode({"state" => state})
uri = "#{path}?#{params}"
rep = client.get(uri)
Log.debug { {message: "Getting build service monitor. Server respose: #{rep.status_code}", state: state} }
rep
end
end

def self.cancel_job(job : String)
host = URI.parse(Core.build_host)
ConnectProxy::HTTPClient.new(host) do |client|
path = "#{BUILD_API_BASE}/cancel/#{URI.encode_www_form(job)}"
rep = client.delete(path)
Log.debug { {message: "Cancelling build job. Server respose: #{rep.status_code}", job: job} }
rep
end
end
end
end
42 changes: 42 additions & 0 deletions src/placeos-core/driver_manager/driver_store.cr
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,47 @@ module PlaceOS::Core
@[JSON::Field(converter: Time::EpochConverter)]
getter link_expiry : Time
end

enum State
Pending
Running
Cancelled
Error
Done

def to_s(io : IO) : Nil
io << (member_name || value.to_s).downcase
end

def to_s : String
String.build { |io| to_s(io) }
end
end

record TaskStatus, state : State, id : String, message : String,
driver : String, repo : String, branch : String, commit : String, timestamp : Time do
include JSON::Serializable
end

record CancelStatus, status : String, message : String do
include JSON::Serializable
end

def monitor_jobs(state : State = State::Pending)
resp = BuildApi.monitor(state.to_s)
return {success: true, output: Array(TaskStatus).from_json(resp.body), code: 200} if resp.success?
{success: false, output: "Build service returned #{resp.status_code} with reponse #{resp.body}", code: resp.status_code}
rescue ex
{success: false, output: "Call to Build service endpoint failed with error #{ex.message}", code: 500}
end

def cancel_job(job : String)
resp = BuildApi.cancel_job(job)

return {success: true, output: CancelStatus.from_json(resp.body), code: resp.status_code} if resp.success? || resp.status_code == 409
{success: false, output: CancelStatus.new("error", "Build service returned #{resp.status_code} with reponse #{resp.body}"), code: resp.status_code}
rescue ex
{success: false, output: CancelStatus.new("error", "Call to Build service endpoint failed with error #{ex.message}"), code: 500}
end
end
end
Loading