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]
|
[dependencies]
|
||||||
libcitadel = { path = "../libcitadel" }
|
libcitadel = { path = "../libcitadel" }
|
||||||
rpassword = "4.0"
|
rpassword = "7.3"
|
||||||
clap = "2.33"
|
clap = { version = "4.5", features = ["cargo", "derive"] }
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
toml = "0.5"
|
toml = "0.8"
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
dbus = "0.8.4"
|
dbus = "0.8.4"
|
||||||
pwhash = "0.3.1"
|
pwhash = "1.0"
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
|
@ -1,89 +1,97 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
use clap::{Arg,ArgMatches};
|
||||||
use clap::{App,Arg,SubCommand,ArgMatches};
|
use clap::{command, ArgAction, Command};
|
||||||
use clap::AppSettings::*;
|
|
||||||
use libcitadel::{Result, ResourceImage, Logger, LogLevel, Partition, KeyPair, ImageHeader, util};
|
|
||||||
use hex;
|
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")
|
.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() {
|
let result = match matches.subcommand() {
|
||||||
("metainfo", Some(m)) => metainfo(m),
|
Some(("metainfo", sub_m)) => metainfo(sub_m),
|
||||||
("info", Some(m)) => info(m),
|
Some(("info", sub_m)) => info(sub_m),
|
||||||
("generate-verity", Some(m)) => generate_verity(m),
|
Some(("generate-verity", sub_m)) => generate_verity(sub_m),
|
||||||
("verify", Some(m)) => verify(m),
|
Some(("verify", sub_m)) => verify(sub_m),
|
||||||
("sign-image", Some(m)) => sign_image(m),
|
Some(("sign-image", sub_m)) => sign_image(sub_m),
|
||||||
("genkeys", Some(_)) => genkeys(),
|
Some(("genkeys", _)) => genkeys(),
|
||||||
("decompress", Some(m)) => decompress(m),
|
Some(("decompress", sub_m)) => decompress(sub_m),
|
||||||
("verify-shasum", Some(m)) => verify_shasum(m),
|
Some(("verify-shasum", sub_m)) => verify_shasum(sub_m),
|
||||||
("install-rootfs", Some(m)) => install_rootfs(m),
|
Some(("install-rootfs", sub_m)) => install_rootfs(sub_m),
|
||||||
("install", Some(m)) => install_image(m),
|
Some(("install", sub_m)) => install_image(sub_m),
|
||||||
("bless", Some(_)) => bless(),
|
Some(("bless", _)) => bless(),
|
||||||
_ => Ok(()),
|
_ => Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -159,7 +167,9 @@ fn verify_shasum(arg_matches: &ArgMatches) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn load_image(arg_matches: &ArgMatches) -> Result<ResourceImage> {
|
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() {
|
if !Path::new(path).exists() {
|
||||||
bail!("Cannot load image {}: File does not exist", path);
|
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<()> {
|
fn install_rootfs(arg_matches: &ArgMatches) -> Result<()> {
|
||||||
if arg_matches.is_present("choose") {
|
if arg_matches.get_flag("choose") {
|
||||||
let _ = choose_install_partition(true)?;
|
let _ = choose_install_partition(true)?;
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
let img = load_image(arg_matches)?;
|
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");
|
info!("Verifying sha256 hash of image");
|
||||||
let shasum = img.generate_shasum()?;
|
let shasum = img.generate_shasum()?;
|
||||||
if shasum != img.metainfo().shasum() {
|
if shasum != img.metainfo().shasum() {
|
||||||
@ -188,7 +198,7 @@ fn install_rootfs(arg_matches: &ArgMatches) -> Result<()> {
|
|||||||
|
|
||||||
let partition = choose_install_partition(true)?;
|
let partition = choose_install_partition(true)?;
|
||||||
|
|
||||||
if !arg_matches.is_present("no-prefer") {
|
if !arg_matches.get_flag("no-prefer") {
|
||||||
clear_prefer_boot()?;
|
clear_prefer_boot()?;
|
||||||
img.header().set_flag(ImageHeader::FLAG_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<()> {
|
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 img = load_image(arg_matches)?;
|
||||||
let _hdr = img.header();
|
let _hdr = img.header();
|
||||||
let metainfo = img.metainfo();
|
let metainfo = img.metainfo();
|
||||||
|
@ -125,7 +125,7 @@ fn read_passphrase(prompt: &str) -> io::Result<Option<String>> {
|
|||||||
loop {
|
loop {
|
||||||
println!("{}", prompt);
|
println!("{}", prompt);
|
||||||
println!();
|
println!();
|
||||||
let passphrase = rpassword::read_password_from_tty(Some(" Passphrase : "))?;
|
let passphrase = rpassword::prompt_password(" Passphrase : ")?;
|
||||||
if passphrase.is_empty() {
|
if passphrase.is_empty() {
|
||||||
println!("Passphrase cannot be empty");
|
println!("Passphrase cannot be empty");
|
||||||
continue;
|
continue;
|
||||||
@ -133,7 +133,7 @@ fn read_passphrase(prompt: &str) -> io::Result<Option<String>> {
|
|||||||
if passphrase == "q" || passphrase == "Q" {
|
if passphrase == "q" || passphrase == "Q" {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
let confirm = rpassword::read_password_from_tty(Some(" Confirm : "))?;
|
let confirm = rpassword::prompt_password(" Confirm : ")?;
|
||||||
if confirm == "q" || confirm == "Q" {
|
if confirm == "q" || confirm == "Q" {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
@ -34,9 +34,9 @@ fn main() {
|
|||||||
} else if exe == Path::new("/usr/libexec/citadel-install-backend") {
|
} else if exe == Path::new("/usr/libexec/citadel-install-backend") {
|
||||||
install_backend::main();
|
install_backend::main();
|
||||||
} else if exe == Path::new("/usr/bin/citadel-image") {
|
} else if exe == Path::new("/usr/bin/citadel-image") {
|
||||||
image::main(args);
|
image::main();
|
||||||
} else if exe == Path::new("/usr/bin/citadel-realmfs") {
|
} else if exe == Path::new("/usr/bin/citadel-realmfs") {
|
||||||
realmfs::main(args);
|
realmfs::main();
|
||||||
} else if exe == Path::new("/usr/bin/citadel-update") {
|
} else if exe == Path::new("/usr/bin/citadel-update") {
|
||||||
update::main(args);
|
update::main(args);
|
||||||
} else if exe == Path::new("/usr/libexec/citadel-desktop-sync") {
|
} else if exe == Path::new("/usr/libexec/citadel-desktop-sync") {
|
||||||
@ -57,8 +57,8 @@ fn dispatch_command(args: Vec<String>) {
|
|||||||
match command.as_str() {
|
match command.as_str() {
|
||||||
"boot" => boot::main(rebuild_args("citadel-boot", args)),
|
"boot" => boot::main(rebuild_args("citadel-boot", args)),
|
||||||
"install" => install::main(rebuild_args("citadel-install", args)),
|
"install" => install::main(rebuild_args("citadel-install", args)),
|
||||||
"image" => image::main(rebuild_args("citadel-image", args)),
|
"image" => image::main(),
|
||||||
"realmfs" => realmfs::main(rebuild_args("citadel-realmfs", args)),
|
"realmfs" => realmfs::main(),
|
||||||
"update" => update::main(rebuild_args("citadel-update", args)),
|
"update" => update::main(rebuild_args("citadel-update", args)),
|
||||||
"mkimage" => mkimage::main(rebuild_args("citadel-mkimage", args)),
|
"mkimage" => mkimage::main(rebuild_args("citadel-mkimage", args)),
|
||||||
"sync" => sync::main(rebuild_args("citadel-desktop-sync", args)),
|
"sync" => sync::main(rebuild_args("citadel-desktop-sync", args)),
|
||||||
|
@ -1,28 +1,24 @@
|
|||||||
use clap::App;
|
use clap::{command, Command};
|
||||||
use clap::ArgMatches;
|
use clap::{Arg, ArgMatches};
|
||||||
|
|
||||||
use libcitadel::{Result,RealmFS,Logger,LogLevel};
|
use libcitadel::{Result,RealmFS,Logger,LogLevel};
|
||||||
use libcitadel::util::is_euid_root;
|
use libcitadel::util::is_euid_root;
|
||||||
use clap::SubCommand;
|
|
||||||
use clap::AppSettings::*;
|
|
||||||
use clap::Arg;
|
|
||||||
use libcitadel::ResizeSize;
|
use libcitadel::ResizeSize;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
|
||||||
pub fn main(args: Vec<String>) {
|
pub fn main() {
|
||||||
|
|
||||||
Logger::set_log_level(LogLevel::Debug);
|
Logger::set_log_level(LogLevel::Debug);
|
||||||
|
|
||||||
let app = App::new("citadel-realmfs")
|
let matches = command!()
|
||||||
.about("Citadel realmfs image tool")
|
.about("citadel-realmfs")
|
||||||
.settings(&[ArgRequiredElseHelp,ColoredHelp, DisableHelpSubcommand, DisableVersion, DeriveDisplayOrder,SubcommandsNegateReqs])
|
.arg_required_else_help(true)
|
||||||
|
.subcommand(Command::new("resize")
|
||||||
.subcommand(SubCommand::with_name("resize")
|
|
||||||
.about("Resize an existing RealmFS image. If the image is currently sealed, it will also be unsealed.")
|
.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")
|
.help("Path or name of RealmFS image to resize")
|
||||||
.required(true))
|
.required(true))
|
||||||
.arg(Arg::with_name("size")
|
.arg(Arg::new("size")
|
||||||
.help("Size to increase RealmFS image to (or by if prefixed with '+')")
|
.help("Size to increase RealmFS image to (or by if prefixed with '+')")
|
||||||
.long_help("\
|
.long_help("\
|
||||||
The size can be followed by a 'g' or 'm' character \
|
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)))
|
.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")
|
.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")
|
.help("Path or name of RealmFS image to fork")
|
||||||
.required(true))
|
.required(true))
|
||||||
|
|
||||||
.arg(Arg::with_name("forkname")
|
.arg(Arg::new("forkname")
|
||||||
.help("Name of new image to create")
|
.help("Name of new image to create")
|
||||||
.required(true)))
|
.required(true)))
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("autoresize")
|
.subcommand(Command::new("autoresize")
|
||||||
.about("Increase size of RealmFS image if not enough free space remains")
|
.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")
|
.help("Path or name of RealmFS image")
|
||||||
.required(true)))
|
.required(true)))
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("update")
|
.subcommand(Command::new("update")
|
||||||
.about("Open an update shell on the image")
|
.about("Open an update shell on the image")
|
||||||
.arg(Arg::with_name("image")
|
.arg(Arg::new("image")
|
||||||
.help("Path or name of RealmFS image")
|
.help("Path or name of RealmFS image")
|
||||||
.required(true)))
|
.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.")
|
.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")
|
.help("Path or name of RealmFS image to activate")
|
||||||
.required(true)))
|
.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.")
|
.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")
|
.help("Path or name of RealmFS image to deactivate")
|
||||||
.required(true)))
|
.required(true)))
|
||||||
|
|
||||||
|
|
||||||
.arg(Arg::with_name("image")
|
.arg(Arg::new("image")
|
||||||
.help("Name of or path to RealmFS image to display information about")
|
.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() {
|
let result = match matches.subcommand() {
|
||||||
("resize", Some(m)) => resize(m),
|
Some(("resize", m)) => resize(m),
|
||||||
("autoresize", Some(m)) => autoresize(m),
|
Some(("autoresize", m)) => autoresize(m),
|
||||||
("fork", Some(m)) => fork(m),
|
Some(("fork", m)) => fork(m),
|
||||||
("update", Some(m)) => update(m),
|
Some(("update", m)) => update(m),
|
||||||
("activate", Some(m)) => activate(m),
|
Some(("activate", m)) => activate(m),
|
||||||
("deactivate", Some(m)) => deactivate(m),
|
Some(("deactivate", m)) => deactivate(m),
|
||||||
_ => image_info(&matches),
|
_ => image_info(&matches),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -92,7 +88,7 @@ is the final absolute size of the image.")
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn realmfs_image(arg_matches: &ArgMatches) -> Result<RealmFS> {
|
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,
|
Some(s) => s,
|
||||||
None => bail!("Image argument required."),
|
None => bail!("Image argument required."),
|
||||||
};
|
};
|
||||||
@ -136,10 +132,9 @@ fn parse_resize_size(s: &str) -> Result<ResizeSize> {
|
|||||||
fn resize(arg_matches: &ArgMatches) -> Result<()> {
|
fn resize(arg_matches: &ArgMatches) -> Result<()> {
|
||||||
let img = realmfs_image(arg_matches)?;
|
let img = realmfs_image(arg_matches)?;
|
||||||
info!("image is {}", img.path().display());
|
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,
|
Some(size) => size,
|
||||||
None => "No size argument",
|
None => "No size argument",
|
||||||
|
|
||||||
};
|
};
|
||||||
info!("Size is {}", size_arg);
|
info!("Size is {}", size_arg);
|
||||||
let mode_add = size_arg.starts_with('+');
|
let mode_add = size_arg.starts_with('+');
|
||||||
@ -165,7 +160,7 @@ fn autoresize(arg_matches: &ArgMatches) -> Result<()> {
|
|||||||
|
|
||||||
fn fork(arg_matches: &ArgMatches) -> Result<()> {
|
fn fork(arg_matches: &ArgMatches) -> Result<()> {
|
||||||
let img = realmfs_image(arg_matches)?;
|
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,
|
Some(name) => name,
|
||||||
None => bail!("No fork name argument"),
|
None => bail!("No fork name argument"),
|
||||||
};
|
};
|
||||||
@ -190,7 +185,7 @@ fn update(arg_matches: &ArgMatches) -> Result<()> {
|
|||||||
|
|
||||||
fn activate(arg_matches: &ArgMatches) -> Result<()> {
|
fn activate(arg_matches: &ArgMatches) -> Result<()> {
|
||||||
let img = realmfs_image(arg_matches)?;
|
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() {
|
if img.is_activated() {
|
||||||
info!("RealmFS image {} is already activated", img_arg);
|
info!("RealmFS image {} is already activated", img_arg);
|
||||||
@ -203,7 +198,7 @@ fn activate(arg_matches: &ArgMatches) -> Result<()> {
|
|||||||
|
|
||||||
fn deactivate(arg_matches: &ArgMatches) -> Result<()> {
|
fn deactivate(arg_matches: &ArgMatches) -> Result<()> {
|
||||||
let img = realmfs_image(arg_matches)?;
|
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() {
|
if !img.is_activated() {
|
||||||
info!("RealmFS image {} is not activated", img_arg);
|
info!("RealmFS image {} is not activated", img_arg);
|
||||||
} else if img.is_in_use() {
|
} else if img.is_in_use() {
|
||||||
|
Loading…
Reference in New Issue
Block a user