Skip to content

Commit

Permalink
Drop a ton of target_os based cfg's to allow more tests and clippies …
Browse files Browse the repository at this point in the history
…to be caught cross-platform (#1058)

* First large swath of un-cfg'ing target os

* Kill more cfg(target_os, this time the tests pass

* Drop more cfg target_os, tests pass

* Drop the remaining target_os cfg's that aren't strictly host tuning

* Create a host-specific planner struct to restrict what can be passed to clap

* Ostree

* Drop the HostSpecificBuiltinPlanner enum and add a platform_check to the planner impl

* Hide the planners based on the target os

* derp

* Move up the platform check on plan, to eliminate platform incompatibilities before getting fancy with the planner

* make the error type have context about the planner and host os
  • Loading branch information
grahamc authored Jul 23, 2024
1 parent 2f8c4ec commit 151026b
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 112 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use std::path::PathBuf;

#[cfg(target_os = "macos")]
use serde::{Deserialize, Serialize};
#[cfg(target_os = "macos")]
use tokio::io::AsyncWriteExt;
use tokio::process::Command;
use tracing::{span, Span};
Expand All @@ -12,12 +10,9 @@ use crate::execute_command;

use crate::action::{Action, ActionDescription};

#[cfg(target_os = "macos")]
const DARWIN_ENTERPRISE_EDITION_DAEMON_DEST: &str =
"/Library/LaunchDaemons/systems.determinate.nix-daemon.plist";
#[cfg(target_os = "macos")]
const DARWIN_LAUNCHD_DOMAIN: &str = "system";
#[cfg(target_os = "macos")]
const DARWIN_LAUNCHD_SERVICE: &str = "systems.determinate.nix-daemon";
/**
Configure the init to run the Nix daemon
Expand Down Expand Up @@ -156,7 +151,6 @@ impl Action for ConfigureEnterpriseEditionInitService {
#[derive(Debug, thiserror::Error)]
pub enum ConfigureEnterpriseEditionNixDaemonServiceError {}

#[cfg(target_os = "macos")]
#[derive(Deserialize, Clone, Debug, Serialize, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct DeterminateNixDaemonPlist {
Expand All @@ -169,14 +163,12 @@ pub struct DeterminateNixDaemonPlist {
soft_resource_limits: ResourceLimits,
}

#[cfg(target_os = "macos")]
#[derive(Deserialize, Clone, Debug, Serialize, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct ResourceLimits {
number_of_files: usize,
}

#[cfg(target_os = "macos")]
fn generate_plist() -> DeterminateNixDaemonPlist {
DeterminateNixDaemonPlist {
keep_alive: true,
Expand Down
39 changes: 0 additions & 39 deletions src/action/common/configure_init_service.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#[cfg(target_os = "linux")]
use std::path::Path;
use std::path::PathBuf;

#[cfg(target_os = "macos")]
use serde::{Deserialize, Serialize};
use tokio::process::Command;
use tracing::{span, Span};
Expand All @@ -13,26 +11,16 @@ use crate::execute_command;
use crate::action::{Action, ActionDescription};
use crate::settings::InitSystem;

#[cfg(target_os = "linux")]
const SERVICE_SRC: &str = "/nix/var/nix/profiles/default/lib/systemd/system/nix-daemon.service";
#[cfg(target_os = "linux")]
const SERVICE_DEST: &str = "/etc/systemd/system/nix-daemon.service";
#[cfg(target_os = "linux")]
const SOCKET_SRC: &str = "/nix/var/nix/profiles/default/lib/systemd/system/nix-daemon.socket";
#[cfg(target_os = "linux")]
const SOCKET_DEST: &str = "/etc/systemd/system/nix-daemon.socket";
#[cfg(target_os = "linux")]
const TMPFILES_SRC: &str = "/nix/var/nix/profiles/default/lib/tmpfiles.d/nix-daemon.conf";
#[cfg(target_os = "linux")]
const TMPFILES_DEST: &str = "/etc/tmpfiles.d/nix-daemon.conf";
#[cfg(target_os = "macos")]
const DARWIN_NIX_DAEMON_DEST: &str = "/Library/LaunchDaemons/org.nixos.nix-daemon.plist";
#[cfg(target_os = "macos")]
const DARWIN_NIX_DAEMON_SOURCE: &str =
"/nix/var/nix/profiles/default/Library/LaunchDaemons/org.nixos.nix-daemon.plist";
#[cfg(target_os = "macos")]
const DARWIN_LAUNCHD_DOMAIN: &str = "system";
#[cfg(target_os = "macos")]
const DARWIN_LAUNCHD_SERVICE: &str = "org.nixos.nix-daemon";
/**
Configure the init to run the Nix daemon
Expand All @@ -44,7 +32,6 @@ pub struct ConfigureInitService {
}

impl ConfigureInitService {
#[cfg(target_os = "linux")]
async fn check_if_systemd_unit_exists(src: &str, dest: &str) -> Result<(), ActionErrorKind> {
// TODO: once we have a way to communicate interaction between the library and the cli,
// interactively ask for permission to remove the file
Expand Down Expand Up @@ -80,11 +67,9 @@ impl ConfigureInitService {
start_daemon: bool,
) -> Result<StatefulAction<Self>, ActionError> {
match init {
#[cfg(target_os = "macos")]
InitSystem::Launchd => {
// No plan checks, yet
},
#[cfg(target_os = "linux")]
InitSystem::Systemd => {
// If `no_start_daemon` is set, then we don't require a running systemd,
// so we don't need to check if `/run/systemd/system` exists.
Expand All @@ -107,7 +92,6 @@ impl ConfigureInitService {
.await
.map_err(Self::error)?;
},
#[cfg(target_os = "linux")]
InitSystem::None => {
// Nothing here, no init system
},
Expand All @@ -125,13 +109,10 @@ impl Action for ConfigureInitService {
}
fn tracing_synopsis(&self) -> String {
match self.init {
#[cfg(target_os = "linux")]
InitSystem::Systemd => "Configure Nix daemon related settings with systemd".to_string(),
#[cfg(target_os = "macos")]
InitSystem::Launchd => {
"Configure Nix daemon related settings with launchctl".to_string()
},
#[cfg(not(target_os = "macos"))]
InitSystem::None => "Leave the Nix daemon unconfigured".to_string(),
}
}
Expand All @@ -143,7 +124,6 @@ impl Action for ConfigureInitService {
fn execute_description(&self) -> Vec<ActionDescription> {
let mut vec = Vec::new();
match self.init {
#[cfg(target_os = "linux")]
InitSystem::Systemd => {
let mut explanation = vec![
"Run `systemd-tmpfiles --create --prefix=/nix/var/nix`".to_string(),
Expand All @@ -156,7 +136,6 @@ impl Action for ConfigureInitService {
}
vec.push(ActionDescription::new(self.tracing_synopsis(), explanation))
},
#[cfg(target_os = "macos")]
InitSystem::Launchd => {
let mut explanation = vec![format!(
"Copy `{DARWIN_NIX_DAEMON_SOURCE}` to `{DARWIN_NIX_DAEMON_DEST}`"
Expand All @@ -168,7 +147,6 @@ impl Action for ConfigureInitService {
}
vec.push(ActionDescription::new(self.tracing_synopsis(), explanation))
},
#[cfg(not(target_os = "macos"))]
InitSystem::None => (),
}
vec
Expand All @@ -179,7 +157,6 @@ impl Action for ConfigureInitService {
let Self { init, start_daemon } = self;

match init {
#[cfg(target_os = "macos")]
InitSystem::Launchd => {
let daemon_file = DARWIN_NIX_DAEMON_DEST;
let domain = DARWIN_LAUNCHD_DOMAIN;
Expand Down Expand Up @@ -232,7 +209,6 @@ impl Action for ConfigureInitService {
.map_err(Self::error)?;
}
},
#[cfg(target_os = "linux")]
InitSystem::Systemd => {
if *start_daemon {
execute_command(
Expand Down Expand Up @@ -357,7 +333,6 @@ impl Action for ConfigureInitService {
enable(SOCKET_SRC, false).await.map_err(Self::error)?;
}
},
#[cfg(not(target_os = "macos"))]
InitSystem::None => {
// Nothing here, no init system
},
Expand All @@ -368,7 +343,6 @@ impl Action for ConfigureInitService {

fn revert_description(&self) -> Vec<ActionDescription> {
match self.init {
#[cfg(target_os = "linux")]
InitSystem::Systemd => {
vec![ActionDescription::new(
"Unconfigure Nix daemon related settings with systemd".to_string(),
Expand All @@ -380,25 +354,21 @@ impl Action for ConfigureInitService {
],
)]
},
#[cfg(target_os = "macos")]
InitSystem::Launchd => {
vec![ActionDescription::new(
"Unconfigure Nix daemon related settings with launchctl".to_string(),
vec![format!("Run `launchctl bootout {DARWIN_NIX_DAEMON_DEST}`")],
)]
},
#[cfg(not(target_os = "macos"))]
InitSystem::None => Vec::new(),
}
}

#[tracing::instrument(level = "debug", skip_all)]
async fn revert(&mut self) -> Result<(), ActionError> {
#[cfg_attr(target_os = "macos", allow(unused_mut))]
let mut errors = vec![];

match self.init {
#[cfg(target_os = "macos")]
InitSystem::Launchd => {
execute_command(
Command::new("launchctl")
Expand All @@ -409,7 +379,6 @@ impl Action for ConfigureInitService {
.await
.map_err(Self::error)?;
},
#[cfg(target_os = "linux")]
InitSystem::Systemd => {
// We separate stop and disable (instead of using `--now`) to avoid cases where the service isn't started, but is enabled.

Expand Down Expand Up @@ -505,7 +474,6 @@ impl Action for ConfigureInitService {
errors.push(err);
}
},
#[cfg(not(target_os = "macos"))]
InitSystem::None => {
// Nothing here, no init
},
Expand Down Expand Up @@ -533,7 +501,6 @@ pub enum ConfigureNixDaemonServiceError {
InitNotSupported,
}

#[cfg(target_os = "macos")]
#[derive(Deserialize, Clone, Debug, Serialize, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct DeterminateNixDaemonPlist {
Expand All @@ -546,14 +513,12 @@ pub struct DeterminateNixDaemonPlist {
soft_resource_limits: ResourceLimits,
}

#[cfg(target_os = "macos")]
#[derive(Deserialize, Clone, Debug, Serialize, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct ResourceLimits {
number_of_files: usize,
}

#[cfg(target_os = "linux")]
async fn stop(unit: &str) -> Result<(), ActionErrorKind> {
let mut command = Command::new("systemctl");
command.arg("stop");
Expand All @@ -571,7 +536,6 @@ async fn stop(unit: &str) -> Result<(), ActionErrorKind> {
}
}

#[cfg(target_os = "linux")]
async fn enable(unit: &str, now: bool) -> Result<(), ActionErrorKind> {
let mut command = Command::new("systemctl");
command.arg("enable");
Expand All @@ -592,7 +556,6 @@ async fn enable(unit: &str, now: bool) -> Result<(), ActionErrorKind> {
}
}

#[cfg(target_os = "linux")]
async fn disable(unit: &str, now: bool) -> Result<(), ActionErrorKind> {
let mut command = Command::new("systemctl");
command.arg("disable");
Expand All @@ -613,7 +576,6 @@ async fn disable(unit: &str, now: bool) -> Result<(), ActionErrorKind> {
}
}

#[cfg(target_os = "linux")]
async fn is_active(unit: &str) -> Result<bool, ActionErrorKind> {
let mut command = Command::new("systemctl");
command.arg("is-active");
Expand All @@ -631,7 +593,6 @@ async fn is_active(unit: &str) -> Result<bool, ActionErrorKind> {
}
}

#[cfg(target_os = "linux")]
async fn is_enabled(unit: &str) -> Result<bool, ActionErrorKind> {
let mut command = Command::new("systemctl");
command.arg("is-enabled");
Expand Down
2 changes: 0 additions & 2 deletions src/action/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! [`Action`](crate::action::Action)s which only call other base plugins

#[cfg(target_os = "macos")]
pub(crate) mod configure_enterprise_edition_init_service;
pub(crate) mod configure_init_service;
pub(crate) mod configure_nix;
Expand All @@ -11,7 +10,6 @@ pub(crate) mod delete_users;
pub(crate) mod place_nix_configuration;
pub(crate) mod provision_nix;

#[cfg(target_os = "macos")]
pub use configure_enterprise_edition_init_service::ConfigureEnterpriseEditionInitService;
pub use configure_init_service::{ConfigureInitService, ConfigureNixDaemonServiceError};
pub use configure_nix::ConfigureNix;
Expand Down
11 changes: 11 additions & 0 deletions src/action/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,17 @@ impl Planner for MyPlanner {
self.common.ssl_cert_file.clone(),
)?)
}
async fn platform_check(&self) -> Result<(), PlannerError> {
use target_lexicon::OperatingSystem;
match target_lexicon::OperatingSystem::host() {
OperatingSystem::MacOSX { .. } | OperatingSystem::Darwin => Ok(()),
host_os => Err(PlannerError::IncompatibleOperatingSystem {
planner: self.typetag_name(),
host_os,
}),
}
}
}
# async fn custom_planner_install() -> color_eyre::Result<()> {
Expand Down
8 changes: 6 additions & 2 deletions src/plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ impl InstallPlan {
where
P: Planner + 'static,
{
planner.platform_check().await?;

#[cfg(feature = "diagnostics")]
let diagnostic_data = Some(planner.diagnostic_data().await?);

Expand All @@ -67,11 +69,13 @@ impl InstallPlan {
}

pub async fn pre_uninstall_check(&self) -> Result<(), NixInstallerError> {
self.planner.platform_check().await?;
self.planner.pre_uninstall_check().await?;
Ok(())
}

pub async fn pre_install_check(&self) -> Result<(), NixInstallerError> {
self.planner.platform_check().await?;
self.planner.pre_install_check().await?;
Ok(())
}
Expand Down Expand Up @@ -156,7 +160,7 @@ impl InstallPlan {
cancel_channel: impl Into<Option<Receiver<()>>>,
) -> Result<(), NixInstallerError> {
self.check_compatible()?;
self.planner.pre_install_check().await?;
self.pre_install_check().await?;

let Self { actions, .. } = self;
let mut cancel_channel = cancel_channel.into();
Expand Down Expand Up @@ -327,7 +331,7 @@ impl InstallPlan {
cancel_channel: impl Into<Option<Receiver<()>>>,
) -> Result<(), NixInstallerError> {
self.check_compatible()?;
self.planner.pre_uninstall_check().await?;
self.pre_uninstall_check().await?;

let Self { actions, .. } = self;
let mut cancel_channel = cancel_channel.into();
Expand Down
12 changes: 12 additions & 0 deletions src/planner/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,18 @@ impl Planner for Linux {
self.settings.ssl_cert_file.clone(),
)?)
}

async fn platform_check(&self) -> Result<(), PlannerError> {
use target_lexicon::OperatingSystem;
match target_lexicon::OperatingSystem::host() {
OperatingSystem::Linux => Ok(()),
host_os => Err(PlannerError::IncompatibleOperatingSystem {
planner: self.typetag_name(),
host_os,
}),
}
}

async fn pre_uninstall_check(&self) -> Result<(), PlannerError> {
check_not_wsl1()?;

Expand Down
12 changes: 11 additions & 1 deletion src/planner/macos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ use crate::{
Action, BuiltinPlanner,
};

#[cfg(target_os = "macos")]
use crate::action::common::ConfigureEnterpriseEditionInitService;

/// A planner for MacOS (Darwin) systems
Expand Down Expand Up @@ -302,6 +301,17 @@ impl Planner for Macos {
)?)
}

async fn platform_check(&self) -> Result<(), PlannerError> {
use target_lexicon::OperatingSystem;
match target_lexicon::OperatingSystem::host() {
OperatingSystem::MacOSX { .. } | OperatingSystem::Darwin => Ok(()),
host_os => Err(PlannerError::IncompatibleOperatingSystem {
planner: self.typetag_name(),
host_os,
}),
}
}

async fn pre_uninstall_check(&self) -> Result<(), PlannerError> {
check_nix_darwin_not_installed().await?;

Expand Down
Loading

0 comments on commit 151026b

Please sign in to comment.