[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