From 3496462bbfc797759a5b07f6c522b0e15417a3a0 Mon Sep 17 00:00:00 2001 From: Arvin Schnell Date: Thu, 19 Mar 2026 12:28:50 +0100 Subject: [PATCH] - minor refactoring --- client/snbk/CmdChecksum.cc | 88 +++++++++++++++ client/snbk/{CmdFileHash.h => CmdChecksum.h} | 22 ++-- client/snbk/CmdFileHash.cc | 109 ------------------- client/snbk/Makefile.am | 2 +- client/snbk/TheBigThing.cc | 31 ++++-- client/snbk/TheBigThing.h | 4 +- 6 files changed, 121 insertions(+), 135 deletions(-) create mode 100644 client/snbk/CmdChecksum.cc rename client/snbk/{CmdFileHash.h => CmdChecksum.h} (66%) delete mode 100644 client/snbk/CmdFileHash.cc diff --git a/client/snbk/CmdChecksum.cc b/client/snbk/CmdChecksum.cc new file mode 100644 index 00000000..7237d87e --- /dev/null +++ b/client/snbk/CmdChecksum.cc @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2026 SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may + * find current contact information at www.novell.com. + */ + + +#include + +#include +#include +#include +#include + +#include "../utils/text.h" + +#include "CmdChecksum.h" + + +namespace snapper +{ + + CmdChecksum::CmdChecksum(const Shell& shell, const string& chksum_bin, const string& path) + : path(path) + { + SystemCmd::Args cmd_args = { chksum_bin, "--", path }; + SystemCmd cmd(shellify(shell, cmd_args)); + + if (cmd.retcode() != 0) + { + y2err("command '" << cmd.cmd() << "' failed: " << cmd.retcode()); + for (const string& tmp : cmd.get_stdout()) + y2err(tmp); + for (const string& tmp : cmd.get_stderr()) + y2err(tmp); + + SN_THROW(Exception(_("Failed to compute checksum."))); + } + + parse(cmd.get_stdout()); + + y2mil(*this); + } + + + void + CmdChecksum::parse(const vector& lines) + { + if (lines.size() != 1) + SN_THROW(Exception(_("Invalid number of lines in checksum output."))); + + vector parts; + boost::split(parts, lines[0], boost::is_any_of(" "), boost::token_compress_on); + if (parts.size() != 2) + { + y2err("Invalid checksum line: " << lines[0]); + SN_THROW(Exception(_("Invalid checksum output format."))); + } + + checksum = parts[0]; + } + + + std::ostream& + operator<<(std::ostream& s, const CmdChecksum& cmd_checksum) + { + s << "path: " << cmd_checksum.path << " checksum: " << cmd_checksum.checksum << '\n'; + + return s; + } + + +} // namespace snapper diff --git a/client/snbk/CmdFileHash.h b/client/snbk/CmdChecksum.h similarity index 66% rename from client/snbk/CmdFileHash.h rename to client/snbk/CmdChecksum.h index 0a6dacc7..4cfc08e0 100644 --- a/client/snbk/CmdFileHash.h +++ b/client/snbk/CmdChecksum.h @@ -20,8 +20,8 @@ */ -#ifndef SNAPPER_CMD_FILE_HASH_H -#define SNAPPER_CMD_FILE_HASH_H +#ifndef SNAPPER_CMD_CHECKSUM_H +#define SNAPPER_CMD_CHECKSUM_H #include "Shell.h" @@ -33,25 +33,25 @@ namespace snapper /** - * Find the hash of the file at the given path. - * If `allow_failure` is `true`, errors are ignored and the hash is set to an empty - * string. + * Get the checksum (e.g. sha256sum) of the file at the given path. */ - class CmdFileHash + class CmdChecksum { public: - CmdFileHash(const Shell& shell, const string& chksum_bin, const string& path, - bool allow_failure); + CmdChecksum(const Shell& shell, const string& checksum_bin, const string& path); - const string& get_hash() const; + const string& get_checksum() const { return checksum; } - friend std::ostream& operator<<(std::ostream& s, const CmdFileHash& cmd_filehash); + friend std::ostream& operator<<(std::ostream& s, const CmdChecksum& cmd_checksum); private: + void parse(const vector& lines); + const string path; - string hash; + string checksum; + }; diff --git a/client/snbk/CmdFileHash.cc b/client/snbk/CmdFileHash.cc deleted file mode 100644 index e8b67ffb..00000000 --- a/client/snbk/CmdFileHash.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2026 SUSE LLC - * - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, contact Novell, Inc. - * - * To contact Novell about this file by physical or electronic mail, you may - * find current contact information at www.novell.com. - */ - - -#include - -#include -#include -#include -#include - -#include "../utils/text.h" - -#include "CmdFileHash.h" - - -namespace snapper -{ - - - CmdFileHash::CmdFileHash(const Shell& shell, const string& chksum_bin, - const string& path, bool allow_failure) - : path(path) - { - SystemCmd::Args cmd_args = { chksum_bin, "--", path }; - SystemCmd cmd(shellify(shell, cmd_args)); - - try - { - if (cmd.retcode() != 0) - { - y2err("command '" << cmd.cmd() << "' failed: " << cmd.retcode()); - for (const string& tmp : cmd.get_stdout()) - y2err(tmp); - for (const string& tmp : cmd.get_stderr()) - y2err(tmp); - - SN_THROW(Exception(_("Failed to compute file hash."))); - } - else - { - // Check if the hash utility returns 1 line exactly - vector cmd_outputs = cmd.get_stdout(); - if (cmd_outputs.size() != 1) - { - y2err(sformat("Expected 1 line, but %lu lines were received from %s.", - cmd_outputs.size(), chksum_bin.c_str())); - SN_THROW(Exception(_("Unexpected output from the hash utility."))); - } - - // Parse the hash output - vector parts; - const string& line = cmd_outputs[0]; - boost::split(parts, line, boost::is_any_of(" "), - boost::token_compress_on); - if (parts.size() != 2) - { - y2err("Invalid hash string: " << line); - SN_THROW(Exception(_("Invalid hash output format."))); - } - - hash = parts[0]; - } - } - catch (const Exception& e) - { - if (!allow_failure) - { - SN_THROW(e); - } - else - { - y2err(e); - } - } - - y2mil(*this); - } - - - const string& CmdFileHash::get_hash() const { return hash; } - - std::ostream& operator<<(std::ostream& s, const CmdFileHash& cmd_filehash) - { - s << "path: " << cmd_filehash.path << " hash: " << cmd_filehash.hash << '\n'; - - return s; - } - - -} // namespace snapper diff --git a/client/snbk/Makefile.am b/client/snbk/Makefile.am index 91f6dfd8..6adc05f7 100644 --- a/client/snbk/Makefile.am +++ b/client/snbk/Makefile.am @@ -22,7 +22,7 @@ snbk_SOURCES = \ Shell.cc Shell.h \ CmdBtrfs.cc CmdBtrfs.h \ CmdLs.cc CmdLs.h \ - CmdFileHash.cc CmdFileHash.h \ + CmdChecksum.cc CmdChecksum.h \ JsonFile.cc JsonFile.h \ utils.cc utils.h \ TreeView.cc TreeView.h diff --git a/client/snbk/TheBigThing.cc b/client/snbk/TheBigThing.cc index 5effad66..f9b22c66 100644 --- a/client/snbk/TheBigThing.cc +++ b/client/snbk/TheBigThing.cc @@ -34,7 +34,7 @@ #include "CmdBtrfs.h" #include "CmdLs.h" -#include "CmdFileHash.h" +#include "CmdChecksum.h" #include "BackupConfig.h" #include "TheBigThing.h" @@ -516,11 +516,10 @@ namespace snapper the_big_thing.source_received_uuid = extra.get_received_uuid(); the_big_thing.source_creation_time = extra.get_creation_time(); - // Find the hash of info.xml - CmdFileHash cmd_filehash(shell_source, SHA256SUM_BIN, - source_snapshot_dir(snapper, num) + "/info.xml", - false); - the_big_thing.source_meta_hash = cmd_filehash.get_hash(); + // Get the checksum of info.xml. + CmdChecksum cmd_checksum(shell_source, SHA256SUM_BIN, + source_snapshot_dir(snapper, num) + "/info.xml"); + the_big_thing.source_meta_checksum = cmd_checksum.get_checksum(); the_big_things.push_back(the_big_thing); } @@ -618,15 +617,23 @@ namespace snapper it->target_received_uuid = extra.get_received_uuid(); it->target_creation_time = extra.get_creation_time(); - // Find the hash of info.xml - CmdFileHash cmd_filehash( - shell_target, backup_config.target_sha256sum_bin, - target_snapshot_dir(backup_config, num) + "/info.xml", true); - it->target_meta_hash = cmd_filehash.get_hash(); + try + { + // Get the checksum of info.xml. + CmdChecksum cmd_checksum(shell_target, backup_config.target_sha256sum_bin, + target_snapshot_dir(backup_config, num) + "/info.xml"); + it->target_meta_checksum = cmd_checksum.get_checksum(); + } + catch (const Exception& e) + { + SN_CAUGHT(e); + + // keep checksum empty + } if (it->source_state == TheBigThing::SourceState::READ_ONLY && it->target_state == TheBigThing::TargetState::VALID && - it->source_meta_hash != it->target_meta_hash) + it->source_meta_checksum != it->target_meta_checksum) { it->target_state = TheBigThing::TargetState::LEGACY; } diff --git a/client/snbk/TheBigThing.h b/client/snbk/TheBigThing.h index b42eb809..ba41ef2a 100644 --- a/client/snbk/TheBigThing.h +++ b/client/snbk/TheBigThing.h @@ -83,13 +83,13 @@ namespace snapper string source_parent_uuid; string source_received_uuid; string source_creation_time; - string source_meta_hash; + string source_meta_checksum; string target_uuid; string target_parent_uuid; string target_received_uuid; string target_creation_time; - string target_meta_hash; + string target_meta_checksum; private: -- 2.47.3