Rename the project to Synchronik
This commit is contained in:
parent
3b95ff87ad
commit
8e600ba3b6
|
@ -1,14 +1,14 @@
|
|||
[package]
|
||||
name = "janky"
|
||||
name = "synchronik"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
name = "janky-server"
|
||||
name = "synchronik-server"
|
||||
path = "src/server/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "janky-agent"
|
||||
name = "synchronik-agent"
|
||||
path = "src/agent/main.rs"
|
||||
|
||||
[dependencies]
|
||||
|
@ -30,6 +30,7 @@ serde = { version = "1.0", features = ["derive"] }
|
|||
serde_json = "1"
|
||||
serde_yaml = "0.9"
|
||||
sqlx = { version = "~0.6", features = ["chrono", "json", "migrate", "offline", "sqlite", "uuid", "runtime-async-std-rustls"] }
|
||||
subprocess = "0.2"
|
||||
tide = "0"
|
||||
uuid = { version = "1", features = ["v4", "serde"]}
|
||||
url = "2"
|
||||
|
|
13
README.adoc
13
README.adoc
|
@ -1,14 +1,15 @@
|
|||
= Janky CI
|
||||
= Synchronik
|
||||
|
||||
Janky is a simple CI system built in Rust. This is performative coding and not
|
||||
intended to be a production system you can actually use.
|
||||
Synchronik is a simple task execution system built in Rust. This is
|
||||
performative coding and not intended to be a production system you can actually
|
||||
use.
|
||||
|
||||
* Two binaries:
|
||||
* `janky-server`
|
||||
* `synchronik-server`
|
||||
* Listens HTTP
|
||||
* Does web shit
|
||||
* Does web things
|
||||
* Interacts with agents
|
||||
* `janky-agent`:
|
||||
* `synchronik-agent`:
|
||||
* Run workloads
|
||||
* Listen HTTP
|
||||
* executes commands
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
openapi: "3.0.0"
|
||||
info:
|
||||
description: |
|
||||
Janky API v1 defintion
|
||||
Synchronik API v1 defintion
|
||||
version: "1.0.0"
|
||||
title: Janky APIs
|
||||
title: Synchronik APIs
|
||||
contact:
|
||||
email: "rtyler+janky@brokenco.de"
|
||||
email: "rtyler+synchronik@brokenco.de"
|
||||
license:
|
||||
name: "AGPL v3.0"
|
||||
url: "https://www.gnu.org/licenses/agpl-3.0.en.html"
|
||||
|
@ -33,7 +33,7 @@ paths:
|
|||
- in: path
|
||||
name: name
|
||||
required: true
|
||||
example: 'janky'
|
||||
example: 'synchronik'
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"openapi":"3.0.0","info":{"description":"Janky API v1 defintion\n","version":"1.0.0","title":"Janky APIs","contact":{"email":"rtyler+janky@brokenco.de"},"license":{"name":"AGPL v3.0","url":"https://www.gnu.org/licenses/agpl-3.0.en.html"}},"servers":[{"url":"http://localhost:8000","description":"Local dev server"},{"url":"http://localhost:9000","description":"Local dev agent"}],"tags":[{"name":"agent","description":"Agent APIs"},{"name":"server","description":"Server APIs"}],"paths":{"/api/v1/projects/{name}":{"post":{"tags":["server"],"summary":"Trigger execution for this project","description":null,"parameters":[{"in":"path","name":"name","required":true,"example":"janky","schema":{"type":"string"}}],"responses":{"404":{"summary":"No project configured by that name"},"200":{"summary":"Execution has been triggered"}}}},"/api/v1/capabilities":{"get":{"tags":["agent"],"summary":"Retrieve a list of capabilities of this agent","description":null,"responses":{"200":{"description":"Getting capabilities","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CapsResponse"}}}}}}},"/api/v1/execute":{"put":{"tags":["agent"],"summary":"Execute a series of commands on this agent","description":null,"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandRequest"},"example":{"commands":[{"script":"echo \"Hi\""}]}}}},"responses":{"201":{"description":"Successfully accepted the commands for execution","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandResponse"}}}},"409":{"description":"Returned when the agent is busy with another series of commands"}}}}},"components":{"schemas":{"CapsResponse":{"type":"object","properties":{"caps":{"type":"array","items":{"$ref":"#/components/schemas/Capability"}}}},"Capability":{"type":"object","properties":{"name":{"type":"string"},"path":{"type":"string"},"data":{"type":"object"}}},"Command":{"type":"object","properties":{"script":{"type":"string","description":"A script that can be exec()'d on the agent"}}},"CommandRequest":{"type":"object","properties":{"commands":{"type":"array","items":{"$ref":"#/components/schemas/Command"}}}},"CommandResponse":{"type":"object","properties":{"uuid":{"type":"string","format":"uuid"},"stream":{"description":"URL to streaming WebSockets logs","type":"string","format":"url"},"task":{"description":"URL to the task metadata","type":"string","format":"url"},"log":{"description":"URL to the raw log of the task run","type":"string","format":"url"}}}}}}
|
||||
{"openapi":"3.0.0","info":{"description":"Synchronik API v1 defintion\n","version":"1.0.0","title":"Synchronik APIs","contact":{"email":"rtyler+synchronik@brokenco.de"},"license":{"name":"AGPL v3.0","url":"https://www.gnu.org/licenses/agpl-3.0.en.html"}},"servers":[{"url":"http://localhost:8000","description":"Local dev server"},{"url":"http://localhost:9000","description":"Local dev agent"}],"tags":[{"name":"agent","description":"Agent APIs"},{"name":"server","description":"Server APIs"}],"paths":{"/api/v1/projects/{name}":{"post":{"tags":["server"],"summary":"Trigger execution for this project","description":null,"parameters":[{"in":"path","name":"name","required":true,"example":"synchronik","schema":{"type":"string"}}],"responses":{"404":{"summary":"No project configured by that name"},"200":{"summary":"Execution has been triggered"}}}},"/api/v1/capabilities":{"get":{"tags":["agent"],"summary":"Retrieve a list of capabilities of this agent","description":null,"responses":{"200":{"description":"Getting capabilities","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CapsResponse"}}}}}}},"/api/v1/execute":{"put":{"tags":["agent"],"summary":"Execute a series of commands on this agent","description":null,"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandRequest"},"example":{"commands":[{"script":"echo \"Hi\""}]}}}},"responses":{"201":{"description":"Successfully accepted the commands for execution","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandResponse"}}}},"409":{"description":"Returned when the agent is busy with another series of commands"}}}}},"components":{"schemas":{"CapsResponse":{"type":"object","properties":{"caps":{"type":"array","items":{"$ref":"#/components/schemas/Capability"}}}},"Capability":{"type":"object","properties":{"name":{"type":"string"},"path":{"type":"string"},"data":{"type":"object"}}},"Command":{"type":"object","properties":{"script":{"type":"string","description":"A script that can be exec()'d on the agent"}}},"CommandRequest":{"type":"object","properties":{"commands":{"type":"array","items":{"$ref":"#/components/schemas/Command"}}}},"CommandResponse":{"type":"object","properties":{"uuid":{"type":"string","format":"uuid"},"stream":{"description":"URL to streaming WebSockets logs","type":"string","format":"url"},"task":{"description":"URL to the task metadata","type":"string","format":"url"},"log":{"description":"URL to the raw log of the task run","type":"string","format":"url"}}}}}}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
# This is a Janky formatted YAML file. Using YAML for now to make hacking on
|
||||
# This is a Synchronik formatted YAML file. Using YAML for now to make hacking on
|
||||
# this quicker and easier
|
||||
|
||||
needs:
|
|
@ -5,22 +5,22 @@ agents:
|
|||
'Duplicate Local':
|
||||
url: 'http://localhost:9000'
|
||||
projects:
|
||||
'janky':
|
||||
'synchronik':
|
||||
description: |
|
||||
Self-hosted Janky project
|
||||
filename: 'ci.janky.yml'
|
||||
Self-hosted project
|
||||
filename: 'ci.synchronik.yml'
|
||||
scm:
|
||||
github:
|
||||
owner: 'rtyler'
|
||||
repo: 'janky'
|
||||
repo: 'synchronik'
|
||||
ref: 'main'
|
||||
'janky with spaces':
|
||||
'with spaces':
|
||||
description: A test configuration with spaces in the name
|
||||
filename: 'ci.janky.yml'
|
||||
filename: 'ci.synchronik.yml'
|
||||
scm:
|
||||
github:
|
||||
owner: 'rtyler'
|
||||
repo: 'janky'
|
||||
repo: 'synchronik'
|
||||
ref: 'main'
|
||||
# The filetype Git is not yet supported
|
||||
#- type: 'git'
|
||||
|
|
|
@ -5,8 +5,8 @@ use std::path::PathBuf;
|
|||
|
||||
use async_std::channel::{bounded, Receiver, Sender};
|
||||
use dotenv::dotenv;
|
||||
use janky::CommandRequest;
|
||||
use log::*;
|
||||
use synchronik::CommandRequest;
|
||||
use uuid::Uuid;
|
||||
|
||||
const AGENT_LOGS_DIR: &str = "agent-logs";
|
||||
|
@ -20,13 +20,13 @@ mod routes {
|
|||
* GET /
|
||||
*/
|
||||
pub async fn index(_req: Request<crate::State>) -> Result<Body, tide::Error> {
|
||||
Ok("Hello World from the Janky Agent".into())
|
||||
Ok("Hello World from the Synchronik Agent".into())
|
||||
}
|
||||
|
||||
pub mod api {
|
||||
use crate::caps::*;
|
||||
use crate::*;
|
||||
use janky::{CommandRequest, CommandResponse};
|
||||
use synchronik::{CommandRequest, CommandResponse};
|
||||
use tide::{Body, Request, Response, StatusCode};
|
||||
use uuid::Uuid;
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@ use url::Url;
|
|||
use crate::AppState;
|
||||
|
||||
/*
|
||||
* Representation of the Janky YAML format
|
||||
* Representation of the Synchronik YAML format
|
||||
*/
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct JankyYml {
|
||||
pub struct Yml {
|
||||
pub needs: Vec<String>,
|
||||
pub commands: Vec<String>,
|
||||
}
|
||||
|
@ -44,11 +44,11 @@ pub struct Project {
|
|||
pub struct Agent {
|
||||
pub name: String,
|
||||
pub url: Url,
|
||||
pub capabilities: Vec<janky::Capability>,
|
||||
pub capabilities: Vec<synchronik::Capability>,
|
||||
}
|
||||
|
||||
impl Agent {
|
||||
pub fn new(name: String, url: Url, capabilities: Vec<janky::Capability>) -> Self {
|
||||
pub fn new(name: String, url: Url, capabilities: Vec<synchronik::Capability>) -> Self {
|
||||
Self {
|
||||
name,
|
||||
url,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* This is the main Janky entrypoint for the server"
|
||||
* This is the main Synchronik entrypoint for the server
|
||||
*/
|
||||
|
||||
#[macro_use]
|
||||
|
@ -93,7 +93,7 @@ async fn main() -> Result<(), tide::Error> {
|
|||
let database_url = std::env::var("DATABASE_URL").unwrap_or(":memory:".to_string());
|
||||
let pool = SqlitePool::connect(&database_url).await?;
|
||||
|
||||
/* If janky-server is running in memory, make sure the database is set up properly */
|
||||
/* If synchronik-server is running in memory, make sure the database is set up properly */
|
||||
if database_url == ":memory:" {
|
||||
sqlx::migrate!().run(&pool).await?;
|
||||
}
|
||||
|
@ -118,10 +118,11 @@ async fn main() -> Result<(), tide::Error> {
|
|||
|
||||
for (name, agent) in config.agents.iter() {
|
||||
debug!("Requesting capabilities from agent: {:?}", agent);
|
||||
let response: janky::CapsResponse = reqwest::get(agent.url.join("/api/v1/capabilities")?)
|
||||
.await?
|
||||
.json()
|
||||
.await?;
|
||||
let response: synchronik::CapsResponse =
|
||||
reqwest::get(agent.url.join("/api/v1/capabilities")?)
|
||||
.await?
|
||||
.json()
|
||||
.await?;
|
||||
state.agents.push(Agent::new(
|
||||
name.to_string(),
|
||||
agent.url.clone(),
|
||||
|
@ -177,7 +178,7 @@ async fn main() -> Result<(), tide::Error> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use janky::*;
|
||||
use synchronik::*;
|
||||
|
||||
#[test]
|
||||
fn agent_can_meet_false() {
|
||||
|
|
|
@ -46,7 +46,7 @@ pub async fn project(req: Request<AppState<'_>>) -> Result<Body, tide::Error> {
|
|||
}
|
||||
|
||||
pub mod api {
|
||||
use crate::config::{JankyYml, Scm};
|
||||
use crate::config::{Scm, Yml};
|
||||
use crate::AppState;
|
||||
use log::*;
|
||||
use serde::Deserialize;
|
||||
|
@ -88,18 +88,18 @@ pub mod api {
|
|||
&project.filename,
|
||||
)
|
||||
.await?;
|
||||
let jankyfile: JankyYml = serde_yaml::from_str(&res.text().await?)?;
|
||||
debug!("text: {:?}", jankyfile);
|
||||
let config_file: Yml = serde_yaml::from_str(&res.text().await?)?;
|
||||
debug!("text: {:?}", config_file);
|
||||
|
||||
for agent in &state.agents {
|
||||
if agent.can_meet(&jankyfile.needs) {
|
||||
if agent.can_meet(&config_file.needs) {
|
||||
debug!("agent: {:?} can meet our needs", agent);
|
||||
let commands: Vec<janky::Command> = jankyfile
|
||||
let commands: Vec<synchronik::Command> = config_file
|
||||
.commands
|
||||
.iter()
|
||||
.map(|c| janky::Command::with_script(c))
|
||||
.map(|c| synchronik::Command::with_script(c))
|
||||
.collect();
|
||||
let commands = janky::CommandRequest { commands };
|
||||
let commands = synchronik::CommandRequest { commands };
|
||||
let client = reqwest::Client::new();
|
||||
let _res = client
|
||||
.put(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<nav class="navbar navbar-expand-lg bg-dark" data-bs-theme="dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/">Janky</a>
|
||||
<a class="navbar-brand" href="/">Synchronik</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Janky</title>
|
||||
<title>Synchronik</title>
|
||||
<link type="text/css" rel="stylesheet" href="/static/bootstrap.min.css"/>
|
||||
<script src="/static/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
|
||||
|
||||
|
|
Loading…
Reference in New Issue