More content for the build endpoint

This commit is contained in:
Niko Reunanen 2025-01-25 02:39:52 +02:00
parent 2570644a90
commit b70f1c934d
Signed by: nreunane
GPG key ID: D192625387DB0F16
2 changed files with 85 additions and 19 deletions

View file

@ -6,7 +6,9 @@ edition = "2021"
[dependencies] [dependencies]
axum = { version = "0.8.1" } axum = { version = "0.8.1" }
bollard = { version = "0.18.1", registry = "cratesio" } bollard = { version = "0.18.1", registry = "cratesio" }
futures-util = { version = "0.3.31", registry = "cratesio" }
git2 = { version = "0.20.0" } git2 = { version = "0.20.0" }
serde = { version = "1.0.217", features = ["derive"] }
tokio = { version = "1.43.0", features = ["full"] } tokio = { version = "1.43.0", features = ["full"] }
tower-http = { version = "0.6.2", features = ["trace"] } tower-http = { version = "0.6.2", features = ["trace"] }
tracing = { version = "0.1.41" } tracing = { version = "0.1.41" }

View file

@ -1,30 +1,97 @@
use std::process::ExitCode; use std::{collections::HashMap, process::ExitCode, sync::Arc};
use axum::{routing::get, Router}; use axum::{
use bollard::Docker; extract::State,
http::StatusCode,
routing::{get, post},
Json, Router,
};
use bollard::{image::BuildImageOptions, Docker};
use futures_util::stream::StreamExt;
use git2::Repository; use git2::Repository;
use serde::Deserialize;
use tokio::sync::Mutex;
use tower_http::trace::TraceLayer; use tower_http::trace::TraceLayer;
use tracing::level_filters::LevelFilter; use tracing::level_filters::LevelFilter;
#[tokio::main] struct AppState {
async fn download_repository(url: &str, name: &str) { docker: Docker,
let folder = format!("/tmp/{name}"); pub(crate) name: Option<String>,
}
match tokio::fs::try_exists(&folder).await { #[derive(Deserialize)]
struct CdBuild {
url: String,
path: String,
serve: bool,
name: String,
}
async fn build(
State(state): State<Arc<Mutex<AppState>>>,
Json(cd): Json<CdBuild>,
) -> (StatusCode, &'static str) {
match tokio::fs::try_exists(&cd.path).await {
Ok(true) => { Ok(true) => {
let repo = Repository::open(folder).unwrap(); let repo = Repository::open(&cd.path).unwrap();
repo.find_remote("origin") repo.find_remote("origin")
.unwrap() .unwrap()
.fetch(&["main"], None, None) .fetch(&["main"], None, None)
.unwrap(); .unwrap();
} }
Ok(false) => { Ok(false) => {
Repository::clone(url, folder).unwrap(); Repository::clone(&cd.url, &cd.path).unwrap();
} }
Err(error) => { Err(error) => {
tracing::error!("{error}"); tracing::error!("{error}");
} }
}
let build_image_options = BuildImageOptions {
dockerfile: "Dockerfile",
t: "bollard-build-example",
extrahosts: Some("myhost:127.0.0.1"),
remote: "",
q: false,
nocache: false,
cachefrom: vec![],
pull: true,
rm: true,
forcerm: true,
memory: Some(120_000_000),
memswap: Some(500_000),
cpushares: Some(2),
cpusetcpus: "0-3",
cpuperiod: Some(2000),
cpuquota: Some(1000),
buildargs: HashMap::new(),
shmsize: Some(1_000_000),
squash: false,
labels: HashMap::new(),
networkmode: "host",
platform: "linux/x86_64",
target: "",
#[cfg(feature = "buildkit")]
session: None,
#[cfg(feature = "buildkit")]
outputs: None,
version: bollard::image::BuilderVersion::BuilderV1,
}; };
{
let mtx = state.lock().await;
let mut image_build_stream = mtx.docker.build_image(build_image_options, None, None);
while let Some(msg) = image_build_stream.next().await {
tracing::info!("{msg:?}");
}
}
if cd.serve {
let mut mtx = state.lock().await;
mtx.name = Some(cd.name);
}
(StatusCode::OK, "ok")
} }
#[tokio::main] #[tokio::main]
@ -65,17 +132,14 @@ async fn main() -> ExitCode {
} }
}; };
let app = Router::new() let shared_state = Arc::new(Mutex::new(AppState { docker, name: None }));
.route(
"/api/v1/image/build",
get({
download_repository("URL", "microdeploy");
"todo" let app = Router::new()
}), .route("/api/v1/build", post(build))
) .route("/api/v1/serve", get("todo"))
.route("/api/v1/image/serve", get("todo")) .route("/api/v1/stop", get("todo"))
.layer(TraceLayer::new_for_http()); .layer(TraceLayer::new_for_http())
.with_state(shared_state);
match axum::serve(listener, app).await { match axum::serve(listener, app).await {
Ok(()) => ExitCode::SUCCESS, Ok(()) => ExitCode::SUCCESS,