with engine

This commit is contained in:
Kasper Juul Hermansen 2023-01-27 21:57:39 +01:00
parent 1e88bb3270
commit ee655d02ef
Signed by: kjuulh
GPG Key ID: 57B6E1465221F912
8 changed files with 217 additions and 3 deletions

16
Cargo.lock generated
View File

@ -150,6 +150,8 @@ dependencies = [
"hex-literal",
"platform-info",
"reqwest",
"serde",
"serde_json",
"sha2",
"tar",
"tempfile",
@ -898,6 +900,20 @@ name = "serde"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"

View File

@ -17,6 +17,8 @@ hex = "0.4.3"
hex-literal = "0.3.4"
platform-info = "1.0.2"
reqwest = { version = "0.11.14", features = ["stream", "blocking", "deflate"] }
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.91"
sha2 = "0.10.6"
tar = "0.4.38"
tempfile = "3.3.0"

103
src/cli_session.rs Normal file
View File

@ -0,0 +1,103 @@
use std::{
fs::canonicalize,
io::{BufRead, BufReader},
path::PathBuf,
process::Stdio,
sync::Arc,
};
use crate::{config::Config, connect_params::ConnectParams};
#[derive(Clone, Debug)]
pub struct CliSession {
inner: Arc<InnerCliSession>,
}
impl CliSession {
pub fn new() -> Self {
Self {
inner: Arc::new(InnerCliSession {}),
}
}
pub fn connect(&self, config: &Config, cli_path: &PathBuf) -> eyre::Result<ConnectParams> {
self.inner.connect(config, cli_path)
}
}
#[derive(Debug)]
struct InnerCliSession {}
impl InnerCliSession {
pub fn connect(&self, config: &Config, cli_path: &PathBuf) -> eyre::Result<ConnectParams> {
let mut proc = self.start(config, cli_path)?;
let params = self.get_conn(&mut proc)?;
Ok(params)
}
fn start(&self, config: &Config, cli_path: &PathBuf) -> eyre::Result<std::process::Child> {
let mut args: Vec<String> = vec!["session".into()];
if let Some(workspace) = &config.workdir_path {
let abs_path = canonicalize(workspace)?;
args.extend(["--workdir".into(), abs_path.to_string_lossy().to_string()])
}
if let Some(config_path) = &config.config_path {
let abs_path = canonicalize(config_path)?;
args.extend(["--project".into(), abs_path.to_string_lossy().to_string()])
}
let proc = std::process::Command::new(
cli_path
.to_str()
.ok_or(eyre::anyhow!("could not get string from path"))?,
)
.args(args.as_slice())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
//TODO: Add retry mechanism
return Ok(proc);
}
fn get_conn(&self, proc: &mut std::process::Child) -> eyre::Result<ConnectParams> {
let stdout = proc
.stdout
.take()
.ok_or(eyre::anyhow!("could not acquire stdout from child process"))?;
let stderr = proc
.stderr
.take()
.ok_or(eyre::anyhow!("could not acquire stderr from child process"))?;
let mut conn: Option<ConnectParams> = None;
std::thread::scope(|s| {
s.spawn(|| {
let stdout_bufr = BufReader::new(stdout);
let mut res_conn: Option<ConnectParams> = None;
for line in stdout_bufr.lines() {
let out = line.unwrap();
let conn: ConnectParams = serde_json::from_str(&out).unwrap();
res_conn = Some(conn);
break;
}
conn = res_conn;
});
//s.spawn(|| {
// let stderr_bufr = BufReader::new(stderr);
// for line in stderr_bufr.lines() {
// let out = line.unwrap();
// panic!("could not start dagger session: {}", out)
// }
//});
});
Ok(conn.ok_or(eyre::anyhow!("could not connect to dagger"))?)
}
}

24
src/config.rs Normal file
View File

@ -0,0 +1,24 @@
use std::path::PathBuf;
pub struct Config {
pub workdir_path: Option<PathBuf>,
pub config_path: Option<PathBuf>,
pub timeout_ms: u64,
pub execute_timeout_ms: Option<u64>,
}
impl Config {
pub fn new(
workdir_path: Option<PathBuf>,
config_path: Option<PathBuf>,
timeout_ms: Option<u64>,
execute_timeout_ms: Option<u64>,
) -> Self {
Self {
workdir_path,
config_path,
timeout_ms: timeout_ms.unwrap_or(10 * 1000),
execute_timeout_ms,
}
}
}

20
src/connect_params.rs Normal file
View File

@ -0,0 +1,20 @@
use serde::Deserialize;
#[derive(Clone, Debug, Deserialize, PartialEq)]
pub struct ConnectParams {
pub port: u64,
pub session_token: String,
}
impl ConnectParams {
pub fn new(port: u64, session_token: &str) -> Self {
Self {
port,
session_token: session_token.to_string(),
}
}
pub fn url(&self) -> String {
format!("http://127.0.0.1:{}/query", self.port)
}
}

View File

@ -1,17 +1,16 @@
use std::{
fs::File,
io::{copy, BufReader, BufWriter, Read, Write},
io::{copy, Read, Write},
os::unix::prelude::PermissionsExt,
path::PathBuf,
};
use eyre::Context;
use flate2::read::GzDecoder;
use hex_literal::hex;
use platform_info::Uname;
use sha2::Digest;
use tar::Archive;
use tempfile::{tempfile, NamedTempFile};
use tempfile::tempfile;
#[allow(dead_code)]
#[derive(Clone)]

46
src/engine.rs Normal file
View File

@ -0,0 +1,46 @@
use crate::{
cli_session::CliSession, config::Config, connect_params::ConnectParams, downloader::Downloader,
};
pub struct Engine {}
impl Engine {
pub fn new() -> Self {
Self {}
}
fn from_cli(&self, cfg: &Config) -> eyre::Result<ConnectParams> {
let cli = Downloader::new("0.3.10".into())?.get_cli()?;
let cli_session = CliSession::new();
Ok(cli_session.connect(cfg, &cli)?)
}
pub fn start(&self, cfg: &Config) -> eyre::Result<ConnectParams> {
// TODO: Add from existing session as well
self.from_cli(cfg)
}
}
#[cfg(test)]
mod tests {
use crate::{config::Config, connect_params::ConnectParams};
use super::Engine;
// TODO: these tests potentially have a race condition
#[test]
fn engine_can_start() {
let engine = Engine::new();
let params = engine.start(&Config::new(None, None, None, None)).unwrap();
assert_ne!(
params,
ConnectParams {
port: 123,
session_token: "123".into()
}
)
}
}

View File

@ -1,4 +1,8 @@
pub mod cli;
mod cli_session;
mod config;
mod connect_params;
pub mod dagger;
mod downloader;
mod engine;
mod schema;