diff --git a/frontend/src/pages/workers.vue b/frontend/src/pages/workers.vue index 563c643..fbd19c1 100644 --- a/frontend/src/pages/workers.vue +++ b/frontend/src/pages/workers.vue @@ -1,5 +1,20 @@ \ No newline at end of file diff --git a/server/src/github.rs b/server/src/github.rs index 545167e..01a0854 100644 --- a/server/src/github.rs +++ b/server/src/github.rs @@ -2,7 +2,6 @@ use crate::ARGS; use octocrab::models::pulls::PullRequest; use octocrab::{models::InstallationId, Octocrab}; use serde::{Deserialize, Serialize}; -use teloxide::prelude::*; use teloxide::types::{ChatId, Message}; #[derive(Deserialize, Serialize, Debug)] diff --git a/server/src/main.rs b/server/src/main.rs index ac1830d..a6153b7 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -8,7 +8,8 @@ use diesel::r2d2::Pool; use server::bot::{answer, Command}; use server::recycler::recycler_worker; use server::routes::{ - dashboard_status, ping, job_list, pipeline_list, pipeline_new_pr, worker_job_update, worker_poll, AppState + dashboard_status, job_list, ping, pipeline_list, pipeline_new_pr, worker_job_update, + worker_list, worker_poll, AppState, }; use server::routes::{pipeline_new, worker_heartbeat}; use server::routes::{pipeline_status, worker_status}; @@ -70,6 +71,7 @@ async fn main() -> anyhow::Result<()> { .route("/api/worker/poll", post(worker_poll)) .route("/api/worker/job_update", post(worker_job_update)) .route("/api/worker/status", get(worker_status)) + .route("/api/worker/list", get(worker_list)) .route("/api/dashboard/status", get(dashboard_status)) .fallback_service(serve_dir) .with_state(state) diff --git a/server/src/routes.rs b/server/src/routes.rs index a121c87..c252834 100644 --- a/server/src/routes.rs +++ b/server/src/routes.rs @@ -869,3 +869,66 @@ pub async fn job_list( })?, )) } + +#[derive(Deserialize)] +pub struct WorkerListRequest { + page: i64, + items_per_page: i64, +} + +#[derive(Serialize)] +pub struct WorkerListResponseItem { + id: i32, + hostname: String, + arch: String, + logical_cores: i32, + memory_bytes: i64, +} + +#[derive(Serialize)] +pub struct WorkerListResponse { + total_items: i64, + items: Vec, +} + +pub async fn worker_list( + Query(query): Query, + State(AppState { pool, .. }): State, +) -> Result, AnyhowError> { + let mut conn = pool + .get() + .context("Failed to get db connection from pool")?; + + Ok(Json( + conn.transaction::(|conn| { + let total_items = crate::schema::workers::dsl::workers + .count() + .get_result(conn)?; + + let workers = if query.items_per_page == -1 { + crate::schema::workers::dsl::workers + .order_by(crate::schema::workers::dsl::id) + .load::(conn)? + } else { + crate::schema::workers::dsl::workers + .order_by(crate::schema::workers::dsl::id) + .offset((query.page - 1) * query.items_per_page) + .limit(query.items_per_page) + .load::(conn)? + }; + + let mut items = vec![]; + for worker in workers { + items.push(WorkerListResponseItem { + id: worker.id, + hostname: worker.hostname, + arch: worker.arch, + logical_cores: worker.logical_cores, + memory_bytes: worker.memory_bytes, + }); + } + + Ok(WorkerListResponse { total_items, items }) + })?, + )) +}