]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
Implemented snbk restore command
authorCheng-Ling Lai <jamesljlster@gmail.com>
Tue, 9 Dec 2025 08:45:34 +0000 (16:45 +0800)
committerCheng-Ling Lai <jamesljlster@gmail.com>
Tue, 9 Dec 2025 08:45:34 +0000 (16:45 +0800)
client/snbk/Makefile.am
client/snbk/cmd-restore.cc [new file with mode: 0644]
client/snbk/cmd.h
client/snbk/snbk.cc

index 4a0f06ad48d9ee9e13a55e36708cef9b20e4b719..d229e1b664d25c1bf8b7da536e79fcd987349633 100644 (file)
@@ -12,6 +12,7 @@ snbk_SOURCES =                                                \
        cmd-list-configs.cc                             \
        cmd-list.cc                                     \
        cmd-transfer.cc                                 \
+       cmd-restore.cc                                  \
        cmd-delete.cc                                   \
        cmd-transfer-and-delete.cc                      \
        BackupConfig.cc         BackupConfig.h          \
diff --git a/client/snbk/cmd-restore.cc b/client/snbk/cmd-restore.cc
new file mode 100644 (file)
index 0000000..78a4e2e
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2024 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 <iostream>
+#include <regex>
+
+#include <snapper/AppUtil.h>
+
+#include "../proxy/errors.h"
+#include "../utils/text.h"
+
+#include "BackupConfig.h"
+#include "GlobalOptions.h"
+#include "TheBigThing.h"
+#include "cmd.h"
+
+
+namespace snapper
+{
+
+    using namespace std;
+
+
+    void
+    help_restore()
+    {
+       cout << "  " << _("Restore:") << '\n'
+            << "\t" << _("snbk restore [numbers]") << '\n'
+            << '\n';
+    }
+
+
+    void
+    command_restore(const GlobalOptions& global_options, GetOpts& get_opts,
+                   BackupConfigs& backup_configs, ProxySnappers* snappers)
+    {
+       static const regex num_regex("[0-9]+", regex::extended);
+
+       ParsedOpts opts = get_opts.parse("restore", GetOpts::no_options);
+
+       vector<unsigned int> nums;
+
+       while (get_opts.has_args())
+       {
+           string arg = get_opts.pop_arg();
+
+           if (!regex_match(arg, num_regex))
+               SN_THROW(Exception(_("Failed to parse number.")));
+
+           nums.push_back(stoi(arg));
+       }
+
+       unsigned int errors = 0;
+
+       for (const BackupConfig& backup_config : backup_configs)
+       {
+           if (!global_options.quiet())
+               cout << sformat(_("Running restore for backup config '%s'."),
+                               backup_config.name.c_str()) << endl;
+
+           try
+           {
+               TheBigThings the_big_things(backup_config, snappers,
+                                           global_options.verbose());
+
+               if (nums.empty())
+               {
+                   the_big_things.restore(backup_config, global_options.quiet(),
+                                          global_options.quiet());
+               }
+               else
+               {
+                   for (unsigned int num : nums)
+                   {
+                       TheBigThings::iterator it = the_big_things.find(num);
+                       if (it == the_big_things.end())
+                       {
+                           string error = sformat(_("Snapshot number %d not found."),
+                                                  num);
+                           SN_THROW(Exception(error));
+                       }
+
+                       it->restore(backup_config, the_big_things,
+                                   global_options.quiet());
+                   }
+               }
+           }
+           catch (const DBus::ErrorException& e)
+           {
+               SN_CAUGHT(e);
+
+               cerr << error_description(e) << endl;
+
+               ++errors;
+           }
+           catch (const Exception& e)
+           {
+               SN_CAUGHT(e);
+
+               cerr << e.what() << '\n';
+
+               cerr << sformat(_("Running restore for backup config '%s' failed."),
+                               backup_config.name.c_str()) << endl;
+
+               ++errors;
+           }
+       }
+
+       if (errors != 0)
+       {
+           string error = sformat(
+               _("Running restore failed for %d of %ld backup config.",
+                 "Running restore failed for %d of %ld backup configs.",
+                 backup_configs.size()), errors, backup_configs.size()
+           );
+
+           SN_THROW(Exception(error));
+       }
+    }
+
+}
index 5a5a9c88f77626b4370dd925468cd4c5afa6a687..681c004310df311ca1303aedde1d756be1c8dbab 100644 (file)
@@ -53,6 +53,14 @@ namespace snapper
                     ProxySnappers* snappers);
 
 
+    void
+    help_restore();
+
+    void
+    command_restore(const GlobalOptions& global_options, GetOpts& get_opts, BackupConfigs& backup_configs,
+                    ProxySnappers* snappers);
+
+
     void
     help_delete();
 
index bad9290669735e1c60553b89450228d08573416d..753bf34070025305f407948b4eb813b37ff7b465 100644 (file)
@@ -125,6 +125,7 @@ main(int argc, char** argv)
        Cmd("list-configs", command_list_configs, help_list_configs, false),
        Cmd("list", { "ls" }, command_list, help_list, true),
        Cmd("transfer", command_transfer, help_transfer, true),
+       Cmd("restore", command_restore, help_restore, true),
        Cmd("delete", { "remove", "rm" }, command_delete, help_delete, true),
        Cmd("transfer-and-delete", command_transfer_and_delete, help_transfer_and_delete, true),
     };