From 313e415ee955176032bc0e354984ff468463dbf1 Mon Sep 17 00:00:00 2001 From: Aiden McClelland Date: Mon, 8 Apr 2024 14:01:16 -0600 Subject: [PATCH 1/4] miscellaneous bugfixes --- core/startos/bindings/GetServicePortForwardParams.ts | 2 ++ core/startos/src/db/mod.rs | 2 +- core/startos/src/s9pk/v1/manifest.rs | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core/startos/bindings/GetServicePortForwardParams.ts b/core/startos/bindings/GetServicePortForwardParams.ts index 3de7e0219..70d69c674 100644 --- a/core/startos/bindings/GetServicePortForwardParams.ts +++ b/core/startos/bindings/GetServicePortForwardParams.ts @@ -1,6 +1,8 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { HostId } from "./HostId"; export type GetServicePortForwardParams = { packageId: string | null; internalPort: number; + hostId: HostId; }; diff --git a/core/startos/src/db/mod.rs b/core/startos/src/db/mod.rs index ab5d23efb..95e42f46b 100644 --- a/core/startos/src/db/mod.rs +++ b/core/startos/src/db/mod.rs @@ -324,7 +324,7 @@ pub struct UiParams { // #[command(display(display_serializable))] #[instrument(skip_all)] pub async fn ui(ctx: RpcContext, UiParams { pointer, value, .. }: UiParams) -> Result<(), Error> { - let ptr = "/ui" + let ptr = "/public/ui" .parse::() .with_kind(ErrorKind::Database)? + &pointer; diff --git a/core/startos/src/s9pk/v1/manifest.rs b/core/startos/src/s9pk/v1/manifest.rs index ef346ad2b..264843766 100644 --- a/core/startos/src/s9pk/v1/manifest.rs +++ b/core/startos/src/s9pk/v1/manifest.rs @@ -19,7 +19,7 @@ fn current_version() -> Version { } #[derive(Clone, Debug, Deserialize, Serialize, HasModel)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all = "kebab-case")] #[model = "Model"] pub struct Manifest { #[serde(default = "current_version")] @@ -54,7 +54,7 @@ pub struct Manifest { } #[derive(Clone, Debug, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all = "kebab-case")] #[serde(tag = "type")] pub enum DependencyRequirement { OptIn { how: String }, @@ -68,7 +68,7 @@ impl DependencyRequirement { } #[derive(Clone, Debug, Deserialize, Serialize, HasModel)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all = "kebab-case")] #[model = "Model"] pub struct DepInfo { pub version: VersionRange, @@ -77,7 +77,7 @@ pub struct DepInfo { } #[derive(Clone, Debug, Default, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all = "kebab-case")] pub struct Assets { #[serde(default)] pub license: Option, From f07992c09135267c79c7c0ae305fbe04a1cda0c9 Mon Sep 17 00:00:00 2001 From: Aiden McClelland Date: Tue, 9 Apr 2024 14:04:31 -0600 Subject: [PATCH 2/4] misc fixes --- core/startos/bindings/ServerInfo.ts | 2 +- core/startos/bindings/WifiInfo.ts | 1 + core/startos/src/backup/restore.rs | 6 +++++- core/startos/src/db/model/mod.rs | 5 ++--- core/startos/src/db/model/public.rs | 10 +++++---- core/startos/src/net/vhost.rs | 21 +++++++++++++++---- core/startos/src/properties.rs | 7 +++++-- core/startos/src/setup.rs | 6 +++++- .../ui/src/app/services/api/mock-patch.ts | 1 + 9 files changed, 43 insertions(+), 16 deletions(-) diff --git a/core/startos/bindings/ServerInfo.ts b/core/startos/bindings/ServerInfo.ts index e505c84e7..130a5bafe 100644 --- a/core/startos/bindings/ServerInfo.ts +++ b/core/startos/bindings/ServerInfo.ts @@ -24,7 +24,7 @@ export type ServerInfo = { torAddress: string; ipInfo: { [key: string]: IpInfo }; statusInfo: ServerStatus; - wifi: WifiInfo; + wifi: WifiInfo | null; unreadNotificationCount: number; passwordHash: string; pubkey: string; diff --git a/core/startos/bindings/WifiInfo.ts b/core/startos/bindings/WifiInfo.ts index c949b1e76..59b1b901d 100644 --- a/core/startos/bindings/WifiInfo.ts +++ b/core/startos/bindings/WifiInfo.ts @@ -1,6 +1,7 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. export type WifiInfo = { + interface: string; ssids: Array; selected: string | null; connected: string | null; diff --git a/core/startos/src/backup/restore.rs b/core/startos/src/backup/restore.rs index 4753a4290..41aaeca7b 100644 --- a/core/startos/src/backup/restore.rs +++ b/core/startos/src/backup/restore.rs @@ -96,7 +96,11 @@ pub async fn recover_full_embassy( .with_kind(ErrorKind::PasswordHashGeneration)?; let db = ctx.db().await?; - db.put(&ROOT, &Database::init(&os_backup.account)?).await?; + db.put( + &ROOT, + &Database::init(&os_backup.account, ctx.config.wifi_interface.clone())?, + ) + .await?; drop(db); init(&ctx.config).await?; diff --git a/core/startos/src/db/model/mod.rs b/core/startos/src/db/model/mod.rs index 9be0f8b68..8b959cdfd 100644 --- a/core/startos/src/db/model/mod.rs +++ b/core/startos/src/db/model/mod.rs @@ -2,7 +2,6 @@ use std::collections::BTreeMap; use patch_db::HasModel; use serde::{Deserialize, Serialize}; -use ts_rs::TS; use crate::account::AccountInfo; use crate::auth::Sessions; @@ -28,9 +27,9 @@ pub struct Database { pub private: Private, } impl Database { - pub fn init(account: &AccountInfo) -> Result { + pub fn init(account: &AccountInfo, wifi_interface: Option) -> Result { Ok(Self { - public: Public::init(account)?, + public: Public::init(account, wifi_interface)?, private: Private { key_store: KeyStore::new(account)?, password: account.password.clone(), diff --git a/core/startos/src/db/model/public.rs b/core/startos/src/db/model/public.rs index d1eec5443..5b83eb74d 100644 --- a/core/startos/src/db/model/public.rs +++ b/core/startos/src/db/model/public.rs @@ -35,7 +35,7 @@ pub struct Public { pub ui: Value, } impl Public { - pub fn init(account: &AccountInfo) -> Result { + pub fn init(account: &AccountInfo, wifi_interface: Option) -> Result { let lan_address = account.hostname.lan_address().parse().unwrap(); Ok(Self { server_info: ServerInfo { @@ -60,11 +60,12 @@ impl Public { shutting_down: false, restarting: false, }, - wifi: WifiInfo { + wifi: wifi_interface.map(|interface| WifiInfo { + interface, ssids: Vec::new(), connected: None, selected: None, - }, + }), unread_notification_count: 0, password_hash: account.password.clone(), pubkey: ssh_key::PublicKey::from(&account.ssh_key) @@ -131,7 +132,7 @@ pub struct ServerInfo { pub ip_info: BTreeMap, #[serde(default)] pub status_info: ServerStatus, - pub wifi: WifiInfo, + pub wifi: Option, #[ts(type = "number")] pub unread_notification_count: u64, pub password_hash: String, @@ -206,6 +207,7 @@ pub struct UpdateProgress { #[model = "Model"] #[ts(export)] pub struct WifiInfo { + pub interface: String, pub ssids: Vec, pub selected: Option, pub connected: Option, diff --git a/core/startos/src/net/vhost.rs b/core/startos/src/net/vhost.rs index 46838ed51..47cf30ad5 100644 --- a/core/startos/src/net/vhost.rs +++ b/core/startos/src/net/vhost.rs @@ -111,7 +111,7 @@ impl VHostServer { _thread: tokio::spawn(async move { loop { match listener.accept().await { - Ok((stream, sock_addr)) => { + Ok((stream, _)) => { let stream = Box::pin(TimeoutStream::new(stream, Duration::from_secs(300))); let mut stream = BackTrackingReader::new(stream); @@ -195,9 +195,22 @@ impl VHostServer { .as_ref() .into_iter() .map(InternedString::intern) - .chain(std::iter::once(InternedString::from_display( - &sock_addr.ip(), - ))) + .chain( + db.peek() + .await + .into_public() + .into_server_info() + .into_ip_info() + .into_entries()? + .into_iter() + .flat_map(|(_, ips)| [ + ips.as_ipv4().de().map(|ip| ip.map(IpAddr::V4)), + ips.as_ipv6().de().map(|ip| ip.map(IpAddr::V6)) + ]) + .filter_map(|a| a.transpose()) + .map(|a| a.map(|ip| InternedString::from_display(&ip))) + .collect::, _>>()?, + ) .collect(); let key = db .mutate(|v| { diff --git a/core/startos/src/properties.rs b/core/startos/src/properties.rs index 5aa8a01d4..f8753ab10 100644 --- a/core/startos/src/properties.rs +++ b/core/startos/src/properties.rs @@ -1,5 +1,5 @@ use clap::Parser; -use imbl_value::Value; +use imbl_value::{json, Value}; use models::PackageId; use rpc_toolkit::command; use serde::{Deserialize, Serialize}; @@ -24,7 +24,10 @@ pub async fn properties( PropertiesParam { id }: PropertiesParam, ) -> Result { match &*ctx.services.get(&id).await { - Some(service) => service.properties().await, + Some(service) => Ok(json!({ + "version": 2, + "data": service.properties().await? + })), None => Err(Error::new( eyre!("Could not find a service with id {id}"), ErrorKind::NotFound, diff --git a/core/startos/src/setup.rs b/core/startos/src/setup.rs index 9120544e3..b8b761e69 100644 --- a/core/startos/src/setup.rs +++ b/core/startos/src/setup.rs @@ -419,7 +419,11 @@ async fn fresh_setup( ) -> Result<(Hostname, OnionAddressV3, X509), Error> { let account = AccountInfo::new(start_os_password, root_ca_start_time().await?)?; let db = ctx.db().await?; - db.put(&ROOT, &Database::init(&account)?).await?; + db.put( + &ROOT, + &Database::init(&account, ctx.config.wifi_interface.clone())?, + ) + .await?; drop(db); init(&ctx.config).await?; Ok(( diff --git a/web/projects/ui/src/app/services/api/mock-patch.ts b/web/projects/ui/src/app/services/api/mock-patch.ts index 8a3f714d1..446bf2424 100644 --- a/web/projects/ui/src/app/services/api/mock-patch.ts +++ b/web/projects/ui/src/app/services/api/mock-patch.ts @@ -76,6 +76,7 @@ export const mockPatchData: DataModel = { zram: true, governor: 'performance', wifi: { + interface: 'wlan0', ssids: [], selected: null, connected: null, From e9166c4a7dd20c9a8ed27c6194b8e35a73eabe48 Mon Sep 17 00:00:00 2001 From: Aiden McClelland Date: Tue, 9 Apr 2024 15:24:05 -0600 Subject: [PATCH 3/4] fix wifi types --- core/startos/bindings/ServerInfo.ts | 6 +- core/startos/bindings/WifiInfo.ts | 4 +- core/startos/src/backup/restore.rs | 6 +- core/startos/src/context/config.rs | 3 - core/startos/src/context/rpc.rs | 9 +-- core/startos/src/db/model/mod.rs | 4 +- core/startos/src/db/model/public.rs | 26 +++---- core/startos/src/init.rs | 15 ++-- core/startos/src/net/wifi.rs | 71 +++++++++++++++---- core/startos/src/os_install/mod.rs | 4 +- core/startos/src/setup.rs | 6 +- .../ui/src/app/services/api/mock-patch.ts | 3 +- 12 files changed, 85 insertions(+), 72 deletions(-) diff --git a/core/startos/bindings/ServerInfo.ts b/core/startos/bindings/ServerInfo.ts index 130a5bafe..618d396fd 100644 --- a/core/startos/bindings/ServerInfo.ts +++ b/core/startos/bindings/ServerInfo.ts @@ -11,10 +11,6 @@ export type ServerInfo = { hostname: string; version: string; lastBackup: string | null; - /** - * Used in the wifi to determine the region to set the system to - */ - lastWifiRegion: string | null; eosVersionCompat: string; lanAddress: string; onionAddress: string; @@ -24,7 +20,7 @@ export type ServerInfo = { torAddress: string; ipInfo: { [key: string]: IpInfo }; statusInfo: ServerStatus; - wifi: WifiInfo | null; + wifi: WifiInfo; unreadNotificationCount: number; passwordHash: string; pubkey: string; diff --git a/core/startos/bindings/WifiInfo.ts b/core/startos/bindings/WifiInfo.ts index 59b1b901d..812cc431f 100644 --- a/core/startos/bindings/WifiInfo.ts +++ b/core/startos/bindings/WifiInfo.ts @@ -1,8 +1,8 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. export type WifiInfo = { - interface: string; + interface: string | null; ssids: Array; selected: string | null; - connected: string | null; + lastRegion: string | null; }; diff --git a/core/startos/src/backup/restore.rs b/core/startos/src/backup/restore.rs index 41aaeca7b..4753a4290 100644 --- a/core/startos/src/backup/restore.rs +++ b/core/startos/src/backup/restore.rs @@ -96,11 +96,7 @@ pub async fn recover_full_embassy( .with_kind(ErrorKind::PasswordHashGeneration)?; let db = ctx.db().await?; - db.put( - &ROOT, - &Database::init(&os_backup.account, ctx.config.wifi_interface.clone())?, - ) - .await?; + db.put(&ROOT, &Database::init(&os_backup.account)?).await?; drop(db); init(&ctx.config).await?; diff --git a/core/startos/src/context/config.rs b/core/startos/src/context/config.rs index 55065e816..0e6d9feff 100644 --- a/core/startos/src/context/config.rs +++ b/core/startos/src/context/config.rs @@ -91,8 +91,6 @@ impl ClientConfig { pub struct ServerConfig { #[arg(short = 'c', long = "config")] pub config: Option, - #[arg(long = "wifi-interface")] - pub wifi_interface: Option, #[arg(long = "ethernet-interface")] pub ethernet_interface: Option, #[arg(skip)] @@ -117,7 +115,6 @@ impl ContextConfig for ServerConfig { self.config.take() } fn merge_with(&mut self, other: Self) { - self.wifi_interface = self.wifi_interface.take().or(other.wifi_interface); self.ethernet_interface = self.ethernet_interface.take().or(other.ethernet_interface); self.os_partitions = self.os_partitions.take().or(other.os_partitions); self.bind_rpc = self.bind_rpc.take().or(other.bind_rpc); diff --git a/core/startos/src/context/rpc.rs b/core/startos/src/context/rpc.rs index a51e23b08..5adab5e58 100644 --- a/core/startos/src/context/rpc.rs +++ b/core/startos/src/context/rpc.rs @@ -26,7 +26,7 @@ use crate::init::check_time_is_synchronized; use crate::lxc::{LxcContainer, LxcManager}; use crate::middleware::auth::HashSessionToken; use crate::net::net_controller::NetController; -use crate::net::utils::find_eth_iface; +use crate::net::utils::{find_eth_iface, find_wifi_iface}; use crate::net::wifi::WpaCli; use crate::prelude::*; use crate::service::ServiceMap; @@ -132,6 +132,8 @@ impl RpcContext { }); } + let wifi_interface = find_wifi_iface().await?; + let seed = Arc::new(RpcContextSeed { is_closed: AtomicBool::new(false), datadir: config.datadir().to_path_buf(), @@ -141,7 +143,7 @@ impl RpcContext { ErrorKind::Filesystem, ) })?, - wifi_interface: config.wifi_interface.clone(), + wifi_interface: wifi_interface.clone(), ethernet_interface: if let Some(eth) = config.ethernet_interface.clone() { eth } else { @@ -158,8 +160,7 @@ impl RpcContext { lxc_manager: Arc::new(LxcManager::new()), open_authed_websockets: Mutex::new(BTreeMap::new()), rpc_stream_continuations: Mutex::new(BTreeMap::new()), - wifi_manager: config - .wifi_interface + wifi_manager: wifi_interface .clone() .map(|i| Arc::new(RwLock::new(WpaCli::init(i)))), current_secret: Arc::new( diff --git a/core/startos/src/db/model/mod.rs b/core/startos/src/db/model/mod.rs index 8b959cdfd..cae1bfe51 100644 --- a/core/startos/src/db/model/mod.rs +++ b/core/startos/src/db/model/mod.rs @@ -27,9 +27,9 @@ pub struct Database { pub private: Private, } impl Database { - pub fn init(account: &AccountInfo, wifi_interface: Option) -> Result { + pub fn init(account: &AccountInfo) -> Result { Ok(Self { - public: Public::init(account, wifi_interface)?, + public: Public::init(account)?, private: Private { key_store: KeyStore::new(account)?, password: account.password.clone(), diff --git a/core/startos/src/db/model/public.rs b/core/startos/src/db/model/public.rs index 5b83eb74d..a51303cf4 100644 --- a/core/startos/src/db/model/public.rs +++ b/core/startos/src/db/model/public.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::net::{Ipv4Addr, Ipv6Addr}; use chrono::{DateTime, Utc}; @@ -35,7 +35,7 @@ pub struct Public { pub ui: Value, } impl Public { - pub fn init(account: &AccountInfo, wifi_interface: Option) -> Result { + pub fn init(account: &AccountInfo) -> Result { let lan_address = account.hostname.lan_address().parse().unwrap(); Ok(Self { server_info: ServerInfo { @@ -45,7 +45,6 @@ impl Public { version: Current::new().semver().into(), hostname: account.hostname.no_dot_host_name(), last_backup: None, - last_wifi_region: None, eos_version_compat: Current::new().compat().clone(), lan_address, onion_address: account.tor_key.public().get_onion_address(), @@ -60,12 +59,7 @@ impl Public { shutting_down: false, restarting: false, }, - wifi: wifi_interface.map(|interface| WifiInfo { - interface, - ssids: Vec::new(), - connected: None, - selected: None, - }), + wifi: WifiInfo::default(), unread_notification_count: 0, password_hash: account.password.clone(), pubkey: ssh_key::PublicKey::from(&account.ssh_key) @@ -117,9 +111,6 @@ pub struct ServerInfo { pub version: Version, #[ts(type = "string | null")] pub last_backup: Option>, - /// Used in the wifi to determine the region to set the system to - #[ts(type = "string | null")] - pub last_wifi_region: Option, #[ts(type = "string")] pub eos_version_compat: VersionRange, #[ts(type = "string")] @@ -132,7 +123,7 @@ pub struct ServerInfo { pub ip_info: BTreeMap, #[serde(default)] pub status_info: ServerStatus, - pub wifi: Option, + pub wifi: WifiInfo, #[ts(type = "number")] pub unread_notification_count: u64, pub password_hash: String, @@ -202,15 +193,16 @@ pub struct UpdateProgress { pub downloaded: u64, } -#[derive(Debug, Deserialize, Serialize, HasModel, TS)] +#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)] #[serde(rename_all = "camelCase")] #[model = "Model"] #[ts(export)] pub struct WifiInfo { - pub interface: String, - pub ssids: Vec, + pub interface: Option, + pub ssids: BTreeSet, pub selected: Option, - pub connected: Option, + #[ts(type = "string | null")] + pub last_region: Option, } #[derive(Debug, Deserialize, Serialize, TS)] diff --git a/core/startos/src/init.rs b/core/startos/src/init.rs index d1d5a9943..3f7d7f1bc 100644 --- a/core/startos/src/init.rs +++ b/core/startos/src/init.rs @@ -232,15 +232,12 @@ pub async fn init(cfg: &ServerConfig) -> Result { .invoke(crate::ErrorKind::OpenSsl) .await?; - if let Some(wifi_interface) = &cfg.wifi_interface { - crate::net::wifi::synchronize_wpa_supplicant_conf( - &cfg.datadir().join("main"), - wifi_interface, - &server_info.last_wifi_region, - ) - .await?; - tracing::info!("Synchronized WiFi"); - } + crate::net::wifi::synchronize_wpa_supplicant_conf( + &cfg.datadir().join("main"), + &mut server_info.wifi, + ) + .await?; + tracing::info!("Synchronized WiFi"); let should_rebuild = tokio::fs::metadata(SYSTEM_REBUILD_PATH).await.is_ok() || &*server_info.version < &emver::Version::new(0, 3, 2, 0) diff --git a/core/startos/src/net/wifi.rs b/core/startos/src/net/wifi.rs index 9de177bfe..93f610a42 100644 --- a/core/startos/src/net/wifi.rs +++ b/core/startos/src/net/wifi.rs @@ -16,6 +16,8 @@ use tracing::instrument; use ts_rs::TS; use crate::context::{CliContext, RpcContext}; +use crate::db::model::public::WifiInfo; +use crate::net::utils::find_wifi_iface; use crate::prelude::*; use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat}; use crate::util::Invoke; @@ -137,6 +139,18 @@ pub async fn add(ctx: RpcContext, AddParams { ssid, password }: AddParams) -> Re ErrorKind::Wifi, )); } + ctx.db + .mutate(|db| { + db.as_public_mut() + .as_server_info_mut() + .as_wifi_mut() + .as_ssids_mut() + .mutate(|s| { + s.insert(ssid); + Ok(()) + }) + }) + .await?; Ok(()) } #[derive(Deserialize, Serialize, Parser, TS)] @@ -190,6 +204,17 @@ pub async fn connect(ctx: RpcContext, SsidParams { ssid }: SsidParams) -> Result ErrorKind::Wifi, )); } + + ctx.db + .mutate(|db| { + let wifi = db.as_public_mut().as_server_info_mut().as_wifi_mut(); + wifi.as_ssids_mut().mutate(|s| { + s.insert(ssid.clone()); + Ok(()) + })?; + wifi.as_selected_mut().ser(&Some(ssid)) + }) + .await?; Ok(()) } @@ -215,11 +240,23 @@ pub async fn delete(ctx: RpcContext, SsidParams { ssid }: SsidParams) -> Result< } wpa_supplicant.remove_network(ctx.db.clone(), &ssid).await?; + + ctx.db + .mutate(|db| { + let wifi = db.as_public_mut().as_server_info_mut().as_wifi_mut(); + wifi.as_ssids_mut().mutate(|s| { + s.remove(&ssid.0); + Ok(()) + })?; + wifi.as_selected_mut() + .map_mutate(|s| Ok(s.filter(|s| s == &ssid.0))) + }) + .await?; Ok(()) } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename_all = "camelCase")] -pub struct WiFiInfo { +pub struct WifiListInfo { ssids: HashMap, connected: Option, country: Option, @@ -228,7 +265,7 @@ pub struct WiFiInfo { } #[derive(serde::Serialize, serde::Deserialize, Clone)] #[serde(rename_all = "camelCase")] -pub struct WifiListInfo { +pub struct WifiListInfoLow { strength: SignalStrength, security: Vec, } @@ -239,8 +276,8 @@ pub struct WifiListOut { strength: SignalStrength, security: Vec, } -pub type WifiList = HashMap; -fn display_wifi_info(params: WithIoFormat, info: WiFiInfo) { +pub type WifiList = HashMap; +fn display_wifi_info(params: WithIoFormat, info: WifiListInfo) { use prettytable::*; if let Some(format) = params.format { @@ -330,7 +367,7 @@ fn display_wifi_list(params: WithIoFormat, info: Vec) { // #[command(display(display_wifi_info))] #[instrument(skip_all)] -pub async fn get(ctx: RpcContext, _: Empty) -> Result { +pub async fn get(ctx: RpcContext, _: Empty) -> Result { let wifi_manager = wifi_manager(&ctx)?; let wpa_supplicant = wifi_manager.read().await; let (list_networks, current_res, country_res, ethernet_res, signal_strengths) = tokio::join!( @@ -368,7 +405,7 @@ pub async fn get(ctx: RpcContext, _: Empty) -> Result { }) .collect(); let current = current_res?; - Ok(WiFiInfo { + Ok(WifiListInfo { ssids, connected: current, country: country_res?, @@ -477,7 +514,7 @@ impl SignalStrength { } #[derive(Debug, Clone)] -pub struct WifiInfo { +pub struct WifiInfoLow { ssid: Ssid, device: Option, } @@ -604,7 +641,7 @@ impl WpaCli { Ok(()) } #[instrument(skip_all)] - pub async fn list_networks_low(&self) -> Result, Error> { + pub async fn list_networks_low(&self) -> Result, Error> { let r = Command::new("nmcli") .arg("-t") .arg("c") @@ -623,13 +660,13 @@ impl WpaCli { if !connection_type.contains("wireless") { return None; } - let info = WifiInfo { + let info = WifiInfoLow { ssid: name, device: device.map(|x| x.to_owned()), }; Some((uuid, info)) }) - .collect::>()) + .collect::>()) } #[instrument(skip_all)] @@ -652,7 +689,7 @@ impl WpaCli { values.next()?.split(' ').map(|x| x.to_owned()).collect(); Some(( ssid, - WifiListInfo { + WifiListInfoLow { strength: signal, security, }, @@ -686,7 +723,8 @@ impl WpaCli { db.mutate(|d| { d.as_public_mut() .as_server_info_mut() - .as_last_wifi_region_mut() + .as_wifi_mut() + .as_last_region_mut() .ser(&new_country) }) .await @@ -837,9 +875,12 @@ impl TypedValueParser for CountryCodeParser { #[instrument(skip_all)] pub async fn synchronize_wpa_supplicant_conf>( main_datadir: P, - wifi_iface: &str, - last_country_code: &Option, + wifi: &mut WifiInfo, ) -> Result<(), Error> { + wifi.interface = find_wifi_iface().await?; + let Some(wifi_iface) = &wifi.interface else { + return Ok(()); + }; let persistent = main_datadir.as_ref().join("system-connections"); tracing::debug!("persistent: {:?}", persistent); // let supplicant = Path::new("/etc/wpa_supplicant.conf"); @@ -863,7 +904,7 @@ pub async fn synchronize_wpa_supplicant_conf>( .arg("up") .invoke(ErrorKind::Wifi) .await?; - if let Some(last_country_code) = last_country_code { + if let Some(last_country_code) = wifi.last_region { tracing::info!("Setting the region"); let _ = Command::new("iw") .arg("reg") diff --git a/core/startos/src/os_install/mod.rs b/core/startos/src/os_install/mod.rs index 0abd1d23e..4bbbe70a6 100644 --- a/core/startos/src/os_install/mod.rs +++ b/core/startos/src/os_install/mod.rs @@ -17,7 +17,7 @@ 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, find_wifi_iface}; +use crate::net::utils::find_eth_iface; use crate::util::serde::IoFormat; use crate::util::Invoke; use crate::ARCH; @@ -140,7 +140,6 @@ pub async fn execute( ) })?; let eth_iface = find_eth_iface().await?; - let wifi_iface = find_wifi_iface().await?; overwrite |= disk.guid.is_none() && disk.partitions.iter().all(|p| p.guid.is_none()); @@ -260,7 +259,6 @@ pub async fn execute( IoFormat::Yaml.to_vec(&ServerConfig { os_partitions: Some(part_info.clone()), ethernet_interface: Some(eth_iface), - wifi_interface: wifi_iface, ..Default::default() })?, ) diff --git a/core/startos/src/setup.rs b/core/startos/src/setup.rs index b8b761e69..9120544e3 100644 --- a/core/startos/src/setup.rs +++ b/core/startos/src/setup.rs @@ -419,11 +419,7 @@ async fn fresh_setup( ) -> Result<(Hostname, OnionAddressV3, X509), Error> { let account = AccountInfo::new(start_os_password, root_ca_start_time().await?)?; let db = ctx.db().await?; - db.put( - &ROOT, - &Database::init(&account, ctx.config.wifi_interface.clone())?, - ) - .await?; + db.put(&ROOT, &Database::init(&account)?).await?; drop(db); init(&ctx.config).await?; Ok(( diff --git a/web/projects/ui/src/app/services/api/mock-patch.ts b/web/projects/ui/src/app/services/api/mock-patch.ts index 446bf2424..ed0edacbe 100644 --- a/web/projects/ui/src/app/services/api/mock-patch.ts +++ b/web/projects/ui/src/app/services/api/mock-patch.ts @@ -55,7 +55,6 @@ export const mockPatchData: DataModel = { ipv6Range: 'FE80:CD00:0000:0CDE:1257:0000:211E:729CD/64', }, }, - lastWifiRegion: null, unreadNotificationCount: 4, // password is asdfasdf passwordHash: @@ -79,7 +78,7 @@ export const mockPatchData: DataModel = { interface: 'wlan0', ssids: [], selected: null, - connected: null, + lastRegion: null, }, }, packageData: { From 932b53d92d6118b37faad83190af0cad48a42ca5 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Tue, 9 Apr 2024 21:06:06 -0600 Subject: [PATCH 4/4] deprecate wifi --- web/package-lock.json | 4 +-- .../ui/src/app/app/menu/menu.component.html | 6 +++++ .../ui/src/app/app/menu/menu.component.ts | 2 ++ .../server-show/server-show.page.html | 4 +-- .../server-show/server-show.page.ts | 3 ++- .../pages/server-routes/wifi/wifi.page.html | 27 ++++++++++--------- .../app/pages/server-routes/wifi/wifi.page.ts | 12 ++++++++- 7 files changed, 39 insertions(+), 19 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 90a6ad58d..68156eb21 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "startos-ui", - "version": "0.3.5.1", + "version": "0.3.5.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "startos-ui", - "version": "0.3.5.1", + "version": "0.3.5.2", "dependencies": { "@angular/animations": "^14.1.0", "@angular/common": "^14.1.0", diff --git a/web/projects/ui/src/app/app/menu/menu.component.html b/web/projects/ui/src/app/app/menu/menu.component.html index 6db19dea6..0814c81ad 100644 --- a/web/projects/ui/src/app/app/menu/menu.component.html +++ b/web/projects/ui/src/app/app/menu/menu.component.html @@ -22,6 +22,12 @@ {{ page.title }} +

{{ button.title }}

{{ button.description }}

-

diff --git a/web/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts b/web/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts index b479f1750..73763578e 100644 --- a/web/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts +++ b/web/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts @@ -40,6 +40,7 @@ export class ServerShowPage { readonly server$ = this.patch.watch$('serverInfo') readonly showUpdate$ = this.eosService.showUpdate$ readonly showDiskRepair$ = this.ClientStorageService.showDiskRepair$ + readonly wifiConnected$ = this.patch.watch$('serverInfo', 'wifi', 'selected') constructor( private readonly alertCtrl: AlertController, @@ -553,7 +554,7 @@ export class ServerShowPage { }, { title: 'WiFi', - description: 'Add or remove WiFi networks', + description: 'WiFi is deprecated. Click to learn more.', icon: 'wifi', action: () => this.navCtrl.navigateForward(['wifi'], { relativeTo: this.route }), diff --git a/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.html b/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.html index 011704cc2..08387fcbc 100644 --- a/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.html +++ b/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.html @@ -16,21 +16,22 @@ - + + -

- Adding WiFi credentials to your StartOS allows you to remove the - Ethernet cable and move the device anywhere you want. StartOS will - automatically connect to available networks. - - View instructions - -

+

WiFi is deprecated

+

+ WiFi will be eliminated from StartOS in version v0.4.0, expected soon. + Before then, we highly recommend switching your server to a direct, + Ethernet connection, which is faster and more reliable. If using + Ethernet is not possible for you, we recommend using a WiFi extender + instead. +

+ + Learn More + + Country diff --git a/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.ts b/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.ts index bac270613..e6d5da252 100644 --- a/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.ts +++ b/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core' +import { Component, Inject } from '@angular/core' import { ActionSheetController, AlertController, @@ -14,6 +14,7 @@ import { RR } from 'src/app/services/api/api.types' import { pauseFor, ErrorToastService } from '@start9labs/shared' import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page' import { ConfigService } from 'src/app/services/config.service' +import { WINDOW } from '@ng-web-apis/common' @Component({ selector: 'wifi', @@ -36,12 +37,21 @@ export class WifiPage { private readonly errToast: ErrorToastService, private readonly actionCtrl: ActionSheetController, private readonly config: ConfigService, + @Inject(WINDOW) private readonly windowRef: Window, ) {} async ngOnInit() { await this.getWifi() } + async openDocs() { + this.windowRef.open( + 'https://docs.start9.com/user-manual/wifi.html', + '_blank', + 'noreferrer', + ) + } + async getWifi(timeout: number = 0): Promise { this.loading = true try {