Skip to content

Commit

Permalink
Merge pull request #2949 from jbaublitz/start-stop
Browse files Browse the repository at this point in the history
Add ability to start and stop pools
  • Loading branch information
mulkieran authored Jun 24, 2022
2 parents 83d0b8d + ca53152 commit 705888e
Show file tree
Hide file tree
Showing 46 changed files with 1,774 additions and 517 deletions.
8 changes: 4 additions & 4 deletions dracut/90stratis-clevis/stratis-clevis-rootfs-setup
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ if [ -z "$STRATIS_ROOTFS_UUID" ]; then
fi

i=0
while ! stratis-min pool is-locked "$STRATIS_ROOTFS_UUID" >/dev/null; do
while ! stratis-min pool is-stopped "$STRATIS_ROOTFS_UUID" >/dev/null; do
echo Waiting on pool with UUID $STRATIS_ROOTFS_UUID...
sleep 1
if [ "$i" = 5 ]; then
Expand All @@ -15,10 +15,10 @@ while ! stratis-min pool is-locked "$STRATIS_ROOTFS_UUID" >/dev/null; do
i=$(($i + 1))
done

if $(stratis-min pool is-locked "$STRATIS_ROOTFS_UUID"); then
if $(stratis-min pool is-stopped "$STRATIS_ROOTFS_UUID"); then
if $(stratis-min pool is-bound "$STRATIS_ROOTFS_UUID"); then
if ! stratis-min pool unlock clevis "$STRATIS_ROOTFS_UUID"; then
echo Failed to unlock pool with UUID $STRATIS_ROOTFS_UUID using Clevis >&2
if ! stratis-min pool start --unlock-method=clevis "$STRATIS_ROOTFS_UUID"; then
echo Failed to start pool with UUID $STRATIS_ROOTFS_UUID using Clevis >&2
exit 1
fi
fi
Expand Down
23 changes: 15 additions & 8 deletions dracut/90stratis/stratis-rootfs-setup
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ if [ -z "$STRATIS_ROOTFS_UUID" ]; then
fi

i=0
while ! stratis-min pool is-locked "$STRATIS_ROOTFS_UUID" >/dev/null; do
while ! stratis-min pool is-stopped "$STRATIS_ROOTFS_UUID" >/dev/null; do
echo Waiting on pool with UUID $STRATIS_ROOTFS_UUID...
sleep 1
if [ "$i" = 5 ]; then
Expand All @@ -15,12 +15,19 @@ while ! stratis-min pool is-locked "$STRATIS_ROOTFS_UUID" >/dev/null; do
i=$(($i + 1))
done

if $(stratis-min pool is-locked "$STRATIS_ROOTFS_UUID"); then
if ! plymouth ask-for-password \
--command="stratis-min pool unlock --prompt keyring $STRATIS_ROOTFS_UUID" \
--prompt="Enter password for Stratis pool with UUID $STRATIS_ROOTFS_UUID containing root filesystem" \
--number-of-tries=3; then
echo Failed to unlock pool with UUID $STRATIS_ROOTFS_UUID using a passphrase >&2
exit 1
if $(stratis-min pool is-stopped "$STRATIS_ROOTFS_UUID"); then
if $(stratis-min pool is-encrypted "$STRATIS_ROOTFS_UUID"); then
if ! plymouth ask-for-password \
--command="stratis-min pool start --prompt --unlock-method=keyring $STRATIS_ROOTFS_UUID" \
--prompt="Enter password for Stratis pool with UUID $STRATIS_ROOTFS_UUID containing root filesystem" \
--number-of-tries=3; then
echo Failed to start pool with UUID $STRATIS_ROOTFS_UUID using a passphrase >&2
exit 1
fi
else
if ! stratis-min pool start "$STRATIS_ROOTFS_UUID"; then
echo Failed to start pool with UUID $STRATIS_ROOTFS_UUID >&2
exit 1
fi
fi
fi
36 changes: 22 additions & 14 deletions src/bin/stratis-min/stratis-min.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,20 @@ fn parse_args() -> Command<'static> {
Command::new("unset").arg(Arg::new("key_desc").required(true)),
]),
Command::new("pool").subcommands(vec![
Command::new("unlock")
.arg(Arg::new("unlock_method").required(true))
.arg(Arg::new("pool_uuid").required(false))
Command::new("start")
.arg(Arg::new("pool_uuid").required(true))
.arg(
Arg::new("unlock_method")
.long("--unlock-method")
.takes_value(true),
)
.arg(
Arg::new("prompt")
.long("--prompt")
.takes_value(false)
.requires("pool_uuid"),
.requires("unlock_method"),
),
Command::new("stop").arg(Arg::new("pool_uuid").required(true)),
Command::new("create")
.arg(Arg::new("name").required(true))
.arg(
Expand Down Expand Up @@ -117,7 +122,7 @@ fn parse_args() -> Command<'static> {
),
Command::new("destroy").arg(Arg::new("name").required(true)),
Command::new("is-encrypted").arg(Arg::new("pool_uuid").required(true)),
Command::new("is-locked").arg(Arg::new("pool_uuid").required(true)),
Command::new("is-stopped").arg(Arg::new("pool_uuid").required(true)),
Command::new("is-bound").arg(Arg::new("pool_uuid").required(true)),
Command::new("has-passphrase").arg(Arg::new("pool_uuid").required(true)),
Command::new("clevis-pin").arg(Arg::new("pool_uuid").required(true)),
Expand Down Expand Up @@ -169,20 +174,23 @@ fn main() -> Result<(), String> {
Ok(())
}
} else if let Some(subcommand) = args.subcommand_matches("pool") {
if let Some(args) = subcommand.subcommand_matches("unlock") {
let unlock_method =
UnlockMethod::try_from(args.value_of("unlock_method").expect("required"))?;
let uuid = match args.value_of("pool_uuid") {
Some(u) => Some(PoolUuid::parse_str(u)?),
if let Some(args) = subcommand.subcommand_matches("start") {
let uuid = PoolUuid::parse_str(args.value_of("pool_uuid").expect("required"))?;
let unlock_method = match args.value_of("unlock_method") {
Some(um) => Some(UnlockMethod::try_from(um)?),
None => None,
};
let prompt = args.is_present("prompt");
if prompt && unlock_method == UnlockMethod::Clevis {
if prompt && unlock_method == Some(UnlockMethod::Clevis) {
return Err(Box::new(StratisError::Msg(
"--prompt and an unlock_method of clevis are mutally exclusive".to_string(),
)));
}
pool::pool_unlock(unlock_method, uuid, prompt)?;
pool::pool_start(uuid, unlock_method, prompt)?;
Ok(())
} else if let Some(args) = subcommand.subcommand_matches("stop") {
let uuid = PoolUuid::parse_str(args.value_of("pool_uuid").expect("required"))?;
pool::pool_stop(uuid)?;
Ok(())
} else if let Some(args) = subcommand.subcommand_matches("create") {
let paths = get_paths_from_args(args);
Expand Down Expand Up @@ -241,10 +249,10 @@ fn main() -> Result<(), String> {
let uuid = PoolUuid::parse_str(uuid_str)?;
println!("{}", pool::pool_is_encrypted(uuid)?,);
Ok(())
} else if let Some(args) = subcommand.subcommand_matches("is-locked") {
} else if let Some(args) = subcommand.subcommand_matches("is-stopped") {
let uuid_str = args.value_of("pool_uuid").expect("required");
let uuid = PoolUuid::parse_str(uuid_str)?;
println!("{}", pool::pool_is_locked(uuid)?,);
println!("{}", pool::pool_is_stopped(uuid)?,);
Ok(())
} else if let Some(args) = subcommand.subcommand_matches("is-bound") {
let uuid_str = args.value_of("pool_uuid").expect("required");
Expand Down
4 changes: 2 additions & 2 deletions src/dbus_api/api/manager_3_0/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
},
props::{get_locked_pools, get_version},
},
prop_conv::LockedPools,
prop_conv::StoppedOrLockedPools,
},
consts,
types::TData,
Expand Down Expand Up @@ -180,7 +180,7 @@ pub fn locked_pools_property<E>(
where
E: 'static + Engine,
{
f.property::<LockedPools, _>(consts::LOCKED_POOLS_PROP, ())
f.property::<StoppedOrLockedPools, _>(consts::LOCKED_POOLS_PROP, ())
.access(Access::Read)
.emits_changed(EmitsChangedSignal::True)
.on_get(get_locked_pools)
Expand Down
82 changes: 82 additions & 0 deletions src/dbus_api/api/manager_3_2/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use dbus_tree::{Access, EmitsChangedSignal, Factory, MTSync, Method, Property};

use crate::{
dbus_api::{
api::{
manager_3_2::{
methods::{refresh_state, start_pool, stop_pool},
props::get_stopped_pools,
},
prop_conv::StoppedOrLockedPools,
},
consts,
types::TData,
},
engine::Engine,
};

pub fn start_pool_method<E>(
f: &Factory<MTSync<TData<E>>, TData<E>>,
) -> Method<MTSync<TData<E>>, TData<E>>
where
E: 'static + Engine,
{
f.method("StartPool", (), start_pool)
.in_arg(("pool_uuid", "s"))
.in_arg(("unlock_method", "(bs)"))
// In order from left to right:
// b: true if the pool was newly started
// o: pool path
// oa: block device paths
// oa: filesystem paths
//
// Rust representation: bool
.out_arg(("result", "(b(oaoao))"))
.out_arg(("return_code", "q"))
.out_arg(("return_string", "s"))
}

pub fn stop_pool_method<E>(
f: &Factory<MTSync<TData<E>>, TData<E>>,
) -> Method<MTSync<TData<E>>, TData<E>>
where
E: 'static + Engine,
{
f.method("StopPool", (), stop_pool)
.in_arg(("pool", "o"))
// In order from left to right:
// b: true if the pool was newly stopped
// s: string representation of UUID of stopped pool
//
// Rust representation: (bool, String)
.out_arg(("result", "(bs)"))
.out_arg(("return_code", "q"))
.out_arg(("return_string", "s"))
}

pub fn refresh_state_method<E>(
f: &Factory<MTSync<TData<E>>, TData<E>>,
) -> Method<MTSync<TData<E>>, TData<E>>
where
E: 'static + Engine,
{
f.method("RefreshState", (), refresh_state)
.out_arg(("return_code", "q"))
.out_arg(("return_string", "s"))
}

pub fn stopped_pools_property<E>(
f: &Factory<MTSync<TData<E>>, TData<E>>,
) -> Property<MTSync<TData<E>>, TData<E>>
where
E: 'static + Engine,
{
f.property::<StoppedOrLockedPools, _>(consts::STOPPED_POOLS_PROP, ())
.access(Access::Read)
.emits_changed(EmitsChangedSignal::True)
.on_get(get_stopped_pools)
}
Loading

0 comments on commit 705888e

Please sign in to comment.