diff options
-rw-r--r-- | src/dbctx.rs | 46 | ||||
-rw-r--r-- | src/main.rs | 67 | ||||
-rw-r--r-- | src/sql.rs | 3 |
3 files changed, 116 insertions, 0 deletions
diff --git a/src/dbctx.rs b/src/dbctx.rs index a5de23d..a646c19 100644 --- a/src/dbctx.rs +++ b/src/dbctx.rs @@ -361,6 +361,20 @@ impl DbCtx { Ok(artifacts) } + pub fn repo_by_id(&self, id: u64) -> Result<Option<Repo>, String> { + self.conn.lock() + .unwrap() + .query_row("select * from repos where id=?1", [id], |row| { + let (id, repo_name) = row.try_into().unwrap(); + Ok(Repo { + id, + name: repo_name, + }) + }) + .optional() + .map_err(|e| e.to_string()) + } + pub fn get_repos(&self) -> Result<Vec<Repo>, String> { let conn = self.conn.lock().unwrap(); @@ -444,6 +458,38 @@ impl DbCtx { Ok(jobs) } + pub fn get_started_jobs(&self) -> Result<Vec<Job>, String> { + let conn = self.conn.lock().unwrap(); + + let mut started_query = conn.prepare(sql::STARTED_JOBS).unwrap(); + let mut jobs = started_query.query([]).unwrap(); + let mut started = Vec::new(); + + while let Some(row) = jobs.next().unwrap() { + let (id, artifacts_path, state, run_host, remote_id, commit_id, created_time, start_time, complete_time, build_token, job_timeout, source, build_result, final_text) = row.try_into().unwrap(); + let state: u8 = state; + + started.push(Job { + id, + artifacts_path, + state: state.try_into().unwrap(), + run_host, + remote_id, + commit_id, + created_time, + start_time, + complete_time, + build_token, + job_timeout, + source, + build_result, + final_text, + }); + } + + Ok(started) + } + pub fn get_pending_jobs(&self) -> Result<Vec<PendingJob>, String> { let conn = self.conn.lock().unwrap(); diff --git a/src/main.rs b/src/main.rs index 1b9b31b..ddd263c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -401,6 +401,73 @@ async fn handle_ci_index(State(ctx): State<WebserverState>) -> impl IntoResponse } response.push_str("</table>"); + response.push_str("<h4>active jobs</h4>\n"); + + let jobs = ctx.dbctx.get_started_jobs().expect("can query"); + if jobs.len() == 0 { + response.push_str("<p>(none)</p>\n"); + } else { + response.push_str("<table class='build-table'>"); + response.push_str("<tr>\n"); + let headings = ["repo", "last build", "job", "build commit", "duration", "status", "result"]; + for heading in headings { + response.push_str(&format!("<th class='row-item'>{}</th>", heading)); + } + response.push_str("</tr>\n"); + + let mut row_num = 0; + + for job in jobs.iter() { + let row_index = row_num % 2; + + let remote = ctx.dbctx.remote_by_id(job.remote_id).expect("query succeeds").expect("remote id is valid"); + let repo = ctx.dbctx.repo_by_id(remote.repo_id).expect("query succeeds").expect("repo id is valid"); + + let repo_html = format!("<a href=\"/{}\">{}</a>", &repo.name, &repo.name); + + let job_commit = ctx.dbctx.commit_sha(job.commit_id).expect("job has a commit"); + let commit_html = match commit_url(&job, &job_commit, &ctx.dbctx) { + Some(url) => format!("<a href=\"{}\">{}</a>", url, &job_commit), + None => job_commit.clone() + }; + + let job_html = format!("<a href=\"{}\">{}</a>", job_url(&job, &job_commit, &ctx.dbctx), job.id); + + let last_build_time = Utc.timestamp_millis_opt(job.created_time as i64).unwrap().to_rfc2822(); + let duration = display_job_time(&job); + + let status = format!("{:?}", job.state).to_lowercase(); + + let result = match job.build_result { + Some(0) => "<span style='color:green;'>pass</span>", + Some(_) => "<span style='color:red;'>fail</span>", + None => match job.state { + JobState::Pending => { "unstarted" }, + JobState::Started => { "<span style='color:darkgoldenrod;'>in progress</span>" }, + _ => { "<span style='color:red;'>unreported</span>" } + } + }; + + let entries = [repo_html.as_str(), last_build_time.as_str(), job_html.as_str(), commit_html.as_str(), &duration, &status, &result]; + let entries = entries.iter().chain(std::iter::repeat(&"")).take(headings.len()); + + let mut row_html = String::new(); + for entry in entries { + row_html.push_str(&format!("<td class='row-item'>{}</td>", entry)); + } + + + response.push_str(&format!("<tr class=\"{}\">", ["even-row", "odd-row"][row_index])); + response.push_str(&row_html); + response.push_str("</tr>"); + response.push('\n'); + + row_num += 1; + } + + response.push_str("</table>\n"); + } + response.push_str("</html>"); (StatusCode::OK, Html(response)) @@ -97,6 +97,9 @@ pub const CREATE_REPO_NAME_INDEX: &'static str = "\ pub const PENDING_JOBS: &'static str = "\ select id, artifacts_path, state, run_host, remote_id, commit_id, created_time, source from jobs where state=0;"; +pub const STARTED_JOBS: &'static str = "\ + select * from jobs where state=1;"; + pub const LAST_ARTIFACTS_FOR_JOB: &'static str = "\ select * from artifacts where job_id=?1 and (name like \"%(stderr)%\" or name like \"%(stdout)%\") order by id desc limit ?2;"; |