From a613340b26ad88801666362d2824118396f34c38 Mon Sep 17 00:00:00 2001 From: Finn Behrens <me@kloenk.de> Date: Sun, 12 Nov 2023 17:12:36 +0100 Subject: [PATCH] rust keylocation add none variant and implement ValueEnum This enables a possible values help in the clap help text. Signed-Off-By: Finn Behrens <me@kloenk.de> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- rust-src/src/cmd_mount.rs | 11 +++------- rust-src/src/key.rs | 44 ++++++++++++++++++++++++++------------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/rust-src/src/cmd_mount.rs b/rust-src/src/cmd_mount.rs index 9d58cb3e..17a289ca 100644 --- a/rust-src/src/cmd_mount.rs +++ b/rust-src/src/cmd_mount.rs @@ -5,7 +5,7 @@ use clap::{Parser, Subcommand}; use uuid::Uuid; use std::path::PathBuf; use crate::{key, transform_c_args}; -use crate::key::KeyLoc; +use crate::key::KeyLocation; use crate::logger::SimpleLogger; use std::ffi::{CStr, CString, OsStr, c_int, c_char, c_void}; use std::os::unix::ffi::OsStrExt; @@ -137,7 +137,7 @@ pub struct Cli { /// "wait" - wait for password to become available before mounting; /// "ask" - prompt the user for password; #[arg(short, long, default_value = "ask", verbatim_doc_comment)] - key_location: KeyLoc, + key_location: KeyLocation, /// Device, or UUID=<UUID> dev: String, @@ -199,12 +199,7 @@ fn cmd_mount_inner(opt: Cli) -> anyhow::Result<()> { if sbs.len() == 0 { Err(anyhow::anyhow!("No device found from specified parameters"))?; } else if unsafe { bcachefs::bch2_sb_is_encrypted(sbs[0].sb) } { - let key = opt - .key_location - .0 - .ok_or_else(|| anyhow::anyhow!("no keyoption specified for locked filesystem"))?; - - key::prepare_key(&sbs[0], key)?; + key::prepare_key(&sbs[0], opt.key_location)?; } if let Some(mountpoint) = opt.mountpoint { diff --git a/rust-src/src/key.rs b/rust-src/src/key.rs index 9319351e..93daa263 100644 --- a/rust-src/src/key.rs +++ b/rust-src/src/key.rs @@ -1,37 +1,50 @@ use log::{info}; use bch_bindgen::bcachefs::bch_sb_handle; +use clap::builder::PossibleValue; use crate::c_str; use anyhow::anyhow; #[derive(Clone, Debug)] pub enum KeyLocation { + None, Fail, Wait, Ask, } -#[derive(Clone, Debug)] -pub struct KeyLoc(pub Option<KeyLocation>); -impl std::ops::Deref for KeyLoc { - type Target = Option<KeyLocation>; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl std::str::FromStr for KeyLoc { +impl std::str::FromStr for KeyLocation { type Err = anyhow::Error; fn from_str(s: &str) -> anyhow::Result<Self> { match s { - "" => Ok(KeyLoc(None)), - "fail" => Ok(KeyLoc(Some(KeyLocation::Fail))), - "wait" => Ok(KeyLoc(Some(KeyLocation::Wait))), - "ask" => Ok(KeyLoc(Some(KeyLocation::Ask))), - _ => Err(anyhow!("invalid password option")), + ""|"none" => Ok(KeyLocation::None), + "fail" => Ok(KeyLocation::Fail), + "wait" => Ok(KeyLocation::Wait), + "ask" => Ok(KeyLocation::Ask), + _ => Err(anyhow!("invalid password option")), } } } +impl clap::ValueEnum for KeyLocation { + fn value_variants<'a>() -> &'a [Self] { + &[ + KeyLocation::None, + KeyLocation::Fail, + KeyLocation::Wait, + KeyLocation::Ask, + ] + } + + fn to_possible_value(&self) -> Option<PossibleValue> { + Some(match self { + Self::None => PossibleValue::new("none").alias(""), + Self::Fail => PossibleValue::new("fail"), + Self::Wait => PossibleValue::new("wait"), + Self::Ask => PossibleValue::new("ask"), + }) + } +} + fn check_for_key(key_name: &std::ffi::CStr) -> anyhow::Result<bool> { use bch_bindgen::keyutils::{self, keyctl_search}; let key_name = key_name.to_bytes_with_nul().as_ptr() as *const _; @@ -126,5 +139,6 @@ pub fn prepare_key(sb: &bch_sb_handle, password: KeyLocation) -> anyhow::Result< KeyLocation::Fail => Err(anyhow!("no key available")), KeyLocation::Wait => Ok(wait_for_key(&sb.sb().uuid())?), KeyLocation::Ask => ask_for_key(sb), + _ => Err(anyhow!("no keyoption specified for locked filesystem")), } }