]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
- added simple cleanup algorithm
authorArvin Schnell <aschnell@suse.de>
Mon, 21 Feb 2011 16:11:26 +0000 (17:11 +0100)
committerArvin Schnell <aschnell@suse.de>
Mon, 21 Feb 2011 16:11:26 +0000 (17:11 +0100)
snapper/Snapper.cc
snapper/Snapper.h
snapper/Snapshot.cc
snapper/Snapshot.h
testsuite-real/common.cc
tools/snapper.cc

index 3efd0420a65c44878fb61bfc2d2409225f242ce0..b59e2b879d613a46a8dd642496b40c373d07881d 100644 (file)
@@ -171,4 +171,48 @@ namespace snapper
        return files.doRollback();
     }
 
+
+    bool
+    Snapper::doCleanupAmount()
+    {
+       size_t n = 10;          // TODO
+
+       y2mil("n:" << n);
+
+       vector<Snapshots::iterator> tmp;
+
+       for (Snapshots::iterator it = snapshots.begin(); it != snapshots.end(); ++it)
+       {
+           if (it->getCleanup() == "amount")
+               tmp.push_back(it);
+       }
+
+       y2mil("filtered " << tmp.size() << " snapshots");
+
+       if (tmp.size() > n)
+       {
+           tmp.erase(tmp.end() - n, tmp.end());
+
+           // TODO: only remove pre and post together
+
+           y2mil("deleting " << tmp.size() << " snapshots");
+
+           for (vector<Snapshots::iterator>::iterator it = tmp.begin(); it != tmp.end(); ++it)
+           {
+               deleteSnapshot(*it);
+           }
+       }
+
+       return true;
+    }
+
+
+    bool
+    Snapper::doCleanupTimeline()
+    {
+       // TODO: hourly, daily, monthly, yearly algorithm
+
+       return false;
+    }
+
 }
index 863a6d32f29de9603b21d3ce9f4e0f5f04ef2b86..3184438dbe13991dda83ae88b3ae37e8ce986904 100644 (file)
@@ -78,6 +78,9 @@ namespace snapper
 
        bool doRollback();
 
+       bool doCleanupAmount();
+       bool doCleanupTimeline();
+
        void setCompareCallback(CompareCallback* p) { compare_callback = p; }
        CompareCallback* getCompareCallback() const { return compare_callback; }
 
index 00fe9a578754c9c6a083d95956b2ea45ae7bff93..5675d02324f34edda1c0d004f9934030aaf401d8 100644 (file)
@@ -53,6 +53,9 @@ namespace snapper
        if (!snapshot.description.empty())
            s << " description:\"" << snapshot.description << "\"";
 
+       if (!snapshot.cleanup.empty())
+           s << " cleanup:\"" << snapshot.cleanup << "\"";
+
        return s;
     }
 
@@ -82,9 +85,17 @@ namespace snapper
 
 
     void
-    Snapshot::setDescription(const string& desc)
+    Snapshot::setDescription(const string& val)
     {
-       description = desc;
+       description = val;
+       writeInfo();
+    }
+
+
+    void
+    Snapshot::setCleanup(const string& val)
+    {
+       cleanup = val;
        writeInfo();
     }
 
@@ -131,6 +142,8 @@ namespace snapper
 
            getChildValue(node, "pre_num", snapshot.pre_num);
 
+           getChildValue(node, "cleanup", snapshot.cleanup);
+
            if (!checkDir(snapshot.snapshotDir()))
            {
                y2err("snapshot directory does not exist. not adding snapshot " << num);
@@ -258,6 +271,9 @@ namespace snapper
        if (type == POST)
            setChildValue(node, "pre_num", pre_num);
 
+       if (!cleanup.empty())
+           setChildValue(node, "cleanup", cleanup);
+
        xml.save(baseDir() + "/info.xml");
 
        return true;
index 4b369ddba2eb1d95685124ad7b2858a450086610..eea707c7882f7d6c520daf506d4c1dc35a9a2714 100644 (file)
@@ -48,7 +48,8 @@ namespace snapper
 
        friend class Snapshots;
 
-       Snapshot(const Snapper* snapper) : snapper(snapper), type(SINGLE), num(0), pre_num(0) {}
+       Snapshot(const Snapper* snapper)
+           : snapper(snapper), type(SINGLE), num(0), date((time_t)(-1)), pre_num(0) {}
 
        SnapshotType getType() const { return type; }
 
@@ -62,6 +63,9 @@ namespace snapper
 
        unsigned int getPreNum() const { return pre_num; }
 
+       void setCleanup(const string& cleanup);
+       string getCleanup() const { return cleanup; }
+
        string baseDir() const;
        string snapshotDir() const;
 
@@ -81,6 +85,8 @@ namespace snapper
 
        unsigned int pre_num;   // valid only for type=POST
 
+       string cleanup;
+
        bool writeInfo() const;
        bool createFilesystemSnapshot() const;
        bool deleteFilesystemSnapshot() const;
@@ -105,7 +111,10 @@ namespace snapper
        typedef list<Snapshot>::iterator iterator;
        typedef list<Snapshot>::const_iterator const_iterator;
 
+       iterator begin() { return entries.begin(); }
        const_iterator begin() const { return entries.begin(); }
+
+       iterator end() { return entries.end(); }
        const_iterator end() const { return entries.end(); }
 
        iterator find(unsigned int num);
index e61e54bd3ec35d14ed03af97933f6185a567fe01..6737c5533136995695db095a503a585d0a4bc3db 100644 (file)
@@ -43,6 +43,7 @@ void
 first_snapshot()
 {
     first = sh->createPreSnapshot("testsuite");
+    first->setCleanup("amount");
 }
 
 
@@ -50,6 +51,7 @@ void
 second_snapshot()
 {
     second = sh->createPostSnapshot(first);
+    second->setCleanup("amount");
 }
 
 
index 67017c75ffe59567a5c1f0b6982a8ebec8674518..6f83937200960c9440692cea781ae4eabed956d0 100644 (file)
@@ -76,6 +76,7 @@ command_list()
     header.add("#");
     header.add("Pre #");
     header.add("Date");
+    header.add("Cleanup");
     header.add("Description");
     table.setHeader(header);
 
@@ -87,6 +88,7 @@ command_list()
        row.add(decString(it->getNum()));
        row.add(it->getType() == POST ? decString(it->getPreNum()) : "");
        row.add(it->isCurrent() ? "" : datetime(it->getDate(), false, false));
+       row.add(it->getCleanup());
        row.add(it->getDescription());
        table.add(row);
     }
@@ -106,6 +108,7 @@ help_create()
         << _("\t--pre-number <number>\t\tNumber of corresponding pre snapshot.") << endl
         << _("\t--description, -d <description>\tDescription for snapshot.") << endl
         << _("\t--print-number, -p\t\tPrint number of created snapshot.") << endl
+        << _("\t--cleanup-algorithm, -c\t\tCleanup algorithm for snapshot.") << endl
         << endl;
 }
 
@@ -118,6 +121,7 @@ command_create()
        { "pre-number",         required_argument,      0,      0 },
        { "description",        required_argument,      0,      'd' },
        { "print-number",       no_argument,            0,      'p' },
+       { "cleanup",            required_argument,      0,      'c' },
        { 0, 0, 0, 0 }
     };
 
@@ -132,6 +136,7 @@ command_create()
     Snapshots::const_iterator snap1;
     string description;
     bool print_number = false;
+    string cleanup;
 
     GetOpts::parsed_opts::const_iterator it;
 
@@ -147,22 +152,28 @@ command_create()
     if ((it = opts.find("print-number")) != opts.end())
        print_number = true;
 
+    if ((it = opts.find("cleanup")) != opts.end())
+       cleanup = it->second;
+
     switch (type)
     {
        case SINGLE: {
-           Snapshots::const_iterator snap1 = sh->createSingleSnapshot(description);
+           Snapshots::iterator snap1 = sh->createSingleSnapshot(description);
+           snap1->setCleanup(cleanup);
            if (print_number)
                cout << snap1->getNum() << endl;
        } break;
 
        case PRE: {
-           Snapshots::const_iterator snap1 = sh->createPreSnapshot(description);
+           Snapshots::iterator snap1 = sh->createPreSnapshot(description);
+           snap1->setCleanup(cleanup);
            if (print_number)
                cout << snap1->getNum() << endl;
        } break;
 
        case POST: {
-           Snapshots::const_iterator snap2 = sh->createPostSnapshot(snap1);
+           Snapshots::iterator snap2 = sh->createPostSnapshot(snap1);
+           snap2->setCleanup(cleanup);
            if (print_number)
                cout << snap2->getNum() << endl;
            sh->startBackgroundComparsion(snap1, snap2);
@@ -383,6 +394,47 @@ command_rollback()
 }
 
 
+void
+help_cleanup()
+{
+    cout << _("  Cleanup snapshots:") << endl
+        << _("\tsnapper cleanup <cleanup-algorithm>") << endl
+        << endl;
+}
+
+
+void
+command_cleanup()
+{
+    const struct option options[] = {
+       { 0, 0, 0, 0 }
+    };
+
+    GetOpts::parsed_opts opts = getopts.parse("cleanup", options);
+    if (getopts.numArgs() != 1)
+    {
+       cerr << _("Command 'cleanup' needs one arguments.") << endl;
+       exit(EXIT_FAILURE);
+    }
+
+    string cleanup = getopts.popArg();
+
+    if (cleanup == "amount")
+    {
+       sh->doCleanupAmount();
+    }
+    else if (cleanup == "timeline")
+    {
+       sh->doCleanupTimeline();
+    }
+    else
+    {
+       cerr << sformat(_("Unknown cleanup algorithm '%s'."), cleanup.c_str()) << endl;
+       exit(EXIT_FAILURE);
+    }
+}
+
+
 void
 command_help()
 {
@@ -408,6 +460,7 @@ command_help()
     help_delete();
     help_diff();
     help_rollback();
+    help_cleanup();
 }
 
 
@@ -433,6 +486,7 @@ main(int argc, char** argv)
     cmds["delete"] = command_delete;
     cmds["diff"] = command_diff;
     cmds["rollback"] = command_rollback;
+    cmds["cleanup"] = command_cleanup;
     cmds["help"] = command_help;
 
     const struct option options[] = {