[buildd-tools-devel] [PATCH 4/6] Add creation and last-run date to session keyfile.

Jan-Marek Glogowski glogow at fbihome.de
Tue Jun 28 10:27:56 UTC 2011


Adds 'creation-date' and 'last-run-date' to the session keyfile
and updates the 'last-run-date' before and after a session run.
---
 debian/changelog                      |    4 +-
 sbuild/sbuild-chroot-facet-session.cc |   89 ++++++++++++++++++++++++++++++++-
 sbuild/sbuild-chroot-facet-session.h  |   44 ++++++++++++++++
 sbuild/sbuild-chroot.cc               |   90 ++++++++++++++++++++------------
 sbuild/sbuild-chroot.h                |   27 +++++++++-
 sbuild/sbuild-session.cc              |   29 ++++++++++-
 test/Makefile.am                      |    2 +-
 test/test-sbuild-chroot.h             |    8 +++
 8 files changed, 253 insertions(+), 40 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 6bc21d8..99bcabc 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -7,8 +7,10 @@ schroot (1.4.24-1) unstable; urgency=low
     - Drop sbuild-types.c.
     - Convert code to use Boost.Date_Time for all dates.
   * Don't include facet-source-clonable data in sessions.
+  * Include session creation and last-run date in session keyfile:
+    - Update session keyfile before and after session run.
 
- -- Jan-Marek Glogowski <jan-marek.glogowski at muenchen.de>  Thu, 23 Jun 2011 15:31:19 +0200
+ -- Jan-Marek Glogowski <jan-marek.glogowski at muenchen.de>  Thu, 23 Jun 2011 16:05:10 +0200
 
 schroot (1.4.23-1) unstable; urgency=low
 
diff --git a/sbuild/sbuild-chroot-facet-session.cc b/sbuild/sbuild-chroot-facet-session.cc
index 4b72a6f..57df478 100644
--- a/sbuild/sbuild-chroot-facet-session.cc
+++ b/sbuild/sbuild-chroot-facet-session.cc
@@ -33,14 +33,18 @@
 #include <cassert>
 
 #include <boost/format.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
 
 using boost::format;
 using std::endl;
 using namespace sbuild;
+using namespace boost::posix_time;
 
 chroot_facet_session::chroot_facet_session ():
   chroot_facet(),
-  original_chroot_name()
+  original_chroot_name(),
+  creation_date(),
+  last_run_date()
 {
 }
 
@@ -80,6 +84,64 @@ chroot_facet_session::set_original_name (std::string const& name)
   this->original_chroot_name = name;
 }
 
+std::string const&
+chroot_facet_session::get_creation_date () const
+{
+  return this->creation_date;
+}
+
+void
+chroot_facet_session::set_creation_date (std::string const& date_str)
+{
+  if (date_str.empty())
+    {
+      this->creation_date = date_str;
+      return;
+    }
+
+  try
+    {
+      ptime pt(time_from_string(date_str));
+      this->creation_date = to_simple_string(pt);
+    }
+  catch(std::exception& e)
+    {
+      this->creation_date = "invalid";
+    }
+}
+
+std::string const&
+chroot_facet_session::get_last_run_date () const
+{
+  return this->last_run_date;
+}
+
+void
+chroot_facet_session::set_last_run_date (std::string const& date_str)
+{
+  if (date_str.empty())
+    {
+      this->last_run_date = date_str;
+      return;
+    }
+
+  try
+    {
+      ptime pt(time_from_string(date_str));
+      this->last_run_date = to_simple_string(pt);
+    }
+  catch(std::exception& e)
+    {
+      this->last_run_date = "invalid";
+    }
+}
+
+void
+chroot_facet_session::set_last_run_date ()
+{
+  this->last_run_date = to_simple_string(second_clock::local_time());
+}
+
 void
 chroot_facet_session::setup_env (chroot const& chroot,
 				 environment&  env) const
@@ -104,6 +166,11 @@ chroot_facet_session::get_details (chroot const&  chroot,
     detail.add(_("Original Chroot Name"), get_original_name());
   if (!chroot.get_name().empty())
     detail.add(_("Session ID"), chroot.get_name());
+  if (!get_creation_date().empty() || !get_last_run_date().empty())
+    {
+      detail.add(_("Session Creation Date"), get_creation_date());
+      detail.add(_("Last Session Run Date"), get_last_run_date());
+    }
 }
 
 void
@@ -113,6 +180,14 @@ chroot_facet_session::get_keyfile (chroot const& chroot,
   keyfile::set_object_value(*this, &chroot_facet_session::get_original_name,
 			    keyfile, chroot.get_name(),
 			    "original-name");
+
+  keyfile::set_object_value(*this, &chroot_facet_session::get_creation_date,
+			    keyfile, chroot.get_name(),
+			    "creation-date");
+
+  keyfile::set_object_value(*this, &chroot_facet_session::get_last_run_date,
+			    keyfile, chroot.get_name(),
+			    "last-run-date");
 }
 
 void
@@ -163,4 +238,16 @@ chroot_facet_session::set_keyfile (chroot&        chroot,
 			    "original-name",
 			    keyfile::PRIORITY_OPTIONAL);
   used_keys.push_back("original-name");
+
+  keyfile::get_object_value(*this, &chroot_facet_session::set_creation_date,
+			    keyfile, chroot.get_name(),
+			    "creation-date",
+                            keyfile::PRIORITY_OPTIONAL);
+  used_keys.push_back("creation-date");
+
+  keyfile::get_object_value(*this, &chroot_facet_session::set_last_run_date,
+			    keyfile, chroot.get_name(),
+			    "last-run-date",
+                            keyfile::PRIORITY_OPTIONAL);
+  used_keys.push_back("last-run-date");
 }
diff --git a/sbuild/sbuild-chroot-facet-session.h b/sbuild/sbuild-chroot-facet-session.h
index 2a6dcc1..cc16d83 100644
--- a/sbuild/sbuild-chroot-facet-session.h
+++ b/sbuild/sbuild-chroot-facet-session.h
@@ -79,6 +79,46 @@ namespace sbuild
     void
     set_original_name (std::string const& name);
 
+    /**
+     * Get the session creation date.
+     *
+     * @returns the session creation date.
+     */
+    std::string const&
+    get_creation_date () const;
+
+    /**
+     * Set the session creation date.
+     *
+     * @param date the date of the session creation.
+     */
+    void
+    set_creation_date (std::string const& date);
+
+    /**
+     * Get the last session run date.
+     *
+     * @returns the date when the session was last run.
+     */
+    std::string const&
+    get_last_run_date () const;
+
+    /**
+     * Set the last session run date.
+     *
+     * @param date the date when the session was last run.
+     */
+    void
+    set_last_run_date (std::string const& date);
+
+    /**
+     * Set the last session run date.
+     *
+     * Convenient function to set the current date.
+     */
+    void
+    set_last_run_date ();
+
     virtual void
     setup_env (chroot const& chroot,
 	       environment&  env) const;
@@ -102,6 +142,10 @@ namespace sbuild
   private:
     /// Original chroot name prior to session cloning.
     std::string  original_chroot_name;
+    /// UTC date when session got created as to_simple_string.
+    std::string  creation_date;
+    /// UTC date when session was last run as to_simple_string.
+    std::string  last_run_date;
   };
 
 }
diff --git a/sbuild/sbuild-chroot.cc b/sbuild/sbuild-chroot.cc
index 8069401..228f0e4 100644
--- a/sbuild/sbuild-chroot.cc
+++ b/sbuild/sbuild-chroot.cc
@@ -515,55 +515,77 @@ sbuild::chroot::setup_env (chroot const& chroot,
 	  static_cast<bool>(chroot.get_session_flags() & SESSION_PURGE));
 }
 
+inline std::string get_session_filename(sbuild::chroot const& chroot)
+{
+  return std::string(SCHROOT_SESSION_DIR) + "/" + chroot.get_name();
+}
+
 void
-sbuild::chroot::setup_session_info (bool start)
+sbuild::chroot::write_session_info (bool update)
 {
-  /* Create or unlink session information. */
-  std::string file = std::string(SCHROOT_SESSION_DIR) + "/" + get_name();
+  std::string file = get_session_filename(*this);
 
-  if (start)
+  int fd;
+  if (update)
+    fd = open(file.c_str(), O_WRONLY|O_TRUNC, 0664);
+  else
+    fd = open(file.c_str(), O_CREAT|O_EXCL|O_WRONLY, 0664);
+
+  if (fd < 0)
+    throw error(file, SESSION_WRITE, strerror(errno));
+
+  // Create a stream buffer from the file descriptor.  The fd will
+  // be closed when the buffer is destroyed.
+  __gnu_cxx::stdio_filebuf<char> fdbuf(fd, std::ios::out);
+  std::ostream output(&fdbuf);
+  output.imbue(std::locale::classic());
+
+  file_lock lock(fd);
+  try
     {
-      int fd = open(file.c_str(), O_CREAT|O_EXCL|O_WRONLY, 0664);
-      if (fd < 0)
-	throw error(file, SESSION_WRITE, strerror(errno));
-
-      // Create a stream buffer from the file descriptor.  The fd will
-      // be closed when the buffer is destroyed.
-      __gnu_cxx::stdio_filebuf<char> fdbuf(fd, std::ios::out);
-      std::ostream output(&fdbuf);
-      output.imbue(std::locale::classic());
-
-      file_lock lock(fd);
-      try
-	{
-	  lock.set_lock(lock::LOCK_EXCLUSIVE, 2);
-	}
-      catch (lock::error const& e)
-	{
-	  throw error(file, FILE_LOCK, e);
-	}
+      lock.set_lock(lock::LOCK_EXCLUSIVE, 2);
+    }
+  catch (lock::error const& e)
+    {
+      throw error(file, FILE_LOCK, e);
+    }
 
-      keyfile details;
-      get_keyfile(details);
-      output << details;
+  keyfile details;
+  get_keyfile(details);
+  output << details;
 
-      try
-	{
-	  lock.unset_lock();
-	}
-      catch (lock::error const& e)
-	{
-	  throw error(file, FILE_UNLOCK, e);
-	}
+  try
+    {
+      lock.unset_lock();
+    }
+  catch (lock::error const& e)
+    {
+      throw error(file, FILE_UNLOCK, e);
+    }
+}
+
+void
+sbuild::chroot::setup_session_info (bool start)
+{
+  if (start)
+    {
+      write_session_info(false);
     }
   else /* start == false */
     {
+      std::string file = get_session_filename(*this);
       if (unlink(file.c_str()) != 0)
 	throw error(file, SESSION_UNLINK, strerror(errno));
     }
 }
 
 void
+sbuild::chroot::update_session_info ()
+{
+  write_session_info(true);
+}
+
+void
 sbuild::chroot::lock (setup_type type)
 {
   setup_lock(type, true, 0);
diff --git a/sbuild/sbuild-chroot.h b/sbuild/sbuild-chroot.h
index 6fde87a..eb29d4e 100644
--- a/sbuild/sbuild-chroot.h
+++ b/sbuild/sbuild-chroot.h
@@ -534,16 +534,41 @@ namespace sbuild
     unlock (setup_type type,
 	    int        status);
 
+    /**
+     * Updates the session information (session file).
+     *
+     * Same as setup_session_info(true), except the file has to exists.
+     *
+     * @see setup_session_info
+     */
+    virtual void
+    update_session_info ();
+
   protected:
     /**
      * Set up persistent session information.
      *
-     * @param start true if startion, or false if ending a session.
+     * @param start true if writing session info (e.g. on start, run),
+     *              otherwise deleting the session file (ending).
      */
     virtual void
     setup_session_info (bool start);
 
     /**
+     * Write session information to the file descriptor.
+     *
+     * Convenience function called by setup_session_info and
+     * update_session_info to write the session information to the
+     * session file.
+     *
+     * @param update false to force file creation, otherwise expect existing
+                     session file.
+     * @see setup_session_info
+     */
+    virtual void
+    write_session_info (bool update);
+
+    /**
      * Unlock a chroot during setup.  The locking technique (if any) may
      * vary depending upon the chroot type and setup stage.  For
      * example, during creation of an LVM snapshot a block device
diff --git a/sbuild/sbuild-session.cc b/sbuild/sbuild-session.cc
index 8b05ebe..62570f5 100644
--- a/sbuild/sbuild-session.cc
+++ b/sbuild/sbuild-session.cc
@@ -50,10 +50,13 @@
 #include <syslog.h>
 
 #include <boost/format.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
 
 using std::cout;
 using std::endl;
 using boost::format;
+using boost::posix_time::second_clock;
+using boost::posix_time::to_simple_string;
 using namespace sbuild;
 
 namespace
@@ -626,6 +629,9 @@ session::run_impl ()
 	  chroot::ptr chroot(ch->clone());
 	  assert(chroot);
 
+	  // Session facet for runtime updates.
+	  chroot_facet_session::ptr psess;
+
 	  /* Create a session using randomly-generated session ID. */
 	  if (ch->get_session_flags() & chroot::SESSION_CREATE)
 	    {
@@ -657,9 +663,14 @@ session::run_impl ()
 	      chroot = ch->clone_session(new_session_id,
 					 this->authstat->get_ruser(),
 					 (in_root_users || in_root_groups));
-	      assert(chroot->get_facet<chroot_facet_session>());
+	      assert(chroot);
+	      psess = chroot->get_facet<chroot_facet_session>();
+	      assert(psess);
+	      psess->set_creation_date(
+		to_simple_string(second_clock::local_time()));
 	    }
-	  assert(chroot);
+	  else
+	    psess = chroot->get_facet<chroot_facet_session>();
 
 	  // Override chroot verbosity if needed.
 	  if (!this->verbosity.empty())
@@ -687,6 +698,13 @@ session::run_impl ()
 	      if (this->session_operation == OPERATION_AUTOMATIC ||
 		  this->session_operation == OPERATION_RUN)
 		{
+		  /* Update last session run time before execution. */
+		  if (psess)
+		    {
+		      psess->set_last_run_date();
+		      chroot->update_session_info();
+		    }
+
 		  try
 		    {
 		      this->authstat->open_session();
@@ -701,6 +719,13 @@ session::run_impl ()
 		      this->authstat->close_session();
 		      throw;
 		    }
+
+		  /* Update last session run time on successful end. */
+		  if (psess)
+		    {
+		      psess->set_last_run_date();
+		      chroot->update_session_info();
+		    }
 		  restore_termios();
 		  this->authstat->close_session();
 		}
diff --git a/test/Makefile.am b/test/Makefile.am
index 003f7f2..3ea76a5 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -76,7 +76,7 @@ endif
 libtest_la_SOURCES = 	\
 	test-helpers.h	\
 	testmain.cc
-libtest_la_LIBADD = $(top_builddir)/sbuild/libsbuild.la $(CPPUNIT_LIBS)
+libtest_la_LIBADD = $(top_builddir)/sbuild/libsbuild.la $(CPPUNIT_LIBS) $(BOOST_DATE_TIME_LIBS)
 
 if BUILD_BLOCKDEV
 sbuild_chroot_blockdev_sources =	\
diff --git a/test/test-sbuild-chroot.h b/test/test-sbuild-chroot.h
index b665144..21d22d9 100644
--- a/test/test-sbuild-chroot.h
+++ b/test/test-sbuild-chroot.h
@@ -209,6 +209,8 @@ public:
     keyfile.set_value(group, "root-users", "");
     keyfile.set_value(group, "groups", "");
     keyfile.set_value(group, "root-groups", "");
+    keyfile.set_value(group, "creation-date", "");
+    keyfile.set_value(group, "last-run-date", "");
   }
 
   void setup_keyfile_union_unconfigured (sbuild::keyfile&   keyfile,
@@ -412,6 +414,12 @@ public:
 	 pos != expected_keys.end();
 	 ++pos)
       {
+	// Start date is set on session creation, so it always varies.
+	// Same for last run date.
+	// -> skip value check
+	if ((*pos == "creation-date") || (*pos == "last-run-date"))
+	  continue;
+
 	std::string expected_val;
 	CPPUNIT_ASSERT(expected_keyfile.get_value(expected_group,
 						  *pos, expected_val) == true);
-- 
1.7.2.5




More information about the Buildd-tools-devel mailing list