Upgrade clap, rpassword and pwhash to prepare for new code using them
This commit is contained in:
parent
b7e6ee3b3c
commit
2a16bd4c41
1550
Cargo.lock
generated
1550
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
2648
citadel-installer-ui/Cargo.lock
generated
2648
citadel-installer-ui/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -8,14 +8,14 @@ homepage = "https://subgraph.com"
|
||||
|
||||
[dependencies]
|
||||
libcitadel = { path = "../libcitadel" }
|
||||
rpassword = "4.0"
|
||||
clap = "2.33"
|
||||
rpassword = "7.3"
|
||||
clap = { version = "4.5", features = ["cargo", "derive"] }
|
||||
lazy_static = "1.4"
|
||||
serde_derive = "1.0"
|
||||
serde = "1.0"
|
||||
toml = "0.5"
|
||||
toml = "0.8"
|
||||
hex = "0.4"
|
||||
byteorder = "1"
|
||||
dbus = "0.8.4"
|
||||
pwhash = "0.3.1"
|
||||
pwhash = "1.0"
|
||||
tempfile = "3"
|
||||
|
@ -1,89 +1,97 @@
|
||||
use std::path::Path;
|
||||
use std::process::exit;
|
||||
|
||||
use clap::{App,Arg,SubCommand,ArgMatches};
|
||||
use clap::AppSettings::*;
|
||||
use libcitadel::{Result, ResourceImage, Logger, LogLevel, Partition, KeyPair, ImageHeader, util};
|
||||
use clap::{Arg,ArgMatches};
|
||||
use clap::{command, ArgAction, Command};
|
||||
use hex;
|
||||
|
||||
pub fn main(args: Vec<String>) {
|
||||
use libcitadel::{Result, ResourceImage, Logger, LogLevel, Partition, KeyPair, ImageHeader, util};
|
||||
|
||||
let app = App::new("citadel-image")
|
||||
pub fn main() {
|
||||
let matches = command!()
|
||||
.about("Citadel update image builder")
|
||||
.settings(&[ArgRequiredElseHelp,ColoredHelp, DisableHelpSubcommand, DisableVersion, DeriveDisplayOrder])
|
||||
.arg_required_else_help(true)
|
||||
.disable_help_subcommand(true)
|
||||
.subcommand(
|
||||
Command::new("metainfo")
|
||||
.about("Display metainfo variables for an image file")
|
||||
.arg(Arg::new("path").required(true).help("Path to image file")),
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("info")
|
||||
.about("Display metainfo variables for an image file")
|
||||
.arg(Arg::new("path").required(true).help("Path to image file")),
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("generate-verity")
|
||||
.about("Generate dm-verity hash tree for an image file")
|
||||
.arg(Arg::new("path").required(true).help("Path to image file")),
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("verify")
|
||||
.about("Verify dm-verity hash tree for an image file")
|
||||
.arg(
|
||||
Arg::new("option")
|
||||
.long("option")
|
||||
.required(true)
|
||||
.help("Path to image file"),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("install-rootfs")
|
||||
.about("Install rootfs image file to a partition")
|
||||
.arg(
|
||||
Arg::new("choose")
|
||||
.long("just-choose")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Don't install anything, just show which partition would be chosen"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("skip-sha")
|
||||
.long("skip-sha")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Skip verification of header sha256 value"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("no-prefer")
|
||||
.long("no-prefer")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Don't set PREFER_BOOT flag"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("path")
|
||||
.required_unless_present("choose")
|
||||
.help("Path to image file"),
|
||||
),
|
||||
)
|
||||
.subcommand(Command::new("genkeys").about("Generate a pair of keys"))
|
||||
.subcommand(
|
||||
Command::new("decompress")
|
||||
.about("Decompress a compressed image file")
|
||||
.arg(Arg::new("path").required(true).help("Path to image file")),
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("bless")
|
||||
.about("Mark currently mounted rootfs partition as successfully booted"),
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("verify-shasum")
|
||||
.about("Verify the sha256 sum of the image")
|
||||
.arg(Arg::new("path").required(true).help("Path to image file")),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
.subcommand(SubCommand::with_name("metainfo")
|
||||
.about("Display metainfo variables for an image file")
|
||||
.arg(Arg::with_name("path")
|
||||
.required(true)
|
||||
.help("Path to image file")))
|
||||
|
||||
.subcommand(SubCommand::with_name("info")
|
||||
.about("Display metainfo variables for an image file")
|
||||
.arg(Arg::with_name("path")
|
||||
.required(true)
|
||||
.help("Path to image file")))
|
||||
|
||||
.subcommand(SubCommand::with_name("generate-verity")
|
||||
.about("Generate dm-verity hash tree for an image file")
|
||||
.arg(Arg::with_name("path")
|
||||
.required(true)
|
||||
.help("Path to image file")))
|
||||
|
||||
.subcommand(SubCommand::with_name("verify")
|
||||
.about("Verify dm-verity hash tree for an image file")
|
||||
.arg(Arg::with_name("path")
|
||||
.required(true)
|
||||
.help("Path to image file")))
|
||||
|
||||
.subcommand(SubCommand::with_name("install-rootfs")
|
||||
.about("Install rootfs image file to a partition")
|
||||
.arg(Arg::with_name("choose")
|
||||
.long("just-choose")
|
||||
.help("Don't install anything, just show which partition would be chosen"))
|
||||
.arg(Arg::with_name("skip-sha")
|
||||
.long("skip-sha")
|
||||
.help("Skip verification of header sha256 value"))
|
||||
.arg(Arg::with_name("no-prefer")
|
||||
.long("no-prefer")
|
||||
.help("Don't set PREFER_BOOT flag"))
|
||||
.arg(Arg::with_name("path")
|
||||
.required_unless("choose")
|
||||
.help("Path to image file")))
|
||||
|
||||
.subcommand(SubCommand::with_name("genkeys")
|
||||
.about("Generate a pair of keys"))
|
||||
|
||||
.subcommand(SubCommand::with_name("decompress")
|
||||
.about("Decompress a compressed image file")
|
||||
.arg(Arg::with_name("path")
|
||||
.required(true)
|
||||
.help("Path to image file")))
|
||||
|
||||
.subcommand(SubCommand::with_name("bless")
|
||||
.about("Mark currently mounted rootfs partition as successfully booted"))
|
||||
|
||||
.subcommand(SubCommand::with_name("verify-shasum")
|
||||
.about("Verify the sha256 sum of the image")
|
||||
.arg(Arg::with_name("path")
|
||||
.required(true)
|
||||
.help("Path to image file")));
|
||||
|
||||
Logger::set_log_level(LogLevel::Debug);
|
||||
|
||||
let matches = app.get_matches_from(args);
|
||||
let result = match matches.subcommand() {
|
||||
("metainfo", Some(m)) => metainfo(m),
|
||||
("info", Some(m)) => info(m),
|
||||
("generate-verity", Some(m)) => generate_verity(m),
|
||||
("verify", Some(m)) => verify(m),
|
||||
("sign-image", Some(m)) => sign_image(m),
|
||||
("genkeys", Some(_)) => genkeys(),
|
||||
("decompress", Some(m)) => decompress(m),
|
||||
("verify-shasum", Some(m)) => verify_shasum(m),
|
||||
("install-rootfs", Some(m)) => install_rootfs(m),
|
||||
("install", Some(m)) => install_image(m),
|
||||
("bless", Some(_)) => bless(),
|
||||
Some(("metainfo", sub_m)) => metainfo(sub_m),
|
||||
Some(("info", sub_m)) => info(sub_m),
|
||||
Some(("generate-verity", sub_m)) => generate_verity(sub_m),
|
||||
Some(("verify", sub_m)) => verify(sub_m),
|
||||
Some(("sign-image", sub_m)) => sign_image(sub_m),
|
||||
Some(("genkeys", _)) => genkeys(),
|
||||
Some(("decompress", sub_m)) => decompress(sub_m),
|
||||
Some(("verify-shasum", sub_m)) => verify_shasum(sub_m),
|
||||
Some(("install-rootfs", sub_m)) => install_rootfs(sub_m),
|
||||
Some(("install", sub_m)) => install_image(sub_m),
|
||||
Some(("bless", _)) => bless(),
|
||||
_ => Ok(()),
|
||||
};
|
||||
|
||||
@ -159,7 +167,9 @@ fn verify_shasum(arg_matches: &ArgMatches) -> Result<()> {
|
||||
}
|
||||
|
||||
fn load_image(arg_matches: &ArgMatches) -> Result<ResourceImage> {
|
||||
let path = arg_matches.value_of("path").expect("path argument missing");
|
||||
let path = arg_matches.get_one::<String>("path")
|
||||
.expect("path argument missing");
|
||||
|
||||
if !Path::new(path).exists() {
|
||||
bail!("Cannot load image {}: File does not exist", path);
|
||||
}
|
||||
@ -171,14 +181,14 @@ fn load_image(arg_matches: &ArgMatches) -> Result<ResourceImage> {
|
||||
}
|
||||
|
||||
fn install_rootfs(arg_matches: &ArgMatches) -> Result<()> {
|
||||
if arg_matches.is_present("choose") {
|
||||
if arg_matches.get_flag("choose") {
|
||||
let _ = choose_install_partition(true)?;
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
let img = load_image(arg_matches)?;
|
||||
|
||||
if !arg_matches.is_present("skip-sha") {
|
||||
if !arg_matches.get_flag("skip-sha") {
|
||||
info!("Verifying sha256 hash of image");
|
||||
let shasum = img.generate_shasum()?;
|
||||
if shasum != img.metainfo().shasum() {
|
||||
@ -188,7 +198,7 @@ fn install_rootfs(arg_matches: &ArgMatches) -> Result<()> {
|
||||
|
||||
let partition = choose_install_partition(true)?;
|
||||
|
||||
if !arg_matches.is_present("no-prefer") {
|
||||
if !arg_matches.get_flag("no-prefer") {
|
||||
clear_prefer_boot()?;
|
||||
img.header().set_flag(ImageHeader::FLAG_PREFER_BOOT);
|
||||
}
|
||||
@ -212,7 +222,9 @@ fn sign_image(arg_matches: &ArgMatches) -> Result<()> {
|
||||
}
|
||||
|
||||
fn install_image(arg_matches: &ArgMatches) -> Result<()> {
|
||||
let source = arg_matches.value_of("path").expect("path argument missing");
|
||||
let source = arg_matches.get_one::<String>("path")
|
||||
.expect("path argument missing");
|
||||
|
||||
let img = load_image(arg_matches)?;
|
||||
let _hdr = img.header();
|
||||
let metainfo = img.metainfo();
|
||||
|
@ -125,7 +125,7 @@ fn read_passphrase(prompt: &str) -> io::Result<Option<String>> {
|
||||
loop {
|
||||
println!("{}", prompt);
|
||||
println!();
|
||||
let passphrase = rpassword::read_password_from_tty(Some(" Passphrase : "))?;
|
||||
let passphrase = rpassword::prompt_password(" Passphrase : ")?;
|
||||
if passphrase.is_empty() {
|
||||
println!("Passphrase cannot be empty");
|
||||
continue;
|
||||
@ -133,7 +133,7 @@ fn read_passphrase(prompt: &str) -> io::Result<Option<String>> {
|
||||
if passphrase == "q" || passphrase == "Q" {
|
||||
return Ok(None);
|
||||
}
|
||||
let confirm = rpassword::read_password_from_tty(Some(" Confirm : "))?;
|
||||
let confirm = rpassword::prompt_password(" Confirm : ")?;
|
||||
if confirm == "q" || confirm == "Q" {
|
||||
return Ok(None);
|
||||
}
|
||||
|
@ -34,9 +34,9 @@ fn main() {
|
||||
} else if exe == Path::new("/usr/libexec/citadel-install-backend") {
|
||||
install_backend::main();
|
||||
} else if exe == Path::new("/usr/bin/citadel-image") {
|
||||
image::main(args);
|
||||
image::main();
|
||||
} else if exe == Path::new("/usr/bin/citadel-realmfs") {
|
||||
realmfs::main(args);
|
||||
realmfs::main();
|
||||
} else if exe == Path::new("/usr/bin/citadel-update") {
|
||||
update::main(args);
|
||||
} else if exe == Path::new("/usr/libexec/citadel-desktop-sync") {
|
||||
@ -57,8 +57,8 @@ fn dispatch_command(args: Vec<String>) {
|
||||
match command.as_str() {
|
||||
"boot" => boot::main(rebuild_args("citadel-boot", args)),
|
||||
"install" => install::main(rebuild_args("citadel-install", args)),
|
||||
"image" => image::main(rebuild_args("citadel-image", args)),
|
||||
"realmfs" => realmfs::main(rebuild_args("citadel-realmfs", args)),
|
||||
"image" => image::main(),
|
||||
"realmfs" => realmfs::main(),
|
||||
"update" => update::main(rebuild_args("citadel-update", args)),
|
||||
"mkimage" => mkimage::main(rebuild_args("citadel-mkimage", args)),
|
||||
"sync" => sync::main(rebuild_args("citadel-desktop-sync", args)),
|
||||
|
@ -1,28 +1,24 @@
|
||||
use clap::App;
|
||||
use clap::ArgMatches;
|
||||
use clap::{command, Command};
|
||||
use clap::{Arg, ArgMatches};
|
||||
|
||||
use libcitadel::{Result,RealmFS,Logger,LogLevel};
|
||||
use libcitadel::util::is_euid_root;
|
||||
use clap::SubCommand;
|
||||
use clap::AppSettings::*;
|
||||
use clap::Arg;
|
||||
use libcitadel::ResizeSize;
|
||||
use std::process::exit;
|
||||
|
||||
pub fn main(args: Vec<String>) {
|
||||
pub fn main() {
|
||||
|
||||
Logger::set_log_level(LogLevel::Debug);
|
||||
|
||||
let app = App::new("citadel-realmfs")
|
||||
.about("Citadel realmfs image tool")
|
||||
.settings(&[ArgRequiredElseHelp,ColoredHelp, DisableHelpSubcommand, DisableVersion, DeriveDisplayOrder,SubcommandsNegateReqs])
|
||||
|
||||
.subcommand(SubCommand::with_name("resize")
|
||||
let matches = command!()
|
||||
.about("citadel-realmfs")
|
||||
.arg_required_else_help(true)
|
||||
.subcommand(Command::new("resize")
|
||||
.about("Resize an existing RealmFS image. If the image is currently sealed, it will also be unsealed.")
|
||||
.arg(Arg::with_name("image")
|
||||
.arg(Arg::new("image")
|
||||
.help("Path or name of RealmFS image to resize")
|
||||
.required(true))
|
||||
.arg(Arg::with_name("size")
|
||||
.arg(Arg::new("size")
|
||||
.help("Size to increase RealmFS image to (or by if prefixed with '+')")
|
||||
.long_help("\
|
||||
The size can be followed by a 'g' or 'm' character \
|
||||
@ -35,53 +31,53 @@ is the final absolute size of the image.")
|
||||
.required(true)))
|
||||
|
||||
|
||||
.subcommand(SubCommand::with_name("fork")
|
||||
.subcommand(Command::new("fork")
|
||||
.about("Create a new RealmFS image as an unsealed copy of an existing image")
|
||||
.arg(Arg::with_name("image")
|
||||
.arg(Arg::new("image")
|
||||
.help("Path or name of RealmFS image to fork")
|
||||
.required(true))
|
||||
|
||||
.arg(Arg::with_name("forkname")
|
||||
.arg(Arg::new("forkname")
|
||||
.help("Name of new image to create")
|
||||
.required(true)))
|
||||
|
||||
.subcommand(SubCommand::with_name("autoresize")
|
||||
.subcommand(Command::new("autoresize")
|
||||
.about("Increase size of RealmFS image if not enough free space remains")
|
||||
.arg(Arg::with_name("image")
|
||||
.arg(Arg::new("image")
|
||||
.help("Path or name of RealmFS image")
|
||||
.required(true)))
|
||||
|
||||
.subcommand(SubCommand::with_name("update")
|
||||
.subcommand(Command::new("update")
|
||||
.about("Open an update shell on the image")
|
||||
.arg(Arg::with_name("image")
|
||||
.arg(Arg::new("image")
|
||||
.help("Path or name of RealmFS image")
|
||||
.required(true)))
|
||||
|
||||
.subcommand(SubCommand::with_name("activate")
|
||||
.subcommand(Command::new("activate")
|
||||
.about("Activate a RealmFS by creating a block device for the image and mounting it.")
|
||||
.arg(Arg::with_name("image")
|
||||
.arg(Arg::new("image")
|
||||
.help("Path or name of RealmFS image to activate")
|
||||
.required(true)))
|
||||
|
||||
.subcommand(SubCommand::with_name("deactivate")
|
||||
.subcommand(Command::new("deactivate")
|
||||
.about("Deactivate a RealmFS by unmounting it and removing block device created during activation.")
|
||||
.arg(Arg::with_name("image")
|
||||
.arg(Arg::new("image")
|
||||
.help("Path or name of RealmFS image to deactivate")
|
||||
.required(true)))
|
||||
|
||||
|
||||
.arg(Arg::with_name("image")
|
||||
.arg(Arg::new("image")
|
||||
.help("Name of or path to RealmFS image to display information about")
|
||||
.required(true));
|
||||
.required(true))
|
||||
.get_matches();
|
||||
|
||||
let matches = app.get_matches_from(args);
|
||||
let result = match matches.subcommand() {
|
||||
("resize", Some(m)) => resize(m),
|
||||
("autoresize", Some(m)) => autoresize(m),
|
||||
("fork", Some(m)) => fork(m),
|
||||
("update", Some(m)) => update(m),
|
||||
("activate", Some(m)) => activate(m),
|
||||
("deactivate", Some(m)) => deactivate(m),
|
||||
Some(("resize", m)) => resize(m),
|
||||
Some(("autoresize", m)) => autoresize(m),
|
||||
Some(("fork", m)) => fork(m),
|
||||
Some(("update", m)) => update(m),
|
||||
Some(("activate", m)) => activate(m),
|
||||
Some(("deactivate", m)) => deactivate(m),
|
||||
_ => image_info(&matches),
|
||||
};
|
||||
|
||||
@ -92,7 +88,7 @@ is the final absolute size of the image.")
|
||||
}
|
||||
|
||||
fn realmfs_image(arg_matches: &ArgMatches) -> Result<RealmFS> {
|
||||
let image = match arg_matches.value_of("image") {
|
||||
let image = match arg_matches.get_one::<String>("image") {
|
||||
Some(s) => s,
|
||||
None => bail!("Image argument required."),
|
||||
};
|
||||
@ -136,10 +132,9 @@ fn parse_resize_size(s: &str) -> Result<ResizeSize> {
|
||||
fn resize(arg_matches: &ArgMatches) -> Result<()> {
|
||||
let img = realmfs_image(arg_matches)?;
|
||||
info!("image is {}", img.path().display());
|
||||
let size_arg = match arg_matches.value_of("size") {
|
||||
let size_arg = match arg_matches.get_one::<String>("size") {
|
||||
Some(size) => size,
|
||||
None => "No size argument",
|
||||
|
||||
};
|
||||
info!("Size is {}", size_arg);
|
||||
let mode_add = size_arg.starts_with('+');
|
||||
@ -165,7 +160,7 @@ fn autoresize(arg_matches: &ArgMatches) -> Result<()> {
|
||||
|
||||
fn fork(arg_matches: &ArgMatches) -> Result<()> {
|
||||
let img = realmfs_image(arg_matches)?;
|
||||
let forkname = match arg_matches.value_of("forkname") {
|
||||
let forkname = match arg_matches.get_one::<String>("forkname") {
|
||||
Some(name) => name,
|
||||
None => bail!("No fork name argument"),
|
||||
};
|
||||
@ -190,7 +185,7 @@ fn update(arg_matches: &ArgMatches) -> Result<()> {
|
||||
|
||||
fn activate(arg_matches: &ArgMatches) -> Result<()> {
|
||||
let img = realmfs_image(arg_matches)?;
|
||||
let img_arg = arg_matches.value_of("image").unwrap();
|
||||
let img_arg = arg_matches.get_one::<String>("image").unwrap();
|
||||
|
||||
if img.is_activated() {
|
||||
info!("RealmFS image {} is already activated", img_arg);
|
||||
@ -203,7 +198,7 @@ fn activate(arg_matches: &ArgMatches) -> Result<()> {
|
||||
|
||||
fn deactivate(arg_matches: &ArgMatches) -> Result<()> {
|
||||
let img = realmfs_image(arg_matches)?;
|
||||
let img_arg = arg_matches.value_of("image").unwrap();
|
||||
let img_arg = arg_matches.get_one::<String>("image").unwrap();
|
||||
if !img.is_activated() {
|
||||
info!("RealmFS image {} is not activated", img_arg);
|
||||
} else if img.is_in_use() {
|
||||
|
Loading…
Reference in New Issue
Block a user