From 72dd36b4cefee5a85145103771d9352585cc9388 Mon Sep 17 00:00:00 2001 From: Yuhang Wei <weiyuhang3@huawei.com> Date: Fri, 13 Dec 2024 15:31:09 +0800 Subject: [PATCH 1/2] fix(kbimg): add info log for successful image creation Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com> --- KubeOS-Rust/kbimg/src/main.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/KubeOS-Rust/kbimg/src/main.rs b/KubeOS-Rust/kbimg/src/main.rs index 43e9d422..0af7ff89 100644 --- a/KubeOS-Rust/kbimg/src/main.rs +++ b/KubeOS-Rust/kbimg/src/main.rs @@ -15,7 +15,7 @@ use std::{fs, path::PathBuf, process::exit}; use anyhow::Result; use clap::Parser; use env_logger::{Builder, Env, Target}; -use log::{debug, error}; +use log::{debug, error, info}; mod admin_container; mod commands; @@ -55,6 +55,7 @@ fn process(info: Box<dyn CreateImage>, mut config: Config, debug: bool) -> Resul let path = info.generate_scripts(&config)?; if !debug { execute_scripts(path)?; + info!("Image created successfully"); } else { debug!("Executed following command to generate KubeOS image: bash {:?}", path); } @@ -129,14 +130,9 @@ fn main() { } if let Some(i) = info { - match process(i, data, cli.debug) { - Ok(_) => { - println!("Image created successfully"); - }, - Err(e) => { - error!("Failed to create image: {:?}", e); - exit(1); - }, + if let Err(e) = process(i, data, cli.debug) { + error!("Failed to create image: {:?}", e); + exit(1); } } exit(0); -- Gitee From 9030b7f223e1fec1ab4c3612dbcc4b231743ad25 Mon Sep 17 00:00:00 2001 From: Yuhang Wei <weiyuhang3@huawei.com> Date: Fri, 13 Dec 2024 15:31:22 +0800 Subject: [PATCH 2/2] fix(kbimg): enforce non-empty strings for required fields in deserialization Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com> --- KubeOS-Rust/kbimg/src/commands.rs | 46 ++++++++++++++++++++++++++++++- KubeOS-Rust/kbimg/src/main.rs | 8 +++++- KubeOS-Rust/kbimg/src/repo.rs | 4 +-- 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/KubeOS-Rust/kbimg/src/commands.rs b/KubeOS-Rust/kbimg/src/commands.rs index c5bc3890..24fc1031 100644 --- a/KubeOS-Rust/kbimg/src/commands.rs +++ b/KubeOS-Rust/kbimg/src/commands.rs @@ -54,14 +54,17 @@ pub enum CreateType { #[derive(Debug, Deserialize, Clone)] pub struct RepoInfo { /// Required: KubeOS version + #[serde(deserialize_with = "reject_empty_string")] pub version: String, /// Required: Repo path for installing packages pub repo_path: PathBuf, /// Required: Path to the os-agent binary pub agent_path: PathBuf, /// Required: Encrypted password for root user + #[serde(deserialize_with = "reject_empty_string")] pub root_passwd: String, /// Required for creating upgrade docker image + #[serde(default, deserialize_with = "reject_empty_option_string")] pub upgrade_img: Option<String>, /// Required: RPM packages pub rpmlist: Vec<String>, @@ -84,6 +87,7 @@ pub struct DockerImgInfo { #[derive(Debug, Deserialize, Clone)] pub struct AdminContainerInfo { /// Required: Name of the container image + #[serde(deserialize_with = "reject_empty_string")] pub img_name: String, /// Required: Path to the hostshell binary pub hostshell: PathBuf, @@ -107,21 +111,28 @@ pub struct Config { #[derive(Deserialize, Debug, Clone)] pub struct User { + #[serde(deserialize_with = "reject_empty_string")] pub name: String, + #[serde(deserialize_with = "reject_empty_string")] pub passwd: String, + #[serde(default, deserialize_with = "reject_empty_option_string")] pub primary_group: Option<String>, pub groups: Option<Vec<String>>, } #[derive(Deserialize, Debug, Clone)] pub struct CopyFile { + #[serde(deserialize_with = "reject_empty_string")] pub src: String, + #[serde(deserialize_with = "reject_empty_string")] pub dst: String, + #[serde(default, deserialize_with = "reject_empty_option_string")] pub create_dir: Option<String>, } #[derive(Deserialize, Debug, Clone)] pub struct Grub { + #[serde(deserialize_with = "reject_empty_string")] pub passwd: String, } @@ -149,19 +160,28 @@ pub struct PersistMkdir { #[derive(Debug, Deserialize, Clone)] pub struct PxeConfig { + #[serde(deserialize_with = "reject_empty_string")] pub rootfs_name: String, + #[serde(deserialize_with = "reject_empty_string")] pub disk: String, + #[serde(deserialize_with = "reject_empty_string")] pub server_ip: String, - pub local_ip: Option<String>, + #[serde(deserialize_with = "reject_empty_string")] pub route_ip: String, + #[serde(default, deserialize_with = "reject_empty_option_string")] + pub local_ip: Option<String>, + #[serde(default, deserialize_with = "reject_empty_option_string")] pub netmask: Option<String>, + #[serde(default, deserialize_with = "reject_empty_option_string")] pub net_name: Option<String>, pub dhcp: Option<bool>, } #[derive(Debug, Deserialize, Clone)] pub struct DmVerity { + #[serde(deserialize_with = "reject_empty_string")] pub efi_key: String, + #[serde(deserialize_with = "reject_empty_string")] pub grub_key: String, pub keys_dir: Option<PathBuf>, } @@ -196,3 +216,27 @@ impl From<&str> for ImageType { } } } + +fn reject_empty_option_string<'de, D>(deserializer: D) -> Result<Option<String>, D::Error> +where + D: serde::Deserializer<'de>, +{ + let opt = Option::<String>::deserialize(deserializer)?; + if let Some(ref value) = opt { + if value.trim().is_empty() { + return Err(serde::de::Error::custom("String in Option should not be an empty string if provided")); + } + } + Ok(opt) +} + +fn reject_empty_string<'de, D>(deserializer: D) -> Result<String, D::Error> +where + D: serde::Deserializer<'de>, +{ + let value: String = Deserialize::deserialize(deserializer)?; + if value.trim().is_empty() { + return Err(serde::de::Error::custom("String field should not be empty")); + } + Ok(value) +} diff --git a/KubeOS-Rust/kbimg/src/main.rs b/KubeOS-Rust/kbimg/src/main.rs index 0af7ff89..878d41f4 100644 --- a/KubeOS-Rust/kbimg/src/main.rs +++ b/KubeOS-Rust/kbimg/src/main.rs @@ -74,7 +74,13 @@ fn main() { }; debug!("Config file path: {:?}", config); let content = fs::read_to_string(config).expect("Failed to read config file"); - let data: Config = toml::from_str(&content).expect("Failed to parse toml file"); + let data: Config = match toml::from_str(&content) { + Ok(d) => d, + Err(e) => { + error!("Failed to parse config file: {}", e); + exit(1); + }, + }; debug!("Config: {:?}", data); let info; diff --git a/KubeOS-Rust/kbimg/src/repo.rs b/KubeOS-Rust/kbimg/src/repo.rs index 3f11d072..752ca403 100644 --- a/KubeOS-Rust/kbimg/src/repo.rs +++ b/KubeOS-Rust/kbimg/src/repo.rs @@ -287,8 +287,8 @@ impl RepoInfo { // Check pxe config fn check_pxe_conf_valid(config: &PxeConfig) -> anyhow::Result<()> { if config.dhcp.unwrap_or(false) { - if config.local_ip.is_some() || config.net_name.is_some() { - bail!("dhcp and local_ip/net_name cannot be set at the same time"); + if config.local_ip.is_some() || config.net_name.is_some() || config.netmask.is_some() { + bail!("dhcp and local_ip/net_name/netmask cannot be set at the same time"); } } else { let local_ip = config.local_ip.as_ref().ok_or_else(|| anyhow!("local_ip not found!"))?; -- Gitee