prevent gateways from getting stuck empty

This commit is contained in:
Aiden McClelland
2025-11-13 15:19:30 -07:00
parent b4d82b82a9
commit 1bf610a853
12 changed files with 94 additions and 68 deletions

34
core/Cargo.lock generated
View File

@@ -3458,7 +3458,7 @@ dependencies = [
"lazy_async_pool",
"models",
"pin-project",
"rpc-toolkit",
"rpc-toolkit 0.3.2 (git+https://github.com/Start9Labs/rpc-toolkit.git?branch=master)",
"serde",
"serde_json",
"tokio",
@@ -4835,7 +4835,7 @@ dependencies = [
"rand 0.9.2",
"regex",
"reqwest",
"rpc-toolkit",
"rpc-toolkit 0.3.2 (git+https://github.com/Start9Labs/rpc-toolkit.git?branch=master)",
"rustls 0.23.35",
"serde",
"serde_json",
@@ -6744,6 +6744,34 @@ dependencies = [
"yajrc",
]
[[package]]
name = "rpc-toolkit"
version = "0.3.2"
source = "git+https://github.com/Start9Labs/rpc-toolkit.git?rev=068db90#068db905ee38a7da97cc4a43b806409204e73723"
dependencies = [
"async-stream",
"async-trait",
"axum 0.8.6",
"clap",
"futures",
"http",
"http-body-util",
"imbl-value 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.14.0",
"lazy_format",
"lazy_static",
"openssl",
"pin-project",
"reqwest",
"serde",
"serde_json",
"thiserror 2.0.17",
"tokio",
"tokio-stream",
"url",
"yajrc",
]
[[package]]
name = "rsa"
version = "0.9.8"
@@ -7981,7 +8009,7 @@ dependencies = [
"reqwest",
"reqwest_cookie_store",
"rpassword",
"rpc-toolkit",
"rpc-toolkit 0.3.2 (git+https://github.com/Start9Labs/rpc-toolkit.git?rev=068db90)",
"rust-argon2",
"safelog",
"semver",

View File

@@ -223,7 +223,7 @@ regex = "1.10.2"
reqwest = { version = "0.12.4", features = ["json", "socks", "stream"] }
reqwest_cookie_store = "0.8.0"
rpassword = "7.2.0"
rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git", branch = "master" }
rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git", rev = "068db90" }
rust-argon2 = "2.0.0"
safelog = { version = "0.4.8", git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit", optional = true }
semver = { version = "1.0.20", features = ["serde"] }

View File

@@ -130,7 +130,6 @@ async fn list_interfaces(
}
#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)]
#[ts(export)]
struct NetworkInterfaceSetPublicParams {
gateway: GatewayId,
public: Option<bool>,
@@ -147,7 +146,6 @@ async fn set_public(
}
#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)]
#[ts(export)]
struct UnsetPublicParams {
gateway: GatewayId,
}
@@ -163,7 +161,6 @@ async fn unset_public(
}
#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)]
#[ts(export)]
struct ForgetGatewayParams {
gateway: GatewayId,
}
@@ -176,7 +173,6 @@ async fn forget_iface(
}
#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)]
#[ts(export)]
struct RenameGatewayParams {
id: GatewayId,
name: InternedString,
@@ -404,6 +400,12 @@ async fn watcher(
) {
loop {
let res: Result<(), Error> = async {
Command::new("systemctl")
.arg("start")
.arg("NetworkManager")
.invoke(ErrorKind::Network)
.await?;
let connection = Connection::system().await?;
let netman_proxy = NetworkManagerProxy::new(&connection).await?;
@@ -435,49 +437,60 @@ async fn watcher(
loop {
until
.run(async {
let devices = netman_proxy.all_devices().await?;
let mut ifaces = BTreeSet::new();
let mut jobs = Vec::new();
for device in devices {
use futures::future::Either;
let device_proxy =
device::DeviceProxy::new(&connection, device.clone()).await?;
let iface = InternedString::intern(device_proxy.ip_interface().await?);
if iface.is_empty() {
loop {
let devices = netman_proxy.all_devices().await?;
if devices.is_empty() {
tracing::warn!(
"NetworkManager returned no devices. Trying again..."
);
tokio::time::sleep(Duration::from_secs(1)).await;
continue;
}
let iface: GatewayId = iface.into();
if watch_activation.peek(|a| a.contains_key(&iface)) {
jobs.push(Either::Left(watch_activated(
let mut ifaces = BTreeSet::new();
let mut jobs = Vec::new();
for device in devices {
use futures::future::Either;
let device_proxy =
device::DeviceProxy::new(&connection, device.clone()).await?;
let iface =
InternedString::intern(device_proxy.ip_interface().await?);
if iface.is_empty() {
continue;
}
let iface: GatewayId = iface.into();
if watch_activation.peek(|a| a.contains_key(&iface)) {
jobs.push(Either::Left(watch_activated(
&connection,
device_proxy.clone(),
iface.clone(),
&watch_activation,
)));
}
jobs.push(Either::Right(watch_ip(
&connection,
device_proxy.clone(),
iface.clone(),
&watch_activation,
&watch_ip_info,
)));
ifaces.insert(iface);
}
jobs.push(Either::Right(watch_ip(
&connection,
device_proxy.clone(),
iface.clone(),
&watch_ip_info,
)));
ifaces.insert(iface);
}
watch_ip_info.send_if_modified(|m| {
let mut changed = false;
for (iface, info) in OrdMapIterMut::from(m) {
if !ifaces.contains(iface) {
info.ip_info = None;
changed = true;
watch_ip_info.send_if_modified(|m| {
let mut changed = false;
for (iface, info) in OrdMapIterMut::from(m) {
if !ifaces.contains(iface) {
info.ip_info = None;
changed = true;
}
}
}
changed
});
futures::future::try_join_all(jobs).await?;
changed
});
futures::future::try_join_all(jobs).await?;
break;
}
Ok::<_, Error>(())
})
.await?;

View File

@@ -49,7 +49,7 @@ pub mod net;
pub mod rpc;
pub mod rpc_client;
pub mod serde;
pub mod squashfs;
// pub mod squashfs;
pub mod sync;
pub mod tui;

View File

@@ -63,7 +63,7 @@ find . -type f -not -path "./DEBIAN/*" -exec md5sum {} \; | sort -k 2 | sed 's/\
cd ../..
cd dpkg-workdir
dpkg-deb --root-owner-group -b $BASENAME
dpkg-deb --root-owner-group -Zzstd -b $BASENAME
mkdir -p ../results
mv $BASENAME.deb ../results/$BASENAME.deb
rm -rf $BASENAME

View File

@@ -1,4 +0,0 @@
// 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 ForgetGatewayParams = { gateway: GatewayId }

View File

@@ -1,7 +0,0 @@
// 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 NetworkInterfaceSetPublicParams = {
gateway: GatewayId
public: boolean | null
}

View File

@@ -1,4 +0,0 @@
// 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 RenameGatewayParams = { id: GatewayId; name: string }

View File

@@ -1,3 +1,9 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AnyVerifyingKey } from "./AnyVerifyingKey"
import type { ContactInfo } from "./ContactInfo"
export type SignerInfo = { name: string }
export type SignerInfo = {
name: string
contact: Array<ContactInfo>
keys: Array<AnyVerifyingKey>
}

View File

@@ -1,4 +0,0 @@
// 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 UnsetPublicParams = { gateway: GatewayId }

View File

@@ -76,7 +76,6 @@ export { EventId } from "./EventId"
export { ExportActionParams } from "./ExportActionParams"
export { ExportServiceInterfaceParams } from "./ExportServiceInterfaceParams"
export { FileType } from "./FileType"
export { ForgetGatewayParams } from "./ForgetGatewayParams"
export { FullIndex } from "./FullIndex"
export { FullProgress } from "./FullProgress"
export { GatewayId } from "./GatewayId"
@@ -143,7 +142,6 @@ export { NamedProgress } from "./NamedProgress"
export { NetInfo } from "./NetInfo"
export { NetworkInfo } from "./NetworkInfo"
export { NetworkInterfaceInfo } from "./NetworkInterfaceInfo"
export { NetworkInterfaceSetPublicParams } from "./NetworkInterfaceSetPublicParams"
export { NetworkInterfaceType } from "./NetworkInterfaceType"
export { OnionHostname } from "./OnionHostname"
export { OsIndex } from "./OsIndex"
@@ -175,7 +173,6 @@ export { RemovePackageFromCategoryParams } from "./RemovePackageFromCategoryPara
export { RemovePackageParams } from "./RemovePackageParams"
export { RemoveTunnelParams } from "./RemoveTunnelParams"
export { RemoveVersionParams } from "./RemoveVersionParams"
export { RenameGatewayParams } from "./RenameGatewayParams"
export { ReplayId } from "./ReplayId"
export { RequestCommitment } from "./RequestCommitment"
export { RunActionParams } from "./RunActionParams"
@@ -211,7 +208,6 @@ export { TaskSeverity } from "./TaskSeverity"
export { TaskTrigger } from "./TaskTrigger"
export { Task } from "./Task"
export { TestSmtpParams } from "./TestSmtpParams"
export { UnsetPublicParams } from "./UnsetPublicParams"
export { UpdatingState } from "./UpdatingState"
export { VerifyCifsParams } from "./VerifyCifsParams"
export { VersionSignerParams } from "./VersionSignerParams"

View File

@@ -59,7 +59,9 @@ export class AppComponent {
await this.api.reboot()
this.dialogs
.open(
'Please wait 1-2 minutes, then refresh this page to access the StartOS setup wizard.',
window.location.host === 'localhost'
? 'Please wait 1-2 minutes for your server to restart'
: 'Please wait 1-2 minutes, then refresh this page to access the StartOS setup wizard.',
{
label: 'Rebooting',
size: 's',