use super::{command_mechanism, ActionSpec};
use sysknife_types::RiskLevel;
pub fn specs() -> Vec<ActionSpec> {
vec![
get_lvm_report(),
extend_logical_volume("ubuntu-vg", "ubuntu-lv", "+10G"),
create_logical_volume("ubuntu-vg", "data", "20G"),
create_lv_snapshot("ubuntu-vg", "ubuntu-lv", "ubuntu-lv-snap", "5G"),
]
}
pub fn get_lvm_report() -> ActionSpec {
ActionSpec {
action_name: "GetLvmReport",
mechanism: command_mechanism(
"lvs",
[
"--reportformat",
"json",
"--units",
"b",
"-o",
"lv_name,vg_name,lv_size,lv_attr,origin,data_percent",
],
),
risk_level: RiskLevel::Low,
reboot_required: false,
rollback_available: false,
}
}
pub fn extend_logical_volume(vg: &str, lv: &str, size: &str) -> ActionSpec {
ActionSpec {
action_name: "ExtendLogicalVolume",
mechanism: command_mechanism(
"sudo",
["lvextend", "-L", size, "-r", &format!("{vg}/{lv}")],
),
risk_level: RiskLevel::High,
reboot_required: false,
rollback_available: false,
}
}
pub fn create_logical_volume(vg: &str, name: &str, size: &str) -> ActionSpec {
ActionSpec {
action_name: "CreateLogicalVolume",
mechanism: command_mechanism("sudo", ["lvcreate", "-L", size, "-n", name, vg]),
risk_level: RiskLevel::Medium,
reboot_required: false,
rollback_available: false,
}
}
pub fn create_lv_snapshot(vg: &str, origin: &str, snapshot: &str, size: &str) -> ActionSpec {
ActionSpec {
action_name: "CreateLvSnapshot",
mechanism: command_mechanism(
"sudo",
[
"lvcreate",
"-s",
"-L",
size,
"-n",
snapshot,
&format!("{vg}/{origin}"),
],
),
risk_level: RiskLevel::Medium,
reboot_required: false,
rollback_available: false,
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::actions::ActionMechanism;
fn args_of(spec: &ActionSpec) -> (&'static str, Vec<String>) {
match &spec.mechanism {
ActionMechanism::Command { program, args } => (program, args.clone()),
other => panic!("expected Command, got {other:?}"),
}
}
#[test]
fn report_is_read_only_json() {
let spec = get_lvm_report();
let (program, args) = args_of(&spec);
assert_eq!(program, "lvs");
assert!(args.contains(&"--reportformat".to_string()));
assert!(args.contains(&"json".to_string()));
assert_eq!(spec.risk_level, RiskLevel::Low);
}
#[test]
fn extend_uses_resizefs_flag_and_vg_lv_ref() {
let spec = extend_logical_volume("ubuntu-vg", "root", "+10G");
let (program, args) = args_of(&spec);
assert_eq!(program, "sudo");
assert_eq!(args, vec!["lvextend", "-L", "+10G", "-r", "ubuntu-vg/root"]);
assert_eq!(spec.risk_level, RiskLevel::High);
}
#[test]
fn create_lv_and_snapshot_shapes() {
let (_, create) = args_of(&create_logical_volume("vg0", "data", "20G"));
assert_eq!(create, vec!["lvcreate", "-L", "20G", "-n", "data", "vg0"]);
let (_, snap) = args_of(&create_lv_snapshot("vg0", "root", "root-snap", "5G"));
assert_eq!(
snap,
vec!["lvcreate", "-s", "-L", "5G", "-n", "root-snap", "vg0/root"]
);
}
}