feat: add tunnel restart command

This commit is contained in:
Aiden McClelland
2026-03-18 23:49:29 -06:00
parent d669aa9afb
commit 427c38f23b
4 changed files with 36 additions and 3 deletions

View File

@@ -5275,6 +5275,13 @@ about.restart-service:
fr_FR: "Redémarrer un service" fr_FR: "Redémarrer un service"
pl_PL: "Uruchom ponownie usługę" pl_PL: "Uruchom ponownie usługę"
about.restart-tunnel:
en_US: "Reboot the tunnel server"
de_DE: "Den Tunnel-Server neu starten"
es_ES: "Reiniciar el servidor del túnel"
fr_FR: "Redémarrer le serveur tunnel"
pl_PL: "Uruchom ponownie serwer tunelu"
about.restore-packages-from-backup: about.restore-packages-from-backup:
en_US: "Restore packages from backup" en_US: "Restore packages from backup"
de_DE: "Pakete aus Backup wiederherstellen" de_DE: "Pakete aus Backup wiederherstellen"

View File

@@ -71,6 +71,13 @@ pub fn tunnel_api<C: Context>() -> ParentHandler<C> {
.with_call_remote::<CliContext>(), .with_call_remote::<CliContext>(),
), ),
) )
.subcommand(
"restart",
from_fn_async(restart)
.no_display()
.with_about("about.restart-tunnel")
.with_call_remote::<CliContext>(),
)
.subcommand( .subcommand(
"update", "update",
ParentHandler::<C>::new() ParentHandler::<C>::new()
@@ -91,7 +98,13 @@ pub fn tunnel_api<C: Context>() -> ParentHandler<C> {
) )
} }
pub async fn restart(ctx: TunnelContext) -> Result<(), Error> {
ctx.shutdown.send(Some(true)).ok();
Ok(())
}
#[derive(Deserialize, Serialize, Parser, TS)] #[derive(Deserialize, Serialize, Parser, TS)]
#[group(skip)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SubnetParams { pub struct SubnetParams {
#[ts(type = "string")] #[ts(type = "string")]
@@ -171,6 +184,7 @@ pub fn device_api<C: Context>() -> ParentHandler<C> {
} }
#[derive(Deserialize, Serialize, Parser, TS)] #[derive(Deserialize, Serialize, Parser, TS)]
#[group(skip)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct AddSubnetParams { pub struct AddSubnetParams {
name: InternedString, name: InternedString,
@@ -296,6 +310,7 @@ pub async fn remove_subnet(
} }
#[derive(Deserialize, Serialize, Parser, TS)] #[derive(Deserialize, Serialize, Parser, TS)]
#[group(skip)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct AddDeviceParams { pub struct AddDeviceParams {
#[ts(type = "string")] #[ts(type = "string")]
@@ -359,6 +374,7 @@ pub async fn add_device(
} }
#[derive(Deserialize, Serialize, Parser, TS)] #[derive(Deserialize, Serialize, Parser, TS)]
#[group(skip)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RemoveDeviceParams { pub struct RemoveDeviceParams {
#[ts(type = "string")] #[ts(type = "string")]
@@ -390,6 +406,7 @@ pub async fn remove_device(
} }
#[derive(Deserialize, Serialize, Parser, TS)] #[derive(Deserialize, Serialize, Parser, TS)]
#[group(skip)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ListDevicesParams { pub struct ListDevicesParams {
#[ts(type = "string")] #[ts(type = "string")]
@@ -411,6 +428,7 @@ pub async fn list_devices(
} }
#[derive(Deserialize, Serialize, Parser, TS)] #[derive(Deserialize, Serialize, Parser, TS)]
#[group(skip)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ShowConfigParams { pub struct ShowConfigParams {
#[ts(type = "string")] #[ts(type = "string")]
@@ -477,6 +495,7 @@ pub async fn show_config(
} }
#[derive(Deserialize, Serialize, Parser, TS)] #[derive(Deserialize, Serialize, Parser, TS)]
#[group(skip)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct AddPortForwardParams { pub struct AddPortForwardParams {
#[ts(type = "string")] #[ts(type = "string")]
@@ -546,6 +565,7 @@ pub async fn add_forward(
} }
#[derive(Deserialize, Serialize, Parser, TS)] #[derive(Deserialize, Serialize, Parser, TS)]
#[group(skip)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RemovePortForwardParams { pub struct RemovePortForwardParams {
#[ts(type = "string")] #[ts(type = "string")]
@@ -568,6 +588,7 @@ pub async fn remove_forward(
} }
#[derive(Deserialize, Serialize, Parser, TS)] #[derive(Deserialize, Serialize, Parser, TS)]
#[group(skip)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct UpdatePortForwardLabelParams { pub struct UpdatePortForwardLabelParams {
#[ts(type = "string")] #[ts(type = "string")]
@@ -597,10 +618,12 @@ pub async fn update_forward_label(
} }
#[derive(Deserialize, Serialize, Parser, TS)] #[derive(Deserialize, Serialize, Parser, TS)]
#[group(skip)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SetPortForwardEnabledParams { pub struct SetPortForwardEnabledParams {
#[ts(type = "string")] #[ts(type = "string")]
source: SocketAddrV4, source: SocketAddrV4,
#[arg(long)]
enabled: bool, enabled: bool,
} }

View File

@@ -41,6 +41,7 @@ use crate::util::io::read_file_to_string;
use crate::util::sync::{SyncMutex, Watch}; use crate::util::sync::{SyncMutex, Watch};
#[derive(Debug, Clone, Default, Deserialize, Serialize, Parser)] #[derive(Debug, Clone, Default, Deserialize, Serialize, Parser)]
#[group(skip)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
pub struct TunnelConfig { pub struct TunnelConfig {
@@ -80,7 +81,7 @@ pub struct TunnelContextSeed {
pub net_iface: Watch<OrdMap<GatewayId, NetworkInterfaceInfo>>, pub net_iface: Watch<OrdMap<GatewayId, NetworkInterfaceInfo>>,
pub forward: PortForwardController, pub forward: PortForwardController,
pub active_forwards: SyncMutex<BTreeMap<SocketAddrV4, Arc<()>>>, pub active_forwards: SyncMutex<BTreeMap<SocketAddrV4, Arc<()>>>,
pub shutdown: Sender<()>, pub shutdown: Sender<Option<bool>>,
} }
#[derive(Clone)] #[derive(Clone)]
@@ -238,6 +239,7 @@ impl Deref for TunnelContext {
} }
#[derive(Debug, Deserialize, Serialize, Parser)] #[derive(Debug, Deserialize, Serialize, Parser)]
#[group(skip)]
pub struct TunnelAddrParams { pub struct TunnelAddrParams {
#[arg(help = "help.arg.tunnel-ip-address")] #[arg(help = "help.arg.tunnel-ip-address")]
pub tunnel: IpAddr, pub tunnel: IpAddr,
@@ -305,6 +307,7 @@ impl CallRemote<TunnelContext> for CliContext {
} }
#[derive(Debug, Deserialize, Serialize, Parser)] #[derive(Debug, Deserialize, Serialize, Parser)]
#[group(skip)]
pub struct TunnelUrlParams { pub struct TunnelUrlParams {
#[arg(help = "help.arg.tunnel-url")] #[arg(help = "help.arg.tunnel-url")]
pub tunnel: Url, pub tunnel: Url,

View File

@@ -22,7 +22,7 @@ pub struct TunnelUpdateResult {
} }
#[instrument(skip_all)] #[instrument(skip_all)]
pub async fn check_update(_ctx: TunnelContext, _: Empty) -> Result<TunnelUpdateResult, Error> { pub async fn check_update(_ctx: TunnelContext) -> Result<TunnelUpdateResult, Error> {
Command::new("apt-get") Command::new("apt-get")
.arg("update") .arg("update")
.invoke(ErrorKind::UpdateFailed) .invoke(ErrorKind::UpdateFailed)
@@ -52,7 +52,7 @@ pub async fn check_update(_ctx: TunnelContext, _: Empty) -> Result<TunnelUpdateR
} }
#[instrument(skip_all)] #[instrument(skip_all)]
pub async fn apply_update(_ctx: TunnelContext, _: Empty) -> Result<TunnelUpdateResult, Error> { pub async fn apply_update(_ctx: TunnelContext) -> Result<TunnelUpdateResult, Error> {
let policy_output = Command::new("apt-cache") let policy_output = Command::new("apt-cache")
.arg("policy") .arg("policy")
.arg("start-tunnel") .arg("start-tunnel")