runner moved into terminal

This commit is contained in:
Drew Tada 2024-01-18 16:54:30 -06:00
parent 2db9f2d971
commit 566b255099
8 changed files with 219 additions and 900 deletions

View File

@ -1,30 +0,0 @@
[
{
"process_name": "runner",
"process_wasm_path": "/runner.wasm",
"on_exit": "Restart",
"request_networking": true,
"request_capabilities": [
"terminal:terminal:sys",
"filesystem:distro:sys",
"http_server:distro:sys",
"http_client:distro:sys",
"net:distro:sys",
"vfs:distro:sys",
"kernel:distro:sys",
"eth:distro:sys",
"sqlite:distro:sys",
"kv:distro:sys",
"chess:chess:sys",
"kns_indexer:kns_indexer:sys",
{
"process": "vfs:distro:sys",
"params": {
"root": true
}
}
],
"grant_capabilities": [],
"public": true
}
]

View File

@ -1,556 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
[[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.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]]
name = "bytes"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
[[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 = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "form_urlencoded"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [
"percent-encoding",
]
[[package]]
name = "getrandom"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
dependencies = [
"unicode-segmentation",
]
[[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 = "id-arena"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
[[package]]
name = "idna"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[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.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "kinode_process_lib"
version = "0.5.0"
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=9790c0f#9790c0fecc64572d1fbeecdf3724eb37b3d6d3fa"
dependencies = [
"anyhow",
"bincode",
"http",
"mime_guess",
"rand",
"serde",
"serde_json",
"thiserror",
"url",
"wit-bindgen",
]
[[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.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "mime"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "mime_guess"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
dependencies = [
"mime",
"unicase",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[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.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
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 = "runner"
version = "0.1.0"
dependencies = [
"anyhow",
"bincode",
"kinode_process_lib",
"rand",
"serde",
"serde_json",
"wit-bindgen",
]
[[package]]
name = "ryu"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]]
name = "semver"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0"
[[package]]
name = "serde"
version = "1.0.195"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.195"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "smallvec"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e"
[[package]]
name = "spdx"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bde1398b09b9f93fc2fc9b9da86e362693e999d3a54a8ac47a99a5a73f638b"
dependencies = [
"smallvec",
]
[[package]]
name = "syn"
version = "2.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "unicase"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-bidi"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-normalization"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
dependencies = [
"tinyvec",
]
[[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 = "url"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
]
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[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.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f"
dependencies = [
"leb128",
]
[[package]]
name = "wasm-encoder"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "111495d6204760238512f57a9af162f45086504da332af210f2f75dd80b34f1d"
dependencies = [
"leb128",
]
[[package]]
name = "wasm-metadata"
version = "0.10.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "818931c85b1d197909699d36c509fa89550ccfa0d66932ba3c1726faddb4d0c7"
dependencies = [
"anyhow",
"indexmap",
"serde",
"serde_derive",
"serde_json",
"spdx",
"wasm-encoder 0.39.0",
"wasmparser 0.119.0",
]
[[package]]
name = "wasmparser"
version = "0.118.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9"
dependencies = [
"indexmap",
"semver",
]
[[package]]
name = "wasmparser"
version = "0.119.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c35daf77afb4f9b14016625144a391085ec2ca99ca9cc53ed291bb53ab5278d"
dependencies = [
"bitflags",
"indexmap",
"semver",
]
[[package]]
name = "wit-bindgen"
version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [
"bitflags",
"wit-bindgen-rust-macro",
]
[[package]]
name = "wit-bindgen-core"
version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [
"anyhow",
"wit-component",
"wit-parser",
]
[[package]]
name = "wit-bindgen-rust"
version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [
"anyhow",
"heck",
"wasm-metadata",
"wit-bindgen-core",
"wit-component",
]
[[package]]
name = "wit-bindgen-rust-macro"
version = "0.16.0"
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
dependencies = [
"anyhow",
"proc-macro2",
"quote",
"syn",
"wit-bindgen-core",
"wit-bindgen-rust",
"wit-component",
]
[[package]]
name = "wit-component"
version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2"
dependencies = [
"anyhow",
"bitflags",
"indexmap",
"log",
"serde",
"serde_derive",
"serde_json",
"wasm-encoder 0.38.1",
"wasm-metadata",
"wasmparser 0.118.1",
"wit-parser",
]
[[package]]
name = "wit-parser"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df4913a2219096373fd6512adead1fb77ecdaa59d7fc517972a7d30b12f625be"
dependencies = [
"anyhow",
"id-arena",
"indexmap",
"log",
"semver",
"serde",
"serde_derive",
"serde_json",
"unicode-xid",
]

View File

@ -1,24 +0,0 @@
[package]
name = "runner"
version = "0.1.0"
edition = "2021"
[profile.release]
panic = "abort"
opt-level = "s"
lto = true
[dependencies]
anyhow = "1.0"
bincode = "1.3.3"
kinode_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "9790c0f" }
rand = "0.8"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" }
[lib]
crate-type = ["cdylib"]
[package.metadata.component]
package = "kinode:process"

View File

@ -1,263 +0,0 @@
use kinode_process_lib::kernel_types as kt;
use kinode_process_lib::*;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use kinode_process_lib::{
await_message, call_init, println, Address, Capability, Message, ProcessId, Request, Response,
};
// TODO move this into kt::
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DotScriptsEntry {
pub public: bool,
pub request_networking: bool,
pub request_capabilities: Option<Vec<serde_json::Value>>,
pub grant_capabilities: Option<Vec<serde_json::Value>>,
}
wit_bindgen::generate!({
path: "wit",
world: "process",
exports: {
world: Component,
},
});
#[derive(Debug, Serialize, Deserialize)]
pub enum ScriptRequest {
Run {
package: PackageId,
wasm_path: String, // vfs path
args: String, // first message, in json
},
Inject {
process: String, // ProcessId
args: String, // next message, in json
},
Terminate(String), // ProcessId string encoded
}
call_init!(init);
fn init(our: Address) {
println!("runner:script : begin");
loop {
match handle_message(&our) {
Ok(()) => {}
Err(e) => {
println!("script_runner: error: {:?}", e);
}
};
}
}
fn handle_message(our: &Address) -> anyhow::Result<()> {
let message = await_message()?;
match message {
Message::Response { .. } => {
return Err(anyhow::anyhow!("unexpected Response: {:?}", message));
}
Message::Request {
ref source,
ref body,
..
} => match serde_json::from_slice::<ScriptRequest>(body)? {
ScriptRequest::Run {
package,
wasm_path,
args,
} => match handle_run(our, &package, wasm_path, args) {
Ok(()) => {} // LocalResponse::InstallResponse(InstallResponse::Success),
Err(_) => {} // LocalResponse::InstallResponse(InstallResponse::Failure),
},
ScriptRequest::Inject { process, args } => {
println!("script_runner: got inject request");
}
ScriptRequest::Terminate(process) => {
println!("script_runner: got terminate request");
}
},
}
Ok(())
}
fn handle_run(
our: &Address,
package: &PackageId,
wasm_path: String,
args: String,
) -> anyhow::Result<()> {
let drive_path = format!("/{}/pkg", package);
Request::new()
.target(("our", "vfs", "distro", "sys"))
.body(serde_json::to_vec(&vfs::VfsRequest {
path: format!("{}/scripts.json", drive_path),
action: vfs::VfsAction::Read,
})?)
.send_and_await_response(5)??;
let Some(blob) = get_blob() else {
return Err(anyhow::anyhow!("no blob"));
};
let dot_scripts = String::from_utf8(blob.bytes)?;
let dot_scripts = serde_json::from_str::<HashMap<String, DotScriptsEntry>>(&dot_scripts)?;
let Some(entry) = dot_scripts.get(&wasm_path) else {
return Err(anyhow::anyhow!("script not in scripts.json file"));
};
let wasm_path = if wasm_path.starts_with("/") {
wasm_path.clone()
} else {
format!("/{}", wasm_path)
};
let wasm_path = format!("{}{}", drive_path, wasm_path);
// build initial caps
let mut initial_capabilities: HashSet<kt::Capability> = HashSet::new();
if entry.request_networking {
initial_capabilities.insert(kt::de_wit_capability(Capability {
issuer: Address::new(&our.node, ("kernel", "distro", "sys")),
params: "\"network\"".to_string(),
}));
}
let process_id = format!("{}:{}", rand::random::<u64>(), package); // all scripts are given random process IDs
let Ok(parsed_new_process_id) = process_id.parse::<ProcessId>() else {
return Err(anyhow::anyhow!("app store: invalid process id!"));
};
let _bytes_response = Request::new()
.target(("our", "vfs", "distro", "sys"))
.body(serde_json::to_vec(&vfs::VfsRequest {
path: wasm_path.clone(),
action: vfs::VfsAction::Read,
})?)
.send_and_await_response(5)??;
if let Some(to_request) = &entry.request_capabilities {
for value in to_request {
let mut capability = None;
match value {
serde_json::Value::String(process_name) => {
if let Ok(parsed_process_id) = process_name.parse::<ProcessId>() {
capability = get_capability(
&Address {
node: our.node.clone(),
process: parsed_process_id.clone(),
},
"\"messaging\"".into(),
);
}
}
serde_json::Value::Object(map) => {
if let Some(process_name) = map.get("process") {
if let Ok(parsed_process_id) = process_name
.as_str()
.unwrap_or_default()
.parse::<ProcessId>()
{
if let Some(params) = map.get("params") {
capability = get_capability(
&Address {
node: our.node.clone(),
process: parsed_process_id.clone(),
},
&params.to_string(),
);
}
}
}
}
_ => {
continue;
}
}
if let Some(cap) = capability {
initial_capabilities.insert(kt::de_wit_capability(cap));
} else {
println!(
"runner: no cap: {}, for {} to request!",
value.to_string(),
package
);
}
}
}
Request::new()
.target(("our", "kernel", "distro", "sys"))
.body(serde_json::to_vec(&kt::KernelCommand::InitializeProcess {
id: parsed_new_process_id.clone(),
wasm_bytes_handle: wasm_path,
wit_version: None,
on_exit: kt::OnExit::None, // TODO this should send a message back to runner:script:sys so that it can Drop capabilities
initial_capabilities,
public: entry.public,
})?)
.inherit(true)
.send_and_await_response(5)??;
if let Some(to_grant) = &entry.grant_capabilities {
for value in to_grant {
match value {
serde_json::Value::String(process_name) => {
if let Ok(parsed_process_id) = process_name.parse::<ProcessId>() {
let _ = Request::new()
.target(("our", "kernel", "distro", "sys"))
.body(
serde_json::to_vec(&kt::KernelCommand::GrantCapabilities {
target: parsed_process_id,
capabilities: vec![kt::Capability {
issuer: Address {
node: our.node.clone(),
process: parsed_new_process_id.clone(),
},
params: "\"messaging\"".into(),
}],
})
.unwrap(),
)
.send()?;
}
}
serde_json::Value::Object(map) => {
if let Some(process_name) = map.get("process") {
if let Ok(parsed_process_id) = process_name
.as_str()
.unwrap_or_default()
.parse::<ProcessId>()
{
if let Some(params) = map.get("params") {
let _ = Request::new()
.target(("our", "kernel", "distro", "sys"))
.body(
serde_json::to_vec(&kt::KernelCommand::GrantCapabilities {
target: parsed_process_id,
capabilities: vec![kt::Capability {
issuer: Address {
node: our.node.clone(),
process: parsed_new_process_id.clone(),
},
params: params.to_string(),
}],
})
.unwrap(),
)
.send()?;
}
}
}
}
_ => {
continue;
}
}
}
}
let _ = Request::new()
.target(("our", "kernel", "distro", "sys"))
.body(serde_json::to_vec(&kt::KernelCommand::RunProcess(
parsed_new_process_id.clone(),
))?)
.send_and_await_response(5)??;
let _ = Request::new()
.target(("our", parsed_new_process_id))
.body(args.into_bytes())
.send();
Ok(())
}

View File

@ -6,10 +6,24 @@
"request_networking": true,
"request_capabilities": [
"net:distro:sys",
"filesystem:distro:sys",
"http_server:distro:sys",
"http_client:distro:sys",
"kernel:distro:sys"
"kernel:distro:sys",
"vfs:distro:sys",
"eth:distro:sys",
"sqlite:distro:sys",
"kv:distro:sys",
"chess:chess:sys",
"kns_indexer:kns_indexer:sys",
{
"process": "vfs:distro:sys",
"params": {
"root": true
}
}
],
"grant_capabilities": [],
"public": true
}
]
]

View File

@ -313,6 +313,7 @@ dependencies = [
"anyhow",
"bincode",
"kinode_process_lib",
"rand",
"serde",
"serde_json",
"wit-bindgen",

View File

@ -13,6 +13,7 @@ lto = true
[dependencies]
anyhow = "1.0"
bincode = "1.3.3"
rand = "0.8"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
kinode_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", tag = "v0.5.3-alpha" }

View File

@ -1,8 +1,11 @@
use anyhow::anyhow;
use kinode_process_lib::kernel_types::{KernelCommand, KernelPrint};
use kinode_process_lib::kernel_types as kt;
use kinode_process_lib::kinode::process::standard as wit;
use kinode_process_lib::{println, Address, ProcessId, Request};
use serde_json::json;
use kinode_process_lib::{
get_blob, get_capability, println, vfs, Address, Capability, PackageId, ProcessId, Request,
};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
wit_bindgen::generate!({
path: "../../../wit",
@ -12,15 +15,21 @@ wit_bindgen::generate!({
},
});
// TODO move this into kt::
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DotScriptsEntry {
pub public: bool,
pub request_networking: bool,
pub request_capabilities: Option<Vec<serde_json::Value>>,
pub grant_capabilities: Option<Vec<serde_json::Value>>,
}
struct TerminalState {
our: Address,
current_target: Option<Address>,
}
fn serialize_message(message: &str) -> anyhow::Result<Vec<u8>> {
Ok(message.as_bytes().to_vec())
}
fn parse_command(state: &mut TerminalState, line: &str) -> anyhow::Result<()> {
let (head, tail) = line.split_once(" ").unwrap_or((&line, ""));
match head {
@ -70,24 +79,12 @@ fn parse_command(state: &mut TerminalState, line: &str) -> anyhow::Result<()> {
Err(_) => return Err(anyhow!("invalid process id: \"{tail}\"")),
},
};
Request::new()
.target(Address::new("our", ("runner", "script", "sys")))
.body(
json!({
"Run": {
// TODO we should add a package_id() method to ProcessId that will get this for you
"package": {
"package_name": process.package(),
"publisher_node": process.publisher(),
},
"wasm_path": format!("{}.wasm", process.process()),
"args": args
}
})
.to_string()
.into_bytes(),
)
.send()
let wasm_path = format!("{}.wasm", process.process());
let package = PackageId::new(process.package(), process.publisher());
match handle_run(&state.our, &package, wasm_path, args.to_string()) {
Ok(_) => Ok(()), // TODO clean up process
Err(e) => Err(anyhow!("terminal: failed to instantiate script: {}", e)),
}
}
_ => return Err(anyhow!("invalid command: \"{line}\"")),
}
@ -130,3 +127,182 @@ impl Guest for Component {
}
}
}
fn handle_run(
our: &Address,
package: &PackageId,
wasm_path: String,
args: String,
) -> anyhow::Result<()> {
let drive_path = format!("/{}/pkg", package);
Request::new()
.target(("our", "vfs", "distro", "sys"))
.body(serde_json::to_vec(&vfs::VfsRequest {
path: format!("{}/scripts.json", drive_path),
action: vfs::VfsAction::Read,
})?)
.send_and_await_response(5)??;
let Some(blob) = get_blob() else {
return Err(anyhow::anyhow!("no blob"));
};
let dot_scripts = String::from_utf8(blob.bytes)?;
let dot_scripts = serde_json::from_str::<HashMap<String, DotScriptsEntry>>(&dot_scripts)?;
let Some(entry) = dot_scripts.get(&wasm_path) else {
return Err(anyhow::anyhow!("script not in scripts.json file"));
};
let wasm_path = if wasm_path.starts_with("/") {
wasm_path.clone()
} else {
format!("/{}", wasm_path)
};
let wasm_path = format!("{}{}", drive_path, wasm_path);
// build initial caps
let mut initial_capabilities: HashSet<kt::Capability> = HashSet::new();
if entry.request_networking {
initial_capabilities.insert(kt::de_wit_capability(Capability {
issuer: Address::new(&our.node, ("kernel", "distro", "sys")),
params: "\"network\"".to_string(),
}));
}
let process_id = format!("{}:{}", rand::random::<u64>(), package); // all scripts are given random process IDs
let Ok(parsed_new_process_id) = process_id.parse::<ProcessId>() else {
return Err(anyhow::anyhow!("app store: invalid process id!"));
};
let _bytes_response = Request::new()
.target(("our", "vfs", "distro", "sys"))
.body(serde_json::to_vec(&vfs::VfsRequest {
path: wasm_path.clone(),
action: vfs::VfsAction::Read,
})?)
.send_and_await_response(5)??;
if let Some(to_request) = &entry.request_capabilities {
for value in to_request {
let mut capability = None;
match value {
serde_json::Value::String(process_name) => {
if let Ok(parsed_process_id) = process_name.parse::<ProcessId>() {
capability = get_capability(
&Address {
node: our.node.clone(),
process: parsed_process_id.clone(),
},
"\"messaging\"".into(),
);
}
}
serde_json::Value::Object(map) => {
if let Some(process_name) = map.get("process") {
if let Ok(parsed_process_id) = process_name
.as_str()
.unwrap_or_default()
.parse::<ProcessId>()
{
if let Some(params) = map.get("params") {
capability = get_capability(
&Address {
node: our.node.clone(),
process: parsed_process_id.clone(),
},
&params.to_string(),
);
}
}
}
}
_ => {
continue;
}
}
if let Some(cap) = capability {
initial_capabilities.insert(kt::de_wit_capability(cap));
} else {
println!(
"runner: no cap: {}, for {} to request!",
value.to_string(),
package
);
}
}
}
Request::new()
.target(("our", "kernel", "distro", "sys"))
.body(serde_json::to_vec(&kt::KernelCommand::InitializeProcess {
id: parsed_new_process_id.clone(),
wasm_bytes_handle: wasm_path,
wit_version: None,
on_exit: kt::OnExit::None, // TODO this should send a message back to runner:script:sys so that it can Drop capabilities
initial_capabilities,
public: entry.public,
})?)
.inherit(true)
.send_and_await_response(5)??;
if let Some(to_grant) = &entry.grant_capabilities {
for value in to_grant {
match value {
serde_json::Value::String(process_name) => {
if let Ok(parsed_process_id) = process_name.parse::<ProcessId>() {
let _ = Request::new()
.target(("our", "kernel", "distro", "sys"))
.body(
serde_json::to_vec(&kt::KernelCommand::GrantCapabilities {
target: parsed_process_id,
capabilities: vec![kt::Capability {
issuer: Address {
node: our.node.clone(),
process: parsed_new_process_id.clone(),
},
params: "\"messaging\"".into(),
}],
})
.unwrap(),
)
.send()?;
}
}
serde_json::Value::Object(map) => {
if let Some(process_name) = map.get("process") {
if let Ok(parsed_process_id) = process_name
.as_str()
.unwrap_or_default()
.parse::<ProcessId>()
{
if let Some(params) = map.get("params") {
let _ = Request::new()
.target(("our", "kernel", "distro", "sys"))
.body(
serde_json::to_vec(&kt::KernelCommand::GrantCapabilities {
target: parsed_process_id,
capabilities: vec![kt::Capability {
issuer: Address {
node: our.node.clone(),
process: parsed_new_process_id.clone(),
},
params: params.to_string(),
}],
})
.unwrap(),
)
.send()?;
}
}
}
}
_ => {
continue;
}
}
}
}
let _ = Request::new()
.target(("our", "kernel", "distro", "sys"))
.body(serde_json::to_vec(&kt::KernelCommand::RunProcess(
parsed_new_process_id.clone(),
))?)
.send_and_await_response(5)??;
let _ = Request::new()
.target(("our", parsed_new_process_id))
.body(args.into_bytes())
.send();
Ok(())
}