This commit is contained in:
Aiden McClelland
2025-08-20 14:46:15 -06:00
parent d564471825
commit 359146f02c
189 changed files with 1105 additions and 631 deletions

View File

@@ -24,7 +24,14 @@ PATCH_DB_CLIENT_SRC := $(shell git ls-files --recurse-submodules patch-db/client
GZIP_BIN := $(shell which pigz || which gzip)
TAR_BIN := $(shell which gtar || which tar)
COMPILED_TARGETS := core/target/$(ARCH)-unknown-linux-musl/release/startbox core/target/$(ARCH)-unknown-linux-musl/release/containerbox container-runtime/rootfs.$(ARCH).squashfs
ALL_TARGETS := $(STARTD_SRC) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) $(VERSION_FILE) $(COMPILED_TARGETS) cargo-deps/$(ARCH)-unknown-linux-musl/release/startos-backup-fs $(shell if [ "$(PLATFORM)" = "raspberrypi" ]; then echo cargo-deps/aarch64-unknown-linux-musl/release/pi-beep; fi) $(shell /bin/bash -c 'if [[ "${ENVIRONMENT}" =~ (^|-)unstable($$|-) ]]; then echo cargo-deps/$(ARCH)-unknown-linux-musl/release/tokio-console; fi') $(PLATFORM_FILE)
ALL_TARGETS := $(STARTD_SRC) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) $(VERSION_FILE) $(COMPILED_TARGETS) cargo-deps/$(ARCH)-unknown-linux-musl/release/startos-backup-fs $(PLATFORM_FILE) \
$(shell if [ "$(PLATFORM)" = "raspberrypi" ]; then \
echo cargo-deps/aarch64-unknown-linux-musl/release/pi-beep; \
fi) \
$(shell /bin/bash -c 'if [[ "${ENVIRONMENT}" =~ (^|-)unstable($$|-) ]]; then \
echo cargo-deps/$(ARCH)-unknown-linux-musl/release/tokio-console; \
echo cargo-deps/$(ARCH)-unknown-linux-musl/release/flamegraph; \
fi')
REBUILD_TYPES = 1
ifeq ($(REMOTE),)
@@ -130,7 +137,10 @@ install: $(ALL_TARGETS)
$(call ln,/usr/bin/startbox,$(DESTDIR)/usr/bin/startd)
$(call ln,/usr/bin/startbox,$(DESTDIR)/usr/bin/start-cli)
if [ "$(PLATFORM)" = "raspberrypi" ]; then $(call cp,cargo-deps/aarch64-unknown-linux-musl/release/pi-beep,$(DESTDIR)/usr/bin/pi-beep); fi
if /bin/bash -c '[[ "${ENVIRONMENT}" =~ (^|-)unstable($$|-) ]]'; then $(call cp,cargo-deps/$(ARCH)-unknown-linux-musl/release/tokio-console,$(DESTDIR)/usr/bin/tokio-console); fi
if /bin/bash -c '[[ "${ENVIRONMENT}" =~ (^|-)unstable($$|-) ]]'; then \
$(call cp,cargo-deps/$(ARCH)-unknown-linux-musl/release/tokio-console,$(DESTDIR)/usr/bin/tokio-console); \
$(call cp,cargo-deps/$(ARCH)-unknown-linux-musl/release/flamegraph,$(DESTDIR)/usr/bin/flamegraph); \
fi
$(call cp,cargo-deps/$(ARCH)-unknown-linux-musl/release/startos-backup-fs,$(DESTDIR)/usr/bin/startos-backup-fs)
$(call ln,/usr/bin/startos-backup-fs,$(DESTDIR)/usr/sbin/mount.backup-fs)
@@ -325,3 +335,6 @@ cargo-deps/$(ARCH)-unknown-linux-musl/release/tokio-console:
cargo-deps/$(ARCH)-unknown-linux-musl/release/startos-backup-fs:
ARCH=$(ARCH) PREINSTALL="apk add fuse3 fuse3-dev fuse3-static musl-dev pkgconfig" ./build-cargo-dep.sh --git https://github.com/Start9Labs/start-fs.git startos-backup-fs
cargo-deps/$(ARCH)-unknown-linux-musl/release/flamegraph:
ARCH=$(ARCH) PREINSTALL="apk add musl-dev pkgconfig" ./build-cargo-dep.sh flamegraph

View File

@@ -8,8 +8,8 @@ IFS="-" read -ra FEATURES <<< "$ENVIRONMENT"
feature_file_checker='
/^#/ { next }
/^\+ [a-z0-9]+$/ { next }
/^- [a-z0-9]+$/ { next }
/^\+ [a-z0-9-]+$/ { next }
/^- [a-z0-9-]+$/ { next }
{ exit 1 }
'

View File

@@ -1,2 +1,3 @@
+ gdb
+ heaptrack
+ heaptrack
+ linux-perf

3
core/Cargo.lock generated
View File

@@ -3909,8 +3909,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3"
dependencies = [
"bitflags 2.9.2",
"futures-core",
"inotify-sys",
"libc",
"tokio",
]
[[package]]
@@ -7344,6 +7346,7 @@ dependencies = [
"include_dir",
"indexmap 2.10.0",
"indicatif",
"inotify",
"integer-encoding",
"ipnet",
"isocountry",

View File

@@ -63,6 +63,7 @@ arti-client = { version = "0.33", features = [
"rustls",
"static",
"tokio",
"ephemeral-keystore",
], default-features = false }
aes = { version = "0.7.5", features = ["ctr"] }
async-acme = { version = "0.6.0", git = "https://github.com/dr-bonez/async-acme.git", features = [
@@ -139,6 +140,7 @@ imbl-value = { version = "0.4.3", features = ["ts-rs"] }
include_dir = { version = "0.7.3", features = ["metadata"] }
indexmap = { version = "2.0.2", features = ["serde"] }
indicatif = { version = "0.17.7", features = ["tokio"] }
inotify = "0.11.0"
integer-encoding = { version = "4.0.0", features = ["tokio_async"] }
ipnet = { version = "2.8.0", features = ["serde"] }
isocountry = "0.3.2"

View File

@@ -5,7 +5,7 @@ use openssl::pkey::{PKey, Private};
use openssl::x509::X509;
use crate::db::model::DatabaseModel;
use crate::hostname::{generate_hostname, generate_id, Hostname};
use crate::hostname::{Hostname, generate_hostname, generate_id};
use crate::net::ssl::{generate_key, make_root_cert};
use crate::net::tor::TorSecretKey;
use crate::prelude::*;

View File

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

View File

@@ -3,11 +3,11 @@ use std::collections::BTreeMap;
use chrono::{DateTime, Utc};
use clap::Parser;
use color_eyre::eyre::eyre;
use imbl_value::{json, InternedString};
use imbl_value::{InternedString, json};
use itertools::Itertools;
use josekit::jwk::Jwk;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{from_fn_async, CallRemote, Context, HandlerArgs, HandlerExt, ParentHandler};
use rpc_toolkit::{CallRemote, Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use tokio::io::AsyncWriteExt;
use tracing::instrument;
@@ -20,8 +20,8 @@ use crate::middleware::auth::{
use crate::prelude::*;
use crate::util::crypto::EncryptedWire;
use crate::util::io::create_file_mod;
use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat};
use crate::{ensure_code, Error, ResultExt};
use crate::util::serde::{HandlerExtSerde, WithIoFormat, display_serializable};
use crate::{Error, ResultExt, ensure_code};
#[derive(Debug, Clone, Default, Deserialize, Serialize, TS)]
pub struct Sessions(pub BTreeMap<InternedString, Session>);

View File

@@ -13,8 +13,8 @@ use tokio::io::AsyncWriteExt;
use tracing::instrument;
use ts_rs::TS;
use super::target::{BackupTargetId, PackageBackupInfo};
use super::PackageBackupReport;
use super::target::{BackupTargetId, PackageBackupInfo};
use crate::backup::os::OsBackup;
use crate::backup::{BackupReport, ServerBackupReport};
use crate::context::RpcContext;
@@ -24,7 +24,7 @@ use crate::disk::mount::backup::BackupMountGuard;
use crate::disk::mount::filesystem::ReadWrite;
use crate::disk::mount::guard::{GenericMountGuard, TmpMountGuard};
use crate::middleware::auth::AuthContext;
use crate::notifications::{notify, NotificationLevel};
use crate::notifications::{NotificationLevel, notify};
use crate::prelude::*;
use crate::util::io::dir_copy;
use crate::util::serde::IoFormat;

View File

@@ -3,7 +3,7 @@ use std::collections::BTreeMap;
use chrono::{DateTime, Utc};
use models::{HostId, PackageId};
use reqwest::Url;
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use crate::context::CliContext;

View File

@@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
use ssh_key::private::Ed25519Keypair;
use crate::account::AccountInfo;
use crate::hostname::{generate_hostname, generate_id, Hostname};
use crate::hostname::{Hostname, generate_hostname, generate_id};
use crate::net::tor::TorSecretKey;
use crate::prelude::*;
use crate::util::crypto::ed25519_expand_key;
@@ -36,7 +36,7 @@ impl<'de> Deserialize<'de> for OsBackup {
v => {
return Err(serde::de::Error::custom(&format!(
"Unknown backup version {v}"
)))
)));
}
})
}

View File

@@ -2,7 +2,7 @@ use std::collections::BTreeMap;
use std::sync::Arc;
use clap::Parser;
use futures::{stream, StreamExt};
use futures::{StreamExt, stream};
use models::PackageId;
use patch_db::json_ptr::ROOT;
use serde::{Deserialize, Serialize};
@@ -11,6 +11,7 @@ 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};
@@ -26,7 +27,6 @@ use crate::service::service_map::DownloadInstallFuture;
use crate::setup::SetupExecuteProgress;
use crate::system::sync_kiosk;
use crate::util::serde::IoFormat;
use crate::PLATFORM;
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]

View File

@@ -4,17 +4,17 @@ use std::path::{Path, PathBuf};
use clap::Parser;
use color_eyre::eyre::eyre;
use imbl_value::InternedString;
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use super::{BackupTarget, BackupTargetId};
use crate::context::{CliContext, RpcContext};
use crate::db::model::DatabaseModel;
use crate::disk::mount::filesystem::cifs::Cifs;
use crate::disk::mount::filesystem::ReadOnly;
use crate::disk::mount::filesystem::cifs::Cifs;
use crate::disk::mount::guard::{GenericMountGuard, TmpMountGuard};
use crate::disk::util::{recovery_info, StartOsRecoveryInfo};
use crate::disk::util::{StartOsRecoveryInfo, recovery_info};
use crate::prelude::*;
use crate::util::serde::KeyVal;

View File

@@ -2,15 +2,15 @@ use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use chrono::{DateTime, Utc};
use clap::builder::ValueParserFactory;
use clap::Parser;
use clap::builder::ValueParserFactory;
use color_eyre::eyre::eyre;
use digest::generic_array::GenericArray;
use digest::OutputSizeUser;
use digest::generic_array::GenericArray;
use exver::Version;
use imbl_value::InternedString;
use models::{FromStrParser, PackageId};
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use sha2::Sha256;
use tokio::sync::Mutex;
@@ -27,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::serde::{
deserialize_from_str, display_serializable, serialize_display, HandlerExtSerde, WithIoFormat,
};
use crate::util::VersionString;
use crate::util::serde::{
HandlerExtSerde, WithIoFormat, deserialize_from_str, display_serializable, serialize_display,
};
pub mod cifs;

View File

@@ -6,8 +6,8 @@ use rpc_toolkit::CliApp;
use tokio::signal::unix::signal;
use tracing::instrument;
use crate::context::config::ClientConfig;
use crate::context::CliContext;
use crate::context::config::ClientConfig;
use crate::net::web_server::{Acceptor, WebServer};
use crate::prelude::*;
use crate::registry::context::{RegistryConfig, RegistryContext};

View File

@@ -3,8 +3,8 @@ use std::ffi::OsString;
use rpc_toolkit::CliApp;
use serde_json::Value;
use crate::context::config::ClientConfig;
use crate::context::CliContext;
use crate::context::config::ClientConfig;
use crate::util::logger::LOGGER;
use crate::version::{Current, VersionT};

View File

@@ -6,9 +6,9 @@ use tracing::instrument;
use crate::context::config::ServerConfig;
use crate::context::rpc::InitRpcContextPhases;
use crate::context::{DiagnosticContext, InitContext, InstallContext, RpcContext, SetupContext};
use crate::disk::REPAIR_DISK_PATH;
use crate::disk::fsck::RepairStrategy;
use crate::disk::main::DEFAULT_PASSWORD;
use crate::disk::REPAIR_DISK_PATH;
use crate::firmware::{check_for_firmware_update, update_firmware};
use crate::init::{InitPhases, STANDBY_MODE_PATH};
use crate::net::web_server::{UpgradableListener, WebServer};
@@ -137,7 +137,7 @@ async fn setup_or_init(
return Err(Error::new(
eyre!("Setup mode exited before setup completed"),
ErrorKind::Unknown,
))
));
}
}))
} else {

View File

@@ -6,8 +6,8 @@ use rpc_toolkit::CliApp;
use tokio::signal::unix::signal;
use tracing::instrument;
use crate::context::config::ClientConfig;
use crate::context::CliContext;
use crate::context::config::ClientConfig;
use crate::net::web_server::{Acceptor, WebServer};
use crate::prelude::*;
use crate::tunnel::context::{TunnelConfig, TunnelContext};

View File

@@ -20,9 +20,9 @@ use tokio_tungstenite::{MaybeTlsStream, WebSocketStream};
use tracing::instrument;
use super::setup::CURRENT_SECRET;
use crate::context::config::{local_config_path, ClientConfig};
use crate::context::config::{ClientConfig, local_config_path};
use crate::context::{DiagnosticContext, InitContext, InstallContext, RpcContext, SetupContext};
use crate::developer::{default_developer_key_path, OS_DEVELOPER_KEY_PATH};
use crate::developer::{OS_DEVELOPER_KEY_PATH, default_developer_key_path};
use crate::middleware::auth::AuthContext;
use crate::prelude::*;
use crate::rpc_continuations::Guid;
@@ -190,7 +190,7 @@ impl CliContext {
eyre!("Cannot parse scheme from base URL"),
crate::ErrorKind::ParseUrl,
)
.into())
.into());
}
};
url.set_scheme(ws_scheme)

View File

@@ -8,11 +8,11 @@ use reqwest::Url;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use crate::MAIN_DATA;
use crate::disk::OsPartitionInfo;
use crate::prelude::*;
use crate::util::serde::IoFormat;
use crate::version::VersionT;
use crate::MAIN_DATA;
pub const DEVICE_CONFIG_PATH: &str = "/media/startos/config/config.yaml"; // "/media/startos/config/config.yaml";
pub const CONFIG_PATH: &str = "/etc/startos/config.yaml";

View File

@@ -1,15 +1,15 @@
use std::ops::Deref;
use std::sync::Arc;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::Context;
use rpc_toolkit::yajrc::RpcError;
use tokio::sync::broadcast::Sender;
use tracing::instrument;
use crate::Error;
use crate::context::config::ServerConfig;
use crate::rpc_continuations::RpcContinuations;
use crate::shutdown::Shutdown;
use crate::Error;
pub struct DiagnosticContextSeed {
pub shutdown: Sender<Shutdown>,

View File

@@ -6,10 +6,10 @@ use tokio::sync::broadcast::Sender;
use tokio::sync::watch;
use tracing::instrument;
use crate::Error;
use crate::context::config::ServerConfig;
use crate::progress::FullProgressTracker;
use crate::rpc_continuations::RpcContinuations;
use crate::Error;
pub struct InitContextSeed {
pub config: ServerConfig,

View File

@@ -5,9 +5,9 @@ use rpc_toolkit::Context;
use tokio::sync::broadcast::Sender;
use tracing::instrument;
use crate::Error;
use crate::net::utils::find_eth_iface;
use crate::rpc_continuations::RpcContinuations;
use crate::Error;
pub struct InstallContextSeed {
pub ethernet_interface: String,

View File

@@ -4,8 +4,8 @@ use std::future::Future;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::Duration;
use chrono::{TimeDelta, Utc};
@@ -18,18 +18,19 @@ use models::{ActionId, PackageId};
use reqwest::{Client, Proxy};
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{CallRemote, Context, Empty};
use tokio::sync::{broadcast, oneshot, watch, Mutex, RwLock};
use tokio::sync::{Mutex, RwLock, broadcast, oneshot, watch};
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;
use crate::db::model::package::TaskSeverity;
use crate::db::model::Database;
use crate::db::model::package::TaskSeverity;
use crate::disk::OsPartitionInfo;
use crate::init::{check_time_is_synchronized, InitResult};
use crate::init::{InitResult, check_time_is_synchronized};
use crate::install::PKG_ARCHIVE_DIR;
use crate::lxc::{ContainerId, LxcContainer, LxcManager};
use crate::net::net_controller::{NetController, NetService};
@@ -39,14 +40,13 @@ use crate::net::wifi::WpaCli;
use crate::prelude::*;
use crate::progress::{FullProgressTracker, PhaseProgressTrackerHandle};
use crate::rpc_continuations::{Guid, OpenAuthedContinuations, RpcContinuations};
use crate::service::ServiceMap;
use crate::service::action::update_tasks;
use crate::service::effects::callbacks::ServiceCallbacks;
use crate::service::ServiceMap;
use crate::shutdown::Shutdown;
use crate::util::io::delete_file;
use crate::util::lshw::LshwDevice;
use crate::util::sync::{SyncMutex, Watch};
use crate::DATA_DIR;
pub struct RpcContextSeed {
is_closed: AtomicBool,

View File

@@ -10,14 +10,15 @@ use josekit::jwk::Jwk;
use patch_db::PatchDb;
use rpc_toolkit::Context;
use serde::{Deserialize, Serialize};
use tokio::sync::broadcast::Sender;
use tokio::sync::OnceCell;
use tokio::sync::broadcast::Sender;
use tracing::instrument;
use ts_rs::TS;
use crate::MAIN_DATA;
use crate::account::AccountInfo;
use crate::context::config::ServerConfig;
use crate::context::RpcContext;
use crate::context::config::ServerConfig;
use crate::disk::OsPartitionInfo;
use crate::hostname::Hostname;
use crate::net::web_server::{UpgradableListener, WebServer, WebServerAcceptorSetter};
@@ -27,7 +28,6 @@ use crate::rpc_continuations::{Guid, RpcContinuation, RpcContinuations};
use crate::setup::SetupProgress;
use crate::shutdown::Shutdown;
use crate::util::net::WebSocketExt;
use crate::MAIN_DATA;
lazy_static::lazy_static! {
pub static ref CURRENT_SECRET: Jwk = Jwk::generate_ec_key(josekit::jwk::alg::ec::EcCurve::P256).unwrap_or_else(|e| {

View File

@@ -5,10 +5,10 @@ use serde::{Deserialize, Serialize};
use tracing::instrument;
use ts_rs::TS;
use crate::Error;
use crate::context::RpcContext;
use crate::prelude::*;
use crate::rpc_continuations::Guid;
use crate::Error;
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]

View File

@@ -12,7 +12,7 @@ use itertools::Itertools;
use patch_db::json_ptr::{JsonPointer, ROOT};
use patch_db::{DiffPatch, Dump, Revision};
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{from_fn_async, Context, HandlerArgs, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use tokio::sync::mpsc::{self, UnboundedReceiver};
use tokio::sync::watch;
@@ -23,7 +23,7 @@ use crate::context::{CliContext, RpcContext};
use crate::prelude::*;
use crate::rpc_continuations::{Guid, RpcContinuation};
use crate::util::net::WebSocketExt;
use crate::util::serde::{apply_expr, HandlerExtSerde};
use crate::util::serde::{HandlerExtSerde, apply_expr};
lazy_static::lazy_static! {
static ref PUBLIC: JsonPointer = "/public".parse().unwrap();

View File

@@ -5,8 +5,8 @@ use chrono::{DateTime, Utc};
use exver::VersionRange;
use imbl_value::InternedString;
use models::{ActionId, DataUrl, HealthCheckId, HostId, PackageId, ReplayId, ServiceInterfaceId};
use patch_db::json_ptr::JsonPointer;
use patch_db::HasModel;
use patch_db::json_ptr::JsonPointer;
use reqwest::Url;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -17,7 +17,7 @@ use crate::prelude::*;
use crate::progress::FullProgress;
use crate::s9pk::manifest::Manifest;
use crate::status::MainStatus;
use crate::util::serde::{is_partial_of, Pem};
use crate::util::serde::{Pem, is_partial_of};
#[derive(Debug, Default, Deserialize, Serialize, TS)]
#[ts(export)]
@@ -268,7 +268,7 @@ impl Model<PackageState> {
return Err(Error::new(
eyre!("could not determine package state to get manifest"),
ErrorKind::Database,
))
));
}
})
}

View File

@@ -1,5 +1,5 @@
use std::collections::{BTreeMap, BTreeSet};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
use chrono::{DateTime, Utc};
use exver::{Version, VersionRange};
@@ -19,8 +19,8 @@ use crate::account::AccountInfo;
use crate::db::model::package::AllPackageData;
use crate::net::acme::AcmeProvider;
use crate::net::forward::START9_BRIDGE_IFACE;
use crate::net::host::binding::{AddSslOptions, BindInfo, BindOptions, NetInfo};
use crate::net::host::Host;
use crate::net::host::binding::{AddSslOptions, BindInfo, BindOptions, NetInfo};
use crate::net::utils::ipv6_is_local;
use crate::net::vhost::AlpnInfo;
use crate::prelude::*;
@@ -202,8 +202,8 @@ pub struct NetworkInfo {
#[model = "Model<Self>"]
#[ts(export)]
pub struct DnsSettings {
pub dhcp_servers: Vec<IpAddr>,
pub static_servers: Option<Vec<IpAddr>>,
pub dhcp_servers: Vec<SocketAddr>,
pub static_servers: Option<Vec<SocketAddr>>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize, HasModel, TS)]

View File

@@ -5,9 +5,9 @@ use models::PackageId;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::Error;
use crate::prelude::*;
use crate::util::PathOrUrl;
use crate::Error;
#[derive(Clone, Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[model = "Model<Self>"]

View File

@@ -1,13 +1,13 @@
use std::path::{Path, PathBuf};
use ed25519::pkcs8::EncodePrivateKey;
use ed25519::PublicKeyBytes;
use ed25519::pkcs8::EncodePrivateKey;
use ed25519_dalek::{SigningKey, VerifyingKey};
use tokio::io::AsyncWriteExt;
use tracing::instrument;
use crate::context::config::local_config_path;
use crate::context::CliContext;
use crate::context::config::local_config_path;
use crate::prelude::*;
use crate::util::io::create_file_mod;
use crate::util::serde::Pem;

View File

@@ -2,7 +2,7 @@ use std::sync::Arc;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{
from_fn, from_fn_async, CallRemoteHandler, Context, Empty, HandlerExt, ParentHandler,
CallRemoteHandler, Context, Empty, HandlerExt, ParentHandler, from_fn, from_fn_async,
};
use crate::context::{CliContext, DiagnosticContext, RpcContext};

View File

@@ -4,9 +4,9 @@ use std::path::Path;
use tokio::process::Command;
use tracing::instrument;
use crate::Error;
use crate::disk::fsck::RequiresReboot;
use crate::util::Invoke;
use crate::Error;
#[instrument(skip_all)]
pub async fn btrfs_check_readonly(logicalname: impl AsRef<Path>) -> Result<RequiresReboot, Error> {

View File

@@ -2,13 +2,13 @@ use std::ffi::OsStr;
use std::path::Path;
use color_eyre::eyre::eyre;
use futures::future::BoxFuture;
use futures::FutureExt;
use futures::future::BoxFuture;
use tokio::process::Command;
use tracing::instrument;
use crate::disk::fsck::RequiresReboot;
use crate::Error;
use crate::disk::fsck::RequiresReboot;
#[instrument(skip_all)]
pub async fn e2fsck_preen(

View File

@@ -3,10 +3,10 @@ use std::path::Path;
use color_eyre::eyre::eyre;
use tokio::process::Command;
use crate::Error;
use crate::disk::fsck::btrfs::{btrfs_check_readonly, btrfs_check_repair};
use crate::disk::fsck::ext4::{e2fsck_aggressive, e2fsck_preen};
use crate::util::Invoke;
use crate::Error;
pub mod btrfs;
pub mod ext4;
@@ -45,7 +45,7 @@ impl RepairStrategy {
return Err(Error::new(
eyre!("Unknown filesystem {fs}"),
crate::ErrorKind::DiskManagement,
))
));
}
}
}

View File

@@ -2,13 +2,13 @@ use std::path::{Path, PathBuf};
use itertools::Itertools;
use lazy_format::lazy_format;
use rpc_toolkit::{from_fn_async, CallRemoteHandler, Context, Empty, HandlerExt, ParentHandler};
use rpc_toolkit::{CallRemoteHandler, Context, Empty, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use crate::Error;
use crate::context::{CliContext, RpcContext};
use crate::disk::util::DiskInfo;
use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat};
use crate::Error;
use crate::util::serde::{HandlerExtSerde, WithIoFormat, display_serializable};
pub mod fsck;
pub mod main;

View File

@@ -10,8 +10,8 @@ use tracing::instrument;
use super::guard::{GenericMountGuard, TmpMountGuard};
use crate::auth::check_password;
use crate::backup::target::BackupInfo;
use crate::disk::mount::filesystem::backupfs::BackupFS;
use crate::disk::mount::filesystem::ReadWrite;
use crate::disk::mount::filesystem::backupfs::BackupFS;
use crate::disk::mount::guard::SubPath;
use crate::disk::util::StartOsRecoveryInfo;
use crate::util::crypto::{decrypt_slice, encrypt_slice};

View File

@@ -11,9 +11,9 @@ use tracing::instrument;
use ts_rs::TS;
use super::{FileSystem, MountType, ReadOnly};
use crate::Error;
use crate::disk::mount::guard::{GenericMountGuard, TmpMountGuard};
use crate::util::Invoke;
use crate::Error;
async fn resolve_hostname(hostname: &str) -> Result<IpAddr, Error> {
if let Ok(addr) = hostname.parse() {

View File

@@ -7,8 +7,8 @@ use serde::{Deserialize, Serialize};
use sha2::Sha256;
use super::{FileSystem, MountType};
use crate::util::Invoke;
use crate::Error;
use crate::util::Invoke;
pub async fn mount_httpdirfs(url: &Url, mountpoint: impl AsRef<Path>) -> Result<(), Error> {
tokio::fs::create_dir_all(mountpoint.as_ref()).await?;

View File

@@ -2,8 +2,8 @@ use std::ffi::OsStr;
use std::fmt::{Display, Write};
use std::path::Path;
use digest::generic_array::GenericArray;
use digest::OutputSizeUser;
use digest::generic_array::GenericArray;
use futures::Future;
use sha2::Sha256;
use tokio::process::Command;
@@ -106,6 +106,7 @@ pub trait FileSystem: Send + Sync {
}
fn source_hash(
&self,
) -> impl Future<Output = Result<GenericArray<u8, <Sha256 as OutputSizeUser>::OutputSize>, Error>>
+ Send;
) -> impl Future<
Output = Result<GenericArray<u8, <Sha256 as OutputSizeUser>::OutputSize>, Error>,
> + Send;
}

View File

@@ -21,11 +21,8 @@ impl<P0: AsRef<Path>, P1: AsRef<Path>, P2: AsRef<Path>> OverlayFs<P0, P1, P2> {
Self { lower, upper, work }
}
}
impl<
P0: AsRef<Path> + Send + Sync,
P1: AsRef<Path> + Send + Sync,
P2: AsRef<Path> + Send + Sync,
> FileSystem for OverlayFs<P0, P1, P2>
impl<P0: AsRef<Path> + Send + Sync, P1: AsRef<Path> + Send + Sync, P2: AsRef<Path> + Send + Sync>
FileSystem for OverlayFs<P0, P1, P2>
{
fn mount_type(&self) -> Option<impl AsRef<str>> {
Some("overlay")

View File

@@ -10,8 +10,8 @@ use tracing::instrument;
use super::filesystem::{FileSystem, MountType, ReadOnly, ReadWrite};
use super::util::unmount;
use crate::util::{Invoke, Never};
use crate::Error;
use crate::util::{Invoke, Never};
pub const TMP_MOUNTPOINT: &'static str = "/media/startos/tmp";

View File

@@ -2,8 +2,8 @@ use std::path::Path;
use tracing::instrument;
use crate::util::Invoke;
use crate::Error;
use crate::util::Invoke;
pub async fn is_mountpoint(path: impl AsRef<Path>) -> Result<bool, Error> {
let is_mountpoint = tokio::process::Command::new("mountpoint")

View File

@@ -14,14 +14,14 @@ use serde::{Deserialize, Serialize};
use tokio::process::Command;
use tracing::instrument;
use super::mount::filesystem::block_dev::BlockDev;
use super::mount::filesystem::ReadOnly;
use super::mount::filesystem::block_dev::BlockDev;
use super::mount::guard::TmpMountGuard;
use crate::disk::mount::guard::GenericMountGuard;
use crate::disk::OsPartitionInfo;
use crate::disk::mount::guard::GenericMountGuard;
use crate::hostname::Hostname;
use crate::util::serde::IoFormat;
use crate::util::Invoke;
use crate::util::serde::IoFormat;
use crate::{Error, ResultExt as _};
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]

View File

@@ -6,11 +6,11 @@ use serde::{Deserialize, Serialize};
use tokio::io::BufReader;
use tokio::process::Command;
use crate::PLATFORM;
use crate::disk::fsck::RequiresReboot;
use crate::prelude::*;
use crate::util::io::open_file;
use crate::util::Invoke;
use crate::PLATFORM;
use crate::util::io::open_file;
/// Part of the Firmware, look there for more about
#[derive(Debug, Clone, Deserialize, Serialize)]

View File

@@ -1,6 +1,6 @@
use imbl_value::InternedString;
use lazy_format::lazy_format;
use rand::{rng, Rng};
use rand::{Rng, rng};
use tokio::process::Command;
use tracing::instrument;

View File

@@ -8,7 +8,7 @@ use const_format::formatcp;
use futures::{StreamExt, TryStreamExt};
use itertools::Itertools;
use models::ResultExt;
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use tokio::process::Command;
use tracing::instrument;
@@ -17,8 +17,8 @@ use ts_rs::TS;
use crate::account::AccountInfo;
use crate::context::config::ServerConfig;
use crate::context::{CliContext, InitContext, RpcContext};
use crate::db::model::public::ServerStatus;
use crate::db::model::Database;
use crate::db::model::public::ServerStatus;
use crate::developer::OS_DEVELOPER_KEY_PATH;
use crate::hostname::Hostname;
use crate::middleware::auth::AuthContext;
@@ -33,10 +33,10 @@ use crate::rpc_continuations::{Guid, RpcContinuation};
use crate::s9pk::v2::pack::{CONTAINER_DATADIR, CONTAINER_TOOL};
use crate::ssh::SSH_DIR;
use crate::system::{get_mem_info, sync_kiosk};
use crate::util::io::{open_file, IOHook};
use crate::util::io::{IOHook, open_file};
use crate::util::lshw::lshw;
use crate::util::net::WebSocketExt;
use crate::util::{cpupower, Invoke};
use crate::util::{Invoke, cpupower};
use crate::{Error, MAIN_DATA, PACKAGE_DATA};
pub const SYSTEM_REBUILD_PATH: &str = "/media/startos/config/system-rebuild";

View File

@@ -4,17 +4,17 @@ use std::time::Duration;
use axum::extract::ws;
use clap::builder::ValueParserFactory;
use clap::{value_parser, CommandFactory, FromArgMatches, Parser};
use clap::{CommandFactory, FromArgMatches, Parser, value_parser};
use color_eyre::eyre::eyre;
use exver::VersionRange;
use futures::{AsyncWriteExt, StreamExt};
use imbl_value::{json, InternedString};
use imbl_value::{InternedString, json};
use itertools::Itertools;
use models::{FromStrParser, VersionString};
use reqwest::header::{HeaderMap, CONTENT_LENGTH};
use reqwest::Url;
use rpc_toolkit::yajrc::RpcError;
use reqwest::header::{CONTENT_LENGTH, HeaderMap};
use rpc_toolkit::HandlerArgs;
use rpc_toolkit::yajrc::RpcError;
use rustyline_async::ReadlineEvent;
use serde::{Deserialize, Serialize};
use tokio::sync::oneshot;
@@ -31,9 +31,9 @@ use crate::registry::package::get::GetPackageResponse;
use crate::rpc_continuations::{Guid, RpcContinuation};
use crate::s9pk::manifest::PackageId;
use crate::upload::upload;
use crate::util::Never;
use crate::util::io::open_file;
use crate::util::net::WebSocketExt;
use crate::util::Never;
pub const PKG_ARCHIVE_DIR: &str = "package-data/archive";
pub const PKG_PUBLIC_DIR: &str = "package-data/public";
@@ -483,7 +483,9 @@ pub async fn cli_install(
let version = if packages.best.len() == 1 {
packages.best.pop_first().map(|(k, _)| k).unwrap()
} else {
println!("Multiple flavors of {id} found. Please select one of the following versions to install:");
println!(
"Multiple flavors of {id} found. Please select one of the following versions to install:"
);
let version;
loop {
let (mut read, mut output) = rustyline_async::Readline::new("> ".into())

View File

@@ -79,8 +79,8 @@ pub use error::{Error, ErrorKind, ResultExt};
use imbl_value::Value;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{
from_fn, from_fn_async, from_fn_blocking, CallRemoteHandler, Context, Empty, HandlerExt,
ParentHandler,
CallRemoteHandler, Context, Empty, HandlerExt, ParentHandler, from_fn, from_fn_async,
from_fn_blocking,
};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -91,7 +91,7 @@ use crate::context::{
use crate::disk::fsck::RequiresReboot;
use crate::registry::context::{RegistryContext, RegistryUrlParams};
use crate::system::kiosk;
use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat};
use crate::util::serde::{HandlerExtSerde, WithIoFormat, display_serializable};
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]

View File

@@ -15,7 +15,7 @@ use itertools::Itertools;
use models::{FromStrParser, PackageId};
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{
from_fn_async, CallRemote, Context, Empty, HandlerArgs, HandlerExt, HandlerFor, ParentHandler,
CallRemote, Context, Empty, HandlerArgs, HandlerExt, HandlerFor, ParentHandler, from_fn_async,
};
use serde::de::{self, DeserializeOwned};
use serde::{Deserialize, Serialize};
@@ -30,9 +30,9 @@ use crate::error::ResultExt;
use crate::lxc::ContainerId;
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::Invoke;
#[pin_project::pin_project]
pub struct LogStream {

View File

@@ -31,7 +31,7 @@ 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::{new_guid, Invoke};
use crate::util::{Invoke, new_guid};
const LXC_CONTAINER_DIR: &str = "/var/lib/lxc";
const RPC_DIR: &str = "media/startos/rpc"; // must not be absolute path

View File

@@ -13,9 +13,9 @@ use chrono::Utc;
use color_eyre::eyre::eyre;
use digest::Digest;
use helpers::const_true;
use http::header::{COOKIE, USER_AGENT};
use http::HeaderValue;
use imbl_value::{json, InternedString};
use http::header::{COOKIE, USER_AGENT};
use imbl_value::{InternedString, json};
use rand::random;
use rpc_toolkit::yajrc::INTERNAL_ERROR;
use rpc_toolkit::{Middleware, RpcRequest, RpcResponse};
@@ -25,18 +25,18 @@ use tokio::io::AsyncWriteExt;
use tokio::process::Command;
use tokio::sync::Mutex;
use crate::auth::{check_password, write_shadow, Sessions};
use crate::auth::{Sessions, check_password, write_shadow};
use crate::context::RpcContext;
use crate::db::model::Database;
use crate::middleware::signature::{SignatureAuth, SignatureAuthContext};
use crate::prelude::*;
use crate::rpc_continuations::OpenAuthedContinuations;
use crate::sign::AnyVerifyingKey;
use crate::util::Invoke;
use crate::util::io::{create_file_mod, read_file_to_string};
use crate::util::iter::TransposeResultIterExt;
use crate::util::serde::BASE64;
use crate::util::sync::SyncMutex;
use crate::util::Invoke;
pub trait AuthContext: SignatureAuthContext {
const LOCAL_AUTH_COOKIE_PATH: &str;

View File

@@ -1,6 +1,6 @@
use axum::response::Response;
use http::header::InvalidHeaderValue;
use http::HeaderValue;
use http::header::InvalidHeaderValue;
use rpc_toolkit::{Middleware, RpcRequest, RpcResponse};
use serde::Deserialize;

View File

@@ -8,15 +8,15 @@ use axum::extract::Request;
use http::HeaderValue;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{Context, Middleware, RpcRequest, RpcResponse};
use serde::de::DeserializeOwned;
use serde::Deserialize;
use serde::de::DeserializeOwned;
use tokio::sync::Mutex;
use url::Url;
use crate::context::CliContext;
use crate::prelude::*;
use crate::sign::commitment::request::RequestCommitment;
use crate::sign::commitment::Commitment;
use crate::sign::commitment::request::RequestCommitment;
use crate::sign::{AnySignature, AnySigningKey, AnyVerifyingKey, SignatureScheme};
use crate::util::serde::Base64;
@@ -28,7 +28,7 @@ pub trait SignatureAuthContext: Context {
fn sig_context(
&self,
) -> impl Future<Output = impl IntoIterator<Item = Result<impl AsRef<str> + Send, Error>> + Send>
+ Send;
+ Send;
fn check_pubkey(
db: &Model<Self::Database>,
pubkey: Option<&AnyVerifyingKey>,
@@ -223,10 +223,10 @@ pub async fn call_remote(
method: &str,
params: Value,
) -> Result<Value, RpcError> {
use reqwest::header::{ACCEPT, CONTENT_LENGTH, CONTENT_TYPE};
use reqwest::Method;
use rpc_toolkit::yajrc::{GenericRpcMethod, Id, RpcRequest};
use reqwest::header::{ACCEPT, CONTENT_LENGTH, CONTENT_TYPE};
use rpc_toolkit::RpcResponse;
use rpc_toolkit::yajrc::{GenericRpcMethod, Id, RpcRequest};
let rpc_req = RpcRequest {
id: Some(Id::Number(0.into())),

View File

@@ -2,21 +2,21 @@ use std::collections::{BTreeMap, BTreeSet};
use std::str::FromStr;
use async_acme::acme::Identifier;
use clap::builder::ValueParserFactory;
use clap::Parser;
use clap::builder::ValueParserFactory;
use imbl_value::InternedString;
use itertools::Itertools;
use models::{ErrorData, FromStrParser};
use openssl::pkey::{PKey, Private};
use openssl::x509::X509;
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use url::Url;
use crate::context::{CliContext, RpcContext};
use crate::db::model::public::AcmeSettings;
use crate::db::model::Database;
use crate::db::model::public::AcmeSettings;
use crate::prelude::*;
use crate::util::serde::{Pem, Pkcs8Doc};

View File

@@ -1,17 +1,19 @@
use std::borrow::Borrow;
use std::collections::BTreeMap;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
use std::sync::{Arc, Weak};
use std::time::Duration;
use clap::Parser;
use color_eyre::eyre::eyre;
use futures::{FutureExt, TryStreamExt};
use futures::future::BoxFuture;
use futures::{FutureExt, StreamExt, TryStreamExt};
use helpers::NonDetachingJoinHandle;
use hickory_client::client::Client;
use hickory_client::proto::runtime::TokioRuntimeProvider;
use hickory_client::proto::tcp::TcpClientStream;
use hickory_client::proto::udp::UdpClientStream;
use hickory_client::proto::xfer::DnsRequestOptions;
use hickory_client::proto::xfer::{DnsExchangeBackground, DnsRequestOptions};
use hickory_client::proto::DnsHandle;
use hickory_server::authority::MessageResponseBuilder;
use hickory_server::proto::op::{Header, ResponseCode};
@@ -20,7 +22,7 @@ use hickory_server::server::{Request, RequestHandler, ResponseHandler, ResponseI
use hickory_server::ServerFuture;
use imbl::OrdMap;
use imbl_value::InternedString;
use models::{GatewayId, PackageId};
use models::{GatewayId, OptionExt, PackageId};
use rpc_toolkit::{
from_fn_async, from_fn_blocking, Context, HandlerArgs, HandlerExt, ParentHandler,
};
@@ -30,10 +32,12 @@ use tracing::instrument;
use crate::context::RpcContext;
use crate::db::model::public::NetworkInterfaceInfo;
use crate::db::model::Database;
use crate::net::gateway::NetworkInterfaceWatcher;
use crate::prelude::*;
use crate::util::io::file_string_stream;
use crate::util::serde::{display_serializable, HandlerExtSerde};
use crate::util::sync::{SyncRwLock, Watch};
use crate::{Error, ErrorKind, ResultExt};
pub fn dns_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new()
@@ -103,14 +107,35 @@ pub fn query_dns<C: Context>(
#[derive(Deserialize, Serialize, Parser)]
pub struct SetStaticDnsParams {
pub servers: Option<Vec<IpAddr>>,
pub servers: Option<Vec<String>>,
}
pub async fn set_static_dns(
ctx: RpcContext,
SetStaticDnsParams { servers }: SetStaticDnsParams,
) -> Result<(), Error> {
todo!()
ctx.db
.mutate(|db| {
db.as_public_mut()
.as_server_info_mut()
.as_network_mut()
.as_dns_mut()
.as_static_servers_mut()
.ser(
&servers
.map(|s| {
s.into_iter()
.map(|s| {
s.parse::<SocketAddr>()
.or_else(|_| s.parse::<IpAddr>().map(|a| (a, 53).into()))
})
.collect()
})
.transpose()?,
)
})
.await
.result
}
#[derive(Default)]
@@ -125,8 +150,120 @@ pub struct DnsController {
dns_server: NonDetachingJoinHandle<()>,
}
struct DnsClient {
client: Arc<SyncRwLock<Vec<(SocketAddr, hickory_client::client::Client)>>>,
_thread: NonDetachingJoinHandle<()>,
}
impl DnsClient {
pub fn new(db: TypedPatchDb<Database>) -> Self {
let client = Arc::new(SyncRwLock::new(Vec::new()));
Self {
client: client.clone(),
_thread: tokio::spawn(async move {
loop {
if let Err::<(), Error>(e) = async {
let mut stream = file_string_stream("/run/systemd/resolve/resolv.conf")
.filter_map(|a| futures::future::ready(a.transpose())).boxed();
let mut conf = stream
.next()
.await
.or_not_found("/run/systemd/resolve/resolv.conf")??;
let mut prev_nameservers = Vec::new();
let mut bg = BTreeMap::<SocketAddr, BoxFuture<_>>::new();
loop {
let nameservers = conf
.lines()
.map(|l| l.trim())
.filter_map(|l| l.strip_prefix("nameserver "))
.map(|n| {
n.parse::<SocketAddr>()
.or_else(|_| n.parse::<IpAddr>().map(|a| (a, 53).into()))
})
.collect::<Result<Vec<_>, _>>()?;
let static_nameservers = db
.mutate(|db| {
let dns = db
.as_public_mut()
.as_server_info_mut()
.as_network_mut()
.as_dns_mut();
dns.as_dhcp_servers_mut().ser(&nameservers)?;
dns.as_static_servers().de()
})
.await
.result?;
let nameservers = static_nameservers.unwrap_or(nameservers);
if nameservers != prev_nameservers {
let mut existing: BTreeMap<_, _> =
client.peek(|c| c.iter().cloned().collect());
let mut new = Vec::with_capacity(nameservers.len());
for addr in &nameservers {
if let Some(existing) = existing.remove(addr) {
new.push((*addr, existing));
} else {
let client = if let Ok((client, bg_thread)) =
Client::connect(
UdpClientStream::builder(
*addr,
TokioRuntimeProvider::new(),
)
.build(),
)
.await
{
bg.insert(*addr, bg_thread.boxed());
client
} else {
let (stream, sender) = TcpClientStream::new(
*addr,
None,
Some(Duration::from_secs(30)),
TokioRuntimeProvider::new(),
);
let (client, bg_thread) =
Client::new(stream, sender, None)
.await
.with_kind(ErrorKind::Network)?;
bg.insert(*addr, bg_thread.boxed());
client
};
new.push((*addr, client));
}
}
bg.retain(|n, _| nameservers.iter().any(|a| a == n));
prev_nameservers = nameservers;
}
tokio::select! {
c = stream.next() => conf = c.or_not_found("/run/systemd/resolve/resolv.conf")??,
_ = futures::future::join_all(bg.values_mut()) => (),
}
}
}
.await
{
tracing::error!("{e}");
tracing::debug!("{e:?}");
}
}
})
.into(),
}
}
fn lookup(
&self,
query: hickory_client::proto::op::Query,
options: DnsRequestOptions,
) -> Vec<hickory_client::proto::xfer::DnsExchangeSend> {
self.client.peek(|c| {
c.iter()
.map(|(_, c)| c.lookup(query.clone(), options.clone()))
.collect()
})
}
}
struct Resolver {
client: hickory_client::client::Client,
client: DnsClient,
net_iface: Watch<OrdMap<GatewayId, NetworkInterfaceInfo>>,
resolve: Arc<SyncRwLock<ResolveMap>>,
}
@@ -271,29 +408,43 @@ impl RequestHandler for Resolver {
}
} else {
let query = query.original().clone();
let mut stream = self.client.lookup(query, DnsRequestOptions::default());
let mut res = None;
while let Some(msg) = stream.try_next().await? {
res = Some(
response_handle
.send_response(
MessageResponseBuilder::from_message_request(&*request).build(
msg.header().clone(),
msg.answers(),
msg.name_servers(),
&msg.soa().map(|s| s.to_owned().into_record_of_rdata()),
msg.additionals(),
),
)
.await?,
);
let mut streams = self.client.lookup(query, DnsRequestOptions::default());
let mut err = None;
for stream in streams.iter_mut() {
match stream.next().await {
None => (),
Some(Err(e)) => err = Some(e),
Some(Ok(msg)) => {
return response_handle
.send_response(
MessageResponseBuilder::from_message_request(&*request).build(
msg.header().clone(),
msg.answers(),
msg.name_servers(),
&msg.soa().map(|s| s.to_owned().into_record_of_rdata()),
msg.additionals(),
),
)
.await;
}
}
}
res.ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::NotFound,
eyre!("no response from server"),
if let Some(e) = err {
tracing::error!("{e}");
tracing::debug!("{e:?}");
}
let res = Header::response_from_request(request.header());
response_handle
.send_response(
MessageResponseBuilder::from_message_request(&*request).build(
res.into(),
[],
[],
[],
[],
),
)
})
.await
}
}
.await
@@ -309,50 +460,40 @@ impl RequestHandler for Resolver {
impl DnsController {
#[instrument(skip_all)]
pub async fn init(watcher: &NetworkInterfaceWatcher) -> Result<Self, Error> {
pub async fn init(
db: TypedPatchDb<Database>,
watcher: &NetworkInterfaceWatcher,
) -> Result<Self, Error> {
let resolve = Arc::new(SyncRwLock::new(ResolveMap::default()));
let stream =
UdpClientStream::builder(([127, 0, 0, 53], 5355).into(), TokioRuntimeProvider::new())
.build();
let (client, bg) = Client::connect(stream)
.await
.with_kind(ErrorKind::Network)?;
let mut server = ServerFuture::new(Resolver {
client,
client: DnsClient::new(db),
net_iface: watcher.subscribe(),
resolve: resolve.clone(),
});
let dns_server = tokio::spawn(
futures::future::join(
async move {
server.register_listener(
TcpListener::bind((Ipv6Addr::UNSPECIFIED, 53))
.await
.with_kind(ErrorKind::Network)?,
Duration::from_secs(30),
);
server.register_socket(
UdpSocket::bind((Ipv6Addr::UNSPECIFIED, 53))
.await
.with_kind(ErrorKind::Network)?,
);
server
.block_until_done()
async move {
server.register_listener(
TcpListener::bind((Ipv6Addr::UNSPECIFIED, 53))
.await
.with_kind(ErrorKind::Network)
}
.map(|r| {
r.log_err();
}),
bg.map(|r| {
r.log_err();
}),
)
.map(|_| ()),
.with_kind(ErrorKind::Network)?,
Duration::from_secs(30),
);
server.register_socket(
UdpSocket::bind((Ipv6Addr::UNSPECIFIED, 53))
.await
.with_kind(ErrorKind::Network)?,
);
server
.block_until_done()
.await
.with_kind(ErrorKind::Network)
}
.map(|r| {
r.log_err();
}),
)
.into();

View File

@@ -15,8 +15,8 @@ use crate::db::model::public::NetworkInterfaceInfo;
use crate::net::gateway::{DynInterfaceFilter, InterfaceFilter};
use crate::net::utils::ipv6_is_link_local;
use crate::prelude::*;
use crate::util::sync::Watch;
use crate::util::Invoke;
use crate::util::sync::Watch;
pub const START9_BRIDGE_IFACE: &str = "lxcbr0";
pub const FIRST_DYNAMIC_PRIVATE_PORT: u16 = 49152;

View File

@@ -316,6 +316,7 @@ trait Dhcp4Config {
#[zvariant(signature = "dict")]
struct Dhcp4Options {
ntp_servers: Option<String>,
domain_name_servers: Option<String>,
}
impl TryFrom<OwnedValue> for Dhcp4Options {
type Error = zbus::Error;
@@ -323,6 +324,8 @@ impl TryFrom<OwnedValue> for Dhcp4Options {
let dict = value.downcast_ref::<Dict>()?;
Ok(Self {
ntp_servers: dict.get::<_, String>(&zbus::zvariant::Str::from_static("ntp_servers"))?,
domain_name_servers: dict
.get::<_, String>(&zbus::zvariant::Str::from_static("domain_name_servers"))?,
})
}
}
@@ -622,12 +625,20 @@ async fn watch_ip(
.chain(ip6_proxy.address_data().await?)
.collect_vec();
let lan_ip = [
dbg!(ip4_proxy.gateway().await?).parse::<IpAddr>()?,
dbg!(ip6_proxy.gateway().await?).parse::<IpAddr>()?,
Some(ip4_proxy.gateway().await?)
.filter(|g| !g.is_empty())
.map(|g| g.parse::<IpAddr>())
.transpose()?,
Some(ip6_proxy.gateway().await?)
.filter(|g| !g.is_empty())
.map(|g| g.parse::<IpAddr>())
.transpose()?,
]
.into_iter()
.filter_map(|a| a)
.collect();
let mut ntp_servers = OrdSet::new();
let mut dns_servers = OrdSet::new();
if let Some(dhcp4_proxy) = &dhcp4_proxy {
let dhcp = dhcp4_proxy.options().await?;
if let Some(ntp) = dhcp.ntp_servers {
@@ -636,15 +647,14 @@ async fn watch_ip(
.map(InternedString::intern),
);
}
if let Some(dns) = dhcp.domain_name_servers {
dns_servers.extend(
dns.split(",")
.map(|s| s.trim().parse::<IpAddr>())
.collect::<Result<Vec<_>, _>>()?,
);
}
}
let dns_servers = []
.into_iter()
.chain(ip4_proxy.nameserver_data().await?)
.chain(ip6_proxy.nameserver_data().await?)
.map(|NameserverData { address }| {
address.parse::<IpAddr>()
})
.collect::<Result<_, _>>()?;
let scope_id = if_nametoindex(iface.as_str())
.with_kind(ErrorKind::Network)?;
let subnets: OrdSet<IpNet> = addresses
@@ -852,22 +862,6 @@ impl NetworkInterfaceController {
) -> Result<(), Error> {
tracing::debug!("syncronizing {info:?} to db");
// let dns = todo!();
let dns = info
.values()
.filter_map(|i| i.ip_info.as_ref())
.flat_map(|i| &i.dns_servers)
.copied()
.collect();
db.mutate(|db| {
let net = db.as_public_mut().as_server_info_mut().as_network_mut();
net.as_dns_mut().as_dhcp_servers_mut().ser(&dns)?;
net.as_gateways_mut().ser(info)
})
.await
.result?;
let ntp: BTreeSet<_> = info
.values()
.filter_map(|i| i.ip_info.as_ref())
@@ -1191,23 +1185,39 @@ impl ListenerMap {
}
pub trait InterfaceFilter: Any + Clone + std::fmt::Debug + Eq + Ord + Send + Sync {
#[cfg_attr(feature = "unstable", inline(never))]
fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool;
#[cfg_attr(feature = "unstable", inline(never))]
fn simplify(&self) -> &dyn DynInterfaceFilterT {
self
}
#[cfg_attr(feature = "unstable", inline(never))]
fn eq(&self, other: &dyn Any) -> bool {
Some(self) == other.downcast_ref::<Self>()
}
#[cfg_attr(feature = "unstable", inline(never))]
fn cmp(&self, other: &dyn Any) -> std::cmp::Ordering {
match self.as_any().type_id().cmp(&other.type_id()) {
std::cmp::Ordering::Equal => std::cmp::Ord::cmp(&self, other.downcast_ref().unwrap()),
match (self as &dyn Any).type_id().cmp(&other.type_id()) {
std::cmp::Ordering::Equal => {
std::cmp::Ord::cmp(self, other.downcast_ref::<Self>().unwrap())
}
ord => ord,
}
}
#[cfg_attr(feature = "unstable", inline(never))]
fn as_any(&self) -> &dyn Any {
self
}
fn into_dyn(self) -> DynInterfaceFilter {
#[cfg(feature = "unstable")]
{
let res = DynInterfaceFilter::new(self.clone());
if !DynInterfaceFilterT::eq(&self, &res) || !DynInterfaceFilterT::eq(&res, &self) {
panic!("self != self")
}
res
}
#[cfg(not(feature = "unstable"))]
DynInterfaceFilter::new(self)
}
}
@@ -1285,12 +1295,9 @@ impl<A: InterfaceFilter, B: InterfaceFilter> InterfaceFilter for AndFilter<A, B>
})
.into_inner()
} else {
match InterfaceFilter::as_any(self)
.type_id()
.cmp(&other.type_id())
{
match (self as &dyn Any).type_id().cmp(&other.type_id()) {
std::cmp::Ordering::Equal => {
std::cmp::Ord::cmp(&self, other.downcast_ref().unwrap())
std::cmp::Ord::cmp(self, other.downcast_ref::<Self>().unwrap())
}
ord => ord,
}
@@ -1337,12 +1344,9 @@ impl<A: InterfaceFilter, B: InterfaceFilter> InterfaceFilter for OrFilter<A, B>
})
.into_inner()
} else {
match InterfaceFilter::as_any(self)
.type_id()
.cmp(&other.type_id())
{
match (self as &dyn Any).type_id().cmp(&other.type_id()) {
std::cmp::Ordering::Equal => {
std::cmp::Ord::cmp(&self, other.downcast_ref().unwrap())
std::cmp::Ord::cmp(self, other.downcast_ref::<Self>().unwrap())
}
ord => ord,
}
@@ -1380,7 +1384,7 @@ impl InterfaceFilter for AllFilter {
}
}
pub trait DynInterfaceFilterT: std::fmt::Debug + Send + Sync {
pub trait DynInterfaceFilterT: std::fmt::Debug + Any + Send + Sync {
fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool;
fn eq(&self, other: &dyn Any) -> bool;
fn cmp(&self, other: &dyn Any) -> std::cmp::Ordering;
@@ -1392,15 +1396,15 @@ impl<T: InterfaceFilter> DynInterfaceFilterT for T {
}
fn eq(&self, other: &dyn Any) -> bool {
let simplified = self.simplify();
if std::ptr::eq(simplified, self) {
if (simplified as &dyn Any).is::<Self>() {
InterfaceFilter::eq(self, other)
} else {
simplified.eq(other)
dbg!(simplified.eq(other))
}
}
fn cmp(&self, other: &dyn Any) -> std::cmp::Ordering {
let simplified = self.simplify();
if std::ptr::eq(simplified, self) {
if (simplified as &dyn Any).is::<Self>() {
InterfaceFilter::cmp(self, other)
} else {
simplified.cmp(other)
@@ -1408,7 +1412,7 @@ impl<T: InterfaceFilter> DynInterfaceFilterT for T {
}
fn as_any(&self) -> &dyn Any {
let simplified = self.simplify();
if std::ptr::eq(simplified, self) {
if (simplified as &dyn Any).is::<Self>() {
InterfaceFilter::as_any(self)
} else {
simplified.as_any()
@@ -1571,6 +1575,7 @@ impl NetworkInterfaceListener {
self.listeners.port
}
#[cfg_attr(feature = "unstable", inline(never))]
pub fn poll_accept(
&mut self,
cx: &mut std::task::Context<'_>,
@@ -1580,7 +1585,7 @@ impl NetworkInterfaceListener {
|| !InterfaceFilter::eq(&self.listeners.prev_filter, filter)
{
self.ip_info
.peek(|ip_info| self.listeners.update(ip_info, filter))?;
.peek_and_mark_seen(|ip_info| self.listeners.update(ip_info, filter))?;
}
self.listeners.poll_accept(cx)
}

View File

@@ -3,17 +3,17 @@ use std::collections::BTreeSet;
use clap::Parser;
use imbl_value::InternedString;
use models::GatewayId;
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::context::{CliContext, RpcContext};
use crate::db::model::DatabaseModel;
use crate::net::acme::AcmeProvider;
use crate::net::host::{all_hosts, HostApiKind};
use crate::net::host::{HostApiKind, all_hosts};
use crate::net::tor::OnionAddress;
use crate::prelude::*;
use crate::util::serde::{display_serializable, HandlerExtSerde};
use crate::util::serde::{HandlerExtSerde, display_serializable};
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
@@ -73,8 +73,8 @@ fn check_duplicates(db: &DatabaseModel) -> Result<(), Error> {
Ok(())
}
pub fn address_api<C: Context, Kind: HostApiKind>(
) -> ParentHandler<C, Kind::Params, Kind::InheritedParams> {
pub fn address_api<C: Context, Kind: HostApiKind>()
-> ParentHandler<C, Kind::Params, Kind::InheritedParams> {
ParentHandler::<C, Kind::Params, Kind::InheritedParams>::new()
.subcommand(
"domain",

View File

@@ -1,11 +1,11 @@
use std::collections::{BTreeMap, BTreeSet};
use std::str::FromStr;
use clap::builder::ValueParserFactory;
use clap::Parser;
use clap::builder::ValueParserFactory;
use imbl::OrdSet;
use models::{FromStrParser, GatewayId, HostId};
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -16,7 +16,7 @@ use crate::net::gateway::InterfaceFilter;
use crate::net::host::HostApiKind;
use crate::net::vhost::AlpnInfo;
use crate::prelude::*;
use crate::util::serde::{display_serializable, HandlerExtSerde};
use crate::util::serde::{HandlerExtSerde, display_serializable};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, TS)]
#[ts(export)]
@@ -169,8 +169,8 @@ pub struct AddSslOptions {
pub alpn: Option<AlpnInfo>,
}
pub fn binding<C: Context, Kind: HostApiKind>(
) -> ParentHandler<C, Kind::Params, Kind::InheritedParams> {
pub fn binding<C: Context, Kind: HostApiKind>()
-> ParentHandler<C, Kind::Params, Kind::InheritedParams> {
ParentHandler::<C, Kind::Params, Kind::InheritedParams>::new()
.subcommand(
"list",

View File

@@ -6,15 +6,15 @@ use clap::Parser;
use imbl_value::InternedString;
use itertools::Itertools;
use models::{HostId, PackageId};
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, OrEmpty, ParentHandler};
use rpc_toolkit::{Context, Empty, HandlerExt, OrEmpty, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::context::RpcContext;
use crate::db::model::DatabaseModel;
use crate::net::forward::AvailablePorts;
use crate::net::host::address::{address_api, HostAddress, PublicDomainConfig};
use crate::net::host::binding::{binding, BindInfo, BindOptions};
use crate::net::host::address::{HostAddress, PublicDomainConfig, address_api};
use crate::net::host::binding::{BindInfo, BindOptions, binding};
use crate::net::service_interface::HostnameInfo;
use crate::net::tor::OnionAddress;
use crate::prelude::*;

View File

@@ -50,8 +50,8 @@ impl NetController {
Ok(Self {
db: db.clone(),
tor: TorController::new().await?,
vhost: VHostController::new(db, net_iface.clone()),
dns: DnsController::init(&net_iface.watcher).await?,
vhost: VHostController::new(db.clone(), net_iface.clone()),
dns: DnsController::init(db, &net_iface.watcher).await?,
forward: PortForwardController::new(net_iface.watcher.subscribe()),
net_iface,
server_hostnames: vec![

View File

@@ -1,4 +1,4 @@
use std::cmp::{min, Ordering};
use std::cmp::{Ordering, min};
use std::collections::{BTreeMap, BTreeSet};
use std::net::IpAddr;
use std::path::Path;
@@ -13,18 +13,18 @@ use openssl::ec::{EcGroup, EcKey};
use openssl::hash::MessageDigest;
use openssl::nid::Nid;
use openssl::pkey::{PKey, Private};
use openssl::x509::{X509Builder, X509Extension, X509NameBuilder, X509};
use openssl::x509::{X509, X509Builder, X509Extension, X509NameBuilder};
use openssl::*;
use patch_db::HasModel;
use serde::{Deserialize, Serialize};
use tracing::instrument;
use crate::SOURCE_DATE;
use crate::account::AccountInfo;
use crate::hostname::Hostname;
use crate::init::check_time_is_synchronized;
use crate::prelude::*;
use crate::util::serde::Pem;
use crate::SOURCE_DATE;
#[derive(Debug, Deserialize, Serialize, HasModel)]
#[model = "Model<Self>"]

View File

@@ -6,11 +6,11 @@ use std::sync::Arc;
use std::time::UNIX_EPOCH;
use async_compression::tokio::bufread::GzipEncoder;
use axum::Router;
use axum::body::Body;
use axum::extract::{self as x, Request};
use axum::response::{Redirect, Response};
use axum::routing::{any, get};
use axum::Router;
use base64::display::Base64Display;
use digest::Digest;
use futures::future::ready;
@@ -37,12 +37,12 @@ use crate::middleware::auth::{Auth, HasValidSession};
use crate::middleware::cors::Cors;
use crate::middleware::db::SyncDb;
use crate::prelude::*;
use crate::sign::commitment::merkle_archive::MerkleArchiveCommitment;
use crate::rpc_continuations::{Guid, RpcContinuations};
use crate::s9pk::S9pk;
use crate::s9pk::merkle_archive::source::FileSource;
use crate::s9pk::merkle_archive::source::http::HttpSource;
use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile;
use crate::s9pk::merkle_archive::source::FileSource;
use crate::s9pk::S9pk;
use crate::sign::commitment::merkle_archive::MerkleArchiveCommitment;
use crate::util::io::open_file;
use crate::util::net::SyncBody;
use crate::util::serde::BASE64;

View File

@@ -357,7 +357,16 @@ pub enum OnionServiceState {
}
impl From<ArtiOnionServiceState> for OnionServiceState {
fn from(value: ArtiOnionServiceState) -> Self {
todo!()
match value {
ArtiOnionServiceState::Shutdown => Self::Shutdown,
ArtiOnionServiceState::Bootstrapping => Self::Bootstrapping,
ArtiOnionServiceState::DegradedReachable => Self::DegradedReachable,
ArtiOnionServiceState::DegradedUnreachable => Self::DegradedUnreachable,
ArtiOnionServiceState::Running => Self::Running,
ArtiOnionServiceState::Recovering => Self::Recovering,
ArtiOnionServiceState::Broken => Self::Broken,
_ => unreachable!(),
}
}
}
@@ -369,7 +378,7 @@ pub async fn list_services(
}
pub struct TorController {
client: TorClient<TokioRustlsRuntime>,
client: Arc<SyncRwLock<TorClient<TokioRustlsRuntime>>>,
services: SyncMutex<BTreeMap<OnionAddress, OnionService>>,
}
impl TorController {
@@ -381,10 +390,12 @@ impl TorController {
.primary()
.kind(ArtiKeystoreKind::Ephemeral.into());
Ok(Self {
client: TorClient::with_runtime(TokioRustlsRuntime::current()?)
.config(config.build().with_kind(ErrorKind::Tor)?)
.create_unbootstrapped_async()
.await?,
client: Arc::new(SyncRwLock::new(
TorClient::with_runtime(TokioRustlsRuntime::current()?)
.config(config.build().with_kind(ErrorKind::Tor)?)
.create_unbootstrapped_async()
.await?,
)),
services: SyncMutex::new(BTreeMap::new()),
})
}
@@ -440,11 +451,14 @@ impl TorController {
}
pub async fn reset(&self, wipe_state: bool) -> Result<(), Error> {
todo!()
// todo!()
Ok(())
}
pub async fn list_services(&self) -> Result<BTreeMap<OnionAddress, OnionServiceState>, Error> {
todo!()
Ok(self
.services
.peek(|s| s.iter().map(|(a, s)| (a.clone(), s.state())).collect()))
}
}
@@ -456,7 +470,10 @@ struct OnionServiceData {
_thread: NonDetachingJoinHandle<()>,
}
impl OnionService {
fn launch(client: TorClient<TokioRustlsRuntime>, key: TorSecretKey) -> Result<Self, Error> {
fn launch(
client: Arc<SyncRwLock<TorClient<TokioRustlsRuntime>>>,
key: TorSecretKey,
) -> Result<Self, Error> {
let service = Arc::new(SyncMutex::new(None));
let bindings = Arc::new(SyncRwLock::new(BTreeMap::<
u16,
@@ -471,8 +488,8 @@ impl OnionService {
.run_while(async {
loop {
if let Err(e) = async {
let (new_service, mut stream) = client
.launch_onion_service_with_hsid(
let (new_service, mut stream) = client.peek(|c| {
c.launch_onion_service_with_hsid(
OnionServiceConfigBuilder::default()
.nickname(
key.onion_address()
@@ -485,7 +502,8 @@ impl OnionService {
.with_kind(ErrorKind::Tor)?,
key.clone().0,
)
.with_kind(ErrorKind::Tor)?;
.with_kind(ErrorKind::Tor)
})?;
service.replace(Some(new_service));
while let Some(req) = stream.next().await {
bg.add_job({
@@ -608,4 +626,11 @@ impl OnionService {
self.0._thread.abort();
Ok(())
}
pub fn state(&self) -> OnionServiceState {
self.0
.service
.peek(|s| s.as_ref().map(|s| s.status().state().into()))
.unwrap_or(OnionServiceState::Bootstrapping)
}
}

View File

@@ -1,7 +1,7 @@
use clap::Parser;
use imbl_value::InternedString;
use models::GatewayId;
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use tokio::process::Command;
use ts_rs::TS;
@@ -9,8 +9,8 @@ use ts_rs::TS;
use crate::context::{CliContext, RpcContext};
use crate::db::model::public::NetworkInterfaceType;
use crate::prelude::*;
use crate::util::io::{write_file_atomic, TmpDir};
use crate::util::Invoke;
use crate::util::io::{TmpDir, write_file_atomic};
pub fn tunnel_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new()

View File

@@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};
use std::net::{IpAddr, SocketAddr};
use std::sync::{Arc, Weak};
use async_acme::acme::{Identifier, ACME_TLS_ALPN_NAME};
use async_acme::acme::{ACME_TLS_ALPN_NAME, Identifier};
use axum::body::Body;
use axum::extract::Request;
use axum::response::Response;
@@ -14,7 +14,7 @@ use imbl::OrdMap;
use imbl_value::InternedString;
use itertools::Itertools;
use models::{GatewayId, ResultExt};
use rpc_toolkit::{from_fn, Context, HandlerArgs, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn};
use serde::{Deserialize, Serialize};
use tokio::io::AsyncWriteExt;
use tokio::net::TcpStream;
@@ -27,14 +27,14 @@ use tokio_rustls::rustls::server::{Acceptor, ResolvesServerCert};
use tokio_rustls::rustls::sign::CertifiedKey;
use tokio_rustls::rustls::{RootCertStore, ServerConfig};
use tokio_rustls::{LazyConfigAcceptor, TlsConnector};
use tokio_stream::wrappers::WatchStream;
use tokio_stream::StreamExt;
use tokio_stream::wrappers::WatchStream;
use tracing::instrument;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext};
use crate::db::model::public::NetworkInterfaceInfo;
use crate::db::model::Database;
use crate::db::model::public::NetworkInterfaceInfo;
use crate::net::acme::{AcmeCertCache, AcmeProvider};
use crate::net::gateway::{
Accepted, AnyFilter, DynInterfaceFilter, InterfaceFilter, NetworkInterfaceController,
@@ -44,7 +44,7 @@ use crate::net::static_server::server_error;
use crate::prelude::*;
use crate::util::collections::EqSet;
use crate::util::io::BackTrackingIO;
use crate::util::serde::{display_serializable, HandlerExtSerde, MaybeUtf8String};
use crate::util::serde::{HandlerExtSerde, MaybeUtf8String, display_serializable};
use crate::util::sync::SyncMutex;
pub fn vhost_api<C: Context>() -> ParentHandler<C> {

View File

@@ -23,7 +23,7 @@ use crate::net::static_server::{
};
use crate::prelude::*;
use crate::util::actor::background::BackgroundJobQueue;
use crate::util::sync::{SyncMutex, Watch};
use crate::util::sync::{SyncMutex, SyncRwLock, Watch};
pub struct Accepted {
pub https_redirect: bool,
@@ -170,7 +170,7 @@ impl<A: Accept + Send + Sync + 'static> WebServer<A> {
let thread = NonDetachingJoinHandle::from(tokio::spawn(async move {
#[derive(Clone)]
struct QueueRunner {
queue: Arc<SyncMutex<Option<BackgroundJobQueue>>>,
queue: Arc<SyncRwLock<Option<BackgroundJobQueue>>>,
}
impl<Fut> hyper::rt::Executor<Fut> for QueueRunner
where
@@ -215,7 +215,7 @@ impl<A: Accept + Send + Sync + 'static> WebServer<A> {
}
}
let queue_cell = Arc::new(SyncMutex::new(None));
let queue_cell = Arc::new(SyncRwLock::new(None));
let graceful = hyper_util::server::graceful::GracefulShutdown::new();
let mut server = hyper_util::server::conn::auto::Builder::new(QueueRunner {
queue: queue_cell.clone(),
@@ -231,7 +231,7 @@ impl<A: Accept + Send + Sync + 'static> WebServer<A> {
.keep_alive_interval(Duration::from_secs(60))
.keep_alive_timeout(Duration::from_secs(300));
let (queue, mut runner) = BackgroundJobQueue::new();
queue_cell.mutate(|q| *q = Some(queue.clone()));
queue_cell.replace(Some(queue.clone()));
let handler = async {
loop {
@@ -266,7 +266,7 @@ impl<A: Accept + Send + Sync + 'static> WebServer<A> {
}
drop(queue);
drop(queue_cell.mutate(|q| q.take()));
drop(queue_cell.replace(None));
if !runner.is_empty() {
tokio::time::timeout(Duration::from_secs(60), runner)

View File

@@ -3,12 +3,12 @@ use std::path::Path;
use std::sync::Arc;
use std::time::Duration;
use clap::builder::TypedValueParser;
use clap::Parser;
use clap::builder::TypedValueParser;
use isocountry::CountryCode;
use lazy_static::lazy_static;
use regex::Regex;
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, Empty, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use tokio::process::Command;
use tokio::sync::RwLock;
@@ -16,11 +16,11 @@ use tracing::instrument;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext};
use crate::db::model::public::WifiInfo;
use crate::db::model::Database;
use crate::db::model::public::WifiInfo;
use crate::prelude::*;
use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat};
use crate::util::Invoke;
use crate::util::serde::{HandlerExtSerde, WithIoFormat, display_serializable};
use crate::{Error, ErrorKind};
type WifiManager = Arc<RwLock<Option<WpaCli>>>;
@@ -315,7 +315,12 @@ pub async fn remove(ctx: RpcContext, SsidParams { ssid }: SsidParams) -> Result<
let is_current_removed_and_no_hardwire =
is_current_being_removed && !interface_connected(&ctx.ethernet_interface).await?;
if is_current_removed_and_no_hardwire {
return Err(Error::new(color_eyre::eyre::eyre!("Forbidden: Deleting this network would make your server unreachable. Either connect to ethernet or connect to a different WiFi network to remedy this."), ErrorKind::Wifi));
return Err(Error::new(
color_eyre::eyre::eyre!(
"Forbidden: Deleting this network would make your server unreachable. Either connect to ethernet or connect to a different WiFi network to remedy this."
),
ErrorKind::Wifi,
));
}
wpa_supplicant.remove_network(ctx.db.clone(), &ssid).await?;

View File

@@ -3,13 +3,13 @@ use std::fmt;
use std::str::FromStr;
use chrono::{DateTime, Utc};
use clap::builder::ValueParserFactory;
use clap::Parser;
use clap::builder::ValueParserFactory;
use color_eyre::eyre::eyre;
use helpers::const_true;
use imbl_value::InternedString;
use models::{FromStrParser, PackageId};
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use tracing::instrument;
use ts_rs::TS;

View File

@@ -1,10 +1,10 @@
use std::path::Path;
use gpt::disk::LogicalBlockSize;
use gpt::GptConfig;
use gpt::disk::LogicalBlockSize;
use crate::disk::util::DiskInfo;
use crate::disk::OsPartitionInfo;
use crate::disk::util::DiskInfo;
use crate::os_install::partition_for;
use crate::prelude::*;

View File

@@ -1,10 +1,10 @@
use color_eyre::eyre::eyre;
use mbrman::{MBRPartitionEntry, CHS, MBR};
use mbrman::{CHS, MBR, MBRPartitionEntry};
use crate::disk::util::DiskInfo;
use crate::disk::OsPartitionInfo;
use crate::os_install::partition_for;
use crate::Error;
use crate::disk::OsPartitionInfo;
use crate::disk::util::DiskInfo;
use crate::os_install::partition_for;
pub async fn partition(disk: &DiskInfo, overwrite: bool) -> Result<OsPartitionInfo, Error> {
{

View File

@@ -3,13 +3,15 @@ use std::path::{Path, PathBuf};
use clap::Parser;
use color_eyre::eyre::eyre;
use models::Error;
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
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;
use crate::disk::mount::filesystem::bind::Bind;
use crate::disk::mount::filesystem::block_dev::BlockDev;
use crate::disk::mount::filesystem::efivarfs::EfiVarFs;
@@ -17,14 +19,12 @@ use crate::disk::mount::filesystem::overlayfs::OverlayFs;
use crate::disk::mount::filesystem::{MountType, ReadWrite};
use crate::disk::mount::guard::{GenericMountGuard, MountGuard, TmpMountGuard};
use crate::disk::util::{DiskInfo, PartitionTable};
use crate::disk::OsPartitionInfo;
use crate::net::utils::find_eth_iface;
use crate::prelude::*;
use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile;
use crate::util::io::{delete_file, open_file, TmpDir};
use crate::util::serde::IoFormat;
use crate::util::Invoke;
use crate::ARCH;
use crate::util::io::{TmpDir, delete_file, open_file};
use crate::util::serde::IoFormat;
mod gpt;
mod mbr;

View File

@@ -3,18 +3,18 @@ use std::path::PathBuf;
use clap::Parser;
use itertools::Itertools;
use rpc_toolkit::{from_fn_async, Context, HandlerArgs, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::context::CliContext;
use crate::prelude::*;
use crate::registry::context::RegistryContext;
use crate::sign::AnyVerifyingKey;
use crate::registry::signer::{ContactInfo, SignerInfo};
use crate::registry::RegistryDatabase;
use crate::registry::context::RegistryContext;
use crate::registry::signer::{ContactInfo, SignerInfo};
use crate::rpc_continuations::Guid;
use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat};
use crate::sign::AnyVerifyingKey;
use crate::util::serde::{HandlerExtSerde, WithIoFormat, display_serializable};
pub fn admin_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new()

View File

@@ -11,13 +11,13 @@ use url::Url;
use crate::prelude::*;
use crate::progress::PhaseProgressTrackerHandle;
use crate::registry::signer::AcceptSigners;
use crate::s9pk::S9pk;
use crate::s9pk::merkle_archive::source::http::HttpSource;
use crate::s9pk::merkle_archive::source::{ArchiveSource, Section};
use crate::sign::commitment::merkle_archive::MerkleArchiveCommitment;
use crate::sign::commitment::{Commitment, Digestable};
use crate::sign::{AnySignature, AnyVerifyingKey};
use crate::registry::signer::AcceptSigners;
use crate::s9pk::merkle_archive::source::http::HttpSource;
use crate::s9pk::merkle_archive::source::{ArchiveSource, Section};
use crate::s9pk::S9pk;
use crate::upload::UploadingFile;
#[derive(Debug, Deserialize, Serialize, TS)]

View File

@@ -17,13 +17,13 @@ use tracing::instrument;
use ts_rs::TS;
use url::Url;
use crate::context::config::{ContextConfig, CONFIG_PATH};
use crate::context::config::{CONFIG_PATH, ContextConfig};
use crate::context::{CliContext, RpcContext};
use crate::middleware::signature::SignatureAuthContext;
use crate::prelude::*;
use crate::registry::device_info::{DeviceInfo, DEVICE_INFO_HEADER};
use crate::registry::signer::SignerInfo;
use crate::registry::RegistryDatabase;
use crate::registry::device_info::{DEVICE_INFO_HEADER, DeviceInfo};
use crate::registry::signer::SignerInfo;
use crate::rpc_continuations::RpcContinuations;
use crate::sign::AnyVerifyingKey;
use crate::util::io::append_file;
@@ -197,10 +197,10 @@ impl CallRemote<RegistryContext, RegistryUrlParams> for RpcContext {
params: Value,
RegistryUrlParams { registry }: RegistryUrlParams,
) -> Result<Value, RpcError> {
use reqwest::header::{ACCEPT, CONTENT_LENGTH, CONTENT_TYPE};
use reqwest::Method;
use rpc_toolkit::yajrc::{GenericRpcMethod, Id, RpcRequest};
use reqwest::header::{ACCEPT, CONTENT_LENGTH, CONTENT_TYPE};
use rpc_toolkit::RpcResponse;
use rpc_toolkit::yajrc::{GenericRpcMethod, Id, RpcRequest};
let url = registry.join("rpc/v0")?;
method = method.strip_prefix("registry.").unwrap_or(method);

View File

@@ -2,19 +2,19 @@ use std::path::PathBuf;
use clap::Parser;
use itertools::Itertools;
use patch_db::json_ptr::{JsonPointer, ROOT};
use patch_db::Dump;
use patch_db::json_ptr::{JsonPointer, ROOT};
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{from_fn_async, Context, HandlerArgs, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use tracing::instrument;
use ts_rs::TS;
use crate::context::CliContext;
use crate::prelude::*;
use crate::registry::context::RegistryContext;
use crate::registry::RegistryDatabase;
use crate::util::serde::{apply_expr, HandlerExtSerde};
use crate::registry::context::RegistryContext;
use crate::util::serde::{HandlerExtSerde, apply_expr};
pub fn db_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new()

View File

@@ -15,8 +15,8 @@ use url::Url;
use crate::context::RpcContext;
use crate::prelude::*;
use crate::registry::context::RegistryContext;
use crate::util::lshw::{LshwDevice, LshwDisplay, LshwProcessor};
use crate::util::VersionString;
use crate::util::lshw::{LshwDevice, LshwDisplay, LshwProcessor};
use crate::version::VersionT;
pub const DEVICE_INFO_HEADER: &str = "X-StartOS-Device-Info";

View File

@@ -5,7 +5,7 @@ use clap::Parser;
use imbl_value::InternedString;
use itertools::Itertools;
use models::DataUrl;
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;

View File

@@ -3,7 +3,7 @@ use std::collections::{BTreeMap, BTreeSet};
use axum::Router;
use futures::future::ready;
use models::DataUrl;
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler, Server};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, Server, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;

View File

@@ -7,7 +7,7 @@ use clap::Parser;
use exver::Version;
use imbl_value::InternedString;
use itertools::Itertools;
use rpc_toolkit::{from_fn_async, Context, HandlerArgs, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use url::Url;
@@ -17,15 +17,15 @@ use crate::prelude::*;
use crate::progress::{FullProgressTracker, ProgressUnits};
use crate::registry::asset::RegistryAsset;
use crate::registry::context::RegistryContext;
use crate::registry::os::index::OsVersionInfo;
use crate::registry::os::SIG_CONTEXT;
use crate::registry::os::index::OsVersionInfo;
use crate::s9pk::merkle_archive::hash::VerifyingWriter;
use crate::s9pk::merkle_archive::source::ArchiveSource;
use crate::s9pk::merkle_archive::source::http::HttpSource;
use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile;
use crate::sign::commitment::blake3::Blake3Commitment;
use crate::sign::ed25519::Ed25519;
use crate::sign::{AnySignature, AnyVerifyingKey, SignatureScheme};
use crate::s9pk::merkle_archive::hash::VerifyingWriter;
use crate::s9pk::merkle_archive::source::http::HttpSource;
use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile;
use crate::s9pk::merkle_archive::source::ArchiveSource;
use crate::util::io::open_file;
use crate::util::serde::Base64;
@@ -101,10 +101,10 @@ async fn add_asset(
commitment,
}: AddAssetParams,
accessor: impl FnOnce(
&mut Model<OsVersionInfo>,
) -> &mut Model<BTreeMap<InternedString, RegistryAsset<Blake3Commitment>>>
+ UnwindSafe
+ Send,
&mut Model<OsVersionInfo>,
) -> &mut Model<BTreeMap<InternedString, RegistryAsset<Blake3Commitment>>>
+ UnwindSafe
+ Send,
) -> Result<(), Error> {
signer
.scheme()
@@ -207,7 +207,7 @@ pub async fn cli_add_asset(
return Err(Error::new(
eyre!("Unknown extension"),
ErrorKind::InvalidRequest,
))
));
}
};
@@ -302,10 +302,10 @@ async fn remove_asset(
signer,
}: RemoveAssetParams,
accessor: impl FnOnce(
&mut Model<OsVersionInfo>,
) -> &mut Model<BTreeMap<InternedString, RegistryAsset<Blake3Commitment>>>
+ UnwindSafe
+ Send,
&mut Model<OsVersionInfo>,
) -> &mut Model<BTreeMap<InternedString, RegistryAsset<Blake3Commitment>>>
+ UnwindSafe
+ Send,
) -> Result<(), Error> {
ctx.db
.mutate(|db| {

View File

@@ -5,9 +5,9 @@ use std::path::{Path, PathBuf};
use clap::Parser;
use exver::Version;
use helpers::AtomicFile;
use imbl_value::{json, InternedString};
use imbl_value::{InternedString, json};
use itertools::Itertools;
use rpc_toolkit::{from_fn_async, Context, HandlerArgs, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -16,11 +16,11 @@ use crate::prelude::*;
use crate::progress::{FullProgressTracker, ProgressUnits};
use crate::registry::asset::RegistryAsset;
use crate::registry::context::RegistryContext;
use crate::registry::os::index::OsVersionInfo;
use crate::registry::os::SIG_CONTEXT;
use crate::sign::commitment::blake3::Blake3Commitment;
use crate::sign::commitment::Commitment;
use crate::registry::os::index::OsVersionInfo;
use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile;
use crate::sign::commitment::Commitment;
use crate::sign::commitment::blake3::Blake3Commitment;
use crate::util::io::open_file;
pub fn get_api<C: Context>() -> ParentHandler<C> {
@@ -62,10 +62,10 @@ async fn get_os_asset(
ctx: RegistryContext,
GetOsAssetParams { version, platform }: GetOsAssetParams,
accessor: impl FnOnce(
&Model<OsVersionInfo>,
) -> &Model<BTreeMap<InternedString, RegistryAsset<Blake3Commitment>>>
+ UnwindSafe
+ Send,
&Model<OsVersionInfo>,
) -> &Model<BTreeMap<InternedString, RegistryAsset<Blake3Commitment>>>
+ UnwindSafe
+ Send,
) -> Result<RegistryAsset<Blake3Commitment>, Error> {
accessor(
ctx.db

View File

@@ -1,4 +1,4 @@
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
pub mod add;
pub mod get;

View File

@@ -6,7 +6,7 @@ use clap::Parser;
use exver::Version;
use imbl_value::InternedString;
use itertools::Itertools;
use rpc_toolkit::{from_fn_async, Context, HandlerArgs, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -15,13 +15,13 @@ use crate::prelude::*;
use crate::progress::FullProgressTracker;
use crate::registry::asset::RegistryAsset;
use crate::registry::context::RegistryContext;
use crate::registry::os::index::OsVersionInfo;
use crate::registry::os::SIG_CONTEXT;
use crate::registry::os::index::OsVersionInfo;
use crate::s9pk::merkle_archive::source::ArchiveSource;
use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile;
use crate::sign::commitment::blake3::Blake3Commitment;
use crate::sign::ed25519::Ed25519;
use crate::sign::{AnySignature, AnyVerifyingKey, SignatureScheme};
use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile;
use crate::s9pk::merkle_archive::source::ArchiveSource;
use crate::util::io::open_file;
use crate::util::serde::Base64;
@@ -70,10 +70,10 @@ async fn sign_asset(
signature,
}: SignAssetParams,
accessor: impl FnOnce(
&mut Model<OsVersionInfo>,
) -> &mut Model<BTreeMap<InternedString, RegistryAsset<Blake3Commitment>>>
+ UnwindSafe
+ Send,
&mut Model<OsVersionInfo>,
) -> &mut Model<BTreeMap<InternedString, RegistryAsset<Blake3Commitment>>>
+ UnwindSafe
+ Send,
) -> Result<(), Error> {
ctx.db
.mutate(|db| {
@@ -165,7 +165,7 @@ pub async fn cli_sign_asset(
return Err(Error::new(
eyre!("Unknown extension"),
ErrorKind::InvalidRequest,
))
));
}
};

View File

@@ -1,4 +1,4 @@
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use crate::context::CliContext;
use crate::util::serde::HandlerExtSerde;

View File

@@ -5,7 +5,7 @@ use clap::Parser;
use exver::{Version, VersionRange};
use imbl_value::InternedString;
use itertools::Itertools;
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -15,7 +15,7 @@ use crate::registry::context::RegistryContext;
use crate::registry::device_info::DeviceInfo;
use crate::registry::os::index::OsVersionInfo;
use crate::sign::AnyVerifyingKey;
use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat};
use crate::util::serde::{HandlerExtSerde, WithIoFormat, display_serializable};
pub mod signer;

View File

@@ -2,7 +2,7 @@ use std::collections::BTreeMap;
use clap::Parser;
use exver::Version;
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;

View File

@@ -15,13 +15,13 @@ use crate::prelude::*;
use crate::progress::{FullProgressTracker, ProgressTrackerWriter, ProgressUnits};
use crate::registry::context::RegistryContext;
use crate::registry::package::index::PackageVersionInfo;
use crate::s9pk::S9pk;
use crate::s9pk::merkle_archive::source::ArchiveSource;
use crate::s9pk::merkle_archive::source::http::HttpSource;
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::s9pk::merkle_archive::source::http::HttpSource;
use crate::s9pk::merkle_archive::source::ArchiveSource;
use crate::s9pk::v2::SIG_CONTEXT;
use crate::s9pk::S9pk;
use crate::util::io::TrackingIO;
#[derive(Debug, Deserialize, Serialize, TS)]

View File

@@ -3,7 +3,7 @@ use std::collections::BTreeMap;
use clap::Parser;
use imbl_value::InternedString;
use models::PackageId;
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -11,7 +11,7 @@ use crate::context::CliContext;
use crate::prelude::*;
use crate::registry::context::RegistryContext;
use crate::registry::package::index::Category;
use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat};
use crate::util::serde::{HandlerExtSerde, WithIoFormat, display_serializable};
pub fn category_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new()

View File

@@ -12,8 +12,8 @@ use crate::prelude::*;
use crate::registry::context::RegistryContext;
use crate::registry::device_info::DeviceInfo;
use crate::registry::package::index::{PackageIndex, PackageVersionInfo};
use crate::util::serde::{display_serializable, WithIoFormat};
use crate::util::VersionString;
use crate::util::serde::{WithIoFormat, display_serializable};
#[derive(
Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS, ValueEnum,

View File

@@ -13,10 +13,10 @@ use crate::registry::asset::RegistryAsset;
use crate::registry::context::RegistryContext;
use crate::registry::device_info::DeviceInfo;
use crate::rpc_continuations::Guid;
use crate::s9pk::S9pk;
use crate::s9pk::git_hash::GitHash;
use crate::s9pk::manifest::{Alerts, Description, HardwareRequirements};
use crate::s9pk::merkle_archive::source::FileSource;
use crate::s9pk::S9pk;
use crate::sign::commitment::merkle_archive::MerkleArchiveCommitment;
use crate::sign::{AnySignature, AnyVerifyingKey};

View File

@@ -1,4 +1,4 @@
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use crate::context::CliContext;
use crate::prelude::*;

View File

@@ -2,7 +2,7 @@ use std::collections::BTreeMap;
use clap::Parser;
use models::PackageId;
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use serde::{Deserialize, Serialize};
use ts_rs::TS;

View File

@@ -5,8 +5,8 @@ use std::sync::Mutex as SyncMutex;
use std::task::{Context, Poll};
use std::time::Duration;
use axum::extract::ws::WebSocket;
use axum::extract::Request;
use axum::extract::ws::WebSocket;
use axum::response::Response;
use clap::builder::ValueParserFactory;
use futures::future::BoxFuture;
@@ -14,7 +14,7 @@ use futures::{Future, FutureExt};
use helpers::TimedResource;
use imbl_value::InternedString;
use models::FromStrParser;
use tokio::sync::{broadcast, Mutex as AsyncMutex};
use tokio::sync::{Mutex as AsyncMutex, broadcast};
use ts_rs::TS;
#[allow(unused_imports)]

View File

@@ -4,20 +4,20 @@ use std::path::{Path, PathBuf};
use std::sync::Arc;
use blake3::Hash;
use futures::future::BoxFuture;
use futures::FutureExt;
use futures::future::BoxFuture;
use imbl::OrdMap;
use imbl_value::InternedString;
use itertools::Itertools;
use tokio::io::AsyncRead;
use crate::CAP_10_MiB;
use crate::prelude::*;
use crate::s9pk::merkle_archive::sink::Sink;
use crate::s9pk::merkle_archive::source::{ArchiveSource, DynFileSource, FileSource, Section};
use crate::s9pk::merkle_archive::write_queue::WriteQueue;
use crate::s9pk::merkle_archive::{varint, Entry, EntryContents};
use crate::s9pk::merkle_archive::{Entry, EntryContents, varint};
use crate::util::io::{ParallelBlake3Writer, TrackingIO};
use crate::CAP_10_MiB;
#[derive(Clone)]
pub struct DirectoryContents<S> {
@@ -145,7 +145,12 @@ impl<S: Clone> DirectoryContents<S> {
{
dir = d;
} else {
return Err(Error::new(eyre!("failed to insert entry at path {path:?}: ancestor exists and is not a directory"), ErrorKind::Pack));
return Err(Error::new(
eyre!(
"failed to insert entry at path {path:?}: ancestor exists and is not a directory"
),
ErrorKind::Pack,
));
}
}
dir.insert(file.into(), entry);

View File

@@ -2,9 +2,9 @@ use std::ffi::OsStr;
use std::path::Path;
use crate::prelude::*;
use crate::s9pk::merkle_archive::Entry;
use crate::s9pk::merkle_archive::directory_contents::DirectoryContents;
use crate::s9pk::merkle_archive::source::FileSource;
use crate::s9pk::merkle_archive::Entry;
/// An object for tracking the files expected to be in an s9pk
pub struct Expected<'a, T> {

View File

@@ -1,11 +1,11 @@
use blake3::Hash;
use tokio::io::AsyncRead;
use crate::CAP_10_MiB;
use crate::prelude::*;
use crate::s9pk::merkle_archive::sink::Sink;
use crate::s9pk::merkle_archive::source::{ArchiveSource, DynFileSource, FileSource, Section};
use crate::util::io::{ParallelBlake3Writer, TrackingIO};
use crate::CAP_10_MiB;
#[derive(Debug, Clone)]
pub struct FileContents<S>(S);

View File

@@ -4,9 +4,9 @@ use blake3::Hash;
use tokio::io::AsyncWrite;
use tokio_util::either::Either;
use crate::CAP_10_MiB;
use crate::prelude::*;
use crate::util::io::{ParallelBlake3Writer, TeeWriter};
use crate::CAP_10_MiB;
#[pin_project::pin_project]
pub struct VerifyingWriter<W> {

View File

@@ -6,17 +6,17 @@ use imbl_value::InternedString;
use sha2::{Digest, Sha512};
use tokio::io::AsyncRead;
use crate::CAP_1_MiB;
use crate::prelude::*;
use crate::sign::commitment::merkle_archive::MerkleArchiveCommitment;
use crate::sign::ed25519::Ed25519;
use crate::sign::SignatureScheme;
use crate::s9pk::merkle_archive::directory_contents::DirectoryContents;
use crate::s9pk::merkle_archive::file_contents::FileContents;
use crate::s9pk::merkle_archive::sink::Sink;
use crate::s9pk::merkle_archive::source::{ArchiveSource, DynFileSource, FileSource, Section};
use crate::s9pk::merkle_archive::write_queue::WriteQueue;
use crate::sign::SignatureScheme;
use crate::sign::commitment::merkle_archive::MerkleArchiveCommitment;
use crate::sign::ed25519::Ed25519;
use crate::util::serde::Base64;
use crate::CAP_1_MiB;
pub mod directory_contents;
pub mod expected;
@@ -128,7 +128,9 @@ impl<S: ArchiveSource + Clone> MerkleArchive<Section<S>> {
} else {
if max_size > CAP_1_MiB as u64 {
return Err(Error::new(
eyre!("root directory max size over 1MiB, cancelling download in case of DOS attack"),
eyre!(
"root directory max size over 1MiB, cancelling download in case of DOS attack"
),
ErrorKind::InvalidSignature,
));
}

View File

@@ -12,8 +12,8 @@ use tokio_util::io::StreamReader;
use crate::prelude::*;
use crate::s9pk::merkle_archive::source::ArchiveSource;
use crate::util::io::TrackingIO;
use crate::util::Apply;
use crate::util::io::TrackingIO;
pub struct HttpSource {
url: Url,

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