Skip to content

Commit

Permalink
Stub windows functions via conditional compilation
Browse files Browse the repository at this point in the history
This allows spfs to build via cross, but produces a binary that will
panic because of missing implementations. The goal at this point is to
build for windows in CI to avoid any regressions moving forward as we
work to add support.

Signed-off-by: Ryan Bottriell <[email protected]>
  • Loading branch information
rydrman committed Aug 4, 2023
1 parent 2e28a05 commit 1bfebf9
Show file tree
Hide file tree
Showing 38 changed files with 1,028 additions and 313 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,26 @@ env:
CARGO_TERM_COLOR: always

jobs:
build-windows:
name: Windows Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.71.0
target: x86_64-pc-windows-gnu
override: true
- name: Install Cross
uses: brndnmtthws/rust-action-cargo-binstall@v1
with:
packages: cross
- name: Build SPFS
run: |
make debug-spfs PLATFORM=windows
build-and-test:
name: Linux Build and Test
runs-on: ubuntu-latest
timeout-minutes: 45
container:
Expand Down
39 changes: 12 additions & 27 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cross.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[target.x86_64-pc-windows-gnu]
pre-build = ["apt-get install -y protobuf-compiler"]
32 changes: 21 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,24 @@ CARGO_TARGET_DIR := $(shell \
then (grep target-dir .cargo/config.toml || echo target) | sed -sE 's|.*"(.*)".*|\1|'; \
else echo target; \
fi)
CARGO ?= cargo

spfs_packages = spfs,spfs-cli-main,spfs-cli-clean,spfs-cli-enter,spfs-cli-join,spfs-cli-render

export PLATFORM ?= unix
ifeq ($(PLATFORM),windows)
CARGO_ARGS += --target x86_64-pc-windows-gnu
# swap cargo for cross when building for other platforms
CARGO = cross
else
spfs_packages := $(spfs_packages),spfs-cli-fuse,spfs-cli-monitor
endif

comma := ,
cargo_features_arg = $(if $(FEATURES),--features $(FEATURES))
cargo_packages_arg := $(if $(CRATES),-p=$(CRATES))
cargo_packages_arg := $(subst $(comma), -p=,$(cargo_packages_arg))

cargo_packages_arg := $(if $(cargo_packages_arg),$(cargo_packages_arg),--workspace)

# Create a file called "config.mak" to configure variables.
-include config.mak
Expand Down Expand Up @@ -41,37 +53,35 @@ clean: packages.clean
.PHONY: lint
lint: FEATURES?=server,spfs/server
lint:
cargo +nightly fmt --check
cargo clippy --tests $(cargo_features_arg) $(cargo_packages_arg) -- -Dwarnings
$(CARGO) +nightly fmt --check
$(CARGO) clippy --tests $(cargo_features_arg) $(cargo_packages_arg) -- -Dwarnings
env RUSTDOCFLAGS="-Dwarnings" cargo doc --no-deps $(cargo_features_arg) $(cargo_packages_arg)

.PHONY: format
format:
cargo +nightly fmt
$(CARGO) +nightly fmt

.PHONY: build
build: debug

debug:
cd $(SOURCE_ROOT)
cargo build --workspace $(cargo_features_arg)
$(CARGO) build $(cargo_packages_arg) $(cargo_features_arg) $(CARGO_ARGS)

debug-spfs:
cd $(SOURCE_ROOT)
cargo build -p spfs -p spfs-cli-fuse -p spfs-cli-main -p spfs-cli-clean -p spfs-cli-enter -p spfs-cli-join -p spfs-cli-monitor -p spfs-cli-render $(cargo_features_arg)
$(MAKE) debug CRATES=$(spfs_packages)

release:
cd $(SOURCE_ROOT)
cargo build --workspace --release $(cargo_features_arg)
$(CARGO) build --release $(cargo_packages_arg) $(cargo_features_arg) $(CARGO_ARGS)

release-spfs:
cd $(SOURCE_ROOT)
cargo build --release -p spfs -p spfs-cli-fuse -p spfs-cli-main -p spfs-cli-clean -p spfs-cli-enter -p spfs-cli-join -p spfs-cli-monitor -p spfs-cli-render $(cargo_features_arg)
$(MAKE) release CRATES=$(spfs_packages)

.PHONY: test
test: FEATURES?=server,spfs/server
test:
spfs run - -- cargo test --workspace $(cargo_features_arg) $(cargo_packages_arg)
spfs run - -- cargo test $(cargo_features_arg) $(cargo_packages_arg)

.PHONY: converters
converters:
Expand Down
9 changes: 9 additions & 0 deletions crates/spfs-cli/cmd-enter/src/cmd_enter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ impl CmdEnter {
}
}

#[cfg(unix)]
pub async fn setup_runtime(
&mut self,
config: &spfs::Config,
Expand Down Expand Up @@ -215,6 +216,14 @@ impl CmdEnter {
}
}

#[cfg(windows)]
pub async fn setup_runtime(
&mut self,
config: &spfs::Config,
) -> Result<Option<spfs::runtime::OwnedRuntime>> {
todo!()
}

async fn load_runtime(&self, config: &spfs::Config) -> Result<spfs::runtime::Runtime> {
let repo = match &self.runtime_storage {
Some(address) => spfs::open_repository(address).await?,
Expand Down
6 changes: 4 additions & 2 deletions crates/spfs-cli/cmd-fuse/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ sentry = ["spfs-cli-common/sentry"]
anyhow = { workspace = true }
clap = { workspace = true }
dashmap = { workspace = true }
fuser = { workspace = true }
spfs-vfs = { path = "../../spfs-vfs" }
nix = { workspace = true, features = ["process"] }
libc = "0.2"
spfs = { path = "../../spfs" }
spfs = { path = "../../spfs", features = ["fuse-backend"] }
spfs-cli-common = { path = "../common" }
tokio = { version = "1.20", features = ["rt", "rt-multi-thread"] }
tracing = { workspace = true }
url = "2.2"

[target.'cfg(unix)'.dependencies]
fuser = { workspace = true }
4 changes: 2 additions & 2 deletions crates/spfs-cli/cmd-join/src/cmd_join.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl CmdJoin {
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.map_err(|err| Error::process_spawn_error("new_current_thread()".into(), err, None))?;
.map_err(|err| Error::process_spawn_error("new_current_thread()", err, None))?;
let spfs_runtime = rt.block_on(async {
let storage = config.get_runtime_storage().await?;

Expand Down Expand Up @@ -136,7 +136,7 @@ impl CmdJoin {
tracing::debug!("{:?}", proc);
Ok(proc
.status()
.map_err(|err| Error::process_spawn_error("exec_runtime_command".into(), err, None))?
.map_err(|err| Error::process_spawn_error("exec_runtime_command", err, None))?
.code()
.unwrap_or(1))
}
Expand Down
6 changes: 3 additions & 3 deletions crates/spfs-cli/cmd-monitor/src/cmd_monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,11 @@ impl CmdMonitor {

pub async fn run_async(&mut self) -> Result<i32> {
let mut interrupt = signal(SignalKind::interrupt())
.map_err(|err| Error::process_spawn_error("signal()".into(), err, None))?;
.map_err(|err| Error::process_spawn_error("signal()", err, None))?;
let mut quit = signal(SignalKind::quit())
.map_err(|err| Error::process_spawn_error("signal()".into(), err, None))?;
.map_err(|err| Error::process_spawn_error("signal()", err, None))?;
let mut terminate = signal(SignalKind::terminate())
.map_err(|err| Error::process_spawn_error("signal()".into(), err, None))?;
.map_err(|err| Error::process_spawn_error("signal()", err, None))?;

let repo = spfs::open_repository(&self.runtime_storage).await?;
let storage = spfs::runtime::Storage::new(repo);
Expand Down
5 changes: 4 additions & 1 deletion crates/spfs-cli/common/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ pub struct Logging {
#[clap(long, global = true, env = "SPFS_LOG_FILE")]
pub log_file: Option<std::path::PathBuf>,

/// Enables logging to syslog (for background processes)
/// Enables logging to syslog (for background processes, unix only)
#[clap(skip)]
pub syslog: bool,

Expand Down Expand Up @@ -363,6 +363,7 @@ impl Logging {
let env_filter = move || tracing_subscriber::filter::EnvFilter::from(config.clone());
let fmt_layer = || tracing_subscriber::fmt::layer().with_target(self.show_target());

#[cfg(unix)]
let syslog_layer = self.syslog.then(|| {
let identity = std::ffi::CStr::from_bytes_with_nul(b"spfs\0")
.expect("identity value is valid CStr");
Expand All @@ -374,6 +375,8 @@ impl Logging {
let layer = configure_timestamp!(layer, self.timestamp).with_filter(env_filter());
without_sentry_target!(layer)
});
#[cfg(windows)]
let syslog_layer = false.then(fmt_layer);

let stderr_layer = {
let layer = fmt_layer().with_writer(std::io::stderr);
Expand Down
13 changes: 12 additions & 1 deletion crates/spfs-cli/main/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ colored = "2.0"
futures = { workspace = true }
hyper = { version = "0.14.16", optional = true }
itertools = "0.10.3"
libc = { workspace = true }
nix = { workspace = true }
number_prefix = "*" # we hope to match versions with indicatif
procfs = { workspace = true }
relative-path = "1.3"
serde_json = { workspace = true }
spfs = { path = "../../spfs" }
Expand All @@ -36,3 +36,14 @@ tonic = { version = "0.8", optional = true }
tracing = { workspace = true }
unix_mode = "0.1.3"
url = { version = "2.2", optional = true }

[target.'cfg(unix)'.dependencies]
procfs = { workspace = true }

[target.'cfg(windows)'.dependencies.windows]
version = "0.48"
features = [
"Win32_Foundation",
"Win32_System_SystemInformation",
"Win32_System_Threading",
]
37 changes: 13 additions & 24 deletions crates/spfs-cli/main/src/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,38 +155,27 @@ async fn run_external_subcommand(args: Vec<String>) -> Result<i32> {
Some(cmd) => cmd,
None => {
let mut p = std::env::current_exe()
.map_err(|err| Error::process_spawn_error("current_exe()".into(), err, None))?;
.map_err(|err| Error::process_spawn_error("current_exe()", err, None))?;
p.set_file_name(&command);
p
}
};
let command_cstr = match std::ffi::CString::new(cmd_path.to_string_lossy().to_string()) {
Ok(s) => s,
Err(_) => {
tracing::error!("Invalid subcommand, not a valid string");
return Ok(1);
}

let cmd = spfs::bootstrap::Command {
executable: cmd_path.into(),
args: args.into_iter().skip(1).map(Into::into).collect(),
vars: Vec::new(),
};
let mut args_cstr = Vec::with_capacity(args.len());
args_cstr.push(command_cstr.clone());
for arg in args.iter().skip(1) {
args_cstr.push(match std::ffi::CString::new(arg.clone()) {
Ok(s) => s,
Err(_) => {
tracing::error!("Invalid argument, not a valid string");
return Ok(1);
}
})
}
if let Err(err) = nix::unistd::execvp(command_cstr.as_c_str(), args_cstr.as_slice()) {
match err {
nix::errno::Errno::ENOENT => {

match cmd.exec() {
Ok(o) => match o {},
Err(err) => match err.raw_os_error() {
Some(libc::ENOENT) => {
tracing::error!("{command} not found in PATH, was it properly installed?")
}
_ => tracing::error!("subcommand failed: {err:?}"),
}
return Ok(1);
},
}
Ok(0)
Ok(1)
}
}
Loading

0 comments on commit 1bfebf9

Please sign in to comment.