diff --git a/crates/server-config/src/node_config.rs b/crates/server-config/src/node_config.rs index 0aa87966ab..dc6ae668ea 100644 --- a/crates/server-config/src/node_config.rs +++ b/crates/server-config/src/node_config.rs @@ -637,8 +637,10 @@ pub struct VmNetworkConfig { pub public_ip: Ipv4Addr, #[serde(default = "default_vm_ip")] pub vm_ip: Ipv4Addr, + // SSH port on the host machine to connect to the VM from outside #[serde(default = "default_host_ssh_port")] pub host_ssh_port: u16, + // SSH port inside the VM #[serde(default = "default_vm_ssh_port")] pub vm_ssh_port: u16, #[serde(default = "default_port_range_config")] diff --git a/nox/src/node.rs b/nox/src/node.rs index a8cae9c15a..1070389376 100644 --- a/nox/src/node.rs +++ b/nox/src/node.rs @@ -54,7 +54,7 @@ use core_distributor::CoreDistributor; use fluence_libp2p::build_transport; use health::HealthCheckRegistry; use particle_builtins::{ - Builtins, BuiltinsConfig, CustomService, NodeInfo, ParticleAppServicesConfig, + Builtins, BuiltinsConfig, CustomService, NodeInfo, ParticleAppServicesConfig, PortInfo, VmInfo, }; use particle_execution::ParticleFunctionStatic; use particle_protocol::ExtendedParticle; @@ -405,8 +405,15 @@ impl Node { node_version: env!("CARGO_PKG_VERSION"), air_version: air_interpreter_wasm::VERSION, spell_version: spell_version.clone(), - // TODO: remove allowed_binaries, + vm_info: config.node_config.vm.as_ref().map(|vm| VmInfo { + ip: vm.network.public_ip.to_string(), + default_ssh_port: vm.network.host_ssh_port, + forwarded_ports: vec![PortInfo::Range( + vm.network.port_range.start, + vm.network.port_range.end, + )], + }), }; if let Some(m) = metrics_registry.as_mut() { peer_metrics::add_info_metrics( diff --git a/particle-builtins/src/identify.rs b/particle-builtins/src/identify.rs index 669ea2c26c..f15e1bbb9b 100644 --- a/particle-builtins/src/identify.rs +++ b/particle-builtins/src/identify.rs @@ -27,4 +27,45 @@ pub struct NodeInfo { pub air_version: &'static str, pub spell_version: String, pub allowed_binaries: Vec, + // Note: this is Vec for Aqua's representation of an option + #[serde(serialize_with = "serialize_aqua_option")] + pub vm_info: Option, +} + +fn serialize_aqua_option(value: &Option, serializer: S) -> Result +where + S: serde::Serializer, +{ + match value { + Some(vm_info) => serializer.collect_seq(&[vm_info]), + None => serializer.serialize_none(), + } +} + +#[derive(Serialize, Clone, Debug)] +pub struct VmInfo { + // Public IP via which we can connect to the VM + pub ip: String, + // List of ports that are forwarded to the VM + pub forwarded_ports: Vec, + // Default SSH port to which to connect + pub default_ssh_port: u16, +} + +#[derive(Clone, Debug)] +pub enum PortInfo { + Port(u16), + Range(u16, u16), +} + +impl Serialize for PortInfo { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + match self { + PortInfo::Port(port) => serializer.serialize_u16(*port), + PortInfo::Range(start, end) => serializer.serialize_str(&format!("{}-{}", start, end)), + } + } } diff --git a/particle-builtins/src/lib.rs b/particle-builtins/src/lib.rs index 16627fefd5..9e76e4d671 100644 --- a/particle-builtins/src/lib.rs +++ b/particle-builtins/src/lib.rs @@ -33,7 +33,7 @@ )] pub use builtins::{Builtins, BuiltinsConfig, CustomService}; -pub use identify::NodeInfo; +pub use identify::{NodeInfo, PortInfo, VmInfo}; pub use outcome::{ok, wrap, wrap_unit}; pub use particle_services::ParticleAppServicesConfig; mod builtins;