Write userdata string to history log (fate#312521)
authorMichael Andres <ma@suse.de>
Fri, 23 Nov 2012 16:58:11 +0000 (17:58 +0100)
committerMichael Andres <ma@suse.de>
Fri, 23 Nov 2012 17:00:32 +0000 (18:00 +0100)
doc/autoinclude/UserData.doc
doc/autoinclude/g_ZyppHistory.doc [new file with mode: 0644]
doc/autoinclude/groups.doc
zypp/HistoryLog.cc
zypp/HistoryLog.h
zypp/HistoryLogData.h
zypp/parser/HistoryLogReader.cc
zypp/parser/HistoryLogReader.h

index 737d71e..cd7d544 100644 (file)
@@ -12,4 +12,6 @@ It is possible to store a user defined data string via \ref zypp::ZConfig::setUs
 
 \li The user data string will also be passed to commit plugins, so they can make use of it. The btrfs e.g would be able to tag created snapshots with this string. \see \ref plugin-commit
 
+\li The user data string will appear on each histoy line logging package or repository related events (install, delete, add, modify). \see \ref zypp::HistoryLog and zypp::parser::HistoryLogReader
+
 */
diff --git a/doc/autoinclude/g_ZyppHistory.doc b/doc/autoinclude/g_ZyppHistory.doc
new file mode 100644 (file)
index 0000000..c701713
--- /dev/null
@@ -0,0 +1,89 @@
+/** \defgroup g_ZyppHistory Libzypp History File
+
+Log important events like installation/deletion of packages and repositories.
+
+
+\section g_ZyppHistory_Location Location
+
+The default location is \c /var/log/zypp/history. This can be changed via \c history.logfile key in \c /etc/zypp/zypp.conf.
+
+
+\section g_ZyppHistory_Format Format
+
+\li CSV file with pipe character (|) as the value separator
+\li one event per line
+\li different actions have different set of values (columns), see the tables below
+\li lines starting with # are treated as comments
+
+\see \ref zypp-userdata
+
+\subsection g_ZyppHistory_Format_Colummn Action Columns
+
+\subsubsection g_ZyppHistory_Format_Colummn_Install Install
+A package has been installed.
+\li \b 1 timestamp
+\li \b 2 action ID (\c "install")
+\li \b 3 package name
+\li \b 4 package epoch:version-release
+\li \b 5 package architecture
+\li \b 6 requested by (user@hostname, pid:appname, or empty (solver))
+\li \b 7 repository alias
+\li \b 8 package checksum
+\li \b 9 userdata/transactionId
+
+\subsubsection g_ZyppHistory_Format_Colummn_Remove Remove
+A package has been removed.
+\li \b 1 timestamp
+\li \b 2 action ID (\c "remove")
+\li \b 3 package name
+\li \b 4 package epoch:version-release
+\li \b 5 package architecture
+\li \b 6 requested by (user@hostname, pid:appname, or empty (solver))
+\li \b 7 userdata/transactionId
+
+\subsubsection g_ZyppHistory_Format_Colummn_Radd Radd
+A repository has been added.
+\li \b 1 timestamp
+\li \b 2 action ID (\c "radd")
+\li \b 3 repository alias
+\li \b 4 primary URL
+\li \b 5 userdata/transactionId
+
+\subsubsection g_ZyppHistory_Format_Colummn_Rremove Rremove
+A repository has been removed.
+\li \b 1 timestamp
+\li \b 2 action ID (\c "rremove")
+\li \b 3 repository alias
+\li \b 4 userdata/transactionId
+
+\subsubsection g_ZyppHistory_Format_Colummn_Ralias Ralias
+A repository alias has changed.
+\li \b 1 timestamp
+\li \b 2 action ID (\c "ralias")
+\li \b 3 old alias
+\li \b 4 new alias
+\li \b 5 userdata/transactionId
+
+\subsubsection g_ZyppHistory_Format_Colummn_Rurl Rurl
+The primary URL of a repository has changed.
+\li \b 1 timestamp
+\li \b 2 action ID (\c "rurl")
+\li \b 3 repository alias
+\li \b 4 new URL
+\li \b 5 userdata/transactionId
+
+
+\section g_ZyppHistory_Example Example
+
+\code
+2008-09-24 11:48:58|rremove|packman
+2008-09-24 11:50:02|radd   |packman|http://packman.iu-bremen.de/suse/11.0
+2008-09-24 11:53:10|install|amarok-yauap|1.4.10-25|x86_64||factory|4421dfa718ab73c805c1c695c97b1b67f39bf2f3
+2008-09-24 11:53:25|install|amarok-lang|1.4.10-25|x86_64||factory|691030edafcc4fbc22aa225350f9de32974e4bc2
+# Additional rpm output:
+# warning: /var/cache/zypp/packages/packman/x86_64/amarok-1.4.10-100.pm.1.x86_64.rpm: Header V3 DSA signature: NOKEY, key ID 9a795806
+#
+2008-09-24 11:53:45|install|amarok|1.4.10-100.pm.1|x86_64|root@kompost|packman|ee0fffa1e4eeaaeb8799bd05c6882ef74100d681
+\endcode
+
+*/
index 84c0a69..4369f48 100644 (file)
@@ -23,3 +23,6 @@
 /*! \defgroup g_Algorithm Algorithms
 */
 ////////////////////////////////////////////////////////////////////////////////
+/*! \defgroup g_Parser Parser
+*/
+////////////////////////////////////////////////////////////////////////////////
index d1c96ba..5f1a8fd 100644 (file)
@@ -192,27 +192,25 @@ namespace zypp
       return;
 
     _log
-      << timestamp()                                   // 1 timestamp
-      << _sep << HistoryActionID::INSTALL.asString(true) // 2 action
-      << _sep << p->name()                             // 3 name
-      << _sep << p->edition()                          // 4 evr
-      << _sep << p->arch();                            // 5 arch
+      << timestamp()                                                   // 1 timestamp
+      << _sep << HistoryActionID::INSTALL.asString(true)               // 2 action
+      << _sep << p->name()                                             // 3 name
+      << _sep << p->edition()                                          // 4 evr
+      << _sep << p->arch();                                            // 5 arch
 
     // ApplLow is what the solver selected on behalf of the user.
     if (pi.status().isByUser() || pi.status().isByApplLow() )
-      _log << _sep << userAtHostname();                // 6 reqested by
+      _log << _sep << userAtHostname();                                        // 6 reqested by
     else if (pi.status().isByApplHigh())
       _log << _sep << pidAndAppname();
     else
       _log << _sep;
 
     _log
-      << _sep << p->repoInfo().alias()                 // 7 repo alias
-      << _sep << p->checksum().checksum();             // 8 checksum
-
-    _log << endl;
-
-    //_log << pi << endl;
+      << _sep << p->repoInfo().alias()                                 // 7 repo alias
+      << _sep << p->checksum().checksum()                              // 8 checksum
+      << _sep << str::escape(ZConfig::instance().userData(), _sep)     // 9 userdata
+      << endl;
   }
 
 
@@ -223,26 +221,23 @@ namespace zypp
       return;
 
     _log
-      << timestamp()                                   // 1 timestamp
-      << _sep << HistoryActionID::REMOVE.asString(true) // 2 action
-      << _sep << p->name()                             // 3 name
-      << _sep << p->edition()                          // 4 evr
-      << _sep << p->arch();                            // 5 arch
+      << timestamp()                                                   // 1 timestamp
+      << _sep << HistoryActionID::REMOVE.asString(true)                        // 2 action
+      << _sep << p->name()                                             // 3 name
+      << _sep << p->edition()                                          // 4 evr
+      << _sep << p->arch();                                            // 5 arch
 
     // ApplLow is what the solver selected on behalf of the user.
     if ( pi.status().isByUser() || pi.status().isByApplLow() )
-      _log << _sep << userAtHostname();                // 6 reqested by
+      _log << _sep << userAtHostname();                                        // 6 reqested by
     else if (pi.status().isByApplHigh())
       _log << _sep << pidAndAppname();
     else
       _log << _sep;
 
-    // we don't have checksum in rpm db
-    //  << _sep << p->checksum().checksum();           // x checksum
-
-    _log << endl;
-
-    //_log << pi << endl;
+    _log
+      << _sep << str::escape(ZConfig::instance().userData(), _sep)     // 7 userdata
+      << endl;
   }
 
   /////////////////////////////////////////////////////////////////////////
@@ -250,11 +245,11 @@ namespace zypp
   void HistoryLog::addRepository(const RepoInfo & repo)
   {
     _log
-      << timestamp()                                   // 1 timestamp
-      << _sep << HistoryActionID::REPO_ADD.asString(true) // 2 action
-      << _sep << str::escape(repo.alias(), _sep)       // 3 alias
-      // what about the rest of the URLs??
-      << _sep << *repo.baseUrlsBegin()                 // 4 primary URL
+      << timestamp()                                                   // 1 timestamp
+      << _sep << HistoryActionID::REPO_ADD.asString(true)              // 2 action
+      << _sep << str::escape(repo.alias(), _sep)                       // 3 alias
+      << _sep << *repo.baseUrlsBegin()                                 // 4 primary URL
+      << _sep << str::escape(ZConfig::instance().userData(), _sep)     // 5 userdata
       << endl;
   }
 
@@ -262,9 +257,10 @@ namespace zypp
   void HistoryLog::removeRepository(const RepoInfo & repo)
   {
     _log
-      << timestamp()                                   // 1 timestamp
-      << _sep << HistoryActionID::REPO_REMOVE.asString(true) // 2 action
-      << _sep << str::escape(repo.alias(), _sep)       // 3 alias
+      << timestamp()                                                   // 1 timestamp
+      << _sep << HistoryActionID::REPO_REMOVE.asString(true)           // 2 action
+      << _sep << str::escape(repo.alias(), _sep)                       // 3 alias
+      << _sep << str::escape(ZConfig::instance().userData(), _sep)     // 4 userdata
       << endl;
   }
 
@@ -275,20 +271,21 @@ namespace zypp
     if (oldrepo.alias() != newrepo.alias())
     {
       _log
-        << timestamp()                                    // 1 timestamp
-        << _sep << HistoryActionID::REPO_CHANGE_ALIAS.asString(true) // 2 action
-        << _sep << str::escape(oldrepo.alias(), _sep)     // 3 old alias
-        << _sep << str::escape(newrepo.alias(), _sep)     // 4 new alias
+        << timestamp()                                                 // 1 timestamp
+        << _sep << HistoryActionID::REPO_CHANGE_ALIAS.asString(true)   // 2 action
+        << _sep << str::escape(oldrepo.alias(), _sep)                  // 3 old alias
+        << _sep << str::escape(newrepo.alias(), _sep)                  // 4 new alias
+        << _sep << str::escape(ZConfig::instance().userData(), _sep)   // 5 userdata
         << endl;
     }
-
     if (*oldrepo.baseUrlsBegin() != *newrepo.baseUrlsBegin())
     {
       _log
-        << timestamp()                                             //1 timestamp
-        << _sep << HistoryActionID::REPO_CHANGE_URL.asString(true) // 2 action
-        << _sep << str::escape(oldrepo.alias(), _sep)              // 3 old url
-        << _sep << *newrepo.baseUrlsBegin()                        // 4 new url
+        << timestamp()                                                 // 1 timestamp
+        << _sep << HistoryActionID::REPO_CHANGE_URL.asString(true)     // 2 action
+        << _sep << str::escape(oldrepo.alias(), _sep)                  // 3 old url
+        << _sep << *newrepo.baseUrlsBegin()                            // 4 new url
+        << _sep << str::escape(ZConfig::instance().userData(), _sep)   // 5 userdata
         << endl;
     }
   }
index e2c0152..9ac4959 100644 (file)
@@ -22,40 +22,36 @@ namespace zypp
   class RepoInfo;
 
   ///////////////////////////////////////////////////////////////////
-  //
-  //   CLASS NAME : HistoryLog
-  /**
-   * Simple wrapper for progress log. Refcnt, filename and corresponding
-   * ofstream are static members. Logfile constructor raises, destructor
-   * lowers refcounter. On refcounter changing from 0->1, file is opened.
-   * Changing from 1->0 the file is closed. Thus Logfile objects should be
-   * local to those functions, writing the log, and must not be stored
-   * permanently.
-   *
-   * Usage:
-   * <code>
-   *  some method ()
-   *  {
-   *    PoolItem pi;
-   *    ...
-   *    HistoryLog().install(pi);
-   *    ...
-   *    HistoryLog().comment(someMessage);
-   *  }
-   * </code>
-   *
-   * \note Take care to set proper target root dir if needed. Either pass
-   *       it via the constructor, or set it via setRoot(Pathname) method.
-   *       The default location of the file is determined by
-   *       \ref ZConfig::historyLogPath() which defaults to
-   *       /var/log/zypp/history.
-   *
-   * \see http://en.opensuse.org/Libzypp/Package_History
-   *
-   * \todo The implementation as pseudo signleton is questionable.
-   * Use shared_ptr instead of handcrafted ref/unref. Manage multiple
-   * logs at different locations.
-   */
+  /// \class HistoryLog
+  /// \brief Writing the zypp history file
+  /// \ingroup g_ZyppHistory
+  ///
+  /// Reference counted signleton for writhing the zypp history file.
+  /// The history file is opened on demand and closed when the last
+  /// HistoryLog object drops its reference. Thus HistoryLog objects
+  /// should be local to those functions, writing the log, and must
+  /// not be stored permanently.
+  ///
+  /// \code
+  /// some method ()
+  /// {
+  ///   PoolItem pi;
+  ///   ...
+  ///   HistoryLog().install(pi);
+  ///   ...
+  ///   HistoryLog().comment(someMessage);
+  /// }
+  /// \endcode
+  ///
+  /// \note Take care to set proper target root dir if needed. Either pass
+  /// it via the constructor, or set it via setRoot(Pathname) method.
+  /// The default location of the file is determined by
+  /// \ref zypp::ZConfig::historyLogPath (default: \c /var/log/zypp/history).
+  ///
+  /// \todo The implementation as pseudo signleton is questionable.
+  /// Use shared_ptr instead of handcrafted ref/unref. Manage multiple
+  /// logs at different locations.
+  ///////////////////////////////////////////////////////////////////
   class HistoryLog
   {
     HistoryLog( const HistoryLog & );
index c542ef4..8ce5880 100644 (file)
 
 namespace zypp
 {
-
-
   ///////////////////////////////////////////////////////////////////
-  //
-  //  CLASS NAME : HistoryActionID
-  //
-  /**
-   * Enumeration of known history actions.
-   *
-   * \ingroup g_EnumerationClass
-   */
+  /// \class HistoryActionID
+  /// \brief Enumeration of known history actions.
+  /// \ingroup g_EnumerationClass
+  /// \ingroup g_ZyppHistory
+  ///////////////////////////////////////////////////////////////////
   struct HistoryActionID
   {
     static const HistoryActionID NONE;
index 99e0748..a3d2ff5 100644 (file)
@@ -89,6 +89,9 @@ namespace zypp
     case HistoryActionID::REPO_CHANGE_URL_e:
       return HistoryItemRepoUrlChange::Ptr( new HistoryItemRepoUrlChange( fields ) );
       break;
+
+    case HistoryActionID::NONE_e:
+      break;
     }
     return HistoryItem::Ptr();
   }
index e31eb91..b8941dd 100644 (file)
@@ -29,47 +29,40 @@ namespace zypp
   namespace parser
   { /////////////////////////////////////////////////////////////////
 
-
+  ///////////////////////////////////////////////////////////////////
+  /// \class HistoryLogReader
+  /// \brief Zypp history file parser
+  /// \ingroup g_ZyppHistory
+  /// \ingroup g_ZyppParser
+  ///
+  /// Reads a zypp history log file and calls the ProcessItem function
+  /// passed in the constructor for each item read.
+  ///
+  /// \code
+  /// struct HistoryItemCollector
+  /// {
+  ///   vector<HistoryItem::Ptr> items;
+  ///
+  ///   bool operator()( const HistoryItem::Ptr & item_ptr )
+  ///   {
+  ///     items.push_back(item_ptr);
+  ///     return true;
+  ///   }
+  /// }
+  /// ...
+  /// HistoryItemCollector ic;
+  /// HistoryLogReader reader("/var/log/zypp/history", boost::ref(ic));
+  ///
+  /// try
+  /// {
+  ///   reader.readAll();
+  /// }
+  /// catch (const Exception & e)
+  /// {
+  ///   cout << e.asUserHistory() << endl;
+  /// }
+  /// \endcode
   /////////////////////////////////////////////////////////////////////
-  //
-  // CLASS NAME: HistoryLogReader
-  //
-  /**
-   * Reads a zypp history log file and calls the ProcessItem function passed
-   * in the constructor for each item read.
-   *
-   * Example:
-   * <code>
-   *
-   * struct HistoryItemCollector
-   * {
-   *   vector<HistoryItem::Ptr> items;
-   *
-   *   bool operator()( const HistoryItem::Ptr & item_ptr )
-   *   {
-   *     items.push_back(item_ptr);
-   *     return true;
-   *   }
-   * }
-   *
-   * ...
-   *
-   * HistoryItemCollector ic;
-   * HistoryLogReader reader("/var/log/zypp/history", boost::ref(ic));
-   *
-   * try
-   * {
-   *   reader.readAll();
-   * }
-   * catch (const Exception & e)
-   * {
-   *   cout << e.asUserHistory() << endl;
-   * }
-   *
-   * </code>
-   *
-   * \see http://en.opensuse.org/Libzypp/Package_History
-   */
   class HistoryLogReader
   {
   public: