diff --git a/cli/src/activation.rs b/cli/src/activation.rs new file mode 100644 index 0000000..b99d6f1 --- /dev/null +++ b/cli/src/activation.rs @@ -0,0 +1,15 @@ +//! Activation and revert of plugin versions (PROTOCOL.md section 10.3). +use crate::{Host, RpcResult, error}; +use serde_json::Value; + +impl Host { + /// `core.activate` and `core.revert`. + pub(crate) async fn activation( + &self, + _caller: &str, + _method: &str, + _params: Value, + ) -> RpcResult { + Err(error(-32601, "method not found")) + } +} diff --git a/cli/src/core.rs b/cli/src/core.rs index 6539650..96d0810 100644 --- a/cli/src/core.rs +++ b/cli/src/core.rs @@ -49,6 +49,7 @@ impl Host { Ok(Value::Null) } "log" => Ok(self.0.journal.query(p).await), + "activate" | "revert" => self.activation(caller, method, p).await, "exit" => { self.0.exit.send_replace(true); Ok(json!({})) diff --git a/cli/src/graph.rs b/cli/src/graph.rs new file mode 100644 index 0000000..7cf8f1d --- /dev/null +++ b/cli/src/graph.rs @@ -0,0 +1,31 @@ +//! The interface graph (PROTOCOL.md section 10.4): the `rpc.discover` +//! documents of all plugins, their imports, and the result of each check. +//! +//! The `/proc` layer reads the files of `/proc/core/` through these +//! functions. They must be cheap and must not block: they return cached data. +use crate::Host; +use serde_json::Value; + +// The /proc layer (T6) uses these functions. Remove this when it does. +#[allow(dead_code)] +impl Host { + /// The content of `/proc/core/graph.json`. + pub(crate) fn graph_json(&self) -> Vec { + b"{}\n".to_vec() + } + + /// The content of `/proc/core/graph.dot`. + pub(crate) fn graph_dot(&self) -> Vec { + b"digraph plugins {}\n".to_vec() + } + + /// The plugins that have an `rpc.discover` document, for `/proc/core/plugins/`. + pub(crate) fn discovered_plugins(&self) -> Vec { + Vec::new() + } + + /// The `rpc.discover` document of the current `plugin.wasm` of `plugin`. + pub(crate) fn discover_document(&self, _plugin: &str) -> Option { + None + } +} diff --git a/cli/src/host.rs b/cli/src/host.rs index 10edf61..6a9520a 100644 --- a/cli/src/host.rs +++ b/cli/src/host.rs @@ -65,23 +65,7 @@ impl Host { exit: watch::channel(false).0, components: components::Components::default(), })); - let boot: Vec = serde_json::from_slice( - &tokio::fs::read(host.0.world.root.join("config/boot.json")).await?, - )?; - for service in boot { - let result = host - .route( - "core".into(), - Some(json!(Uuid::now_v7().to_string())), - service["method"].as_str().unwrap_or("").into(), - service["params"].clone(), - true, - ) - .await; - if let Err(e) = result { - host.0.journal.write("core", "core", "core", &e.to_string()); - } - } + host.boot().await?; Ok(host) } /// Register a native plugin for subsequent calls. diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 4a4d4f5..2f78937 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -1,9 +1,11 @@ //! A host for worlds of JSON-RPC plugins. +mod activation; pub mod cargo; mod components; pub mod console; mod core; mod execution; +mod graph; mod host; mod journal; mod locks; @@ -11,6 +13,7 @@ mod native; mod process; mod routing; pub mod runtime; +mod services; pub mod world; pub use host::Host; pub use native::{NativeContext, NativeFuture, NativePlugin}; diff --git a/cli/src/services.rs b/cli/src/services.rs new file mode 100644 index 0000000..7faf67a --- /dev/null +++ b/cli/src/services.rs @@ -0,0 +1,31 @@ +//! Services: the calls in `/config/boot.json` (PROTOCOL.md section 8). The +//! core starts them in order at boot. +use crate::Host; +use serde_json::{Value, json}; +use uuid::Uuid; + +impl Host { + /// Start each service of `/config/boot.json` as a detached call with the + /// parent `core`, in order. A failure goes to the journal, and boot + /// continues. + pub(crate) async fn boot(&self) -> anyhow::Result<()> { + let boot: Vec = serde_json::from_slice( + &tokio::fs::read(self.0.world.root.join("config/boot.json")).await?, + )?; + for service in boot { + let result = self + .route( + "core".into(), + Some(json!(Uuid::now_v7().to_string())), + service["method"].as_str().unwrap_or("").into(), + service["params"].clone(), + true, + ) + .await; + if let Err(e) = result { + self.0.journal.write("core", "core", "core", &e.to_string()); + } + } + Ok(()) + } +}