]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
- support weekly snapshots in cleanup algorithm
authorArvin Schnell <aschnell@suse.de>
Thu, 11 Dec 2014 17:01:42 +0000 (18:01 +0100)
committerArvin Schnell <aschnell@suse.de>
Thu, 11 Dec 2014 17:01:42 +0000 (18:01 +0100)
client/cleanup.cc
client/utils/Makefile.am
client/utils/equal-date.cc [new file with mode: 0644]
client/utils/equal-date.h [new file with mode: 0644]
data/default-config
doc/snapper-configs.xml.in
doc/snapper.xml.in
package/snapper.changes
testsuite/.gitignore
testsuite/Makefile.am
testsuite/equal-date.cc [new file with mode: 0644]

index cd48e70db97ed9e07452613b8afcf1a25bd8d186..8d2d77c7b86802a53162e56d8f3fe4fae327897f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) [2011-2013] Novell, Inc.
+ * Copyright (c) [2011-2014] Novell, Inc.
  *
  * All Rights Reserved.
  *
@@ -24,6 +24,8 @@
 
 #include <snapper/SnapperTmpl.h>
 
+#include "utils/equal-date.h"
+
 #include "commands.h"
 
 using namespace std;
@@ -188,31 +190,6 @@ is_first(list<XSnapshots::const_iterator>::const_iterator first,
 }
 
 
-bool
-equal_year(const struct tm& tmp1, const struct tm& tmp2)
-{
-    return tmp1.tm_year == tmp2.tm_year;
-}
-
-bool
-equal_month(const struct tm& tmp1, const struct tm& tmp2)
-{
-    return equal_year(tmp1, tmp2) && tmp1.tm_mon == tmp2.tm_mon;
-}
-
-bool
-equal_day(const struct tm& tmp1, const struct tm& tmp2)
-{
-    return equal_month(tmp1, tmp2) && tmp1.tm_mday == tmp2.tm_mday;
-}
-
-bool
-equal_hour(const struct tm& tmp1, const struct tm& tmp2)
-{
-    return equal_day(tmp1, tmp2) && tmp1.tm_hour == tmp2.tm_hour;
-}
-
-
 bool
 is_first_yearly(list<XSnapshots::const_iterator>::const_iterator first,
                list<XSnapshots::const_iterator>::const_iterator last,
@@ -229,6 +206,14 @@ is_first_monthly(list<XSnapshots::const_iterator>::const_iterator first,
     return is_first(first, last, it1, equal_month);
 }
 
+bool
+is_first_weekly(list<XSnapshots::const_iterator>::const_iterator first,
+               list<XSnapshots::const_iterator>::const_iterator last,
+               XSnapshots::const_iterator it1)
+{
+    return is_first(first, last, it1, equal_week);
+}
+
 bool
 is_first_daily(list<XSnapshots::const_iterator>::const_iterator first,
               list<XSnapshots::const_iterator>::const_iterator last,
@@ -253,6 +238,7 @@ do_cleanup_timeline(DBus::Connection& conn, const string& config_name)
     size_t limit_hourly = 10;
     size_t limit_daily = 10;
     size_t limit_monthly = 10;
+    size_t limit_weekly = 0;
     size_t limit_yearly = 10;
 
     XConfigInfo ci = command_get_xconfig(conn, config_name);
@@ -263,6 +249,8 @@ do_cleanup_timeline(DBus::Connection& conn, const string& config_name)
        pos->second >> limit_hourly;
     if ((pos = ci.raw.find("TIMELINE_LIMIT_DAILY")) != ci.raw.end())
        pos->second >> limit_daily;
+    if ((pos = ci.raw.find("TIMELINE_LIMIT_WEEKLY")) != ci.raw.end())
+       pos->second >> limit_weekly;
     if ((pos = ci.raw.find("TIMELINE_LIMIT_MONTHLY")) != ci.raw.end())
        pos->second >> limit_monthly;
     if ((pos = ci.raw.find("TIMELINE_LIMIT_YEARLY")) != ci.raw.end())
@@ -270,6 +258,7 @@ do_cleanup_timeline(DBus::Connection& conn, const string& config_name)
 
     size_t num_hourly = 0;
     size_t num_daily = 0;
+    size_t num_weekly = 0;
     size_t num_monthly = 0;
     size_t num_yearly = 0;
 
@@ -298,6 +287,11 @@ do_cleanup_timeline(DBus::Connection& conn, const string& config_name)
            ++num_daily;
            keep = true;
        }
+       if (num_weekly < limit_weekly && is_first_weekly(it, tmp.end(), *it))
+       {
+           ++num_weekly;
+           keep = true;
+       }
        if (num_monthly < limit_monthly && is_first_monthly(it, tmp.end(), *it))
        {
            ++num_monthly;
index aeda1fae15f59c8b836a4cfb2fab79e57dfe481c..020137dcf1bd077ca308b429a2c8453f222569c7 100644 (file)
@@ -10,6 +10,7 @@ libutils_la_SOURCES =                 \
        Table.cc        Table.h         \
        text.cc         text.h          \
        console.cc      console.h       \
+       equal-date.cc   equal-date.h    \
        GetOpts.cc      GetOpts.h
 
 libutils_la_LIBADD = ../../snapper/libsnapper.la
diff --git a/client/utils/equal-date.cc b/client/utils/equal-date.cc
new file mode 100644 (file)
index 0000000..b367c64
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) [2011-2014] Novell, Inc.
+ *
+ * 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 <time.h>
+
+#include "equal-date.h"
+
+
+int
+yday_of_weeks_monday(const struct tm& tmp)
+{
+    return tmp.tm_yday - (tmp.tm_wday != 0 ? tmp.tm_wday : 7);
+}
+
+
+int
+days_in_year(const struct tm& tmp)
+{
+    return __isleap(tmp.tm_year) ? 366 : 365;
+}
+
+
+bool
+equal_year(const struct tm& tmp1, const struct tm& tmp2)
+{
+    return tmp1.tm_year == tmp2.tm_year;
+}
+
+
+bool
+equal_month(const struct tm& tmp1, const struct tm& tmp2)
+{
+    return equal_year(tmp1, tmp2) && tmp1.tm_mon == tmp2.tm_mon;
+}
+
+
+bool
+equal_week(const struct tm& tmp1, const struct tm& tmp2)
+{
+    if (tmp1.tm_year == tmp2.tm_year)
+        return yday_of_weeks_monday(tmp1) == yday_of_weeks_monday(tmp2);
+
+    if (tmp1.tm_year + 1 == tmp2.tm_year)
+        return yday_of_weeks_monday(tmp1) == yday_of_weeks_monday(tmp2) + days_in_year(tmp1);
+
+    if (tmp1.tm_year == tmp2.tm_year + 1)
+        return yday_of_weeks_monday(tmp1) + days_in_year(tmp2) == yday_of_weeks_monday(tmp2);
+
+    return false;
+}
+
+
+bool
+equal_day(const struct tm& tmp1, const struct tm& tmp2)
+{
+    return equal_month(tmp1, tmp2) && tmp1.tm_mday == tmp2.tm_mday;
+}
+
+
+bool
+equal_hour(const struct tm& tmp1, const struct tm& tmp2)
+{
+    return equal_day(tmp1, tmp2) && tmp1.tm_hour == tmp2.tm_hour;
+}
diff --git a/client/utils/equal-date.h b/client/utils/equal-date.h
new file mode 100644 (file)
index 0000000..51ec49a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) [2011-2014] Novell, Inc.
+ *
+ * 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.
+ */
+
+
+bool
+equal_year(const struct tm& tmp1, const struct tm& tmp2);
+
+bool
+equal_month(const struct tm& tmp1, const struct tm& tmp2);
+
+bool
+equal_week(const struct tm& tmp1, const struct tm& tmp2);
+
+bool
+equal_day(const struct tm& tmp1, const struct tm& tmp2);
+
+bool
+equal_hour(const struct tm& tmp1, const struct tm& tmp2);
+
index 76ddd47e4985c3f631af86ad3f752d7fbc76e157..1e3b78d2a164a453be1c99955d70c492d91f734b 100644 (file)
@@ -39,6 +39,7 @@ TIMELINE_CLEANUP="yes"
 TIMELINE_MIN_AGE="1800"
 TIMELINE_LIMIT_HOURLY="10"
 TIMELINE_LIMIT_DAILY="10"
+TIMELINE_LIMIT_WEEKLY="0"
 TIMELINE_LIMIT_MONTHLY="10"
 TIMELINE_LIMIT_YEARLY="10"
 
index 538fb4d0ec60679d9a88a445fe1e6a8dec85828e..9713bbc619bf31d92ebb299a68fb1abffd1a1b06 100644 (file)
        </listitem>
       </varlistentry>
 
+      <varlistentry>
+       <term><option>TIMELINE_LIMIT_WEEKLY=<replaceable>number</replaceable></option></term>
+       <listitem>
+         <para>Defines how many weekly snapshots the timeline cleanup
+         algorithm should keep. A weekly snapshot is the first snapshot in a week. The
+         youngest weekly snapshots will be kept.</para>
+         <para>Default value is &quot;0&quot;.</para>
+       </listitem>
+      </varlistentry>
+
       <varlistentry>
        <term><option>TIMELINE_LIMIT_MONTHLY=<replaceable>number</replaceable></option></term>
        <listitem>
index 09d17051c70dbd09d852e64c05a1511fddc3dc19..e1572a2aa848f1188c812169030d748d14f4bcf9 100644 (file)
          <glossterm>timeline</glossterm>
          <glossdef>
            <para>Deletes old snapshots but keeps a number of hourly, daily,
-           monthly and yearly snapshots.</para>
+           weekly, monthly and yearly snapshots.</para>
          </glossdef>
        </glossentry>
        <glossentry>
index d849f8b420ef3829f53978cc4bdb9b572225dba6..b9aad17f69c629fa95c0cf77bbd09ac3854b7791 100644 (file)
@@ -1,3 +1,9 @@
+-------------------------------------------------------------------
+Thu Dec 11 17:58:14 CET 2014 - aschnell@suse.de
+
+- support weekly snapshots in cleanup algorithm (see
+  gh#openSUSE/snapper#135)
+
 -------------------------------------------------------------------
 Thu Oct 23 12:05:12 CEST 2014 - aschnell@suse.de
 
index 39d94e9f803951c022b578d44a2c096173f434ad..85f0d0bb78cba94421ffa6230127e37b9342adb1 100644 (file)
@@ -1,7 +1,5 @@
 *.log
 *.o
+*.test
 *.trs
-basename1
-dirname1
-sysconfig-get1
 test-suite.log
index df6db5a14c3a4a141deb5bdaa32153496691a94e..f0f38d8de4684ae1cf7fc5ba439dd1eeb21a1c50 100644 (file)
@@ -6,7 +6,7 @@ INCLUDES = -I$(top_srcdir)
 
 LDADD = ../snapper/libsnapper.la -lboost_unit_test_framework
 
-check_PROGRAMS = sysconfig-get1 dirname1 basename1
+check_PROGRAMS = sysconfig-get1.test dirname1.test basename1.test equal-date.test
 
 TESTS = $(check_PROGRAMS)
 
@@ -14,3 +14,5 @@ AM_DEFAULT_SOURCE_EXT = .cc
 
 EXTRA_DIST = $(noinst_SCRIPTS) sysconfig-get1.txt
 
+equal_date_test_LDADD = -lboost_unit_test_framework ../client/utils/libutils.la
+
diff --git a/testsuite/equal-date.cc b/testsuite/equal-date.cc
new file mode 100644 (file)
index 0000000..42e00d8
--- /dev/null
@@ -0,0 +1,70 @@
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE snapper
+
+#include <boost/test/unit_test.hpp>
+
+#include "../client/utils/equal-date.h"
+
+
+bool
+equal_week(const char* s1, const char* s2)
+{
+    struct tm tmp1;
+    memset(&tmp1, 0, sizeof(tmp1));
+    strptime(s1, "%Y-%m-%d", &tmp1);
+
+    struct tm tmp2;
+    memset(&tmp2, 0, sizeof(tmp2));
+    strptime(s2, "%Y-%m-%d", &tmp2);
+
+    return equal_week(tmp1, tmp2);
+}
+
+
+BOOST_AUTO_TEST_CASE(test1)
+{
+    // 2012 is a leap year
+    BOOST_CHECK(equal_week("2011-12-31", "2012-01-01"));
+    BOOST_CHECK(equal_week("2012-01-01", "2011-12-31"));
+}
+
+
+BOOST_AUTO_TEST_CASE(test2)
+{
+    // 2012 is a leap year
+    BOOST_CHECK(equal_week("2012-12-31", "2013-01-01"));
+    BOOST_CHECK(equal_week("2013-01-01", "2012-12-31"));
+}
+
+
+BOOST_AUTO_TEST_CASE(test3)
+{
+    // Saturday and Sunday
+    BOOST_CHECK(equal_week("2014-01-04", "2014-01-05"));
+    BOOST_CHECK(equal_week("2014-01-05", "2014-01-04"));
+
+    // Sunday and Monday
+    BOOST_CHECK(!equal_week("2014-01-05", "2014-01-06"));
+    BOOST_CHECK(!equal_week("2014-01-06", "2014-01-05"));
+
+    // Monday and Tuesday
+    BOOST_CHECK(equal_week("2014-01-06", "2014-01-07"));
+    BOOST_CHECK(equal_week("2014-01-07", "2014-01-06"));
+}
+
+
+BOOST_AUTO_TEST_CASE(test4)
+{
+    // 2014-12-31 is a Wednesday, 2015-01-01 is a Thursday
+    BOOST_CHECK(equal_week("2014-12-31", "2015-01-01"));
+    BOOST_CHECK(equal_week("2015-01-01", "2014-12-31"));
+}
+
+
+BOOST_AUTO_TEST_CASE(test5)
+{
+    // 2017-12-31 is a Sunday, 2018-01-01 is a Monday
+    BOOST_CHECK(!equal_week("2017-12-31", "2018-01-01"));
+    BOOST_CHECK(!equal_week("2018-01-01", "2017-12-31"));
+}