Merge pull request #42 from uqbar-dao/hf/start-from-commandline

start from commandline
This commit is contained in:
hosted-fornet 2023-12-05 09:37:35 -08:00 committed by GitHub
commit 989645c419
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 1625 additions and 215 deletions

72
Cargo.lock generated
View File

@ -686,18 +686,19 @@ dependencies = [
[[package]]
name = "clap"
version = "4.4.8"
version = "4.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64"
checksum = "41fffed7514f420abec6d183b1d3acfd9099c79c3a10a06ade4f8203f1411272"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.4.8"
version = "4.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc"
checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1"
dependencies = [
"anstream",
"anstyle",
@ -705,6 +706,18 @@ dependencies = [
"strsim 0.10.0",
]
[[package]]
name = "clap_derive"
version = "4.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.32",
]
[[package]]
name = "clap_lex"
version = "0.6.0"
@ -1712,7 +1725,7 @@ dependencies = [
"futures-timer",
"futures-util",
"hashers",
"http",
"http 0.2.9",
"instant",
"jsonwebtoken",
"once_cell",
@ -2141,7 +2154,7 @@ dependencies = [
"futures-core",
"futures-sink",
"futures-util",
"http",
"http 0.2.9",
"indexmap 1.9.3",
"slab",
"tokio",
@ -2192,7 +2205,7 @@ dependencies = [
"base64 0.21.4",
"bytes",
"headers-core",
"http",
"http 0.2.9",
"httpdate",
"mime",
"sha1",
@ -2204,7 +2217,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
dependencies = [
"http",
"http 0.2.9",
]
[[package]]
@ -2276,6 +2289,17 @@ dependencies = [
"itoa",
]
[[package]]
name = "http"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.5"
@ -2283,7 +2307,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
dependencies = [
"bytes",
"http",
"http 0.2.9",
"pin-project-lite",
]
@ -2310,7 +2334,7 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http 0.2.9",
"http-body",
"httparse",
"httpdate",
@ -2330,7 +2354,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97"
dependencies = [
"futures-util",
"http",
"http 0.2.9",
"hyper",
"rustls",
"tokio",
@ -2889,7 +2913,7 @@ dependencies = [
"bytes",
"encoding_rs",
"futures-util",
"http",
"http 0.2.9",
"httparse",
"log",
"memchr",
@ -3546,7 +3570,7 @@ dependencies = [
"dns-lookup",
"futures-core",
"futures-util",
"http",
"http 0.2.9",
"hyper",
"hyper-system-resolver",
"pin-project-lite",
@ -3724,7 +3748,7 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http 0.2.9",
"http-body",
"hyper",
"hyper-rustls",
@ -3871,7 +3895,7 @@ dependencies = [
"bytes",
"crc32fast",
"futures",
"http",
"http 0.2.9",
"hyper",
"hyper-tls",
"lazy_static",
@ -3929,7 +3953,7 @@ dependencies = [
"futures",
"hex",
"hmac 0.11.0",
"http",
"http 0.2.9",
"hyper",
"log",
"md-5 0.9.1",
@ -4969,7 +4993,7 @@ dependencies = [
"base64 0.13.1",
"byteorder",
"bytes",
"http",
"http 0.2.9",
"httparse",
"log",
"rand",
@ -4988,7 +5012,7 @@ dependencies = [
"byteorder",
"bytes",
"data-encoding",
"http",
"http 0.2.9",
"httparse",
"log",
"rand",
@ -5121,7 +5145,7 @@ dependencies = [
"hex",
"hkdf",
"hmac 0.12.1",
"http",
"http 0.2.9",
"jwt",
"lazy_static",
"log",
@ -5159,13 +5183,17 @@ dependencies = [
[[package]]
name = "uqbar_process_lib"
version = "0.2.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=e53c124#e53c124ec95ef99c06d201d4d08dada8ec691d29"
version = "0.3.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=77ebb26#77ebb261bf74f2183fb81856ce9a6b66b8360a6d"
dependencies = [
"anyhow",
"bincode",
"http 1.0.0",
"rand",
"serde",
"serde_json",
"thiserror",
"url",
"wit-bindgen",
]
@ -5253,7 +5281,7 @@ dependencies = [
"futures-channel",
"futures-util",
"headers",
"http",
"http 0.2.9",
"hyper",
"log",
"mime",

View File

@ -1,8 +1,9 @@
[package]
name = "uqbar"
authors = ["UqbarDAO"]
version = "0.4.0"
edition = "2021"
description = "a general-purpose sovereign cloud computing platform"
description = "A general-purpose sovereign cloud computing platform"
homepage = "https://uqbar.network"
repository = "https://github.com/uqbar-dao/uqbar"
@ -13,6 +14,9 @@ sha2 = "0.10"
walkdir = "2.4"
zip = "0.6"
[features]
llm = []
simulation-mode = []
[dependencies]
aes-gcm = "0.10.2"
@ -26,6 +30,7 @@ bytes = "1.4.0"
cap-std = "2.0.0"
chacha20poly1305 = "0.10.1"
chrono = "0.4.31"
clap = { version = "4.4", features = ["derive"] }
crossterm = { version = "0.26.1", features = ["event-stream", "bracketed-paste"] }
dashmap = "5.5.3"
digest = "0.10"
@ -44,6 +49,7 @@ http = "0.2.9"
jwt = "0.16"
lazy_static = "1.4.0"
log = "*"
lru-mem = "0.3.0"
nohash-hasher = "0.2.0"
num-traits = "0.2"
open = "5.0.0"
@ -66,14 +72,9 @@ thiserror = "1.0"
tokio = { version = "1.28", features = ["fs", "macros", "rt-multi-thread", "sync"] }
tokio-tungstenite = "0.20.1"
url = "2.4.1"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "e53c124" }
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "77ebb26" }
uuid = { version = "1.1.2", features = ["serde", "v4"] }
warp = "0.3.5"
wasmtime = "14.0.4"
wasmtime-wasi = "14.0.4"
zip = "0.6"
lru-mem = "0.3.0"
clap = "4.4.8"
[features]
llm = []

View File

@ -31,7 +31,7 @@ Get an eth-sepolia-rpc API key and pass that as an argument. You can get one for
Make sure not to use the same home directory for two nodes at once! You can use any name for the home directory: here we just use `home`.
```bash
cargo +nightly run --release home --rpc wss://eth-sepolia.g.alchemy.com/v2/<your-api-key>
cargo +nightly run --release -- home --rpc wss://eth-sepolia.g.alchemy.com/v2/<your-api-key>
```
On boot you will be prompted to navigate to `localhost:8080`. Make sure your ETH wallet is connected to the Sepolia test network. Login should be straightforward, just submit the transactions and follow the flow. If you want to register a new ID you will either need [Sepolia testnet tokens](https://www.infura.io/faucet/sepolia) or an invite code.

View File

@ -104,19 +104,23 @@ fn handle_message(our: &Address, db_to_process: &mut DbToProcess) -> anyhow::Res
.send_and_await_response(15)??;
// (2)
let vfs_read = wit::get_capability(&vfs_address, &make_vfs_cap("read", &vfs_drive))
.ok_or(anyhow::anyhow!(
"New failed: no vfs 'read' capability found"
))?;
let vfs_write =
wit::get_capability(&vfs_address, &make_vfs_cap("write", &vfs_drive)).ok_or(
anyhow::anyhow!("New failed: no vfs 'write' capability found"),
)?;
let vfs_read = wit::get_capability(
&vfs_address,
&make_vfs_cap("read", &vfs_drive)
).ok_or(anyhow::anyhow!("New failed: no vfs 'read' capability found"))?;
let vfs_write = wit::get_capability(
&vfs_address,
&make_vfs_cap("write", &vfs_drive)
).ok_or(anyhow::anyhow!("New failed: no vfs 'write' capability found"))?;
let messaging = wit::get_capability(
&source,
&"\"messaging\"".into(),
).ok_or(anyhow::anyhow!("New failed: no source 'messaging' capability found"))?;
let spawned_process_id = match wit::spawn(
None,
"/key_value_worker.wasm",
&wit::OnPanic::None, // TODO: notify us
&wit::Capabilities::Some(vec![vfs_read, vfs_write]),
&wit::Capabilities::Some(vec![vfs_read, vfs_write, messaging]),
false, // not public
) {
Ok(spawned_process_id) => spawned_process_id,

View File

@ -3,7 +3,7 @@ use std::collections::HashMap;
use redb::ReadableTable;
use serde::{Deserialize, Serialize};
use uqbar_process_lib::{Address, ProcessId, Response};
use uqbar_process_lib::{Address, create_capability, ProcessId, Response};
use uqbar_process_lib::uqbar::process::standard as wit;
wit_bindgen::generate!({
@ -178,6 +178,12 @@ impl Guest for Component {
let our = Address::from_str(&our).unwrap();
let mut db_handle: Option<redb::Database> = None;
let vfs_address = ProcessId::from_str("vfs:sys:uqbar").unwrap();
create_capability(
&vfs_address,
&"\"messaging\"".into(),
);
loop {
match handle_message(&our, &mut db_handle) {
Ok(()) => {},

View File

@ -8,12 +8,6 @@ version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bincode"
version = "1.3.3"
@ -29,12 +23,6 @@ version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.5.0"
@ -156,21 +144,6 @@ version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [
"autocfg",
]
[[package]]
name = "paste"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "percent-encoding"
version = "2.3.1"
@ -231,28 +204,6 @@ dependencies = [
"getrandom",
]
[[package]]
name = "rmp"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20"
dependencies = [
"byteorder",
"num-traits",
"paste",
]
[[package]]
name = "rmp-serde"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a"
dependencies = [
"byteorder",
"rmp",
"serde",
]
[[package]]
name = "ryu"
version = "1.0.15"
@ -317,7 +268,6 @@ version = "0.1.0"
dependencies = [
"anyhow",
"bincode",
"rmp-serde",
"serde",
"serde_json",
"thiserror",

View File

@ -13,7 +13,6 @@ lto = true
[dependencies]
anyhow = "1.0"
bincode = "1.3.3"
rmp-serde = "1.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"

View File

@ -124,7 +124,7 @@ fn handle_message (
let spawned_process_id = match wit::spawn(
None,
"/sqlite_worker.wasm",
&wit::OnPanic::None,
&wit::OnPanic::None,
&wit::Capabilities::Some(vec![vfs_read, vfs_write, msg_cap]),
false, // not public
) {
@ -152,7 +152,7 @@ fn handle_message (
.ipc(ipc)
.send()?;
},
sq::SqliteMessage::Write { ref db, ref statement, ref tx_id } => {
sq::SqliteMessage::Write { ref db, ref statement, .. } => {
let first_word = statement
.split_whitespace()
.next()
@ -174,7 +174,7 @@ fn handle_message (
}
forward_if_have_cap(our, "read", db, ipc, db_to_process)?;
},
sq::SqliteMessage::Commit { ref db, ref tx_id } => {
sq::SqliteMessage::Commit { ref db, .. } => {
forward_if_have_cap(our, "write", db, ipc, db_to_process)?;
},
}

View File

@ -8,7 +8,7 @@ pub enum SqliteMessage {
Commit { db: String, tx_id: u64 },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum SqlValue {
Integer(i64),
Real(f64),
@ -18,16 +18,6 @@ pub enum SqlValue {
Null,
}
pub trait Deserializable: for<'de> Deserialize<'de> + Sized {
fn from_serialized(bytes: &[u8]) -> Result<Self, rmp_serde::decode::Error> {
rmp_serde::from_slice(bytes)
}
}
impl Deserializable for Vec<SqlValue> {}
impl Deserializable for Vec<Vec<SqlValue>> {}
#[derive(Debug, Serialize, Deserialize, thiserror::Error)]
pub enum SqliteError {
#[error("DbDoesNotExist")]

View File

@ -25,12 +25,6 @@ version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "base64"
version = "0.13.1"
@ -52,12 +46,6 @@ version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.5.0"
@ -223,27 +211,12 @@ version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "paste"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "percent-encoding"
version = "2.3.1"
@ -310,28 +283,6 @@ dependencies = [
"getrandom",
]
[[package]]
name = "rmp"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20"
dependencies = [
"byteorder",
"num-traits",
"paste",
]
[[package]]
name = "rmp-serde"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a"
dependencies = [
"byteorder",
"rmp",
"serde",
]
[[package]]
name = "rusqlite"
version = "0.29.0"
@ -410,7 +361,6 @@ dependencies = [
"anyhow",
"base64",
"bincode",
"rmp-serde",
"rusqlite",
"serde",
"serde_json",

View File

@ -12,13 +12,12 @@ lto = true
[dependencies]
anyhow = "1.0"
base64 = "0.13"
bincode = "1.3.3"
rmp-serde = "1.1"
rusqlite = { git = "https://github.com/uqbar-dao/rusqlite", rev = "8fb20a9", features = ["bundled", "wasm32-wasi-vfs"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"
base64 = "0.13"
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "7e4065c" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" }

View File

@ -4,7 +4,7 @@ use std::ffi::CString;
use rusqlite::{types::FromSql, types::FromSqlError, types::ToSql, types::ValueRef};
use std::collections::HashMap;
use uqbar_process_lib::{Address, ProcessId, Response, create_capability};
use uqbar_process_lib::{Address, create_capability, ProcessId, Response};
use uqbar_process_lib::uqbar::process::standard as wit;
@ -519,7 +519,7 @@ fn handle_message(
Ok(map)
})?
.collect::<Result<Vec<_>, _>>()?;
let results = serde_json::json!(results).to_string();
let results_bytes = results.as_bytes().to_vec();
@ -548,7 +548,6 @@ impl Guest for Component {
let mut txs: HashMap<u64, Vec<(String, Vec<sq::SqlValue>)>> = HashMap::new();
let vfs_address = ProcessId::from_str("vfs:sys:uqbar").unwrap();
create_capability(
&vfs_address,
&"\"messaging\"".into(),

View File

@ -0,0 +1,15 @@
[
{
"process_name": "tester",
"process_wasm_path": "/tester.wasm",
"on_panic": "Restart",
"request_networking": true,
"request_messaging": [
"net:sys:uqbar"
],
"grant_messaging": [
"vfs:sys:uqbar"
],
"public": true
}
]

View File

@ -0,0 +1,5 @@
{
"package": "tester",
"publisher": "uqbar",
"version": [0, 1, 0]
}

View File

@ -0,0 +1,3 @@
# This file is automatically generated by cargo-component.
# It is not intended for manual editing.
version = 1

411
modules/tester/test_runner/Cargo.lock generated Normal file
View File

@ -0,0 +1,411 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "bitflags"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "getrandom"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "id-arena"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
[[package]]
name = "indexmap"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
dependencies = [
"equivalent",
"hashbrown",
"serde",
]
[[package]]
name = "itoa"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]]
name = "leb128"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]]
name = "libc"
version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "ryu"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "semver"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
[[package]]
name = "serde"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "smallvec"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]]
name = "spdx"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b19b32ed6d899ab23174302ff105c1577e45a06b08d4fe0a9dd13ce804bbbf71"
dependencies = [
"smallvec",
]
[[package]]
name = "syn"
version = "2.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "test_runner"
version = "0.1.0"
dependencies = [
"anyhow",
"bincode",
"serde",
"serde_json",
"thiserror",
"uqbar_process_lib",
"wit-bindgen",
]
[[package]]
name = "thiserror"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "unicode-segmentation"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
name = "unicode-xid"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "uqbar_process_lib"
version = "0.2.0"
source = "git+https://github.com/uqbar-dao/process_lib?rev=e53c124#e53c124ec95ef99c06d201d4d08dada8ec691d29"
dependencies = [
"anyhow",
"bincode",
"rand",
"serde",
"wit-bindgen",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-encoder"
version = "0.36.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421"
dependencies = [
"leb128",
]
[[package]]
name = "wasm-metadata"
version = "0.10.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f"
dependencies = [
"anyhow",
"indexmap",
"serde",
"serde_derive",
"serde_json",
"spdx",
"wasm-encoder",
"wasmparser",
]
[[package]]
name = "wasmparser"
version = "0.116.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50"
dependencies = [
"indexmap",
"semver",
]
[[package]]
name = "wit-bindgen"
version = "0.13.1"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
dependencies = [
"bitflags",
"wit-bindgen-rust-macro",
]
[[package]]
name = "wit-bindgen-core"
version = "0.13.1"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
dependencies = [
"anyhow",
"wit-component",
"wit-parser",
]
[[package]]
name = "wit-bindgen-rust"
version = "0.13.2"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
dependencies = [
"anyhow",
"heck",
"wasm-metadata",
"wit-bindgen-core",
"wit-component",
]
[[package]]
name = "wit-bindgen-rust-macro"
version = "0.13.1"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
dependencies = [
"anyhow",
"proc-macro2",
"quote",
"syn",
"wit-bindgen-core",
"wit-bindgen-rust",
"wit-component",
]
[[package]]
name = "wit-component"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e"
dependencies = [
"anyhow",
"bitflags",
"indexmap",
"log",
"serde",
"serde_derive",
"serde_json",
"wasm-encoder",
"wasm-metadata",
"wasmparser",
"wit-parser",
]
[[package]]
name = "wit-parser"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76"
dependencies = [
"anyhow",
"id-arena",
"indexmap",
"log",
"semver",
"serde",
"serde_derive",
"serde_json",
"unicode-xid",
]

View File

@ -0,0 +1,31 @@
[package]
name = "test_runner"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release]
panic = "abort"
opt-level = "s"
lto = true
[dependencies]
anyhow = "1.0"
bincode = "1.3.3"
serde = {version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"
uqbar_process_lib = { git = "https://github.com/uqbar-dao/process_lib", rev = "e53c124" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" }
[lib]
crate-type = ["cdylib"]
[package.metadata.component]
package = "uqbar:process"
[package.metadata.component.target]
path = "wit"
[package.metadata.component.dependencies]

View File

@ -0,0 +1,133 @@
use serde::{Serialize, Deserialize};
use std::collections::{HashMap, HashSet};
use uqbar_process_lib::{Address, ProcessId, Request, Response};
use uqbar_process_lib::kernel_types as kt;
use uqbar_process_lib::uqbar::process::standard as wit;
mod tester_types;
use tester_types as tt;
wit_bindgen::generate!({
path: "../../../wit",
world: "process",
exports: {
world: Component,
},
});
fn make_vfs_address(our: &wit::Address) -> anyhow::Result<Address> {
Ok(wit::Address {
node: our.node.clone(),
process: ProcessId::from_str("vfs:sys:uqbar")?,
})
}
fn handle_message(our: &Address) -> anyhow::Result<()> {
let (source, message) = wit::receive().unwrap();
if our.node != source.node {
return Err(tt::TesterError::RejectForeign.into());
}
match message {
wit::Message::Response(_) => {
return Err(tt::TesterError::UnexpectedResponse.into());
},
wit::Message::Request(wit::Request { ref ipc, .. }) => {
match serde_json::from_slice(ipc)? {
tt::TesterRequest::Run(_) => {
wit::print_to_terminal(0, "test_runner: got Run");
let (_, response) = Request::new()
.target(make_vfs_address(&our)?)?
.ipc_bytes(serde_json::to_vec(&kt::VfsRequest {
drive: "tester:uqbar".into(),
action: kt::VfsAction::GetEntry("/".into()),
})?)
.send_and_await_response(5)??;
let wit::Message::Response((response, _)) = response else { panic!("") };
let kt::VfsResponse::GetEntry { children, .. } =
serde_json::from_slice(&response.ipc)? else { panic!("") };
let mut children: HashSet<_> = children.into_iter().collect();
children.remove("/manifest.json");
children.remove("/metadata.json");
children.remove("/tester.wasm");
children.remove("/test_runner.wasm");
wit::print_to_terminal(0, &format!("test_runner: running {:?}...", children));
for child in &children {
let child_process_id = match wit::spawn(
None,
child,
&wit::OnPanic::None, // TODO: notify us
&wit::Capabilities::All,
false, // not public
) {
Ok(child_process_id) => child_process_id,
Err(e) => {
wit::print_to_terminal(0, &format!("couldn't spawn {}: {}", child, e));
panic!("couldn't spawn"); // TODO
}
};
let (_, response) = Request::new()
.target(Address {
node: our.node.clone(),
process: child_process_id,
})?
.ipc_bytes(ipc.clone())
.send_and_await_response(5)??;
let wit::Message::Response((response, _)) = response else { panic!("") };
match serde_json::from_slice(&response.ipc)? {
tt::TesterResponse::Pass => {},
tt::TesterResponse::GetFullMessage(_) => {},
tt::TesterResponse::Fail { test, file, line, column } => {
fail!(test, file, line, column);
},
}
}
wit::print_to_terminal(0, &format!("test_runner: done running {:?}", children));
Response::new()
.ipc_bytes(serde_json::to_vec(&tt::TesterResponse::Pass).unwrap())
.send()
.unwrap();
},
tt::TesterRequest::KernelMessage(_) | tt::TesterRequest::GetFullMessage(_) => { unimplemented!() },
}
Ok(())
},
}
}
struct Component;
impl Guest for Component {
fn init(our: String) {
wit::print_to_terminal(0, "test_runner: begin");
let our = Address::from_str(&our).unwrap();
wit::create_capability(
&ProcessId::new("vfs", "sys", "uqbar"),
&"\"messaging\"".into(),
);
loop {
match handle_message(&our) {
Ok(()) => {},
Err(e) => {
wit::print_to_terminal(0, format!(
"test_runner: error: {:?}",
e,
).as_str());
fail!("test_runner");
},
};
}
}
}

View File

@ -0,0 +1 @@
../../tester_types.rs

View File

@ -0,0 +1,3 @@
# This file is automatically generated by cargo-component.
# It is not intended for manual editing.
version = 1

411
modules/tester/tester/Cargo.lock generated Normal file
View File

@ -0,0 +1,411 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "bitflags"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "getrandom"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "id-arena"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
[[package]]
name = "indexmap"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [
"equivalent",
"hashbrown",
"serde",
]
[[package]]
name = "itoa"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]]
name = "leb128"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]]
name = "libc"
version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "ryu"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "semver"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
[[package]]
name = "serde"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "smallvec"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]]
name = "spdx"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b19b32ed6d899ab23174302ff105c1577e45a06b08d4fe0a9dd13ce804bbbf71"
dependencies = [
"smallvec",
]
[[package]]
name = "syn"
version = "2.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tester"
version = "0.1.0"
dependencies = [
"anyhow",
"bincode",
"indexmap",
"serde",
"serde_json",
"thiserror",
"uqbar_process_lib",
"wit-bindgen",
]
[[package]]
name = "thiserror"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "unicode-segmentation"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
name = "unicode-xid"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "uqbar_process_lib"
version = "0.2.0"
dependencies = [
"anyhow",
"bincode",
"rand",
"serde",
"wit-bindgen",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-encoder"
version = "0.36.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421"
dependencies = [
"leb128",
]
[[package]]
name = "wasm-metadata"
version = "0.10.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f"
dependencies = [
"anyhow",
"indexmap",
"serde",
"serde_derive",
"serde_json",
"spdx",
"wasm-encoder",
"wasmparser",
]
[[package]]
name = "wasmparser"
version = "0.116.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50"
dependencies = [
"indexmap",
"semver",
]
[[package]]
name = "wit-bindgen"
version = "0.13.1"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
dependencies = [
"bitflags",
"wit-bindgen-rust-macro",
]
[[package]]
name = "wit-bindgen-core"
version = "0.13.1"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
dependencies = [
"anyhow",
"wit-component",
"wit-parser",
]
[[package]]
name = "wit-bindgen-rust"
version = "0.13.2"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
dependencies = [
"anyhow",
"heck",
"wasm-metadata",
"wit-bindgen-core",
"wit-component",
]
[[package]]
name = "wit-bindgen-rust-macro"
version = "0.13.1"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d"
dependencies = [
"anyhow",
"proc-macro2",
"quote",
"syn",
"wit-bindgen-core",
"wit-bindgen-rust",
"wit-component",
]
[[package]]
name = "wit-component"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e"
dependencies = [
"anyhow",
"bitflags",
"indexmap",
"log",
"serde",
"serde_derive",
"serde_json",
"wasm-encoder",
"wasm-metadata",
"wasmparser",
"wit-parser",
]
[[package]]
name = "wit-parser"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76"
dependencies = [
"anyhow",
"id-arena",
"indexmap",
"log",
"semver",
"serde",
"serde_derive",
"serde_json",
"unicode-xid",
]

View File

@ -0,0 +1,33 @@
[package]
name = "tester"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release]
panic = "abort"
opt-level = "s"
lto = true
[dependencies]
anyhow = "1.0"
bincode = "1.3.3"
indexmap = "2.1"
serde = {version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"
uqbar_process_lib = { path = "../../../../process_lib" }
# uqbar_process_lib = { git = "https://github.com/uqbar-dao/process_lib", rev = "9684d33" }
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" }
[lib]
crate-type = ["cdylib"]
[package.metadata.component]
package = "uqbar:process"
[package.metadata.component.target]
path = "wit"
[package.metadata.component.dependencies]

View File

@ -0,0 +1,130 @@
use indexmap::map::IndexMap;
use uqbar_process_lib::{Address, ProcessId, Request, Response};
use uqbar_process_lib::kernel_types as kt;
use uqbar_process_lib::uqbar::process::standard as wit;
mod tester_types;
use tester_types as tt;
wit_bindgen::generate!({
path: "../../../wit",
world: "process",
exports: {
world: Component,
},
});
type Messages = IndexMap<kt::Message, tt::KernelMessage>;
fn make_vfs_address(our: &wit::Address) -> anyhow::Result<Address> {
Ok(wit::Address {
node: our.node.clone(),
process: ProcessId::from_str("vfs:sys:uqbar")?,
})
}
fn handle_message(
our: &Address,
_messages: &mut Messages,
node_names: &mut Vec<String>,
) -> anyhow::Result<()> {
let (source, message) = wit::receive().unwrap();
match message {
wit::Message::Response((wit::Response { ipc, .. }, _)) => {
match serde_json::from_slice(&ipc)? {
tt::TesterResponse::Pass | tt::TesterResponse::Fail { .. } => {
if (source.process.package_name != "tester")
| (source.process.publisher_node != "uqbar") {
return Err(tt::TesterError::UnexpectedResponse.into());
}
Response::new()
.ipc_bytes(ipc)
.send()
.unwrap();
},
tt::TesterResponse::GetFullMessage(_) => { unimplemented!() }
}
Ok(())
},
wit::Message::Request(wit::Request { ipc, .. }) => {
match serde_json::from_slice(&ipc)? {
tt::TesterRequest::Run(input_node_names) => {
wit::print_to_terminal(0, "tester: got Run");
assert!(input_node_names.len() >= 1);
*node_names = input_node_names.clone();
if our.node != node_names[0] {
Response::new()
.ipc_bytes(serde_json::to_vec(&tt::TesterResponse::Pass).unwrap())
.send()
.unwrap();
} else {
// we are master node
let child = "/test_runner.wasm";
let child_process_id = match wit::spawn(
None,
child,
&wit::OnPanic::None, // TODO: notify us
&wit::Capabilities::All,
false, // not public
) {
Ok(child_process_id) => child_process_id,
Err(e) => {
wit::print_to_terminal(0, &format!("couldn't spawn {}: {}", child, e));
panic!("couldn't spawn"); // TODO
}
};
Request::new()
.target(Address {
node: our.node.clone(),
process: child_process_id,
})?
.ipc_bytes(ipc)
.expects_response(15)
.send()?;
}
},
tt::TesterRequest::KernelMessage(_) | tt::TesterRequest::GetFullMessage(_) => { unimplemented!() },
}
Ok(())
},
}
}
struct Component;
impl Guest for Component {
fn init(our: String) {
wit::print_to_terminal(0, "tester: begin");
let our = Address::from_str(&our).unwrap();
let mut messages: Messages = IndexMap::new();
let mut node_names: Vec<String> = Vec::new();
// orchestrate tests using external scripts
// -> must give drive cap to rpc
let drive_cap = wit::get_capability(
&make_vfs_address(&our).unwrap(),
&serde_json::to_string(&serde_json::json!({
"kind": "write",
"drive": "tester:uqbar",
})).unwrap()
).unwrap();
wit::share_capability(&ProcessId::from_str("http_server:sys:uqbar").unwrap(), &drive_cap);
loop {
match handle_message(&our, &mut messages, &mut node_names) {
Ok(()) => {},
Err(e) => {
wit::print_to_terminal(0, format!(
"tester: error: {:?}",
e,
).as_str());
fail!("tester");
},
};
}
}
}

View File

@ -0,0 +1 @@
../../tester_types.rs

View File

@ -0,0 +1,77 @@
use serde::{Serialize, Deserialize};
use uqbar_process_lib::Response;
use uqbar_process_lib::kernel_types as kt;
// use uqbar_process_lib::uqbar::process::standard as wit;
type Rsvp = Option<kt::Address>;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct KernelMessage {
pub id: u64,
pub source: kt::Address,
pub target: kt::Address,
pub rsvp: Rsvp,
pub message: kt::Message,
pub payload: Option<kt::Payload>,
pub signed_capabilities: Option<Vec<kt::SignedCapability>>,
}
#[derive(Debug, Serialize, Deserialize)]
pub enum TesterRequest {
Run(Vec<String>),
KernelMessage(KernelMessage),
GetFullMessage(kt::Message),
}
#[derive(Debug, Serialize, Deserialize)]
pub struct TesterFail {
pub test: String,
pub file: String,
pub line: u32,
pub column: u32,
}
#[derive(Debug, Serialize, Deserialize)]
pub enum TesterResponse {
Pass,
Fail { test: String, file: String, line: u32, column: u32 },
GetFullMessage(Option<KernelMessage>),
}
#[derive(Debug, Serialize, Deserialize, thiserror::Error)]
pub enum TesterError {
#[error("RejectForeign")]
RejectForeign,
#[error("UnexpectedResponse")]
UnexpectedResponse,
#[error("FAIL {test} {message}")]
Fail { test: String, message: String },
}
#[macro_export]
macro_rules! fail {
($test:expr) => {
Response::new()
.ipc_bytes(serde_json::to_vec(&tt::TesterResponse::Fail {
test: $test.into(),
file: file!().into(),
line: line!(),
column: column!(),
}).unwrap())
.send()
.unwrap();
};
($test:expr, $file:expr, $line:expr, $column:expr) => {
Response::new()
.ipc_bytes(serde_json::to_vec(&tt::TesterResponse::Fail {
test: $test.into(),
file: $file.into(),
line: $line,
column: $column,
}).unwrap())
.send()
.unwrap();
panic!("");
};
}

View File

@ -175,6 +175,14 @@ async fn bootstrap(
let mut vfs_messages = Vec::new();
for (package_name, mut package) in packages {
// special case tester: only load it in if in simulation mode
if package_name == "tester" {
#[cfg(not(feature = "simulation-mode"))]
continue;
#[cfg(feature = "simulation-mode")]
{}
}
println!("fs: handling package {package_name}...\r");
// get and read metadata.json
let Ok(mut package_metadata_zip) = package.by_name("metadata.json") else {
@ -390,6 +398,7 @@ async fn bootstrap(
.write(kernel_process_id, &serialized_process_map)
.await;
}
Ok(vfs_messages)
}

View File

@ -753,6 +753,9 @@ pub async fn kernel(
.await
.expect("fatal: kernel event loop died");
#[cfg(feature = "simulation-mode")]
let tester_process_id = t::ProcessId::new(Some("tester"), "tester", "uqbar");
// main event loop
loop {
tokio::select! {
@ -924,6 +927,7 @@ pub async fn kernel(
content: format!("event loop: got message: {}", kernel_message)
}
).await;
if our.name != kernel_message.target.node {
send_to_net.send(kernel_message).await.expect("fatal: net module died");
} else if kernel_message.target.process.process() == "kernel" {

View File

@ -2,7 +2,10 @@
use crate::types::*;
use anyhow::Result;
use clap::{arg, Command};
use clap::{arg, value_parser, Command};
use ring::rand::SystemRandom;
use ring::signature;
use ring::signature::KeyPair;
use std::env;
use std::sync::Arc;
use tokio::sync::{mpsc, oneshot};
@ -44,29 +47,112 @@ const VERSION: &str = env!("CARGO_PKG_VERSION");
/// such that only their routers can ever see their physical networking details.
const REVEAL_IP: bool = true;
async fn serve_register_fe(
home_directory_path: &str,
our_ip: String,
http_server_port: u16,
rpc_url: String,
) -> (Identity, Keyfile) {
// check if we have keys saved on disk, encrypted
// if so, prompt user for "password" to decrypt with
// once password is received, use to decrypt local keys file,
// and pass the keys into boot process as is done in registration.
// NOTE: when we log in, we MUST check the PKI to make sure our
// information matches what we think it should be. this includes
// username, networking key, and routing info.
// if any do not match, we should prompt user to create a "transaction"
// that updates their PKI info on-chain.
let (kill_tx, kill_rx) = oneshot::channel::<bool>();
let disk_keyfile = match fs::read(format!("{}/.keys", home_directory_path)).await {
Ok(keyfile) => keyfile,
Err(_) => Vec::new(),
};
let (tx, mut rx) = mpsc::channel::<(Identity, Keyfile, Vec<u8>)>(1);
let (our, decoded_keyfile, encoded_keyfile) = tokio::select! {
_ = register::register(tx, kill_rx, our_ip, http_server_port, rpc_url, disk_keyfile) => {
panic!("registration failed")
}
Some((our, decoded_keyfile, encoded_keyfile)) = rx.recv() => {
(our, decoded_keyfile, encoded_keyfile)
}
};
println!(
"saving encrypted networking keys to {}/.keys",
home_directory_path
);
fs::write(format!("{}/.keys", home_directory_path), encoded_keyfile)
.await
.unwrap();
println!("registration complete!");
let _ = kill_tx.send(true);
(our, decoded_keyfile)
}
#[tokio::main]
async fn main() {
let matches = Command::new("Uqbar")
let app = Command::new("Uqbar")
.version(VERSION)
.author("Uqbar DAO: https://github.com/uqbar-dao")
.about("A General Purpose Sovereign Cloud Computing Platform")
.arg(arg!([home] "Path to home directory").required(true))
.arg(arg!(--rpc <WS_URL> "Ethereum RPC endpoint (must be wss://)").required(true))
.arg(arg!(--llm <LLM_URL> "LLM endpoint"))
.get_matches();
let home_directory_path = matches.get_one::<String>("home").unwrap();
let rpc_url = matches.get_one::<String>("rpc").unwrap();
let llm_url = matches.get_one::<String>("llm");
.arg(
arg!(--port <PORT> "First port to try binding")
.default_value("8080")
.value_parser(value_parser!(u16)),
);
#[cfg(not(feature = "simulation-mode"))]
let app = app.arg(arg!(--rpc <WS_URL> "Ethereum RPC endpoint (must be wss://)").required(true));
#[cfg(feature = "simulation-mode")]
let app = app
.arg(arg!(--rpc <WS_URL> "Ethereum RPC endpoint (must be wss://)"))
.arg(arg!(--password <PASSWORD> "Networking password"))
.arg(arg!(--"fake-node-name" <NAME> "Name of fake node to boot"))
.arg(
arg!(--"network-router-port" <PORT> "Network router port")
.default_value("9001")
.value_parser(value_parser!(u16)),
);
#[cfg(feature = "llm")]
let app = app.arg(arg!(--llm <LLM_URL> "LLM endpoint"));
let matches = app.get_matches();
let home_directory_path = matches.get_one::<String>("home").unwrap();
let port = matches.get_one::<u16>("port").unwrap().clone();
#[cfg(not(feature = "simulation-mode"))]
let rpc_url = matches.get_one::<String>("rpc").unwrap();
#[cfg(feature = "simulation-mode")]
let (rpc_url, password, network_router_port, fake_node_name) = (
matches.get_one::<String>("rpc"),
matches.get_one::<String>("password"),
matches
.get_one::<u16>("network-router-port")
.unwrap()
.clone(),
matches.get_one::<String>("fake-node-name"),
);
#[cfg(feature = "llm")]
let llm_url = matches.get_one::<String>("llm").unwrap();
// create home directory if it does not already exist
if let Err(e) = fs::create_dir_all(home_directory_path).await {
panic!("failed to create home directory: {:?}", e);
}
#[cfg(not(feature = "llm"))]
if let Some(llm_url) = llm_url {
panic!("You passed in --llm {:?} but you do not have the llm feature enabled. Please re-run with `--features llm`", llm_url);
}
println!("home at {}\r", home_directory_path);
// kernel receives system messages via this channel, all other modules send messages
let (kernel_message_sender, kernel_message_receiver): (MessageSender, MessageReceiver) =
@ -185,39 +271,111 @@ async fn main() {
}
};
// check if we have keys saved on disk, encrypted
// if so, prompt user for "password" to decrypt with
let http_server_port = http::utils::find_open_port(port).await.unwrap();
println!("runtime bound port {}\r", http_server_port);
println!(
"login or register at http://localhost:{}\r",
http_server_port
);
#[cfg(not(feature = "simulation-mode"))]
let (our, decoded_keyfile) = serve_register_fe(
&home_directory_path,
our_ip.to_string(),
http_server_port.clone(),
rpc_url.clone(),
)
.await;
#[cfg(feature = "simulation-mode")]
let (our, decoded_keyfile) = match fake_node_name {
None => {
match password {
None => match rpc_url {
None => panic!(""),
Some(rpc_url) => {
serve_register_fe(
&home_directory_path,
our_ip.to_string(),
http_server_port.clone(),
rpc_url.clone(),
)
.await
}
},
Some(password) => {
match fs::read(format!("{}/.keys", home_directory_path)).await {
Err(e) => panic!("could not read keyfile: {}", e),
Ok(keyfile) => {
match keygen::decode_keyfile(keyfile, &password) {
Err(e) => panic!("could not decode keyfile: {}", e),
Ok(decoded_keyfile) => {
let our = Identity {
name: decoded_keyfile.username.clone(),
networking_key: format!(
"0x{}",
hex::encode(
decoded_keyfile
.networking_keypair
.public_key()
.as_ref()
)
),
ws_routing: None, // TODO
allowed_routers: decoded_keyfile.routers.clone(),
};
(our, decoded_keyfile)
}
}
}
}
}
}
}
Some(name) => {
let password = match password {
None => "123".to_string(),
Some(password) => password.to_string(),
};
let (pubkey, networking_keypair) = keygen::generate_networking_key();
// once password is received, use to decrypt local keys file,
// and pass the keys into boot process as is done in registration.
let seed = SystemRandom::new();
let mut jwt_secret = [0u8, 32];
ring::rand::SecureRandom::fill(&seed, &mut jwt_secret).unwrap();
// NOTE: when we log in, we MUST check the PKI to make sure our
// information matches what we think it should be. this includes
// username, networking key, and routing info.
// if any do not match, we should prompt user to create a "transaction"
// that updates their PKI info on-chain.
let http_server_port = http::utils::find_open_port(8080).await.unwrap();
println!("login or register at http://localhost:{}", http_server_port);
let (kill_tx, kill_rx) = oneshot::channel::<bool>();
let our = Identity {
name: name.clone(),
networking_key: pubkey,
ws_routing: None,
allowed_routers: vec![],
};
let disk_keyfile = match fs::read(format!("{}/.keys", home_directory_path)).await {
Ok(keyfile) => keyfile,
Err(_) => Vec::new(),
let decoded_keyfile = Keyfile {
username: name.clone(),
routers: vec![],
networking_keypair: signature::Ed25519KeyPair::from_pkcs8(
networking_keypair.as_ref(),
)
.unwrap(),
jwt_secret_bytes: jwt_secret.to_vec(),
file_key: keygen::generate_file_key(),
};
let encoded_keyfile = keygen::encode_keyfile(
password,
name.clone(),
decoded_keyfile.routers.clone(),
networking_keypair,
decoded_keyfile.jwt_secret_bytes.clone(),
decoded_keyfile.file_key.clone(),
);
fs::write(format!("{}/.keys", home_directory_path), encoded_keyfile)
.await
.unwrap();
(our, decoded_keyfile)
}
};
let (tx, mut rx) = mpsc::channel::<(Identity, Keyfile, Vec<u8>)>(1);
let (our, decoded_keyfile, encoded_keyfile) = tokio::select! {
_ = register::register(tx, kill_rx, our_ip.to_string(), http_server_port, rpc_url.clone(), disk_keyfile)
=> panic!("registration failed"),
(our, decoded_keyfile, encoded_keyfile) = async {
rx.recv().await.expect("registration failed")
} => (our, decoded_keyfile, encoded_keyfile),
};
fs::write(format!("{}/.keys", home_directory_path), encoded_keyfile)
.await
.unwrap();
// the boolean flag determines whether the runtime module is *public* or not,
// where public means that any process can always message it.
#[allow(unused_mut)]
@ -255,16 +413,11 @@ async fn main() {
];
#[cfg(feature = "llm")]
{
if llm_url.is_none() {
panic!("You did not pass in --llm <LLM_URL> but you have the llm feature enabled. Please re-run with `--llm <LLM_URL>`");
}
runtime_extensions.push((
ProcessId::new(Some("llm"), "sys", "uqbar"), // TODO llm:extensions:uqbar ?
llm_sender,
true,
));
}
runtime_extensions.push((
ProcessId::new(Some("llm"), "sys", "uqbar"), // TODO llm:extensions:uqbar ?
llm_sender,
true,
));
let (kernel_process_map, manifest, vfs_messages) = filesystem::load_fs(
our.name.clone(),
@ -276,8 +429,6 @@ async fn main() {
.await
.expect("fs load failed!");
let _ = kill_tx.send(true);
/*
* the kernel module will handle our userspace processes and receives
* all "messages", the basic message format for uqbar.
@ -301,6 +452,7 @@ async fn main() {
net_message_sender.clone(),
runtime_extensions,
));
#[cfg(not(feature = "simulation-mode"))]
tasks.spawn(net::networking(
our.clone(),
our_ip.to_string(),
@ -312,6 +464,13 @@ async fn main() {
net_message_receiver,
REVEAL_IP,
));
#[cfg(feature = "simulation-mode")]
tasks.spawn(net::mock_client(
network_router_port,
our.name.clone(),
kernel_message_sender.clone(),
net_message_receiver,
));
tasks.spawn(filesystem::fs_sender(
our.name.clone(),
manifest,
@ -341,6 +500,7 @@ async fn main() {
timer_service_receiver,
print_sender.clone(),
));
#[cfg(not(feature = "simulation-mode"))]
tasks.spawn(eth_rpc::eth_rpc(
our.name.clone(),
rpc_url.clone(),
@ -362,7 +522,7 @@ async fn main() {
our.name.clone(),
kernel_message_sender.clone(),
llm_receiver,
llm_url.unwrap().to_string(),
llm_url.to_string(),
print_sender.clone(),
));
}

50
src/net/mock.rs Normal file
View File

@ -0,0 +1,50 @@
use futures::{SinkExt, StreamExt};
use tokio::net::TcpStream;
use tokio::sync::mpsc;
use tokio_tungstenite::{
connect_async,
tungstenite::protocol::Message::{Binary, Text},
WebSocketStream,
};
use url::Url;
use crate::types;
type Sender = mpsc::Sender<types::KernelMessage>;
type Receiver = mpsc::Receiver<types::KernelMessage>;
pub async fn mock_client(
port: u16,
node_identity: types::NodeId,
send_to_loop: Sender,
mut recv_from_loop: Receiver,
) -> anyhow::Result<()> {
let url = format!("ws://127.0.0.1:{}", port);
let (ws_stream, _) = connect_async(url).await?;
let (mut send_to_ws, mut recv_from_ws) = ws_stream.split();
// Send node identity
send_to_ws.send(Text(node_identity.clone())).await?;
loop {
tokio::select! {
Some(kernel_message) = recv_from_loop.recv() => {
if kernel_message.target.node != node_identity {
// Serialize and send the message through WebSocket
// println!("{}:mock: outgoing {}\r", node_identity ,kernel_message);
let message = Binary(rmp_serde::to_vec(&kernel_message)?);
send_to_ws.send(message).await?;
}
},
Some(Ok(message)) = recv_from_ws.next() => {
// Deserialize and forward the message to the loop
// println!("{}:mock: incoming {}\r", node_identity, message);
if let Binary(ref bin) = message {
let kernel_message: types::KernelMessage = rmp_serde::from_slice(bin)?;
send_to_loop.send(kernel_message).await?;
}
},
}
}
}

View File

@ -16,6 +16,12 @@ use tokio_tungstenite::{
mod types;
mod utils;
// Re-export for testing.
#[cfg(feature = "simulation-mode")]
mod mock;
#[cfg(feature = "simulation-mode")]
pub use mock::mock_client;
// only used in connection initialization, otherwise, nacks and Responses are only used for "timeouts"
const TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5);

View File

@ -1,4 +1,5 @@
use crate::kernel::process::wit;
use clap::Parser;
use ring::signature;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};