From 5339e4c41a79c07baadca8b51215500ed9b93d06 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Mon, 21 Oct 2024 07:53:00 -0500 Subject: [PATCH] make all of the unix-specific things gated behind cfg --- src/api/generic_server.rs | 7 +++++-- src/block/manager.rs | 15 ++++++++++----- src/garage/secrets.rs | 4 ++++ src/rpc/system.rs | 32 +++++++++++++++++++++++++------- src/util/socket_address.rs | 15 +++++++++------ src/web/web_server.rs | 7 ++++--- 6 files changed, 57 insertions(+), 23 deletions(-) diff --git a/src/api/generic_server.rs b/src/api/generic_server.rs index 283abdd4..d21e7b14 100644 --- a/src/api/generic_server.rs +++ b/src/api/generic_server.rs @@ -1,6 +1,5 @@ use std::convert::Infallible; use std::fs::{self, Permissions}; -use std::os::unix::fs::PermissionsExt; use std::sync::Arc; use std::time::Duration; @@ -18,7 +17,8 @@ use hyper::{HeaderMap, StatusCode}; use hyper_util::rt::TokioIo; use tokio::io::{AsyncRead, AsyncWrite}; -use tokio::net::{TcpListener, TcpStream, UnixListener, UnixStream}; +use tokio::net::{TcpListener, TcpStream}; +// , UnixListener, UnixStream}; use tokio::sync::watch; use tokio::time::{sleep_until, Instant}; @@ -119,6 +119,7 @@ impl ApiServer { let handler = move |request, socketaddr| self.clone().handler(request, socketaddr); server_loop(server_name, listener, handler, must_exit).await } + #[cfg(unix)] UnixOrTCPSocketAddress::UnixSocket(ref path) => { if path.exists() { fs::remove_file(path)? @@ -264,8 +265,10 @@ impl Accept for TcpListener { } } +#[cfg(unix)] pub struct UnixListenerOn(pub UnixListener, pub String); +#[cfg(unix)] #[async_trait] impl Accept for UnixListenerOn { type Stream = UnixStream; diff --git a/src/block/manager.rs b/src/block/manager.rs index 40b177a2..04b1547a 100644 --- a/src/block/manager.rs +++ b/src/block/manager.rs @@ -792,11 +792,16 @@ impl BlockManagerLocked { // Now, we do an fsync on the containing directory, to ensure that the rename // is persisted properly. See: // http://thedjbway.b0llix.net/qmail/syncdir.html - let dir = fs::OpenOptions::new() - .read(true) - .mode(0) - .open(directory) - .await?; + let mut dir = fs::OpenOptions::new(); + dir.read(true); + + // TODO: Windows open options? + #[cfg(unix)] + { + dir.mode(0); + } + + let dir = dir.open(directory).await?; dir.sync_all().await?; drop(dir); } diff --git a/src/garage/secrets.rs b/src/garage/secrets.rs index 8d2ff475..698799be 100644 --- a/src/garage/secrets.rs +++ b/src/garage/secrets.rs @@ -52,10 +52,14 @@ pub struct Secrets { /// from config or CLI param or env variable or read from a file specified in config or CLI /// param or env variable) pub fn fill_secrets(mut config: Config, secrets: Secrets) -> Result { + #[cfg(unix)] let allow_world_readable = secrets .allow_world_readable_secrets .unwrap_or(config.allow_world_readable_secrets); + #[cfg(not(unix))] + let allow_world_readable = config.allow_world_readable_secrets; + fill_secret( &mut config.rpc_secret, &config.rpc_secret_file, diff --git a/src/rpc/system.rs b/src/rpc/system.rs index d94d4eec..d49bec8f 100644 --- a/src/rpc/system.rs +++ b/src/rpc/system.rs @@ -218,6 +218,7 @@ pub fn gen_node_key(metadata_dir: &Path) -> Result { info!("Generating new node key pair."); let (pubkey, key) = ed25519::gen_keypair(); + #[cfg(unix)] { use std::os::unix::fs::PermissionsExt; let mut f = std::fs::File::create(key_file.as_path())?; @@ -227,6 +228,17 @@ pub fn gen_node_key(metadata_dir: &Path) -> Result { f.write_all(&key[..])?; } + #[cfg(windows)] + { + // use std::os::windows::io::AsHandle; + let mut f = std::fs::File::create(key_file.as_path())?; + // TODO: Set ACL here? + let mut perm = f.metadata()?.permissions(); + perm.set_readonly(true); + std::fs::set_permissions(key_file.as_path(), perm)?; + f.write_all(&key[..])?; + } + { let mut pubkey_file = metadata_dir.to_path_buf(); pubkey_file.push("node_key.pub"); @@ -806,16 +818,22 @@ impl NodeStatus { } fn update_disk_usage(&mut self, meta_dir: &Path, data_dir: &DataDirEnum) { - use nix::sys::statvfs::statvfs; - let mount_avail = |path: &Path| match statvfs(path) { - Ok(x) => { - let avail = x.blocks_available() as u64 * x.fragment_size() as u64; - let total = x.blocks() as u64 * x.fragment_size() as u64; - Some((x.filesystem_id(), avail, total)) + #[cfg(unix)] + let mount_avail = { + use nix::sys::statvfs::statvfs; + |path: &Path| match statvfs(path) { + Ok(x) => { + let avail = x.blocks_available() as u64 * x.fragment_size() as u64; + let total = x.blocks() as u64 * x.fragment_size() as u64; + Some((x.filesystem_id(), avail, total)) + } + Err(_) => None, } - Err(_) => None, }; + #[cfg(windows)] + let mount_avail = |_path: &Path| None::<(u64, _, _)>; + self.meta_disk_avail = mount_avail(meta_dir).map(|(_, a, t)| (a, t)); self.data_disk_avail = match data_dir { DataDirEnum::Single(dir) => mount_avail(dir).map(|(_, a, t)| (a, t)), diff --git a/src/util/socket_address.rs b/src/util/socket_address.rs index f01225f6..84411d95 100644 --- a/src/util/socket_address.rs +++ b/src/util/socket_address.rs @@ -9,6 +9,7 @@ use serde::{Deserialize, Deserializer}; #[derive(Debug, Clone)] pub enum UnixOrTCPSocketAddress { TCPSocket(SocketAddr), + #[cfg(unix)] UnixSocket(PathBuf), } @@ -16,6 +17,7 @@ impl Display for UnixOrTCPSocketAddress { fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result { match self { UnixOrTCPSocketAddress::TCPSocket(address) => write!(formatter, "http://{}", address), + #[cfg(unix)] UnixOrTCPSocketAddress::UnixSocket(path) => { write!(formatter, "http+unix://{}", path.to_string_lossy()) } @@ -31,14 +33,15 @@ impl<'de> Deserialize<'de> for UnixOrTCPSocketAddress { let string = String::deserialize(deserializer)?; let string = string.as_str(); + #[cfg(unix)] if string.starts_with("/") { - Ok(UnixOrTCPSocketAddress::UnixSocket( + return Ok(UnixOrTCPSocketAddress::UnixSocket( PathBuf::from_str(string).map_err(Error::custom)?, - )) - } else { - Ok(UnixOrTCPSocketAddress::TCPSocket( - SocketAddr::from_str(string).map_err(Error::custom)?, - )) + )); } + + Ok(UnixOrTCPSocketAddress::TCPSocket( + SocketAddr::from_str(string).map_err(Error::custom)?, + )) } } diff --git a/src/web/web_server.rs b/src/web/web_server.rs index 69939f65..c002f0c8 100644 --- a/src/web/web_server.rs +++ b/src/web/web_server.rs @@ -1,8 +1,8 @@ use std::fs::{self, Permissions}; -use std::os::unix::prelude::PermissionsExt; use std::{convert::Infallible, sync::Arc}; -use tokio::net::{TcpListener, UnixListener}; +use tokio::net::TcpListener; +// /, UnixListener}; use tokio::sync::watch; use hyper::{ @@ -20,7 +20,7 @@ use opentelemetry::{ use crate::error::*; -use garage_api::generic_server::{server_loop, UnixListenerOn}; +use garage_api::generic_server::server_loop; use garage_api::helpers::*; use garage_api::s3::cors::{add_cors_headers, find_matching_cors_rule, handle_options_for_bucket}; use garage_api::s3::error::{ @@ -96,6 +96,7 @@ impl WebServer { move |stream, socketaddr| self.clone().handle_request(stream, socketaddr); server_loop(server_name, listener, handler, must_exit).await } + #[cfg(unix)] UnixOrTCPSocketAddress::UnixSocket(ref path) => { if path.exists() { fs::remove_file(path)?