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>
This commit is contained in:
Finn Behrens 2023-11-12 17:12:36 +01:00 committed by Kent Overstreet
parent 73da05d983
commit a613340b26
2 changed files with 32 additions and 23 deletions
rust-src/src

View File

@ -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 {

View File

@ -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")),
}
}