mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
fix wifi types
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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<string>;
|
||||
selected: string | null;
|
||||
connected: string | null;
|
||||
lastRegion: string | null;
|
||||
};
|
||||
|
||||
@@ -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?;
|
||||
|
||||
@@ -91,8 +91,6 @@ impl ClientConfig {
|
||||
pub struct ServerConfig {
|
||||
#[arg(short = 'c', long = "config")]
|
||||
pub config: Option<PathBuf>,
|
||||
#[arg(long = "wifi-interface")]
|
||||
pub wifi_interface: Option<String>,
|
||||
#[arg(long = "ethernet-interface")]
|
||||
pub ethernet_interface: Option<String>,
|
||||
#[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);
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -27,9 +27,9 @@ pub struct Database {
|
||||
pub private: Private,
|
||||
}
|
||||
impl Database {
|
||||
pub fn init(account: &AccountInfo, wifi_interface: Option<String>) -> Result<Self, Error> {
|
||||
pub fn init(account: &AccountInfo) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
public: Public::init(account, wifi_interface)?,
|
||||
public: Public::init(account)?,
|
||||
private: Private {
|
||||
key_store: KeyStore::new(account)?,
|
||||
password: account.password.clone(),
|
||||
|
||||
@@ -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<String>) -> Result<Self, Error> {
|
||||
pub fn init(account: &AccountInfo) -> Result<Self, Error> {
|
||||
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<DateTime<Utc>>,
|
||||
/// Used in the wifi to determine the region to set the system to
|
||||
#[ts(type = "string | null")]
|
||||
pub last_wifi_region: Option<CountryCode>,
|
||||
#[ts(type = "string")]
|
||||
pub eos_version_compat: VersionRange,
|
||||
#[ts(type = "string")]
|
||||
@@ -132,7 +123,7 @@ pub struct ServerInfo {
|
||||
pub ip_info: BTreeMap<String, IpInfo>,
|
||||
#[serde(default)]
|
||||
pub status_info: ServerStatus,
|
||||
pub wifi: Option<WifiInfo>,
|
||||
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<Self>"]
|
||||
#[ts(export)]
|
||||
pub struct WifiInfo {
|
||||
pub interface: String,
|
||||
pub ssids: Vec<String>,
|
||||
pub interface: Option<String>,
|
||||
pub ssids: BTreeSet<String>,
|
||||
pub selected: Option<String>,
|
||||
pub connected: Option<String>,
|
||||
#[ts(type = "string | null")]
|
||||
pub last_region: Option<CountryCode>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, TS)]
|
||||
|
||||
@@ -232,15 +232,12 @@ pub async fn init(cfg: &ServerConfig) -> Result<InitResult, Error> {
|
||||
.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)
|
||||
|
||||
@@ -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<Ssid, SignalStrength>,
|
||||
connected: Option<Ssid>,
|
||||
country: Option<CountryCode>,
|
||||
@@ -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<String>,
|
||||
}
|
||||
@@ -239,8 +276,8 @@ pub struct WifiListOut {
|
||||
strength: SignalStrength,
|
||||
security: Vec<String>,
|
||||
}
|
||||
pub type WifiList = HashMap<Ssid, WifiListInfo>;
|
||||
fn display_wifi_info(params: WithIoFormat<Empty>, info: WiFiInfo) {
|
||||
pub type WifiList = HashMap<Ssid, WifiListInfoLow>;
|
||||
fn display_wifi_info(params: WithIoFormat<Empty>, info: WifiListInfo) {
|
||||
use prettytable::*;
|
||||
|
||||
if let Some(format) = params.format {
|
||||
@@ -330,7 +367,7 @@ fn display_wifi_list(params: WithIoFormat<Empty>, info: Vec<WifiListOut>) {
|
||||
|
||||
// #[command(display(display_wifi_info))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get(ctx: RpcContext, _: Empty) -> Result<WiFiInfo, Error> {
|
||||
pub async fn get(ctx: RpcContext, _: Empty) -> Result<WifiListInfo, Error> {
|
||||
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<WiFiInfo, Error> {
|
||||
})
|
||||
.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<String>,
|
||||
}
|
||||
@@ -604,7 +641,7 @@ impl WpaCli {
|
||||
Ok(())
|
||||
}
|
||||
#[instrument(skip_all)]
|
||||
pub async fn list_networks_low(&self) -> Result<BTreeMap<NetworkId, WifiInfo>, Error> {
|
||||
pub async fn list_networks_low(&self) -> Result<BTreeMap<NetworkId, WifiInfoLow>, 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::<BTreeMap<NetworkId, WifiInfo>>())
|
||||
.collect::<BTreeMap<NetworkId, WifiInfoLow>>())
|
||||
}
|
||||
|
||||
#[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<P: AsRef<Path>>(
|
||||
main_datadir: P,
|
||||
wifi_iface: &str,
|
||||
last_country_code: &Option<CountryCode>,
|
||||
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<P: AsRef<Path>>(
|
||||
.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")
|
||||
|
||||
@@ -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()
|
||||
})?,
|
||||
)
|
||||
|
||||
@@ -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((
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user