use serde::{Deserialize, Serialize};
mod adapter;
mod conversation;
mod door;
mod engine;
mod node;
pub use adapter::{InboundManagement, ManagementConversation, ServeExit, serve};
pub use conversation::{
DevManagementConversation, DevResumeStore, MANAGEMENT_LINE_PREFIX, format_management_line,
parse_management_line,
};
pub struct DevWiring {
pub meta: frame_core::component::ComponentMeta,
pub boot: CandidateBytes,
pub mailbox_proof: Witness,
pub content_proof: Witness,
}
pub use door::require_dev_node;
pub use engine::{BarrierEngine, NodeControl, StartFailure};
pub use node::{DevNodeControl, Witness};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum NodeMode {
Production,
Dev,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CandidateBytes {
pub build_generation: u64,
pub content_digest: [u8; 32],
pub component_beam: Vec<u8>,
pub ffi_beam: Vec<u8>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum DevRequest {
StageAndActivate(CandidateBytes),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum DevReply {
Activated(GenerationReport),
Refused(StageRefusal),
RolledBack {
failed: ReloadStage,
detail: String,
serving: GenerationReport,
},
NodeFailed {
failed: ReloadStage,
detail: String,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum StageRefusal {
NotADevNode,
ActivationInFlight,
StaleGeneration {
offered: u64,
newest_seen: u64,
},
SchemaInvalid {
detail: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ReloadStage {
Drain,
StopOld,
PurgeOld,
LoadCandidate,
StartFresh,
LivenessMailbox,
LivenessContent,
Restore,
Report,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct GenerationReport {
pub build_generation: u64,
pub content_digest: [u8; 32],
pub component_incarnation: u64,
pub module_generation: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum DevStatusEvent {
RunningCurrent(GenerationReport),
Reloading {
build_generation: u64,
stage: ReloadStage,
},
ReloadFailed {
failed_generation: u64,
failed: ReloadStage,
detail: String,
serving: GenerationReport,
},
NodeFailed {
detail: String,
},
}
#[cfg(test)]
mod tests {
#![allow(clippy::expect_used)]
use super::{
CandidateBytes, DevReply, DevRequest, DevStatusEvent, GenerationReport, NodeMode,
ReloadStage, StageRefusal,
};
fn report() -> GenerationReport {
GenerationReport {
build_generation: 4,
content_digest: [7; 32],
component_incarnation: 9,
module_generation: 5,
}
}
#[test]
fn vocabulary_round_trips_through_serde() {
let request = DevRequest::StageAndActivate(CandidateBytes {
build_generation: 4,
content_digest: [7; 32],
component_beam: vec![1, 2, 3],
ffi_beam: vec![4, 5],
});
let json = serde_json::to_string(&request).expect("serializes");
let back: DevRequest = serde_json::from_str(&json).expect("deserializes");
assert_eq!(request, back);
for reply in [
DevReply::Activated(report()),
DevReply::Refused(StageRefusal::NotADevNode),
DevReply::Refused(StageRefusal::StaleGeneration {
offered: 3,
newest_seen: 4,
}),
DevReply::RolledBack {
failed: ReloadStage::StartFresh,
detail: "supervisor refused".to_owned(),
serving: report(),
},
DevReply::NodeFailed {
failed: ReloadStage::Restore,
detail: "restore load failed".to_owned(),
},
] {
let json = serde_json::to_string(&reply).expect("serializes");
let back: DevReply = serde_json::from_str(&json).expect("deserializes");
assert_eq!(reply, back);
}
for event in [
DevStatusEvent::RunningCurrent(report()),
DevStatusEvent::Reloading {
build_generation: 5,
stage: ReloadStage::PurgeOld,
},
DevStatusEvent::ReloadFailed {
failed_generation: 5,
failed: ReloadStage::LoadCandidate,
detail: "invalid BEAM".to_owned(),
serving: report(),
},
DevStatusEvent::NodeFailed {
detail: "child exited: signal 9".to_owned(),
},
] {
let json = serde_json::to_string(&event).expect("serializes");
let back: DevStatusEvent = serde_json::from_str(&json).expect("deserializes");
assert_eq!(event, back);
}
}
#[test]
fn unknown_variants_refuse_typed() {
assert!(serde_json::from_str::<DevRequest>("{\"InstallPlugin\":{}}").is_err());
assert!(serde_json::from_str::<NodeMode>("\"Staging\"").is_err());
}
}