support docker runtime in dfinit with ut (#868)
Signed-off-by: cormick <cormick1080@gmail.com>
This commit is contained in:
parent
62c62f7ec6
commit
c93e01b005
|
|
@ -1016,6 +1016,7 @@ dependencies = [
|
|||
"dragonfly-client",
|
||||
"dragonfly-client-config",
|
||||
"dragonfly-client-core",
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"toml",
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ bytesize-serde = "0.2.1"
|
|||
percent-encoding = "2.3.1"
|
||||
tempfile = "3.14.0"
|
||||
tokio-rustls = "0.25.0-alpha.4"
|
||||
serde_json = "1.0.132"
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z"
|
||||
|
|
|
|||
|
|
@ -26,3 +26,4 @@ toml_edit.workspace = true
|
|||
toml.workspace = true
|
||||
url.workspace = true
|
||||
tempfile.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
|
|
|||
|
|
@ -15,8 +15,14 @@
|
|||
*/
|
||||
|
||||
use dragonfly_client_config::dfinit;
|
||||
use dragonfly_client_core::{Error, Result};
|
||||
use dragonfly_client_core::{
|
||||
error::{ErrorType, OrErr},
|
||||
Error, Result,
|
||||
};
|
||||
use serde_json::{json, Value};
|
||||
use tokio::{self, fs};
|
||||
use tracing::{info, instrument};
|
||||
use url::Url;
|
||||
|
||||
/// Docker represents the docker runtime manager.
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -40,8 +46,6 @@ impl Docker {
|
|||
}
|
||||
}
|
||||
|
||||
/// TODO: Implement the run method for Docker.
|
||||
///
|
||||
/// run runs the docker runtime to initialize
|
||||
/// runtime environment for the dfdaemon.
|
||||
#[instrument(skip_all)]
|
||||
|
|
@ -50,6 +54,200 @@ impl Docker {
|
|||
"docker feature is enabled, proxy_addr: {}, config_path: {:?}",
|
||||
self.proxy_config.addr, self.config.config_path,
|
||||
);
|
||||
Err(Error::Unimplemented)
|
||||
|
||||
// Parse proxy address to get host and port.
|
||||
let proxy_url = Url::parse(&self.proxy_config.addr).or_err(ErrorType::ParseError)?;
|
||||
let proxy_host = proxy_url
|
||||
.host_str()
|
||||
.ok_or(Error::Unknown("host not found".to_string()))?;
|
||||
let proxy_port = proxy_url
|
||||
.port_or_known_default()
|
||||
.ok_or(Error::Unknown("port not found".to_string()))?;
|
||||
let proxy_location = format!("{}:{}", proxy_host, proxy_port);
|
||||
|
||||
// Prepare proxies configuration.
|
||||
let mut proxies_map = serde_json::Map::new();
|
||||
proxies_map.insert(
|
||||
"http-proxy".to_string(),
|
||||
json!(format!("http://{}", proxy_location)),
|
||||
);
|
||||
proxies_map.insert(
|
||||
"https-proxy".to_string(),
|
||||
json!(format!("http://{}", proxy_location)),
|
||||
);
|
||||
|
||||
let config_path = &self.config.config_path;
|
||||
let mut docker_config: serde_json::Map<String, Value> = if config_path.exists() {
|
||||
let contents = fs::read_to_string(config_path).await?;
|
||||
if contents.trim().is_empty() {
|
||||
serde_json::Map::new()
|
||||
} else {
|
||||
serde_json::from_str(&contents).or_err(ErrorType::ParseError)?
|
||||
}
|
||||
} else {
|
||||
serde_json::Map::new()
|
||||
};
|
||||
|
||||
// Insert or update proxies configuration.
|
||||
docker_config.insert("proxies".to_string(), Value::Object(proxies_map));
|
||||
|
||||
// Create config directory if it doesn't exist.
|
||||
let config_dir = config_path
|
||||
.parent()
|
||||
.ok_or(Error::Unknown("invalid config path".to_string()))?;
|
||||
fs::create_dir_all(config_dir).await?;
|
||||
|
||||
// Write configuration to file.
|
||||
fs::write(
|
||||
config_path,
|
||||
serde_json::to_string_pretty(&Value::Object(docker_config))
|
||||
.or_err(ErrorType::SerializeError)?,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use tempfile::NamedTempFile;
|
||||
use tokio::fs;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_docker_config_empty() {
|
||||
let docker_config_file = NamedTempFile::new().unwrap();
|
||||
let docker = Docker::new(
|
||||
dfinit::Docker {
|
||||
config_path: docker_config_file.path().to_path_buf(),
|
||||
},
|
||||
dfinit::Proxy {
|
||||
addr: "http://127.0.0.1:5000".into(),
|
||||
},
|
||||
);
|
||||
|
||||
let result = docker.run().await;
|
||||
println!("{:?}", result);
|
||||
assert!(result.is_ok());
|
||||
|
||||
// Read and verify configuration.
|
||||
let contents = fs::read_to_string(docker_config_file.path()).await.unwrap();
|
||||
let config: serde_json::Value = serde_json::from_str(&contents).unwrap();
|
||||
|
||||
// Verify proxies configuration.
|
||||
assert_eq!(config["proxies"]["http-proxy"], "http://127.0.0.1:5000");
|
||||
assert_eq!(config["proxies"]["https-proxy"], "http://127.0.0.1:5000");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_docker_config_existing() {
|
||||
let docker_config_file = NamedTempFile::new().unwrap();
|
||||
let initial_config = r#"
|
||||
{
|
||||
"log-driver": "json-file",
|
||||
"experimental": true
|
||||
}
|
||||
"#;
|
||||
fs::write(docker_config_file.path(), initial_config)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let docker = Docker::new(
|
||||
dfinit::Docker {
|
||||
config_path: docker_config_file.path().to_path_buf(),
|
||||
},
|
||||
dfinit::Proxy {
|
||||
addr: "http://127.0.0.1:5000".into(),
|
||||
},
|
||||
);
|
||||
|
||||
let result = docker.run().await;
|
||||
assert!(result.is_ok());
|
||||
|
||||
// Read and verify configuration.
|
||||
let contents = fs::read_to_string(docker_config_file.path()).await.unwrap();
|
||||
let config: serde_json::Value = serde_json::from_str(&contents).unwrap();
|
||||
|
||||
// Verify existing configurations.
|
||||
assert_eq!(config["log-driver"], "json-file");
|
||||
assert_eq!(config["experimental"], true);
|
||||
|
||||
// Verify proxies configuration.
|
||||
assert_eq!(config["proxies"]["http-proxy"], "http://127.0.0.1:5000");
|
||||
assert_eq!(config["proxies"]["https-proxy"], "http://127.0.0.1:5000");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_docker_config_invalid_json() {
|
||||
let docker_config_file = NamedTempFile::new().unwrap();
|
||||
let invalid_config = r#"
|
||||
{
|
||||
"log-driver": "json-file",
|
||||
"experimental": true,
|
||||
}
|
||||
"#;
|
||||
fs::write(docker_config_file.path(), invalid_config)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let docker = Docker::new(
|
||||
dfinit::Docker {
|
||||
config_path: docker_config_file.path().to_path_buf(),
|
||||
},
|
||||
dfinit::Proxy {
|
||||
addr: "http://127.0.0.1:5000".into(),
|
||||
},
|
||||
);
|
||||
|
||||
let result = docker.run().await;
|
||||
assert!(result.is_err());
|
||||
if let Err(e) = result {
|
||||
assert_eq!(
|
||||
format!("{}", e),
|
||||
"ParseError cause: trailing comma at line 5 column 9"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_docker_config_proxies_existing() {
|
||||
let docker_config_file = NamedTempFile::new().unwrap();
|
||||
let existing_proxies = r#"
|
||||
{
|
||||
"proxies": {
|
||||
"http-proxy": "http://old-proxy:3128",
|
||||
"https-proxy": "https://old-proxy:3129",
|
||||
"no-proxy": "old-no-proxy"
|
||||
},
|
||||
"log-driver": "json-file"
|
||||
}
|
||||
"#;
|
||||
fs::write(docker_config_file.path(), existing_proxies)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let docker = Docker::new(
|
||||
dfinit::Docker {
|
||||
config_path: docker_config_file.path().to_path_buf(),
|
||||
},
|
||||
dfinit::Proxy {
|
||||
addr: "http://127.0.0.1:5000".into(),
|
||||
},
|
||||
);
|
||||
|
||||
let result = docker.run().await;
|
||||
assert!(result.is_ok());
|
||||
|
||||
// Read and verify configuration.
|
||||
let contents = fs::read_to_string(docker_config_file.path()).await.unwrap();
|
||||
let config: serde_json::Value = serde_json::from_str(&contents).unwrap();
|
||||
|
||||
// Verify existing configurations.
|
||||
assert_eq!(config["log-driver"], "json-file");
|
||||
|
||||
// Verify proxies configuration.
|
||||
assert_eq!(config["proxies"]["http-proxy"], "http://127.0.0.1:5000");
|
||||
assert_eq!(config["proxies"]["https-proxy"], "http://127.0.0.1:5000");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ bytesize.workspace = true
|
|||
uuid.workspace = true
|
||||
percent-encoding.workspace = true
|
||||
tokio-rustls.workspace = true
|
||||
serde_json.workspace = true
|
||||
lazy_static = "1.5"
|
||||
serde_json = "1.0"
|
||||
tracing-log = "0.2"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter", "time", "chrono"] }
|
||||
tracing-appender = "0.2.3"
|
||||
|
|
|
|||
Loading…
Reference in New Issue