Files
nomact/nomact/src/lib.rs
2026-01-17 20:51:09 +01:00

116 lines
3.5 KiB
Rust

use std::vec;
pub mod runner {
tonic::include_proto!("runner.v1");
}
pub mod ping {
tonic::include_proto!("ping.v1");
}
pub struct RegisterConfig {
pub name: String,
pub register_token: String,
pub instance: hyper::Uri,
pub version: String,
pub labels: Vec<String>,
pub ephemeral: bool,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct RegisteredRunner {
pub uuid: String,
pub token: String,
}
pub fn instance_to_api_url(instance: hyper::Uri) -> hyper::Uri {
let mut parts = instance.into_parts();
parts.path_and_query = Some("/api/actions".try_into().unwrap());
hyper::Uri::from_parts(parts).unwrap()
}
pub async fn register(conf: RegisterConfig) -> Result<RegisteredRunner, ()> {
use hyper_rustls::ConfigBuilderExt;
let tls = rustls::ClientConfig::builder()
.with_native_roots()
.unwrap()
.with_no_client_auth();
// Prepare the HTTPS connector
let https = hyper_rustls::HttpsConnectorBuilder::new()
.with_tls_config(tls)
.https_or_http()
.enable_http1()
.build();
// Must use hyper directly...
let client = hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new())
.build(https);
let svc = tower::ServiceBuilder::new()
.layer(tonic_web::GrpcWebClientLayer::new())
.service(client);
let uri = instance_to_api_url(conf.instance);
let mut client = runner::runner_service_client::RunnerServiceClient::with_origin(svc, uri);
let request = tonic::Request::new(runner::RegisterRequest {
name: conf.name,
token: conf.register_token,
version: conf.version,
labels: conf.labels,
ephemeral: conf.ephemeral,
..Default::default()
});
let response = client.register(request).await.unwrap();
match response.into_inner().runner {
Some(runner) => Ok(RegisteredRunner {
uuid: runner.uuid,
token: runner.token,
}),
None => Err(()),
}
}
pub async fn run_task<T>(
client: &mut runner::runner_service_client::RunnerServiceClient<T>,
task: runner::Task,
) where
T: tonic::client::GrpcService<tonic::body::Body>,
T::Error: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
T::ResponseBody: http_body::Body<Data = prost::bytes::Bytes> + std::marker::Send + 'static,
<T::ResponseBody as http_body::Body>::Error:
Into<Box<dyn std::error::Error + Send + Sync + 'static>> + std::marker::Send,
{
tracing::debug!(?task, "Run-Task");
let workflow = core::str::from_utf8(task.workflow_payload()).unwrap();
tracing::info!("Raw-Workflow: {}", workflow);
let task_id = task.id;
let task_workflow = core::str::from_utf8(task.workflow_payload()).unwrap();
let task_context = task.context.as_ref();
let task_secrets = &task.secrets;
let task_needs = &task.needs;
let task_vars = &task.vars;
let workflow = serde_yaml::from_slice::<serde_yaml::Value>(task.workflow_payload());
tracing::info!("Workflow: {:?}", &workflow);
let update_req = tonic::Request::new(runner::UpdateTaskRequest {
outputs: std::collections::HashMap::new(),
state: Some(runner::TaskState {
id: task.id,
result: runner::Result::Failure.into(),
started_at: None,
stopped_at: None,
steps: vec![],
}),
});
let resp = client.update_task(update_req).await.unwrap();
tracing::info!(resp = tracing::field::debug(resp.get_ref()), "Update Task State");
}