168 lines
6.0 KiB
Diff
168 lines
6.0 KiB
Diff
|
|
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!"))?;
|
||
|
|
--
|
||
|
|
2.39.5 (Apple Git-154)
|
||
|
|
|