diff --git a/backend/src/backup/os.rs b/backend/src/backup/os.rs index 5cca8532d..74498452c 100644 --- a/backend/src/backup/os.rs +++ b/backend/src/backup/os.rs @@ -1,12 +1,13 @@ +use openssl::pkey::PKey; +use openssl::x509::X509; +use serde::{Deserialize, Serialize}; +use serde_json::Value; + use crate::account::AccountInfo; use crate::hostname::{generate_hostname, generate_id, Hostname}; use crate::net::keys::Key; use crate::util::serde::Base64; use crate::Error; -use openssl::pkey::PKey; -use openssl::x509::X509; -use serde::{Deserialize, Serialize}; -use serde_json::Value; pub struct OsBackup { pub account: AccountInfo, diff --git a/backend/src/backup/restore.rs b/backend/src/backup/restore.rs index 99b84e747..a2083fda3 100644 --- a/backend/src/backup/restore.rs +++ b/backend/src/backup/restore.rs @@ -6,8 +6,8 @@ use std::time::Duration; use clap::ArgMatches; use color_eyre::eyre::eyre; -use futures::{future::BoxFuture, stream}; -use futures::{FutureExt, StreamExt}; +use futures::future::BoxFuture; +use futures::{stream, FutureExt, StreamExt}; use openssl::x509::X509; use patch_db::{DbHandle, PatchDbHandle}; use rpc_toolkit::command; diff --git a/backend/src/context/cli.rs b/backend/src/context/cli.rs index 04b7839fe..25adecdde 100644 --- a/backend/src/context/cli.rs +++ b/backend/src/context/cli.rs @@ -17,12 +17,11 @@ use rpc_toolkit::Context; use serde::Deserialize; use tracing::instrument; +use super::setup::CURRENT_SECRET; use crate::middleware::auth::LOCAL_AUTH_COOKIE_PATH; use crate::util::config::{load_config_from_paths, local_config_path}; use crate::ResultExt; -use super::setup::CURRENT_SECRET; - #[derive(Debug, Default, Deserialize)] #[serde(rename_all = "kebab-case")] pub struct CliContextConfig { diff --git a/backend/src/context/rpc.rs b/backend/src/context/rpc.rs index cf2d59875..16c5297dc 100644 --- a/backend/src/context/rpc.rs +++ b/backend/src/context/rpc.rs @@ -19,11 +19,12 @@ use sqlx::PgPool; use tokio::sync::{broadcast, oneshot, Mutex, RwLock}; use tracing::instrument; +use super::setup::CURRENT_SECRET; use crate::account::AccountInfo; use crate::core::rpc_continuations::{RequestGuid, RestHandler, RpcContinuation}; use crate::db::model::{CurrentDependents, Database, InstalledPackageDataEntry, PackageDataEntry}; use crate::disk::OsPartitionInfo; -use crate::init::{init_postgres, pgloader}; +use crate::init::init_postgres; use crate::install::cleanup::{cleanup_failed, uninstall, CleanupFailedReceipts}; use crate::manager::ManagerMap; use crate::middleware::auth::HashSessionToken; @@ -36,8 +37,6 @@ use crate::status::{MainStatus, Status}; use crate::util::config::load_config_from_paths; use crate::{Error, ErrorKind, ResultExt}; -use super::setup::CURRENT_SECRET; - #[derive(Debug, Default, Deserialize)] #[serde(rename_all = "kebab-case")] pub struct RpcContextConfig { @@ -96,15 +95,6 @@ impl RpcContextConfig { .run(&secret_store) .await .with_kind(crate::ErrorKind::Database)?; - let old_db_path = self.datadir().join("main/secrets.db"); - if tokio::fs::metadata(&old_db_path).await.is_ok() { - pgloader( - &old_db_path, - self.migration_batch_rows.unwrap_or(25000), - self.migration_prefetch_rows.unwrap_or(100_000), - ) - .await?; - } Ok(secret_store) } } diff --git a/backend/src/context/setup.rs b/backend/src/context/setup.rs index 283ac922f..8e516d719 100644 --- a/backend/src/context/setup.rs +++ b/backend/src/context/setup.rs @@ -17,7 +17,7 @@ use tracing::instrument; use crate::account::AccountInfo; use crate::db::model::Database; use crate::disk::OsPartitionInfo; -use crate::init::{init_postgres, pgloader}; +use crate::init::init_postgres; use crate::setup::SetupStatus; use crate::util::config::load_config_from_paths; use crate::{Error, ResultExt}; @@ -132,15 +132,6 @@ impl SetupContext { .run(&secret_store) .await .with_kind(crate::ErrorKind::Database)?; - let old_db_path = self.datadir.join("main/secrets.db"); - if tokio::fs::metadata(&old_db_path).await.is_ok() { - pgloader( - &old_db_path, - self.migration_batch_rows, - self.migration_prefetch_rows, - ) - .await?; - } Ok(secret_store) } } diff --git a/backend/src/init.rs b/backend/src/init.rs index 38192f993..807dcb2e1 100644 --- a/backend/src/init.rs +++ b/backend/src/init.rs @@ -47,6 +47,7 @@ pub struct InitReceipts { pub status_info: LockReceipt, pub ip_info: LockReceipt, ()>, pub system_start_time: LockReceipt, + pub zram: LockReceipt, } impl InitReceipts { pub async fn new(db: &mut impl DbHandle) -> Result { @@ -83,6 +84,11 @@ impl InitReceipts { .system_start_time() .make_locker(LockType::Write) .add_to_keys(&mut locks); + let zram = crate::db::DatabaseModel::new() + .server_info() + .zram() + .make_locker(LockType::Write) + .add_to_keys(&mut locks); let skeleton_key = db.lock_all(locks).await?; Ok(Self { @@ -92,68 +98,11 @@ impl InitReceipts { status_info: status_info.verify(&skeleton_key)?, last_wifi_region: last_wifi_region.verify(&skeleton_key)?, system_start_time: system_start_time.verify(&skeleton_key)?, + zram: zram.verify(&skeleton_key)?, }) } } -pub async fn pgloader( - old_db_path: impl AsRef, - batch_rows: usize, - prefetch_rows: usize, -) -> Result<(), Error> { - tokio::fs::write( - "/etc/embassy/migrate.load", - format!( - include_str!("migrate.load"), - sqlite_path = old_db_path.as_ref().display(), - batch_rows = batch_rows, - prefetch_rows = prefetch_rows - ), - ) - .await?; - match tokio::fs::remove_dir_all("/tmp/pgloader").await { - Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()), - a => a, - }?; - tracing::info!("Running pgloader"); - let out = Command::new("pgloader") - .arg("-v") - .arg("/etc/embassy/migrate.load") - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .await?; - let stdout = String::from_utf8(out.stdout)?; - for line in stdout.lines() { - tracing::debug!("pgloader: {}", line); - } - let stderr = String::from_utf8(out.stderr)?; - for line in stderr.lines() { - tracing::debug!("pgloader err: {}", line); - } - tracing::debug!("pgloader exited with code {:?}", out.status); - if let Some(err) = stdout.lines().chain(stderr.lines()).find_map(|l| { - if l.split_ascii_whitespace() - .any(|word| word == "ERROR" || word == "FATAL") - { - Some(l) - } else { - None - } - }) { - return Err(Error::new( - eyre!("pgloader error: {}", err), - crate::ErrorKind::Database, - )); - } - tokio::fs::rename( - old_db_path.as_ref(), - old_db_path.as_ref().with_extension("bak"), - ) - .await?; - Ok(()) -} - // must be idempotent pub async fn init_postgres(datadir: impl AsRef) -> Result<(), Error> { let db_dir = datadir.as_ref().join("main/postgresql"); @@ -399,6 +348,9 @@ pub async fn init(cfg: &RpcContextConfig) -> Result { tracing::info!("Syncronized system clock"); } + if receipts.zram.get(&mut handle).await? { + crate::system::enable_zram().await? + } receipts .ip_info .set(&mut handle, crate::net::dhcp::init_ips().await?) diff --git a/backend/src/net/static_server.rs b/backend/src/net/static_server.rs index c42c58079..616cd2f39 100644 --- a/backend/src/net/static_server.rs +++ b/backend/src/net/static_server.rs @@ -3,13 +3,11 @@ use std::path::Path; use std::sync::Arc; use std::time::UNIX_EPOCH; -use async_compression::tokio::bufread::BrotliEncoder; -use async_compression::tokio::bufread::GzipEncoder; +use async_compression::tokio::bufread::{BrotliEncoder, GzipEncoder}; use color_eyre::eyre::eyre; use digest::Digest; use futures::FutureExt; -use http::header::ACCEPT_ENCODING; -use http::header::CONTENT_ENCODING; +use http::header::{ACCEPT_ENCODING, CONTENT_ENCODING}; use http::request::Parts as RequestParts; use http::response::Builder; use hyper::{Body, Method, Request, Response, StatusCode}; diff --git a/backend/src/procedure/docker.rs b/backend/src/procedure/docker.rs index afd7ffb7a..bcf350830 100644 --- a/backend/src/procedure/docker.rs +++ b/backend/src/procedure/docker.rs @@ -18,10 +18,8 @@ use nix::unistd::Pid; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use serde_json::Value; -use tokio::{ - io::{AsyncBufRead, AsyncBufReadExt, BufReader}, - time::timeout, -}; +use tokio::io::{AsyncBufRead, AsyncBufReadExt, BufReader}; +use tokio::time::timeout; use tracing::instrument; use super::ProcedureName; diff --git a/backend/src/system.rs b/backend/src/system.rs index 9add66892..c52eeb038 100644 --- a/backend/src/system.rs +++ b/backend/src/system.rs @@ -29,6 +29,34 @@ pub async fn experimental() -> Result<(), Error> { Ok(()) } +pub async fn enable_zram() -> Result<(), Error> { + let mem_info = get_mem_info().await?; + Command::new("modprobe") + .arg("zram") + .invoke(ErrorKind::Zram) + .await?; + tokio::fs::write("/sys/block/zram0/comp_algorithm", "lz4") + .await + .with_kind(ErrorKind::Zram)?; + tokio::fs::write( + "/sys/block/zram0/disksize", + format!("{}M", mem_info.total.0 as u64 / 4), + ) + .await + .with_kind(ErrorKind::Zram)?; + Command::new("mkswap") + .arg("/dev/zram0") + .invoke(ErrorKind::Zram) + .await?; + Command::new("swapon") + .arg("-p") + .arg("5") + .arg("/dev/zram0") + .invoke(ErrorKind::Zram) + .await?; + Ok(()) +} + #[command(display(display_none))] pub async fn zram(#[context] ctx: RpcContext, #[arg] enable: bool) -> Result<(), Error> { let mut db = ctx.db.handle(); @@ -42,30 +70,7 @@ pub async fn zram(#[context] ctx: RpcContext, #[arg] enable: bool) -> Result<(), } *zram = enable; if enable { - let mem_info = get_mem_info().await?; - Command::new("modprobe") - .arg("zram") - .invoke(ErrorKind::Zram) - .await?; - tokio::fs::write("/sys/block/zram0/comp_algorithm", "lz4") - .await - .with_kind(ErrorKind::Zram)?; - tokio::fs::write( - "/sys/block/zram0/disksize", - format!("{}M", mem_info.total.0 as u64 / 4), - ) - .await - .with_kind(ErrorKind::Zram)?; - Command::new("mkswap") - .arg("/dev/zram0") - .invoke(ErrorKind::Zram) - .await?; - Command::new("swapon") - .arg("-p") - .arg("5") - .arg("/dev/zram0") - .invoke(ErrorKind::Zram) - .await?; + enable_zram().await?; } else { Command::new("swapoff") .arg("/dev/zram0") diff --git a/backend/src/version/v0_3_4.rs b/backend/src/version/v0_3_4.rs index 40f8c8228..dee3222e9 100644 --- a/backend/src/version/v0_3_4.rs +++ b/backend/src/version/v0_3_4.rs @@ -5,11 +5,10 @@ use openssl::hash::MessageDigest; use serde_json::{json, Value}; use ssh_key::public::Ed25519PublicKey; -use crate::account::AccountInfo; -use crate::hostname::{generate_hostname, sync_hostname, Hostname}; - use super::v0_3_0::V0_3_0_COMPAT; use super::*; +use crate::account::AccountInfo; +use crate::hostname::{generate_hostname, sync_hostname, Hostname}; const V0_3_4: emver::Version = emver::Version::new(0, 3, 4, 0); diff --git a/libs/embassy_container_init/src/main.rs b/libs/embassy_container_init/src/main.rs index ea0d67343..0764382c0 100644 --- a/libs/embassy_container_init/src/main.rs +++ b/libs/embassy_container_init/src/main.rs @@ -5,8 +5,8 @@ use std::process::Stdio; use std::sync::Arc; use embassy_container_init::{ - OutputParams, OutputStrategy, ProcessGroupId, ProcessId, ReadLineStderrParams, - ReadLineStdoutParams, RunCommandParams, SendSignalParams, SignalGroupParams, LogParams, + LogParams, OutputParams, OutputStrategy, ProcessGroupId, ProcessId, ReadLineStderrParams, + ReadLineStdoutParams, RunCommandParams, SendSignalParams, SignalGroupParams, }; use futures::StreamExt; use helpers::NonDetachingJoinHandle; @@ -219,7 +219,8 @@ impl Handler { let mut child = { self.children .lock() - .await.processes + .await + .processes .get(&pid) .ok_or_else(not_found)? .child @@ -264,7 +265,8 @@ impl Handler { if signal == 9 { self.children .lock() - .await.processes + .await + .processes .remove(&pid) .ok_or_else(not_found)?; } @@ -354,7 +356,6 @@ async fn main() { tokio::spawn(async move { let w = Arc::new(Mutex::new(w)); while let Some(line) = lines.next_line().await.transpose() { - let handler = handler.clone(); let w = w.clone(); tokio::spawn(async move {