mirror of
https://github.com/uqbar-dao/nectar.git
synced 2024-12-02 08:02:23 +03:00
merge develop
This commit is contained in:
commit
b69d48c001
78
Cargo.lock
generated
78
Cargo.lock
generated
@ -3044,6 +3044,29 @@ dependencies = [
|
||||
"sha3-asm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kfetch"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"kinode_process_lib 0.8.0 (git+https://github.com/kinode-dao/process_lib?rev=010e175)",
|
||||
"rmp-serde",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kill"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"kinode_process_lib 0.8.0 (git+https://github.com/kinode-dao/process_lib?rev=010e175)",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kinode"
|
||||
version = "0.8.0"
|
||||
@ -3129,6 +3152,28 @@ dependencies = [
|
||||
"lib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kinode_process_lib"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/kinode-dao/process_lib?rev=010e175#010e175b4e66242c2ef9422088e355698728600d"
|
||||
dependencies = [
|
||||
"alloy-json-rpc 0.1.0 (git+https://github.com/alloy-rs/alloy.git?rev=cad7935)",
|
||||
"alloy-primitives 0.7.0",
|
||||
"alloy-rpc-types 0.1.0 (git+https://github.com/alloy-rs/alloy.git?rev=cad7935)",
|
||||
"alloy-transport 0.1.0 (git+https://github.com/alloy-rs/alloy.git?rev=cad7935)",
|
||||
"anyhow",
|
||||
"bincode",
|
||||
"http 1.1.0",
|
||||
"mime_guess",
|
||||
"rand 0.8.5",
|
||||
"rmp-serde",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"url",
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kinode_process_lib"
|
||||
version = "0.8.0"
|
||||
@ -4076,6 +4121,15 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "process_macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/kinode-dao/process_macros?rev=626e501#626e501d351e3365480ec6f770d474ed4ae339bf"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proptest"
|
||||
version = "1.4.0"
|
||||
@ -5033,9 +5087,8 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "snow"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "850948bee068e713b8ab860fe1adc4d109676ab4c3b621fd8147f06b261f2f85"
|
||||
version = "0.9.0"
|
||||
source = "git+https://github.com/dr-frmr/snow?branch=dr/extract_cipherstates#1d4eb5f6747aa59aabb32bbbe698fb4bb7dfb9a4"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"blake2",
|
||||
@ -5283,27 +5336,14 @@ dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test_runner"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
"kinode_process_lib 0.8.0 (git+https://github.com/kinode-dao/process_lib?rev=09dc9f9)",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tester"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
"indexmap",
|
||||
"kinode_process_lib 0.8.0 (git+https://github.com/kinode-dao/process_lib?rev=09dc9f9)",
|
||||
"process_macros",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
@ -5543,10 +5583,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "top"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"kinode_process_lib 0.8.0 (git+https://github.com/kinode-dao/process_lib?rev=09dc9f9)",
|
||||
"kinode_process_lib 0.8.0 (git+https://github.com/kinode-dao/process_lib?rev=010e175)",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wit-bindgen",
|
||||
|
@ -22,9 +22,9 @@ members = [
|
||||
"kinode/packages/kns_indexer/kns_indexer", "kinode/packages/kns_indexer/get_block", "kinode/packages/kns_indexer/state",
|
||||
"kinode/packages/settings/settings",
|
||||
"kinode/packages/terminal/terminal",
|
||||
"kinode/packages/terminal/alias", "kinode/packages/terminal/cat", "kinode/packages/terminal/echo", "kinode/packages/terminal/hi", "kinode/packages/terminal/m", "kinode/packages/terminal/top",
|
||||
"kinode/packages/terminal/alias", "kinode/packages/terminal/cat", "kinode/packages/terminal/echo", "kinode/packages/terminal/hi", "kinode/packages/terminal/kfetch", "kinode/packages/terminal/kill", "kinode/packages/terminal/m", "kinode/packages/terminal/top",
|
||||
"kinode/packages/terminal/namehash_to_name", "kinode/packages/terminal/net_diagnostics", "kinode/packages/terminal/peer", "kinode/packages/terminal/peers",
|
||||
"kinode/packages/tester/tester", "kinode/packages/tester/test_runner",
|
||||
"kinode/packages/tester/tester",
|
||||
]
|
||||
default-members = ["lib"]
|
||||
resolver = "2"
|
||||
|
@ -80,7 +80,9 @@ serde_json = "1.0"
|
||||
serde_urlencoded = "0.7"
|
||||
sha2 = "0.10"
|
||||
sha3 = "0.10.8"
|
||||
snow = { version = "0.9.5", features = ["ring-resolver"] }
|
||||
# snow = { version = "0.9.5", features = ["ring-resolver"] }
|
||||
# unfortunately need to use forked version for async use and in-place encryption
|
||||
snow = { git = "https://github.com/dr-frmr/snow", branch = "dr/extract_cipherstates", features = ["ring-resolver"] }
|
||||
socket2 = "0.5.7"
|
||||
static_dir = "0.2.0"
|
||||
thiserror = "1.0"
|
||||
|
File diff suppressed because one or more lines are too long
@ -14,7 +14,7 @@
|
||||
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1.00001, viewport-fit=cover" />
|
||||
<script type="module" crossorigin src="/main:app_store:sys/assets/index-Gc4HI_PE.js"></script>
|
||||
<script type="module" crossorigin src="/main:app_store:sys/assets/index--h2dsLNv.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/main:app_store:sys/assets/index-OOHWYMdt.css">
|
||||
</head>
|
||||
|
||||
|
@ -10,9 +10,10 @@ import classNames from "classnames";
|
||||
interface ActionButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
|
||||
app: AppInfo;
|
||||
isIcon?: boolean;
|
||||
permitMultiButton?: boolean;
|
||||
}
|
||||
|
||||
export default function ActionButton({ app, isIcon = false, ...props }: ActionButtonProps) {
|
||||
export default function ActionButton({ app, isIcon = false, permitMultiButton = false, ...props }: ActionButtonProps) {
|
||||
const { installed, downloaded, updatable } = useMemo(() => {
|
||||
const versions = Object.entries(app?.metadata?.properties?.code_hashes || {});
|
||||
const latestHash = (versions.find(([v]) => v === app.metadata?.properties?.current_version) || [])[1];
|
||||
@ -48,6 +49,8 @@ export default function ActionButton({ app, isIcon = false, ...props }: ActionBu
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* if it's got a UI and it's updatable, show both buttons if we have space (launch will otherwise push out update) */}
|
||||
{permitMultiButton && installed && updatable && launchPath && <UpdateButton app={app} {...props} isIcon={isIcon} />}
|
||||
{(installed && launchPath)
|
||||
? <LaunchButton app={app} {...props} isIcon={isIcon} launchPath={launchPath} />
|
||||
: (installed && updatable)
|
||||
|
@ -140,7 +140,11 @@ export default function AppPage() {
|
||||
)
|
||||
)}
|
||||
</div>}
|
||||
<ActionButton app={app} className={classNames("self-center bg-orange text-lg px-12")} />
|
||||
<div className={classNames("flex-center gap-2", {
|
||||
'flex-col': isMobile,
|
||||
})}>
|
||||
<ActionButton app={app} className={classNames("self-center bg-orange text-lg px-12")} permitMultiButton />
|
||||
</div>
|
||||
{app.installed && app.state?.mirroring && (
|
||||
<button type="button" onClick={goToPublish}>
|
||||
Publish
|
||||
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "test_runner"
|
||||
name = "kfetch"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
@ -8,11 +8,10 @@ simulation-mode = []
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
bincode = "1.3.3"
|
||||
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "09dc9f9" }
|
||||
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "010e175" }
|
||||
rmp-serde = "1.1.2"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
thiserror = "1.0"
|
||||
wit-bindgen = "0.24.0"
|
||||
|
||||
[lib]
|
166
kinode/packages/terminal/kfetch/src/lib.rs
Normal file
166
kinode/packages/terminal/kfetch/src/lib.rs
Normal file
@ -0,0 +1,166 @@
|
||||
use kinode_process_lib::kernel_types::{
|
||||
KernelCommand, KernelPrint, KernelPrintResponse, KernelResponse,
|
||||
};
|
||||
use kinode_process_lib::{call_init, eth, net, println, Address, Message, Request};
|
||||
use std::collections::HashSet;
|
||||
|
||||
/// Fetching OS version from main package.. LMK if there's a better way...
|
||||
const CARGO_TOML: &str = include_str!("../../../../Cargo.toml");
|
||||
|
||||
wit_bindgen::generate!({
|
||||
path: "target/wit",
|
||||
world: "process-v0",
|
||||
});
|
||||
|
||||
call_init!(init);
|
||||
fn init(our: Address) {
|
||||
// get identity
|
||||
let Ok(Ok(Message::Response { body, .. })) = Request::to(("our", "net", "distro", "sys"))
|
||||
.body(rmp_serde::to_vec(&net::NetAction::GetPeer(our.node.clone())).unwrap())
|
||||
.send_and_await_response(60)
|
||||
else {
|
||||
println!("failed to get response from net");
|
||||
return;
|
||||
};
|
||||
let Ok(net::NetResponse::Peer(Some(our_id))) = rmp_serde::from_slice(&body) else {
|
||||
println!("got malformed response from net");
|
||||
return;
|
||||
};
|
||||
|
||||
// get eth providers
|
||||
let Ok(Message::Response { body, .. }) = Request::new()
|
||||
.target(("our", "eth", "distro", "sys"))
|
||||
.body(serde_json::to_vec(ð::EthConfigAction::GetProviders).unwrap())
|
||||
.send_and_await_response(60)
|
||||
.unwrap()
|
||||
else {
|
||||
println!("failed to get response from eth");
|
||||
return;
|
||||
};
|
||||
let Ok(eth::EthConfigResponse::Providers(providers)) = serde_json::from_slice(&body) else {
|
||||
println!("failed to parse eth response");
|
||||
return;
|
||||
};
|
||||
|
||||
// get eth subs
|
||||
let Ok(Message::Response { body, .. }) = Request::new()
|
||||
.target(("our", "eth", "distro", "sys"))
|
||||
.body(serde_json::to_vec(ð::EthConfigAction::GetState).unwrap())
|
||||
.send_and_await_response(60)
|
||||
.unwrap()
|
||||
else {
|
||||
println!("failed to get response from eth");
|
||||
return;
|
||||
};
|
||||
let Ok(eth::EthConfigResponse::State {
|
||||
active_subscriptions,
|
||||
outstanding_requests,
|
||||
}) = serde_json::from_slice(&body)
|
||||
else {
|
||||
println!("failed to parse eth response");
|
||||
return;
|
||||
};
|
||||
|
||||
// get number of processes
|
||||
let Ok(Message::Response { body, .. }) = Request::new()
|
||||
.target(("our", "kernel", "distro", "sys"))
|
||||
.body(serde_json::to_vec(&KernelCommand::Debug(KernelPrint::ProcessMap)).unwrap())
|
||||
.send_and_await_response(60)
|
||||
.unwrap()
|
||||
else {
|
||||
println!("failed to get response from kernel");
|
||||
return;
|
||||
};
|
||||
let Ok(KernelResponse::Debug(KernelPrintResponse::ProcessMap(map))) =
|
||||
serde_json::from_slice::<KernelResponse>(&body)
|
||||
else {
|
||||
println!("failed to parse kernel response");
|
||||
return;
|
||||
};
|
||||
let num_processes = map.len();
|
||||
print_bird(
|
||||
&our,
|
||||
our_id,
|
||||
providers,
|
||||
// sum up all the subscriptions
|
||||
active_subscriptions
|
||||
.values()
|
||||
.map(|v| v.len())
|
||||
.sum::<usize>(),
|
||||
outstanding_requests.len() as usize,
|
||||
num_processes,
|
||||
);
|
||||
}
|
||||
|
||||
fn print_bird(
|
||||
our: &Address,
|
||||
our_id: net::Identity,
|
||||
providers: HashSet<eth::ProviderConfig>,
|
||||
active_subscriptions: usize,
|
||||
outstanding_requests: usize,
|
||||
num_processes: usize,
|
||||
) {
|
||||
println!(
|
||||
r#"
|
||||
.`
|
||||
`@@,, ,* {}
|
||||
`@%@@@, ,~-##`
|
||||
~@@#@%#@@, ##### Kinode {}
|
||||
~-%######@@@, #####
|
||||
-%%#######@#####, pubkey: {}
|
||||
~^^%##########@ routing: {}
|
||||
>^#########@
|
||||
`>#######` {} eth providers for chain IDs {}
|
||||
.>######% {} active eth subscriptions
|
||||
/###%^#% {} outstanding eth requests
|
||||
/##%@# `
|
||||
./######`
|
||||
/.^`.#^#^`
|
||||
` ,#`#`#, {} running processes
|
||||
,/ /` `
|
||||
.*`
|
||||
"#,
|
||||
our.node(),
|
||||
version_from_cargo_toml(),
|
||||
our_id.networking_key,
|
||||
routing_to_string(our_id.routing),
|
||||
providers.len(),
|
||||
providers
|
||||
.into_iter()
|
||||
.map(|p| p.chain_id.to_string())
|
||||
// remove duplicates
|
||||
.collect::<HashSet<_>>()
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
active_subscriptions,
|
||||
outstanding_requests,
|
||||
num_processes
|
||||
)
|
||||
}
|
||||
|
||||
fn routing_to_string(routing: net::NodeRouting) -> String {
|
||||
match routing {
|
||||
net::NodeRouting::Direct { ip, ports } => format!(
|
||||
"direct at {} with {}",
|
||||
ip,
|
||||
ports.into_keys().into_iter().collect::<Vec<_>>().join(", ")
|
||||
),
|
||||
net::NodeRouting::Routers(routers) => format!("{} routers", routers.len()),
|
||||
}
|
||||
}
|
||||
|
||||
fn version_from_cargo_toml() -> String {
|
||||
let version = CARGO_TOML
|
||||
.lines()
|
||||
.find(|line| line.starts_with("version = "))
|
||||
.expect("Failed to find version in Cargo.toml");
|
||||
|
||||
version
|
||||
.split('=')
|
||||
.last()
|
||||
.expect("Failed to parse version from Cargo.toml")
|
||||
.trim()
|
||||
.trim_matches('"')
|
||||
.to_string()
|
||||
}
|
20
kinode/packages/terminal/kill/Cargo.toml
Normal file
20
kinode/packages/terminal/kill/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "kill"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
simulation-mode = []
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "010e175" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
wit-bindgen = "0.24.0"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[package.metadata.component]
|
||||
package = "kinode:process"
|
48
kinode/packages/terminal/kill/src/lib.rs
Normal file
48
kinode/packages/terminal/kill/src/lib.rs
Normal file
@ -0,0 +1,48 @@
|
||||
use kinode_process_lib::kernel_types::{KernelCommand, KernelPrint, KernelResponse};
|
||||
use kinode_process_lib::{
|
||||
await_next_message_body, call_init, println, Address, Message, ProcessId, Request,
|
||||
};
|
||||
|
||||
wit_bindgen::generate!({
|
||||
path: "target/wit",
|
||||
world: "process-v0",
|
||||
});
|
||||
|
||||
call_init!(init);
|
||||
fn init(_our: Address) {
|
||||
let Ok(args) = await_next_message_body() else {
|
||||
println!("failed to get args");
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(proc_id) = String::from_utf8(args) else {
|
||||
println!("failed to stringify arguments");
|
||||
return;
|
||||
};
|
||||
|
||||
let body = match proc_id.parse::<ProcessId>() {
|
||||
Ok(proc_id) => serde_json::to_vec(&KernelCommand::KillProcess(proc_id)).unwrap(),
|
||||
Err(_) => {
|
||||
println!("invalid process id");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let Ok(Message::Response { body, .. }) = Request::new()
|
||||
.target(("our", "kernel", "distro", "sys"))
|
||||
.body(body)
|
||||
.send_and_await_response(60)
|
||||
.unwrap()
|
||||
else {
|
||||
println!("failed to get response from kernel");
|
||||
return;
|
||||
};
|
||||
let Ok(KernelResponse::KilledProcess(proc_id)) =
|
||||
serde_json::from_slice::<KernelResponse>(&body)
|
||||
else {
|
||||
println!("failed to parse kernel response");
|
||||
return;
|
||||
};
|
||||
|
||||
println!("killed process {}", proc_id);
|
||||
}
|
@ -9,7 +9,7 @@ call_init!(init);
|
||||
fn init(_our: Address) {
|
||||
let Ok(Ok(Message::Response { body, .. })) = Request::to(("our", "net", "distro", "sys"))
|
||||
.body(rmp_serde::to_vec(&net::NetAction::GetDiagnostics).unwrap())
|
||||
.send_and_await_response(5)
|
||||
.send_and_await_response(60)
|
||||
else {
|
||||
println!("failed to get diagnostics from networking module");
|
||||
return;
|
||||
@ -18,5 +18,5 @@ fn init(_our: Address) {
|
||||
println!("got malformed response from networking module");
|
||||
return;
|
||||
};
|
||||
println!("{printout}");
|
||||
println!("\r\n{printout}");
|
||||
}
|
||||
|
@ -9,14 +9,6 @@
|
||||
"grant_capabilities": [],
|
||||
"wit_version": 0
|
||||
},
|
||||
"echo.wasm": {
|
||||
"root": false,
|
||||
"public": false,
|
||||
"request_networking": false,
|
||||
"request_capabilities": [],
|
||||
"grant_capabilities": [],
|
||||
"wit_version": 0
|
||||
},
|
||||
"cat.wasm": {
|
||||
"root": false,
|
||||
"public": false,
|
||||
@ -33,6 +25,14 @@
|
||||
"grant_capabilities": [],
|
||||
"wit_version": 0
|
||||
},
|
||||
"echo.wasm": {
|
||||
"root": false,
|
||||
"public": false,
|
||||
"request_networking": false,
|
||||
"request_capabilities": [],
|
||||
"grant_capabilities": [],
|
||||
"wit_version": 0
|
||||
},
|
||||
"hi.wasm": {
|
||||
"root": false,
|
||||
"public": false,
|
||||
@ -45,6 +45,23 @@
|
||||
],
|
||||
"wit_version": 0
|
||||
},
|
||||
"kfetch.wasm": {
|
||||
"root": true,
|
||||
"public": false,
|
||||
"request_networking": false,
|
||||
"grant_capabilities": [
|
||||
"eth:distro:sys",
|
||||
"kernel:distro:sys",
|
||||
"net:distro:sys"
|
||||
],
|
||||
"wit_version": 0
|
||||
},
|
||||
"kill.wasm": {
|
||||
"root": true,
|
||||
"public": false,
|
||||
"request_networking": false,
|
||||
"wit_version": 0
|
||||
},
|
||||
"m.wasm": {
|
||||
"root": true,
|
||||
"public": true,
|
||||
@ -100,13 +117,9 @@
|
||||
"wit_version": 0
|
||||
},
|
||||
"top.wasm": {
|
||||
"root": false,
|
||||
"root": true,
|
||||
"public": false,
|
||||
"request_networking": false,
|
||||
"request_capabilities": [
|
||||
"kernel:distro:sys"
|
||||
],
|
||||
"grant_capabilities": [],
|
||||
"wit_version": 0
|
||||
}
|
||||
}
|
@ -71,6 +71,14 @@ fn init(our: Address) {
|
||||
"hi".to_string(),
|
||||
ProcessId::new(Some("hi"), "terminal", "sys"),
|
||||
),
|
||||
(
|
||||
"kill".to_string(),
|
||||
ProcessId::new(Some("kill"), "terminal", "sys"),
|
||||
),
|
||||
(
|
||||
"kfetch".to_string(),
|
||||
ProcessId::new(Some("kfetch"), "terminal", "sys"),
|
||||
),
|
||||
(
|
||||
"m".to_string(),
|
||||
ProcessId::new(Some("m"), "terminal", "sys"),
|
||||
@ -115,6 +123,7 @@ fn init(our: Address) {
|
||||
Ok(()) => continue,
|
||||
Err(e) => println!("{e}"),
|
||||
}
|
||||
// checks for a request from a terminal script (different process, same package)
|
||||
} else if state.our.node == source.node && state.our.package() == source.package() {
|
||||
let Ok(action) = serde_json::from_slice::<TerminalAction>(&body) else {
|
||||
println!("failed to parse action from: {}", source);
|
||||
@ -226,6 +235,8 @@ fn handle_run(our: &Address, process: &ProcessId, args: String) -> anyhow::Resul
|
||||
})?)
|
||||
.send()?;
|
||||
}
|
||||
// inherits the blob from the previous request, `_bytes_response`,
|
||||
// containing the wasm byte code of the process
|
||||
Request::new()
|
||||
.target(("our", "kernel", "distro", "sys"))
|
||||
.body(serde_json::to_vec(&kt::KernelCommand::InitializeProcess {
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "top"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
@ -8,7 +8,7 @@ simulation-mode = []
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "09dc9f9" }
|
||||
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "010e175" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
wit-bindgen = "0.24.0"
|
||||
|
@ -1,6 +1,8 @@
|
||||
use kinode_process_lib::kernel_types::{KernelCommand, KernelPrint};
|
||||
use kinode_process_lib::kernel_types::{
|
||||
KernelCommand, KernelPrint, KernelPrintResponse, KernelResponse, PersistedProcess,
|
||||
};
|
||||
use kinode_process_lib::{
|
||||
await_next_message_body, call_init, println, Address, ProcessId, Request,
|
||||
await_next_message_body, call_init, println, Address, Message, ProcessId, Request,
|
||||
};
|
||||
|
||||
wit_bindgen::generate!({
|
||||
@ -20,25 +22,76 @@ fn init(_our: Address) {
|
||||
return;
|
||||
};
|
||||
|
||||
if proc_id.is_empty() {
|
||||
let _ = Request::new()
|
||||
.target(("our", "kernel", "distro", "sys"))
|
||||
.body(serde_json::to_vec(&KernelCommand::Debug(KernelPrint::ProcessMap)).unwrap())
|
||||
.send();
|
||||
} else {
|
||||
match proc_id.parse::<ProcessId>() {
|
||||
Ok(proc_id) => {
|
||||
let _ = Request::new()
|
||||
.target(("our", "kernel", "distro", "sys"))
|
||||
.body(
|
||||
serde_json::to_vec(&KernelCommand::Debug(KernelPrint::Process(proc_id)))
|
||||
.unwrap(),
|
||||
)
|
||||
.send();
|
||||
let Ok(Message::Response { body, .. }) = Request::new()
|
||||
.target(("our", "kernel", "distro", "sys"))
|
||||
.body(if proc_id.is_empty() {
|
||||
serde_json::to_vec(&KernelCommand::Debug(KernelPrint::ProcessMap)).unwrap()
|
||||
} else {
|
||||
match proc_id.parse::<ProcessId>() {
|
||||
Ok(proc_id) => {
|
||||
serde_json::to_vec(&KernelCommand::Debug(KernelPrint::Process(proc_id)))
|
||||
.unwrap()
|
||||
}
|
||||
Err(_) => {
|
||||
println!("invalid process id");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
println!("invalid process id");
|
||||
})
|
||||
.send_and_await_response(60)
|
||||
.unwrap()
|
||||
else {
|
||||
println!("failed to get response from kernel");
|
||||
return;
|
||||
};
|
||||
let Ok(KernelResponse::Debug(kernel_print_response)) =
|
||||
serde_json::from_slice::<KernelResponse>(&body)
|
||||
else {
|
||||
println!("failed to parse kernel response");
|
||||
return;
|
||||
};
|
||||
|
||||
match kernel_print_response {
|
||||
KernelPrintResponse::ProcessMap(process_map) => {
|
||||
let len = process_map.len();
|
||||
let printout = process_map
|
||||
.iter()
|
||||
.map(|(proc_id, process)| print_process(proc_id, process))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\r\n");
|
||||
println!("\r\n{printout}\r\n\r\ntop: {len} running processes");
|
||||
}
|
||||
KernelPrintResponse::Process(process) => match process {
|
||||
None => {
|
||||
println!("process {} not running", proc_id);
|
||||
return;
|
||||
}
|
||||
Some(process) => {
|
||||
println!("{}", print_process(&proc_id.parse().unwrap(), &process));
|
||||
}
|
||||
},
|
||||
KernelPrintResponse::HasCap(_) => {
|
||||
println!("kernel gave wrong kind of response");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_process(id: &ProcessId, process: &PersistedProcess) -> String {
|
||||
format!(
|
||||
"{}:\r\n {}\r\n wit: {}\r\n on-exit: {:?}\r\n public: {}\r\n capabilities: {:?}",
|
||||
id,
|
||||
if process.wasm_bytes_handle.is_empty() {
|
||||
"(runtime)"
|
||||
} else {
|
||||
&process.wasm_bytes_handle
|
||||
},
|
||||
process.wit_version.unwrap_or_default(),
|
||||
process.on_exit,
|
||||
process.public,
|
||||
process
|
||||
.capabilities
|
||||
.iter()
|
||||
.map(|c| c.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
)
|
||||
}
|
||||
|
27
kinode/packages/tester/api/tester:sys-v0.wit
Normal file
27
kinode/packages/tester/api/tester:sys-v0.wit
Normal file
@ -0,0 +1,27 @@
|
||||
interface tester {
|
||||
variant request {
|
||||
run(run-request),
|
||||
}
|
||||
|
||||
variant response {
|
||||
run(result<_, fail-response>)
|
||||
}
|
||||
|
||||
record run-request {
|
||||
input-node-names: list<string>,
|
||||
test-names: list<string>,
|
||||
test-timeout: u64,
|
||||
}
|
||||
|
||||
record fail-response {
|
||||
test: string,
|
||||
file: string,
|
||||
line: u32,
|
||||
column: u32,
|
||||
}
|
||||
}
|
||||
|
||||
world tester-sys-v0 {
|
||||
import tester;
|
||||
include process-v0;
|
||||
}
|
556
kinode/packages/tester/test_runner/Cargo.lock
generated
556
kinode/packages/tester/test_runner/Cargo.lock
generated
@ -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.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
||||
|
||||
[[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.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "433de089bd45971eecf4668ee0ee8f4cec17db4f8bd8f7bc3197a6ce37aa7d9b"
|
||||
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.6"
|
||||
source = "git+https://github.com/kinode-dao/process_lib?rev=fccb6a0#fccb6a0c07ebda3e385bff7f76e4984b741f01c7"
|
||||
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.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
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 = "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.196"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.196"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.113"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
||||
|
||||
[[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 = "test_runner"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
"kinode_process_lib",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[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.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
||||
|
||||
[[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.41.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e09bca7d6388637d27fb5edbeab11f56bfabcef8743c55ae34370e1e5030a071"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-metadata"
|
||||
version = "0.10.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c853d3809fc9fccf3bc0ad63f4f51d8eefad0bacf88f957aa991c1d9b88b016e"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"spdx",
|
||||
"wasm-encoder 0.41.0",
|
||||
"wasmparser 0.121.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.121.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "953cf6a7606ab31382cb1caa5ae403e77ba70c7f8e12eeda167e7040d42bfda8"
|
||||
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",
|
||||
]
|
@ -1,172 +0,0 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use kinode_process_lib::{
|
||||
await_message, call_init, our_capabilities, println, spawn, vfs,
|
||||
vfs::{DirEntry, FileType},
|
||||
Address, Message, OnExit, ProcessId, Request, Response,
|
||||
};
|
||||
|
||||
mod tester_types;
|
||||
use tester_types as tt;
|
||||
|
||||
wit_bindgen::generate!({
|
||||
path: "target/wit",
|
||||
world: "process-v0",
|
||||
});
|
||||
|
||||
fn make_vfs_address(our: &Address) -> anyhow::Result<Address> {
|
||||
Ok(Address::new(
|
||||
our.node.clone(),
|
||||
ProcessId::from_str("vfs:distro:sys")?,
|
||||
))
|
||||
}
|
||||
|
||||
fn handle_message(our: &Address) -> anyhow::Result<()> {
|
||||
let message = await_message()?;
|
||||
|
||||
match message {
|
||||
Message::Response { .. } => {
|
||||
return Err(tt::TesterError::UnexpectedResponse.into());
|
||||
}
|
||||
Message::Request { ref body, .. } => {
|
||||
match serde_json::from_slice(body)? {
|
||||
tt::TesterRequest::Run {
|
||||
ref test_names,
|
||||
test_timeout,
|
||||
..
|
||||
} => {
|
||||
println!("test_runner: got Run");
|
||||
|
||||
let dir_prefix = "tester:sys/tests";
|
||||
|
||||
let response = Request::new()
|
||||
.target(make_vfs_address(&our)?)
|
||||
.body(serde_json::to_vec(&vfs::VfsRequest {
|
||||
path: dir_prefix.into(),
|
||||
action: vfs::VfsAction::ReadDir,
|
||||
})?)
|
||||
.send_and_await_response(test_timeout)??;
|
||||
|
||||
let Message::Response { body: vfs_body, .. } = response else {
|
||||
fail!("test_runner");
|
||||
};
|
||||
let vfs::VfsResponse::ReadDir(mut children) =
|
||||
serde_json::from_slice(&vfs_body)?
|
||||
else {
|
||||
println!(
|
||||
"{:?}",
|
||||
serde_json::from_slice::<serde_json::Value>(&vfs_body)?
|
||||
);
|
||||
fail!("test_runner");
|
||||
};
|
||||
|
||||
for test_name in test_names {
|
||||
let test_entry = DirEntry {
|
||||
path: format!("{}/{}.wasm", dir_prefix, test_name),
|
||||
file_type: FileType::File,
|
||||
};
|
||||
if !children.contains(&test_entry) {
|
||||
return Err(anyhow::anyhow!(
|
||||
"test {} not found amongst {:?}",
|
||||
test_name,
|
||||
children,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let caps_file_path = format!("{}/grant_capabilities.json", dir_prefix);
|
||||
let caps_index = children.iter().position(|i| *i.path == *caps_file_path);
|
||||
let caps_by_child: std::collections::HashMap<String, Vec<String>> =
|
||||
match caps_index {
|
||||
None => std::collections::HashMap::new(),
|
||||
Some(caps_index) => {
|
||||
children.remove(caps_index);
|
||||
let file = vfs::file::open_file(&caps_file_path, false, None)?;
|
||||
let file_contents = file.read()?;
|
||||
serde_json::from_slice(&file_contents)?
|
||||
}
|
||||
};
|
||||
|
||||
println!("test_runner: running {:?}...", children);
|
||||
|
||||
for test_name in test_names {
|
||||
let test_path = format!("{}/{}.wasm", dir_prefix, test_name);
|
||||
let grant_caps = caps_by_child
|
||||
.get(test_name)
|
||||
.and_then(|caps| {
|
||||
Some(
|
||||
caps.iter()
|
||||
.map(|cap| ProcessId::from_str(cap).unwrap())
|
||||
.collect(),
|
||||
)
|
||||
})
|
||||
.unwrap_or(vec![]);
|
||||
let child_process_id = match spawn(
|
||||
None,
|
||||
&test_path,
|
||||
OnExit::None, // TODO: notify us
|
||||
our_capabilities(),
|
||||
grant_caps,
|
||||
false, // not public
|
||||
) {
|
||||
Ok(child_process_id) => child_process_id,
|
||||
Err(e) => {
|
||||
println!("couldn't spawn {}: {}", test_path, e);
|
||||
fail!("test_runner");
|
||||
}
|
||||
};
|
||||
|
||||
let response = Request::new()
|
||||
.target(Address {
|
||||
node: our.node.clone(),
|
||||
process: child_process_id,
|
||||
})
|
||||
.body(body.clone())
|
||||
.send_and_await_response(test_timeout)??;
|
||||
|
||||
let Message::Response { body, .. } = response else {
|
||||
fail!("test_runner");
|
||||
};
|
||||
match serde_json::from_slice(&body)? {
|
||||
tt::TesterResponse::Pass => {}
|
||||
tt::TesterResponse::GetFullMessage(_) => {}
|
||||
tt::TesterResponse::Fail {
|
||||
test,
|
||||
file,
|
||||
line,
|
||||
column,
|
||||
} => {
|
||||
fail!(test, file, line, column);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("test_runner: done running {:?}", children);
|
||||
|
||||
Response::new()
|
||||
.body(serde_json::to_vec(&tt::TesterResponse::Pass)?)
|
||||
.send()?;
|
||||
}
|
||||
tt::TesterRequest::KernelMessage(_) | tt::TesterRequest::GetFullMessage(_) => {
|
||||
fail!("test_runner");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
call_init!(init);
|
||||
fn init(our: Address) {
|
||||
println!("{}: begin", our);
|
||||
|
||||
loop {
|
||||
match handle_message(&our) {
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
println!("test_runner: error: {:?}", e);
|
||||
fail!("test_runner");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
../../tester_types.rs
|
@ -9,8 +9,8 @@ simulation-mode = []
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
bincode = "1.3.3"
|
||||
indexmap = "2.1"
|
||||
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "09dc9f9" }
|
||||
process_macros = { git = "https://github.com/kinode-dao/process_macros", rev = "626e501" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
thiserror = "1.0"
|
||||
|
@ -1,21 +1,24 @@
|
||||
use indexmap::map::IndexMap;
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::kinode::process::tester::{
|
||||
FailResponse, Request as TesterRequest, Response as TesterResponse, RunRequest,
|
||||
};
|
||||
use kinode_process_lib::kernel_types as kt;
|
||||
use kinode_process_lib::{
|
||||
await_message, call_init, our_capabilities, println, spawn, vfs, Address, Message, OnExit,
|
||||
ProcessId, Request, Response,
|
||||
};
|
||||
|
||||
mod tester_types;
|
||||
use tester_types as tt;
|
||||
mod tester_lib;
|
||||
|
||||
wit_bindgen::generate!({
|
||||
path: "target/wit",
|
||||
world: "process-v0",
|
||||
world: "tester-sys-v0",
|
||||
generate_unused_types: true,
|
||||
additional_derives: [PartialEq, serde::Deserialize, serde::Serialize, process_macros::SerdeJsonInto],
|
||||
});
|
||||
|
||||
type Messages = IndexMap<kt::Message, tt::KernelMessage>;
|
||||
|
||||
fn make_vfs_address(our: &Address) -> anyhow::Result<Address> {
|
||||
Ok(Address {
|
||||
node: our.node.clone(),
|
||||
@ -23,88 +26,172 @@ fn make_vfs_address(our: &Address) -> anyhow::Result<Address> {
|
||||
})
|
||||
}
|
||||
|
||||
fn handle_message(
|
||||
fn handle_response(message: &Message) -> anyhow::Result<()> {
|
||||
let TesterResponse::Run(_) = message.body().try_into()?;
|
||||
let source = message.source();
|
||||
if (source.process.package_name != "tester") || (source.process.publisher_node != "sys") {
|
||||
println!(
|
||||
"got Response from unexpected source: {}; must be in package test:sys",
|
||||
source,
|
||||
);
|
||||
fail!("tester");
|
||||
}
|
||||
Response::new().body(message.body()).send().unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_caps_by_child(
|
||||
dir_prefix: &str,
|
||||
children: &mut Vec<vfs::DirEntry>,
|
||||
) -> anyhow::Result<HashMap<String, Vec<String>>> {
|
||||
let caps_file_path = format!("{}/grant_capabilities.json", dir_prefix);
|
||||
let caps_index = children.iter().position(|i| *i.path == *caps_file_path);
|
||||
let caps_by_child: HashMap<String, Vec<String>> = match caps_index {
|
||||
None => HashMap::new(),
|
||||
Some(caps_index) => {
|
||||
children.remove(caps_index);
|
||||
let file = vfs::file::open_file(&caps_file_path, false, None)?;
|
||||
let file_contents = file.read()?;
|
||||
serde_json::from_slice(&file_contents)?
|
||||
}
|
||||
};
|
||||
Ok(caps_by_child)
|
||||
}
|
||||
|
||||
fn handle_request(
|
||||
our: &Address,
|
||||
_messages: &mut Messages,
|
||||
message: &Message,
|
||||
node_names: &mut Vec<String>,
|
||||
) -> anyhow::Result<()> {
|
||||
let TesterRequest::Run(RunRequest {
|
||||
input_node_names,
|
||||
ref test_names,
|
||||
test_timeout,
|
||||
}) = message.body().try_into()?;
|
||||
println!("got Run");
|
||||
|
||||
assert!(input_node_names.len() >= 1);
|
||||
*node_names = input_node_names.clone();
|
||||
|
||||
if our.node != node_names[0] {
|
||||
// we are not the master node
|
||||
Response::new()
|
||||
.body(TesterResponse::Run(Ok(())))
|
||||
.send()
|
||||
.unwrap();
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// we are the master node
|
||||
let dir_prefix = "tester:sys/tests";
|
||||
|
||||
let response = Request::new()
|
||||
.target(make_vfs_address(&our)?)
|
||||
.body(serde_json::to_vec(&vfs::VfsRequest {
|
||||
path: dir_prefix.into(),
|
||||
action: vfs::VfsAction::ReadDir,
|
||||
})?)
|
||||
.send_and_await_response(test_timeout)??;
|
||||
|
||||
let Message::Response { body: vfs_body, .. } = response else {
|
||||
fail!("tester");
|
||||
};
|
||||
let vfs::VfsResponse::ReadDir(mut children) = serde_json::from_slice(&vfs_body)? else {
|
||||
println!(
|
||||
"{:?}",
|
||||
serde_json::from_slice::<serde_json::Value>(&vfs_body)?
|
||||
);
|
||||
fail!("tester");
|
||||
};
|
||||
|
||||
for test_name in test_names {
|
||||
let test_entry = vfs::DirEntry {
|
||||
path: format!("{}/{}.wasm", dir_prefix, test_name),
|
||||
file_type: vfs::FileType::File,
|
||||
};
|
||||
if !children.contains(&test_entry) {
|
||||
return Err(anyhow::anyhow!(
|
||||
"test {} not found amongst {:?}",
|
||||
test_name,
|
||||
children,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let caps_by_child = read_caps_by_child(dir_prefix, &mut children)?;
|
||||
|
||||
println!("tester: running {:?}...", children);
|
||||
|
||||
for test_name in test_names {
|
||||
let test_path = format!("{}/{}.wasm", dir_prefix, test_name);
|
||||
let grant_caps = caps_by_child
|
||||
.get(test_name)
|
||||
.and_then(|caps| {
|
||||
Some(
|
||||
caps.iter()
|
||||
.map(|cap| ProcessId::from_str(cap).unwrap())
|
||||
.collect(),
|
||||
)
|
||||
})
|
||||
.unwrap_or(vec![]);
|
||||
let child_process_id = match spawn(
|
||||
None,
|
||||
&test_path,
|
||||
OnExit::None, // TODO: notify us
|
||||
our_capabilities(),
|
||||
grant_caps,
|
||||
false, // not public
|
||||
) {
|
||||
Ok(child_process_id) => child_process_id,
|
||||
Err(e) => {
|
||||
println!("couldn't spawn {}: {}", test_path, e);
|
||||
fail!("tester");
|
||||
}
|
||||
};
|
||||
|
||||
let response = Request::new()
|
||||
.target(Address {
|
||||
node: our.node.clone(),
|
||||
process: child_process_id,
|
||||
})
|
||||
.body(message.body())
|
||||
.send_and_await_response(test_timeout)??;
|
||||
|
||||
if response.is_request() {
|
||||
fail!("tester");
|
||||
};
|
||||
let TesterResponse::Run(result) = response.body().try_into()?;
|
||||
if let Err(FailResponse {
|
||||
test,
|
||||
file,
|
||||
line,
|
||||
column,
|
||||
}) = result
|
||||
{
|
||||
fail!(test, file, line, column);
|
||||
}
|
||||
}
|
||||
|
||||
println!("test_runner: done running {:?}", children);
|
||||
|
||||
Response::new().body(TesterResponse::Run(Ok(()))).send()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_message(our: &Address, node_names: &mut Vec<String>) -> anyhow::Result<()> {
|
||||
let Ok(message) = await_message() else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
match message {
|
||||
Message::Response { source, body, .. } => {
|
||||
match serde_json::from_slice(&body)? {
|
||||
tt::TesterResponse::Pass | tt::TesterResponse::Fail { .. } => {
|
||||
if (source.process.package_name != "tester")
|
||||
| (source.process.publisher_node != "sys")
|
||||
{
|
||||
return Err(tt::TesterError::UnexpectedResponse.into());
|
||||
}
|
||||
Response::new().body(body).send().unwrap();
|
||||
}
|
||||
tt::TesterResponse::GetFullMessage(_) => {
|
||||
fail!("tester");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Message::Request { body, .. } => {
|
||||
match serde_json::from_slice(&body)? {
|
||||
tt::TesterRequest::Run {
|
||||
input_node_names,
|
||||
test_timeout,
|
||||
..
|
||||
} => {
|
||||
println!("got Run");
|
||||
|
||||
assert!(input_node_names.len() >= 1);
|
||||
*node_names = input_node_names.clone();
|
||||
|
||||
if our.node != node_names[0] {
|
||||
Response::new()
|
||||
.body(serde_json::to_vec(&tt::TesterResponse::Pass).unwrap())
|
||||
.send()
|
||||
.unwrap();
|
||||
} else {
|
||||
// we are master node
|
||||
let child = "/tester:sys/pkg/test_runner.wasm";
|
||||
let child_process_id = match spawn(
|
||||
None,
|
||||
child,
|
||||
OnExit::None, // TODO: notify us
|
||||
our_capabilities(),
|
||||
vec!["vfs:distro:sys".parse::<ProcessId>().unwrap()],
|
||||
false, // not public
|
||||
) {
|
||||
Ok(child_process_id) => child_process_id,
|
||||
Err(e) => {
|
||||
println!("couldn't spawn {}: {}", child, e);
|
||||
fail!("tester");
|
||||
}
|
||||
};
|
||||
Request::new()
|
||||
.target(Address {
|
||||
node: our.node.clone(),
|
||||
process: child_process_id,
|
||||
})
|
||||
.body(body)
|
||||
.expects_response(test_timeout * 2)
|
||||
.send()?;
|
||||
}
|
||||
}
|
||||
tt::TesterRequest::KernelMessage(_) | tt::TesterRequest::GetFullMessage(_) => {
|
||||
fail!("tester");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
if !message.is_request() {
|
||||
return handle_response(&message);
|
||||
}
|
||||
return handle_request(our, &message, node_names);
|
||||
}
|
||||
|
||||
call_init!(init);
|
||||
fn init(our: Address) {
|
||||
let mut messages: Messages = IndexMap::new();
|
||||
let mut node_names: Vec<String> = Vec::new();
|
||||
match Request::new()
|
||||
.target(make_vfs_address(&our).unwrap())
|
||||
@ -154,7 +241,7 @@ fn init(our: Address) {
|
||||
}
|
||||
|
||||
loop {
|
||||
match handle_message(&our, &mut messages, &mut node_names) {
|
||||
match handle_message(&our, &mut node_names) {
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
println!("tester: error: {:?}", e,);
|
||||
|
29
kinode/packages/tester/tester/src/tester_lib.rs
Normal file
29
kinode/packages/tester/tester/src/tester_lib.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use crate::kinode::process::tester::{FailResponse, Response as TesterResponse};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! fail {
|
||||
($test:expr) => {
|
||||
Response::new()
|
||||
.body(TesterResponse::Run(Err(FailResponse {
|
||||
test: $test.into(),
|
||||
file: file!().into(),
|
||||
line: line!(),
|
||||
column: column!(),
|
||||
})))
|
||||
.send()
|
||||
.unwrap();
|
||||
panic!("")
|
||||
};
|
||||
($test:expr, $file:expr, $line:expr, $column:expr) => {
|
||||
Response::new()
|
||||
.body(TesterResponse::Run(Err(FailResponse {
|
||||
test: $test.into(),
|
||||
file: $file.into(),
|
||||
line: $line,
|
||||
column: $column,
|
||||
})))
|
||||
.send()
|
||||
.unwrap();
|
||||
panic!("")
|
||||
};
|
||||
}
|
@ -1 +0,0 @@
|
||||
../../tester_types.rs
|
31
kinode/packages/tester/tester_lib.rs
Normal file
31
kinode/packages/tester/tester_lib.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use crate::kinode::process::tester::{
|
||||
Response as TesterResponse, FailResponse,
|
||||
};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! fail {
|
||||
($test:expr) => {
|
||||
Response::new()
|
||||
.body(TesterResponse::Run(Err(FailResponse {
|
||||
test: $test.into(),
|
||||
file: file!().into(),
|
||||
line: line!(),
|
||||
column: column!(),
|
||||
})))
|
||||
.send()
|
||||
.unwrap();
|
||||
panic!("")
|
||||
};
|
||||
($test:expr, $file:expr, $line:expr, $column:expr) => {
|
||||
Response::new()
|
||||
.body(TesterResponse::Run(Err(FailResponse {
|
||||
test: $test.into(),
|
||||
file: $file.into(),
|
||||
line: $line,
|
||||
column: $column,
|
||||
})))
|
||||
.send()
|
||||
.unwrap();
|
||||
panic!("")
|
||||
};
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use kinode_process_lib::kernel_types as kt;
|
||||
use kinode_process_lib::Address;
|
||||
|
||||
type Rsvp = Option<Address>;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct KernelMessage {
|
||||
pub id: u64,
|
||||
pub source: Address,
|
||||
pub target: Address,
|
||||
pub rsvp: Rsvp,
|
||||
pub message: kt::Message,
|
||||
pub lazy_load_blob: Option<kt::LazyLoadBlob>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum TesterRequest {
|
||||
Run {
|
||||
input_node_names: Vec<String>,
|
||||
test_names: Vec<String>,
|
||||
test_timeout: u64,
|
||||
},
|
||||
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()
|
||||
.body(
|
||||
serde_json::to_vec(&tt::TesterResponse::Fail {
|
||||
test: $test.into(),
|
||||
file: file!().into(),
|
||||
line: line!(),
|
||||
column: column!(),
|
||||
})
|
||||
.unwrap(),
|
||||
)
|
||||
.send()
|
||||
.unwrap();
|
||||
panic!("")
|
||||
};
|
||||
($test:expr, $file:expr, $line:expr, $column:expr) => {
|
||||
Response::new()
|
||||
.body(
|
||||
serde_json::to_vec(&tt::TesterResponse::Fail {
|
||||
test: $test.into(),
|
||||
file: $file.into(),
|
||||
line: $line,
|
||||
column: $column,
|
||||
})
|
||||
.unwrap(),
|
||||
)
|
||||
.send()
|
||||
.unwrap();
|
||||
panic!("")
|
||||
};
|
||||
}
|
@ -27,8 +27,6 @@ pub fn _verify_auth_token(auth_token: &str, jwt_secret: &[u8]) -> Result<String,
|
||||
return Err(jwt::Error::Format);
|
||||
};
|
||||
|
||||
println!("hello\r");
|
||||
|
||||
let claims: Result<JwtClaims, jwt::Error> = auth_token.verify_with_key(&secret);
|
||||
|
||||
match claims {
|
||||
|
@ -520,52 +520,47 @@ async fn handle_kernel_request(
|
||||
.await
|
||||
.expect("event loop: fatal: sender died");
|
||||
}
|
||||
t::KernelCommand::Debug(kind) => match kind {
|
||||
t::KernelPrint::ProcessMap => {
|
||||
let mut process_map_string = "".to_string();
|
||||
for (id, process) in &mut *process_map {
|
||||
process_map_string.push_str(&format!("{}: {}\r\n", id, process));
|
||||
}
|
||||
let _ = send_to_terminal
|
||||
.send(t::Printout {
|
||||
verbosity: 0,
|
||||
content: format!("kernel process map:\r\n{process_map_string}\r\nfound {} running processes", process_map.len()),
|
||||
})
|
||||
.await;
|
||||
}
|
||||
t::KernelPrint::Process(process_id) => {
|
||||
let Some(proc) = process_map.get(&process_id) else {
|
||||
let _ = send_to_terminal
|
||||
.send(t::Printout {
|
||||
verbosity: 0,
|
||||
content: format!("kernel: no such running process {}", process_id),
|
||||
})
|
||||
.await;
|
||||
return None;
|
||||
};
|
||||
let _ = send_to_terminal
|
||||
.send(t::Printout {
|
||||
verbosity: 0,
|
||||
content: format!("process info for {process_id}:\r\n{proc}",),
|
||||
})
|
||||
.await;
|
||||
}
|
||||
t::KernelPrint::HasCap { on, cap } => {
|
||||
let _ = send_to_terminal
|
||||
.send(t::Printout {
|
||||
verbosity: 0,
|
||||
content: format!(
|
||||
"process {} has cap:\r\n{}",
|
||||
on,
|
||||
process_map
|
||||
.get(&on)
|
||||
.map(|p| p.capabilities.contains_key(&cap))
|
||||
.unwrap_or(false)
|
||||
),
|
||||
})
|
||||
.await;
|
||||
}
|
||||
},
|
||||
t::KernelCommand::Debug(kind) => {
|
||||
let response = match kind {
|
||||
t::KernelPrint::ProcessMap => t::KernelPrintResponse::ProcessMap(
|
||||
process_map
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k, v.into()))
|
||||
.collect(),
|
||||
),
|
||||
t::KernelPrint::Process(process_id) => t::KernelPrintResponse::Process(
|
||||
process_map.get(&process_id).cloned().map(|p| p.into()),
|
||||
),
|
||||
t::KernelPrint::HasCap { on, cap } => t::KernelPrintResponse::HasCap(
|
||||
process_map
|
||||
.get(&on)
|
||||
.map(|p| p.capabilities.contains_key(&cap)),
|
||||
),
|
||||
};
|
||||
send_to_loop
|
||||
.send(t::KernelMessage {
|
||||
id: km.id,
|
||||
source: t::Address {
|
||||
node: our_name.clone(),
|
||||
process: KERNEL_PROCESS_ID.clone(),
|
||||
},
|
||||
target: km.rsvp.unwrap_or(km.source),
|
||||
rsvp: None,
|
||||
message: t::Message::Response((
|
||||
t::Response {
|
||||
inherit: false,
|
||||
body: serde_json::to_vec(&t::KernelResponse::Debug(response)).unwrap(),
|
||||
metadata: None,
|
||||
capabilities: vec![],
|
||||
},
|
||||
None,
|
||||
)),
|
||||
lazy_load_blob: None,
|
||||
})
|
||||
.await
|
||||
.expect("event loop: fatal: sender died");
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
@ -395,7 +395,7 @@ async fn main() {
|
||||
match res {
|
||||
Ok(_) => "graceful exit".into(),
|
||||
Err(e) => format!(
|
||||
"uh oh, a kernel process crashed -- this should never happen: {e:?}"
|
||||
"runtime crash: {e:?}"
|
||||
),
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ use tokio::sync::mpsc;
|
||||
/// if target is a peer, queue to be routed
|
||||
/// otherwise, create peer and initiate routing
|
||||
pub async fn send_to_peer(ext: &IdentityExt, data: &NetData, km: KernelMessage) {
|
||||
// println!("send_to_peer\r");
|
||||
if let Some(peer) = data.peers.get_mut(&km.target.node) {
|
||||
peer.sender.send(km).expect("net: peer sender was dropped");
|
||||
} else {
|
||||
@ -46,7 +45,6 @@ async fn connect_to_peer(
|
||||
peer_id: Identity,
|
||||
peer_rx: mpsc::UnboundedReceiver<KernelMessage>,
|
||||
) {
|
||||
println!("connect_to_peer\r");
|
||||
if peer_id.is_direct() {
|
||||
utils::print_debug(
|
||||
&ext.print_tx,
|
||||
@ -81,7 +79,6 @@ async fn connect_via_router(
|
||||
peer_id: &Identity,
|
||||
mut peer_rx: mpsc::UnboundedReceiver<KernelMessage>,
|
||||
) {
|
||||
println!("connect_via_router\r");
|
||||
let routers_shuffled = {
|
||||
let mut routers = match peer_id.routing {
|
||||
NodeRouting::Routers(ref routers) => routers.clone(),
|
||||
@ -131,7 +128,6 @@ pub async fn handle_failed_connection(
|
||||
peer_id: &Identity,
|
||||
mut peer_rx: mpsc::UnboundedReceiver<KernelMessage>,
|
||||
) {
|
||||
println!("handle_failed_connection\r");
|
||||
utils::print_debug(
|
||||
&ext.print_tx,
|
||||
&format!("net: failed to connect to {}", peer_id.name),
|
||||
|
@ -4,7 +4,6 @@ use lib::types::core::{Identity, NodeRouting};
|
||||
use tokio::{sync::mpsc, time};
|
||||
|
||||
pub async fn maintain_routers(ext: IdentityExt, data: NetData) -> anyhow::Result<()> {
|
||||
println!("maintain_routers\r");
|
||||
let NodeRouting::Routers(ref routers) = ext.our.routing else {
|
||||
return Err(anyhow::anyhow!("net: no routers to maintain"));
|
||||
};
|
||||
@ -25,7 +24,6 @@ pub async fn maintain_routers(ext: IdentityExt, data: NetData) -> anyhow::Result
|
||||
}
|
||||
|
||||
pub async fn connect_to_router(router_id: &Identity, ext: &IdentityExt, data: &NetData) {
|
||||
println!("connect_to_router\r");
|
||||
utils::print_debug(
|
||||
&ext.print_tx,
|
||||
&format!("net: attempting to connect to router {}", router_id.name),
|
||||
|
@ -34,7 +34,6 @@ pub async fn networking(
|
||||
kernel_message_rx: MessageReceiver,
|
||||
_reveal_ip: bool, // only used if indirect
|
||||
) -> anyhow::Result<()> {
|
||||
println!("networking\r\n");
|
||||
let ext = IdentityExt {
|
||||
our: Arc::new(our),
|
||||
our_ip: Arc::new(our_ip),
|
||||
@ -116,7 +115,6 @@ async fn local_recv(
|
||||
mut kernel_message_rx: MessageReceiver,
|
||||
data: NetData,
|
||||
) -> anyhow::Result<()> {
|
||||
println!("local_recv\r\n");
|
||||
while let Some(km) = kernel_message_rx.recv().await {
|
||||
if km.target.node == ext.our.name {
|
||||
// handle messages sent to us
|
||||
@ -306,7 +304,6 @@ async fn handle_remote_request(
|
||||
request_body: &[u8],
|
||||
data: &NetData,
|
||||
) -> anyhow::Result<()> {
|
||||
println!("handle_remote_request\r");
|
||||
match rmp_serde::from_slice::<NetAction>(request_body) {
|
||||
Ok(NetAction::KnsBatchUpdate(_)) | Ok(NetAction::KnsUpdate(_)) => {
|
||||
// for now, we don't get these from remote, only locally.
|
||||
|
@ -82,7 +82,6 @@ pub async fn init_direct(
|
||||
proxy_request: bool,
|
||||
peer_rx: mpsc::UnboundedReceiver<KernelMessage>,
|
||||
) -> Result<(), mpsc::UnboundedReceiver<KernelMessage>> {
|
||||
println!("tcp_init_direct\r");
|
||||
match time::timeout(
|
||||
TIMEOUT,
|
||||
connect_with_handshake(ext, peer_id, port, None, proxy_request),
|
||||
@ -113,7 +112,6 @@ pub async fn init_routed(
|
||||
router_port: u16,
|
||||
peer_rx: mpsc::UnboundedReceiver<KernelMessage>,
|
||||
) -> Result<(), mpsc::UnboundedReceiver<KernelMessage>> {
|
||||
println!("tcp_init_routed\r");
|
||||
match time::timeout(
|
||||
TIMEOUT,
|
||||
connect_with_handshake(ext, peer_id, router_port, Some(router_id), false),
|
||||
@ -148,7 +146,6 @@ async fn recv_connection(
|
||||
data: NetData,
|
||||
mut stream: TcpStream,
|
||||
) -> anyhow::Result<()> {
|
||||
println!("tcp_recv_connection\r");
|
||||
// before we begin XX handshake pattern, check first message over socket
|
||||
let (len, first_message) = utils::recv_raw(&mut stream).await?;
|
||||
|
||||
@ -235,7 +232,6 @@ async fn connect_with_handshake(
|
||||
use_router: Option<&Identity>,
|
||||
proxy_request: bool,
|
||||
) -> anyhow::Result<PeerConnection> {
|
||||
println!("tcp_connect_with_handshake\r");
|
||||
let ip = match use_router {
|
||||
None => peer_id
|
||||
.get_ip()
|
||||
@ -315,7 +311,6 @@ pub async fn recv_via_router(
|
||||
peer_id: Identity,
|
||||
router_id: Identity,
|
||||
) {
|
||||
println!("tcp_recv_via_router\r");
|
||||
let Some((ip, port)) = router_id.tcp_routing() else {
|
||||
return;
|
||||
};
|
||||
@ -358,7 +353,6 @@ async fn connect_with_handshake_via_router(
|
||||
router_id: &Identity,
|
||||
mut stream: TcpStream,
|
||||
) -> anyhow::Result<PeerConnection> {
|
||||
println!("tcp_connect_with_handshake_via_router\r");
|
||||
// before beginning XX handshake pattern, send a routing request
|
||||
utils::send_raw(
|
||||
&mut stream,
|
||||
|
@ -6,7 +6,7 @@ use crate::net::{
|
||||
use lib::types::core::{KernelMessage, MessageSender, NodeId, PrintSender};
|
||||
use {
|
||||
tokio::io::{AsyncReadExt, AsyncWriteExt},
|
||||
tokio::net::TcpStream,
|
||||
tokio::net::{tcp::OwnedReadHalf, tcp::OwnedWriteHalf, TcpStream},
|
||||
tokio::sync::mpsc::UnboundedReceiver,
|
||||
};
|
||||
|
||||
@ -19,8 +19,6 @@ pub async fn maintain_connection(
|
||||
kernel_message_tx: MessageSender,
|
||||
print_tx: PrintSender,
|
||||
) {
|
||||
println!("tcp_maintain_connection\r");
|
||||
|
||||
let sock_ref = socket2::SockRef::from(&conn.stream);
|
||||
let mut ka = socket2::TcpKeepalive::new();
|
||||
ka = ka.with_time(std::time::Duration::from_secs(30));
|
||||
@ -29,110 +27,111 @@ pub async fn maintain_connection(
|
||||
.set_tcp_keepalive(&ka)
|
||||
.expect("failed to set tcp keepalive");
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
maybe_recv = peer_rx.recv() => {
|
||||
let Some(km) = maybe_recv else {
|
||||
break
|
||||
};
|
||||
let Ok(()) = send_protocol_message(&km, &mut conn).await else {
|
||||
break
|
||||
};
|
||||
},
|
||||
outer_len = recv_protocol_message_init(&mut conn.stream) => {
|
||||
match outer_len {
|
||||
Ok((read, outer_len)) => match recv_protocol_message(&mut conn, read, outer_len).await {
|
||||
Ok(km) => {
|
||||
if km.source.node != peer_name {
|
||||
print_loud(
|
||||
&print_tx,
|
||||
&format!(
|
||||
"net: got message with spoofed source from {peer_name}!"
|
||||
),
|
||||
).await;
|
||||
break
|
||||
} else {
|
||||
kernel_message_tx.send(km).await.expect("net: fatal: kernel receiver died");
|
||||
continue
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
print_debug(&print_tx, &format!("net: error receiving message: {e}")).await;
|
||||
break
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
print_debug(&print_tx, &format!("net: error receiving message: {e}")).await;
|
||||
break
|
||||
let (mut read_stream, mut write_stream) = conn.stream.into_split();
|
||||
let initiator = conn.noise.is_initiator();
|
||||
let snow::CipherStates(c1, c2) = conn.noise.extract_cipherstates();
|
||||
let (mut our_cipher, mut their_cipher) = if initiator {
|
||||
// if initiator, we write with first and read with second
|
||||
(c1, c2)
|
||||
} else {
|
||||
// if responder, we read with first and write with second
|
||||
(c2, c1)
|
||||
};
|
||||
|
||||
let write_buf = &mut [0; 65536];
|
||||
let write = async move {
|
||||
while let Some(km) = peer_rx.recv().await {
|
||||
let Ok(()) =
|
||||
send_protocol_message(&km, &mut our_cipher, write_buf, &mut write_stream).await
|
||||
else {
|
||||
break;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
let read_buf = &mut conn.buf;
|
||||
let read_peer_name = peer_name.clone();
|
||||
let read_print_tx = print_tx.clone();
|
||||
let read = async move {
|
||||
loop {
|
||||
match recv_protocol_message(&mut their_cipher, read_buf, &mut read_stream).await {
|
||||
Ok(km) => {
|
||||
if km.source.node != read_peer_name {
|
||||
print_loud(
|
||||
&read_print_tx,
|
||||
&format!("net: got message with spoofed source from {read_peer_name}!"),
|
||||
)
|
||||
.await;
|
||||
break;
|
||||
} else {
|
||||
kernel_message_tx
|
||||
.send(km)
|
||||
.await
|
||||
.expect("net: fatal: kernel receiver died");
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
print_debug(
|
||||
&read_print_tx,
|
||||
&format!("net: error receiving message: {e}"),
|
||||
)
|
||||
.await;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
tokio::select! {
|
||||
_ = write => (),
|
||||
_ = read => (),
|
||||
}
|
||||
let _ = conn.stream.shutdown().await;
|
||||
|
||||
print_debug(&print_tx, &format!("net: connection lost with {peer_name}")).await;
|
||||
peers.remove(&peer_name);
|
||||
}
|
||||
|
||||
async fn send_protocol_message(
|
||||
km: &KernelMessage,
|
||||
conn: &mut PeerConnection,
|
||||
cipher: &mut snow::CipherState,
|
||||
buf: &mut [u8],
|
||||
stream: &mut OwnedWriteHalf,
|
||||
) -> anyhow::Result<()> {
|
||||
println!(
|
||||
"initiatior: {}, sending_nonce: {}, receiving_nonce: {}\r",
|
||||
conn.noise.is_initiator(),
|
||||
conn.noise.sending_nonce(),
|
||||
conn.noise.receiving_nonce()
|
||||
);
|
||||
let serialized = rmp_serde::to_vec(km)?;
|
||||
if serialized.len() > MESSAGE_MAX_SIZE as usize {
|
||||
return Err(anyhow::anyhow!("message too large"));
|
||||
}
|
||||
|
||||
let outer_len = (serialized.len() as u32).to_be_bytes();
|
||||
conn.stream.write_all(&outer_len).await?;
|
||||
stream.write_all(&outer_len).await?;
|
||||
|
||||
// 65519 = 65535 - 16 (TAGLEN)
|
||||
for payload in serialized.chunks(65519) {
|
||||
let len = conn.noise.write_message(payload, &mut conn.buf)? as u16;
|
||||
conn.stream.write_all(&len.to_be_bytes()).await?;
|
||||
conn.stream.write_all(&conn.buf[..len as usize]).await?;
|
||||
let len = cipher.encrypt(payload, buf)? as u16;
|
||||
stream.write_all(&len.to_be_bytes()).await?;
|
||||
stream.write_all(&buf[..len as usize]).await?;
|
||||
}
|
||||
Ok(conn.stream.flush().await?)
|
||||
}
|
||||
|
||||
async fn recv_protocol_message_init(stream: &mut TcpStream) -> anyhow::Result<(usize, [u8; 4])> {
|
||||
let mut outer_len = [0; 4];
|
||||
let read = stream.read(&mut outer_len).await?;
|
||||
Ok((read, outer_len))
|
||||
Ok(stream.flush().await?)
|
||||
}
|
||||
|
||||
/// any error in receiving a message will result in the connection being closed.
|
||||
async fn recv_protocol_message(
|
||||
conn: &mut PeerConnection,
|
||||
already_read: usize,
|
||||
mut outer_len: [u8; 4],
|
||||
cipher: &mut snow::CipherState,
|
||||
buf: &mut [u8],
|
||||
stream: &mut OwnedReadHalf,
|
||||
) -> anyhow::Result<KernelMessage> {
|
||||
// fill out the rest of outer_len depending on how many bytes were read
|
||||
if already_read < 4 {
|
||||
conn.stream
|
||||
.read_exact(&mut outer_len[already_read..])
|
||||
.await?;
|
||||
}
|
||||
let outer_len = u32::from_be_bytes(outer_len) as usize;
|
||||
stream.read_exact(&mut buf[..4]).await?;
|
||||
let outer_len = u32::from_be_bytes(buf[..4].try_into().unwrap()) as usize;
|
||||
|
||||
let mut msg = vec![0; outer_len];
|
||||
let mut ptr = 0;
|
||||
while ptr < outer_len {
|
||||
let mut inner_len = [0; 2];
|
||||
conn.stream.read_exact(&mut inner_len).await?;
|
||||
stream.read_exact(&mut inner_len).await?;
|
||||
let inner_len = u16::from_be_bytes(inner_len);
|
||||
conn.stream
|
||||
.read_exact(&mut conn.buf[..inner_len as usize])
|
||||
.await?;
|
||||
let read_len = conn
|
||||
.noise
|
||||
.read_message(&conn.buf[..inner_len as usize], &mut msg[ptr..])?;
|
||||
|
||||
stream.read_exact(&mut buf[..inner_len as usize]).await?;
|
||||
let read_len = cipher.decrypt(&buf[..inner_len as usize], &mut msg[ptr..])?;
|
||||
ptr += read_len;
|
||||
}
|
||||
Ok(rmp_serde::from_slice(&msg)?)
|
||||
@ -169,6 +168,7 @@ pub async fn recv_protocol_handshake(
|
||||
let mut len = [0; 2];
|
||||
stream.read_exact(&mut len).await?;
|
||||
let msg_len = u16::from_be_bytes(len);
|
||||
|
||||
let mut msg = vec![0; msg_len as usize];
|
||||
stream.read_exact(&mut msg).await?;
|
||||
|
||||
|
@ -36,7 +36,6 @@ pub async fn create_passthrough(
|
||||
pending_passthroughs: &PendingPassthroughs,
|
||||
socket_1: PendingStream,
|
||||
) -> anyhow::Result<()> {
|
||||
println!("create_passthrough\r");
|
||||
// if the target has already generated a pending passthrough for this source,
|
||||
// immediately match them
|
||||
if let Some(((_target, _from), pending_stream)) =
|
||||
@ -111,7 +110,6 @@ pub async fn create_passthrough(
|
||||
|
||||
/// cross the streams -- spawn on own task
|
||||
pub async fn maintain_passthrough(socket_1: PendingStream, socket_2: PendingStream) {
|
||||
println!("maintain_passthrough\r");
|
||||
match (socket_1, socket_2) {
|
||||
(PendingStream::Tcp(socket_1), PendingStream::Tcp(socket_2)) => {
|
||||
// do not use bidirectional because if one side closes,
|
||||
@ -204,7 +202,6 @@ pub fn validate_routing_request(
|
||||
buf: &[u8],
|
||||
pki: &OnchainPKI,
|
||||
) -> anyhow::Result<(Identity, Identity)> {
|
||||
println!("validate_routing_request\r");
|
||||
let routing_request: RoutingRequest = rmp_serde::from_slice(buf)?;
|
||||
let from_id = pki
|
||||
.get(&routing_request.source)
|
||||
@ -255,6 +252,7 @@ pub fn build_responder() -> (snow::HandshakeState, Vec<u8>) {
|
||||
(
|
||||
builder
|
||||
.local_private_key(&keypair.private)
|
||||
.unwrap()
|
||||
.build_responder()
|
||||
.expect("net: couldn't build responder?"),
|
||||
keypair.public,
|
||||
@ -269,6 +267,7 @@ pub fn build_initiator() -> (snow::HandshakeState, Vec<u8>) {
|
||||
(
|
||||
builder
|
||||
.local_private_key(&keypair.private)
|
||||
.unwrap()
|
||||
.build_initiator()
|
||||
.expect("net: couldn't build initiator?"),
|
||||
keypair.public,
|
||||
|
@ -95,7 +95,6 @@ pub async fn init_direct(
|
||||
proxy_request: bool,
|
||||
peer_rx: mpsc::UnboundedReceiver<KernelMessage>,
|
||||
) -> Result<(), mpsc::UnboundedReceiver<KernelMessage>> {
|
||||
println!("init_direct\r");
|
||||
match time::timeout(
|
||||
TIMEOUT,
|
||||
connect_with_handshake(ext, peer_id, port, None, proxy_request),
|
||||
@ -126,7 +125,6 @@ pub async fn init_routed(
|
||||
router_port: u16,
|
||||
peer_rx: mpsc::UnboundedReceiver<KernelMessage>,
|
||||
) -> Result<(), mpsc::UnboundedReceiver<KernelMessage>> {
|
||||
println!("init_routed\r");
|
||||
match time::timeout(
|
||||
TIMEOUT,
|
||||
connect_with_handshake(ext, peer_id, router_port, Some(router_id), false),
|
||||
@ -164,7 +162,6 @@ pub async fn recv_via_router(
|
||||
peer_id: Identity,
|
||||
router_id: Identity,
|
||||
) {
|
||||
println!("recv_via_router\r");
|
||||
let Some((ip, port)) = router_id.ws_routing() else {
|
||||
return;
|
||||
};
|
||||
@ -206,7 +203,6 @@ async fn recv_connection(
|
||||
data: NetData,
|
||||
mut socket: WebSocket,
|
||||
) -> anyhow::Result<()> {
|
||||
println!("recv_connection\r");
|
||||
// before we begin XX handshake pattern, check first message over socket
|
||||
let first_message = &utils::recv(&mut socket).await?;
|
||||
|
||||
@ -293,7 +289,6 @@ async fn connect_with_handshake(
|
||||
use_router: Option<&Identity>,
|
||||
proxy_request: bool,
|
||||
) -> anyhow::Result<PeerConnection> {
|
||||
println!("connect_with_handshake\r");
|
||||
let mut buf = vec![0u8; 65535];
|
||||
let (mut noise, our_static_key) = build_initiator();
|
||||
|
||||
@ -375,7 +370,6 @@ async fn connect_with_handshake_via_router(
|
||||
router_id: &Identity,
|
||||
mut socket: WebSocketStream<MaybeTlsStream<TcpStream>>,
|
||||
) -> anyhow::Result<PeerConnection> {
|
||||
println!("connect_with_handshake_via_router\r");
|
||||
// before beginning XX handshake pattern, send a routing request
|
||||
socket
|
||||
.send(tungstenite::Message::binary(rmp_serde::to_vec(
|
||||
|
@ -10,6 +10,9 @@ use {
|
||||
tokio_tungstenite::tungstenite,
|
||||
};
|
||||
|
||||
type WsWriteHalf = futures::stream::SplitSink<WebSocket, tungstenite::Message>;
|
||||
type WsReadHalf = futures::stream::SplitStream<WebSocket>;
|
||||
|
||||
/// should always be spawned on its own task
|
||||
pub async fn maintain_connection(
|
||||
peer_name: NodeId,
|
||||
@ -19,85 +22,101 @@ pub async fn maintain_connection(
|
||||
kernel_message_tx: MessageSender,
|
||||
print_tx: PrintSender,
|
||||
) {
|
||||
println!("maintain_connection\r");
|
||||
let mut last_message = std::time::Instant::now();
|
||||
loop {
|
||||
tokio::select! {
|
||||
recv_result = recv_protocol_message(&mut conn) => {
|
||||
match recv_result {
|
||||
Ok(km) => {
|
||||
if km.source.node != peer_name {
|
||||
print_loud(
|
||||
&print_tx,
|
||||
&format!(
|
||||
"net: got message with spoofed source from {peer_name}!"
|
||||
),
|
||||
).await;
|
||||
break
|
||||
} else {
|
||||
kernel_message_tx.send(km).await.expect("net error: fatal: kernel receiver died");
|
||||
last_message = std::time::Instant::now();
|
||||
continue
|
||||
}
|
||||
let (mut write_stream, mut read_stream) = conn.socket.split();
|
||||
let initiator = conn.noise.is_initiator();
|
||||
let snow::CipherStates(c1, c2) = conn.noise.extract_cipherstates();
|
||||
let (mut our_cipher, mut their_cipher) = if initiator {
|
||||
// if initiator, we write with first and read with second
|
||||
(c1, c2)
|
||||
} else {
|
||||
// if responder, we read with first and write with second
|
||||
(c2, c1)
|
||||
};
|
||||
|
||||
}
|
||||
Err(_) => break
|
||||
}
|
||||
},
|
||||
maybe_recv = peer_rx.recv() => {
|
||||
match maybe_recv {
|
||||
Some(km) => {
|
||||
match send_protocol_message(&km, &mut conn).await {
|
||||
Ok(()) => {
|
||||
last_message = std::time::Instant::now();
|
||||
continue
|
||||
}
|
||||
Err(e) => {
|
||||
if e.to_string() == "message too large" {
|
||||
// this will result in a Timeout if the message
|
||||
// requested a response, otherwise nothing. so,
|
||||
// we should always print something to terminal
|
||||
print_loud(
|
||||
&print_tx,
|
||||
&format!(
|
||||
"net: tried to send too-large message, limit is {:.2}mb",
|
||||
MESSAGE_MAX_SIZE as f64 / 1_048_576.0
|
||||
),
|
||||
).await;
|
||||
}
|
||||
break
|
||||
}
|
||||
let write_buf = &mut [0; 65536];
|
||||
let write_print_tx = print_tx.clone();
|
||||
let write = async move {
|
||||
loop {
|
||||
tokio::select! {
|
||||
Some(km) = peer_rx.recv() => {
|
||||
if let Err(e) =
|
||||
send_protocol_message(&km, &mut our_cipher, write_buf, &mut write_stream).await
|
||||
{
|
||||
if e.to_string() == "message too large" {
|
||||
// this will result in a Timeout if the message
|
||||
// requested a response, otherwise nothing. so,
|
||||
// we should always print something to terminal
|
||||
print_loud(
|
||||
&write_print_tx,
|
||||
&format!(
|
||||
"net: tried to send too-large message, limit is {:.2}mb",
|
||||
MESSAGE_MAX_SIZE as f64 / 1_048_576.0
|
||||
),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
break;
|
||||
}
|
||||
None => break
|
||||
}
|
||||
},
|
||||
// keepalive ping -- can adjust time based on testing
|
||||
_ = tokio::time::sleep(std::time::Duration::from_secs(30)) => {
|
||||
match conn.socket.send(tungstenite::Message::Ping(vec![])).await {
|
||||
Ok(()) => continue,
|
||||
Err(_) => break,
|
||||
}
|
||||
}
|
||||
// if a message has not been sent or received in 2 hours, close the connection
|
||||
_ = tokio::time::sleep(std::time::Duration::from_secs(7200)) => {
|
||||
if last_message.elapsed().as_secs() > 7200 {
|
||||
break
|
||||
// keepalive ping -- note that we don't look for pongs
|
||||
// just to close if the connection is truly dead
|
||||
_ = tokio::time::sleep(std::time::Duration::from_secs(30)) => {
|
||||
match write_stream.send(tungstenite::Message::Ping(vec![])).await {
|
||||
Ok(()) => continue,
|
||||
Err(_) => break,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let close_msg = match conn.socket.close(None).await {
|
||||
Ok(()) => format!("net: connection with {peer_name} closed"),
|
||||
Err(e) => format!("net: connection with {peer_name} closed: {e}"),
|
||||
};
|
||||
print_debug(&print_tx, &close_msg).await;
|
||||
|
||||
let read_buf = &mut conn.buf;
|
||||
let read_peer_name = peer_name.clone();
|
||||
let read_print_tx = print_tx.clone();
|
||||
let read = async move {
|
||||
loop {
|
||||
match recv_protocol_message(&mut their_cipher, read_buf, &mut read_stream).await {
|
||||
Ok(km) => {
|
||||
if km.source.node != read_peer_name {
|
||||
print_loud(
|
||||
&read_print_tx,
|
||||
&format!("net: got message with spoofed source from {read_peer_name}!"),
|
||||
)
|
||||
.await;
|
||||
break;
|
||||
} else {
|
||||
kernel_message_tx
|
||||
.send(km)
|
||||
.await
|
||||
.expect("net: fatal: kernel receiver died");
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
print_debug(
|
||||
&read_print_tx,
|
||||
&format!("net: error receiving message: {e}"),
|
||||
)
|
||||
.await;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
tokio::select! {
|
||||
_ = write => (),
|
||||
_ = read => (),
|
||||
}
|
||||
|
||||
print_debug(&print_tx, &format!("net: connection lost with {peer_name}")).await;
|
||||
peers.remove(&peer_name);
|
||||
}
|
||||
|
||||
async fn send_protocol_message(
|
||||
km: &KernelMessage,
|
||||
conn: &mut PeerConnection,
|
||||
cipher: &mut snow::CipherState,
|
||||
buf: &mut [u8],
|
||||
stream: &mut WsWriteHalf,
|
||||
) -> anyhow::Result<()> {
|
||||
let serialized = rmp_serde::to_vec(km)?;
|
||||
if serialized.len() > MESSAGE_MAX_SIZE as usize {
|
||||
@ -109,25 +128,27 @@ async fn send_protocol_message(
|
||||
|
||||
// 65519 = 65535 - 16 (TAGLEN)
|
||||
for payload in with_length_prefix.chunks(65519) {
|
||||
let len = conn.noise.write_message(payload, &mut conn.buf)?;
|
||||
conn.socket
|
||||
.feed(tungstenite::Message::binary(&conn.buf[..len]))
|
||||
let len = cipher.encrypt(payload, buf)?;
|
||||
stream
|
||||
.feed(tungstenite::Message::binary(&buf[..len]))
|
||||
.await?;
|
||||
}
|
||||
conn.socket.flush().await?;
|
||||
stream.flush().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// any error in receiving a message will result in the connection being closed.
|
||||
async fn recv_protocol_message(conn: &mut PeerConnection) -> anyhow::Result<KernelMessage> {
|
||||
let outer_len = conn
|
||||
.noise
|
||||
.read_message(&recv(&mut conn.socket).await?, &mut conn.buf)?;
|
||||
async fn recv_protocol_message(
|
||||
cipher: &mut snow::CipherState,
|
||||
buf: &mut [u8],
|
||||
stream: &mut WsReadHalf,
|
||||
) -> anyhow::Result<KernelMessage> {
|
||||
let outer_len = cipher.decrypt(&recv_read_only(stream).await?, buf)?;
|
||||
|
||||
if outer_len < 4 {
|
||||
return Err(anyhow::anyhow!("protocol message too small!"));
|
||||
}
|
||||
let length_bytes = [conn.buf[0], conn.buf[1], conn.buf[2], conn.buf[3]];
|
||||
let length_bytes = [buf[0], buf[1], buf[2], buf[3]];
|
||||
let msg_len = u32::from_be_bytes(length_bytes);
|
||||
if msg_len > MESSAGE_MAX_SIZE {
|
||||
return Err(anyhow::anyhow!("message too large"));
|
||||
@ -135,13 +156,11 @@ async fn recv_protocol_message(conn: &mut PeerConnection) -> anyhow::Result<Kern
|
||||
|
||||
// bad
|
||||
let mut msg = Vec::with_capacity(msg_len as usize);
|
||||
msg.extend_from_slice(&conn.buf[4..outer_len]);
|
||||
msg.extend_from_slice(&buf[4..outer_len]);
|
||||
|
||||
while msg.len() < msg_len as usize {
|
||||
let len = conn
|
||||
.noise
|
||||
.read_message(&recv(&mut conn.socket).await?, &mut conn.buf)?;
|
||||
msg.extend_from_slice(&conn.buf[..len]);
|
||||
let len = cipher.decrypt(&recv_read_only(stream).await?, buf)?;
|
||||
msg.extend_from_slice(&buf[..len]);
|
||||
}
|
||||
|
||||
Ok(rmp_serde::from_slice(&msg)?)
|
||||
@ -196,3 +215,16 @@ pub async fn recv(socket: &mut WebSocket) -> anyhow::Result<Vec<u8>> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Receive a byte array from a read stream. If this returns an error,
|
||||
/// we should close the connection.
|
||||
pub async fn recv_read_only(socket: &mut WsReadHalf) -> anyhow::Result<Vec<u8>> {
|
||||
loop {
|
||||
match socket.next().await {
|
||||
Some(Ok(tungstenite::Message::Ping(_))) => continue,
|
||||
Some(Ok(tungstenite::Message::Pong(_))) => continue,
|
||||
Some(Ok(tungstenite::Message::Binary(bin))) => return Ok(bin),
|
||||
_ => return Err(anyhow::anyhow!("websocket closed")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
135
kinode/src/register-ui/build/assets/index-KlEDwcBC.js
Normal file
135
kinode/src/register-ui/build/assets/index-KlEDwcBC.js
Normal file
File diff suppressed because one or more lines are too long
@ -5,6 +5,8 @@
|
||||
"proxy": "http://localhost:8080",
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||
"@ensdomains/eth-ens-namehash": "^2.0.15",
|
||||
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
|
||||
"@ethersproject/hash": "^5.7.0",
|
||||
"@typechain/ethers-v5": "^11.1.1",
|
||||
"@types/node": "^16.18.50",
|
||||
@ -25,11 +27,11 @@
|
||||
"buffer": "^6.0.3",
|
||||
"classnames": "^2.5.1",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
"eth-ens-namehash": "^2.0.8",
|
||||
"ethers": "^5.7.2",
|
||||
"idna-uts46-hx": "^6.0.4",
|
||||
"is-valid-domain": "^0.1.6",
|
||||
"jazzicon": "^1.5.0",
|
||||
"punycode": "^2.3.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-icons": "^5.0.1",
|
||||
@ -76,4 +78,4 @@
|
||||
"inline-source-cli": "^2.0.0"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import React, { useEffect, useRef } from "react";
|
||||
import { hooks } from "../connectors/metamask";
|
||||
import { NameWrapper, ENSRegistry } from "../abis/types";
|
||||
import isValidDomain from 'is-valid-domain'
|
||||
import { hash } from 'eth-ens-namehash'
|
||||
import { hash } from '@ensdomains/eth-ens-namehash';
|
||||
import { toAscii } from 'idna-uts46-hx'
|
||||
|
||||
const {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { DotOsRegistrar } from "../abis/types";
|
||||
import isValidDomain from "is-valid-domain";
|
||||
import { hash } from "eth-ens-namehash";
|
||||
import hash from "@ensdomains/eth-ens-namehash";
|
||||
import { toAscii } from "idna-uts46-hx";
|
||||
|
||||
type ClaimOsNameProps = {
|
||||
@ -46,7 +46,7 @@ function EnterKnsName({
|
||||
if (index === -1) validities.push(NAME_LENGTH);
|
||||
} else if (index !== -1) validities.splice(index, 1);
|
||||
|
||||
let normalized: string;
|
||||
let normalized = ''
|
||||
index = validities.indexOf(NAME_INVALID_PUNY);
|
||||
try {
|
||||
normalized = toAscii(name + ".os");
|
||||
@ -56,18 +56,21 @@ function EnterKnsName({
|
||||
}
|
||||
|
||||
// only check if name is valid punycode
|
||||
if (normalized! !== undefined) {
|
||||
if (normalized && normalized !== '.os') {
|
||||
index = validities.indexOf(NAME_URL);
|
||||
if (name !== "" && !isValidDomain(normalized)) {
|
||||
if (index === -1) validities.push(NAME_URL);
|
||||
} else if (index !== -1) validities.splice(index, 1);
|
||||
|
||||
index = validities.indexOf(NAME_CLAIMED);
|
||||
if (validities.length === 0 || index !== -1) {
|
||||
|
||||
if (validities.length === 0 || index !== -1 && normalized.length > 2) {
|
||||
try {
|
||||
await dotOs?.ownerOf(hash(normalized));
|
||||
if (index === -1) validities.push(NAME_CLAIMED);
|
||||
const namehash = hash.hash(normalized)
|
||||
const owner = await dotOs?.ownerOf(namehash);
|
||||
if (owner && index === -1) validities.push(NAME_CLAIMED);
|
||||
} catch (e) {
|
||||
console.error({ e })
|
||||
if (index !== -1) validities.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
2
kinode/src/register-ui/src/declarations.d.ts
vendored
2
kinode/src/register-ui/src/declarations.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
declare module 'eth-ens-namehash' {
|
||||
declare module '@ensdomains/eth-ens-namehash' {
|
||||
export function hash(name: string): string;
|
||||
export function normalize(name: string): string;
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ import '@unocss/reset/tailwind.css'
|
||||
import 'uno.css'
|
||||
import './index.css';
|
||||
|
||||
import { Buffer } from 'buffer';
|
||||
window.Buffer = Buffer;
|
||||
|
||||
const connectors: [MetaMask, Web3ReactHooks][] = [
|
||||
[metaMask, metaMaskHooks],
|
||||
]
|
||||
|
@ -8,7 +8,7 @@ import Loader from "../components/Loader";
|
||||
import KinodeHeader from "../components/KnsHeader";
|
||||
import { PageProps } from "../lib/types";
|
||||
import { generateNetworkingKeys, getNetworkName, setChain } from "../utils/chain";
|
||||
import { hash } from "eth-ens-namehash";
|
||||
import { hash } from "@ensdomains/eth-ens-namehash";
|
||||
import DirectCheckbox from "../components/DirectCheckbox";
|
||||
import { MAINNET_OPT_HEX, OPTIMISM_OPT_HEX } from "../constants/chainId";
|
||||
import { KinodeTitle } from "../components/KinodeTitle";
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
import { hooks } from "../connectors/metamask";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { toAscii } from "idna-uts46-hx";
|
||||
import { hash } from "eth-ens-namehash";
|
||||
import { hash } from "@ensdomains/eth-ens-namehash";
|
||||
import isValidDomain from "is-valid-domain";
|
||||
import Loader from "../components/Loader";
|
||||
import KinodeHeader from "../components/KnsHeader";
|
||||
|
@ -2,9 +2,13 @@ import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import UnoCSS from '@unocss/vite'
|
||||
import { presetUno, presetWind, presetIcons, transformerDirectives } from 'unocss'
|
||||
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
NodeGlobalsPolyfillPlugin({
|
||||
buffer: true
|
||||
}),
|
||||
UnoCSS({
|
||||
presets: [presetUno(), presetWind(), presetIcons()],
|
||||
shortcuts: [
|
||||
|
@ -1267,6 +1267,16 @@
|
||||
"@babel/helper-validator-identifier" "^7.24.5"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@ensdomains/eth-ens-namehash@^2.0.15":
|
||||
version "2.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@ensdomains/eth-ens-namehash/-/eth-ens-namehash-2.0.15.tgz#5e5f2f24ba802aff8bc19edd822c9a11200cdf4a"
|
||||
integrity sha512-JRDFP6+Hczb1E0/HhIg0PONgBYasfGfDheujmfxaZaAv/NAH4jE6Kf48WbqfRZdxt4IZI3jl3Ri7sZ1nP09lgw==
|
||||
|
||||
"@esbuild-plugins/node-globals-polyfill@^0.2.3":
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild-plugins/node-globals-polyfill/-/node-globals-polyfill-0.2.3.tgz#0e4497a2b53c9e9485e149bc92ddb228438d6bcf"
|
||||
integrity sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==
|
||||
|
||||
"@esbuild/aix-ppc64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537"
|
||||
@ -4830,14 +4840,6 @@ esutils@^2.0.2:
|
||||
resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
eth-ens-namehash@^2.0.8:
|
||||
version "2.0.8"
|
||||
resolved "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz"
|
||||
integrity sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==
|
||||
dependencies:
|
||||
idna-uts46-hx "^2.3.1"
|
||||
js-sha3 "^0.5.7"
|
||||
|
||||
ethers@^5.7.2:
|
||||
version "5.7.2"
|
||||
resolved "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz"
|
||||
@ -5311,13 +5313,6 @@ idb-keyval@^6.2.1:
|
||||
resolved "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz"
|
||||
integrity sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==
|
||||
|
||||
idna-uts46-hx@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz"
|
||||
integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==
|
||||
dependencies:
|
||||
punycode "2.1.0"
|
||||
|
||||
idna-uts46-hx@^6.0.4:
|
||||
version "6.0.4"
|
||||
resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-6.0.4.tgz#25f9f8af628bd4150b36340e99a1f9532c815905"
|
||||
@ -5686,11 +5681,6 @@ js-sha3@0.8.0, js-sha3@^0.8.0:
|
||||
resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz"
|
||||
integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==
|
||||
|
||||
js-sha3@^0.5.7:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz"
|
||||
integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
|
||||
@ -6603,11 +6593,6 @@ proxy-compare@2.5.1:
|
||||
resolved "https://registry.npmjs.org/proxy-compare/-/proxy-compare-2.5.1.tgz"
|
||||
integrity sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA==
|
||||
|
||||
punycode@2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz"
|
||||
integrity sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==
|
||||
|
||||
punycode@^2.1.1, punycode@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
|
||||
|
@ -43,7 +43,7 @@ pub struct ProcessId {
|
||||
impl Serialize for ProcessId {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::ser::Serializer,
|
||||
S: serde::Serializer,
|
||||
{
|
||||
format!("{}", self).serialize(serializer)
|
||||
}
|
||||
@ -52,7 +52,7 @@ impl Serialize for ProcessId {
|
||||
impl<'a> Deserialize<'a> for ProcessId {
|
||||
fn deserialize<D>(deserializer: D) -> Result<ProcessId, D::Error>
|
||||
where
|
||||
D: serde::de::Deserializer<'a>,
|
||||
D: serde::Deserializer<'a>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
s.parse().map_err(serde::de::Error::custom)
|
||||
@ -1237,6 +1237,14 @@ pub enum KernelResponse {
|
||||
StartedProcess,
|
||||
RunProcessError,
|
||||
KilledProcess(ProcessId),
|
||||
Debug(KernelPrintResponse),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum KernelPrintResponse {
|
||||
ProcessMap(UserspaceProcessMap),
|
||||
Process(Option<UserspacePersistedProcess>),
|
||||
HasCap(Option<bool>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -1282,6 +1290,7 @@ pub enum CapMessage {
|
||||
pub type ReverseCapIndex = HashMap<ProcessId, HashMap<ProcessId, Vec<Capability>>>;
|
||||
|
||||
pub type ProcessMap = HashMap<ProcessId, PersistedProcess>;
|
||||
pub type UserspaceProcessMap = HashMap<ProcessId, UserspacePersistedProcess>;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct PersistedProcess {
|
||||
@ -1292,29 +1301,24 @@ pub struct PersistedProcess {
|
||||
pub public: bool, // marks if a process allows messages from any process
|
||||
}
|
||||
|
||||
impl std::fmt::Display for PersistedProcess {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Process {{\n wasm_bytes_handle: {},\n wit_version: {:?},\n on_exit: {:?},\n public: {}\n capabilities: {}\n}}",
|
||||
{
|
||||
if &self.wasm_bytes_handle == "" {
|
||||
"(none, this is a runtime process)"
|
||||
} else {
|
||||
&self.wasm_bytes_handle
|
||||
}
|
||||
},
|
||||
self.wit_version,
|
||||
self.on_exit,
|
||||
self.public,
|
||||
{
|
||||
let mut caps_string = "[".to_string();
|
||||
for cap in self.capabilities.keys() {
|
||||
caps_string += &format!("\n {}", cap.to_string());
|
||||
}
|
||||
caps_string + "\n ]"
|
||||
},
|
||||
)
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct UserspacePersistedProcess {
|
||||
pub wasm_bytes_handle: String,
|
||||
pub wit_version: Option<u32>,
|
||||
pub on_exit: OnExit,
|
||||
pub capabilities: HashSet<Capability>,
|
||||
pub public: bool,
|
||||
}
|
||||
|
||||
impl From<PersistedProcess> for UserspacePersistedProcess {
|
||||
fn from(p: PersistedProcess) -> Self {
|
||||
UserspacePersistedProcess {
|
||||
wasm_bytes_handle: p.wasm_bytes_handle,
|
||||
wit_version: p.wit_version,
|
||||
on_exit: p.on_exit,
|
||||
capabilities: p.capabilities.into_keys().collect(),
|
||||
public: p.public,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user