Attempt to minimize steam deck display manager restart risk (#237)

* Attempt to minimize steam deck display manager restart risk

* Fiddle a bit more

* Prod CI

* Be much more specific with services we restart
This commit is contained in:
Ana Hobden 2023-02-08 11:58:48 -08:00 committed by GitHub
parent 4884588339
commit 28db9f2953
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 29 deletions

2
Cargo.lock generated
View file

@ -915,7 +915,7 @@ dependencies = [
[[package]] [[package]]
name = "nix-installer" name = "nix-installer"
version = "0.2.0" version = "0.2.1-unreleased"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"atty", "atty",

View file

@ -12,14 +12,19 @@ Start a given systemd unit
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)] #[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
pub struct StartSystemdUnit { pub struct StartSystemdUnit {
unit: String, unit: String,
enable: bool,
} }
impl StartSystemdUnit { impl StartSystemdUnit {
#[tracing::instrument(level = "debug", skip_all)] #[tracing::instrument(level = "debug", skip_all)]
pub async fn plan(unit: impl AsRef<str>) -> Result<StatefulAction<Self>, ActionError> { pub async fn plan(
unit: impl AsRef<str>,
enable: bool,
) -> Result<StatefulAction<Self>, ActionError> {
Ok(StatefulAction { Ok(StatefulAction {
action: Self { action: Self {
unit: unit.as_ref().to_string(), unit: unit.as_ref().to_string(),
enable,
}, },
state: ActionState::Uncompleted, state: ActionState::Uncompleted,
}) })
@ -47,19 +52,35 @@ impl Action for StartSystemdUnit {
#[tracing::instrument(level = "debug", skip_all)] #[tracing::instrument(level = "debug", skip_all)]
async fn execute(&mut self) -> Result<(), ActionError> { async fn execute(&mut self) -> Result<(), ActionError> {
let Self { unit, .. } = self; let Self { unit, enable } = self;
// TODO(@Hoverbear): Handle proxy vars match enable {
execute_command( true => {
Command::new("systemctl") // TODO(@Hoverbear): Handle proxy vars
.process_group(0) execute_command(
.arg("enable") Command::new("systemctl")
.arg("--now") .process_group(0)
.arg(format!("{unit}")) .arg("enable")
.stdin(std::process::Stdio::null()), .arg("--now")
) .arg(format!("{unit}"))
.await .stdin(std::process::Stdio::null()),
.map_err(|e| ActionError::Custom(Box::new(StartSystemdUnitError::Command(e))))?; )
.await
.map_err(|e| ActionError::Custom(Box::new(StartSystemdUnitError::Command(e))))?;
},
false => {
// TODO(@Hoverbear): Handle proxy vars
execute_command(
Command::new("systemctl")
.process_group(0)
.arg("start")
.arg(format!("{unit}"))
.stdin(std::process::Stdio::null()),
)
.await
.map_err(|e| ActionError::Custom(Box::new(StartSystemdUnitError::Command(e))))?;
},
}
Ok(()) Ok(())
} }
@ -73,17 +94,19 @@ impl Action for StartSystemdUnit {
#[tracing::instrument(level = "debug", skip_all)] #[tracing::instrument(level = "debug", skip_all)]
async fn revert(&mut self) -> Result<(), ActionError> { async fn revert(&mut self) -> Result<(), ActionError> {
let Self { unit, .. } = self; let Self { unit, enable } = self;
execute_command( if *enable {
Command::new("systemctl") execute_command(
.process_group(0) Command::new("systemctl")
.arg("disable") .process_group(0)
.arg(format!("{unit}")) .arg("disable")
.stdin(std::process::Stdio::null()), .arg(format!("{unit}"))
) .stdin(std::process::Stdio::null()),
.await )
.map_err(|e| ActionError::Custom(Box::new(StartSystemdUnitError::Command(e))))?; .await
.map_err(|e| ActionError::Custom(Box::new(StartSystemdUnitError::Command(e))))?;
};
// We do both to avoid an error doing `disable --now` if the user did stop it already somehow. // We do both to avoid an error doing `disable --now` if the user did stop it already somehow.
execute_command( execute_command(

View file

@ -152,6 +152,8 @@ impl Planner for SteamDeck {
Requires=nix-directory.service\n\ Requires=nix-directory.service\n\
ConditionPathIsDirectory=/nix\n\ ConditionPathIsDirectory=/nix\n\
DefaultDependencies=no\n\ DefaultDependencies=no\n\
RequiredBy=nix-daemon.service\n\
RequiredBy=nix-daemon.socket\n\
\n\ \n\
[Mount]\n\ [Mount]\n\
What={persistence}\n\ What={persistence}\n\
@ -180,15 +182,13 @@ impl Planner for SteamDeck {
After=nix.mount\n\ After=nix.mount\n\
Requires=nix-directory.service\n\ Requires=nix-directory.service\n\
Requires=nix.mount\n\ Requires=nix.mount\n\
PropagatesStopTo=nix-directory.service\n\
PropagatesStopTo=nix.mount\n\
DefaultDependencies=no\n\ DefaultDependencies=no\n\
\n\ \n\
[Service]\n\ [Service]\n\
Type=oneshot\n\ Type=oneshot\n\
RemainAfterExit=yes\n\ RemainAfterExit=yes\n\
ExecStart=/usr/bin/systemctl daemon-reload\n\ ExecStart=/usr/bin/systemctl daemon-reload\n\
ExecStart=/usr/bin/systemctl restart --no-block sockets.target timers.target multi-user.target\n\ ExecStart=/usr/bin/systemctl restart --no-block nix-daemon.socket\n\
\n\ \n\
[Install]\n\ [Install]\n\
WantedBy=sysinit.target\n\ WantedBy=sysinit.target\n\
@ -213,7 +213,7 @@ impl Planner for SteamDeck {
nix_directory_unit.boxed(), nix_directory_unit.boxed(),
create_bind_mount_unit.boxed(), create_bind_mount_unit.boxed(),
ensure_symlinked_units_resolve_unit.boxed(), ensure_symlinked_units_resolve_unit.boxed(),
StartSystemdUnit::plan("ensure-symlinked-units-resolve.service".to_string()) StartSystemdUnit::plan("nix.mount".to_string(), false)
.await .await
.map_err(PlannerError::Action)? .map_err(PlannerError::Action)?
.boxed(), .boxed(),
@ -230,6 +230,10 @@ impl Planner for SteamDeck {
.await .await
.map_err(PlannerError::Action)? .map_err(PlannerError::Action)?
.boxed(), .boxed(),
StartSystemdUnit::plan("ensure-symlinked-units-resolve.service".to_string(), true)
.await
.map_err(PlannerError::Action)?
.boxed(),
]) ])
} }

View file

@ -51,7 +51,8 @@
{ {
"action": { "action": {
"action": "start_systemd_unit", "action": "start_systemd_unit",
"unit": "ensure-symlinked-units-resolve.service" "unit": "ensure-symlinked-units-resolve.service",
"enable": true
}, },
"state": "Uncompleted" "state": "Uncompleted"
}, },