syscare/0006-syscared-support-saving-restoring-patch-status-by-op.patch
renoseven eea01c1370 update to 1.2.2-4
Signed-off-by: renoseven <dev@renoseven.net>
(cherry picked from commit ef53460df585f2572812c41491306d6c21c207eb)
2025-02-20 10:57:07 +08:00

163 lines
6.1 KiB
Diff

From d98892b0452499284fc577388cf8045af0ffa071 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Thu, 17 Oct 2024 22:24:21 +0800
Subject: [PATCH] syscared: support saving & restoring patch status by
operation order
Signed-off-by: renoseven <dev@renoseven.net>
---
syscared/Cargo.toml | 2 +-
syscared/src/patch/manager.rs | 84 ++++++++++++-----------------------
2 files changed, 30 insertions(+), 56 deletions(-)
diff --git a/syscared/Cargo.toml b/syscared/Cargo.toml
index 1bfd43f..2eecea8 100644
--- a/syscared/Cargo.toml
+++ b/syscared/Cargo.toml
@@ -16,7 +16,7 @@ clap = { version = "3.2", features = ["cargo", "derive"] }
daemonize = { version = "0.5" }
flexi_logger = { version = "0.24", features = ["compress"] }
inotify = { version = "0.9" }
-indexmap = { version = "1.9" }
+indexmap = { version = "1.9", features = ["serde"] }
jsonrpc-core = { version = "18.0" }
jsonrpc-derive = { version = "18.0" }
jsonrpc-ipc-server = { version = "18.0" }
diff --git a/syscared/src/patch/manager.rs b/syscared/src/patch/manager.rs
index a17703c..48c583a 100644
--- a/syscared/src/patch/manager.rs
+++ b/syscared/src/patch/manager.rs
@@ -13,8 +13,6 @@
*/
use std::{
- cmp::Ordering,
- collections::HashMap,
path::{Path, PathBuf},
str::FromStr,
sync::Arc,
@@ -221,19 +219,16 @@ impl PatchManager {
pub fn save_patch_status(&mut self) -> Result<()> {
info!("Saving all patch status...");
- debug!("Updating all patch status...");
+ debug!("Updating patch status...");
for patch in self.get_patch_list() {
- debug!("Update patch '{}' status", patch);
self.get_patch_status(&patch)?;
}
- let mut status_map = HashMap::new();
+ debug!("Writing patch status...");
for (uuid, status) in &self.status_map {
- status_map.insert(uuid, status);
+ debug!("Patch '{}' status: {}", uuid, status);
}
-
- debug!("Writing patch status file");
- serde::serialize(&status_map, &self.patch_status_file)
+ serde::serialize(&self.status_map, &self.patch_status_file)
.context("Failed to write patch status file")?;
fs::sync();
@@ -244,57 +239,35 @@ impl PatchManager {
pub fn restore_patch_status(&mut self, accepted_only: bool) -> Result<()> {
info!("Restoring all patch status...");
+ if !self.patch_status_file.exists() {
+ return Ok(());
+ }
debug!("Reading patch status...");
- let status_file = &self.patch_status_file;
- let status_map: HashMap<Uuid, PatchStatus> = if status_file.exists() {
- serde::deserialize(status_file).context("Failed to read patch status")?
- } else {
- warn!("Cannot find patch status file");
- return Ok(());
- };
+ let status_map: IndexMap<Uuid, PatchStatus> =
+ serde::deserialize(&self.patch_status_file).context("Failed to read patch status")?;
+ for (uuid, status) in &status_map {
+ debug!("Patch '{}' status: {}", uuid, status);
+ }
- /*
- * To ensure that we won't load multiple patches for same target at the same time,
- * we take a sort operation of the status to make sure do REMOVE operation at first
- */
- let mut restore_list = status_map
+ let restore_list = status_map
.into_iter()
- .filter_map(|(uuid, status)| match self.find_patch_by_uuid(&uuid) {
+ .filter(|(_, status)| !accepted_only || (*status == PatchStatus::Accepted));
+ for (uuid, status) in restore_list {
+ match self.find_patch_by_uuid(&uuid) {
Ok(patch) => {
- if accepted_only && (status != PatchStatus::Accepted) {
- debug!(
- "Skipped patch '{}', status is not '{}'",
- patch,
- PatchStatus::Accepted
- );
- return None;
+ debug!("Restore patch '{}' status to '{}'", patch, status);
+ if let Err(e) = self.do_status_transition(&patch, status, PatchOpFlag::Force) {
+ error!("{}", e);
}
- Some((patch, status))
}
Err(e) => {
- error!("{:?}", e);
- None
+ error!("{}", e);
}
- })
- .collect::<Vec<_>>();
-
- restore_list.sort_by(|(lhs_patch, lhs_status), (rhs_patch, rhs_status)| {
- match lhs_status.cmp(rhs_status) {
- Ordering::Less => Ordering::Less,
- Ordering::Equal => lhs_patch.cmp(rhs_patch),
- Ordering::Greater => Ordering::Greater,
- }
- });
-
- for (patch, target_status) in restore_list {
- debug!("Restore patch '{}' status to '{}'", patch, target_status);
- if let Err(e) = self.do_status_transition(&patch, target_status, PatchOpFlag::Force) {
- error!("{}", e);
}
}
- info!("All patch status were restored");
+ info!("All patch status were restored");
Ok(())
}
@@ -426,13 +399,14 @@ impl PatchManager {
bail!("Cannot set patch '{}' status to '{}'", patch, value);
}
- let status_map = &mut self.status_map;
- match status_map.get_mut(patch.uuid()) {
- Some(status) => {
- *status = value;
- }
- None => {
- status_map.insert(*patch.uuid(), value);
+ let (index, _) = self.status_map.insert_full(*patch.uuid(), value);
+ if let Some(last_index) = self
+ .status_map
+ .last()
+ .and_then(|(key, _)| self.status_map.get_index_of(key))
+ {
+ if index != last_index {
+ self.status_map.move_index(index, last_index);
}
}
--
2.34.1