Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: windows symlink support #386

Merged
merged 6 commits into from
Oct 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .cargo/config
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
[alias]
xtask = "run --package xtask --"
xtask = "run --package xtask --"

[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you enlighten me?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so you can cross compile for windows on mac and I don't have to go looking for a windows box.

1 change: 1 addition & 0 deletions iroh-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ thiserror = "1.0"

[dev-dependencies]
tempfile = "3.3.0"
tempdir = "0.3.7"
16 changes: 16 additions & 0 deletions iroh-api/src/api_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,29 @@ async fn save_get_stream(
if let Some(parent) = path.parent() {
tokio::fs::create_dir_all(parent.to_path(root_path)).await?;
}
#[cfg(windows)]
tokio::task::spawn_blocking(move || {
make_windows_symlink(target, full_path).map_err(|e| anyhow::anyhow!(e))
})
.await??;

#[cfg(unix)]
tokio::fs::symlink(target, full_path).await?;
}
}
}
Ok(())
}

#[cfg(windows)]
fn make_windows_symlink(target: PathBuf, path: PathBuf) -> Result<()> {
if target.is_dir() {
std::os::windows::fs::symlink_dir(target, path).map_err(|e| anyhow::anyhow!(e))
} else {
std::os::windows::fs::symlink_file(target, path).map_err(|e| anyhow::anyhow!(e))
}
}

/// Given an cid and an optional output path, determine root path
fn get_root_path(ipfs_path: &IpfsPath, output_path: Option<&Path>) -> PathBuf {
match output_path {
Expand Down
5 changes: 2 additions & 3 deletions iroh-gateway/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use iroh_rpc_client::Client as RpcClient;
use iroh_util::lock::ProgramLock;
use iroh_util::{iroh_config_path, make_config};
use tokio::sync::RwLock;
use tracing::{debug, error};

#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<()> {
Expand Down Expand Up @@ -64,8 +63,8 @@ async fn main() -> Result<()> {
#[cfg(unix)]
{
match iroh_util::increase_fd_limit() {
Ok(soft) => debug!("NOFILE limit: soft = {}", soft),
Err(err) => error!("Error increasing NOFILE limit: {}", err),
Ok(soft) => tracing::debug!("NOFILE limit: soft = {}", soft),
Err(err) => tracing::error!("Error increasing NOFILE limit: {}", err),
}
}

Expand Down
15 changes: 8 additions & 7 deletions iroh-localops/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use nix::sys::signal::{kill, Signal};
#[cfg(any(target_os = "macos", target_os = "linux"))]
use nix::unistd::Pid;
use std::path::PathBuf;
#[cfg(any(target_os = "macos", target_os = "linux"))]
use std::process::{Command, Stdio};

// TODO(b5): instead of using u32's for Process Identifiers, use a proper Pid type
Expand Down Expand Up @@ -33,7 +34,7 @@ pub fn daemonize(bin_path: PathBuf, log_path: PathBuf) -> Result<()> {
}

#[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
fn daemonize_process(bin_path: PathBuf, log_path: PathBuf) -> Result<()> {
fn daemonize_process(_bin_path: PathBuf, _log_path: PathBuf) -> Result<()> {
Err(anyhow!(
"daemonizing processes is not supported on your operating system"
))
Expand Down Expand Up @@ -62,31 +63,31 @@ fn daemonize_process(bin_path: PathBuf, log_path: PathBuf) -> Result<()> {
}

#[cfg(target_os = "windows")]
fn daemonize_process(bin_path: PathBuf, log_path: PathBuf) -> Result<()> {
fn daemonize_process(_bin_path: PathBuf, _log_path: PathBuf) -> Result<()> {
Err(anyhow!("daemonizing processes on windows is not supported"))
}

// TODO(b5) - this level of indirection isn't necessary, factor `stop_process`
// directly into `stop`
// https://github.com/n0-computer/iroh/pull/360#discussion_r1002000769
pub fn stop(pid: i32) -> Result<()> {
pub fn stop(pid: u32) -> Result<()> {
stop_process(pid)
}

#[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
fn stop_process(pid: i32) -> Result<()> {
fn stop_process(pid: u32) -> Result<()> {
Err(anyhow!(
"stopping processes is not supported on your operating system"
))
}

#[cfg(any(target_os = "macos", target_os = "linux"))]
fn stop_process(pid: i32) -> Result<()> {
let id = Pid::from_raw(pid);
fn stop_process(pid: u32) -> Result<()> {
let id = Pid::from_raw(pid as i32);
kill(id, Signal::SIGINT).map_err(|e| anyhow!("killing process: {}", e))
}

#[cfg(target_os = "windows")]
fn stop_process(pid: i32) -> Result<()> {
fn stop_process(_pid: u32) -> Result<()> {
Err(anyhow!("stopping processes on windows is not supported"))
}
14 changes: 10 additions & 4 deletions iroh-one/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ use config::{ConfigError, Map, Source, Value};
use iroh_metrics::config::Config as MetricsConfig;
use iroh_p2p::Libp2pConfig;
use iroh_rpc_client::Config as RpcClientConfig;
use iroh_rpc_types::Addr;
use iroh_store::config::config_data_path;
use iroh_util::insert_into_config_map;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use tempfile::TempDir;

/// CONFIG_FILE_NAME is the name of the optional config file located in the iroh home directory
pub const CONFIG_FILE_NAME: &str = "one.config.toml";
Expand Down Expand Up @@ -67,10 +65,18 @@ impl Config {
/// The gateway itself is exposing a UDS rpc endpoint to be also usable
/// as a single entry point for other system services if feature enabled.
pub fn default_rpc_config() -> RpcClientConfig {
let path: PathBuf = TempDir::new().unwrap().path().join("iroh/ipfsd.http");
#[cfg(feature = "uds-gateway")]
let path: PathBuf = tempdir::TempDir::new("iroh")
.unwrap()
.path()
.join("ipfsd.http");

RpcClientConfig {
gateway_addr: Some(Addr::GrpcUds(path)),
#[cfg(feature = "uds-gateway")]
gateway_addr: Some(iroh_rpc_types::Addr::GrpcUds(path)),
// TODO(ramfox): not sure what the correct option is when not running a uds gateway
#[cfg(not(feature = "uds-gateway"))]
gateway_addr: None,
p2p_addr: None,
store_addr: None,
}
Expand Down
5 changes: 2 additions & 3 deletions iroh-one/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use iroh_util::{iroh_config_path, make_config};
#[cfg(feature = "uds-gateway")]
use tempdir::TempDir;
use tokio::sync::RwLock;
use tracing::{debug, error};

#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<()> {
Expand All @@ -43,8 +42,8 @@ async fn main() -> Result<()> {
#[cfg(unix)]
{
match iroh_util::increase_fd_limit() {
Ok(soft) => debug!("NOFILE limit: soft = {}", soft),
Err(err) => error!("Error increasing NOFILE limit: {}", err),
Ok(soft) => tracing::debug!("NOFILE limit: soft = {}", soft),
Err(err) => tracing::error!("Error increasing NOFILE limit: {}", err),
}
}

Expand Down
4 changes: 2 additions & 2 deletions iroh-p2p/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use iroh_p2p::{cli::Args, metrics, DiskStorage, Keychain, Node};
use iroh_util::lock::ProgramLock;
use iroh_util::{iroh_config_path, make_config};
use tokio::task;
use tracing::{debug, error};
use tracing::error;

/// Starts daemon process
fn main() -> Result<()> {
Expand Down Expand Up @@ -50,7 +50,7 @@ fn main() -> Result<()> {
#[cfg(unix)]
{
match iroh_util::increase_fd_limit() {
Ok(soft) => debug!("NOFILE limit: soft = {}", soft),
Ok(soft) => tracing::debug!("NOFILE limit: soft = {}", soft),
Err(err) => error!("Error increasing NOFILE limit: {}", err),
}
}
Expand Down
1 change: 1 addition & 0 deletions iroh-resolver/src/unixfs_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,7 @@ mod tests {
Ok(())
}

#[cfg(not(windows))]
#[tokio::test]
async fn symlink_from_disk_test() -> Result<()> {
let temp_dir = tempfile::tempdir()?;
Expand Down
6 changes: 3 additions & 3 deletions iroh-store/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use iroh_store::{
};
use iroh_util::lock::ProgramLock;
use iroh_util::{block_until_sigint, iroh_config_path, make_config};
use tracing::{debug, error, info};
use tracing::info;

#[tokio::main(flavor = "multi_thread")]
async fn main() -> anyhow::Result<()> {
Expand Down Expand Up @@ -44,8 +44,8 @@ async fn main() -> anyhow::Result<()> {
#[cfg(unix)]
{
match iroh_util::increase_fd_limit() {
Ok(soft) => debug!("NOFILE limit: soft = {}", soft),
Err(err) => error!("Error increasing NOFILE limit: {}", err),
Ok(soft) => tracing::debug!("NOFILE limit: soft = {}", soft),
Err(err) => tracing::error!("Error increasing NOFILE limit: {}", err),
}
}

Expand Down
2 changes: 2 additions & 0 deletions iroh-util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ pub mod lock;

/// name of directory that wraps all iroh files in a given application directory
const IROH_DIR: &str = "iroh";
#[cfg(unix)]
const DEFAULT_NOFILE_LIMIT: u64 = 65536;
#[cfg(unix)]
const MIN_NOFILE_LIMIT: u64 = 2048;

/// Blocks current thread until ctrl-c is received
Expand Down
5 changes: 3 additions & 2 deletions iroh-util/src/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::io::ErrorKind;
use std::io::Write;
use std::path::PathBuf;
use std::process;
use sysinfo::PidExt;
use sysinfo::{Pid, ProcessExt, ProcessStatus::*, System, SystemExt};
use thiserror::Error;
use tracing::warn;
Expand Down Expand Up @@ -192,9 +193,9 @@ fn read_lock(path: &PathBuf) -> Result<Pid, LockError> {
file.read_to_string(&mut pid)
.map_err(|_| LockError::CorruptLock(path.clone()))?;
let pid = pid
.parse::<i32>()
.parse::<u32>()
.map_err(|_| LockError::CorruptLock(path.clone()))?;
Ok(Pid::from(pid))
Ok(Pid::from_u32(pid))
}

/// LockError is the set of known program lock errors
Expand Down
3 changes: 2 additions & 1 deletion iroh/src/services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use iroh_util::iroh_cache_path;
use std::collections::HashSet;
use std::io::{stdout, Write};
use std::time::SystemTime;
use sysinfo::PidExt;
use tracing::info;

use iroh_api::{Api, ServiceStatus, StatusRow, StatusTable};
Expand Down Expand Up @@ -131,7 +132,7 @@ pub async fn stop_services(api: &impl Api, services: HashSet<&str>) -> Result<()
Ok(pid) => {
info!("stopping {} pid: {}", daemon_name, pid);
print!("stopping {}... ", &daemon_name);
match iroh_localops::process::stop(pid.into()) {
match iroh_localops::process::stop(pid.as_u32()) {
Ok(_) => {
let is_down = ensure_status(
api,
Expand Down