mirror of
https://github.com/fluencelabs/marine.git
synced 2024-12-12 14:55:32 +00:00
add basic autocomplete and history support to REPL
This commit is contained in:
parent
31a15baf76
commit
d68e0cd76e
11
Cargo.lock
generated
11
Cargo.lock
generated
@ -566,6 +566,7 @@ dependencies = [
|
|||||||
"fluence-app-service",
|
"fluence-app-service",
|
||||||
"rustop",
|
"rustop",
|
||||||
"rustyline",
|
"rustyline",
|
||||||
|
"rustyline-derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"uuid",
|
"uuid",
|
||||||
"wasmer-wasi-fl",
|
"wasmer-wasi-fl",
|
||||||
@ -1132,6 +1133,16 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustyline-derive"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "54a50e29610a5be68d4a586a5cce3bfb572ed2c2a74227e4168444b7bf4e5235"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
|
@ -20,5 +20,6 @@ serde_json = "1.0.57"
|
|||||||
wasmer-wasi = { package = "wasmer-wasi-fl", version = "0.17.0"}
|
wasmer-wasi = { package = "wasmer-wasi-fl", version = "0.17.0"}
|
||||||
|
|
||||||
rustyline = "6.1.2"
|
rustyline = "6.1.2"
|
||||||
|
rustyline-derive = "0.3.1"
|
||||||
rustop = "1.1.0"
|
rustop = "1.1.0"
|
||||||
uuid = { version = "0.8.1", features = ["v4"] }
|
uuid = { version = "0.8.1", features = ["v4"] }
|
||||||
|
@ -25,204 +25,146 @@
|
|||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
|
|
||||||
/// Command-line tool intended to test Fluence FaaS.
|
/// Command-line tool intended to test Fluence FaaS.
|
||||||
use std::fs;
|
|
||||||
|
|
||||||
macro_rules! next_argument {
|
mod repl;
|
||||||
($arg_name:ident, $args:ident, $error_msg:expr) => {
|
|
||||||
let $arg_name = if let Some($arg_name) = $args.next() {
|
|
||||||
$arg_name
|
|
||||||
} else {
|
|
||||||
println!($error_msg);
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<(), anyhow::Error> {
|
use repl::REPL;
|
||||||
|
|
||||||
|
use rustyline::completion::{Completer, FilenameCompleter, Pair};
|
||||||
|
use rustyline::config::OutputStreamType;
|
||||||
|
use rustyline::error::ReadlineError;
|
||||||
|
use rustyline::highlight::{Highlighter, MatchingBracketHighlighter};
|
||||||
|
use rustyline::hint::{Hinter, HistoryHinter};
|
||||||
|
use rustyline::validate::{self, MatchingBracketValidator, Validator};
|
||||||
|
use rustyline::{Cmd, CompletionType, Config, Context, EditMode, Editor, KeyPress};
|
||||||
|
use rustyline_derive::Helper;
|
||||||
|
|
||||||
|
use std::borrow::Cow::{self, Borrowed, Owned};
|
||||||
|
|
||||||
|
pub(crate) type Result<T> = std::result::Result<T, anyhow::Error>;
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
let (args, _) = rustop::opts! {
|
let (args, _) = rustop::opts! {
|
||||||
synopsis "Fluence Application service REPL";
|
synopsis "Fluence Application service REPL";
|
||||||
param config_file_path: Option<String>, desc: "Path to a service config";
|
param config_file_path: Option<String>, desc: "Path to a service config";
|
||||||
}
|
}
|
||||||
.parse_or_exit();
|
.parse_or_exit();
|
||||||
|
|
||||||
println!("Welcome to the Fluence FaaS REPL:");
|
let config = Config::builder()
|
||||||
let mut app_service = create_service_from_config(args.config_file_path)?;
|
.history_ignore_space(true)
|
||||||
|
.completion_type(CompletionType::List)
|
||||||
|
.edit_mode(EditMode::Emacs)
|
||||||
|
.output_stream(OutputStreamType::Stdout)
|
||||||
|
.build();
|
||||||
|
let h = MyHelper {
|
||||||
|
completer: FilenameCompleter::new(),
|
||||||
|
highlighter: MatchingBracketHighlighter::new(),
|
||||||
|
hinter: HistoryHinter {},
|
||||||
|
colored_prompt: "".to_owned(),
|
||||||
|
validator: MatchingBracketValidator::new(),
|
||||||
|
};
|
||||||
|
let mut rl = Editor::with_config(config);
|
||||||
|
rl.set_helper(Some(h));
|
||||||
|
rl.bind_sequence(KeyPress::Meta('N'), Cmd::HistorySearchForward);
|
||||||
|
rl.bind_sequence(KeyPress::Meta('P'), Cmd::HistorySearchBackward);
|
||||||
|
let _ = rl.load_history("history.txt");
|
||||||
|
|
||||||
let mut rl = rustyline::Editor::<()>::new();
|
println!("Welcome to the Fluence FaaS REPL:");
|
||||||
|
|
||||||
|
let mut repl = REPL::new(args.config_file_path)?;
|
||||||
|
|
||||||
|
let mut count = 1;
|
||||||
loop {
|
loop {
|
||||||
let readline = rl.readline(">> ");
|
let p = format!("{}> ", count);
|
||||||
let readline = match readline {
|
rl.helper_mut().expect("No helper").colored_prompt = format!("\x1b[1;32m{}\x1b[0m", p);
|
||||||
Ok(readline) => readline,
|
let readline = rl.readline(&p);
|
||||||
Err(e) => {
|
match readline {
|
||||||
println!("a error occurred: {}", e);
|
Ok(line) => {
|
||||||
|
rl.add_history_entry(line.as_str());
|
||||||
|
repl.execute(line.split_whitespace());
|
||||||
|
}
|
||||||
|
Err(ReadlineError::Interrupted) => {
|
||||||
|
println!("CTRL-C");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
Err(ReadlineError::Eof) => {
|
||||||
|
println!("CTRL-D");
|
||||||
let mut args = readline.split_whitespace();
|
break;
|
||||||
match args.next() {
|
|
||||||
Some("new") => {
|
|
||||||
app_service = match create_service_from_config(args.next()) {
|
|
||||||
Ok(service) => service,
|
|
||||||
Err(e) => {
|
|
||||||
println!("failed to create a new application service: {}", e);
|
|
||||||
app_service
|
|
||||||
}
|
}
|
||||||
};
|
Err(err) => {
|
||||||
}
|
println!("Error: {:?}", err);
|
||||||
Some("load") => {
|
break;
|
||||||
next_argument!(module_name, args, "Module name should be specified");
|
|
||||||
next_argument!(module_path, args, "Module path should be specified");
|
|
||||||
|
|
||||||
let wasm_bytes = fs::read(module_path);
|
|
||||||
if let Err(e) = wasm_bytes {
|
|
||||||
println!("failed to read wasm module: {}", e);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let result_msg = match app_service
|
|
||||||
.load_module::<String, fluence_app_service::ModuleConfig>(
|
|
||||||
module_name.into(),
|
|
||||||
&wasm_bytes.unwrap(),
|
|
||||||
None,
|
|
||||||
) {
|
|
||||||
Ok(_) => "module successfully loaded into App service".to_string(),
|
|
||||||
Err(e) => format!("module loaded failed with: {:?}", e),
|
|
||||||
};
|
|
||||||
println!("{}", result_msg);
|
|
||||||
}
|
|
||||||
Some("unload") => {
|
|
||||||
next_argument!(module_name, args, "Module name should be specified");
|
|
||||||
|
|
||||||
let result_msg = match app_service.unload_module(module_name) {
|
|
||||||
Ok(_) => "module successfully unloaded from App service".to_string(),
|
|
||||||
Err(e) => format!("module unloaded failed with: {:?}", e),
|
|
||||||
};
|
|
||||||
println!("{}", result_msg);
|
|
||||||
}
|
|
||||||
Some("call") => {
|
|
||||||
next_argument!(module_name, args, "Module name should be specified");
|
|
||||||
next_argument!(func_name, args, "Function name should be specified");
|
|
||||||
|
|
||||||
let module_arg: String = args.collect();
|
|
||||||
let module_arg: serde_json::Value = match serde_json::from_str(&module_arg) {
|
|
||||||
Ok(module_arg) => module_arg,
|
|
||||||
Err(e) => {
|
|
||||||
println!("incorrect arguments {}", e);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = match app_service.call(module_name, func_name, module_arg) {
|
|
||||||
Ok(result) => format!("result: {:?}", result),
|
|
||||||
Err(e) => format!("execution failed with {:?}", e),
|
|
||||||
};
|
|
||||||
println!("{}", result);
|
|
||||||
}
|
|
||||||
Some("envs") => {
|
|
||||||
next_argument!(module_name, args, "Module name should be specified");
|
|
||||||
match app_service.get_wasi_state(module_name) {
|
|
||||||
Ok(wasi_state) => print_envs(wasi_state),
|
|
||||||
Err(e) => println!("{}", e),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Some("fs") => {
|
|
||||||
next_argument!(module_name, args, "Module name should be specified");
|
|
||||||
match app_service.get_wasi_state(module_name) {
|
|
||||||
Ok(wasi_state) => print_fs_state(wasi_state),
|
|
||||||
Err(e) => println!("{}", e),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Some("interface") => {
|
|
||||||
let interface = app_service.get_interface();
|
|
||||||
println!("application service interface:\n{}", interface);
|
|
||||||
}
|
|
||||||
Some("h") | Some("help") | None => {
|
|
||||||
println!(
|
|
||||||
"Enter:\n\
|
|
||||||
new [config_path] - to create a new AppService (current will be removed)\n\
|
|
||||||
load <module_name> <module_path> - to load a new Wasm module into App service\n\
|
|
||||||
unload <module_name> - to unload Wasm module from AppService\n\
|
|
||||||
call <module_name> <func_name> [args] - to call function with func_name of module with module_name\n\
|
|
||||||
interface - to print public interface of current AppService\n\
|
|
||||||
envs <module_name> - to print environment variables of module with module_name\n\
|
|
||||||
fs <module_name> - to print filesystem state of module with module_name\n\
|
|
||||||
h/help - to print this message\n\
|
|
||||||
e/exit/q/quit - to exit"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Some("e") | Some("exit") | Some("q") | Some("quit") => break,
|
|
||||||
_ => {
|
|
||||||
println!("unsupported command");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_service_from_config<S: Into<String>>(
|
#[derive(Helper)]
|
||||||
config_file_path: Option<S>,
|
struct MyHelper {
|
||||||
) -> Result<fluence_app_service::AppService, anyhow::Error> {
|
completer: FilenameCompleter,
|
||||||
let tmp_path: String = std::env::temp_dir().to_string_lossy().into();
|
highlighter: MatchingBracketHighlighter,
|
||||||
let service_id = uuid::Uuid::new_v4().to_string();
|
validator: MatchingBracketValidator,
|
||||||
|
hinter: HistoryHinter,
|
||||||
let app_service = match config_file_path {
|
colored_prompt: String,
|
||||||
Some(config_file_path) => {
|
|
||||||
let config_file_path = config_file_path.into();
|
|
||||||
fluence_app_service::AppService::with_raw_config(
|
|
||||||
config_file_path,
|
|
||||||
&service_id,
|
|
||||||
Some(&tmp_path),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let mut config: fluence_app_service::RawModulesConfig = <_>::default();
|
|
||||||
config.service_base_dir = Some(tmp_path);
|
|
||||||
|
|
||||||
fluence_app_service::AppService::new(std::iter::empty(), config, &service_id)
|
|
||||||
}
|
|
||||||
}?;
|
|
||||||
|
|
||||||
println!("app service's created with service id = {}", service_id);
|
|
||||||
|
|
||||||
Ok(app_service)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_envs(wasi_state: &wasmer_wasi::state::WasiState) {
|
impl Completer for MyHelper {
|
||||||
let envs = &wasi_state.envs;
|
type Candidate = Pair;
|
||||||
|
|
||||||
println!("Environment variables:");
|
fn complete(
|
||||||
for env in envs.iter() {
|
&self,
|
||||||
match String::from_utf8(env.clone()) {
|
line: &str,
|
||||||
Ok(string) => println!("{}", string),
|
pos: usize,
|
||||||
Err(_) => println!("{:?}", env),
|
ctx: &Context<'_>,
|
||||||
}
|
) -> std::result::Result<(usize, Vec<Pair>), ReadlineError> {
|
||||||
|
self.completer.complete(line, pos, ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_fs_state(wasi_state: &wasmer_wasi::state::WasiState) {
|
impl Hinter for MyHelper {
|
||||||
let wasi_fs = &wasi_state.fs;
|
fn hint(&self, line: &str, pos: usize, ctx: &Context<'_>) -> Option<String> {
|
||||||
|
self.hinter.hint(line, pos, ctx)
|
||||||
println!("preopened file descriptors:\n{:?}\n", wasi_fs.preopen_fds);
|
}
|
||||||
|
}
|
||||||
println!("name map:");
|
|
||||||
for (name, inode) in &wasi_fs.name_map {
|
impl Highlighter for MyHelper {
|
||||||
println!("{} - {:?}", name, inode);
|
fn highlight<'l>(&self, line: &'l str, pos: usize) -> Cow<'l, str> {
|
||||||
}
|
self.highlighter.highlight(line, pos)
|
||||||
|
}
|
||||||
println!("\nfile descriptors map:");
|
|
||||||
for (id, fd) in &wasi_fs.fd_map {
|
fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
|
||||||
println!("{} - {:?}", id, fd);
|
&'s self,
|
||||||
}
|
prompt: &'p str,
|
||||||
|
default: bool,
|
||||||
println!("\norphan file descriptors:");
|
) -> Cow<'b, str> {
|
||||||
for (fd, inode) in &wasi_fs.orphan_fds {
|
if default {
|
||||||
println!("{:?} - {:?}", fd, inode);
|
Borrowed(&self.colored_prompt)
|
||||||
}
|
} else {
|
||||||
|
Borrowed(prompt)
|
||||||
println!("\ninodes:");
|
}
|
||||||
for (id, inode) in wasi_fs.inodes.iter().enumerate() {
|
}
|
||||||
println!("{}: {:?}", id, inode);
|
|
||||||
|
fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
|
||||||
|
Owned("\x1b[1m".to_owned() + hint + "\x1b[m")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn highlight_char(&self, line: &str, pos: usize) -> bool {
|
||||||
|
self.highlighter.highlight_char(line, pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Validator for MyHelper {
|
||||||
|
fn validate(
|
||||||
|
&self,
|
||||||
|
ctx: &mut validate::ValidationContext<'_>,
|
||||||
|
) -> rustyline::Result<validate::ValidationResult> {
|
||||||
|
self.validator.validate(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn validate_while_typing(&self) -> bool {
|
||||||
|
self.validator.validate_while_typing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
200
tools/repl/src/repl.rs
Normal file
200
tools/repl/src/repl.rs
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 Fluence Labs Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::Result;
|
||||||
|
|
||||||
|
use fluence_app_service::AppService;
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
macro_rules! next_argument {
|
||||||
|
($arg_name:ident, $args:ident, $error_msg:expr) => {
|
||||||
|
let $arg_name = if let Some($arg_name) = $args.next() {
|
||||||
|
$arg_name
|
||||||
|
} else {
|
||||||
|
println!($error_msg);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) struct REPL {
|
||||||
|
app_service: AppService,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl REPL {
|
||||||
|
pub fn new<S: Into<PathBuf>>(config_file_path: Option<S>) -> Result<Self> {
|
||||||
|
let app_service = Self::create_app_service(config_file_path)?;
|
||||||
|
Ok(Self { app_service })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn execute<'a>(&mut self, mut args: impl Iterator<Item = &'a str>) {
|
||||||
|
match args.next() {
|
||||||
|
Some("new") => {
|
||||||
|
match Self::create_app_service(args.next()) {
|
||||||
|
Ok(service) => self.app_service = service,
|
||||||
|
Err(e) => println!("failed to create a new application service: {}", e),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Some("load") => {
|
||||||
|
next_argument!(module_name, args, "Module name should be specified");
|
||||||
|
next_argument!(module_path, args, "Module path should be specified");
|
||||||
|
|
||||||
|
let wasm_bytes = fs::read(module_path);
|
||||||
|
if let Err(e) = wasm_bytes {
|
||||||
|
println!("failed to read wasm module: {}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result_msg = match self
|
||||||
|
.app_service
|
||||||
|
.load_module::<String, fluence_app_service::ModuleConfig>(
|
||||||
|
module_name.into(),
|
||||||
|
&wasm_bytes.unwrap(),
|
||||||
|
None,
|
||||||
|
) {
|
||||||
|
Ok(_) => "module successfully loaded into App service".to_string(),
|
||||||
|
Err(e) => format!("module loaded failed with: {:?}", e),
|
||||||
|
};
|
||||||
|
println!("{}", result_msg);
|
||||||
|
}
|
||||||
|
Some("unload") => {
|
||||||
|
next_argument!(module_name, args, "Module name should be specified");
|
||||||
|
|
||||||
|
let result_msg = match self.app_service.unload_module(module_name) {
|
||||||
|
Ok(_) => "module successfully unloaded from App service".to_string(),
|
||||||
|
Err(e) => format!("module unloaded failed with: {:?}", e),
|
||||||
|
};
|
||||||
|
println!("{}", result_msg);
|
||||||
|
}
|
||||||
|
Some("call") => {
|
||||||
|
next_argument!(module_name, args, "Module name should be specified");
|
||||||
|
next_argument!(func_name, args, "Function name should be specified");
|
||||||
|
|
||||||
|
let module_arg: String = args.collect();
|
||||||
|
let module_arg: serde_json::Value = match serde_json::from_str(&module_arg) {
|
||||||
|
Ok(module_arg) => module_arg,
|
||||||
|
Err(e) => {
|
||||||
|
println!("incorrect arguments {}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = match self.app_service.call(module_name, func_name, module_arg) {
|
||||||
|
Ok(result) => format!("result: {:?}", result),
|
||||||
|
Err(e) => format!("execution failed with {:?}", e),
|
||||||
|
};
|
||||||
|
println!("{}", result);
|
||||||
|
}
|
||||||
|
Some("envs") => {
|
||||||
|
next_argument!(module_name, args, "Module name should be specified");
|
||||||
|
match self.app_service.get_wasi_state(module_name) {
|
||||||
|
Ok(wasi_state) => Self::print_envs(wasi_state),
|
||||||
|
Err(e) => println!("{}", e),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Some("fs") => {
|
||||||
|
next_argument!(module_name, args, "Module name should be specified");
|
||||||
|
match self.app_service.get_wasi_state(module_name) {
|
||||||
|
Ok(wasi_state) => Self::print_fs_state(wasi_state),
|
||||||
|
Err(e) => println!("{}", e),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Some("interface") => {
|
||||||
|
let interface = self.app_service.get_interface();
|
||||||
|
println!("application service interface:\n{}", interface);
|
||||||
|
}
|
||||||
|
Some("h") | Some("help") | None => {
|
||||||
|
println!(
|
||||||
|
"Enter:\n\
|
||||||
|
new [config_path] - to create a new AppService (current will be removed)\n\
|
||||||
|
load <module_name> <module_path> - to load a new Wasm module into App service\n\
|
||||||
|
unload <module_name> - to unload Wasm module from AppService\n\
|
||||||
|
call <module_name> <func_name> [args] - to call function with func_name of module with module_name\n\
|
||||||
|
interface - to print public interface of current AppService\n\
|
||||||
|
envs <module_name> - to print environment variables of module with module_name\n\
|
||||||
|
fs <module_name> - to print filesystem state of module with module_name\n\
|
||||||
|
h/help - to print this message\n\
|
||||||
|
Ctrl-C - to exit"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
println!("unsupported command");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_app_service<S: Into<PathBuf>>(config_file_path: Option<S>) -> Result<AppService> {
|
||||||
|
let tmp_path: String = std::env::temp_dir().to_string_lossy().into();
|
||||||
|
let service_id = uuid::Uuid::new_v4().to_string();
|
||||||
|
|
||||||
|
let app_service = match config_file_path {
|
||||||
|
Some(config_file_path) => {
|
||||||
|
let config_file_path = config_file_path.into();
|
||||||
|
AppService::with_raw_config(config_file_path, &service_id, Some(&tmp_path))
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let mut config: fluence_app_service::RawModulesConfig = <_>::default();
|
||||||
|
config.service_base_dir = Some(tmp_path);
|
||||||
|
|
||||||
|
AppService::new(std::iter::empty(), config, &service_id)
|
||||||
|
}
|
||||||
|
}?;
|
||||||
|
|
||||||
|
println!("app service's created with service id = {}", service_id);
|
||||||
|
|
||||||
|
Ok(app_service)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_envs(wasi_state: &wasmer_wasi::state::WasiState) {
|
||||||
|
let envs = &wasi_state.envs;
|
||||||
|
|
||||||
|
println!("Environment variables:");
|
||||||
|
for env in envs.iter() {
|
||||||
|
match String::from_utf8(env.clone()) {
|
||||||
|
Ok(string) => println!("{}", string),
|
||||||
|
Err(_) => println!("{:?}", env),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_fs_state(wasi_state: &wasmer_wasi::state::WasiState) {
|
||||||
|
let wasi_fs = &wasi_state.fs;
|
||||||
|
|
||||||
|
println!("preopened file descriptors:\n{:?}\n", wasi_fs.preopen_fds);
|
||||||
|
|
||||||
|
println!("name map:");
|
||||||
|
for (name, inode) in &wasi_fs.name_map {
|
||||||
|
println!("{} - {:?}", name, inode);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\nfile descriptors map:");
|
||||||
|
for (id, fd) in &wasi_fs.fd_map {
|
||||||
|
println!("{} - {:?}", id, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\norphan file descriptors:");
|
||||||
|
for (fd, inode) in &wasi_fs.orphan_fds {
|
||||||
|
println!("{:?} - {:?}", fd, inode);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\ninodes:");
|
||||||
|
for (id, inode) in wasi_fs.inodes.iter().enumerate() {
|
||||||
|
println!("{}: {:?}", id, inode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user