From 30c7aae66bf945ab06307567928a12044aef0aba Mon Sep 17 00:00:00 2001 From: Ahmed Al Hafoudh Date: Wed, 5 Feb 2025 22:29:37 +0100 Subject: [PATCH 1/4] Implement preopened_dir using set_mapped_directories setting --- Gemfile.lock | 2 +- ext/src/ruby_api/wasi_ctx_builder.rs | 40 +++++++++++++++++++++++++++- lib/wasmtime/version.rb | 2 +- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 458144f4..66be804a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - wasmtime (29.0.0) + wasmtime (30.0.0) rb_sys (~> 0.9.108) GEM diff --git a/ext/src/ruby_api/wasi_ctx_builder.rs b/ext/src/ruby_api/wasi_ctx_builder.rs index 660c21f6..2e2280fa 100644 --- a/ext/src/ruby_api/wasi_ctx_builder.rs +++ b/ext/src/ruby_api/wasi_ctx_builder.rs @@ -1,11 +1,13 @@ use super::{root, WasiCtx}; use crate::error; use crate::helpers::OutputLimitedBuffer; +use cap_std::fs::Dir; use magnus::{ class, function, gc::Marker, method, typed_data::Obj, value::Opaque, DataTypeFunctions, Error, - Module, Object, RArray, RHash, RString, Ruby, TryConvert, TypedData, + Integer, Module, Object, RArray, RHash, RString, Ruby, TryConvert, TypedData, }; use std::cell::RefCell; +use std::path::Path; use std::{fs::File, path::PathBuf}; use wasi_common::pipe::{ReadPipe, WritePipe}; @@ -47,6 +49,7 @@ struct WasiCtxBuilderInner { stderr: Option, env: Option>, args: Option>, + mapped_directories: Option>, } impl WasiCtxBuilderInner { @@ -222,6 +225,17 @@ impl WasiCtxBuilder { rb_self } + /// @yard + /// Set mapped directories to the specified +Array+. + /// @param mapped_directories [Array>] + /// @def set_mapped_directories(mapped_directories) + /// @return [WasiCtxBuilder] +self+ + pub fn set_mapped_directories(rb_self: RbSelf, mapped_directories: RArray) -> RbSelf { + let mut inner = rb_self.inner.borrow_mut(); + inner.mapped_directories = Some(mapped_directories.into()); + rb_self + } + pub fn build(ruby: &Ruby, rb_self: RbSelf) -> Result { let mut builder = wasi_common::sync::WasiCtxBuilder::new(); let inner = rb_self.inner.borrow(); @@ -281,6 +295,25 @@ impl WasiCtxBuilder { builder.envs(&env_vec).map_err(|e| error!("{}", e))?; } + if let Some(mapped_directories) = inner.mapped_directories.as_ref() { + for item in unsafe { ruby.get_inner(*mapped_directories).as_slice() } { + let mapped_directory = RArray::try_convert(*item)?; + if mapped_directory.len() == 2 { + let host_path = + RString::try_convert(mapped_directory.entry(0)?)?.to_string()?; + let guest_path = + RString::try_convert(mapped_directory.entry(1)?)?.to_string()?; + + let host_path_dir = Dir::from_std_file(File::open(host_path).unwrap()); + let guest_path_path = PathBuf::from(guest_path.as_str()); + + builder + .preopened_dir(host_path_dir, guest_path_path) + .map_err(|e| error!("{}", e))?; + } + } + } + let ctx = WasiCtx::from_inner(builder.build()); Ok(ctx) } @@ -339,6 +372,11 @@ pub fn init() -> Result<(), Error> { class.define_method("set_argv", method!(WasiCtxBuilder::set_argv, 1))?; + class.define_method( + "set_mapped_directories", + method!(WasiCtxBuilder::set_mapped_directories, 1), + )?; + class.define_method("build", method!(WasiCtxBuilder::build, 0))?; Ok(()) diff --git a/lib/wasmtime/version.rb b/lib/wasmtime/version.rb index c17bbf25..b564f847 100644 --- a/lib/wasmtime/version.rb +++ b/lib/wasmtime/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Wasmtime - VERSION = "29.0.0" + VERSION = "30.0.0" end From b29b4e5e4f6a1498477c9a20fd5f0c4f936109ce Mon Sep 17 00:00:00 2001 From: Ahmed Al Hafoudh Date: Thu, 6 Feb 2025 16:21:14 +0100 Subject: [PATCH 2/4] Revert back the gem version --- Gemfile.lock | 2 +- lib/wasmtime/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 66be804a..458144f4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - wasmtime (30.0.0) + wasmtime (29.0.0) rb_sys (~> 0.9.108) GEM diff --git a/lib/wasmtime/version.rb b/lib/wasmtime/version.rb index b564f847..c17bbf25 100644 --- a/lib/wasmtime/version.rb +++ b/lib/wasmtime/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Wasmtime - VERSION = "30.0.0" + VERSION = "29.0.0" end From 18ab99833f50a25743ae432400520054eed611c4 Mon Sep 17 00:00:00 2001 From: Ahmed Al Hafoudh Date: Thu, 6 Feb 2025 16:21:33 +0100 Subject: [PATCH 3/4] Cleanup use of Integer which is not used --- ext/src/ruby_api/wasi_ctx_builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/src/ruby_api/wasi_ctx_builder.rs b/ext/src/ruby_api/wasi_ctx_builder.rs index 2e2280fa..824d2afd 100644 --- a/ext/src/ruby_api/wasi_ctx_builder.rs +++ b/ext/src/ruby_api/wasi_ctx_builder.rs @@ -4,7 +4,7 @@ use crate::helpers::OutputLimitedBuffer; use cap_std::fs::Dir; use magnus::{ class, function, gc::Marker, method, typed_data::Obj, value::Opaque, DataTypeFunctions, Error, - Integer, Module, Object, RArray, RHash, RString, Ruby, TryConvert, TypedData, + Module, Object, RArray, RHash, RString, Ruby, TryConvert, TypedData, }; use std::cell::RefCell; use std::path::Path; From 0477a2f67429c8a0ac268f365f066e2bde1a6613 Mon Sep 17 00:00:00 2001 From: Ahmed Al Hafoudh Date: Thu, 6 Feb 2025 16:43:38 +0100 Subject: [PATCH 4/4] Rename the set_mapped_directories to set_mapped_directory and make it set only one mapping per call --- ext/src/ruby_api/wasi_ctx_builder.rs | 32 ++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/ext/src/ruby_api/wasi_ctx_builder.rs b/ext/src/ruby_api/wasi_ctx_builder.rs index 824d2afd..b6b1c96e 100644 --- a/ext/src/ruby_api/wasi_ctx_builder.rs +++ b/ext/src/ruby_api/wasi_ctx_builder.rs @@ -6,6 +6,7 @@ use magnus::{ class, function, gc::Marker, method, typed_data::Obj, value::Opaque, DataTypeFunctions, Error, Module, Object, RArray, RHash, RString, Ruby, TryConvert, TypedData, }; +use rb_sys::ruby_rarray_flags::RARRAY_EMBED_FLAG; use std::cell::RefCell; use std::path::Path; use std::{fs::File, path::PathBuf}; @@ -69,6 +70,9 @@ impl WasiCtxBuilderInner { if let Some(v) = self.args.as_ref() { marker.mark(*v); } + if let Some(v) = self.mapped_directories.as_ref() { + marker.mark(*v); + } } } @@ -226,13 +230,27 @@ impl WasiCtxBuilder { } /// @yard - /// Set mapped directories to the specified +Array+. - /// @param mapped_directories [Array>] - /// @def set_mapped_directories(mapped_directories) + /// Set mapped directory for host path and guest path. + /// @param host_path [String] + /// @param guest_path [String] + /// @def set_mapped_directory(host_path, guest_path) /// @return [WasiCtxBuilder] +self+ - pub fn set_mapped_directories(rb_self: RbSelf, mapped_directories: RArray) -> RbSelf { + pub fn set_mapped_directory( + rb_self: RbSelf, + host_path: RString, + guest_path: RString, + ) -> RbSelf { let mut inner = rb_self.inner.borrow_mut(); - inner.mapped_directories = Some(mapped_directories.into()); + if inner.mapped_directories.is_none() { + inner.mapped_directories = Some(RArray::new().into()); + } + let mapped_directory = RArray::new(); + mapped_directory.push(host_path).unwrap(); + mapped_directory.push(guest_path).unwrap(); + + let ruby = Ruby::get().unwrap(); + let mapped_directories = ruby.get_inner(inner.mapped_directories.unwrap()); + mapped_directories.push(mapped_directory).unwrap(); rb_self } @@ -373,8 +391,8 @@ pub fn init() -> Result<(), Error> { class.define_method("set_argv", method!(WasiCtxBuilder::set_argv, 1))?; class.define_method( - "set_mapped_directories", - method!(WasiCtxBuilder::set_mapped_directories, 1), + "set_mapped_directory", + method!(WasiCtxBuilder::set_mapped_directory, 2), )?; class.define_method("build", method!(WasiCtxBuilder::build, 0))?;