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 <rbottriell@ilm.com>
  • Loading branch information
rydrman committed Aug 4, 2023
1 parent 381ab10 commit 6d81eee
Show file tree
Hide file tree
Showing 38 changed files with 1,038 additions and 322 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,27 @@ env:
CARGO_TERM_COLOR: always

jobs:
build-windows:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: x86_64-pc-windows-gnu
override: true
- name: Install Cross
run:
cargo install cross
- name: Install Protoc
run: |
sudo apt-get update
sudo apt-get install -y protobuf-compiler
- name: Build SPFS
run: |
make debug-spfs PLATFORM=windows
build-and-test:
runs-on: ubuntu-latest
timeout-minutes: 45
Expand Down Expand Up @@ -54,6 +75,8 @@ jobs:
# features enabled.
- name: Build
run: make debug FEATURES=server,spfs/server
- name: Build Windows
run: make debug-spfs PLATFORM=windows
- name: Install Debug Binaries
run: make install-debug-spfs FEATURES=server,spfs/server
- name: Setup a local origin repo
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.

3 changes: 3 additions & 0 deletions Cross.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[target.x86_64-pc-windows-gnu.env]
volumes = ["BUILD_RESOURCES"]
passthrough = ["PROTOC"]
33 changes: 23 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,27 @@ 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

export PROTOC ?= $(shell which protoc)
export BUILD_RESOURCES := $(shell dirname $(PROTOC))

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,32 +56,30 @@ 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
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)
return Ok(1);
}
}
Loading

0 comments on commit 6d81eee

Please sign in to comment.