mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 18:31:52 +00:00
0.3.2 final cleanup (#1782)
* bump version with stubbed release notes * increase BE timeout * 032 release notes * hide developer menu for now * remove unused sub/import * remoce reconnect from disks res in setup wiz * remove quirks * flatten drives response Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use chrono::Utc;
|
||||
use clap::ArgMatches;
|
||||
@@ -8,7 +7,7 @@ use color_eyre::eyre::eyre;
|
||||
use helpers::AtomicFile;
|
||||
use openssl::pkey::{PKey, Private};
|
||||
use openssl::x509::X509;
|
||||
use patch_db::{DbHandle, LockType, PatchDbHandle, Revision};
|
||||
use patch_db::{DbHandle, LockType, PatchDbHandle};
|
||||
use rpc_toolkit::command;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
@@ -9,7 +9,7 @@ use color_eyre::eyre::eyre;
|
||||
use futures::future::BoxFuture;
|
||||
use futures::FutureExt;
|
||||
use openssl::x509::X509;
|
||||
use patch_db::{DbHandle, PatchDbHandle, Revision};
|
||||
use patch_db::{DbHandle, PatchDbHandle};
|
||||
use rpc_toolkit::command;
|
||||
use tokio::fs::File;
|
||||
use tokio::task::JoinHandle;
|
||||
@@ -57,8 +57,7 @@ pub async fn restore_packages_rpc(
|
||||
let backup_guard =
|
||||
BackupMountGuard::mount(TmpMountGuard::mount(&fs, ReadOnly).await?, &password).await?;
|
||||
|
||||
let (revision, backup_guard, tasks, _) =
|
||||
restore_packages(&ctx, &mut db, backup_guard, ids).await?;
|
||||
let (backup_guard, tasks, _) = restore_packages(&ctx, &mut db, backup_guard, ids).await?;
|
||||
|
||||
tokio::spawn(async move {
|
||||
let res = futures::future::join_all(tasks).await;
|
||||
@@ -246,7 +245,7 @@ pub async fn recover_full_embassy(
|
||||
.keys()
|
||||
.cloned()
|
||||
.collect();
|
||||
let (_, backup_guard, tasks, progress_info) = restore_packages(
|
||||
let (backup_guard, tasks, progress_info) = restore_packages(
|
||||
&rpc_ctx,
|
||||
&mut db,
|
||||
backup_guard,
|
||||
@@ -304,14 +303,13 @@ async fn restore_packages(
|
||||
ids: Vec<PackageId>,
|
||||
) -> Result<
|
||||
(
|
||||
Option<Arc<Revision>>,
|
||||
BackupMountGuard<TmpMountGuard>,
|
||||
Vec<JoinHandle<(Result<(), Error>, PackageId)>>,
|
||||
ProgressInfo,
|
||||
),
|
||||
Error,
|
||||
> {
|
||||
let (revision, guards) = assure_restoring(ctx, db, ids, &backup_guard).await?;
|
||||
let guards = assure_restoring(ctx, db, ids, &backup_guard).await?;
|
||||
|
||||
let mut progress_info = ProgressInfo::default();
|
||||
|
||||
@@ -339,7 +337,7 @@ async fn restore_packages(
|
||||
));
|
||||
}
|
||||
|
||||
Ok((revision, backup_guard, tasks, progress_info))
|
||||
Ok((backup_guard, tasks, progress_info))
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db, backup_guard))]
|
||||
@@ -348,13 +346,7 @@ async fn assure_restoring(
|
||||
db: &mut PatchDbHandle,
|
||||
ids: Vec<PackageId>,
|
||||
backup_guard: &BackupMountGuard<TmpMountGuard>,
|
||||
) -> Result<
|
||||
(
|
||||
Option<Arc<Revision>>,
|
||||
Vec<(Manifest, PackageBackupMountGuard)>,
|
||||
),
|
||||
Error,
|
||||
> {
|
||||
) -> Result<Vec<(Manifest, PackageBackupMountGuard)>, Error> {
|
||||
let mut tx = db.begin().await?;
|
||||
|
||||
let mut guards = Vec::with_capacity(ids.len());
|
||||
@@ -414,7 +406,8 @@ async fn assure_restoring(
|
||||
guards.push((manifest, guard));
|
||||
}
|
||||
|
||||
Ok((tx.commit().await?, guards))
|
||||
tx.commit().await?;
|
||||
Ok(guards)
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, guard))]
|
||||
|
||||
@@ -134,7 +134,6 @@ pub fn target() -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: incorporate reconnect into this response as well
|
||||
#[command(display(display_serializable))]
|
||||
pub async fn list(
|
||||
#[context] ctx: RpcContext,
|
||||
@@ -143,7 +142,6 @@ pub async fn list(
|
||||
let (disks_res, cifs) =
|
||||
tokio::try_join!(crate::disk::util::list(), cifs::list(&mut sql_handle),)?;
|
||||
Ok(disks_res
|
||||
.disks
|
||||
.into_iter()
|
||||
.flat_map(|mut disk| {
|
||||
std::mem::take(&mut disk.partitions)
|
||||
|
||||
@@ -77,7 +77,7 @@ async fn subscribe_to_session_kill(
|
||||
async fn deal_with_messages(
|
||||
_has_valid_authentication: HasValidSession,
|
||||
mut kill: oneshot::Receiver<()>,
|
||||
mut sub: patch_db::Subscriber,
|
||||
sub: patch_db::Subscriber,
|
||||
mut stream: WebSocketStream<Upgraded>,
|
||||
) -> Result<(), Error> {
|
||||
loop {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use clap::ArgMatches;
|
||||
use rpc_toolkit::command;
|
||||
|
||||
use self::util::DiskListResponse;
|
||||
use crate::disk::util::DiskInfo;
|
||||
use crate::util::display_none;
|
||||
use crate::util::serde::{display_serializable, IoFormat};
|
||||
use crate::Error;
|
||||
@@ -9,7 +9,6 @@ use crate::Error;
|
||||
pub mod fsck;
|
||||
pub mod main;
|
||||
pub mod mount;
|
||||
pub mod quirks;
|
||||
pub mod util;
|
||||
|
||||
pub const BOOT_RW_PATH: &str = "/media/boot-rw";
|
||||
@@ -20,7 +19,7 @@ pub fn disk() -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn display_disk_info(info: DiskListResponse, matches: &ArgMatches) {
|
||||
fn display_disk_info(info: Vec<DiskInfo>, matches: &ArgMatches) {
|
||||
use prettytable::*;
|
||||
|
||||
if matches.is_present("format") {
|
||||
@@ -35,7 +34,7 @@ fn display_disk_info(info: DiskListResponse, matches: &ArgMatches) {
|
||||
"USED",
|
||||
"EMBASSY OS VERSION"
|
||||
]);
|
||||
for disk in info.disks {
|
||||
for disk in info {
|
||||
let row = row![
|
||||
disk.logicalname.display(),
|
||||
"N/A",
|
||||
@@ -79,7 +78,7 @@ pub async fn list(
|
||||
#[allow(unused_variables)]
|
||||
#[arg]
|
||||
format: Option<IoFormat>,
|
||||
) -> Result<DiskListResponse, Error> {
|
||||
) -> Result<Vec<DiskInfo>, Error> {
|
||||
crate::disk::util::list().await
|
||||
}
|
||||
|
||||
|
||||
@@ -1,172 +0,0 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::num::ParseIntError;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use color_eyre::eyre::eyre;
|
||||
use helpers::AtomicFile;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tracing::instrument;
|
||||
|
||||
use super::BOOT_RW_PATH;
|
||||
use crate::{Error, ErrorKind, ResultExt};
|
||||
|
||||
pub const QUIRK_PATH: &'static str = "/sys/module/usb_storage/parameters/quirks";
|
||||
|
||||
pub const WHITELIST: [(VendorId, ProductId); 5] = [
|
||||
(VendorId(0x1d6b), ProductId(0x0002)), // root hub usb2
|
||||
(VendorId(0x1d6b), ProductId(0x0003)), // root hub usb3
|
||||
(VendorId(0x2109), ProductId(0x3431)),
|
||||
(VendorId(0x1058), ProductId(0x262f)), // western digital black HDD
|
||||
(VendorId(0x04e8), ProductId(0x4001)), // Samsung T7
|
||||
];
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct VendorId(u16);
|
||||
impl std::str::FromStr for VendorId {
|
||||
type Err = ParseIntError;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
u16::from_str_radix(s.trim(), 16).map(VendorId)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for VendorId {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{:04x}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct ProductId(u16);
|
||||
impl std::str::FromStr for ProductId {
|
||||
type Err = ParseIntError;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
u16::from_str_radix(s.trim(), 16).map(ProductId)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for ProductId {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{:04x}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Quirks(BTreeSet<(VendorId, ProductId)>);
|
||||
impl Quirks {
|
||||
pub fn add(&mut self, vendor: VendorId, product: ProductId) {
|
||||
self.0.insert((vendor, product));
|
||||
}
|
||||
pub fn remove(&mut self, vendor: VendorId, product: ProductId) {
|
||||
self.0.remove(&(vendor, product));
|
||||
}
|
||||
pub fn contains(&self, vendor: VendorId, product: ProductId) -> bool {
|
||||
self.0.contains(&(vendor, product))
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for Quirks {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let mut comma = false;
|
||||
for (vendor, product) in &self.0 {
|
||||
if comma {
|
||||
write!(f, ",")?;
|
||||
} else {
|
||||
comma = true;
|
||||
}
|
||||
write!(f, "{}:{}:u", vendor, product)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl std::str::FromStr for Quirks {
|
||||
type Err = Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let s = s.trim();
|
||||
let mut quirks = BTreeSet::new();
|
||||
for item in s.split(",") {
|
||||
if let [vendor, product, "u"] = item.splitn(3, ":").collect::<Vec<_>>().as_slice() {
|
||||
quirks.insert((vendor.parse()?, product.parse()?));
|
||||
} else {
|
||||
return Err(Error::new(
|
||||
eyre!("Invalid quirk: `{}`", item),
|
||||
crate::ErrorKind::DiskManagement,
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(Quirks(quirks))
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn update_quirks(quirks: &mut Quirks) -> Result<Vec<String>, Error> {
|
||||
let mut usb_devices = tokio::fs::read_dir("/sys/bus/usb/devices/").await?;
|
||||
let mut to_reconnect = Vec::new();
|
||||
while let Some(usb_device) = usb_devices.next_entry().await? {
|
||||
if tokio::fs::metadata(usb_device.path().join("idVendor"))
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let vendor = tokio::fs::read_to_string(usb_device.path().join("idVendor"))
|
||||
.await?
|
||||
.parse()?;
|
||||
let product = tokio::fs::read_to_string(usb_device.path().join("idProduct"))
|
||||
.await?
|
||||
.parse()?;
|
||||
if WHITELIST.contains(&(vendor, product)) {
|
||||
quirks.remove(vendor, product);
|
||||
continue;
|
||||
}
|
||||
if quirks.contains(vendor, product) {
|
||||
continue;
|
||||
}
|
||||
quirks.add(vendor, product);
|
||||
{
|
||||
// write quirks to sysfs
|
||||
let mut quirk_file = tokio::fs::File::create(QUIRK_PATH).await?;
|
||||
quirk_file.write_all(quirks.to_string().as_bytes()).await?;
|
||||
quirk_file.sync_all().await?;
|
||||
drop(quirk_file);
|
||||
}
|
||||
|
||||
disconnect_usb(usb_device.path()).await?;
|
||||
let (vendor_name, product_name) = tokio::try_join!(
|
||||
tokio::fs::read_to_string(usb_device.path().join("manufacturer")),
|
||||
tokio::fs::read_to_string(usb_device.path().join("product")),
|
||||
)?;
|
||||
to_reconnect.push(format!("{} {}", vendor_name, product_name));
|
||||
}
|
||||
Ok(to_reconnect)
|
||||
}
|
||||
|
||||
#[instrument(skip(usb_device_path))]
|
||||
pub async fn disconnect_usb(usb_device_path: impl AsRef<Path>) -> Result<(), Error> {
|
||||
let authorized_path = usb_device_path.as_ref().join("bConfigurationValue");
|
||||
let mut authorized_file = tokio::fs::File::create(&authorized_path).await?;
|
||||
authorized_file.write_all(b"0").await?;
|
||||
authorized_file.sync_all().await?;
|
||||
drop(authorized_file);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn fetch_quirks() -> Result<Quirks, Error> {
|
||||
Ok(tokio::fs::read_to_string(QUIRK_PATH).await?.parse()?)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn save_quirks(quirks: &Quirks) -> Result<(), Error> {
|
||||
let orig_path = Path::new(BOOT_RW_PATH).join("cmdline.txt.orig");
|
||||
let target_path = Path::new(BOOT_RW_PATH).join("cmdline.txt");
|
||||
if tokio::fs::metadata(&orig_path).await.is_err() {
|
||||
tokio::fs::copy(&target_path, &orig_path).await?;
|
||||
}
|
||||
let cmdline = tokio::fs::read_to_string(&orig_path).await?;
|
||||
let mut target = AtomicFile::new(&target_path, None::<PathBuf>)
|
||||
.await
|
||||
.with_kind(ErrorKind::Filesystem)?;
|
||||
target
|
||||
.write_all(format!("usb-storage.quirks={} {}", quirks, cmdline).as_bytes())
|
||||
.await?;
|
||||
target.save().await.with_kind(ErrorKind::Filesystem)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -19,19 +19,11 @@ use tracing::instrument;
|
||||
use super::mount::filesystem::block_dev::BlockDev;
|
||||
use super::mount::filesystem::ReadOnly;
|
||||
use super::mount::guard::TmpMountGuard;
|
||||
use super::quirks::{fetch_quirks, save_quirks, update_quirks};
|
||||
use crate::util::io::from_yaml_async_reader;
|
||||
use crate::util::serde::IoFormat;
|
||||
use crate::util::{Invoke, Version};
|
||||
use crate::{Error, ResultExt as _};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct DiskListResponse {
|
||||
pub disks: Vec<DiskInfo>,
|
||||
pub reconnect: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct DiskInfo {
|
||||
@@ -240,10 +232,7 @@ pub async fn recovery_info(
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn list() -> Result<DiskListResponse, Error> {
|
||||
let mut quirks = fetch_quirks().await?;
|
||||
let reconnect = update_quirks(&mut quirks).await?;
|
||||
save_quirks(&mut quirks).await?;
|
||||
pub async fn list() -> Result<Vec<DiskInfo>, Error> {
|
||||
let disk_guids = pvscan().await?;
|
||||
let disks = tokio_stream::wrappers::ReadDirStream::new(
|
||||
tokio::fs::read_dir(DISK_PATH)
|
||||
@@ -374,10 +363,7 @@ pub async fn list() -> Result<DiskListResponse, Error> {
|
||||
})
|
||||
}
|
||||
|
||||
Ok(DiskListResponse {
|
||||
disks: res,
|
||||
reconnect,
|
||||
})
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn parse_pvscan_output(pvscan_output: &str) -> BTreeMap<PathBuf, Option<String>> {
|
||||
|
||||
@@ -508,26 +508,26 @@ pub async fn follow_logs(
|
||||
// println!("{}", serialized);
|
||||
// }
|
||||
|
||||
#[tokio::test]
|
||||
pub async fn test_logs() {
|
||||
let mut cmd = Command::new("journalctl");
|
||||
cmd.kill_on_drop(true);
|
||||
// #[tokio::test]
|
||||
// pub async fn test_logs() {
|
||||
// let mut cmd = Command::new("journalctl");
|
||||
// cmd.kill_on_drop(true);
|
||||
|
||||
cmd.arg("-f");
|
||||
cmd.arg("CONTAINER_NAME=hello-world.embassy");
|
||||
// cmd.arg("-f");
|
||||
// cmd.arg("CONTAINER_NAME=hello-world.embassy");
|
||||
|
||||
let mut child = cmd.stdout(Stdio::piped()).spawn().unwrap();
|
||||
let out = BufReader::new(
|
||||
child
|
||||
.stdout
|
||||
.take()
|
||||
.ok_or_else(|| Error::new(eyre!("No stdout available"), crate::ErrorKind::Journald))
|
||||
.unwrap(),
|
||||
);
|
||||
// let mut child = cmd.stdout(Stdio::piped()).spawn().unwrap();
|
||||
// let out = BufReader::new(
|
||||
// child
|
||||
// .stdout
|
||||
// .take()
|
||||
// .ok_or_else(|| Error::new(eyre!("No stdout available"), crate::ErrorKind::Journald))
|
||||
// .unwrap(),
|
||||
// );
|
||||
|
||||
let mut journalctl_entries = LinesStream::new(out.lines());
|
||||
// let mut journalctl_entries = LinesStream::new(out.lines());
|
||||
|
||||
while let Some(line) = journalctl_entries.try_next().await.unwrap() {
|
||||
dbg!(line);
|
||||
}
|
||||
}
|
||||
// while let Some(line) = journalctl_entries.try_next().await.unwrap() {
|
||||
// dbg!(line);
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -94,7 +94,6 @@ impl MdnsControllerInner {
|
||||
}
|
||||
self.sync();
|
||||
}
|
||||
fn free(&self) {}
|
||||
}
|
||||
|
||||
fn log_str_error(action: &str, e: i32) {
|
||||
|
||||
@@ -36,7 +36,7 @@ use crate::disk::mount::filesystem::block_dev::BlockDev;
|
||||
use crate::disk::mount::filesystem::cifs::Cifs;
|
||||
use crate::disk::mount::filesystem::ReadOnly;
|
||||
use crate::disk::mount::guard::TmpMountGuard;
|
||||
use crate::disk::util::{pvscan, recovery_info, DiskListResponse, EmbassyOsRecoveryInfo};
|
||||
use crate::disk::util::{pvscan, recovery_info, DiskInfo, EmbassyOsRecoveryInfo};
|
||||
use crate::disk::REPAIR_DISK_PATH;
|
||||
use crate::hostname::{get_hostname, Hostname};
|
||||
use crate::id::Id;
|
||||
@@ -87,7 +87,7 @@ pub fn disk() -> Result<(), Error> {
|
||||
}
|
||||
|
||||
#[command(rename = "list", rpc_only, metadata(authenticated = false))]
|
||||
pub async fn list_disks() -> Result<DiskListResponse, Error> {
|
||||
pub async fn list_disks() -> Result<Vec<DiskInfo>, Error> {
|
||||
crate::disk::list(None).await
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,9 @@ mod v0_3_0_3;
|
||||
mod v0_3_1;
|
||||
mod v0_3_1_1;
|
||||
mod v0_3_1_2;
|
||||
mod v0_3_2;
|
||||
|
||||
pub type Current = v0_3_1_2::Version;
|
||||
pub type Current = v0_3_2::Version;
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
#[serde(untagged)]
|
||||
@@ -28,6 +29,7 @@ enum Version {
|
||||
V0_3_1(Wrapper<v0_3_1::Version>),
|
||||
V0_3_1_1(Wrapper<v0_3_1_1::Version>),
|
||||
V0_3_1_2(Wrapper<v0_3_1_2::Version>),
|
||||
V0_3_2(Wrapper<v0_3_2::Version>),
|
||||
Other(emver::Version),
|
||||
}
|
||||
|
||||
@@ -50,6 +52,7 @@ impl Version {
|
||||
Version::V0_3_1(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_1_1(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_1_2(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_2(Wrapper(x)) => x.semver(),
|
||||
Version::Other(x) => x.clone(),
|
||||
}
|
||||
}
|
||||
@@ -183,6 +186,7 @@ pub async fn init<Db: DbHandle>(
|
||||
Version::V0_3_1(v) => v.0.migrate_to(&Current::new(), db, receipts).await?,
|
||||
Version::V0_3_1_1(v) => v.0.migrate_to(&Current::new(), db, receipts).await?,
|
||||
Version::V0_3_1_2(v) => v.0.migrate_to(&Current::new(), db, receipts).await?,
|
||||
Version::V0_3_2(v) => v.0.migrate_to(&Current::new(), db, receipts).await?,
|
||||
Version::Other(_) => {
|
||||
return Err(Error::new(
|
||||
eyre!("Cannot downgrade"),
|
||||
@@ -221,6 +225,8 @@ mod tests {
|
||||
Just(Version::V0_3_0_3(Wrapper(v0_3_0_3::Version::new()))),
|
||||
Just(Version::V0_3_1(Wrapper(v0_3_1::Version::new()))),
|
||||
Just(Version::V0_3_1_1(Wrapper(v0_3_1_1::Version::new()))),
|
||||
Just(Version::V0_3_1_2(Wrapper(v0_3_1_2::Version::new()))),
|
||||
Just(Version::V0_3_2(Wrapper(v0_3_2::Version::new()))),
|
||||
em_version().prop_map(Version::Other),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ use emver::VersionRange;
|
||||
use tokio::process::Command;
|
||||
|
||||
use super::*;
|
||||
use crate::disk::quirks::{fetch_quirks, save_quirks, update_quirks};
|
||||
use crate::disk::BOOT_RW_PATH;
|
||||
use crate::update::query_mounted_label;
|
||||
use crate::util::Invoke;
|
||||
@@ -36,9 +35,6 @@ impl VersionT for Version {
|
||||
.arg(Path::new(BOOT_RW_PATH).join("cmdline.txt.orig"))
|
||||
.invoke(crate::ErrorKind::Filesystem)
|
||||
.await?;
|
||||
let mut q = fetch_quirks().await?;
|
||||
update_quirks(&mut q).await?;
|
||||
save_quirks(&q).await?;
|
||||
Ok(())
|
||||
}
|
||||
async fn down<Db: DbHandle>(&self, _db: &mut Db) -> Result<(), Error> {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
use emver::VersionRange;
|
||||
|
||||
use crate::hostname::{generate_id, get_hostname, sync_hostname};
|
||||
|
||||
use super::v0_3_0::V0_3_0_COMPAT;
|
||||
use super::*;
|
||||
|
||||
@@ -21,41 +19,10 @@ impl VersionT for Version {
|
||||
fn compat(&self) -> &'static VersionRange {
|
||||
&*V0_3_0_COMPAT
|
||||
}
|
||||
async fn up<Db: DbHandle>(&self, db: &mut Db) -> Result<(), Error> {
|
||||
let hostname = get_hostname(db).await?;
|
||||
crate::db::DatabaseModel::new()
|
||||
.server_info()
|
||||
.hostname()
|
||||
.put(db, &Some(hostname.0))
|
||||
.await?;
|
||||
crate::db::DatabaseModel::new()
|
||||
.server_info()
|
||||
.id()
|
||||
.put(db, &generate_id())
|
||||
.await?;
|
||||
|
||||
sync_hostname(db).await?;
|
||||
let mut ui = crate::db::DatabaseModel::new()
|
||||
.ui()
|
||||
.get(db, false)
|
||||
.await?
|
||||
.clone();
|
||||
if let serde_json::Value::Object(ref mut ui) = ui {
|
||||
ui.insert("ack-instructions".to_string(), serde_json::json!({}));
|
||||
}
|
||||
crate::db::DatabaseModel::new().ui().put(db, &ui).await?;
|
||||
async fn up<Db: DbHandle>(&self, _db: &mut Db) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
async fn down<Db: DbHandle>(&self, db: &mut Db) -> Result<(), Error> {
|
||||
let mut ui = crate::db::DatabaseModel::new()
|
||||
.ui()
|
||||
.get(db, false)
|
||||
.await?
|
||||
.clone();
|
||||
if let serde_json::Value::Object(ref mut ui) = ui {
|
||||
ui.remove("ack-instructions");
|
||||
}
|
||||
crate::db::DatabaseModel::new().ui().put(db, &ui).await?;
|
||||
async fn down<Db: DbHandle>(&self, _db: &mut Db) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
61
backend/src/version/v0_3_2.rs
Normal file
61
backend/src/version/v0_3_2.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use emver::VersionRange;
|
||||
|
||||
use crate::hostname::{generate_id, get_hostname, sync_hostname};
|
||||
|
||||
use super::v0_3_0::V0_3_0_COMPAT;
|
||||
use super::*;
|
||||
|
||||
const V0_3_2: emver::Version = emver::Version::new(0, 3, 2, 0);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Version;
|
||||
#[async_trait]
|
||||
impl VersionT for Version {
|
||||
type Previous = v0_3_1_2::Version;
|
||||
fn new() -> Self {
|
||||
Version
|
||||
}
|
||||
fn semver(&self) -> emver::Version {
|
||||
V0_3_2
|
||||
}
|
||||
fn compat(&self) -> &'static VersionRange {
|
||||
&*V0_3_0_COMPAT
|
||||
}
|
||||
async fn up<Db: DbHandle>(&self, db: &mut Db) -> Result<(), Error> {
|
||||
let hostname = get_hostname(db).await?;
|
||||
crate::db::DatabaseModel::new()
|
||||
.server_info()
|
||||
.hostname()
|
||||
.put(db, &Some(hostname.0))
|
||||
.await?;
|
||||
crate::db::DatabaseModel::new()
|
||||
.server_info()
|
||||
.id()
|
||||
.put(db, &generate_id())
|
||||
.await?;
|
||||
|
||||
sync_hostname(db).await?;
|
||||
let mut ui = crate::db::DatabaseModel::new()
|
||||
.ui()
|
||||
.get(db, false)
|
||||
.await?
|
||||
.clone();
|
||||
if let serde_json::Value::Object(ref mut ui) = ui {
|
||||
ui.insert("ack-instructions".to_string(), serde_json::json!({}));
|
||||
}
|
||||
crate::db::DatabaseModel::new().ui().put(db, &ui).await?;
|
||||
Ok(())
|
||||
}
|
||||
async fn down<Db: DbHandle>(&self, db: &mut Db) -> Result<(), Error> {
|
||||
let mut ui = crate::db::DatabaseModel::new()
|
||||
.ui()
|
||||
.get(db, false)
|
||||
.await?
|
||||
.clone();
|
||||
if let serde_json::Value::Object(ref mut ui) = ui {
|
||||
ui.remove("ack-instructions");
|
||||
}
|
||||
crate::db::DatabaseModel::new().ui().put(db, &ui).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user