hotfixes for alpha.16

This commit is contained in:
Aiden McClelland
2025-12-18 04:22:56 -07:00
parent 83133ced6a
commit cd70fa4c32
109 changed files with 410 additions and 263 deletions

View File

@@ -161,7 +161,7 @@ results/$(REGISTRY_BASENAME).deb: dpkg-build.sh $(call ls-files,debian/start-reg
tunnel-deb: results/$(TUNNEL_BASENAME).deb
results/$(TUNNEL_BASENAME).deb: dpkg-build.sh $(call ls-files,debian/start-tunnel) $(TUNNEL_TARGETS)
results/$(TUNNEL_BASENAME).deb: dpkg-build.sh $(call ls-files,debian/start-tunnel) $(TUNNEL_TARGETS) build/lib/scripts/forward-port
PROJECT=start-tunnel PLATFORM=$(ARCH) REQUIRES=debian DEPENDS=wireguard-tools,iptables,conntrack ./build/os-compat/run-compat.sh ./dpkg-build.sh
$(IMAGE_TYPE): results/$(BASENAME).$(IMAGE_TYPE)

View File

@@ -5,29 +5,47 @@ if [ -z "$sip" ] || [ -z "$dip" ] || [ -z "$sport" ] || [ -z "$dport" ]; then
exit 1
fi
rule_exists() {
iptables -t nat -C "$@" 2>/dev/null
}
NAME="F$(echo "$sip:$sport -> $dip:$dport" | sha256sum | head -c 15)"
apply_rule() {
if [ "$UNDO" = "1" ]; then
if rule_exists "$@"; then
iptables -t nat -D "$@"
for kind in INPUT FORWARD ACCEPT; do
if ! iptables -C $kind -j "${NAME}_${kind}" 2> /dev/null; then
iptables -N "${NAME}_${kind}" 2> /dev/null
iptables -A $kind -j "${NAME}_${kind}"
fi
else
if ! rule_exists "$@"; then
iptables -t nat -A "$@"
done
for kind in PREROUTING INPUT OUTPUT POSTROUTING; do
if ! iptables -t nat -C $kind -j "${NAME}_${kind}" 2> /dev/null; then
iptables -t nat -N "${NAME}_${kind}" 2> /dev/null
iptables -t nat -A $kind -j "${NAME}_${kind}"
fi
fi
}
done
apply_rule PREROUTING -p tcp -d $sip --dport $sport -j DNAT --to-destination $dip:$dport
apply_rule PREROUTING -p udp -d $sip --dport $sport -j DNAT --to-destination $dip:$dport
apply_rule OUTPUT -p tcp -d $sip --dport $sport -j DNAT --to-destination $dip:$dport
apply_rule OUTPUT -p udp -d $sip --dport $sport -j DNAT --to-destination $dip:$dport
apply_rule POSTROUTING -p tcp -d $dip --dport $dport -j MASQUERADE
apply_rule POSTROUTING -p udp -d $dip --dport $dport -j MASQUERADE
err=0
trap 'err=1' ERR
for kind in INPUT FORWARD ACCEPT; do
iptables -F "${NAME}_${kind}" 2> /dev/null
done
for kind in PREROUTING INPUT OUTPUT POSTROUTING; do
iptables -t nat -F "${NAME}_${kind}" 2> /dev/null
done
if [ "$UNDO" = 1 ]; then
conntrack -D -p tcp -d $sip --dport $sport || true # conntrack returns exit 1 if no connections are active
conntrack -D -p udp -d $sip --dport $sport || true # conntrack returns exit 1 if no connections are active
exit $err
fi
iptables -t nat -A ${NAME}_PREROUTING -d "$sip" -p tcp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
iptables -t nat -A ${NAME}_PREROUTING -d "$sip" -p udp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
iptables -t nat -A ${NAME}_OUTPUT -d "$sip" -p tcp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
iptables -t nat -A ${NAME}_OUTPUT -d "$sip" -p udp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
iptables -t nat -A ${NAME}_PREROUTING -s "$dip/24" -d "$sip" -p tcp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
iptables -t nat -A ${NAME}_PREROUTING -s "$dip/24" -d "$sip" -p udp --dport "$sport" -j DNAT --to-destination "$dip:$dport"
iptables -t nat -A ${NAME}_POSTROUTING -s "$dip/24" -d "$dip" -p tcp --dport "$dport" -j MASQUERADE
iptables -t nat -A ${NAME}_POSTROUTING -s "$dip/24" -d "$dip" -p udp --dport "$dport" -j MASQUERADE
iptables -A ${NAME}_FORWARD -d $dip -p tcp --dport $dport -m state --state NEW -j ACCEPT
iptables -A ${NAME}_FORWARD -d $dip -p udp --dport $dport -m state --state NEW -j ACCEPT
exit $err

View File

@@ -4,6 +4,7 @@ OnFailure=container-runtime-failure.service
[Service]
Type=simple
Environment=RUST_LOG=startos=debug
ExecStart=/usr/bin/node --experimental-detect-module --trace-warnings --unhandled-rejections=warn /usr/lib/startos/init/index.js
Restart=no

View File

@@ -68,7 +68,10 @@ export class SystemForStartOs implements System {
try {
if (this.runningMain || this.starting) return
this.starting = true
effects.constRetry = utils.once(() => effects.restart())
effects.constRetry = utils.once(() => {
console.debug(".const() triggered")
effects.restart()
})
let mainOnTerm: () => Promise<void> | undefined
const daemons = await (
await this.abi.main({

View File

@@ -1,14 +1,13 @@
use std::fmt;
use clap::{CommandFactory, FromArgMatches, Parser};
pub use crate::ActionId;
use crate::{PackageId, ReplayId};
use qrcode::QrCode;
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use tracing::instrument;
use ts_rs::TS;
pub use crate::ActionId;
use crate::context::{CliContext, RpcContext};
use crate::db::model::package::TaskSeverity;
use crate::prelude::*;
@@ -16,6 +15,7 @@ use crate::rpc_continuations::Guid;
use crate::util::serde::{
HandlerExtSerde, StdinDeserializable, WithIoFormat, display_serializable,
};
use crate::{PackageId, ReplayId};
pub fn action_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new()

View File

@@ -6,7 +6,6 @@ use chrono::Utc;
use clap::Parser;
use color_eyre::eyre::eyre;
use imbl::OrdSet;
use crate::PackageId;
use serde::{Deserialize, Serialize};
use tokio::io::AsyncWriteExt;
use tracing::instrument;
@@ -14,6 +13,7 @@ use ts_rs::TS;
use super::PackageBackupReport;
use super::target::{BackupTargetId, PackageBackupInfo};
use crate::PackageId;
use crate::backup::os::OsBackup;
use crate::backup::{BackupReport, ServerBackupReport};
use crate::context::RpcContext;

View File

@@ -1,9 +1,9 @@
use std::collections::BTreeMap;
use crate::PackageId;
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use crate::PackageId;
use crate::context::CliContext;
#[allow(unused_imports)]
use crate::prelude::*;

View File

@@ -3,7 +3,6 @@ use std::sync::Arc;
use clap::Parser;
use futures::{StreamExt, stream};
use crate::PackageId;
use patch_db::json_ptr::ROOT;
use serde::{Deserialize, Serialize};
use tokio::sync::Mutex;
@@ -11,7 +10,6 @@ use tracing::instrument;
use ts_rs::TS;
use super::target::BackupTargetId;
use crate::PLATFORM;
use crate::backup::os::OsBackup;
use crate::context::setup::SetupResult;
use crate::context::{RpcContext, SetupContext};
@@ -27,6 +25,7 @@ use crate::service::service_map::DownloadInstallFuture;
use crate::setup::SetupExecuteProgress;
use crate::system::sync_kiosk;
use crate::util::serde::IoFormat;
use crate::{PLATFORM, PackageId};
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]

View File

@@ -9,8 +9,6 @@ use digest::OutputSizeUser;
use digest::generic_array::GenericArray;
use exver::Version;
use imbl_value::InternedString;
use crate::util::FromStrParser;
use crate::PackageId;
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use sha2::Sha256;
@@ -19,6 +17,7 @@ use tracing::instrument;
use ts_rs::TS;
use self::cifs::CifsBackupTarget;
use crate::PackageId;
use crate::context::{CliContext, RpcContext};
use crate::db::model::DatabaseModel;
use crate::disk::mount::backup::BackupMountGuard;
@@ -28,10 +27,10 @@ use crate::disk::mount::filesystem::{FileSystem, MountType, ReadWrite};
use crate::disk::mount::guard::{GenericMountGuard, TmpMountGuard};
use crate::disk::util::PartitionInfo;
use crate::prelude::*;
use crate::util::VersionString;
use crate::util::serde::{
HandlerExtSerde, WithIoFormat, deserialize_from_str, display_serializable, serialize_display,
};
use crate::util::{FromStrParser, VersionString};
pub mod cifs;

View File

@@ -5,7 +5,6 @@ use std::time::Duration;
use clap::Parser;
use futures::FutureExt;
use crate::util::future::NonDetachingJoinHandle;
use rpc_toolkit::CliApp;
use tokio::signal::unix::signal;
use tracing::instrument;
@@ -20,6 +19,7 @@ use crate::prelude::*;
use crate::tunnel::context::{TunnelConfig, TunnelContext};
use crate::tunnel::tunnel_router;
use crate::tunnel::web::TunnelCertHandler;
use crate::util::future::NonDetachingJoinHandle;
use crate::util::logger::LOGGER;
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]

View File

@@ -8,12 +8,10 @@ use std::sync::atomic::{AtomicBool, Ordering};
use std::time::Duration;
use chrono::{TimeDelta, Utc};
use crate::util::future::NonDetachingJoinHandle;
use imbl::OrdMap;
use imbl_value::InternedString;
use itertools::Itertools;
use josekit::jwk::Jwk;
use crate::{ActionId, PackageId};
use reqwest::{Client, Proxy};
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{CallRemote, Context, Empty};
@@ -22,7 +20,6 @@ use tokio::time::Instant;
use tracing::instrument;
use super::setup::CURRENT_SECRET;
use crate::DATA_DIR;
use crate::account::AccountInfo;
use crate::auth::Sessions;
use crate::context::config::ServerConfig;
@@ -45,9 +42,11 @@ use crate::service::ServiceMap;
use crate::service::action::update_tasks;
use crate::service::effects::callbacks::ServiceCallbacks;
use crate::shutdown::Shutdown;
use crate::util::future::NonDetachingJoinHandle;
use crate::util::io::delete_file;
use crate::util::lshw::LshwDevice;
use crate::util::sync::{SyncMutex, SyncRwLock, Watch};
use crate::{ActionId, DATA_DIR, PackageId};
pub struct RpcContextSeed {
is_closed: AtomicBool,

View File

@@ -4,7 +4,6 @@ use std::sync::Arc;
use std::time::Duration;
use futures::{Future, StreamExt};
use crate::util::future::NonDetachingJoinHandle;
use imbl_value::InternedString;
use josekit::jwk::Jwk;
use patch_db::PatchDb;
@@ -28,6 +27,7 @@ use crate::progress::FullProgressTracker;
use crate::rpc_continuations::{Guid, RpcContinuation, RpcContinuations};
use crate::setup::SetupProgress;
use crate::shutdown::Shutdown;
use crate::util::future::NonDetachingJoinHandle;
use crate::util::net::WebSocketExt;
lazy_static::lazy_static! {

View File

@@ -1,12 +1,11 @@
use clap::Parser;
use crate::PackageId;
use serde::{Deserialize, Serialize};
use tracing::instrument;
use ts_rs::TS;
use crate::Error;
use crate::context::RpcContext;
use crate::prelude::*;
use crate::{Error, PackageId};
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]

View File

@@ -4,8 +4,6 @@ use std::path::PathBuf;
use chrono::{DateTime, Utc};
use exver::VersionRange;
use imbl_value::InternedString;
use crate::util::DataUrl;
use crate::{ActionId, HealthCheckId, HostId, PackageId, ReplayId, ServiceInterfaceId};
use patch_db::HasModel;
use patch_db::json_ptr::JsonPointer;
use reqwest::Url;
@@ -18,7 +16,9 @@ use crate::prelude::*;
use crate::progress::FullProgress;
use crate::s9pk::manifest::Manifest;
use crate::status::StatusInfo;
use crate::util::DataUrl;
use crate::util::serde::{Pem, is_partial_of};
use crate::{ActionId, HealthCheckId, HostId, PackageId, ReplayId, ServiceInterfaceId};
#[derive(Debug, Default, Deserialize, Serialize, TS)]
#[ts(export)]

View File

@@ -1,9 +1,9 @@
use std::collections::{BTreeMap, HashSet};
use crate::PackageId;
use patch_db::{HasModel, Value};
use serde::{Deserialize, Serialize};
use crate::PackageId;
use crate::auth::Sessions;
use crate::backup::target::cifs::CifsTargets;
use crate::net::forward::AvailablePorts;

View File

@@ -9,7 +9,6 @@ use imbl_value::InternedString;
use ipnet::IpNet;
use isocountry::CountryCode;
use itertools::Itertools;
use crate::{GatewayId, PackageId};
use openssl::hash::MessageDigest;
use patch_db::{HasModel, Value};
use serde::{Deserialize, Serialize};
@@ -31,7 +30,7 @@ use crate::util::cpupower::Governor;
use crate::util::lshw::LshwDevice;
use crate::util::serde::MaybeUtf8String;
use crate::version::{Current, VersionT};
use crate::{ARCH, PLATFORM};
use crate::{ARCH, GatewayId, PLATFORM, PackageId};
pub static DB_UI_SEED_CELL: OnceLock<&'static str> = OnceLock::new();

View File

@@ -2,13 +2,12 @@ use std::collections::BTreeMap;
use std::path::Path;
use imbl_value::InternedString;
use crate::PackageId;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::Error;
use crate::prelude::*;
use crate::util::PathOrUrl;
use crate::{Error, PackageId};
#[derive(Clone, Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[model = "Model<Self>"]

View File

@@ -2,11 +2,11 @@ use std::path::{Path, PathBuf};
use std::sync::Arc;
use color_eyre::eyre::eyre;
use crate::PackageId;
use tokio::io::AsyncWriteExt;
use tracing::instrument;
use super::guard::{GenericMountGuard, TmpMountGuard};
use crate::PackageId;
use crate::auth::check_password;
use crate::backup::target::BackupInfo;
use crate::disk::mount::filesystem::ReadWrite;

View File

@@ -8,7 +8,6 @@ use clap::Parser;
use clap::builder::ValueParserFactory;
use digest::generic_array::GenericArray;
use digest::{Digest, OutputSizeUser};
use crate::util::FromStrParser;
use serde::{Deserialize, Serialize};
use sha2::Sha256;
use tokio::process::Command;
@@ -16,7 +15,7 @@ use ts_rs::TS;
use super::FileSystem;
use crate::prelude::*;
use crate::util::Invoke;
use crate::util::{FromStrParser, Invoke};
#[derive(Clone, Copy, Debug, Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]

View File

@@ -4,14 +4,13 @@ use std::sync::{Arc, Weak};
use futures::Future;
use lazy_static::lazy_static;
use crate::ResultExt;
use tokio::sync::Mutex;
use tracing::instrument;
use super::filesystem::{FileSystem, MountType, ReadOnly, ReadWrite};
use super::util::unmount;
use crate::Error;
use crate::util::{Invoke, Never};
use crate::{Error, ResultExt};
pub const TMP_MOUNTPOINT: &'static str = "/media/startos/tmp";

View File

@@ -1,7 +1,6 @@
use std::fmt::{Debug, Display};
use axum::http::StatusCode;
use tokio_rustls::rustls;
use axum::http::uri::InvalidUri;
use color_eyre::eyre::eyre;
use num_enum::TryFromPrimitive;
@@ -12,6 +11,7 @@ use rpc_toolkit::yajrc::{
};
use serde::{Deserialize, Serialize};
use tokio::task::JoinHandle;
use tokio_rustls::rustls;
use ts_rs::TS;
use crate::InvalidId;
@@ -217,7 +217,8 @@ impl Error {
source: E,
kind: ErrorKind,
) -> Self {
let debug = (std::any::TypeId::of::<E>() == std::any::TypeId::of::<color_eyre::eyre::Error>())
let debug = (std::any::TypeId::of::<E>()
== std::any::TypeId::of::<color_eyre::eyre::Error>())
.then(|| eyre!("{source:?}"));
Error {
source: source.into(),
@@ -591,7 +592,8 @@ where
fn with_ctx<F: FnOnce(&E) -> (ErrorKind, D), D: Display>(self, f: F) -> Result<T, Error> {
self.map_err(|e| {
let (kind, ctx) = f(&e);
let debug = (std::any::TypeId::of::<E>() == std::any::TypeId::of::<color_eyre::eyre::Error>())
let debug = (std::any::TypeId::of::<E>()
== std::any::TypeId::of::<color_eyre::eyre::Error>())
.then(|| eyre!("{ctx}: {e:?}"));
let source = color_eyre::eyre::Error::from(e);
let with_ctx = format!("{ctx}: {source}");

View File

@@ -2,9 +2,9 @@ use std::convert::Infallible;
use std::path::Path;
use std::str::FromStr;
use imbl_value::InternedString;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use imbl_value::InternedString;
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, TS)]
#[ts(type = "string")]

View File

@@ -1,9 +1,9 @@
use std::path::Path;
use std::str::FromStr;
use imbl_value::InternedString;
use serde::{Deserialize, Deserializer, Serialize};
use ts_rs::TS;
use imbl_value::InternedString;
use crate::{Id, InvalidId};

View File

@@ -1,9 +1,9 @@
use std::borrow::Borrow;
use std::str::FromStr;
use imbl_value::InternedString;
use regex::Regex;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use imbl_value::InternedString;
mod action;
mod gateway;

View File

@@ -2,9 +2,9 @@ use std::borrow::Borrow;
use std::path::Path;
use std::str::FromStr;
use imbl_value::InternedString;
use serde::{Deserialize, Serialize, Serializer};
use ts_rs::TS;
use imbl_value::InternedString;
use crate::{Id, InvalidId, SYSTEM_ID};

View File

@@ -2,9 +2,9 @@ use std::convert::Infallible;
use std::path::Path;
use std::str::FromStr;
use imbl_value::InternedString;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use imbl_value::InternedString;
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, TS)]
#[ts(type = "string")]

View File

@@ -5,8 +5,8 @@ use rpc_toolkit::clap::builder::ValueParserFactory;
use serde::{Deserialize, Deserializer, Serialize};
use ts_rs::TS;
use crate::util::FromStrParser;
use crate::Id;
use crate::util::FromStrParser;
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, TS)]
#[ts(export, type = "string")]

View File

@@ -10,7 +10,6 @@ use exver::VersionRange;
use futures::StreamExt;
use imbl_value::{InternedString, json};
use itertools::Itertools;
use crate::util::{FromStrParser, VersionString};
use reqwest::Url;
use reqwest::header::{CONTENT_LENGTH, HeaderMap};
use rpc_toolkit::HandlerArgs;
@@ -31,10 +30,10 @@ use crate::rpc_continuations::{Guid, RpcContinuation};
use crate::s9pk::manifest::PackageId;
use crate::s9pk::v2::SIG_CONTEXT;
use crate::upload::upload;
use crate::util::Never;
use crate::util::io::open_file;
use crate::util::net::WebSocketExt;
use crate::util::tui::choose;
use crate::util::{FromStrParser, Never, VersionString};
pub const PKG_ARCHIVE_DIR: &str = "package-data/archive";
pub const PKG_PUBLIC_DIR: &str = "package-data/public";

View File

@@ -43,8 +43,8 @@ pub mod diagnostic;
pub mod disk;
pub mod error;
pub mod firmware;
pub mod id;
pub mod hostname;
pub mod id;
pub mod init;
pub mod install;
pub mod logs;

View File

@@ -13,8 +13,6 @@ use color_eyre::eyre::eyre;
use futures::stream::BoxStream;
use futures::{Future, FutureExt, Stream, StreamExt, TryStreamExt};
use itertools::Itertools;
use crate::util::FromStrParser;
use crate::PackageId;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{
CallRemote, Context, Empty, HandlerArgs, HandlerExt, HandlerFor, ParentHandler, from_fn_async,
@@ -27,13 +25,14 @@ use tokio_stream::wrappers::LinesStream;
use tokio_tungstenite::tungstenite::Message;
use tracing::instrument;
use crate::PackageId;
use crate::context::{CliContext, RpcContext};
use crate::error::ResultExt;
use crate::prelude::*;
use crate::rpc_continuations::{Guid, RpcContinuation, RpcContinuations};
use crate::util::Invoke;
use crate::util::net::WebSocketExt;
use crate::util::serde::Reversible;
use crate::util::{FromStrParser, Invoke};
#[pin_project::pin_project]
pub struct LogStream {

View File

@@ -7,8 +7,6 @@ use std::time::Duration;
use clap::builder::ValueParserFactory;
use futures::StreamExt;
use imbl_value::InternedString;
use crate::util::FromStrParser;
use crate::{InvalidId, PackageId};
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{RpcRequest, RpcResponse};
use serde::{Deserialize, Serialize};
@@ -31,7 +29,8 @@ use crate::rpc_continuations::{Guid, RpcContinuation};
use crate::service::ServiceStats;
use crate::util::io::open_file;
use crate::util::rpc_client::UnixRpcClient;
use crate::util::{Invoke, new_guid};
use crate::util::{FromStrParser, Invoke, new_guid};
use crate::{InvalidId, PackageId};
const LXC_CONTAINER_DIR: &str = "/var/lib/lxc";
const RPC_DIR: &str = "media/startos/rpc"; // must not be absolute path

View File

@@ -9,8 +9,6 @@ use clap::builder::ValueParserFactory;
use futures::StreamExt;
use imbl_value::InternedString;
use itertools::Itertools;
use crate::error::ErrorData;
use crate::util::FromStrParser;
use openssl::pkey::{PKey, Private};
use openssl::x509::X509;
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
@@ -27,10 +25,12 @@ use crate::context::{CliContext, RpcContext};
use crate::db::model::Database;
use crate::db::model::public::AcmeSettings;
use crate::db::{DbAccess, DbAccessByKey, DbAccessMut};
use crate::error::ErrorData;
use crate::net::ssl::should_use_cert;
use crate::net::tls::{SingleCertResolver, TlsHandler};
use crate::net::web_server::Accept;
use crate::prelude::*;
use crate::util::FromStrParser;
use crate::util::serde::{Pem, Pkcs8Doc};
use crate::util::sync::{SyncMutex, Watch};

View File

@@ -9,7 +9,6 @@ use clap::Parser;
use color_eyre::eyre::eyre;
use futures::future::BoxFuture;
use futures::{FutureExt, StreamExt};
use crate::util::future::NonDetachingJoinHandle;
use hickory_client::client::Client;
use hickory_client::proto::DnsHandle;
use hickory_client::proto::runtime::TokioRuntimeProvider;
@@ -23,7 +22,6 @@ use hickory_server::proto::rr::{Name, Record, RecordType};
use hickory_server::server::{Request, RequestHandler, ResponseHandler, ResponseInfo};
use imbl::OrdMap;
use imbl_value::InternedString;
use crate::{GatewayId, OptionExt, PackageId};
use patch_db::json_ptr::JsonPointer;
use rpc_toolkit::{
Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async, from_fn_blocking,
@@ -38,9 +36,11 @@ use crate::db::model::public::NetworkInterfaceInfo;
use crate::net::gateway::NetworkInterfaceWatcher;
use crate::prelude::*;
use crate::util::actor::background::BackgroundJobQueue;
use crate::util::future::NonDetachingJoinHandle;
use crate::util::io::file_string_stream;
use crate::util::serde::{HandlerExtSerde, display_serializable};
use crate::util::sync::{SyncRwLock, Watch};
use crate::{GatewayId, OptionExt, PackageId};
pub fn dns_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new()

View File

@@ -4,21 +4,21 @@ use std::sync::{Arc, Weak};
use std::time::Duration;
use futures::channel::oneshot;
use crate::util::future::NonDetachingJoinHandle;
use id_pool::IdPool;
use iddqd::{IdOrdItem, IdOrdMap};
use imbl::OrdMap;
use crate::GatewayId;
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use tokio::process::Command;
use tokio::sync::mpsc;
use crate::GatewayId;
use crate::context::{CliContext, RpcContext};
use crate::db::model::public::NetworkInterfaceInfo;
use crate::net::gateway::{DynInterfaceFilter, InterfaceFilter};
use crate::prelude::*;
use crate::util::Invoke;
use crate::util::future::NonDetachingJoinHandle;
use crate::util::serde::{HandlerExtSerde, display_serializable};
use crate::util::sync::Watch;
@@ -180,11 +180,51 @@ pub struct PortForwardController {
_thread: NonDetachingJoinHandle<()>,
}
pub async fn add_iptables_rule(nat: bool, undo: bool, args: &[&str]) -> Result<(), Error> {
let mut cmd = Command::new("iptables");
if nat {
cmd.arg("-t").arg("nat");
}
if undo != !cmd.arg("-C").args(args).status().await?.success() {
let mut cmd = Command::new("iptables");
if nat {
cmd.arg("-t").arg("nat");
}
if undo {
cmd.arg("-D");
} else {
cmd.arg("-A");
}
cmd.args(args).invoke(ErrorKind::Network).await?;
}
Ok(())
}
impl PortForwardController {
pub fn new() -> Self {
let (req_send, mut req_recv) = mpsc::unbounded_channel::<PortForwardCommand>();
let thread = NonDetachingJoinHandle::from(tokio::spawn(async move {
while let Err(e) = async {
Command::new("iptables")
.arg("-P")
.arg("FORWARD")
.arg("DROP")
.invoke(ErrorKind::Network)
.await?;
add_iptables_rule(
false,
false,
&[
"FORWARD",
"-m",
"state",
"--state",
"ESTABLISHED,RELATED",
"-j",
"ACCEPT",
],
)
.await?;
Command::new("sysctl")
.arg("-w")
.arg("net.ipv4.ip_forward=1")

View File

@@ -10,12 +10,10 @@ use std::time::Duration;
use clap::Parser;
use futures::future::Either;
use futures::{FutureExt, Stream, StreamExt, TryStreamExt};
use crate::util::future::NonDetachingJoinHandle;
use imbl::{OrdMap, OrdSet};
use imbl_value::InternedString;
use ipnet::IpNet;
use itertools::Itertools;
use crate::GatewayId;
use nix::net::if_::if_nametoindex;
use patch_db::json_ptr::JsonPointer;
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
@@ -32,6 +30,7 @@ use zbus::zvariant::{
};
use zbus::{Connection, proxy};
use crate::GatewayId;
use crate::context::{CliContext, RpcContext};
use crate::db::model::Database;
use crate::db::model::public::{IpInfo, NetworkInterfaceInfo, NetworkInterfaceType};
@@ -42,7 +41,7 @@ use crate::net::web_server::{Accept, AcceptStream, Acceptor, MetadataVisitor};
use crate::prelude::*;
use crate::util::Invoke;
use crate::util::collections::OrdMapIterMut;
use crate::util::future::Until;
use crate::util::future::{NonDetachingJoinHandle, Until};
use crate::util::io::open_file;
use crate::util::serde::{HandlerExtSerde, display_serializable};
use crate::util::sync::{SyncMutex, Watch};
@@ -65,13 +64,15 @@ pub fn gateway_api<C: Context>() -> ParentHandler<C> {
for (iface, info) in res {
table.add_row(row![
iface,
info.ip_info.as_ref()
info.ip_info
.as_ref()
.and_then(|ip_info| ip_info.device_type)
.map_or_else(|| "UNKNOWN".to_owned(), |ty| format!("{ty:?}")),
info.public(),
info.ip_info.as_ref().map_or_else(
|| "<DISCONNECTED>".to_owned(),
|ip_info| ip_info.subnets
|ip_info| ip_info
.subnets
.iter()
.map(|ipnet| match ipnet.addr() {
IpAddr::V4(ip) => format!("{ip}/{}", ipnet.prefix_len()),
@@ -81,8 +82,10 @@ pub fn gateway_api<C: Context>() -> ParentHandler<C> {
ipnet.prefix_len()
),
})
.join(", ")),
info.ip_info.as_ref()
.join(", ")
),
info.ip_info
.as_ref()
.and_then(|ip_info| ip_info.wan_ip)
.map_or_else(|| "N/A".to_owned(), |ip| ip.to_string())
]);
@@ -102,25 +105,33 @@ pub fn gateway_api<C: Context>() -> ParentHandler<C> {
.no_display()
.with_about("Indicate whether this gateway has inbound access from the WAN")
.with_call_remote::<CliContext>(),
).subcommand(
)
.subcommand(
"unset-public",
from_fn_async(unset_public)
.with_metadata("sync_db", Value::Bool(true))
.no_display()
.with_about("Allow this gateway to infer whether it has inbound access from the WAN based on its IPv4 address")
.with_about(concat!(
"Allow this gateway to infer whether it has",
" inbound access from the WAN based on its IPv4 address"
))
.with_call_remote::<CliContext>(),
).subcommand("forget",
)
.subcommand(
"forget",
from_fn_async(forget_iface)
.with_metadata("sync_db", Value::Bool(true))
.no_display()
.with_about("Forget a disconnected gateway")
.with_call_remote::<CliContext>()
).subcommand("set-name",
.with_call_remote::<CliContext>(),
)
.subcommand(
"set-name",
from_fn_async(set_name)
.with_metadata("sync_db", Value::Bool(true))
.no_display()
.with_about("Rename a gateway")
.with_call_remote::<CliContext>()
.with_call_remote::<CliContext>(),
)
}
@@ -266,6 +277,9 @@ trait Ip4Config {
#[zbus(property)]
fn address_data(&self) -> Result<Vec<AddressData>, Error>;
#[zbus(property)]
fn route_data(&self) -> Result<Vec<RouteData>, Error>;
#[zbus(property)]
fn gateway(&self) -> Result<String, Error>;
@@ -301,6 +315,14 @@ impl TryFrom<AddressData> for IpNet {
}
}
#[derive(Clone, Debug, DeserializeDict, ZValue, ZType)]
#[zvariant(signature = "dict")]
struct RouteData {
dest: String,
prefix: u32,
table: Option<u32>,
}
#[derive(Clone, Debug, DeserializeDict, ZValue, ZType)]
#[zvariant(signature = "dict")]
struct NameserverData {
@@ -613,6 +635,7 @@ async fn watch_ip(
Ip6ConfigProxy::new(&connection, ip6_config.clone()).await?;
let mut until = Until::new()
.with_stream(ip4_proxy.receive_address_data_changed().await.stub())
.with_stream(ip4_proxy.receive_route_data_changed().await.stub())
.with_stream(ip4_proxy.receive_gateway_changed().await.stub())
.with_stream(
ip4_proxy.receive_nameserver_data_changed().await.stub(),
@@ -680,6 +703,22 @@ async fn watch_ip(
.into_iter()
.map(IpNet::try_from)
.try_collect()?;
let tables = ip4_proxy.route_data().await?.into_iter().filter_map(|d|d.table).collect::<Vec<_>>();
if !tables.is_empty() {
let rules = String::from_utf8(Command::new("ip").arg("rule").arg("list").invoke(ErrorKind::Network).await?)?;
for table in tables {
for subnet in subnets.iter().filter(|s| s.addr().is_ipv4()) {
let subnet_string = subnet.trunc().to_string();
let rule = ["from", &subnet_string, "lookup", &table.to_string()];
if !rules.contains(&rule.join(" ")) {
if rules.contains(&rule[..2].join(" ")) {
Command::new("ip").arg("rule").arg("del").args(&rule[..2]).invoke(ErrorKind::Network).await?;
}
Command::new("ip").arg("rule").arg("add").args(rule).invoke(ErrorKind::Network).await?;
}
}
}
}
let wan_ip = if !subnets.is_empty()
&& !matches!(
device_type,
@@ -1405,12 +1444,8 @@ impl<B: Bind> ListenerMap<B> {
&mut self,
cx: &mut std::task::Context<'_>,
) -> Poll<Result<(SocketAddr, <B::Accept as Accept>::Metadata, AcceptStream), Error>> {
for (addr, listener) in self.listeners.iter_mut() {
if let Poll::Ready((metadata, stream)) = listener.poll_accept(cx)? {
return Poll::Ready(Ok((*addr, metadata, stream)));
}
}
Poll::Pending
let (metadata, stream) = ready!(self.listeners.poll_accept(cx)?);
Poll::Ready(Ok((metadata.key, metadata.inner, stream)))
}
}

View File

@@ -3,11 +3,11 @@ use std::net::Ipv4Addr;
use clap::Parser;
use imbl_value::InternedString;
use crate::GatewayId;
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::GatewayId;
use crate::context::{CliContext, RpcContext};
use crate::db::model::DatabaseModel;
use crate::net::acme::AcmeProvider;

View File

@@ -4,8 +4,6 @@ use std::str::FromStr;
use clap::Parser;
use clap::builder::ValueParserFactory;
use imbl::OrdSet;
use crate::util::FromStrParser;
use crate::{GatewayId, HostId};
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -17,7 +15,9 @@ use crate::net::gateway::InterfaceFilter;
use crate::net::host::HostApiKind;
use crate::net::vhost::AlpnInfo;
use crate::prelude::*;
use crate::util::FromStrParser;
use crate::util::serde::{HandlerExtSerde, display_serializable};
use crate::{GatewayId, HostId};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, TS)]
#[ts(export)]

View File

@@ -5,7 +5,6 @@ use std::panic::RefUnwindSafe;
use clap::Parser;
use imbl_value::InternedString;
use itertools::Itertools;
use crate::{HostId, PackageId};
use rpc_toolkit::{Context, Empty, HandlerExt, OrEmpty, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -18,6 +17,7 @@ use crate::net::host::binding::{BindInfo, BindOptions, binding};
use crate::net::service_interface::HostnameInfo;
use crate::net::tor::OnionAddress;
use crate::prelude::*;
use crate::{HostId, PackageId};
pub mod address;
pub mod binding;

View File

@@ -6,19 +6,17 @@ use color_eyre::eyre::eyre;
use imbl::{OrdMap, vector};
use imbl_value::InternedString;
use ipnet::IpNet;
use crate::{GatewayId, HostId, OptionExt, PackageId};
use tokio::sync::Mutex;
use tokio::task::JoinHandle;
use tokio_rustls::rustls::ClientConfig as TlsClientConfig;
use tracing::instrument;
use crate::HOST_IP;
use crate::db::model::Database;
use crate::db::model::public::NetworkInterfaceType;
use crate::error::ErrorCollection;
use crate::hostname::Hostname;
use crate::net::dns::DnsController;
use crate::net::forward::{InterfacePortForwardController, START9_BRIDGE_IFACE};
use crate::net::forward::{InterfacePortForwardController, START9_BRIDGE_IFACE, add_iptables_rule};
use crate::net::gateway::{
AndFilter, DynInterfaceFilter, IdFilter, InterfaceFilter, NetworkInterfaceController, OrFilter,
PublicFilter, SecureFilter, TypeFilter,
@@ -34,6 +32,7 @@ use crate::net::vhost::{AlpnInfo, DynVHostTarget, ProxyTarget, VHostController};
use crate::prelude::*;
use crate::service::effects::callbacks::ServiceCallbacks;
use crate::util::serde::MaybeUtf8String;
use crate::{GatewayId, HOST_IP, HostId, OptionExt, PackageId};
pub struct NetController {
pub(crate) db: TypedPatchDb<Database>,
@@ -70,6 +69,22 @@ impl NetController {
.de()?
.0],
)?);
add_iptables_rule(
false,
false,
&[
"FORWARD",
"-i",
START9_BRIDGE_IFACE,
"-m",
"state",
"--state",
"NEW",
"-j",
"ACCEPT",
],
)
.await?;
Ok(Self {
db: db.clone(),
tor,

View File

@@ -1,10 +1,11 @@
use std::net::{Ipv4Addr, Ipv6Addr};
use imbl_value::InternedString;
use crate::{GatewayId, HostId, ServiceInterfaceId};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::{GatewayId, HostId, ServiceInterfaceId};
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]

View File

@@ -2,7 +2,6 @@ use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::sync::Arc;
use std::time::Duration;
use crate::util::future::NonDetachingJoinHandle;
use socks5_impl::protocol::{Address, Reply};
use socks5_impl::server::auth::NoAuth;
use socks5_impl::server::{AuthAdaptor, ClientConnection, Server};
@@ -12,6 +11,7 @@ use crate::HOST_IP;
use crate::net::tor::TorController;
use crate::prelude::*;
use crate::util::actor::background::BackgroundJobQueue;
use crate::util::future::NonDetachingJoinHandle;
pub const DEFAULT_SOCKS_LISTEN: SocketAddr = SocketAddr::V4(SocketAddrV4::new(
Ipv4Addr::new(HOST_IP[0], HOST_IP[1], HOST_IP[2], HOST_IP[3]),

View File

@@ -22,7 +22,6 @@ use http::request::Parts as RequestParts;
use http::{HeaderValue, Method, StatusCode};
use imbl_value::InternedString;
use include_dir::Dir;
use crate::PackageId;
use new_mime_guess::MimeGuess;
use openssl::hash::MessageDigest;
use openssl::x509::X509;
@@ -33,7 +32,6 @@ use url::Url;
use crate::context::{DiagnosticContext, InitContext, InstallContext, RpcContext, SetupContext};
use crate::hostname::Hostname;
use crate::main_api;
use crate::middleware::auth::{Auth, HasValidSession};
use crate::middleware::cors::Cors;
use crate::middleware::db::SyncDb;
@@ -49,6 +47,7 @@ use crate::sign::commitment::merkle_archive::MerkleArchiveCommitment;
use crate::util::io::open_file;
use crate::util::net::SyncBody;
use crate::util::serde::BASE64;
use crate::{PackageId, main_api};
const NOT_FOUND: &[u8] = b"Not Found";
const METHOD_NOT_ALLOWED: &[u8] = b"Method Not Allowed";

View File

@@ -11,7 +11,6 @@ use base64::Engine;
use clap::Parser;
use color_eyre::eyre::eyre;
use futures::{FutureExt, StreamExt};
use crate::util::future::NonDetachingJoinHandle;
use imbl_value::InternedString;
use itertools::Itertools;
use rpc_toolkit::{Context, Empty, HandlerExt, ParentHandler, from_fn_async};
@@ -31,7 +30,7 @@ use ts_rs::TS;
use crate::context::{CliContext, RpcContext};
use crate::prelude::*;
use crate::util::actor::background::BackgroundJobQueue;
use crate::util::future::Until;
use crate::util::future::{NonDetachingJoinHandle, Until};
use crate::util::io::ReadWriter;
use crate::util::serde::{
BASE64, Base64, HandlerExtSerde, WithIoFormat, deserialize_from_str, display_serializable,

View File

@@ -10,7 +10,6 @@ use clap::Parser;
use color_eyre::eyre::eyre;
use futures::future::BoxFuture;
use futures::{FutureExt, TryFutureExt, TryStreamExt};
use crate::util::future::NonDetachingJoinHandle;
use imbl::OrdMap;
use imbl_value::InternedString;
use lazy_static::lazy_static;
@@ -31,6 +30,7 @@ use crate::logs::{LogSource, LogsParams, journalctl};
use crate::prelude::*;
use crate::util::Invoke;
use crate::util::collections::ordmap_retain;
use crate::util::future::NonDetachingJoinHandle;
use crate::util::io::{ReadWriter, write_file_atomic};
use crate::util::serde::{
BASE64, Base64, HandlerExtSerde, WithIoFormat, deserialize_from_str, display_serializable,

View File

@@ -1,12 +1,12 @@
use clap::Parser;
use imbl_value::InternedString;
use crate::GatewayId;
use patch_db::json_ptr::JsonPointer;
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use tokio::process::Command;
use ts_rs::TS;
use crate::GatewayId;
use crate::context::{CliContext, RpcContext};
use crate::db::model::public::{NetworkInterfaceInfo, NetworkInterfaceType};
use crate::net::host::all_hosts;

View File

@@ -8,11 +8,11 @@ use futures::stream::BoxStream;
use futures::{StreamExt, TryStreamExt};
use imbl_value::InternedString;
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
use crate::GatewayId;
use nix::net::if_::if_nametoindex;
use tokio::net::{TcpListener, TcpStream};
use tokio::process::Command;
use crate::GatewayId;
use crate::db::model::public::{IpInfo, NetworkInterfaceType};
use crate::prelude::*;
use crate::util::Invoke;

View File

@@ -9,9 +9,7 @@ use async_acme::acme::ACME_TLS_ALPN_NAME;
use color_eyre::eyre::eyre;
use futures::FutureExt;
use futures::future::BoxFuture;
use crate::util::future::NonDetachingJoinHandle;
use imbl_value::{InOMap, InternedString};
use crate::ResultExt;
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn};
use serde::{Deserialize, Serialize};
use tokio::net::TcpStream;
@@ -24,6 +22,7 @@ use tracing::instrument;
use ts_rs::TS;
use visit_rs::Visit;
use crate::ResultExt;
use crate::context::{CliContext, RpcContext};
use crate::db::model::Database;
use crate::db::model::public::AcmeSettings;
@@ -42,7 +41,7 @@ use crate::net::tls::{
use crate::net::web_server::{Accept, AcceptStream, ExtractVisitor, TcpMetadata, extract};
use crate::prelude::*;
use crate::util::collections::EqSet;
use crate::util::future::WeakFuture;
use crate::util::future::{NonDetachingJoinHandle, WeakFuture};
use crate::util::serde::{HandlerExtSerde, MaybeUtf8String, display_serializable};
use crate::util::sync::{SyncMutex, Watch};

View File

@@ -12,7 +12,6 @@ use std::time::Duration;
use axum::Router;
use futures::future::Either;
use futures::{FutureExt, TryFutureExt};
use crate::util::future::NonDetachingJoinHandle;
use http::Extensions;
use hyper_util::rt::{TokioIo, TokioTimer};
use tokio::net::TcpListener;
@@ -22,6 +21,7 @@ use visit_rs::{Visit, VisitFields, Visitor};
use crate::net::static_server::{UiContext, ui_router};
use crate::prelude::*;
use crate::util::actor::background::BackgroundJobQueue;
use crate::util::future::NonDetachingJoinHandle;
use crate::util::io::ReadWriter;
use crate::util::sync::{SyncRwLock, Watch};
@@ -483,7 +483,7 @@ where
.http2()
.timer(TokioTimer::new())
.enable_connect_protocol()
.keep_alive_interval(Duration::from_secs(60))
.keep_alive_interval(Duration::from_secs(25))
.keep_alive_timeout(Duration::from_secs(300));
let (queue, mut runner) = BackgroundJobQueue::new();
queue_cell.replace(Some(queue.clone()));

View File

@@ -7,17 +7,17 @@ use clap::Parser;
use clap::builder::ValueParserFactory;
use color_eyre::eyre::eyre;
use imbl_value::InternedString;
use crate::util::FromStrParser;
use crate::PackageId;
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use tracing::instrument;
use ts_rs::TS;
use crate::PackageId;
use crate::backup::BackupReport;
use crate::context::{CliContext, RpcContext};
use crate::db::model::DatabaseModel;
use crate::prelude::*;
use crate::util::FromStrParser;
use crate::util::serde::{HandlerExtSerde, const_true};
// #[command(subcommands(list, delete, delete_before, create))]

View File

@@ -2,13 +2,11 @@ use std::path::{Path, PathBuf};
use clap::Parser;
use color_eyre::eyre::eyre;
use crate::Error;
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use tokio::process::Command;
use ts_rs::TS;
use crate::ARCH;
use crate::context::config::ServerConfig;
use crate::context::{CliContext, InstallContext};
use crate::disk::OsPartitionInfo;
@@ -25,6 +23,7 @@ use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile;
use crate::util::Invoke;
use crate::util::io::{TmpDir, delete_file, open_file};
use crate::util::serde::IoFormat;
use crate::{ARCH, Error};
mod gpt;
mod mbr;

View File

@@ -3,7 +3,6 @@ use std::path::Path;
use std::sync::Arc;
use chrono::{DateTime, Utc};
use crate::util::future::NonDetachingJoinHandle;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use tokio::io::AsyncWrite;
@@ -20,6 +19,7 @@ use crate::sign::commitment::merkle_archive::MerkleArchiveCommitment;
use crate::sign::commitment::{Commitment, Digestable};
use crate::sign::{AnySignature, AnyVerifyingKey};
use crate::upload::UploadingFile;
use crate::util::future::NonDetachingJoinHandle;
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]

View File

@@ -4,7 +4,6 @@ use std::path::PathBuf;
use clap::Parser;
use imbl_value::InternedString;
use itertools::Itertools;
use crate::util::DataUrl;
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -13,6 +12,7 @@ use crate::context::CliContext;
use crate::prelude::*;
use crate::registry::context::RegistryContext;
use crate::registry::package::index::Category;
use crate::util::DataUrl;
use crate::util::serde::{HandlerExtSerde, WithIoFormat};
pub fn info_api<C: Context>() -> ParentHandler<C, WithIoFormat<Empty>> {

View File

@@ -3,7 +3,6 @@ use std::collections::{BTreeMap, BTreeSet};
use axum::Router;
use futures::future::ready;
use imbl_value::InternedString;
use crate::util::DataUrl;
use rpc_toolkit::{Context, HandlerExt, ParentHandler, Server, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -19,6 +18,7 @@ use crate::registry::os::index::OsIndex;
use crate::registry::package::index::PackageIndex;
use crate::registry::signer::SignerInfo;
use crate::rpc_continuations::Guid;
use crate::util::DataUrl;
use crate::util::serde::HandlerExtSerde;
pub mod admin;

View File

@@ -4,13 +4,12 @@ use std::sync::Arc;
use clap::Parser;
use imbl_value::InternedString;
use itertools::Itertools;
use crate::util::VersionString;
use crate::PackageId;
use rpc_toolkit::HandlerArgs;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use url::Url;
use crate::PackageId;
use crate::context::CliContext;
use crate::prelude::*;
use crate::progress::{FullProgressTracker, ProgressTrackerWriter, ProgressUnits};
@@ -23,6 +22,7 @@ use crate::s9pk::v2::SIG_CONTEXT;
use crate::sign::commitment::merkle_archive::MerkleArchiveCommitment;
use crate::sign::ed25519::Ed25519;
use crate::sign::{AnySignature, AnyVerifyingKey, SignatureScheme};
use crate::util::VersionString;
use crate::util::io::TrackingIO;
#[derive(Debug, Deserialize, Serialize, TS)]

View File

@@ -2,11 +2,11 @@ use std::collections::BTreeMap;
use clap::Parser;
use imbl_value::InternedString;
use crate::PackageId;
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::PackageId;
use crate::context::CliContext;
use crate::prelude::*;
use crate::registry::context::RegistryContext;

View File

@@ -5,10 +5,10 @@ use clap::{Parser, ValueEnum};
use exver::{ExtendedVersion, VersionRange};
use imbl_value::{InternedString, json};
use itertools::Itertools;
use crate::PackageId;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::PackageId;
use crate::context::CliContext;
use crate::prelude::*;
use crate::progress::{FullProgressTracker, ProgressUnits};

View File

@@ -3,12 +3,11 @@ use std::collections::{BTreeMap, BTreeSet};
use chrono::Utc;
use exver::{Version, VersionRange};
use imbl_value::InternedString;
use crate::util::{DataUrl, VersionString};
use crate::PackageId;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use url::Url;
use crate::PackageId;
use crate::prelude::*;
use crate::registry::asset::RegistryAsset;
use crate::registry::context::RegistryContext;
@@ -20,6 +19,7 @@ use crate::s9pk::manifest::{Alerts, Description, HardwareRequirements};
use crate::s9pk::merkle_archive::source::FileSource;
use crate::sign::commitment::merkle_archive::MerkleArchiveCommitment;
use crate::sign::{AnySignature, AnyVerifyingKey};
use crate::util::{DataUrl, VersionString};
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]

View File

@@ -2,11 +2,11 @@ use std::collections::BTreeMap;
use clap::Parser;
use exver::VersionRange;
use crate::PackageId;
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::PackageId;
use crate::context::CliContext;
use crate::prelude::*;
use crate::registry::admin::display_package_signers;

View File

@@ -3,7 +3,6 @@ use std::str::FromStr;
use clap::builder::ValueParserFactory;
use itertools::Itertools;
use crate::util::FromStrParser;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use url::Url;
@@ -11,6 +10,7 @@ use url::Url;
use crate::prelude::*;
use crate::sign::commitment::Digestable;
use crate::sign::{AnySignature, AnyVerifyingKey, SignatureScheme};
use crate::util::FromStrParser;
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]

View File

@@ -12,14 +12,13 @@ use clap::builder::ValueParserFactory;
use futures::future::BoxFuture;
use futures::{Future, FutureExt};
use imbl_value::InternedString;
use crate::util::FromStrParser;
use tokio::sync::{Mutex as AsyncMutex, broadcast};
use ts_rs::TS;
#[allow(unused_imports)]
use crate::prelude::*;
use crate::util::future::TimedResource;
use crate::util::new_guid;
use crate::util::{FromStrParser, new_guid};
#[derive(
Debug, Clone, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, TS,

View File

@@ -2,11 +2,11 @@ use std::path::PathBuf;
use std::sync::Arc;
use clap::Parser;
use crate::ImageId;
use rpc_toolkit::{Empty, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::ImageId;
use crate::context::CliContext;
use crate::prelude::*;
use crate::s9pk::manifest::Manifest;

View File

@@ -4,15 +4,15 @@ use std::path::{Path, PathBuf};
use exver::{Version, VersionRange};
use imbl_value::InternedString;
use indexmap::IndexMap;
pub use crate::PackageId;
use crate::{ActionId, HealthCheckId, ImageId, VolumeId};
use serde::{Deserialize, Serialize};
use url::Url;
pub use crate::PackageId;
use crate::prelude::*;
use crate::s9pk::git_hash::GitHash;
use crate::s9pk::manifest::{Alerts, Description};
use crate::util::serde::{Duration, IoFormat, Regex};
use crate::{ActionId, HealthCheckId, ImageId, VolumeId};
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]

View File

@@ -9,7 +9,6 @@ use std::task::{Context, Poll};
use color_eyre::eyre::eyre;
use digest::Output;
use ed25519_dalek::VerifyingKey;
use crate::{ImageId, PackageId};
use sha2::{Digest, Sha512};
use tokio::fs::File;
use tokio::io::{AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, BufReader, ReadBuf};
@@ -21,6 +20,7 @@ use crate::prelude::*;
use crate::s9pk::v1::docker::DockerReader;
use crate::util::VersionString;
use crate::util::io::open_file;
use crate::{ImageId, PackageId};
#[pin_project::pin_project]
#[derive(Debug)]

View File

@@ -4,22 +4,21 @@ use std::path::Path;
use color_eyre::eyre::eyre;
use exver::{Version, VersionRange};
use imbl_value::InternedString;
pub use crate::PackageId;
use crate::util::mime;
use crate::{ImageId, VolumeId};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use url::Url;
pub use crate::PackageId;
use crate::dependencies::Dependencies;
use crate::prelude::*;
use crate::s9pk::git_hash::GitHash;
use crate::s9pk::merkle_archive::directory_contents::DirectoryContents;
use crate::s9pk::merkle_archive::expected::{Expected, Filter};
use crate::s9pk::v2::pack::ImageConfig;
use crate::util::VersionString;
use crate::util::serde::Regex;
use crate::util::{VersionString, mime};
use crate::version::{Current, VersionT};
use crate::{ImageId, VolumeId};
fn current_version() -> Version {
Current::default().semver()

View File

@@ -3,10 +3,9 @@ use std::path::Path;
use std::sync::Arc;
use imbl_value::InternedString;
use crate::util::{DataUrl, mime};
use crate::PackageId;
use tokio::fs::File;
use crate::PackageId;
use crate::dependencies::DependencyMetadata;
use crate::prelude::*;
use crate::s9pk::manifest::Manifest;
@@ -20,6 +19,7 @@ use crate::s9pk::v2::pack::{ImageSource, PackSource};
use crate::sign::commitment::merkle_archive::MerkleArchiveCommitment;
use crate::util::io::{TmpDir, open_file};
use crate::util::serde::IoFormat;
use crate::util::{DataUrl, mime};
const MAGIC_AND_VERSION: &[u8] = &[0x3b, 0x3b, 0x02];

View File

@@ -2,8 +2,6 @@ use std::collections::BTreeMap;
use std::time::Duration;
use imbl_value::json;
use crate::service::ProcedureName;
use crate::{ActionId, PackageId, ReplayId};
use crate::action::{ActionInput, ActionResult};
use crate::db::model::package::{
@@ -11,10 +9,11 @@ use crate::db::model::package::{
};
use crate::prelude::*;
use crate::rpc_continuations::Guid;
use crate::service::{Service, ServiceActor};
use crate::service::{ProcedureName, Service, ServiceActor};
use crate::util::actor::background::BackgroundJobQueue;
use crate::util::actor::{ConflictBuilder, Handler};
use crate::util::serde::is_partial_of;
use crate::{ActionId, PackageId, ReplayId};
pub(super) struct GetActionInput {
id: ActionId,

View File

@@ -1,6 +1,5 @@
use std::collections::BTreeSet;
use crate::{ActionId, PackageId, ReplayId};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use crate::action::{ActionInput, ActionResult, display_action_result};
@@ -11,6 +10,7 @@ use crate::rpc_continuations::Guid;
use crate::service::cli::ContainerCliContext;
use crate::service::effects::prelude::*;
use crate::util::serde::HandlerExtSerde;
use crate::{ActionId, PackageId, ReplayId};
pub fn action_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new()

View File

@@ -5,10 +5,8 @@ use std::time::{Duration, SystemTime};
use clap::Parser;
use futures::future::join_all;
use crate::util::future::NonDetachingJoinHandle;
use imbl::{Vector, vector};
use imbl_value::InternedString;
use crate::{HostId, PackageId, ServiceInterfaceId};
use serde::{Deserialize, Serialize};
use tracing::warn;
use ts_rs::TS;
@@ -20,6 +18,8 @@ use crate::service::effects::net::ssl::Algorithm;
use crate::service::rpc::{CallbackHandle, CallbackId};
use crate::service::{Service, ServiceActorSeed};
use crate::util::collections::EqMap;
use crate::util::future::NonDetachingJoinHandle;
use crate::{HostId, PackageId, ServiceInterfaceId};
#[derive(Default)]
pub struct ServiceCallbacks(Mutex<ServiceCallbackMap>);

View File

@@ -2,13 +2,13 @@ use std::str::FromStr;
use chrono::Utc;
use clap::builder::ValueParserFactory;
use crate::util::FromStrParser;
use crate::PackageId;
use crate::PackageId;
use crate::service::RebuildParams;
use crate::service::effects::prelude::*;
use crate::service::rpc::CallbackId;
use crate::status::{DesiredStatus, StatusInfo};
use crate::util::FromStrParser;
pub async fn rebuild(context: EffectContext) -> Result<(), Error> {
let seed = context.deref()?.seed.clone();

View File

@@ -5,10 +5,7 @@ use std::str::FromStr;
use clap::builder::ValueParserFactory;
use exver::VersionRange;
use imbl_value::InternedString;
use crate::util::{FromStrParser, VersionString};
use crate::{HealthCheckId, PackageId, ReplayId, VolumeId};
use crate::DATA_DIR;
use crate::db::model::package::{
CurrentDependencies, CurrentDependencyInfo, CurrentDependencyKind, ManifestPreference,
TaskEntry,
@@ -19,7 +16,9 @@ use crate::disk::mount::filesystem::{FileSystem, MountType};
use crate::disk::mount::util::{is_mountpoint, unmount};
use crate::service::effects::prelude::*;
use crate::status::health_check::NamedHealthCheckResult;
use crate::util::{FromStrParser, VersionString};
use crate::volume::data_dir;
use crate::{DATA_DIR, HealthCheckId, PackageId, ReplayId, VolumeId};
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]

View File

@@ -1,5 +1,4 @@
use crate::HealthCheckId;
use crate::service::effects::prelude::*;
use crate::status::health_check::NamedHealthCheckResult;

View File

@@ -1,7 +1,6 @@
use crate::{HostId, PackageId};
use crate::net::host::binding::{BindId, BindOptions, NetInfo};
use crate::service::effects::prelude::*;
use crate::{HostId, PackageId};
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]

View File

@@ -1,9 +1,8 @@
use crate::{HostId, PackageId};
use crate::net::host::Host;
use crate::service::effects::callbacks::CallbackHandler;
use crate::service::effects::prelude::*;
use crate::service::rpc::CallbackId;
use crate::{HostId, PackageId};
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]

View File

@@ -1,7 +1,6 @@
use std::net::Ipv4Addr;
use crate::PackageId;
use crate::service::effects::callbacks::CallbackHandler;
use crate::service::effects::prelude::*;
use crate::service::rpc::CallbackId;

View File

@@ -1,12 +1,12 @@
use std::collections::BTreeMap;
use imbl::vector;
use crate::{PackageId, ServiceInterfaceId};
use crate::net::service_interface::{AddressInfo, ServiceInterface, ServiceInterfaceType};
use crate::service::effects::callbacks::CallbackHandler;
use crate::service::effects::prelude::*;
use crate::service::rpc::CallbackId;
use crate::{PackageId, ServiceInterfaceId};
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]

View File

@@ -13,10 +13,8 @@ use clap::Parser;
use futures::future::BoxFuture;
use futures::stream::FusedStream;
use futures::{FutureExt, SinkExt, StreamExt, TryStreamExt};
use crate::util::future::NonDetachingJoinHandle;
use imbl_value::{InternedString, json};
use itertools::Itertools;
use crate::{ActionId, HostId, ImageId, PackageId};
use nix::sys::signal::Signal;
use persistent_container::{PersistentContainer, Subcontainer};
use rpc_toolkit::HandlerArgs;
@@ -47,12 +45,13 @@ use crate::service::service_map::InstallProgressHandles;
use crate::service::uninstall::cleanup;
use crate::util::Never;
use crate::util::actor::concurrent::ConcurrentActor;
use crate::util::future::NonDetachingJoinHandle;
use crate::util::io::{AsyncReadStream, AtomicFile, TermSize, delete_file};
use crate::util::net::WebSocketExt;
use crate::util::serde::Pem;
use crate::util::sync::SyncMutex;
use crate::volume::data_dir;
use crate::{CAP_1_KiB, DATA_DIR};
use crate::{ActionId, CAP_1_KiB, DATA_DIR, HostId, ImageId, PackageId};
pub mod action;
pub mod cli;

View File

@@ -5,11 +5,8 @@ use std::time::Duration;
use futures::Future;
use futures::future::ready;
use crate::util::future::NonDetachingJoinHandle;
use imbl::{Vector, vector};
use imbl_value::InternedString;
use crate::service::ProcedureName;
use crate::{ImageId, VolumeId};
use rpc_toolkit::{Empty, Server, ShutdownHandle};
use serde::de::DeserializeOwned;
use tokio::process::Command;
@@ -34,12 +31,13 @@ use crate::service::effects::handler;
use crate::service::rpc::{
CallbackHandle, CallbackId, CallbackParams, ExitParams, InitKind, InitParams,
};
use crate::service::{Service, rpc};
use crate::service::{ProcedureName, Service, rpc};
use crate::util::Invoke;
use crate::util::future::NonDetachingJoinHandle;
use crate::util::io::create_file;
use crate::util::rpc_client::UnixRpcClient;
use crate::volume::data_dir;
use crate::{ARCH, DATA_DIR, PACKAGE_DATA};
use crate::{ARCH, DATA_DIR, ImageId, PACKAGE_DATA, VolumeId};
const RPC_CONNECT_TIMEOUT: Duration = Duration::from_secs(30);

View File

@@ -7,16 +7,15 @@ use clap::builder::ValueParserFactory;
use exver::{ExtendedVersion, VersionRange};
use imbl::Vector;
use imbl_value::{InternedString, Value};
use crate::service::ProcedureName;
use crate::util::FromStrParser;
use rpc_toolkit::Empty;
use rpc_toolkit::yajrc::RpcMethod;
use ts_rs::TS;
use crate::prelude::*;
use crate::rpc_continuations::Guid;
use crate::service::ProcedureName;
use crate::service::persistent_container::PersistentContainer;
use crate::util::Never;
use crate::util::{FromStrParser, Never};
#[derive(Clone, serde::Deserialize, serde::Serialize, TS)]
#[serde(rename_all = "kebab-case")]

View File

@@ -132,9 +132,7 @@ async fn service_actor_loop<'a>(
.filter(|task| task.kind == TransitionKind::BackingUp);
*transition = task.or_else(|| Some(seed.backup()));
}
_ => {
*transition = None;
}
_ => (),
};
Ok(())
}

View File

@@ -8,9 +8,7 @@ use exver::VersionRange;
use futures::future::{BoxFuture, Fuse};
use futures::stream::FuturesUnordered;
use futures::{Future, FutureExt, StreamExt, TryFutureExt};
use crate::util::future::NonDetachingJoinHandle;
use imbl::OrdMap;
use crate::error::ErrorData;
use tokio::sync::{OwnedRwLockReadGuard, OwnedRwLockWriteGuard, RwLock, oneshot};
use tracing::instrument;
use url::Url;
@@ -21,6 +19,7 @@ use crate::db::model::package::{
InstallingInfo, InstallingState, PackageDataEntry, PackageState, UpdatingState,
};
use crate::disk::mount::guard::GenericMountGuard;
use crate::error::ErrorData;
use crate::install::PKG_ARCHIVE_DIR;
use crate::notifications::{NotificationLevel, notify};
use crate::prelude::*;
@@ -32,6 +31,7 @@ use crate::service::rpc::{ExitParams, InitKind};
use crate::service::{LoadDisposition, Service, ServiceRef};
use crate::sign::commitment::merkle_archive::MerkleArchiveCommitment;
use crate::status::{DesiredStatus, StatusInfo};
use crate::util::future::NonDetachingJoinHandle;
use crate::util::serde::{Base32, Pem};
use crate::util::sync::SyncMutex;
@@ -115,7 +115,18 @@ impl ServiceMap {
shutdown_err = service.shutdown(None).await;
}
match Service::load(ctx, id, disposition).await {
Ok(s) => *service = s.into(),
Ok(s) => {
ctx.db
.mutate(|db| {
if let Some(pde) = db.as_public_mut().as_package_data_mut().as_idx_mut(id) {
pde.as_status_info_mut().as_error_mut().ser(&None)?;
}
Ok(())
})
.await
.result?;
*service = s.into();
}
Err(e) => {
tracing::error!("Error loading service: {e}");
tracing::debug!("{e:?}");

View File

@@ -2,7 +2,6 @@ use std::path::PathBuf;
use futures::future::BoxFuture;
use futures::{FutureExt, TryFutureExt};
use crate::service::ProcedureName;
use rpc_toolkit::yajrc::RpcError;
use crate::disk::mount::filesystem::ReadWrite;
@@ -11,7 +10,7 @@ use crate::rpc_continuations::Guid;
use crate::service::action::GetActionInput;
use crate::service::start_stop::StartStop;
use crate::service::transition::{Transition, TransitionKind};
use crate::service::{ServiceActor, ServiceActorSeed};
use crate::service::{ProcedureName, ServiceActor, ServiceActorSeed};
use crate::status::DesiredStatus;
use crate::util::actor::background::BackgroundJobQueue;
use crate::util::actor::{ConflictBuilder, Handler};

View File

@@ -1,12 +1,10 @@
use std::path::Path;
use crate::PackageId;
use crate::context::RpcContext;
use crate::db::model::package::{InstalledState, InstallingInfo, InstallingState, PackageState};
use crate::prelude::*;
use crate::volume::PKG_VOLUME_DIR;
use crate::{DATA_DIR, PACKAGE_DATA};
use crate::{DATA_DIR, PACKAGE_DATA, PackageId};
pub async fn cleanup(ctx: &RpcContext, id: &PackageId, soft: bool) -> Result<(), Error> {
Ok(

View File

@@ -4,7 +4,6 @@ use std::str::FromStr;
use ::ed25519::pkcs8::BitStringRef;
use clap::builder::ValueParserFactory;
use der::referenced::OwnedToRef;
use crate::util::FromStrParser;
use pkcs8::der::AnyRef;
use pkcs8::{PrivateKeyInfo, SubjectPublicKeyInfo};
use serde::{Deserialize, Serialize};
@@ -14,6 +13,7 @@ use ts_rs::TS;
use crate::prelude::*;
use crate::sign::commitment::Digestable;
use crate::sign::ed25519::Ed25519;
use crate::util::FromStrParser;
use crate::util::serde::{deserialize_from_str, serialize_display};
pub mod commitment;

View File

@@ -4,7 +4,6 @@ use std::path::Path;
use clap::Parser;
use clap::builder::ValueParserFactory;
use imbl_value::InternedString;
use crate::util::FromStrParser;
use rpc_toolkit::{Context, Empty, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use tokio::fs::OpenOptions;
@@ -15,9 +14,9 @@ use ts_rs::TS;
use crate::context::{CliContext, RpcContext};
use crate::hostname::Hostname;
use crate::prelude::*;
use crate::util::Invoke;
use crate::util::io::create_file;
use crate::util::serde::{HandlerExtSerde, Pem, WithIoFormat, display_serializable};
use crate::util::{FromStrParser, Invoke};
pub const SSH_DIR: &str = "/home/start9/.ssh";

View File

@@ -1,11 +1,12 @@
use std::str::FromStr;
use clap::builder::ValueParserFactory;
use crate::util::FromStrParser;
pub use crate::HealthCheckId;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
pub use crate::HealthCheckId;
use crate::util::FromStrParser;
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, TS)]
#[serde(rename_all = "camelCase")]
pub struct NamedHealthCheckResult {

View File

@@ -1,11 +1,11 @@
use std::collections::BTreeMap;
use chrono::{DateTime, Utc};
use crate::error::ErrorData;
use crate::HealthCheckId;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::HealthCheckId;
use crate::error::ErrorData;
use crate::prelude::*;
use crate::service::start_stop::StartStop;
use crate::status::health_check::NamedHealthCheckResult;

View File

@@ -7,9 +7,11 @@ use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_f
use serde::{Deserialize, Serialize};
use crate::context::CliContext;
use crate::db::model::public::NetworkInterfaceType;
use crate::net::forward::add_iptables_rule;
use crate::prelude::*;
use crate::tunnel::context::TunnelContext;
use crate::tunnel::wg::{WgConfig, WgSubnetClients, WgSubnetConfig};
use crate::tunnel::wg::{WIREGUARD_INTERFACE_NAME, WgConfig, WgSubnetClients, WgSubnetConfig};
use crate::util::serde::{HandlerExtSerde, display_serializable};
pub fn tunnel_api<C: Context>() -> ParentHandler<C> {
@@ -167,7 +169,37 @@ pub async fn add_subnet(
})
.await
.result?;
server.sync().await
server.sync().await?;
for iface in ctx.net_iface.peek(|i| {
i.iter()
.filter(|(_, info)| {
info.ip_info.as_ref().map_or(false, |i| {
i.device_type != Some(NetworkInterfaceType::Loopback)
})
})
.map(|(name, _)| name)
.filter(|id| id.as_str() != WIREGUARD_INTERFACE_NAME)
.cloned()
.collect::<Vec<_>>()
}) {
add_iptables_rule(
true,
false,
&[
"POSTROUTING",
"-s",
&subnet.trunc().to_string(),
"-o",
iface.as_str(),
"-j",
"MASQUERADE",
],
)
.await?;
}
Ok(())
}
pub async fn remove_subnet(
@@ -184,7 +216,37 @@ pub async fn remove_subnet(
.await
.result?;
server.sync().await?;
ctx.gc_forwards(&keep).await
ctx.gc_forwards(&keep).await?;
for iface in ctx.net_iface.peek(|i| {
i.iter()
.filter(|(_, info)| {
info.ip_info.as_ref().map_or(false, |i| {
i.device_type != Some(NetworkInterfaceType::Loopback)
})
})
.map(|(name, _)| name)
.filter(|id| id.as_str() != WIREGUARD_INTERFACE_NAME)
.cloned()
.collect::<Vec<_>>()
}) {
add_iptables_rule(
true,
true,
&[
"POSTROUTING",
"-s",
&subnet.trunc().to_string(),
"-o",
iface.as_str(),
"-j",
"MASQUERADE",
],
)
.await?;
}
Ok(())
}
#[derive(Deserialize, Serialize, Parser)]

View File

@@ -11,23 +11,22 @@ use imbl::OrdMap;
use imbl_value::InternedString;
use include_dir::Dir;
use ipnet::Ipv4Net;
use crate::GatewayId;
use patch_db::PatchDb;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{CallRemote, Context, Empty, ParentHandler};
use serde::{Deserialize, Serialize};
use tokio::process::Command;
use tokio::sync::broadcast::Sender;
use tracing::instrument;
use url::Url;
use crate::GatewayId;
use crate::auth::Sessions;
use crate::context::config::ContextConfig;
use crate::context::{CliContext, RpcContext};
use crate::db::model::public::{NetworkInterfaceInfo, NetworkInterfaceType};
use crate::middleware::auth::{Auth, AuthContext};
use crate::middleware::cors::Cors;
use crate::net::forward::PortForwardController;
use crate::net::forward::{PortForwardController, add_iptables_rule};
use crate::net::static_server::{EMPTY_DIR, UiContext};
use crate::prelude::*;
use crate::rpc_continuations::{OpenAuthedContinuations, RpcContinuations};
@@ -35,7 +34,6 @@ use crate::tunnel::TUNNEL_DEFAULT_LISTEN;
use crate::tunnel::api::tunnel_api;
use crate::tunnel::db::TunnelDatabase;
use crate::tunnel::wg::{WIREGUARD_INTERFACE_NAME, WgSubnetConfig};
use crate::util::Invoke;
use crate::util::collections::OrdMapIterMut;
use crate::util::io::read_file_to_string;
use crate::util::sync::{SyncMutex, Watch};
@@ -134,13 +132,26 @@ impl TunnelContext {
.result?;
let net_iface = Watch::new(net_iface);
let forward = PortForwardController::new();
Command::new("sysctl")
.arg("-w")
.arg("net.ipv4.ip_forward=1")
.invoke(ErrorKind::Network)
add_iptables_rule(
false,
false,
&[
"FORWARD",
"-i",
WIREGUARD_INTERFACE_NAME,
"-m",
"state",
"--state",
"NEW",
"-j",
"ACCEPT",
],
)
.await?;
let peek = db.peek().await;
peek.as_wg().de()?.sync().await?;
for iface in net_iface.peek(|i| {
i.iter()
.filter(|(_, info)| {
@@ -153,37 +164,24 @@ impl TunnelContext {
.cloned()
.collect::<Vec<_>>()
}) {
if Command::new("iptables")
.arg("-t")
.arg("nat")
.arg("-C")
.arg("POSTROUTING")
.arg("-o")
.arg(iface.as_str())
.arg("-j")
.arg("MASQUERADE")
.invoke(ErrorKind::Network)
.await
.is_err()
{
tracing::info!("Adding masquerade rule for interface {}", iface);
Command::new("iptables")
.arg("-t")
.arg("nat")
.arg("-A")
.arg("POSTROUTING")
.arg("-o")
.arg(iface.as_str())
.arg("-j")
.arg("MASQUERADE")
.invoke(ErrorKind::Network)
.await
.log_err();
for subnet in peek.as_wg().as_subnets().keys()? {
add_iptables_rule(
true,
false,
&[
"POSTROUTING",
"-s",
&subnet.trunc().to_string(),
"-o",
iface.as_str(),
"-j",
"MASQUERADE",
],
)
.await?;
}
}
let peek = db.peek().await;
peek.as_wg().de()?.sync().await?;
let mut active_forwards = BTreeMap::new();
for (from, to) in peek.as_port_forwards().de()?.0 {
active_forwards.insert(from, forward.add_forward(from, to).await?);

View File

@@ -8,7 +8,6 @@ use clap::Parser;
use imbl::{HashMap, OrdMap};
use imbl_value::InternedString;
use itertools::Itertools;
use crate::GatewayId;
use patch_db::Dump;
use patch_db::json_ptr::{JsonPointer, ROOT};
use rpc_toolkit::yajrc::RpcError;
@@ -17,6 +16,7 @@ use serde::{Deserialize, Serialize};
use tracing::instrument;
use ts_rs::TS;
use crate::GatewayId;
use crate::auth::Sessions;
use crate::context::CliContext;
use crate::db::model::public::NetworkInterfaceInfo;

View File

@@ -228,10 +228,7 @@ impl std::fmt::Display for ClientConfig {
name = self.client_config.name,
privkey = self.client_config.key.to_padded_string(),
psk = self.client_config.psk.to_padded_string(),
addr = Ipv4Net::new_assert(
self.client_addr,
self.subnet.prefix_len()
),
addr = Ipv4Net::new_assert(self.client_addr, self.subnet.prefix_len()),
subnet = self.subnet.trunc(),
server_pubkey = self.server_pubkey.to_padded_string(),
server_addr = self.server_addr,

View File

@@ -6,7 +6,6 @@ use clap::{ArgAction, Parser};
use color_eyre::eyre::{Result, eyre};
use exver::{Version, VersionRange};
use futures::TryStreamExt;
use crate::util::future::NonDetachingJoinHandle;
use imbl_value::json;
use itertools::Itertools;
use patch_db::json_ptr::JsonPointer;
@@ -36,6 +35,7 @@ use crate::sound::{
CIRCLE_OF_5THS_SHORT, UPDATE_FAILED_1, UPDATE_FAILED_2, UPDATE_FAILED_3, UPDATE_FAILED_4,
};
use crate::util::Invoke;
use crate::util::future::NonDetachingJoinHandle;
use crate::util::io::AtomicFile;
use crate::util::net::WebSocketExt;

View File

@@ -4,13 +4,13 @@ use std::time::Duration;
use futures::future::{BoxFuture, ready};
use futures::{Future, FutureExt, TryFutureExt};
use crate::util::future::NonDetachingJoinHandle;
use tokio::sync::{mpsc, oneshot};
use crate::prelude::*;
use crate::rpc_continuations::Guid;
use crate::util::actor::background::{BackgroundJobQueue, BackgroundJobRunner};
use crate::util::actor::{Actor, ConflictFn, Handler, PendingMessageStrategy, Request};
use crate::util::future::NonDetachingJoinHandle;
#[pin_project::pin_project]
struct ConcurrentRunner<A> {

View File

@@ -2,7 +2,6 @@ use std::time::Duration;
use futures::future::ready;
use futures::{Future, FutureExt, TryFutureExt};
use crate::util::future::NonDetachingJoinHandle;
use tokio::sync::oneshot::error::TryRecvError;
use tokio::sync::{mpsc, oneshot};
@@ -10,6 +9,7 @@ use crate::prelude::*;
use crate::rpc_continuations::Guid;
use crate::util::actor::background::BackgroundJobQueue;
use crate::util::actor::{Actor, Handler, PendingMessageStrategy, Request};
use crate::util::future::NonDetachingJoinHandle;
pub struct SimpleActor<A: Actor> {
shutdown: oneshot::Sender<()>,

View File

@@ -4,11 +4,11 @@ use std::str::FromStr;
use base64::Engine;
use color_eyre::eyre::eyre;
use imbl_value::InternedString;
use reqwest::header::CONTENT_TYPE;
use serde::{Deserialize, Serialize};
use tokio::io::{AsyncRead, AsyncReadExt};
use ts_rs::TS;
use imbl_value::InternedString;
use crate::util::mime::{mime, unmime};
use crate::{Error, ErrorKind, ResultExt};

View File

@@ -16,7 +16,6 @@ use clap::builder::ValueParserFactory;
use futures::future::{BoxFuture, Fuse};
use futures::{FutureExt, Stream, TryStreamExt};
use inotify::{EventMask, EventStream, Inotify, WatchMask};
use crate::util::FromStrParser;
use nix::unistd::{Gid, Uid};
use serde::{Deserialize, Serialize};
use tokio::fs::{File, OpenOptions};
@@ -30,6 +29,7 @@ use tokio::time::{Instant, Sleep};
use ts_rs::TS;
use crate::prelude::*;
use crate::util::FromStrParser;
use crate::util::future::NonDetachingJoinHandle;
use crate::util::sync::SyncMutex;

View File

@@ -1,9 +1,9 @@
use crate::{Error, ResultExt};
use serde::{Deserialize, Serialize};
use tokio::process::Command;
use ts_rs::TS;
use crate::util::Invoke;
use crate::{Error, ResultExt};
const KNOWN_CLASSES: &[&str] = &["processor", "display"];

View File

@@ -35,16 +35,16 @@ use crate::{Error, ErrorKind, ResultExt as _};
pub mod actor;
pub mod clap;
pub mod collections;
pub mod data_url;
pub mod mime;
pub mod cpupower;
pub mod crypto;
pub mod data_url;
pub mod future;
pub mod http_reader;
pub mod io;
pub mod iter;
pub mod logger;
pub mod lshw;
pub mod mime;
pub mod net;
pub mod rpc;
pub mod rpc_client;

View File

@@ -6,7 +6,6 @@ use std::sync::{Arc, Weak};
use futures::future::BoxFuture;
use futures::{FutureExt, TryFutureExt};
use lazy_async_pool::Pool;
use crate::{Error, ErrorKind, ResultExt};
use rpc_toolkit::yajrc::{self, Id, RpcError, RpcMethod, RpcRequest, RpcResponse};
use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
@@ -17,6 +16,7 @@ use tokio::sync::{Mutex, OnceCell, oneshot};
use crate::util::future::NonDetachingJoinHandle;
use crate::util::io::TmpDir;
use crate::{Error, ErrorKind, ResultExt};
type DynWrite = Box<dyn AsyncWrite + Unpin + Send + Sync + 'static>;
type ResponseMap = BTreeMap<Id, oneshot::Sender<Result<Value, RpcError>>>;

View File

@@ -2,7 +2,6 @@ use std::path::Path;
use color_eyre::eyre::eyre;
use futures::StreamExt;
use crate::{Error, ErrorKind};
use tokio::io::{AsyncBufReadExt, AsyncReadExt, BufReader};
use tokio::process::{Child, Command};
use tokio::sync::watch;
@@ -11,6 +10,7 @@ use tokio_stream::wrappers::WatchStream;
use crate::util::future::NonDetachingJoinHandle;
use crate::util::io::ByteReplacementReader;
use crate::util::serde::const_true;
use crate::{Error, ErrorKind};
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]

View File

@@ -8,7 +8,6 @@ use clap::builder::ValueParserFactory;
use clap::{ArgMatches, CommandFactory, FromArgMatches};
use color_eyre::eyre::eyre;
use imbl_value::imbl::OrdMap;
use crate::util::FromStrParser;
use openssl::pkey::{PKey, Private};
use openssl::x509::X509;
use rpc_toolkit::{
@@ -21,7 +20,7 @@ use ts_rs::TS;
use super::IntoDoubleEndedIterator;
use crate::prelude::*;
use crate::util::Apply;
use crate::util::{Apply, FromStrParser};
pub fn const_true() -> bool {
true

Some files were not shown because too many files have changed in this diff Show More