mirror of
https://github.com/uqbar-dao/nectar.git
synced 2024-11-23 11:53:05 +03:00
Merge pull request #313 from kinode-dao/dr/settings-page
Add settings page app
This commit is contained in:
commit
76d0adf795
37
Cargo.lock
generated
37
Cargo.lock
generated
@ -3081,6 +3081,28 @@ dependencies = [
|
|||||||
"wit-bindgen",
|
"wit-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "kinode_process_lib"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "git+https://github.com/kinode-dao/process_lib?tag=v0.6.1#37a20b0249dc2c86ae6c2c69cfb199fb177f1520"
|
||||||
|
dependencies = [
|
||||||
|
"alloy-json-rpc 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=6f8ebb4)",
|
||||||
|
"alloy-primitives 0.6.4",
|
||||||
|
"alloy-rpc-types 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=6f8ebb4)",
|
||||||
|
"alloy-transport 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=6f8ebb4)",
|
||||||
|
"anyhow",
|
||||||
|
"bincode",
|
||||||
|
"http 1.1.0",
|
||||||
|
"mime_guess",
|
||||||
|
"rand 0.8.5",
|
||||||
|
"rmp-serde",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
"url",
|
||||||
|
"wit-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kinode_process_lib"
|
name = "kinode_process_lib"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -4812,6 +4834,21 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "settings"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"base64 0.22.0",
|
||||||
|
"bincode",
|
||||||
|
"kinode_process_lib 0.6.1",
|
||||||
|
"rmp-serde",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"url",
|
||||||
|
"wit-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
|
@ -19,6 +19,7 @@ members = [
|
|||||||
"kinode/packages/chess/chess",
|
"kinode/packages/chess/chess",
|
||||||
"kinode/packages/homepage/homepage",
|
"kinode/packages/homepage/homepage",
|
||||||
"kinode/packages/kns_indexer/kns_indexer", "kinode/packages/kns_indexer/get_block", "kinode/packages/kns_indexer/state",
|
"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/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/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/terminal/namehash_to_name", "kinode/packages/terminal/net_diagnostics", "kinode/packages/terminal/peer", "kinode/packages/terminal/peers",
|
||||||
|
@ -5,10 +5,10 @@ use kinode_process_lib::{
|
|||||||
bind_http_path, bind_http_static_path, send_response, serve_ui, HttpServerError,
|
bind_http_path, bind_http_static_path, send_response, serve_ui, HttpServerError,
|
||||||
HttpServerRequest, StatusCode,
|
HttpServerRequest, StatusCode,
|
||||||
},
|
},
|
||||||
println, Address, Message, ProcessId,
|
println, Address, Message,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
/// The request format to add or remove an app from the homepage. You must have messaging
|
/// The request format to add or remove an app from the homepage. You must have messaging
|
||||||
/// access to `homepage:homepage:sys` in order to perform this. Serialize using serde_json.
|
/// access to `homepage:homepage:sys` in order to perform this. Serialize using serde_json.
|
||||||
@ -40,7 +40,7 @@ wit_bindgen::generate!({
|
|||||||
|
|
||||||
call_init!(init);
|
call_init!(init);
|
||||||
fn init(our: Address) {
|
fn init(our: Address) {
|
||||||
let mut app_data: HashMap<ProcessId, HomepageApp> = HashMap::new();
|
let mut app_data: BTreeMap<ProcessId, HomepageApp> = BTreeMap::new();
|
||||||
|
|
||||||
serve_ui(&our, "ui", true, false, vec!["/"]).expect("failed to serve ui");
|
serve_ui(&our, "ui", true, false, vec!["/"]).expect("failed to serve ui");
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ fn init(our: Address) {
|
|||||||
match request {
|
match request {
|
||||||
HomepageRequest::Add { label, icon, path } => {
|
HomepageRequest::Add { label, icon, path } => {
|
||||||
app_data.insert(
|
app_data.insert(
|
||||||
message.source().process.clone(),
|
message.source().process.to_string(),
|
||||||
HomepageApp {
|
HomepageApp {
|
||||||
package_name: message.source().clone().package().to_string(),
|
package_name: message.source().clone().package().to_string(),
|
||||||
path: format!(
|
path: format!(
|
||||||
@ -113,7 +113,7 @@ fn init(our: Address) {
|
|||||||
if path == "/apps" {
|
if path == "/apps" {
|
||||||
send_response(
|
send_response(
|
||||||
StatusCode::OK,
|
StatusCode::OK,
|
||||||
Some(HashMap::from([(
|
Some(std::collections::HashMap::from([(
|
||||||
"Content-Type".to_string(),
|
"Content-Type".to_string(),
|
||||||
"application/json".to_string(),
|
"application/json".to_string(),
|
||||||
)])),
|
)])),
|
||||||
|
16
kinode/packages/settings/metadata.json
Normal file
16
kinode/packages/settings/metadata.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "System Settings",
|
||||||
|
"description": "A program for managing key system settings, including onchain identity.",
|
||||||
|
"image": "",
|
||||||
|
"properties": {
|
||||||
|
"package_name": "settings",
|
||||||
|
"current_version": "0.1.0",
|
||||||
|
"publisher": "sys",
|
||||||
|
"mirrors": [],
|
||||||
|
"code_hashes": {
|
||||||
|
"0.1.0": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"external_url": "https://kinode.org",
|
||||||
|
"animation_url": ""
|
||||||
|
}
|
30
kinode/packages/settings/pkg/manifest.json
Normal file
30
kinode/packages/settings/pkg/manifest.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"process_name": "settings",
|
||||||
|
"process_wasm_path": "/settings.wasm",
|
||||||
|
"on_exit": "Restart",
|
||||||
|
"request_networking": true,
|
||||||
|
"request_capabilities": [
|
||||||
|
"eth:distro:sys",
|
||||||
|
{
|
||||||
|
"process": "eth:distro:sys",
|
||||||
|
"params": {
|
||||||
|
"root": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"homepage:homepage:sys",
|
||||||
|
"http_server:distro:sys",
|
||||||
|
"kernel:distro:sys",
|
||||||
|
"net:distro:sys",
|
||||||
|
"vfs:distro:sys"
|
||||||
|
],
|
||||||
|
"grant_capabilities": [
|
||||||
|
"eth:distro:sys",
|
||||||
|
"http_server:distro:sys",
|
||||||
|
"kernel:distro:sys",
|
||||||
|
"net:distro:sys",
|
||||||
|
"vfs:distro:sys"
|
||||||
|
],
|
||||||
|
"public": false
|
||||||
|
}
|
||||||
|
]
|
76
kinode/packages/settings/pkg/ui/index.html
Normal file
76
kinode/packages/settings/pkg/ui/index.html
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>Kinode Settings</title>
|
||||||
|
<link rel="stylesheet" href="/settings:settings:sys/style.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>system diagnostics & settings</h1>
|
||||||
|
<main>
|
||||||
|
<article id="node-info">
|
||||||
|
<p>node info</p>
|
||||||
|
<p id="node-name"></p>
|
||||||
|
<p id="net-key"></p>
|
||||||
|
<p id="ip-ports"></p>
|
||||||
|
<p id="routers"></p>
|
||||||
|
<button>reset networking key</button>
|
||||||
|
<button>adjust networking info</button>
|
||||||
|
<button id="shutdown">shut down node</button>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article id="net-diagnostics">
|
||||||
|
<p>networking diagnostics</p>
|
||||||
|
<p id="diagnostics"></p>
|
||||||
|
</article>
|
||||||
|
<article id="pings">
|
||||||
|
<p>fetch PKI data</p>
|
||||||
|
<form id="get-peer-pki">
|
||||||
|
<input type="text" name="peer" placeholder="peer-name.os">
|
||||||
|
<button type="submit">get peer info</button>
|
||||||
|
</form>
|
||||||
|
<p id="peer-pki-response"></p>
|
||||||
|
<p>ping a node</p>
|
||||||
|
<form id="ping-peer">
|
||||||
|
<input type="text" name="peer" placeholder="peer-name.os">
|
||||||
|
<input type="text" name="content" placeholder="message">
|
||||||
|
<label><input type="number" name="timeout">timeout (seconds)</label>
|
||||||
|
<button type="submit">ping</button>
|
||||||
|
</form>
|
||||||
|
<p id="peer-ping-response"></p>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article id="eth-rpc-providers">
|
||||||
|
<p>ETH RPC providers</p>
|
||||||
|
<ul id="providers"></ul>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article id="eth-rpc-settings">
|
||||||
|
<p>ETH RPC settings</p>
|
||||||
|
<p id="public"></p>
|
||||||
|
<div>
|
||||||
|
<p>nodes allowed to connect:</p>
|
||||||
|
<ul id="allowed-nodes"></ul>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>nodes banned from connecting:</p>
|
||||||
|
<ul id="denied-nodes"></ul>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article id="kernel">
|
||||||
|
<p>running processes:</p>
|
||||||
|
<p>(TODO)</p>
|
||||||
|
<ul></ul>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="/settings:settings:sys/script.js"></script>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
167
kinode/packages/settings/pkg/ui/script.js
Normal file
167
kinode/packages/settings/pkg/ui/script.js
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
const APP_PATH = '/settings:settings:sys/ask';
|
||||||
|
|
||||||
|
// Fetch initial data and populate the UI
|
||||||
|
function init() {
|
||||||
|
fetch('/our')
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(data => {
|
||||||
|
const our = data + '@settings:settings:sys';
|
||||||
|
fetch(APP_PATH)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
console.log(data);
|
||||||
|
populate(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function api_call(body) {
|
||||||
|
fetch(APP_PATH, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function shutdown() {
|
||||||
|
api_call("Shutdown");
|
||||||
|
}
|
||||||
|
|
||||||
|
function populate(data) {
|
||||||
|
populate_node_info(data.identity);
|
||||||
|
populate_net_diagnostics(data.diagnostics);
|
||||||
|
populate_eth_rpc_providers(data.eth_rpc_providers);
|
||||||
|
populate_eth_rpc_settings(data.eth_rpc_access_settings);
|
||||||
|
// populate_kernel()
|
||||||
|
}
|
||||||
|
|
||||||
|
function populate_node_info(identity) {
|
||||||
|
document.getElementById('node-name').innerText = identity.name;
|
||||||
|
document.getElementById('net-key').innerText = identity.networking_key;
|
||||||
|
if (identity.ws_routing) {
|
||||||
|
document.getElementById('ip-ports').innerText = identity.ws_routing;
|
||||||
|
} else {
|
||||||
|
document.getElementById('ip-ports').style.display = 'none';
|
||||||
|
}
|
||||||
|
if (identity.routers) {
|
||||||
|
document.getElementById('routers').innerText = identity.routers;
|
||||||
|
} else {
|
||||||
|
document.getElementById('routers').style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function populate_net_diagnostics(diagnostics) {
|
||||||
|
document.getElementById('diagnostics').innerText = diagnostics;
|
||||||
|
}
|
||||||
|
|
||||||
|
function populate_eth_rpc_providers(providers) {
|
||||||
|
const ul = document.getElementById('providers');
|
||||||
|
ul.innerHTML = '';
|
||||||
|
providers.forEach(provider => {
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.innerHTML = `<li>${JSON.stringify(provider)}</li>`;
|
||||||
|
ul.appendChild(li);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function populate_eth_rpc_settings(settings) {
|
||||||
|
if (settings.public) {
|
||||||
|
document.getElementById('public').innerText = 'public';
|
||||||
|
document.getElementById('allowed-nodes').style.display = 'none';
|
||||||
|
} else {
|
||||||
|
document.getElementById('public').innerText = 'private';
|
||||||
|
const ul = document.getElementById('allowed-nodes');
|
||||||
|
ul.innerHTML = '';
|
||||||
|
if (settings.allow.length === 0) {
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.innerHTML = `<li>(none)</li>`;
|
||||||
|
ul.appendChild(li);
|
||||||
|
} else {
|
||||||
|
settings.allow.forEach(allowed_node => {
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.innerHTML = `<li>${allowed_node}</li>`;
|
||||||
|
ul.appendChild(li);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const ul = document.getElementById('denied-nodes');
|
||||||
|
ul.innerHTML = '';
|
||||||
|
if (settings.deny.length === 0) {
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.innerHTML = `<li>(none)</li>`;
|
||||||
|
ul.appendChild(li);
|
||||||
|
} else {
|
||||||
|
settings.deny.forEach(denied_node => {
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.innerHTML = `<li>${denied_node}</li>`;
|
||||||
|
ul.appendChild(li);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call init to start the application
|
||||||
|
init();
|
||||||
|
|
||||||
|
// Setup event listeners
|
||||||
|
document.getElementById('shutdown').addEventListener('click', shutdown);
|
||||||
|
|
||||||
|
document.getElementById('get-peer-pki').addEventListener('submit', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const data = new FormData(e.target);
|
||||||
|
const body = {
|
||||||
|
"PeerId": data.get('peer'),
|
||||||
|
};
|
||||||
|
fetch(APP_PATH, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
}).then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data === null) {
|
||||||
|
document.getElementById('peer-pki-response').innerText = "no pki data for peer";
|
||||||
|
} else {
|
||||||
|
document.getElementById('peer-pki-response').innerText = JSON.stringify(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
document.getElementById('ping-peer').addEventListener('submit', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const data = new FormData(e.target);
|
||||||
|
const body = {
|
||||||
|
"Hi": {
|
||||||
|
node: data.get('peer'),
|
||||||
|
content: data.get('content'),
|
||||||
|
timeout: Number(data.get('timeout')),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetch(APP_PATH, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
}).then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data === null) {
|
||||||
|
document.getElementById('peer-ping-response').innerText = "ping successful!";
|
||||||
|
} else if (data === "HiTimeout") {
|
||||||
|
document.getElementById('peer-ping-response').innerText = "node timed out";
|
||||||
|
} else if (data === "HiOffline") {
|
||||||
|
document.getElementById('peer-ping-response').innerText = "node is offline";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
// Setup WebSocket connection
|
||||||
|
const ws = new WebSocket("ws://" + location.host + "/settings:settings:sys/");
|
||||||
|
ws.onmessage = event => {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
console.log(data);
|
||||||
|
populate(data);
|
||||||
|
};
|
||||||
|
|
181
kinode/packages/settings/pkg/ui/style.css
Normal file
181
kinode/packages/settings/pkg/ui/style.css
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
/* CSS Reset from https://www.joshwcomeau.com/css/custom-css-reset/ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Use a more-intuitive box-sizing model.
|
||||||
|
*/
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
2. Remove default margin
|
||||||
|
*/
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Typographic tweaks!
|
||||||
|
3. Add accessible line-height
|
||||||
|
4. Improve text rendering
|
||||||
|
*/
|
||||||
|
body {
|
||||||
|
line-height: 1.5;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
5. Improve media defaults
|
||||||
|
*/
|
||||||
|
img,
|
||||||
|
picture,
|
||||||
|
video,
|
||||||
|
canvas,
|
||||||
|
svg {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
6. Remove built-in form typography styles
|
||||||
|
*/
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
textarea,
|
||||||
|
select {
|
||||||
|
font: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
7. Avoid text overflows
|
||||||
|
*/
|
||||||
|
p,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
8. Create a root stacking context
|
||||||
|
*/
|
||||||
|
#root,
|
||||||
|
#__next {
|
||||||
|
isolation: isolate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Actual styles */
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Courier New', Courier, monospace;
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
padding: 20px;
|
||||||
|
max-width: 1200px;
|
||||||
|
min-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article {
|
||||||
|
background-color: #333;
|
||||||
|
border: 1px solid #444;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
max-height: 600px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Custom scrollbar styles */
|
||||||
|
article::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article::-webkit-scrollbar-track {
|
||||||
|
background: #2c2c2c;
|
||||||
|
}
|
||||||
|
|
||||||
|
article::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #444;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 4px 2px;
|
||||||
|
transition-duration: 0.4s;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: white;
|
||||||
|
color: #4CAF50;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"],
|
||||||
|
input[type="number"],
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 20px;
|
||||||
|
margin: 8px 0;
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="submit"] {
|
||||||
|
background-color: #f44336;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 4px 2px;
|
||||||
|
transition-duration: 0.4s;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="submit"]:hover {
|
||||||
|
background-color: white;
|
||||||
|
color: #f44336;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding: 8px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
background-color: #2c2c2c;
|
||||||
|
border-radius: 4px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
835
kinode/packages/settings/settings/Cargo.lock
generated
Normal file
835
kinode/packages/settings/settings/Cargo.lock
generated
Normal file
@ -0,0 +1,835 @@
|
|||||||
|
# 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 = "autocfg"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||||
|
|
||||||
|
[[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 = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[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 = "chess"
|
||||||
|
version = "0.2.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"base64",
|
||||||
|
"bincode",
|
||||||
|
"kinode_process_lib",
|
||||||
|
"pleco",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"url",
|
||||||
|
"wit-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cloudabi"
|
||||||
|
version = "0.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.8.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||||
|
|
||||||
|
[[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 = "fuchsia-cprng"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||||
|
|
||||||
|
[[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 = "hermit-abi"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f"
|
||||||
|
|
||||||
|
[[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"
|
||||||
|
<<<<<<< HEAD:modules/chess/chess/Cargo.lock
|
||||||
|
version = "0.5.7"
|
||||||
|
source = "git+https://github.com/kinode-dao/process_lib?tag=v0.5.9-alpha#c1ac7227951fbd8cabf6568704f0ce11e8558c8a"
|
||||||
|
=======
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "git+https://github.com/kinode-dao/process_lib?rev=fccb6a0#fccb6a0c07ebda3e385bff7f76e4984b741f01c7"
|
||||||
|
>>>>>>> develop:kinode/packages/chess/chess/Cargo.lock
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bincode",
|
||||||
|
"http",
|
||||||
|
"mime_guess",
|
||||||
|
"rand 0.8.5",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
"url",
|
||||||
|
"wit-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[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 = "mucow"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c55d0c9dc43dedfd2414deb74ade67687749ef88b1d3482024d4c81d901a7a83"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_cpus"
|
||||||
|
version = "1.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "percent-encoding"
|
||||||
|
version = "2.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pleco"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28a8c8ab569c544644c468a63f4fe4b33c0706b1472bebb517fabb75ec0f688e"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"lazy_static",
|
||||||
|
"mucow",
|
||||||
|
"num_cpus",
|
||||||
|
"rand 0.6.5",
|
||||||
|
"rayon",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 0.1.8",
|
||||||
|
"libc",
|
||||||
|
"rand_chacha 0.1.1",
|
||||||
|
"rand_core 0.4.2",
|
||||||
|
"rand_hc",
|
||||||
|
"rand_isaac",
|
||||||
|
"rand_jitter",
|
||||||
|
"rand_os",
|
||||||
|
"rand_pcg",
|
||||||
|
"rand_xorshift",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha 0.3.1",
|
||||||
|
"rand_core 0.6.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 0.1.8",
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 0.6.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.4.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_hc"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_isaac"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_jitter"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_core 0.4.2",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_os"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||||
|
dependencies = [
|
||||||
|
"cloudabi",
|
||||||
|
"fuchsia-cprng",
|
||||||
|
"libc",
|
||||||
|
"rand_core 0.4.2",
|
||||||
|
"rdrand",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_pcg"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 0.1.8",
|
||||||
|
"rand_core 0.4.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_xorshift"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rdrand"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "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 2.4.2",
|
||||||
|
"indexmap",
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.4.2",
|
||||||
|
"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 2.4.2",
|
||||||
|
"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",
|
||||||
|
]
|
24
kinode/packages/settings/settings/Cargo.toml
Normal file
24
kinode/packages/settings/settings/Cargo.toml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
[package]
|
||||||
|
name = "settings"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
simulation-mode = []
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0"
|
||||||
|
base64 = "0.22.0"
|
||||||
|
bincode = "1.3.3"
|
||||||
|
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", tag = "v0.6.1" }
|
||||||
|
rmp-serde = "1.2.0"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
url = "*"
|
||||||
|
wit-bindgen = "0.24.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[package.metadata.component]
|
||||||
|
package = "kinode:process"
|
1
kinode/packages/settings/settings/src/icon
Normal file
1
kinode/packages/settings/settings/src/icon
Normal file
@ -0,0 +1 @@
|
|||||||
|
data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIiA/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSIgd2lkdGg9IjEwODAiIGhlaWdodD0iMTA4MCIgdmlld0JveD0iMCAwIDEwODAgMTA4MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxkZXNjPkNyZWF0ZWQgd2l0aCBGYWJyaWMuanMgNS4yLjQ8L2Rlc2M+CjxkZWZzPgo8L2RlZnM+CjxnIHRyYW5zZm9ybT0ibWF0cml4KDEgMCAwIDEgNTQwIDU0MCkiIGlkPSI0MDhjZjk5Ni0xN2M1LTQxOTctYmVhMy1jNTQwZGJhYTlhZGUiICA+CjxyZWN0IHN0eWxlPSJzdHJva2U6IG5vbmU7IHN0cm9rZS13aWR0aDogMTsgc3Ryb2tlLWRhc2hhcnJheTogbm9uZTsgc3Ryb2tlLWxpbmVjYXA6IGJ1dHQ7IHN0cm9rZS1kYXNob2Zmc2V0OiAwOyBzdHJva2UtbGluZWpvaW46IG1pdGVyOyBzdHJva2UtbWl0ZXJsaW1pdDogNDsgZmlsbDogcmdiKDI1NSwyNTUsMjU1KTsgZmlsbC1ydWxlOiBub256ZXJvOyBvcGFjaXR5OiAxOyB2aXNpYmlsaXR5OiBoaWRkZW47IiB2ZWN0b3ItZWZmZWN0PSJub24tc2NhbGluZy1zdHJva2UiICB4PSItNTQwIiB5PSItNTQwIiByeD0iMCIgcnk9IjAiIHdpZHRoPSIxMDgwIiBoZWlnaHQ9IjEwODAiIC8+CjwvZz4KPGcgdHJhbnNmb3JtPSJtYXRyaXgoMSAwIDAgMSA1NDAgNTQwKSIgaWQ9ImM1MzhkOTdkLWFhNjAtNGRmNi05NzM1LTE4N2FlOGU3ODQwYyIgID4KPC9nPgo8ZyB0cmFuc2Zvcm09Im1hdHJpeChOYU4gTmFOIE5hTiBOYU4gMCAwKSIgID4KPGcgc3R5bGU9IiIgICA+CjwvZz4KPC9nPgo8ZyB0cmFuc2Zvcm09Im1hdHJpeCgyLjExIDAgMCAyLjExIDU0MCA1NDApIiAgPgo8cGF0aCBzdHlsZT0ic3Ryb2tlOiByZ2IoMCwwLDApOyBzdHJva2Utd2lkdGg6IDA7IHN0cm9rZS1kYXNoYXJyYXk6IG5vbmU7IHN0cm9rZS1saW5lY2FwOiBidXR0OyBzdHJva2UtZGFzaG9mZnNldDogMDsgc3Ryb2tlLWxpbmVqb2luOiBtaXRlcjsgc3Ryb2tlLW1pdGVybGltaXQ6IDQ7IGZpbGw6IHJnYigwLDAsMCk7IGZpbGwtcnVsZTogbm9uemVybzsgb3BhY2l0eTogMTsiICB0cmFuc2Zvcm09IiB0cmFuc2xhdGUoLTI1NiwgLTI1NikiIGQ9Ik0gNDEzLjk2NyAyNzYuOCBDIDQxNS4wMjcgMjcwLjU2NSA0MTUuMDI3IDI2My4yODIwMDAwMDAwMDAwNCA0MTUuMDI3IDI1NiBDIDQxNS4wMjcgMjQ4LjcxNzk5OTk5OTk5OTk2IDQxMy45NjcgMjQyLjQ4MiA0MTMuOTY3IDIzNS4yIEwgNDU4LjYzNCAyMDAuODgyIEMgNDYyLjg5NCAxOTcuNzY0IDQ2My45NTMwMDAwMDAwMDAwMyAxOTIuNTY1IDQ2MC43NjQgMTg3LjM2NCBMIDQxOC4yMTUgMTE1LjYgQyA0MTYuMDg1OTk5OTk5OTk5OTYgMTExLjQzNTk5OTk5OTk5OTk5IDQwOS43MDc5OTk5OTk5OTk5NyAxMDkuMzY1IDQwNS40NDggMTExLjQzNTk5OTk5OTk5OTk5IEwgMzUyLjI2MiAxMzIuMjM3IEMgMzQxLjYyNCAxMjMuOTE5IDMyOC44NjggMTE2LjYzNiAzMTYuMTAyIDExMS40MzU5OTk5OTk5OTk5OSBMIDMwOC42NTQgNTYuMzE4OTk5OTk5OTk5OTk2IEMgMzA3LjU5NCA1Mi4xNjQ5OTk5OTk5OTk5OSAzMDMuMzM1IDQ4LjAwMSAyOTguMDE2IDQ4LjAwMSBMIDIxMi45MTggNDguMDAxIEMgMjA3LjYgNDguMDAxIDIwMy4zNDEgNTIuMTY1IDIwMi4yODEgNTYuMzE4OTk5OTk5OTk5OTk2IEwgMTkzLjc3MyAxMTEuNDM1OTk5OTk5OTk5OTkgQyAxODEuMDA2IDExNi42MzYgMTY5LjMwOSAxMjMuOTE3OTk5OTk5OTk5OTkgMTU3LjYwMiAxMzIuMjM3IEwgMTA0LjQxNiAxMTEuNDM1OTk5OTk5OTk5OTkgQyA5OS4wOTcgMTA5LjM2NSA5My43Nzc5OTk5OTk5OTk5OSAxMTEuNDM1OTk5OTk5OTk5OTkgOTEuNjQ5IDExNS42IEwgNDkuMSAxODcuMzY1IEMgNDYuOTgxIDE5MS41MTggNDguMDM5IDE5Ny43NjQgNTEuMjI5IDIwMC44ODMgTCA5Ni45NyAyMzUuMiBDIDk2Ljk3IDI0Mi40ODIgOTUuOTEgMjQ4LjcxOCA5NS45MSAyNTYgQyA5NS45MSAyNjMuMjgyMDAwMDAwMDAwMDQgOTYuOTcgMjY5LjUxODAwMDAwMDAwMDAzIDk2Ljk3IDI3Ni44IEwgNTIuMzAyIDMxMS4xMTggQyA0OC4wNDIgMzE0LjIzNiA0Ni45ODQgMzE5LjQzNSA1MC4xNzIgMzI0LjYzNTk5OTk5OTk5OTk3IEwgOTIuNzIxIDM5Ni40IEMgOTQuODUxIDQwMC41NjM5OTk5OTk5OTk5NiAxMDEuMjI5IDQwMi42MzUgMTA1LjQ4OCA0MDAuNTYzOTk5OTk5OTk5OTYgTCAxNTguNjc1IDM3OS43NjMgQyAxNjkuMzEyIDM4OC4wODA5OTk5OTk5OTk5NiAxODIuMDY5MDAwMDAwMDAwMDIgMzk1LjM2NCAxOTQuODM1IDQwMC41NjM5OTk5OTk5OTk5NiBMIDIwMy4zNDMwMDAwMDAwMDAwMiA0NTUuNjgxIEMgMjA0LjQxMiA0NjAuODgxIDIwOC42NjEwMDAwMDAwMDAwMyA0NjMuOTk4OTk5OTk5OTk5OTcgMjEzLjk4MDAwMDAwMDAwMDAyIDQ2My45OTg5OTk5OTk5OTk5NyBMIDI5OS4wNzgwMDAwMDAwMDAwMyA0NjMuOTk4OTk5OTk5OTk5OTcgQyAzMDQuMzk3MDAwMDAwMDAwMDUgNDYzLjk5ODk5OTk5OTk5OTk3IDMwOC42NTYgNDU5LjgzNSAzMDkuNzE2IDQ1NS42ODEgTCAzMTguMjM0MDAwMDAwMDAwMDQgNDAwLjU2Mzk5OTk5OTk5OTk2IEMgMzMwLjk5MTAwMDAwMDAwMDA0IDM5NS4zNjQgMzQyLjY5ODAwMDAwMDAwMDA0IDM4OC4wODIgMzU0LjM5NCAzNzkuNzYzIEwgNDA3LjU4MSA0MDAuNTYzOTk5OTk5OTk5OTYgQyA0MTIuODk5IDQwMi42MzUgNDE4LjIxOCA0MDAuNTYzOTk5OTk5OTk5OTYgNDIwLjM0OCAzOTYuNCBMIDQ2Mi44OTcgMzI0LjYzNSBDIDQ2NS4wMjYgMzIwLjQ4MTk5OTk5OTk5OTk3IDQ2My45NTcgMzE0LjIzNiA0NjAuNzY3IDMxMS4xMTY5OTk5OTk5OTk5NiBMIDQxMy45NjcgMjc2Ljc5OTk5OTk5OTk5OTk1IHogTSAyNTUuNDY4IDMyOC44IEMgMjEzLjk3ODk5OTk5OTk5OTk4IDMyOC44IDE4MS4wMDc5OTk5OTk5OTk5OCAyOTYuNTY1IDE4MS4wMDc5OTk5OTk5OTk5OCAyNTYgQyAxODEuMDA3OTk5OTk5OTk5OTggMjE1LjQzNSAyMTMuOTc4OTk5OTk5OTk5OTggMTgzLjIgMjU1LjQ2Nzk5OTk5OTk5OTk2IDE4My4yIEMgMjk2Ljk1Njk5OTk5OTk5OTk0IDE4My4yIDMyOS45MjkgMjE1LjQzNSAzMjkuOTI5IDI1NiBDIDMyOS45MjkgMjk2LjU2NSAyOTYuOTU3IDMyOC44IDI1NS40Njc5OTk5OTk5OTk5NiAzMjguOCB6IiBzdHJva2UtbGluZWNhcD0icm91bmQiIC8+CjwvZz4KPC9zdmc+
|
389
kinode/packages/settings/settings/src/lib.rs
Normal file
389
kinode/packages/settings/settings/src/lib.rs
Normal file
@ -0,0 +1,389 @@
|
|||||||
|
use kinode_process_lib::{println, *};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
extern crate base64;
|
||||||
|
|
||||||
|
const ICON: &str = include_str!("icon");
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
enum SettingsRequest {
|
||||||
|
Hi {
|
||||||
|
node: NodeId,
|
||||||
|
content: String,
|
||||||
|
timeout: u64,
|
||||||
|
},
|
||||||
|
PeerId(NodeId),
|
||||||
|
EthConfig(eth::EthConfigAction),
|
||||||
|
Shutdown,
|
||||||
|
KillProcess(ProcessId),
|
||||||
|
}
|
||||||
|
|
||||||
|
type SettingsResponse = Result<Option<SettingsData>, SettingsError>;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
enum SettingsData {
|
||||||
|
PeerId(net::Identity),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
enum SettingsError {
|
||||||
|
HiTimeout,
|
||||||
|
HiOffline,
|
||||||
|
KernelNonresponsive,
|
||||||
|
MalformedRequest,
|
||||||
|
StateFetchFailed,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// never gets persisted
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct SettingsState {
|
||||||
|
pub our: Address,
|
||||||
|
pub ws_clients: HashSet<u32>,
|
||||||
|
pub identity: Option<net::Identity>,
|
||||||
|
pub diagnostics: Option<String>,
|
||||||
|
pub eth_rpc_providers: Option<eth::SavedConfigs>,
|
||||||
|
pub eth_rpc_access_settings: Option<eth::AccessSettings>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SettingsState {
|
||||||
|
fn new(our: Address) -> Self {
|
||||||
|
Self {
|
||||||
|
our,
|
||||||
|
ws_clients: HashSet::new(),
|
||||||
|
identity: None,
|
||||||
|
diagnostics: None,
|
||||||
|
eth_rpc_providers: None,
|
||||||
|
eth_rpc_access_settings: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ws_update(&self) {
|
||||||
|
for channel in &self.ws_clients {
|
||||||
|
http::send_ws_push(
|
||||||
|
*channel,
|
||||||
|
http::WsMessageType::Text,
|
||||||
|
LazyLoadBlob {
|
||||||
|
mime: Some("application/json".to_string()),
|
||||||
|
bytes: serde_json::to_vec(self).unwrap(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// get data that the settings page presents to user
|
||||||
|
/// - get Identity struct from net:distro:sys
|
||||||
|
/// - get ETH RPC providers from eth:distro:sys
|
||||||
|
/// - get ETH RPC access settings from eth:distro:sys
|
||||||
|
/// - get running processes from kernel:distro:sys
|
||||||
|
fn fetch(&mut self) -> anyhow::Result<()> {
|
||||||
|
// identity
|
||||||
|
let Ok(Ok(Message::Response { body, .. })) = Request::to(("our", "net", "distro", "sys"))
|
||||||
|
.body(rmp_serde::to_vec(&net::NetAction::GetPeer(self.our.node.clone())).unwrap())
|
||||||
|
.send_and_await_response(5)
|
||||||
|
else {
|
||||||
|
return Err(anyhow::anyhow!("failed to get identity from net"));
|
||||||
|
};
|
||||||
|
let Ok(net::NetResponse::Peer(Some(identity))) = rmp_serde::from_slice(&body) else {
|
||||||
|
return Err(anyhow::anyhow!("got malformed response from net"));
|
||||||
|
};
|
||||||
|
self.identity = Some(identity);
|
||||||
|
|
||||||
|
// diagnostics string
|
||||||
|
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)
|
||||||
|
else {
|
||||||
|
return Err(anyhow::anyhow!("failed to get diagnostics from net"));
|
||||||
|
};
|
||||||
|
let Ok(net::NetResponse::Diagnostics(diagnostics_string)) = rmp_serde::from_slice(&body)
|
||||||
|
else {
|
||||||
|
return Err(anyhow::anyhow!("got malformed response from net"));
|
||||||
|
};
|
||||||
|
self.diagnostics = Some(diagnostics_string);
|
||||||
|
|
||||||
|
// eth rpc providers
|
||||||
|
let Ok(Ok(Message::Response { body, .. })) = Request::to(("our", "eth", "distro", "sys"))
|
||||||
|
.body(serde_json::to_vec(ð::EthConfigAction::GetProviders).unwrap())
|
||||||
|
.send_and_await_response(5)
|
||||||
|
else {
|
||||||
|
return Err(anyhow::anyhow!("failed to get providers from eth"));
|
||||||
|
};
|
||||||
|
let Ok(eth::EthConfigResponse::Providers(providers)) = serde_json::from_slice(&body) else {
|
||||||
|
return Err(anyhow::anyhow!("got malformed response from eth"));
|
||||||
|
};
|
||||||
|
self.eth_rpc_providers = Some(providers);
|
||||||
|
|
||||||
|
// eth rpc access settings
|
||||||
|
let Ok(Ok(Message::Response { body, .. })) = Request::to(("our", "eth", "distro", "sys"))
|
||||||
|
.body(serde_json::to_vec(ð::EthConfigAction::GetAccessSettings).unwrap())
|
||||||
|
.send_and_await_response(5)
|
||||||
|
else {
|
||||||
|
return Err(anyhow::anyhow!("failed to get access settings from eth"));
|
||||||
|
};
|
||||||
|
let Ok(eth::EthConfigResponse::AccessSettings(access_settings)) =
|
||||||
|
serde_json::from_slice(&body)
|
||||||
|
else {
|
||||||
|
return Err(anyhow::anyhow!("got malformed response from eth"));
|
||||||
|
};
|
||||||
|
self.eth_rpc_access_settings = Some(access_settings);
|
||||||
|
|
||||||
|
// TODO: running processes
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wit_bindgen::generate!({
|
||||||
|
path: "wit",
|
||||||
|
world: "process",
|
||||||
|
});
|
||||||
|
|
||||||
|
call_init!(initialize);
|
||||||
|
fn initialize(our: Address) {
|
||||||
|
// add ourselves to the homepage
|
||||||
|
Request::to(("our", "homepage", "homepage", "sys"))
|
||||||
|
.body(
|
||||||
|
serde_json::json!({
|
||||||
|
"Add": {
|
||||||
|
"label": "Settings",
|
||||||
|
"icon": ICON,
|
||||||
|
"path": "/", // just our root
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.to_string()
|
||||||
|
.as_bytes()
|
||||||
|
.to_vec(),
|
||||||
|
)
|
||||||
|
.send()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Serve the index.html and other UI files found in pkg/ui at the root path.
|
||||||
|
http::serve_ui(&our, "ui", true, false, vec!["/"]).unwrap();
|
||||||
|
http::bind_http_path("/ask", true, false).unwrap();
|
||||||
|
http::bind_ws_path("/", true, false).unwrap();
|
||||||
|
|
||||||
|
// Grab our state, then enter the main event loop.
|
||||||
|
let mut state: SettingsState = SettingsState::new(our);
|
||||||
|
match state.fetch() {
|
||||||
|
Ok(()) => {}
|
||||||
|
Err(e) => {
|
||||||
|
println!("failed to fetch initial state: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
main_loop(&mut state);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main_loop(state: &mut SettingsState) {
|
||||||
|
loop {
|
||||||
|
match await_message() {
|
||||||
|
Err(send_error) => {
|
||||||
|
println!("got send error: {send_error:?}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Ok(Message::Request {
|
||||||
|
source,
|
||||||
|
body,
|
||||||
|
expects_response,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
|
if source.node() != state.our.node {
|
||||||
|
continue; // ignore messages from other nodes
|
||||||
|
}
|
||||||
|
let response = handle_request(&source, &body, state);
|
||||||
|
if expects_response.is_some() {
|
||||||
|
Response::new()
|
||||||
|
.body(serde_json::to_vec(&response).unwrap())
|
||||||
|
.send()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => continue, // ignore responses
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_request(source: &Address, body: &[u8], state: &mut SettingsState) -> SettingsResponse {
|
||||||
|
// source node is ALWAYS ourselves since networking is disabled
|
||||||
|
if source.process == "http_server:distro:sys" {
|
||||||
|
// receive HTTP requests and websocket connection messages from our server
|
||||||
|
match serde_json::from_slice::<http::HttpServerRequest>(body)
|
||||||
|
.map_err(|_| SettingsError::MalformedRequest)?
|
||||||
|
{
|
||||||
|
http::HttpServerRequest::Http(ref incoming) => {
|
||||||
|
match handle_http_request(state, incoming) {
|
||||||
|
Ok(()) => Ok(None),
|
||||||
|
Err(e) => {
|
||||||
|
println!("error handling HTTP request: {e}");
|
||||||
|
http::send_response(
|
||||||
|
http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
None,
|
||||||
|
"Service Unavailable".to_string().as_bytes().to_vec(),
|
||||||
|
);
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
http::HttpServerRequest::WebSocketOpen { channel_id, .. } => {
|
||||||
|
state.ws_clients.insert(channel_id);
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
http::HttpServerRequest::WebSocketClose(channel_id) => {
|
||||||
|
// client frontend closed a websocket
|
||||||
|
state.ws_clients.remove(&channel_id);
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
http::HttpServerRequest::WebSocketPush { .. } => {
|
||||||
|
// client frontend sent a websocket message
|
||||||
|
// we don't expect this! we only use websockets to push updates
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let settings_request = serde_json::from_slice::<SettingsRequest>(body)
|
||||||
|
.map_err(|_| SettingsError::MalformedRequest)?;
|
||||||
|
handle_settings_request(state, settings_request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handle HTTP requests from our own frontend.
|
||||||
|
fn handle_http_request(
|
||||||
|
state: &mut SettingsState,
|
||||||
|
http_request: &http::IncomingHttpRequest,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
match http_request.method()?.as_str() {
|
||||||
|
"GET" => Ok(http::send_response(
|
||||||
|
http::StatusCode::OK,
|
||||||
|
Some(HashMap::from([(
|
||||||
|
String::from("Content-Type"),
|
||||||
|
String::from("application/json"),
|
||||||
|
)])),
|
||||||
|
serde_json::to_vec(&state)?,
|
||||||
|
)),
|
||||||
|
"POST" => {
|
||||||
|
let Some(blob) = get_blob() else {
|
||||||
|
return Ok(http::send_response(
|
||||||
|
http::StatusCode::BAD_REQUEST,
|
||||||
|
None,
|
||||||
|
vec![],
|
||||||
|
));
|
||||||
|
};
|
||||||
|
let request = serde_json::from_slice::<SettingsRequest>(&blob.bytes)?;
|
||||||
|
let response = handle_settings_request(state, request);
|
||||||
|
state.ws_update();
|
||||||
|
Ok(http::send_response(
|
||||||
|
http::StatusCode::OK,
|
||||||
|
None,
|
||||||
|
match response {
|
||||||
|
Ok(Some(data)) => serde_json::to_vec(&data)?,
|
||||||
|
Ok(None) => "null".as_bytes().to_vec(),
|
||||||
|
Err(e) => serde_json::to_vec(&e)?,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
// Any other method will be rejected.
|
||||||
|
_ => Ok(http::send_response(
|
||||||
|
http::StatusCode::METHOD_NOT_ALLOWED,
|
||||||
|
None,
|
||||||
|
vec![],
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_settings_request(
|
||||||
|
state: &mut SettingsState,
|
||||||
|
request: SettingsRequest,
|
||||||
|
) -> SettingsResponse {
|
||||||
|
match request {
|
||||||
|
SettingsRequest::Hi {
|
||||||
|
node,
|
||||||
|
content,
|
||||||
|
timeout,
|
||||||
|
} => {
|
||||||
|
if let Err(SendError { kind, .. }) = Request::to((&node, "net", "distro", "sys"))
|
||||||
|
.body(content.into_bytes())
|
||||||
|
.send_and_await_response(timeout)
|
||||||
|
.unwrap()
|
||||||
|
{
|
||||||
|
match kind {
|
||||||
|
SendErrorKind::Timeout => {
|
||||||
|
println!("message to {node} timed out");
|
||||||
|
return Err(SettingsError::HiTimeout);
|
||||||
|
}
|
||||||
|
SendErrorKind::Offline => {
|
||||||
|
println!("{node} is offline or does not exist");
|
||||||
|
return Err(SettingsError::HiOffline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SettingsRequest::PeerId(node) => {
|
||||||
|
// get peer info
|
||||||
|
match Request::to(("our", "net", "distro", "sys"))
|
||||||
|
.body(rmp_serde::to_vec(&net::NetAction::GetPeer(node)).unwrap())
|
||||||
|
.send_and_await_response(30)
|
||||||
|
.unwrap()
|
||||||
|
{
|
||||||
|
Ok(msg) => match rmp_serde::from_slice::<net::NetResponse>(msg.body()) {
|
||||||
|
Ok(net::NetResponse::Peer(Some(peer))) => {
|
||||||
|
println!("got peer info: {peer:?}");
|
||||||
|
return Ok(Some(SettingsData::PeerId(peer)));
|
||||||
|
}
|
||||||
|
Ok(net::NetResponse::Peer(None)) => {
|
||||||
|
println!("peer not found");
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(SettingsError::KernelNonresponsive);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
return Err(SettingsError::KernelNonresponsive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SettingsRequest::EthConfig(action) => {
|
||||||
|
match Request::to(("our", "eth", "distro", "sys"))
|
||||||
|
.body(serde_json::to_vec(&action).unwrap())
|
||||||
|
.send_and_await_response(30)
|
||||||
|
.unwrap()
|
||||||
|
{
|
||||||
|
Ok(msg) => match serde_json::from_slice::<eth::EthConfigResponse>(msg.body()) {
|
||||||
|
Ok(eth::EthConfigResponse::PermissionDenied) => {
|
||||||
|
return Err(SettingsError::KernelNonresponsive);
|
||||||
|
}
|
||||||
|
Ok(other) => {
|
||||||
|
println!("eth config action succeeded: {other:?}");
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
return Err(SettingsError::KernelNonresponsive);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
return Err(SettingsError::KernelNonresponsive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SettingsRequest::Shutdown => {
|
||||||
|
// shutdown the node IMMEDIATELY!
|
||||||
|
Request::to(("our", "kernel", "distro", "sys"))
|
||||||
|
.body(serde_json::to_vec(&kernel_types::KernelCommand::Shutdown).unwrap())
|
||||||
|
.send()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
SettingsRequest::KillProcess(pid) => {
|
||||||
|
// kill a process
|
||||||
|
if let Err(_) = Request::to(("our", "kernel", "distro", "sys"))
|
||||||
|
.body(serde_json::to_vec(&kernel_types::KernelCommand::KillProcess(pid)).unwrap())
|
||||||
|
.send_and_await_response(30)
|
||||||
|
.unwrap()
|
||||||
|
{
|
||||||
|
return SettingsResponse::Err(SettingsError::KernelNonresponsive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state.fetch().map_err(|_| SettingsError::StateFetchFailed)?;
|
||||||
|
state.ws_update();
|
||||||
|
SettingsResponse::Ok(None)
|
||||||
|
}
|
@ -75,6 +75,7 @@ async fn persist_state(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// handle commands inside messages sent directly to kernel. source is always our own node.
|
/// handle commands inside messages sent directly to kernel. source is always our own node.
|
||||||
|
/// returns Some(()) if the kernel should shut down.
|
||||||
async fn handle_kernel_request(
|
async fn handle_kernel_request(
|
||||||
our_name: String,
|
our_name: String,
|
||||||
keypair: Arc<signature::Ed25519KeyPair>,
|
keypair: Arc<signature::Ed25519KeyPair>,
|
||||||
@ -88,9 +89,9 @@ async fn handle_kernel_request(
|
|||||||
caps_oracle: t::CapMessageSender,
|
caps_oracle: t::CapMessageSender,
|
||||||
engine: &Engine,
|
engine: &Engine,
|
||||||
home_directory_path: &str,
|
home_directory_path: &str,
|
||||||
) {
|
) -> Option<()> {
|
||||||
let t::Message::Request(request) = km.message else {
|
let t::Message::Request(request) = km.message else {
|
||||||
return;
|
return None;
|
||||||
};
|
};
|
||||||
let command: t::KernelCommand = match serde_json::from_slice(&request.body) {
|
let command: t::KernelCommand = match serde_json::from_slice(&request.body) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -100,7 +101,7 @@ async fn handle_kernel_request(
|
|||||||
content: format!("kernel: couldn't parse command: {:?}", e),
|
content: format!("kernel: couldn't parse command: {:?}", e),
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
};
|
};
|
||||||
@ -138,6 +139,7 @@ async fn handle_kernel_request(
|
|||||||
for handle in process_handles.values() {
|
for handle in process_handles.values() {
|
||||||
handle.abort();
|
handle.abort();
|
||||||
}
|
}
|
||||||
|
return Some(());
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// initialize a new process. this is the only way to create a new process.
|
// initialize a new process. this is the only way to create a new process.
|
||||||
@ -183,7 +185,7 @@ async fn handle_kernel_request(
|
|||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.expect("event loop: fatal: sender died");
|
.expect("event loop: fatal: sender died");
|
||||||
return;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
// check cap sigs & transform valid to unsigned to be plugged into procs
|
// check cap sigs & transform valid to unsigned to be plugged into procs
|
||||||
@ -321,7 +323,7 @@ async fn handle_kernel_request(
|
|||||||
),
|
),
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
return;
|
return None;
|
||||||
};
|
};
|
||||||
let signed_caps: Vec<(t::Capability, Vec<u8>)> = capabilities
|
let signed_caps: Vec<(t::Capability, Vec<u8>)> = capabilities
|
||||||
.iter()
|
.iter()
|
||||||
@ -361,7 +363,7 @@ async fn handle_kernel_request(
|
|||||||
),
|
),
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
return;
|
return None;
|
||||||
};
|
};
|
||||||
for cap in capabilities {
|
for cap in capabilities {
|
||||||
entry.capabilities.remove(&cap);
|
entry.capabilities.remove(&cap);
|
||||||
@ -465,7 +467,7 @@ async fn handle_kernel_request(
|
|||||||
content: format!("kernel: no such process {process_id} to kill"),
|
content: format!("kernel: no such process {process_id} to kill"),
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
process_handle.abort();
|
process_handle.abort();
|
||||||
@ -484,7 +486,7 @@ async fn handle_kernel_request(
|
|||||||
content: format!("killing process {process_id}"),
|
content: format!("killing process {process_id}"),
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
let _ = send_to_terminal
|
let _ = send_to_terminal
|
||||||
.send(t::Printout {
|
.send(t::Printout {
|
||||||
@ -537,7 +539,7 @@ async fn handle_kernel_request(
|
|||||||
content: format!("kernel: no such running process {}", process_id),
|
content: format!("kernel: no such running process {}", process_id),
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
return;
|
return None;
|
||||||
};
|
};
|
||||||
let _ = send_to_terminal
|
let _ = send_to_terminal
|
||||||
.send(t::Printout {
|
.send(t::Printout {
|
||||||
@ -563,6 +565,7 @@ async fn handle_kernel_request(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// spawn a process loop and insert the process in the relevant kernel state maps
|
/// spawn a process loop and insert the process in the relevant kernel state maps
|
||||||
@ -1064,7 +1067,7 @@ pub async fn kernel(
|
|||||||
if our.name != kernel_message.source.node {
|
if our.name != kernel_message.source.node {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
handle_kernel_request(
|
if let Some(()) = handle_kernel_request(
|
||||||
our.name.clone(),
|
our.name.clone(),
|
||||||
keypair.clone(),
|
keypair.clone(),
|
||||||
kernel_message,
|
kernel_message,
|
||||||
@ -1077,7 +1080,10 @@ pub async fn kernel(
|
|||||||
caps_oracle_sender.clone(),
|
caps_oracle_sender.clone(),
|
||||||
&engine,
|
&engine,
|
||||||
&home_directory_path,
|
&home_directory_path,
|
||||||
).await;
|
).await {
|
||||||
|
// shut down the node
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// pass message to appropriate runtime module or process
|
// pass message to appropriate runtime module or process
|
||||||
match senders.get(&kernel_message.target.process) {
|
match senders.get(&kernel_message.target.process) {
|
||||||
|
@ -457,12 +457,15 @@ async fn main() {
|
|||||||
// if a runtime task exits, try to recover it,
|
// if a runtime task exits, try to recover it,
|
||||||
// unless it was terminal signaling a quit
|
// unless it was terminal signaling a quit
|
||||||
// or a SIG* was intercepted
|
// or a SIG* was intercepted
|
||||||
let mut quit_msg: String = tokio::select! {
|
let quit_msg: String = tokio::select! {
|
||||||
Some(Ok(res)) = tasks.join_next() => {
|
Some(Ok(res)) = tasks.join_next() => {
|
||||||
format!(
|
match res {
|
||||||
"uh oh, a kernel process crashed -- this should never happen: {:?}",
|
Ok(_) => "graceful exit".into(),
|
||||||
res
|
Err(e) => format!(
|
||||||
)
|
"uh oh, a kernel process crashed -- this should never happen: {e:?}"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
quit = terminal::terminal(
|
quit = terminal::terminal(
|
||||||
our.clone(),
|
our.clone(),
|
||||||
@ -476,39 +479,39 @@ async fn main() {
|
|||||||
verbose_mode,
|
verbose_mode,
|
||||||
) => {
|
) => {
|
||||||
match quit {
|
match quit {
|
||||||
Ok(_) => "graceful exit".into(),
|
Ok(_) => match kernel_message_sender
|
||||||
|
.send(KernelMessage {
|
||||||
|
id: rand::random(),
|
||||||
|
source: Address {
|
||||||
|
node: our.name.clone(),
|
||||||
|
process: KERNEL_PROCESS_ID.clone(),
|
||||||
|
},
|
||||||
|
target: Address {
|
||||||
|
node: our.name.clone(),
|
||||||
|
process: KERNEL_PROCESS_ID.clone(),
|
||||||
|
},
|
||||||
|
rsvp: None,
|
||||||
|
message: Message::Request(Request {
|
||||||
|
inherit: false,
|
||||||
|
expects_response: None,
|
||||||
|
body: serde_json::to_vec(&KernelCommand::Shutdown).unwrap(),
|
||||||
|
metadata: None,
|
||||||
|
capabilities: vec![],
|
||||||
|
}),
|
||||||
|
lazy_load_blob: None,
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(()) => "graceful exit".into(),
|
||||||
|
Err(_) => {
|
||||||
|
"failed to gracefully shut down kernel".into()
|
||||||
|
}
|
||||||
|
},
|
||||||
Err(e) => e.to_string(),
|
Err(e) => e.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// gracefully abort all running processes in kernel
|
|
||||||
if let Err(_) = kernel_message_sender
|
|
||||||
.send(KernelMessage {
|
|
||||||
id: rand::random(),
|
|
||||||
source: Address {
|
|
||||||
node: our.name.clone(),
|
|
||||||
process: KERNEL_PROCESS_ID.clone(),
|
|
||||||
},
|
|
||||||
target: Address {
|
|
||||||
node: our.name.clone(),
|
|
||||||
process: KERNEL_PROCESS_ID.clone(),
|
|
||||||
},
|
|
||||||
rsvp: None,
|
|
||||||
message: Message::Request(Request {
|
|
||||||
inherit: false,
|
|
||||||
expects_response: None,
|
|
||||||
body: serde_json::to_vec(&KernelCommand::Shutdown).unwrap(),
|
|
||||||
metadata: None,
|
|
||||||
capabilities: vec![],
|
|
||||||
}),
|
|
||||||
lazy_load_blob: None,
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
quit_msg = "failed to gracefully shut down kernel".into();
|
|
||||||
}
|
|
||||||
|
|
||||||
// abort all remaining tasks
|
// abort all remaining tasks
|
||||||
tasks.shutdown().await;
|
tasks.shutdown().await;
|
||||||
let stdout = std::io::stdout();
|
let stdout = std::io::stdout();
|
||||||
|
Loading…
Reference in New Issue
Block a user