From 723dea100f43fd3e790f864b476e855ed8cfa41b Mon Sep 17 00:00:00 2001 From: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> Date: Wed, 10 Sep 2025 18:16:35 +0000 Subject: [PATCH] add more gateway info to hostnameInfo (#3019) --- container-runtime/package-lock.json | 2 +- core/models/src/id/gateway.rs | 14 ++++---- core/startos/src/db/model/public.rs | 5 +-- core/startos/src/net/gateway.rs | 2 +- core/startos/src/net/net_controller.rs | 28 ++++++++++------ core/startos/src/net/service_interface.rs | 12 +++++-- core/startos/src/net/tunnel.rs | 2 +- core/startos/src/version/v0_3_6_alpha_10.rs | 4 +-- sdk/base/lib/osBindings/GatewayInfo.ts | 4 +++ sdk/base/lib/osBindings/HostnameInfo.ts | 3 +- sdk/base/lib/osBindings/index.ts | 1 + sdk/package/package-lock.json | 4 +-- sdk/package/package.json | 2 +- .../interfaces/interface.service.ts | 8 ++--- .../ui/src/app/services/api/api.fixures.ts | 32 +++++++++---------- .../ui/src/app/services/api/mock-patch.ts | 24 +++++++------- 16 files changed, 87 insertions(+), 60 deletions(-) create mode 100644 sdk/base/lib/osBindings/GatewayInfo.ts diff --git a/container-runtime/package-lock.json b/container-runtime/package-lock.json index c0a97dc6d..2ae4b19bf 100644 --- a/container-runtime/package-lock.json +++ b/container-runtime/package-lock.json @@ -38,7 +38,7 @@ }, "../sdk/dist": { "name": "@start9labs/start-sdk", - "version": "0.4.0-beta.37", + "version": "0.4.0-beta.38", "license": "MIT", "dependencies": { "@iarna/toml": "^3.0.0", diff --git a/core/models/src/id/gateway.rs b/core/models/src/id/gateway.rs index 7721a7301..f005147a7 100644 --- a/core/models/src/id/gateway.rs +++ b/core/models/src/id/gateway.rs @@ -14,12 +14,14 @@ impl GatewayId { &*self.0 } } -impl From for GatewayId -where - T: Into, -{ - fn from(value: T) -> Self { - Self(value.into()) +impl From for GatewayId { + fn from(value: InternedString) -> Self { + Self(value) + } +} +impl From for InternedString { + fn from(value: GatewayId) -> Self { + value.0 } } impl FromStr for GatewayId { diff --git a/core/startos/src/db/model/public.rs b/core/startos/src/db/model/public.rs index 5451d4795..a6e3b54d6 100644 --- a/core/startos/src/db/model/public.rs +++ b/core/startos/src/db/model/public.rs @@ -219,7 +219,7 @@ pub struct NetworkInterfaceInfo { impl NetworkInterfaceInfo { pub fn loopback() -> (&'static GatewayId, &'static Self) { lazy_static! { - static ref LO: GatewayId = GatewayId::from("lo"); + static ref LO: GatewayId = GatewayId::from(InternedString::intern("lo")); static ref LOOPBACK: NetworkInterfaceInfo = NetworkInterfaceInfo { name: Some(InternedString::from_static("Loopback")), public: Some(false), @@ -250,7 +250,8 @@ impl NetworkInterfaceInfo { } pub fn lxc_bridge() -> (&'static GatewayId, &'static Self) { lazy_static! { - static ref LXCBR0: GatewayId = GatewayId::from(START9_BRIDGE_IFACE); + static ref LXCBR0: GatewayId = + GatewayId::from(InternedString::intern(START9_BRIDGE_IFACE)); static ref LXC_BRIDGE: NetworkInterfaceInfo = NetworkInterfaceInfo { name: Some(InternedString::from_static("LXC Bridge Interface")), public: Some(false), diff --git a/core/startos/src/net/gateway.rs b/core/startos/src/net/gateway.rs index 83db71356..f30e968c1 100644 --- a/core/startos/src/net/gateway.rs +++ b/core/startos/src/net/gateway.rs @@ -982,7 +982,7 @@ impl NetworkInterfaceController { info } }, - [START9_BRIDGE_IFACE.into()], + [InternedString::from_static(START9_BRIDGE_IFACE).into()], ); let mut ip_info_watch = watcher.subscribe(); ip_info_watch.mark_seen(); diff --git a/core/startos/src/net/net_controller.rs b/core/startos/src/net/net_controller.rs index 11cd36d0f..2f3793482 100644 --- a/core/startos/src/net/net_controller.rs +++ b/core/startos/src/net/net_controller.rs @@ -24,7 +24,7 @@ use crate::net::gateway::{ use crate::net::host::address::HostAddress; use crate::net::host::binding::{AddSslOptions, BindId, BindOptions}; use crate::net::host::{host_for, Host, Hosts}; -use crate::net::service_interface::{HostnameInfo, IpHostname, OnionHostname}; +use crate::net::service_interface::{GatewayInfo, HostnameInfo, IpHostname, OnionHostname}; use crate::net::socks::SocksController; use crate::net::tor::{OnionAddress, TorController, TorSecretKey}; use crate::net::utils::ipv6_is_local; @@ -427,10 +427,19 @@ impl NetServiceData { } let mut bind_hostname_info: Vec = hostname_info.remove(port).unwrap_or_default(); - for (interface, info) in net_ifaces + for (gateway_id, info) in net_ifaces .iter() .filter(|(id, info)| bind.net.filter(id, info)) { + let gateway = GatewayInfo { + id: gateway_id.clone(), + name: info + .name + .clone() + .or_else(|| info.ip_info.as_ref().map(|i| i.name.clone())) + .unwrap_or_else(|| gateway_id.clone().into()), + public: info.public(), + }; let port = bind.net.assigned_port.filter(|_| { bind.options.secure.map_or(false, |s| { !(s.ssl && bind.options.add_ssl.is_some()) || info.secure() @@ -442,7 +451,7 @@ impl NetServiceData { }) { bind_hostname_info.push(HostnameInfo::Ip { - gateway_id: interface.clone(), + gateway: gateway.clone(), public: false, hostname: IpHostname::Local { value: InternedString::from_display(&{ @@ -462,7 +471,8 @@ impl NetServiceData { } = address { let private = private && !info.public(); - let public = public.as_ref().map_or(false, |p| &p.gateway == interface); + let public = + public.as_ref().map_or(false, |p| &p.gateway == gateway_id); if public || private { if bind .options @@ -471,7 +481,7 @@ impl NetServiceData { .map_or(false, |ssl| ssl.preferred_external_port == 443) { bind_hostname_info.push(HostnameInfo::Ip { - gateway_id: interface.clone(), + gateway: gateway.clone(), public, hostname: IpHostname::Domain { value: address.clone(), @@ -481,7 +491,7 @@ impl NetServiceData { }); } else { bind_hostname_info.push(HostnameInfo::Ip { - gateway_id: interface.clone(), + gateway: gateway.clone(), public, hostname: IpHostname::Domain { value: address.clone(), @@ -497,7 +507,7 @@ impl NetServiceData { let public = info.public(); if let Some(wan_ip) = ip_info.wan_ip { bind_hostname_info.push(HostnameInfo::Ip { - gateway_id: interface.clone(), + gateway: gateway.clone(), public: true, hostname: IpHostname::Ipv4 { value: wan_ip, @@ -511,7 +521,7 @@ impl NetServiceData { IpNet::V4(net) => { if !public { bind_hostname_info.push(HostnameInfo::Ip { - gateway_id: interface.clone(), + gateway: gateway.clone(), public, hostname: IpHostname::Ipv4 { value: net.addr(), @@ -523,7 +533,7 @@ impl NetServiceData { } IpNet::V6(net) => { bind_hostname_info.push(HostnameInfo::Ip { - gateway_id: interface.clone(), + gateway: gateway.clone(), public: public && !ipv6_is_local(net.addr()), hostname: IpHostname::Ipv6 { value: net.addr(), diff --git a/core/startos/src/net/service_interface.rs b/core/startos/src/net/service_interface.rs index 7ffab22ed..0d1a193ad 100644 --- a/core/startos/src/net/service_interface.rs +++ b/core/startos/src/net/service_interface.rs @@ -12,8 +12,7 @@ use ts_rs::TS; #[serde(tag = "kind")] pub enum HostnameInfo { Ip { - #[ts(type = "string")] - gateway_id: GatewayId, + gateway: GatewayInfo, public: bool, hostname: IpHostname, }, @@ -30,6 +29,15 @@ impl HostnameInfo { } } +#[derive(Clone, Debug, Deserialize, Serialize, TS)] +#[ts(export)] +#[serde(rename_all = "camelCase")] +pub struct GatewayInfo { + pub id: GatewayId, + pub name: InternedString, + pub public: bool, +} + #[derive(Clone, Debug, Deserialize, Serialize, TS)] #[ts(export)] #[serde(rename_all = "camelCase")] diff --git a/core/startos/src/net/tunnel.rs b/core/startos/src/net/tunnel.rs index 4ff7446fa..7702f7544 100644 --- a/core/startos/src/net/tunnel.rs +++ b/core/startos/src/net/tunnel.rs @@ -47,7 +47,7 @@ pub async fn add_tunnel( }: AddTunnelParams, ) -> Result { let ifaces = ctx.net_controller.net_iface.watcher.subscribe(); - let mut iface = GatewayId::from("wg0"); + let mut iface = GatewayId::from(InternedString::intern("wg0")); if !ifaces.send_if_modified(|i| { for id in 1..256 { if !i.contains_key(&iface) { diff --git a/core/startos/src/version/v0_3_6_alpha_10.rs b/core/startos/src/version/v0_3_6_alpha_10.rs index 655b0e1f3..74fe17e89 100644 --- a/core/startos/src/version/v0_3_6_alpha_10.rs +++ b/core/startos/src/version/v0_3_6_alpha_10.rs @@ -6,7 +6,7 @@ use models::GatewayId; use serde::{Deserialize, Serialize}; use super::v0_3_5::V0_3_0_COMPAT; -use super::{VersionT, v0_3_6_alpha_9}; +use super::{v0_3_6_alpha_9, VersionT}; use crate::net::host::address::PublicDomainConfig; use crate::net::tor::OnionAddress; use crate::prelude::*; @@ -75,7 +75,7 @@ impl VersionT for Version { domains.insert( address.clone(), PublicDomainConfig { - gateway: GatewayId::from("lo"), + gateway: GatewayId::from(InternedString::intern("lo")), acme: None, }, ); diff --git a/sdk/base/lib/osBindings/GatewayInfo.ts b/sdk/base/lib/osBindings/GatewayInfo.ts new file mode 100644 index 000000000..2bae94568 --- /dev/null +++ b/sdk/base/lib/osBindings/GatewayInfo.ts @@ -0,0 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { GatewayId } from "./GatewayId" + +export type GatewayInfo = { id: GatewayId; name: string; public: boolean } diff --git a/sdk/base/lib/osBindings/HostnameInfo.ts b/sdk/base/lib/osBindings/HostnameInfo.ts index 7819eec54..26dc76c67 100644 --- a/sdk/base/lib/osBindings/HostnameInfo.ts +++ b/sdk/base/lib/osBindings/HostnameInfo.ts @@ -1,7 +1,8 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { GatewayInfo } from "./GatewayInfo" import type { IpHostname } from "./IpHostname" import type { OnionHostname } from "./OnionHostname" export type HostnameInfo = - | { kind: "ip"; gatewayId: string; public: boolean; hostname: IpHostname } + | { kind: "ip"; gateway: GatewayInfo; public: boolean; hostname: IpHostname } | { kind: "onion"; hostname: OnionHostname } diff --git a/sdk/base/lib/osBindings/index.ts b/sdk/base/lib/osBindings/index.ts index 724895888..502bd992f 100644 --- a/sdk/base/lib/osBindings/index.ts +++ b/sdk/base/lib/osBindings/index.ts @@ -80,6 +80,7 @@ export { ForgetGatewayParams } from "./ForgetGatewayParams" export { FullIndex } from "./FullIndex" export { FullProgress } from "./FullProgress" export { GatewayId } from "./GatewayId" +export { GatewayInfo } from "./GatewayInfo" export { GetActionInputParams } from "./GetActionInputParams" export { GetContainerIpParams } from "./GetContainerIpParams" export { GetHostInfoParams } from "./GetHostInfoParams" diff --git a/sdk/package/package-lock.json b/sdk/package/package-lock.json index a70719329..bd8865ead 100644 --- a/sdk/package/package-lock.json +++ b/sdk/package/package-lock.json @@ -1,12 +1,12 @@ { "name": "@start9labs/start-sdk", - "version": "0.4.0-beta.37", + "version": "0.4.0-beta.38", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@start9labs/start-sdk", - "version": "0.4.0-beta.37", + "version": "0.4.0-beta.38", "license": "MIT", "dependencies": { "@iarna/toml": "^3.0.0", diff --git a/sdk/package/package.json b/sdk/package/package.json index 7ebc2eb98..5b445fb26 100644 --- a/sdk/package/package.json +++ b/sdk/package/package.json @@ -1,6 +1,6 @@ { "name": "@start9labs/start-sdk", - "version": "0.4.0-beta.37", + "version": "0.4.0-beta.38", "description": "Software development kit to facilitate packaging services for StartOS", "main": "./package/lib/index.js", "types": "./package/lib/index.d.ts", diff --git a/web/projects/ui/src/app/routes/portal/components/interfaces/interface.service.ts b/web/projects/ui/src/app/routes/portal/components/interfaces/interface.service.ts index 38380d385..d9b19a5bc 100644 --- a/web/projects/ui/src/app/routes/portal/components/interfaces/interface.service.ts +++ b/web/projects/ui/src/app/routes/portal/components/interfaces/interface.service.ts @@ -92,7 +92,7 @@ function cmpClearnet( return cmpWithRankedPredicates(a, b, [ x => x.info.hostname.kind === 'domain' && - x.info.gatewayId === host.publicDomains[x.info.hostname.value]?.gateway, // public domain for this gateway + x.info.gateway.id === host.publicDomains[x.info.hostname.value]?.gateway, // public domain for this gateway x => x.gateway?.public ?? false, // public gateway x => x.info.hostname.kind === 'ipv4', // ipv4 x => x.info.hostname.kind === 'ipv6', // ipv6 @@ -136,7 +136,7 @@ export class InterfaceService { utils.addressHostToUrl(serviceInterface.addressInfo, h).map(url => ({ url, info: h, - gateway: gateways.find(g => h.kind === 'ip' && h.gatewayId === g.id), + gateway: gateways.find(g => h.kind === 'ip' && h.gateway.id === g.id), })), ) @@ -306,7 +306,7 @@ export class InterfaceService { h.kind === 'ip' && ((h.hostname.kind === 'ipv6' && utils.IPV6_LINK_LOCAL.contains(h.hostname.value)) || - h.gatewayId === 'lo') + h.gateway.id === 'lo') ), ) || [] ) @@ -360,7 +360,7 @@ export class InterfaceService { // ** Not Tor ** } else { const port = info.hostname.sslPort || info.hostname.port - const gateway = gateways.find(g => g.id === info.gatewayId)! + const gateway = gateways.find(g => g.id === info.gateway.id)! gatewayName = gateway.name const gatewayLanIpv4 = gateway.lanIpv4[0] diff --git a/web/projects/ui/src/app/services/api/api.fixures.ts b/web/projects/ui/src/app/services/api/api.fixures.ts index 1002dee92..cbd277a18 100644 --- a/web/projects/ui/src/app/services/api/api.fixures.ts +++ b/web/projects/ui/src/app/services/api/api.fixures.ts @@ -385,7 +385,7 @@ export namespace Mock { docsUrl: 'https://bitcoin.org', releaseNotes: 'Even better support for Bitcoin and wallets!', osVersion: '0.3.6', - sdkVersion: '0.4.0-beta.37', + sdkVersion: '0.4.0-beta.38', gitHash: 'fakehash', icon: BTC_ICON, sourceVersion: null, @@ -420,7 +420,7 @@ export namespace Mock { docsUrl: 'https://bitcoinknots.org', releaseNotes: 'Even better support for Bitcoin and wallets!', osVersion: '0.3.6', - sdkVersion: '0.4.0-beta.37', + sdkVersion: '0.4.0-beta.38', gitHash: 'fakehash', icon: BTC_ICON, sourceVersion: null, @@ -465,7 +465,7 @@ export namespace Mock { docsUrl: 'https://bitcoin.org', releaseNotes: 'Even better support for Bitcoin and wallets!', osVersion: '0.3.6', - sdkVersion: '0.4.0-beta.37', + sdkVersion: '0.4.0-beta.38', gitHash: 'fakehash', icon: BTC_ICON, sourceVersion: null, @@ -500,7 +500,7 @@ export namespace Mock { docsUrl: 'https://bitcoinknots.org', releaseNotes: 'Even better support for Bitcoin and wallets!', osVersion: '0.3.6', - sdkVersion: '0.4.0-beta.37', + sdkVersion: '0.4.0-beta.38', gitHash: 'fakehash', icon: BTC_ICON, sourceVersion: null, @@ -547,7 +547,7 @@ export namespace Mock { docsUrl: 'https://lightning.engineering/', releaseNotes: 'Upstream release to 0.17.5', osVersion: '0.3.6', - sdkVersion: '0.4.0-beta.37', + sdkVersion: '0.4.0-beta.38', gitHash: 'fakehash', icon: LND_ICON, sourceVersion: null, @@ -595,7 +595,7 @@ export namespace Mock { docsUrl: 'https://lightning.engineering/', releaseNotes: 'Upstream release to 0.17.4', osVersion: '0.3.6', - sdkVersion: '0.4.0-beta.37', + sdkVersion: '0.4.0-beta.38', gitHash: 'fakehash', icon: LND_ICON, sourceVersion: null, @@ -647,7 +647,7 @@ export namespace Mock { docsUrl: 'https://bitcoin.org', releaseNotes: 'Even better support for Bitcoin and wallets!', osVersion: '0.3.6', - sdkVersion: '0.4.0-beta.37', + sdkVersion: '0.4.0-beta.38', gitHash: 'fakehash', icon: BTC_ICON, sourceVersion: null, @@ -682,7 +682,7 @@ export namespace Mock { docsUrl: 'https://bitcoinknots.org', releaseNotes: 'Even better support for Bitcoin and wallets!', osVersion: '0.3.6', - sdkVersion: '0.4.0-beta.37', + sdkVersion: '0.4.0-beta.38', gitHash: 'fakehash', icon: BTC_ICON, sourceVersion: null, @@ -727,7 +727,7 @@ export namespace Mock { docsUrl: 'https://lightning.engineering/', releaseNotes: 'Upstream release and minor fixes.', osVersion: '0.3.6', - sdkVersion: '0.4.0-beta.37', + sdkVersion: '0.4.0-beta.38', gitHash: 'fakehash', icon: LND_ICON, sourceVersion: null, @@ -775,7 +775,7 @@ export namespace Mock { marketingSite: '', releaseNotes: 'Upstream release and minor fixes.', osVersion: '0.3.6', - sdkVersion: '0.4.0-beta.37', + sdkVersion: '0.4.0-beta.38', gitHash: 'fakehash', icon: PROXY_ICON, sourceVersion: null, @@ -2041,7 +2041,7 @@ export namespace Mock { 80: [ { kind: 'ip', - gatewayId: 'eth0', + gateway: { id: 'eth0', name: 'Ethernet', public: false }, public: false, hostname: { kind: 'local', @@ -2052,7 +2052,7 @@ export namespace Mock { }, { kind: 'ip', - gatewayId: 'wlan0', + gateway: { id: 'wlan0', name: 'Wireless', public: false }, public: false, hostname: { kind: 'local', @@ -2063,7 +2063,7 @@ export namespace Mock { }, { kind: 'ip', - gatewayId: 'eth0', + gateway: { id: 'wlan0', name: 'Wireless', public: false }, public: false, hostname: { kind: 'ipv4', @@ -2074,7 +2074,7 @@ export namespace Mock { }, { kind: 'ip', - gatewayId: 'wlan0', + gateway: { id: 'wlan0', name: 'Wireless', public: false }, public: false, hostname: { kind: 'ipv4', @@ -2085,7 +2085,7 @@ export namespace Mock { }, { kind: 'ip', - gatewayId: 'eth0', + gateway: { id: 'eth0', name: 'Ethernet', public: false }, public: false, hostname: { kind: 'ipv6', @@ -2097,7 +2097,7 @@ export namespace Mock { }, { kind: 'ip', - gatewayId: 'wlan0', + gateway: { id: 'wlan0', name: 'Wireless', public: false }, public: false, hostname: { kind: 'ipv6', diff --git a/web/projects/ui/src/app/services/api/mock-patch.ts b/web/projects/ui/src/app/services/api/mock-patch.ts index ae41750aa..287ad5814 100644 --- a/web/projects/ui/src/app/services/api/mock-patch.ts +++ b/web/projects/ui/src/app/services/api/mock-patch.ts @@ -59,7 +59,7 @@ export const mockPatchData: DataModel = { 80: [ { kind: 'ip', - gatewayId: 'eth0', + gateway: { id: 'eth0', name: 'Ethernet', public: false }, public: false, hostname: { kind: 'local', @@ -70,7 +70,7 @@ export const mockPatchData: DataModel = { }, { kind: 'ip', - gatewayId: 'wlan0', + gateway: { id: 'wlan0', name: 'Wireless', public: false }, public: false, hostname: { kind: 'local', @@ -81,7 +81,7 @@ export const mockPatchData: DataModel = { }, { kind: 'ip', - gatewayId: 'eth0', + gateway: { id: 'eth0', name: 'Ethernet', public: false }, public: false, hostname: { kind: 'ipv4', @@ -92,7 +92,7 @@ export const mockPatchData: DataModel = { }, { kind: 'ip', - gatewayId: 'wlan0', + gateway: { id: 'wlan0', name: 'Wireless', public: false }, public: false, hostname: { kind: 'ipv4', @@ -103,7 +103,7 @@ export const mockPatchData: DataModel = { }, { kind: 'ip', - gatewayId: 'eth0', + gateway: { id: 'eth0', name: 'Ethernet', public: false }, public: false, hostname: { kind: 'ipv6', @@ -115,7 +115,7 @@ export const mockPatchData: DataModel = { }, { kind: 'ip', - gatewayId: 'wlan0', + gateway: { id: 'wlan0', name: 'Wireless', public: false }, public: false, hostname: { kind: 'ipv6', @@ -356,7 +356,7 @@ export const mockPatchData: DataModel = { 80: [ { kind: 'ip', - gatewayId: 'eth0', + gateway: { id: 'eth0', name: 'Ethernet', public: false }, public: false, hostname: { kind: 'local', @@ -367,7 +367,7 @@ export const mockPatchData: DataModel = { }, { kind: 'ip', - gatewayId: 'wlan0', + gateway: { id: 'wlan0', name: 'Wireless', public: false }, public: false, hostname: { kind: 'local', @@ -378,7 +378,7 @@ export const mockPatchData: DataModel = { }, { kind: 'ip', - gatewayId: 'eth0', + gateway: { id: 'eth0', name: 'Ethernet', public: false }, public: false, hostname: { kind: 'ipv4', @@ -389,7 +389,7 @@ export const mockPatchData: DataModel = { }, { kind: 'ip', - gatewayId: 'wlan0', + gateway: { id: 'wlan0', name: 'Wireless', public: false }, public: false, hostname: { kind: 'ipv4', @@ -400,7 +400,7 @@ export const mockPatchData: DataModel = { }, { kind: 'ip', - gatewayId: 'eth0', + gateway: { id: 'eth0', name: 'Ethernet', public: false }, public: false, hostname: { kind: 'ipv6', @@ -412,7 +412,7 @@ export const mockPatchData: DataModel = { }, { kind: 'ip', - gatewayId: 'wlan0', + gateway: { id: 'wlan0', name: 'Wireless', public: false }, public: false, hostname: { kind: 'ipv6',