diff --git a/.gitignore b/.gitignore index 78cab4f..917e5a2 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ node_modules /artifacts keypair.json *.wasm +logo.svg diff --git a/curl_template/README.md b/curl_template/README.md index 739b676..777e539 100644 --- a/curl_template/README.md +++ b/curl_template/README.md @@ -1,6 +1,6 @@ # Download & return URL via curl -An example repo to kick-off building services on Fluence. +An example to kick-off building services on Fluence. What it does: - exploits `mounted_binaries` to call `/usr/bin/curl` on the host OS @@ -29,7 +29,7 @@ P.S. JSON5 has comments! yaaay! # Call it ```shell -fldist run_air -p air.clj -d '{"service": "e90bfbaf-ede7-4fbe-b45a-6250bf36ed3e"}' +fldist run_air -p request.air -d '{"service": "e90bfbaf-ede7-4fbe-b45a-6250bf36ed3e"}' ``` # Run frontend diff --git a/curl_template/air.clj b/curl_template/request.air similarity index 100% rename from curl_template/air.clj rename to curl_template/request.air diff --git a/url-downloader/README.md b/url-downloader/README.md new file mode 100644 index 0000000..b28a1bd --- /dev/null +++ b/url-downloader/README.md @@ -0,0 +1,14 @@ +# Download file to disk + +Example to show how to work with disk + link several .wasm modules into a service. + +# Build & deploy it +```shell +./deploy.sh +``` + +# Call it +```shell +fldist run_air -p download.air -d '{"service": "08eba00d-ff40-4e38-bbe6-ee3646498400"}' +``` + \ No newline at end of file diff --git a/url-downloader/artifacts/local_storage.json b/url-downloader/artifacts/local_storage.json index abc5f5f..c4c3ad2 100644 --- a/url-downloader/artifacts/local_storage.json +++ b/url-downloader/artifacts/local_storage.json @@ -1 +1,12 @@ -{"name": "local_storage"} +{ + "name": "local_storage", + "preopenedFiles": [ + "/tmp" + ], + "mappedDirs": { + "sites": "/tmp" + }, + "mountedBinaries": { + "curl": "/usr/bin/curl" + } +} diff --git a/url-downloader/compose.air b/url-downloader/compose.air new file mode 100644 index 0000000..b568a53 --- /dev/null +++ b/url-downloader/compose.air @@ -0,0 +1,13 @@ +(xor + (seq + (seq + (seq + (call relay (curl "download") ["https://fluence.network/img/svg/logo_new.svg"] contents) + (call relay (storage "put") ["logo.svg" contents.$.stdout!] ret_code) + ) + (call relay (storage "get") ["logo.svg"] bytes) + ) + (call %init_peer_id% (returnService "run") [ret_code bytes]) + ) + (call %init_peer_id% (returnService "run") [%last_error%]) +) diff --git a/url-downloader/deploy.sh b/url-downloader/deploy.sh index 6df7021..9b42425 100755 --- a/url-downloader/deploy.sh +++ b/url-downloader/deploy.sh @@ -1,7 +1,7 @@ #!/bin/sh -euo pipefail # build wasms -sh build.sh +./build.sh ( cd artifacts diff --git a/url-downloader/deploy_separate.sh b/url-downloader/deploy_separate.sh new file mode 100755 index 0000000..9753639 --- /dev/null +++ b/url-downloader/deploy_separate.sh @@ -0,0 +1,15 @@ +#!/bin/sh -euo pipefail + +./build.sh + +echo "Deploying storage" +( + cd artifacts + fldist new_service --name "local_storage" --modules local_storage.wasm:local_storage.json +) + +echo "\n\nDeploying curl" +( + cd artifacts + fldist new_service --name "curl_adapter" --modules curl_adapter.wasm:curl_adapter.json +) diff --git a/url-downloader/download.air b/url-downloader/download.air new file mode 100644 index 0000000..d8a1334 --- /dev/null +++ b/url-downloader/download.air @@ -0,0 +1,10 @@ +(xor + (seq + (seq + (call relay (service "get_n_save") ["https://fluence.network/img/svg/logo_new.svg" "logo.svg"] ret_code) + (call relay (service "load_file") ["logo.svg"] bytes) + ) + (call %init_peer_id% (returnService "run") [ret_code bytes]) + ) + (call %init_peer_id% (returnService "run") [%last_error%]) +) diff --git a/url-downloader/download.clj b/url-downloader/download.clj deleted file mode 100644 index 1ec37b1..0000000 --- a/url-downloader/download.clj +++ /dev/null @@ -1,7 +0,0 @@ -(xor - (seq - (call relay (service "request") ["https://api.duckduckgo.com/?q=homotopy&format=json"] result) - (call %init_peer_id% (returnService "run") [result]) - ) - (call %init_peer_id% (returnService "run") [%last_error%]) -) diff --git a/url-downloader/facade/src/main.rs b/url-downloader/facade/src/main.rs index 1a5e04c..cc76c5d 100644 --- a/url-downloader/facade/src/main.rs +++ b/url-downloader/facade/src/main.rs @@ -26,19 +26,19 @@ pub fn main() { /// Combining of modules: `curl` and `local_storage`. /// Calls `curl` and stores returned result into a file. #[fce] -pub fn get_n_save(url: String, file_name: String) -> i32 { +pub fn get_n_save(url: String, file_name: String) -> String { let result = unsafe { download(url) }; if result.is_success() { log::info!("saving file {}", file_name); - unsafe { file_put(file_name, result.stdout) }; + unsafe { file_put(file_name, result.stdout) } } else { - log::error!("download failed: {:#?}", result.as_std()) + log::error!("download failed: {:#?}", result.as_std()); + format!("download failed: {:#?}", result.as_std()) } - - result.ret_code } #[fce] +/// Loads file from disk and returns its content as base64 pub fn load_file(file_name: String) -> String { let bytes = unsafe { file_get(file_name) }; base64::encode(bytes) diff --git a/url-downloader/local_storage/src/main.rs b/url-downloader/local_storage/src/main.rs index 015ddc9..0f50966 100644 --- a/url-downloader/local_storage/src/main.rs +++ b/url-downloader/local_storage/src/main.rs @@ -17,7 +17,7 @@ use std::fs; use fluence::fce; use fluence::WasmLoggerBuilder; -use std::path::PathBuf; +use std::path::Path; const SITES_DIR: &str = "/sites/"; @@ -28,14 +28,14 @@ pub fn main() { /// You can read or write files from the file system if there is permission to use directories described in `Config.toml`. #[fce] -pub fn put(name: String, file_content: Vec) -> String { - log::info!("put called with file name {}", name); +pub fn put(file_name: String, file_content: Vec) -> String { + log::info!("put called with file name {}", file_name); - let rpc_tmp_filepath = format!("{}{}", SITES_DIR, name); + let path = Path::new(SITES_DIR).join(file_name); - let result = fs::write(PathBuf::from(rpc_tmp_filepath.clone()), file_content); + let result = fs::write(&path, file_content); if let Err(e) = result { - return format!("file can't be written: {}", e); + return format!("file {} can't be written: {}", path.to_string_lossy(), e); } String::from("Ok") @@ -45,7 +45,7 @@ pub fn put(name: String, file_content: Vec) -> String { pub fn get(file_name: String) -> Vec { log::info!("get called with file name: {}", file_name); - let tmp_filepath = format!("{}{}", SITES_DIR, file_name); + let path = Path::new(SITES_DIR).join(file_name); - fs::read(tmp_filepath).unwrap_or_else(|_| b"error while reading file".to_vec()) + fs::read(&path).unwrap_or_else(|err| format!("error while reading file {}: {}", path.to_string_lossy(), err).into_bytes()) } diff --git a/url-downloader/repl_config.toml b/url-downloader/repl_config.toml new file mode 100644 index 0000000..6701450 --- /dev/null +++ b/url-downloader/repl_config.toml @@ -0,0 +1,21 @@ +modules_dir = "artifacts/" + +[[module]] +name = "local_storage" +logger_enabled = true + +[module.wasi] +preopened_files = ["."] +# this is where files will be stored +mapped_dirs = { "sites" = "." } + +[[module]] +name = "curl_adapter" +logger_enabled = true + +[module.mounted_binaries] +curl = "/usr/bin/curl" + +[[module]] +name = "facade" +logger_enabled = true