feat(console): expose component capabilities
- project structured capability package, name, version, and interface fields - derive capabilities during registration and artifact restoration - keep Component imports as the source of truth without changing .wasmpkg - verify empty and Clock capability responses through the management API
This commit is contained in:
@@ -39,7 +39,8 @@ use wasmeld_package::{
|
||||
wit_package::{WitPackageError, WitPackageMetadata},
|
||||
};
|
||||
use wasmeld_runtime::{
|
||||
ResourceLimits, Runtime, RuntimeConfig, RuntimeError, ServiceKey, ServiceManifest,
|
||||
CapabilityDescriptor, ResourceLimits, Runtime, RuntimeConfig, RuntimeError, ServiceKey,
|
||||
ServiceManifest,
|
||||
};
|
||||
|
||||
use persistence::{Persistence, StoredDeployment, StoredEvent, StoredService};
|
||||
@@ -113,6 +114,7 @@ struct ConsoleState {
|
||||
#[derive(Clone)]
|
||||
struct ServiceRecord {
|
||||
manifest: ServiceManifest,
|
||||
capabilities: Vec<CapabilityView>,
|
||||
status: ServiceStatus,
|
||||
updated_at_ms: u64,
|
||||
calls: u64,
|
||||
@@ -144,6 +146,26 @@ pub struct DeploymentView {
|
||||
pub updated_at_ms: u64,
|
||||
}
|
||||
|
||||
/// Exact versioned host interface imported by a registered Component.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct CapabilityView {
|
||||
pub interface: String,
|
||||
pub package: String,
|
||||
pub name: String,
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
impl From<CapabilityDescriptor> for CapabilityView {
|
||||
fn from(capability: CapabilityDescriptor) -> Self {
|
||||
Self {
|
||||
interface: capability.interface().to_owned(),
|
||||
package: capability.package().to_owned(),
|
||||
name: capability.name().to_owned(),
|
||||
version: capability.version().to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// API projection of a registered service and its current metrics.
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub struct ServiceView {
|
||||
@@ -151,6 +173,7 @@ pub struct ServiceView {
|
||||
pub revision: String,
|
||||
pub artifact: String,
|
||||
pub world: String,
|
||||
pub capabilities: Vec<CapabilityView>,
|
||||
pub status: ServiceStatus,
|
||||
pub updated_at_ms: u64,
|
||||
pub limits: ResourceLimits,
|
||||
@@ -166,6 +189,7 @@ impl ServiceRecord {
|
||||
revision: self.manifest.revision.clone(),
|
||||
artifact: self.manifest.component.clone(),
|
||||
world: self.manifest.world.clone(),
|
||||
capabilities: self.capabilities.clone(),
|
||||
status: self.status,
|
||||
updated_at_ms: self.updated_at_ms,
|
||||
limits: self.manifest.limits.clone(),
|
||||
@@ -743,8 +767,9 @@ impl Console {
|
||||
let _ = fs::remove_file(&manifest_path);
|
||||
return Err(error.into());
|
||||
}
|
||||
let capabilities = runtime_capabilities(runtime, &key)?;
|
||||
|
||||
let view = self.insert_service(manifest, ServiceStatus::Stopped)?;
|
||||
let view = self.insert_service(manifest, capabilities, ServiceStatus::Stopped)?;
|
||||
self.push_event(
|
||||
EventKind::Registered,
|
||||
Some(&key),
|
||||
@@ -910,10 +935,12 @@ impl Console {
|
||||
)));
|
||||
}
|
||||
runtime.register_from_file(manifest.clone())?;
|
||||
let capabilities = runtime_capabilities(runtime, &key)?;
|
||||
self.state()?.services.insert(
|
||||
key,
|
||||
ServiceRecord {
|
||||
manifest,
|
||||
capabilities,
|
||||
status: ServiceStatus::Stopped,
|
||||
updated_at_ms: stored.updated_at_ms,
|
||||
calls: stored.calls,
|
||||
@@ -956,7 +983,8 @@ impl Console {
|
||||
continue;
|
||||
}
|
||||
runtime.register_from_file(manifest.clone())?;
|
||||
self.insert_service(manifest, ServiceStatus::Stopped)?;
|
||||
let capabilities = runtime_capabilities(runtime, &key)?;
|
||||
self.insert_service(manifest, capabilities, ServiceStatus::Stopped)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -1070,12 +1098,14 @@ impl Console {
|
||||
fn insert_service(
|
||||
&self,
|
||||
manifest: ServiceManifest,
|
||||
capabilities: Vec<CapabilityView>,
|
||||
status: ServiceStatus,
|
||||
) -> Result<ServiceView, ConsoleError> {
|
||||
let key = manifest.key()?;
|
||||
let mut state = self.state()?;
|
||||
let record = ServiceRecord {
|
||||
manifest,
|
||||
capabilities,
|
||||
status,
|
||||
updated_at_ms: unix_time_ms(),
|
||||
calls: 0,
|
||||
@@ -1140,6 +1170,17 @@ impl Console {
|
||||
}
|
||||
}
|
||||
|
||||
fn runtime_capabilities(
|
||||
runtime: &Runtime,
|
||||
key: &ServiceKey,
|
||||
) -> Result<Vec<CapabilityView>, ConsoleError> {
|
||||
Ok(runtime
|
||||
.capabilities(key)?
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect())
|
||||
}
|
||||
|
||||
fn deployment_view(
|
||||
state: &ConsoleState,
|
||||
service_id: &str,
|
||||
|
||||
Reference in New Issue
Block a user