Fix uninstalling on latest steam deck with offload (#502)
This commit is contained in:
parent
1d51b25bf7
commit
99941446df
|
@ -54,9 +54,7 @@ impl Action for SetupDefaultProfile {
|
||||||
// Find an `nix` package
|
// Find an `nix` package
|
||||||
let nix_pkg_glob = format!("{}/nix-*/store/*-nix-*.*.*", self.unpacked_path.display());
|
let nix_pkg_glob = format!("{}/nix-*/store/*-nix-*.*.*", self.unpacked_path.display());
|
||||||
let mut found_nix_pkg = None;
|
let mut found_nix_pkg = None;
|
||||||
for entry in glob(&nix_pkg_glob)
|
for entry in glob(&nix_pkg_glob).map_err(|e| Self::error(e))? {
|
||||||
.map_err(|e| Self::error(SetupDefaultProfileError::GlobPatternError(e)))?
|
|
||||||
{
|
|
||||||
match entry {
|
match entry {
|
||||||
Ok(path) => {
|
Ok(path) => {
|
||||||
// If we are curing, the user may have multiple of these installed
|
// If we are curing, the user may have multiple of these installed
|
||||||
|
@ -85,9 +83,7 @@ impl Action for SetupDefaultProfile {
|
||||||
self.unpacked_path.display()
|
self.unpacked_path.display()
|
||||||
);
|
);
|
||||||
let mut found_nss_ca_cert_pkg = None;
|
let mut found_nss_ca_cert_pkg = None;
|
||||||
for entry in glob(&nss_ca_cert_pkg_glob)
|
for entry in glob(&nss_ca_cert_pkg_glob).map_err(|e| Self::error(e))? {
|
||||||
.map_err(|e| Self::error(SetupDefaultProfileError::GlobPatternError(e)))?
|
|
||||||
{
|
|
||||||
match entry {
|
match entry {
|
||||||
Ok(path) => {
|
Ok(path) => {
|
||||||
// If we are curing, the user may have multiple of these installed
|
// If we are curing, the user may have multiple of these installed
|
||||||
|
@ -113,9 +109,9 @@ impl Action for SetupDefaultProfile {
|
||||||
};
|
};
|
||||||
|
|
||||||
let found_nix_paths = glob::glob(&format!("{}/nix-*", self.unpacked_path.display()))
|
let found_nix_paths = glob::glob(&format!("{}/nix-*", self.unpacked_path.display()))
|
||||||
.map_err(|e| Self::error(SetupDefaultProfileError::from(e)))?
|
.map_err(|e| Self::error(e))?
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()
|
||||||
.map_err(|e| Self::error(SetupDefaultProfileError::from(e)))?;
|
.map_err(|e| Self::error(e))?;
|
||||||
if found_nix_paths.len() != 1 {
|
if found_nix_paths.len() != 1 {
|
||||||
return Err(Self::error(ActionErrorKind::MalformedBinaryTarball));
|
return Err(Self::error(ActionErrorKind::MalformedBinaryTarball));
|
||||||
}
|
}
|
||||||
|
@ -240,18 +236,6 @@ impl Action for SetupDefaultProfile {
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum SetupDefaultProfileError {
|
pub enum SetupDefaultProfileError {
|
||||||
#[error("Glob pattern error")]
|
|
||||||
GlobPatternError(
|
|
||||||
#[from]
|
|
||||||
#[source]
|
|
||||||
glob::PatternError,
|
|
||||||
),
|
|
||||||
#[error("Glob globbing error")]
|
|
||||||
GlobGlobError(
|
|
||||||
#[from]
|
|
||||||
#[source]
|
|
||||||
glob::GlobError,
|
|
||||||
),
|
|
||||||
#[error("Unarchived Nix store did not appear to include a `nss-cacert` location")]
|
#[error("Unarchived Nix store did not appear to include a `nss-cacert` location")]
|
||||||
NoNssCacert,
|
NoNssCacert,
|
||||||
#[error("Unarchived Nix store did not appear to include a `nix` location")]
|
#[error("Unarchived Nix store did not appear to include a `nix` location")]
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
pub(crate) mod ensure_steamos_nix_directory;
|
pub(crate) mod ensure_steamos_nix_directory;
|
||||||
pub(crate) mod provision_selinux;
|
pub(crate) mod provision_selinux;
|
||||||
|
pub(crate) mod revert_clean_steamos_nix_offload;
|
||||||
pub(crate) mod start_systemd_unit;
|
pub(crate) mod start_systemd_unit;
|
||||||
pub(crate) mod systemctl_daemon_reload;
|
pub(crate) mod systemctl_daemon_reload;
|
||||||
|
|
||||||
pub use ensure_steamos_nix_directory::EnsureSteamosNixDirectory;
|
pub use ensure_steamos_nix_directory::EnsureSteamosNixDirectory;
|
||||||
pub use provision_selinux::ProvisionSelinux;
|
pub use provision_selinux::ProvisionSelinux;
|
||||||
|
pub use revert_clean_steamos_nix_offload::RevertCleanSteamosNixOffload;
|
||||||
pub use start_systemd_unit::{StartSystemdUnit, StartSystemdUnitError};
|
pub use start_systemd_unit::{StartSystemdUnit, StartSystemdUnitError};
|
||||||
pub use systemctl_daemon_reload::SystemctlDaemonReload;
|
pub use systemctl_daemon_reload::SystemctlDaemonReload;
|
||||||
|
|
79
src/action/linux/revert_clean_steamos_nix_offload.rs
Normal file
79
src/action/linux/revert_clean_steamos_nix_offload.rs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
|
use crate::action::{ActionError, ActionErrorKind, ActionTag};
|
||||||
|
|
||||||
|
use crate::action::{Action, ActionDescription, StatefulAction};
|
||||||
|
|
||||||
|
const OFFLOAD_PATH: &'static str = "/home/.steamos/offload/nix";
|
||||||
|
|
||||||
|
/**
|
||||||
|
Clean out the `/home/.steamos/offload/nix`
|
||||||
|
|
||||||
|
In SteamOS build ID 20230522.1000 (and, presumably, later) a `/home/.steamos/offload/nix` directory
|
||||||
|
exists by default and needs to be cleaned out on uninstall, otherwise uninstall won't work.
|
||||||
|
*/
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
|
pub struct RevertCleanSteamosNixOffload;
|
||||||
|
|
||||||
|
impl RevertCleanSteamosNixOffload {
|
||||||
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
|
pub async fn plan() -> Result<StatefulAction<Self>, ActionError> {
|
||||||
|
if Path::new(OFFLOAD_PATH).exists() {
|
||||||
|
Ok(StatefulAction::uncompleted(RevertCleanSteamosNixOffload))
|
||||||
|
} else {
|
||||||
|
Ok(StatefulAction::completed(RevertCleanSteamosNixOffload))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
#[typetag::serde(name = "revert_clean_steamos_nix_offload")]
|
||||||
|
impl Action for RevertCleanSteamosNixOffload {
|
||||||
|
fn action_tag() -> ActionTag {
|
||||||
|
ActionTag("revert_clean_steamos_nix_offload")
|
||||||
|
}
|
||||||
|
fn tracing_synopsis(&self) -> String {
|
||||||
|
format!("Clean the `{OFFLOAD_PATH}` directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(tracing::Level::DEBUG, "revert_clean_steamos_nix_offload",)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
|
// noop
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn revert_description(&self) -> Vec<ActionDescription> {
|
||||||
|
vec![ActionDescription::new(
|
||||||
|
self.tracing_synopsis(),
|
||||||
|
vec![
|
||||||
|
format!("On more recent versions of SteamOS, the `{OFFLOAD_PATH}` folder contains the Nix store, and needs to be cleaned on uninstall."),
|
||||||
|
],
|
||||||
|
)]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
|
let paths = glob::glob(OFFLOAD_PATH).map_err(Self::error)?;
|
||||||
|
|
||||||
|
for path in paths {
|
||||||
|
let path = path.map_err(Self::error)?;
|
||||||
|
tracing::trace!(path = %path.display(), "Removing");
|
||||||
|
tokio::fs::remove_dir_all(&path)
|
||||||
|
.await
|
||||||
|
.map_err(|e| Self::error(ActionErrorKind::Remove(path.into(), e)))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -473,6 +473,18 @@ pub enum ActionErrorKind {
|
||||||
NoGroup(String),
|
NoGroup(String),
|
||||||
#[error("Chowning path `{0}`")]
|
#[error("Chowning path `{0}`")]
|
||||||
Chown(std::path::PathBuf, #[source] nix::errno::Errno),
|
Chown(std::path::PathBuf, #[source] nix::errno::Errno),
|
||||||
|
#[error("Glob globbing error")]
|
||||||
|
GlobGlobError(
|
||||||
|
#[from]
|
||||||
|
#[source]
|
||||||
|
glob::GlobError,
|
||||||
|
),
|
||||||
|
#[error("Glob pattern error")]
|
||||||
|
GlobPatternError(
|
||||||
|
#[from]
|
||||||
|
#[source]
|
||||||
|
glob::PatternError,
|
||||||
|
),
|
||||||
/// Failed to execute command
|
/// Failed to execute command
|
||||||
#[error("Failed to execute command `{command}`",
|
#[error("Failed to execute command `{command}`",
|
||||||
command = .command,
|
command = .command,
|
||||||
|
|
|
@ -104,7 +104,10 @@ use crate::{
|
||||||
action::{
|
action::{
|
||||||
base::{CreateDirectory, CreateFile, RemoveDirectory},
|
base::{CreateDirectory, CreateFile, RemoveDirectory},
|
||||||
common::{ConfigureInitService, ConfigureNix, ProvisionNix},
|
common::{ConfigureInitService, ConfigureNix, ProvisionNix},
|
||||||
linux::{EnsureSteamosNixDirectory, StartSystemdUnit, SystemctlDaemonReload},
|
linux::{
|
||||||
|
EnsureSteamosNixDirectory, RevertCleanSteamosNixOffload, StartSystemdUnit,
|
||||||
|
SystemctlDaemonReload,
|
||||||
|
},
|
||||||
Action, StatefulAction,
|
Action, StatefulAction,
|
||||||
},
|
},
|
||||||
planner::{Planner, PlannerError},
|
planner::{Planner, PlannerError},
|
||||||
|
@ -248,10 +251,16 @@ impl Planner for SteamDeck {
|
||||||
.map_err(PlannerError::Action)?;
|
.map_err(PlannerError::Action)?;
|
||||||
actions.push(create_bind_mount_unit.boxed());
|
actions.push(create_bind_mount_unit.boxed());
|
||||||
} else {
|
} else {
|
||||||
|
let revert_clean_streamos_nix_offload = RevertCleanSteamosNixOffload::plan()
|
||||||
|
.await
|
||||||
|
.map_err(PlannerError::Action)?;
|
||||||
|
actions.push(revert_clean_streamos_nix_offload.boxed());
|
||||||
|
|
||||||
let ensure_steamos_nix_directory = EnsureSteamosNixDirectory::plan()
|
let ensure_steamos_nix_directory = EnsureSteamosNixDirectory::plan()
|
||||||
.await
|
.await
|
||||||
.map_err(PlannerError::Action)?;
|
.map_err(PlannerError::Action)?;
|
||||||
actions.push(ensure_steamos_nix_directory.boxed());
|
actions.push(ensure_steamos_nix_directory.boxed());
|
||||||
|
|
||||||
let start_nix_mount = StartSystemdUnit::plan("nix.mount".to_string(), true)
|
let start_nix_mount = StartSystemdUnit::plan("nix.mount".to_string(), true)
|
||||||
.await
|
.await
|
||||||
.map_err(PlannerError::Action)?;
|
.map_err(PlannerError::Action)?;
|
||||||
|
|
Loading…
Reference in a new issue