From f7bfdd7d7a99d5c23a065d8550cdc93530943aeb Mon Sep 17 00:00:00 2001 From: Jeremy Whiting Date: Fri, 20 Sep 2024 12:20:21 -0600 Subject: [PATCH] Add steamos-reset-tool usage. Instead of using steamos-factory-reset-config which resets both the OS and the user home partitions use steamos-reset-tool which has arguments for each or resetting both. --- com.steampowered.SteamOSManager1.xml | 2 + data/platforms/jupiter.toml | 13 ++- src/bin/steamosctl.rs | 13 +-- src/hardware.rs | 9 +++ src/manager/root.rs | 115 ++++++++++++++++++++++----- src/manager/user.rs | 8 +- src/platform.rs | 9 ++- src/proxy/factory_reset1.rs | 2 +- 8 files changed, 140 insertions(+), 31 deletions(-) diff --git a/com.steampowered.SteamOSManager1.xml b/com.steampowered.SteamOSManager1.xml index cf85e2e..8fbff78 100644 --- a/com.steampowered.SteamOSManager1.xml +++ b/com.steampowered.SteamOSManager1.xml @@ -65,11 +65,13 @@ Perform factory reset of device. Runs steamos-factory-reset script for now. + @kind: 1 = Clear just user settings, 2 = Clear just OS, 3 = clear both user settings and OS @returns: Status of reset operation. Valid statuses: 0 = Unknown, 1 = RebootRequired --> + diff --git a/data/platforms/jupiter.toml b/data/platforms/jupiter.toml index f125607..3a629b7 100644 --- a/data/platforms/jupiter.toml +++ b/data/platforms/jupiter.toml @@ -1,5 +1,14 @@ -[factory_reset] -script = "/usr/bin/steamos-factory-reset-config" +[factory_reset.all] +script = "/usr/bin/steamos-reset-tool" +script_args = ["factory-reset", "--reset-all"] + +[factory_reset.os] +script = "/usr/bin/steamos-reset-tool" +script_args = ["factory-reset", "--reset-os"] + +[factory_reset.user] +script = "/usr/bin/steamos-reset-tool" +script_args = ["factory-reset", "--reset-user-data"] [update_bios] script = "/usr/bin/jupiter-biosupdate" diff --git a/src/bin/steamosctl.rs b/src/bin/steamosctl.rs index 3796366..1e9d7ae 100644 --- a/src/bin/steamosctl.rs +++ b/src/bin/steamosctl.rs @@ -11,7 +11,7 @@ use itertools::Itertools; use std::collections::HashMap; use std::io::Cursor; use steamos_manager::cec::HdmiCecState; -use steamos_manager::hardware::FanControlState; +use steamos_manager::hardware::{FactoryResetKind, FanControlState}; use steamos_manager::power::{CPUScalingGovernor, GPUPerformanceLevel, GPUPowerProfile}; use steamos_manager::proxy::{ AmbientLightSensor1Proxy, CpuScaling1Proxy, FactoryReset1Proxy, FanControl1Proxy, @@ -160,8 +160,11 @@ enum Commands { /// Trim applicable drives TrimDevices, - /// Factory reset the device - FactoryReset, + /// Factory reset the os/user partitions + PrepareFactoryReset { + /// Valid kind(s) are `user`, `os`, `all` + kind: FactoryResetKind, + }, } async fn get_all_properties(conn: &Connection) -> Result<()> { @@ -413,9 +416,9 @@ async fn main() -> Result<()> { let proxy = UpdateDock1Proxy::new(&conn).await?; let _ = proxy.update_dock().await?; } - Commands::FactoryReset => { + Commands::PrepareFactoryReset { kind } => { let proxy = FactoryReset1Proxy::new(&conn).await?; - let _ = proxy.prepare_factory_reset().await?; + let _ = proxy.prepare_factory_reset(*kind as u32).await?; } Commands::TrimDevices => { let proxy = Storage1Proxy::new(&conn).await?; diff --git a/src/hardware.rs b/src/hardware.rs index 75ead2f..21f1ee2 100644 --- a/src/hardware.rs +++ b/src/hardware.rs @@ -68,6 +68,15 @@ impl fmt::Display for HardwareCurrentlySupported { } } +#[derive(Display, EnumString, PartialEq, Debug, Copy, Clone, TryFromPrimitive)] +#[strum(ascii_case_insensitive)] +#[repr(u32)] +pub enum FactoryResetKind { + User = 1, + OS = 2, + All = 3, +} + pub(crate) async fn variant() -> Result { let board_vendor = fs::read_to_string(path(BOARD_VENDOR_PATH)).await?; if board_vendor.trim_end() != "Valve" { diff --git a/src/manager/root.rs b/src/manager/root.rs index 6e1f0f5..7857258 100644 --- a/src/manager/root.rs +++ b/src/manager/root.rs @@ -6,7 +6,7 @@ * SPDX-License-Identifier: MIT */ -use anyhow::Result; +use anyhow::{anyhow, Result}; use std::collections::HashMap; use std::ffi::OsStr; use tokio::fs::File; @@ -19,7 +19,7 @@ use zbus::{fdo, interface, Connection, SignalContext}; use crate::daemon::root::{Command, RootCommand}; use crate::daemon::DaemonCommand; use crate::error::{to_zbus_error, to_zbus_fdo_error}; -use crate::hardware::{variant, FanControl, FanControlState, HardwareVariant}; +use crate::hardware::{variant, FactoryResetKind, FanControl, FanControlState, HardwareVariant}; use crate::job::JobManager; use crate::platform::platform_config; use crate::power::{ @@ -54,7 +54,9 @@ macro_rules! with_platform_config { #[derive(PartialEq, Debug, Copy, Clone)] #[repr(u32)] -enum PrepareFactoryReset { +enum PrepareFactoryResetResult { + // NOTE: both old PrepareFactoryReset and new PrepareFactoryResetExt use these + // result values. Unknown = 0, RebootRequired = 1, } @@ -85,14 +87,28 @@ impl SteamOSManager { #[interface(name = "com.steampowered.SteamOSManager1.RootManager")] impl SteamOSManager { - async fn prepare_factory_reset(&self) -> fdo::Result { - // Run steamos factory reset script and return true on success + async fn prepare_factory_reset(&self, kind: u32) -> fdo::Result { + // Run steamos-reset with arguments based on flags passed and return 1 on success with_platform_config! { - config = factory_reset ("PrepareFactoryReset") => { - let res = run_script(&config.script, &config.script_args).await; + config = factory_reset("PrepareFactoryReset") => { + let res = + match FactoryResetKind::try_from(kind) { + Ok(FactoryResetKind::User) => { + run_script(&config.user.script, &config.user.script_args).await + }, + Ok(FactoryResetKind::OS) => { + run_script(&config.os.script, &config.os.script_args).await + }, + Ok(FactoryResetKind::All) => { + run_script(&config.all.script, &config.all.script_args).await + }, + Err(_) => { + Err(anyhow!("Unable to generate command arguments for steamos-reset-tool script")) + } + }; Ok(match res { - Ok(()) => PrepareFactoryReset::RebootRequired as u32, - Err(_) => PrepareFactoryReset::Unknown as u32, + Ok(()) => PrepareFactoryResetResult::RebootRequired as u32, + Err(_) => PrepareFactoryResetResult::Unknown as u32, }) } } @@ -391,7 +407,7 @@ mod test { use crate::daemon::channel; use crate::daemon::root::RootContext; use crate::hardware::test::fake_model; - use crate::platform::{PlatformConfig, ScriptConfig}; + use crate::platform::{PlatformConfig, ResetConfig}; use crate::power::test::{format_clocks, read_clocks}; use crate::power::{self, get_gpu_performance_level}; use crate::process::test::{code, exit, ok}; @@ -439,7 +455,7 @@ mod test { default_path = "/com/steampowered/SteamOSManager1" )] trait PrepareFactoryReset { - fn prepare_factory_reset(&self) -> zbus::Result; + fn prepare_factory_reset(&self, kind: u32) -> zbus::Result; } #[tokio::test] @@ -447,7 +463,7 @@ mod test { let test = start().await.expect("start"); let mut config = PlatformConfig::default(); - config.factory_reset = Some(ScriptConfig::default()); + config.factory_reset = Some(ResetConfig::default()); test.h.test.platform_config.replace(Some(config)); let name = test.connection.unique_name().unwrap(); @@ -457,20 +473,83 @@ mod test { test.h.test.process_cb.set(ok); assert_eq!( - proxy.prepare_factory_reset().await.unwrap(), - PrepareFactoryReset::RebootRequired as u32 + proxy + .prepare_factory_reset(FactoryResetKind::All as u32) + .await + .unwrap(), + PrepareFactoryResetResult::RebootRequired as u32 ); test.h.test.process_cb.set(code); assert_eq!( - proxy.prepare_factory_reset().await.unwrap(), - PrepareFactoryReset::Unknown as u32 + proxy + .prepare_factory_reset(FactoryResetKind::All as u32) + .await + .unwrap(), + PrepareFactoryResetResult::Unknown as u32 ); test.h.test.process_cb.set(exit); assert_eq!( - proxy.prepare_factory_reset().await.unwrap(), - PrepareFactoryReset::Unknown as u32 + proxy + .prepare_factory_reset(FactoryResetKind::All as u32) + .await + .unwrap(), + PrepareFactoryResetResult::Unknown as u32 + ); + + test.h.test.process_cb.set(ok); + assert_eq!( + proxy + .prepare_factory_reset(FactoryResetKind::OS as u32) + .await + .unwrap(), + PrepareFactoryResetResult::RebootRequired as u32 + ); + + test.h.test.process_cb.set(code); + assert_eq!( + proxy + .prepare_factory_reset(FactoryResetKind::OS as u32) + .await + .unwrap(), + PrepareFactoryResetResult::Unknown as u32 + ); + + test.h.test.process_cb.set(exit); + assert_eq!( + proxy + .prepare_factory_reset(FactoryResetKind::OS as u32) + .await + .unwrap(), + PrepareFactoryResetResult::Unknown as u32 + ); + + test.h.test.process_cb.set(ok); + assert_eq!( + proxy + .prepare_factory_reset(FactoryResetKind::User as u32) + .await + .unwrap(), + PrepareFactoryResetResult::RebootRequired as u32 + ); + + test.h.test.process_cb.set(code); + assert_eq!( + proxy + .prepare_factory_reset(FactoryResetKind::User as u32) + .await + .unwrap(), + PrepareFactoryResetResult::Unknown as u32 + ); + + test.h.test.process_cb.set(exit); + assert_eq!( + proxy + .prepare_factory_reset(FactoryResetKind::User as u32) + .await + .unwrap(), + PrepareFactoryResetResult::Unknown as u32 ); test.connection.close().await.unwrap(); diff --git a/src/manager/user.rs b/src/manager/user.rs index ab04900..91c655a 100644 --- a/src/manager/user.rs +++ b/src/manager/user.rs @@ -251,8 +251,8 @@ impl CpuScaling1 { #[interface(name = "com.steampowered.SteamOSManager1.FactoryReset1")] impl FactoryReset1 { - async fn prepare_factory_reset(&self) -> fdo::Result { - method!(self, "PrepareFactoryReset") + async fn prepare_factory_reset(&self, flags: u32) -> fdo::Result { + method!(self, "PrepareFactoryReset", flags) } } @@ -661,7 +661,7 @@ mod test { use crate::hardware::test::fake_model; use crate::hardware::HardwareVariant; use crate::platform::{ - PlatformConfig, RangeConfig, ScriptConfig, ServiceConfig, StorageConfig, + PlatformConfig, RangeConfig, ResetConfig, ScriptConfig, ServiceConfig, StorageConfig, }; use crate::systemd::test::{MockManager, MockUnit}; use crate::{power, testing}; @@ -678,7 +678,7 @@ mod test { fn all_config() -> Option { Some(PlatformConfig { - factory_reset: Some(ScriptConfig::default()), + factory_reset: Some(ResetConfig::default()), update_bios: Some(ScriptConfig::default()), update_dock: Some(ScriptConfig::default()), storage: Some(StorageConfig::default()), diff --git a/src/platform.rs b/src/platform.rs index 87a63b2..5874ca3 100644 --- a/src/platform.rs +++ b/src/platform.rs @@ -21,7 +21,7 @@ static CONFIG: OnceCell> = OnceCell::const_new(); #[derive(Clone, Default, Deserialize, Debug)] #[serde(default)] pub(crate) struct PlatformConfig { - pub factory_reset: Option, + pub factory_reset: Option, pub update_bios: Option, pub update_dock: Option, pub storage: Option, @@ -45,6 +45,13 @@ pub(crate) struct ScriptConfig { pub script_args: Vec, } +#[derive(Clone, Default, Deserialize, Debug)] +pub(crate) struct ResetConfig { + pub all: ScriptConfig, + pub os: ScriptConfig, + pub user: ScriptConfig, +} + #[derive(Clone, Deserialize, Debug)] pub(crate) enum ServiceConfig { #[serde(rename = "systemd")] diff --git a/src/proxy/factory_reset1.rs b/src/proxy/factory_reset1.rs index 5c5885d..e58d487 100644 --- a/src/proxy/factory_reset1.rs +++ b/src/proxy/factory_reset1.rs @@ -20,5 +20,5 @@ use zbus::proxy; )] trait FactoryReset1 { /// PrepareFactoryReset method - fn prepare_factory_reset(&self) -> zbus::Result; + fn prepare_factory_reset(&self, kind: u32) -> zbus::Result; }