bootstrap: add UdevFilter
This commit is contained in:
617
Cargo.lock
generated
617
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,7 @@ use dkl::dls;
|
||||
#[derive(Parser)]
|
||||
#[command()]
|
||||
struct Cli {
|
||||
#[arg(long, default_value = "http://[::1]:7606")]
|
||||
#[arg(long, default_value = "http://[::1]:7606", env = "DLS_URL")]
|
||||
dls: String,
|
||||
|
||||
#[command(subcommand)]
|
||||
|
||||
@ -57,7 +57,10 @@ pub struct Network {
|
||||
pub struct NetworkInterface {
|
||||
pub var: String,
|
||||
pub n: i16,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub regexps: Vec<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub udev: Option<UdevFilter>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
@ -142,41 +145,77 @@ pub enum LvSize {
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct LvmPV {
|
||||
pub n: i16,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub regexps: Vec<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub udev: Option<UdevFilter>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct CryptDev {
|
||||
pub name: String,
|
||||
#[serde(flatten)]
|
||||
pub filter: DevFilter,
|
||||
// hit the limit of enum representation here (flatten + enum variant case)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub dev: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub prefix: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub udev: Option<UdevFilter>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub optional: Option<bool>,
|
||||
}
|
||||
impl CryptDev {
|
||||
pub fn optional(&self) -> bool {
|
||||
self.optional.unwrap_or_else(|| self.filter.is_prefix())
|
||||
pub fn filter(&self) -> DevFilter<'_> {
|
||||
if let Some(dev) = self.dev.as_deref() {
|
||||
DevFilter::Dev(dev)
|
||||
} else if let Some(prefix) = self.prefix.as_deref() {
|
||||
DevFilter::Prefix(prefix)
|
||||
} else if let Some(udev) = self.udev.as_ref() {
|
||||
DevFilter::Udev(udev)
|
||||
} else {
|
||||
DevFilter::None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub fn optional(&self) -> bool {
|
||||
self.optional.unwrap_or_else(|| match self.filter() {
|
||||
DevFilter::None => true,
|
||||
DevFilter::Dev(_) => false,
|
||||
DevFilter::Prefix(_) => true,
|
||||
DevFilter::Udev(_) => true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_crypt_dev() {
|
||||
for s in [
|
||||
"name: sys0\ndev: /dev/sda\n",
|
||||
"name: crypt-\nprefix: /dev/sd\n",
|
||||
"name: crypt-${name}\nudev: !glob [ DEVNAME, /dev/sd* ]\n",
|
||||
] {
|
||||
let dev: CryptDev = serde_yaml::from_str(s).unwrap();
|
||||
dev.filter();
|
||||
dev.optional();
|
||||
}
|
||||
}
|
||||
|
||||
pub enum DevFilter<'t> {
|
||||
None,
|
||||
Dev(&'t str),
|
||||
Prefix(&'t str),
|
||||
Udev(&'t UdevFilter),
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DevFilter {
|
||||
Dev(String),
|
||||
Prefix(String),
|
||||
}
|
||||
impl DevFilter {
|
||||
pub fn is_dev(&self) -> bool {
|
||||
match self {
|
||||
Self::Dev(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn is_prefix(&self) -> bool {
|
||||
match self {
|
||||
Self::Prefix(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub enum UdevFilter {
|
||||
Has(String),
|
||||
Eq(String, String),
|
||||
Glob(String, String),
|
||||
And(Vec<UdevFilter>),
|
||||
Or(Vec<UdevFilter>),
|
||||
Not(Box<UdevFilter>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
|
||||
|
||||
Reference in New Issue
Block a user