Samuel Dai 308e9bcc5d
refactor: project structure and better interfaces (#100)
* refactor: basically rewrite all interface

* refactor: rename crates to make clear meaning; use tokio runtime and handle shutdown within Provider

* remove tracker in main

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(provider): enhance Provider trait with list, update, and status methods; refactor existing methods to async

* fix(containerd): fetch handle from environment and initialize it.

* fix(init): BACKEND init add handle fetching

* fix: add test framework

* fix: move the snapshot logic into snapshot.rs

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* fix: change some spec setting

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: add created_at field, add http status code convertion

* refactor(spec): use builder to generate spec

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* fix: clippy

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* manage reference, fix boot issue

* fix: ip parsing

* feat: add cleanup logic on fail

* fix style: clippy for return function

* feat: add response message

* fix:1.修复proxy和resolve的逻辑 2.spec内netns的路径问题以及传参顺序

* feat:add update list status  service implmentation

* fix: move some consts into consts.rs

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* fix: fmt & clippy

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* fix: update dependecy

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: add function with_vm_network

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat: integrate cni into containerd crate

* fix:修复proxy的路径正则匹配并添加单元测试

* fix:fix proxy_path and add default namespace for Query::from

* fix: integration_test

* fix: path dispatch test

* fix: more specified url dispatch in proxy handle

* feat: add persistent container record for restart service

* feat: add task error type

* fix: delete error handle logic

---------

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
Co-authored-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
Co-authored-by: dolzhuying <1240800466@qq.com>
Co-authored-by: scutKKsix <1129332011@qq.com>
2025-05-22 21:43:16 +08:00

72 lines
2.3 KiB
Rust

type Err = Box<dyn std::error::Error + Send + Sync>;
use handlebars::Handlebars;
use std::{collections::HashMap, fs::File, io::Write, path::Path};
pub struct Systemd;
impl Systemd {
pub fn enable(unit: String) -> Result<(), Err> {
let output = std::process::Command::new("systemctl")
.arg("enable")
.arg(&unit)
.output()?;
if !output.status.success() {
return Err(Box::new(std::io::Error::other(format!(
"Failed to enable unit {}: {}",
unit,
String::from_utf8_lossy(&output.stderr)
))));
}
Ok(())
}
pub fn start(unit: String) -> Result<(), Err> {
let output = std::process::Command::new("systemctl")
.arg("start")
.arg(&unit)
.output()?;
if !output.status.success() {
return Err(Box::new(std::io::Error::other(format!(
"Failed to start unit {}: {}",
unit,
String::from_utf8_lossy(&output.stderr)
))));
}
Ok(())
}
pub fn daemon_reload() -> Result<(), Err> {
let output = std::process::Command::new("systemctl")
.arg("daemon-reload")
.output()?;
if !output.status.success() {
return Err(Box::new(std::io::Error::other(format!(
"Failed to reload systemd daemon: {}",
String::from_utf8_lossy(&output.stderr)
))));
}
Ok(())
}
pub fn install_unit(name: String, tokens: HashMap<String, String>) -> Result<(), Err> {
if tokens.get("Cwd").is_none_or(|v| v.is_empty()) {
return Err("key Cwd expected in tokens parameter".into());
}
let tmpl_name = format!("./hack/{}.service", name);
let mut handlebars = Handlebars::new();
handlebars.register_template_file("template", &tmpl_name)?;
let rendered = handlebars.render("template", &tokens)?;
Self::write_unit(&format!("{}.service", name), rendered.as_bytes())?;
Ok(())
}
pub fn write_unit(name: &str, content: &[u8]) -> Result<(), Err> {
let path = Path::new("/lib/systemd/system").join(name);
let mut file = File::create(path)?;
file.write_all(content)?;
Ok(())
}
}