backend changes

This commit is contained in:
Aiden McClelland
2025-07-22 16:48:16 -06:00
parent 4d9709eb1c
commit d3e7e37f59
28 changed files with 211 additions and 162 deletions

View File

@@ -52,6 +52,7 @@ pub fn action_api<C: Context>() -> ParentHandler<C> {
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ActionInput {
pub event_id: Guid,
#[ts(type = "Record<string, unknown>")]
pub spec: Value,
#[ts(type = "Record<string, unknown> | null")]
@@ -270,6 +271,7 @@ pub fn display_action_result<T: Serialize>(
#[serde(rename_all = "camelCase")]
pub struct RunActionParams {
pub package_id: PackageId,
pub event_id: Option<Guid>,
pub action_id: ActionId,
#[ts(optional, type = "any")]
pub input: Option<Value>,
@@ -278,6 +280,7 @@ pub struct RunActionParams {
#[derive(Parser)]
struct CliRunActionParams {
pub package_id: PackageId,
pub event_id: Option<Guid>,
pub action_id: ActionId,
#[command(flatten)]
pub input: StdinDeserializable<Option<Value>>,
@@ -286,12 +289,14 @@ impl From<CliRunActionParams> for RunActionParams {
fn from(
CliRunActionParams {
package_id,
event_id,
action_id,
input,
}: CliRunActionParams,
) -> Self {
Self {
package_id,
event_id,
action_id,
input: input.0,
}
@@ -331,6 +336,7 @@ pub async fn run_action(
ctx: RpcContext,
RunActionParams {
package_id,
event_id,
action_id,
input,
}: RunActionParams,
@@ -340,7 +346,11 @@ pub async fn run_action(
.await
.as_ref()
.or_not_found(lazy_format!("Manager for {}", package_id))?
.run_action(Guid::new(), action_id, input.unwrap_or_default())
.run_action(
event_id.unwrap_or_default(),
action_id,
input.unwrap_or_default(),
)
.await
.map(|res| res.map(ActionResult::upcast))
}

View File

@@ -198,13 +198,12 @@ pub struct NetworkInfo {
#[model = "Model<Self>"]
#[ts(export)]
pub struct NetworkInterfaceInfo {
pub inbound: Option<bool>,
pub outbound: Option<bool>,
pub public: Option<bool>,
pub ip_info: Option<IpInfo>,
}
impl NetworkInterfaceInfo {
pub fn inbound(&self) -> bool {
self.inbound.unwrap_or_else(|| {
pub fn public(&self) -> bool {
self.public.unwrap_or_else(|| {
!self.ip_info.as_ref().map_or(true, |ip_info| {
let ip4s = ip_info
.subnets

View File

@@ -169,7 +169,7 @@ impl LanPortForwardController {
(
iface.clone(),
(
info.inbound(),
info.public(),
info.ip_info.as_ref().map_or(Vec::new(), |i| {
i.subnets
.iter()
@@ -205,7 +205,7 @@ impl LanPortForwardController {
ip_info
.iter()
.map(|(iface, info)| (iface.clone(), (
info.inbound(),
info.public(),
info.ip_info.as_ref().map_or(Vec::new(), |i| {
i.subnets
.iter()

View File

@@ -335,7 +335,7 @@ impl NetServiceData {
for (interface, public, ip_info) in
net_ifaces.iter().filter_map(|(interface, info)| {
if let Some(ip_info) = &info.ip_info {
Some((interface, info.inbound(), ip_info))
Some((interface, info.public(), ip_info))
} else {
None
}

View File

@@ -58,7 +58,7 @@ pub fn network_interface_api<C: Context>() -> ParentHandler<C> {
info.ip_info.as_ref()
.and_then(|ip_info| ip_info.device_type)
.map_or_else(|| "UNKNOWN".to_owned(), |ty| format!("{ty:?}")),
info.inbound(),
info.public(),
info.ip_info.as_ref().map_or_else(
|| "<DISCONNECTED>".to_owned(),
|ip_info| ip_info.subnets
@@ -585,21 +585,24 @@ async fn watch_ip(
None
};
write_to.send_if_modified(|m| {
let (inbound, outbound) = m
.get(&iface)
.map_or((None, None), |i| (i.inbound, i.outbound));
m.insert(
iface.clone(),
NetworkInterfaceInfo {
inbound,
outbound,
ip_info: ip_info.clone(),
},
)
.filter(|old| &old.ip_info == &ip_info)
.is_none()
});
write_to.send_if_modified(
|m: &mut BTreeMap<
InternedString,
NetworkInterfaceInfo,
>| {
let public =
m.get(&iface).map_or(None, |i| i.public);
m.insert(
iface.clone(),
NetworkInterfaceInfo {
public,
ip_info: ip_info.clone(),
},
)
.filter(|old| &old.ip_info == &ip_info)
.is_none()
},
);
Ok::<_, Error>(())
})
@@ -856,7 +859,7 @@ impl NetworkInterfaceController {
return false;
}
}
.inbound,
.public,
public,
);
prev != public
@@ -968,8 +971,7 @@ impl ListenerMap {
) -> Result<(), Error> {
let mut keep = BTreeSet::<SocketAddr>::new();
for info in ip_info.values().chain([&NetworkInterfaceInfo {
inbound: Some(false),
outbound: Some(false),
public: Some(false),
ip_info: Some(IpInfo {
name: "lo".into(),
scope_id: 1,
@@ -984,7 +986,7 @@ impl ListenerMap {
ntp_servers: Default::default(),
}),
}]) {
if public || !info.inbound() {
if public || !info.public() {
if let Some(ip_info) = &info.ip_info {
for ipnet in &ip_info.subnets {
let addr = match ipnet.addr() {
@@ -1003,7 +1005,7 @@ impl ListenerMap {
};
keep.insert(addr);
if let Some((_, is_public, wan_ip)) = self.listeners.get_mut(&addr) {
*is_public = info.inbound();
*is_public = info.public();
*wan_ip = info.ip_info.as_ref().and_then(|i| i.wan_ip);
continue;
}
@@ -1021,7 +1023,7 @@ impl ListenerMap {
.into(),
)
.with_kind(ErrorKind::Network)?,
info.inbound(),
info.public(),
info.ip_info.as_ref().and_then(|i| i.wan_ip),
),
);

View File

@@ -110,10 +110,6 @@ pub async fn list(
})
})
.collect::<Result<Vec<NotificationWithId>, Error>>()?;
db.as_public_mut()
.as_server_info_mut()
.as_unread_notification_count_mut()
.ser(&0)?;
Ok(notifs)
}
Some(before) => {
@@ -195,22 +191,23 @@ pub async fn mark_seen(
) -> Result<(), Error> {
ctx.db
.mutate(|db| {
let mut diff = 0;
let n = db.as_private_mut().as_notifications_mut();
for id in ids {
if !n
.as_idx_mut(&id)
n.as_idx_mut(&id)
.or_not_found(lazy_format!("Notification #{id}"))?
.as_seen_mut()
.replace(&true)?
{
diff += 1;
.ser(&true)?;
}
let mut unread = 0;
for (_, n) in n.as_entries()? {
if !n.as_seen().de()? {
unread += 1;
}
}
db.as_public_mut()
.as_server_info_mut()
.as_unread_notification_count_mut()
.mutate(|n| Ok(*n -= diff))?;
.ser(&unread)?;
Ok(())
})
.await
@@ -223,22 +220,23 @@ pub async fn mark_seen_before(
) -> Result<(), Error> {
ctx.db
.mutate(|db| {
let mut diff = 0;
let n = db.as_private_mut().as_notifications_mut();
for id in n.keys()?.range(..before) {
if !n
.as_idx_mut(&id)
n.as_idx_mut(&id)
.or_not_found(lazy_format!("Notification #{id}"))?
.as_seen_mut()
.replace(&true)?
{
diff += 1;
.ser(&true)?;
}
let mut unread = 0;
for (_, n) in n.as_entries()? {
if !n.as_seen().de()? {
unread += 1;
}
}
db.as_public_mut()
.as_server_info_mut()
.as_unread_notification_count_mut()
.mutate(|n| Ok(*n -= diff))?;
.ser(&unread)?;
Ok(())
})
.await
@@ -251,21 +249,23 @@ pub async fn mark_unseen(
) -> Result<(), Error> {
ctx.db
.mutate(|db| {
let mut diff = 0;
let n = db.as_private_mut().as_notifications_mut();
for id in ids {
if n.as_idx_mut(&id)
n.as_idx_mut(&id)
.or_not_found(lazy_format!("Notification #{id}"))?
.as_seen_mut()
.replace(&false)?
{
diff += 1;
.ser(&false)?;
}
let mut unread = 0;
for (_, n) in n.as_entries()? {
if !n.as_seen().de()? {
unread += 1;
}
}
db.as_public_mut()
.as_server_info_mut()
.as_unread_notification_count_mut()
.mutate(|n| Ok(*n += diff))?;
.ser(&unread)?;
Ok(())
})
.await

View File

@@ -115,7 +115,7 @@ pub fn update_tasks(
}
pub(super) struct RunAction {
id: ActionId,
action_id: ActionId,
input: Value,
}
impl Handler<RunAction> for ServiceActor {
@@ -127,7 +127,7 @@ impl Handler<RunAction> for ServiceActor {
&mut self,
id: Guid,
RunAction {
id: ref action_id,
ref action_id,
input,
}: RunAction,
jobs: &BackgroundJobQueue,
@@ -145,7 +145,7 @@ impl Handler<RunAction> for ServiceActor {
.into_idx(package_id)
.or_not_found(package_id)?
.into_actions()
.into_idx(&action_id)
.into_idx(action_id)
.or_not_found(lazy_format!("{package_id} action {action_id}"))?
.de()?;
if matches!(&action.visibility, ActionVisibility::Disabled(_)) {
@@ -226,14 +226,6 @@ impl Service {
action_id: ActionId,
input: Value,
) -> Result<Option<ActionResult>, Error> {
self.actor
.send(
id,
RunAction {
id: action_id,
input,
},
)
.await?
self.actor.send(id, RunAction { action_id, input }).await?
}
}

View File

@@ -21,21 +21,15 @@ pub async fn rebuild(context: EffectContext) -> Result<(), Error> {
Ok(())
}
pub async fn restart(
context: EffectContext,
ProcedureId { procedure_id }: ProcedureId,
) -> Result<(), Error> {
pub async fn restart(context: EffectContext, EventId { event_id }: EventId) -> Result<(), Error> {
let context = context.deref()?;
context.restart(procedure_id, false).await?;
context.restart(event_id, false).await?;
Ok(())
}
pub async fn shutdown(
context: EffectContext,
ProcedureId { procedure_id }: ProcedureId,
) -> Result<(), Error> {
pub async fn shutdown(context: EffectContext, EventId { event_id }: EventId) -> Result<(), Error> {
let context = context.deref()?;
context.stop(procedure_id, false).await?;
context.stop(event_id, false).await?;
Ok(())
}

View File

@@ -9,8 +9,8 @@ pub(super) use crate::service::effects::context::EffectContext;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct ProcedureId {
pub struct EventId {
#[serde(default)]
#[arg(default_value_t, long)]
pub procedure_id: Guid,
pub event_id: Guid,
}

View File

@@ -105,7 +105,6 @@ pub struct PersistentContainer {
pub(super) lxc_container: OnceCell<LxcContainer>,
pub(super) rpc_client: UnixRpcClient,
pub(super) rpc_server: watch::Sender<Option<(NonDetachingJoinHandle<()>, ShutdownHandle)>>,
// procedures: Mutex<Vec<(ProcedureName, ProcedureId)>>,
js_mount: MountGuard,
volumes: BTreeMap<VolumeId, MountGuard>,
assets: Vec<MountGuard>,

View File

@@ -202,6 +202,7 @@ pub async fn cli_update_system(
prev.overall.set_complete();
progress.update(&prev);
}
println!("Update complete. Restart your server to apply the update.")
} else {
println!("Updating to v{v}...")
}