mirror of
https://github.com/faas-rs/faasd-in-rust.git
synced 2025-06-08 15:56:48 +00:00
commit
8ec1bdb475
100
Cargo.lock
generated
100
Cargo.lock
generated
@ -432,9 +432,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "containerd-client"
|
name = "containerd-client"
|
||||||
version = "0.6.0"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce8bbfa492159a878a45bbd8fbd8d5a6fb2a4d6bd74836204a324523ba3233e0"
|
checksum = "936cc6911381d95039f381080ec148024d2bb0044a03363542b0a6b0b2c46592"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"prost",
|
"prost",
|
||||||
@ -443,7 +443,7 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"tonic",
|
"tonic",
|
||||||
"tonic-build",
|
"tonic-build",
|
||||||
"tower 0.4.13",
|
"tower 0.5.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -809,6 +809,20 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "handlebars"
|
||||||
|
version = "4.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "faa67bab9ff362228eb3d00bd024a4965d8231bbb7921167f0cfa66c6626b225"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"pest",
|
||||||
|
"pest_derive",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
@ -1312,7 +1326,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"thiserror",
|
"thiserror 1.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1356,6 +1370,51 @@ version = "2.3.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest"
|
||||||
|
version = "2.7.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"thiserror 2.0.11",
|
||||||
|
"ucd-trie",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_derive"
|
||||||
|
version = "2.7.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"pest_generator",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_generator"
|
||||||
|
version = "2.7.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"pest_meta",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_meta"
|
||||||
|
version = "2.7.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"pest",
|
||||||
|
"sha2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "petgraph"
|
name = "petgraph"
|
||||||
version = "0.6.5"
|
version = "0.6.5"
|
||||||
@ -1512,6 +1571,10 @@ dependencies = [
|
|||||||
"prost",
|
"prost",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "provider"
|
||||||
|
version = "0.0.1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.38"
|
version = "1.0.38"
|
||||||
@ -1697,6 +1760,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"containerd-client",
|
"containerd-client",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"handlebars",
|
||||||
"hex",
|
"hex",
|
||||||
"log",
|
"log",
|
||||||
"my-workspace-hack",
|
"my-workspace-hack",
|
||||||
@ -1859,7 +1923,16 @@ version = "1.0.69"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl 2.0.11",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1873,6 +1946,17 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.37"
|
version = "0.3.37"
|
||||||
@ -2101,6 +2185,12 @@ version = "1.17.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ucd-trie"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.15"
|
version = "1.0.15"
|
||||||
|
7
crates/provider/Cargo.toml
Normal file
7
crates/provider/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "provider"
|
||||||
|
edition = "2024"
|
||||||
|
version.workspace = true
|
||||||
|
authors.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
0
crates/provider/src/auth/mod.rs
Normal file
0
crates/provider/src/auth/mod.rs
Normal file
0
crates/provider/src/config/mod.rs
Normal file
0
crates/provider/src/config/mod.rs
Normal file
0
crates/provider/src/handler/mod.rs
Normal file
0
crates/provider/src/handler/mod.rs
Normal file
0
crates/provider/src/httputils/mod.rs
Normal file
0
crates/provider/src/httputils/mod.rs
Normal file
23
crates/provider/src/lib.rs
Normal file
23
crates/provider/src/lib.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
pub mod config;
|
||||||
|
pub mod handler;
|
||||||
|
pub mod types;
|
||||||
|
pub mod httputils;
|
||||||
|
pub mod proxy;
|
||||||
|
pub mod auth;
|
||||||
|
pub mod logs;
|
||||||
|
pub mod metrics;
|
||||||
|
|
||||||
|
pub fn add(left: u64, right: u64) -> u64 {
|
||||||
|
left + right
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = add(2, 2);
|
||||||
|
assert_eq!(result, 4);
|
||||||
|
}
|
||||||
|
}
|
0
crates/provider/src/logs/mod.rs
Normal file
0
crates/provider/src/logs/mod.rs
Normal file
0
crates/provider/src/metrics/mod.rs
Normal file
0
crates/provider/src/metrics/mod.rs
Normal file
0
crates/provider/src/proxy/mod.rs
Normal file
0
crates/provider/src/proxy/mod.rs
Normal file
58
crates/provider/src/types/config.rs
Normal file
58
crates/provider/src/types/config.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(10);
|
||||||
|
const DEFAULT_MAX_IDLE_CONNS: usize = 1024;
|
||||||
|
|
||||||
|
pub struct FaasHandler<S> {
|
||||||
|
pub list_namespaces: S,
|
||||||
|
pub mutate_namespace: S,
|
||||||
|
pub function_proxy: S,
|
||||||
|
pub function_lister: S,
|
||||||
|
pub deploy_function: S,
|
||||||
|
pub update_function: S,
|
||||||
|
pub delete_function: S,
|
||||||
|
pub function_status: S,
|
||||||
|
pub scale_function: S,
|
||||||
|
pub secrets: S,
|
||||||
|
pub logs: S,
|
||||||
|
pub health: Option<S>,
|
||||||
|
pub info: S,
|
||||||
|
pub telemetry: S,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FaaSConfig {
|
||||||
|
pub tcp_port: Option<u16>,
|
||||||
|
pub read_timeout: Duration,
|
||||||
|
pub write_timeout: Duration,
|
||||||
|
pub enable_health: bool,
|
||||||
|
pub enable_basic_auth: bool,
|
||||||
|
pub secret_mount_path: String,
|
||||||
|
pub max_idle_conns: usize,
|
||||||
|
pub max_idle_conns_per_host: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FaaSConfig {
|
||||||
|
pub fn get_read_timeout(&self) -> Duration {
|
||||||
|
if self.read_timeout <= Duration::from_secs(0) {
|
||||||
|
DEFAULT_READ_TIMEOUT
|
||||||
|
} else {
|
||||||
|
self.read_timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_max_idle_conns(&self) -> usize {
|
||||||
|
if self.max_idle_conns < 1 {
|
||||||
|
DEFAULT_MAX_IDLE_CONNS
|
||||||
|
} else {
|
||||||
|
self.max_idle_conns
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_max_idle_conns_per_host(&self) -> usize {
|
||||||
|
if self.max_idle_conns_per_host < 1 {
|
||||||
|
self.get_max_idle_conns()
|
||||||
|
} else {
|
||||||
|
self.max_idle_conns_per_host
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
crates/provider/src/types/mod.rs
Normal file
1
crates/provider/src/types/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod config;
|
@ -4,7 +4,7 @@ version = "0.1.0"
|
|||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
containerd-client = "0.6"
|
containerd-client = "0.8"
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
tonic = "0.12"
|
tonic = "0.12"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
@ -16,3 +16,4 @@ oci-spec = "0.6"
|
|||||||
sha2 = "0.10"
|
sha2 = "0.10"
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
my-workspace-hack = { version = "0.1", path = "../my-workspace-hack" }
|
my-workspace-hack = { version = "0.1", path = "../my-workspace-hack" }
|
||||||
|
handlebars= "4.1.0"
|
@ -1,33 +1,37 @@
|
|||||||
pub mod spec;
|
pub mod spec;
|
||||||
|
pub mod systemd;
|
||||||
|
|
||||||
use containerd_client::{
|
use containerd_client::{
|
||||||
Client,
|
Client,
|
||||||
services::v1::{
|
services::v1::{
|
||||||
Container, CreateContainerRequest, CreateTaskRequest, DeleteContainerRequest,
|
Container, CreateContainerRequest, CreateTaskRequest, DeleteContainerRequest,
|
||||||
DeleteTaskRequest, GetImageRequest, KillRequest, ListContainersRequest, ListTasksRequest,
|
DeleteTaskRequest, GetImageRequest, KillRequest, ListContainersRequest, ListTasksRequest,
|
||||||
ReadContentRequest, StartRequest, WaitRequest,
|
ReadContentRequest, StartRequest, TransferOptions, TransferRequest, WaitRequest,
|
||||||
container::Runtime,
|
container::Runtime,
|
||||||
snapshots::{MountsRequest, PrepareSnapshotRequest},
|
snapshots::{MountsRequest, PrepareSnapshotRequest},
|
||||||
},
|
},
|
||||||
|
to_any,
|
||||||
tonic::Request,
|
tonic::Request,
|
||||||
types::Mount,
|
types::{
|
||||||
|
Mount, Platform,
|
||||||
|
transfer::{ImageStore, OciRegistry, UnpackConfiguration},
|
||||||
|
},
|
||||||
with_namespace,
|
with_namespace,
|
||||||
};
|
};
|
||||||
use oci_spec::image::{Arch, ImageConfiguration, ImageIndex, ImageManifest, MediaType, Os};
|
use oci_spec::image::{Arch, ImageConfiguration, ImageIndex, ImageManifest, MediaType, Os};
|
||||||
use prost_types::Any;
|
use prost_types::Any;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use spec::generate_spec;
|
use spec::{DEFAULT_NAMESPACE, generate_spec};
|
||||||
use std::{
|
use std::{
|
||||||
fs,
|
fs,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
|
vec,
|
||||||
};
|
};
|
||||||
use tokio::time::timeout;
|
use tokio::time::timeout;
|
||||||
|
|
||||||
// config.json,dockerhub密钥
|
// config.json,dockerhub密钥
|
||||||
// const DOCKER_CONFIG_DIR: &str = "/var/lib/faasd/.docker/";
|
// const DOCKER_CONFIG_DIR: &str = "/var/lib/faasd/.docker/";
|
||||||
// 命名空间(容器的)
|
|
||||||
const NAMESPACE: &str = "default";
|
|
||||||
|
|
||||||
type Err = Box<dyn std::error::Error>;
|
type Err = Box<dyn std::error::Error>;
|
||||||
|
|
||||||
@ -110,10 +114,9 @@ impl Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove_container(&self, cid: &str, ns: &str) -> Result<(), Err> {
|
pub async fn remove_container(&self, cid: &str, ns: &str) -> Result<(), Err> {
|
||||||
let namespace = match ns {
|
let namespace = self.check_namespace(ns);
|
||||||
"" => NAMESPACE,
|
let namespace = namespace.as_str();
|
||||||
_ => ns,
|
|
||||||
};
|
|
||||||
let c = self.client.lock().unwrap();
|
let c = self.client.lock().unwrap();
|
||||||
let request = ListContainersRequest {
|
let request = ListContainersRequest {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -236,10 +239,9 @@ impl Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn kill_task(&self, cid: String, ns: &str) -> Result<(), Err> {
|
pub async fn kill_task(&self, cid: String, ns: &str) -> Result<(), Err> {
|
||||||
let namespace = match ns {
|
let namespace = self.check_namespace(ns);
|
||||||
"" => NAMESPACE,
|
let namespace = namespace.as_str();
|
||||||
_ => ns,
|
|
||||||
};
|
|
||||||
let mut c = self.client.lock().unwrap().tasks();
|
let mut c = self.client.lock().unwrap().tasks();
|
||||||
let kill_request = KillRequest {
|
let kill_request = KillRequest {
|
||||||
container_id: cid.to_string(),
|
container_id: cid.to_string(),
|
||||||
@ -260,10 +262,9 @@ impl Service {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
pub async fn delete_task(&self, cid: &str, ns: &str) {
|
pub async fn delete_task(&self, cid: &str, ns: &str) {
|
||||||
let namespace = match ns {
|
let namespace = self.check_namespace(ns);
|
||||||
"" => NAMESPACE,
|
let namespace = namespace.as_str();
|
||||||
_ => ns,
|
|
||||||
};
|
|
||||||
let mut c = self.client.lock().unwrap().tasks();
|
let mut c = self.client.lock().unwrap().tasks();
|
||||||
let time_out = Duration::from_secs(30);
|
let time_out = Duration::from_secs(30);
|
||||||
let wait_result = timeout(time_out, async {
|
let wait_result = timeout(time_out, async {
|
||||||
@ -314,10 +315,9 @@ impl Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_container_list(&self, ns: &str) -> Result<Vec<String>, tonic::Status> {
|
pub async fn get_container_list(&self, ns: &str) -> Result<Vec<String>, tonic::Status> {
|
||||||
let namespace = match ns {
|
let namespace = self.check_namespace(ns);
|
||||||
"" => NAMESPACE,
|
let namespace = namespace.as_str();
|
||||||
_ => ns,
|
|
||||||
};
|
|
||||||
let mut c = self.client.lock().unwrap().containers();
|
let mut c = self.client.lock().unwrap().containers();
|
||||||
|
|
||||||
let request = ListContainersRequest {
|
let request = ListContainersRequest {
|
||||||
@ -340,13 +340,86 @@ impl Service {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_image(&self) {
|
pub async fn prepare_image(
|
||||||
todo!()
|
&self,
|
||||||
|
image_name: &str,
|
||||||
|
ns: &str,
|
||||||
|
always_pull: bool,
|
||||||
|
) -> Result<(), Err> {
|
||||||
|
if always_pull {
|
||||||
|
self.pull_image(image_name, ns).await?;
|
||||||
|
} else {
|
||||||
|
let namespace = self.check_namespace(ns);
|
||||||
|
let namespace = namespace.as_str();
|
||||||
|
let mut c = self.client.lock().unwrap().images();
|
||||||
|
let req = GetImageRequest {
|
||||||
|
name: image_name.to_string(),
|
||||||
|
};
|
||||||
|
let resp = c
|
||||||
|
.get(with_namespace!(req, namespace))
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
eprintln!(
|
||||||
|
"Failed to get the config of {} in namespace {}: {}",
|
||||||
|
image_name, namespace, e
|
||||||
|
);
|
||||||
|
e
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
.unwrap()
|
||||||
|
.into_inner();
|
||||||
|
if resp.image.is_none() {
|
||||||
|
self.pull_image(image_name, ns).await?;
|
||||||
}
|
}
|
||||||
pub fn pull_image(&self) {
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
/// 获取resolver,验证用,后面拉取镜像可能会用到
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn pull_image(&self, image_name: &str, ns: &str) -> Result<(), Err> {
|
||||||
|
let namespace = self.check_namespace(ns);
|
||||||
|
let namespace = namespace.as_str();
|
||||||
|
|
||||||
|
let mut c = self.client.lock().unwrap().transfer();
|
||||||
|
let source = OciRegistry {
|
||||||
|
reference: image_name.to_string(),
|
||||||
|
resolver: Default::default(),
|
||||||
|
};
|
||||||
|
// 这里先写死linux amd64
|
||||||
|
let platform = Platform {
|
||||||
|
os: "linux".to_string(),
|
||||||
|
architecture: "amd64".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let dest = ImageStore {
|
||||||
|
name: image_name.to_string(),
|
||||||
|
platforms: vec![platform.clone()],
|
||||||
|
unpacks: vec![UnpackConfiguration {
|
||||||
|
platform: Some(platform),
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let anys = to_any(&source);
|
||||||
|
let anyd = to_any(&dest);
|
||||||
|
|
||||||
|
let req = TransferRequest {
|
||||||
|
source: Some(anys),
|
||||||
|
destination: Some(anyd),
|
||||||
|
options: Some(TransferOptions {
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
c.transfer(with_namespace!(req, namespace))
|
||||||
|
.await
|
||||||
|
.expect(&format!(
|
||||||
|
"Unable to transfer image {} to namespace {}",
|
||||||
|
image_name, namespace
|
||||||
|
));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不用这个也能拉取镜像?
|
||||||
pub fn get_resolver(&self) {
|
pub fn get_resolver(&self) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
@ -518,6 +591,13 @@ impl Service {
|
|||||||
}
|
}
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_namespace(&self, ns: &str) -> String {
|
||||||
|
match ns {
|
||||||
|
"" => DEFAULT_NAMESPACE.to_string(),
|
||||||
|
_ => ns.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//容器是容器,要先启动,然后才能运行任务
|
//容器是容器,要先启动,然后才能运行任务
|
||||||
//要想删除一个正在运行的Task,必须先kill掉这个task,然后才能删除。
|
//要想删除一个正在运行的Task,必须先kill掉这个task,然后才能删除。
|
||||||
|
80
crates/service/src/systemd.rs
Normal file
80
crates/service/src/systemd.rs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
use crate::Err;
|
||||||
|
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::new(
|
||||||
|
std::io::ErrorKind::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::new(
|
||||||
|
std::io::ErrorKind::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::new(
|
||||||
|
std::io::ErrorKind::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").map_or(true, |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(())
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user