diff options
-rw-r--r-- | abrt.spec | 14 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | lib/Plugins/Bugzilla.conf | 6 | ||||
-rw-r--r-- | lib/Plugins/Bugzilla.cpp | 192 | ||||
-rw-r--r-- | lib/Plugins/Bugzilla.h | 47 | ||||
-rw-r--r-- | lib/Plugins/Makefile.am | 13 |
6 files changed, 271 insertions, 3 deletions
@@ -15,6 +15,7 @@ BuildRequires: sqlite-devel > 3.0 BuildRequires: desktop-file-utils BuildRequires: nss-devel BuildRequires: libnotify-devel +BuildRequires: xmlrpc-c-devel BuildRequires: file-devel BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -121,6 +122,14 @@ Requires: %{name} = %{version}-%{release} %description plugin-runapp Plugin to run external programs. +%package plugin-bugzilla +Summary: %{name}'s bugzilla plugin +Group: System Environment/Libraries +Requires: %{name} = %{version}-%{release} + +%description plugin-bugzilla +Plugin to report bugs into the bugzilla. + %prep %setup -q @@ -224,6 +233,11 @@ fi %defattr(-,root,root,-) %{_libdir}/%{name}/libRunApp.so* +%files plugin-bugzilla +%defattr(-,root,root,-) +%config(noreplace) %{_sysconfdir}/%{name}/plugins/Bugzilla.conf +%{_libdir}/%{name}/libBugzilla.so* + %changelog * Fri Apr 10 2009 Jiri Moskovcak <jmoskovc@redhat.com> 0.0.3-1 - new version diff --git a/configure.ac b/configure.ac index 169ec393..ff7da1be 100644 --- a/configure.ac +++ b/configure.ac @@ -21,6 +21,8 @@ PKG_CHECK_MODULES([RPM], [rpm]) PKG_CHECK_MODULES([CURL], [libcurl]) PKG_CHECK_MODULES([LIBNOTIFY], [libnotify]) PKG_CHECK_MODULES([NSS], [nss]) +PKG_CHECK_MODULES([XMLRPC_CPP], [xmlrpc++]) +PKG_CHECK_MODULES([XMLRPC_CLIENT_CPP], [xmlrpc_client++]) AC_CHECK_HEADER([sys/inotify.h], [], [AC_MSG_ERROR([sys/inotify.h is needed to build abrt])]) diff --git a/lib/Plugins/Bugzilla.conf b/lib/Plugins/Bugzilla.conf new file mode 100644 index 00000000..24cc566f --- /dev/null +++ b/lib/Plugins/Bugzilla.conf @@ -0,0 +1,6 @@ +# Bugzila URL +BugzilaURL = https://bugzilla.redhat.com/xmlrpc.cgi +# your login has to exist, if you don have anyone, please create one +Login = +# your password +Password = diff --git a/lib/Plugins/Bugzilla.cpp b/lib/Plugins/Bugzilla.cpp new file mode 100644 index 00000000..bce5286c --- /dev/null +++ b/lib/Plugins/Bugzilla.cpp @@ -0,0 +1,192 @@ +#include "Bugzilla.h" +#include <xmlrpc-c/base.hpp> +#include "CrashTypes.h" +#include "PluginSettings.h" +#include "DebugDump.h" +#include <iostream> + +CReporterBugzilla::CReporterBugzilla() : + m_sBugzillaURL("https://bugzilla.redhat.com/xmlrpc.cgi") +{ + m_pXmlrpcTransport = new xmlrpc_c::clientXmlTransport_curl(); + m_pXmlrpcClient = new xmlrpc_c::client_xml(m_pXmlrpcTransport); + m_pCarriageParm = new xmlrpc_c::carriageParm_curl0(m_sBugzillaURL); +} + +CReporterBugzilla::~CReporterBugzilla() +{ + delete m_pXmlrpcTransport; + delete m_pXmlrpcClient; +} + +void CReporterBugzilla::Login() +{ + xmlrpc_c::paramList paramList; + map_xmlrpc_params_t loginParams; + map_xmlrpc_params_t ret; + loginParams["login"] = xmlrpc_c::value_string(m_sLogin); + loginParams["password"] = xmlrpc_c::value_string(m_sPassword); + paramList.add(xmlrpc_c::value_struct(loginParams)); + xmlrpc_c::rpcPtr rpc(new xmlrpc_c::rpc("User.login", paramList)); + try + { + rpc->call(m_pXmlrpcClient, m_pCarriageParm); + ret = xmlrpc_c::value_struct(rpc->getResult()); + std::cerr << "Login id: " << xmlrpc_c::value_int(ret["id"]) << std::endl; + } + catch (std::exception& e) + { + throw std::string(e.what()); + } +} + +void CReporterBugzilla::Logout() +{ + xmlrpc_c::paramList paramList; + paramList.add(xmlrpc_c::value_string("")); + xmlrpc_c::rpcPtr rpc(new xmlrpc_c::rpc("User.logout", paramList)); + try + { + rpc->call(m_pXmlrpcClient, m_pCarriageParm); + } + catch (std::exception& e) + { + throw std::string(e.what()); + } +} + +bool CReporterBugzilla::CheckUUIDInBugzilla(const std::string& pUUID) +{ + xmlrpc_c::paramList paramList; + map_xmlrpc_params_t searchParams; + map_xmlrpc_params_t ret; + std::string quicksearch = "component:\"abrt\" statuswhiteboard:\""+ pUUID + "\""; + searchParams["quicksearch"] = xmlrpc_c::value_string(quicksearch.c_str()); + paramList.add(xmlrpc_c::value_struct(searchParams)); + xmlrpc_c::rpcPtr rpc(new xmlrpc_c::rpc("Bug.search", paramList)); + try + { + rpc->call(m_pXmlrpcClient, m_pCarriageParm); + } + catch (std::exception& e) + { + throw std::string(e.what()); + } + ret = xmlrpc_c::value_struct(rpc->getResult()); + std::vector<xmlrpc_c::value> bugs = xmlrpc_c::value_array(ret["bugs"]).vectorValueValue(); + if (bugs.size() > 0) + { + return true; + } + return false; +} + +void CReporterBugzilla::CreateNewBugDescription(const map_crash_report_t& pCrashReport, std::string& pDescription) +{ + pDescription = "\nabrt detected crash.\n" + "\nHow to reproduce\n" + + pCrashReport.find(CD_REPRODUCE)->second[CD_CONTENT] + + "\nCommnet\n" + + pCrashReport.find(CD_COMMENT)->second[CD_CONTENT] + + "\nAdditional information\n" + "======\n"; + + map_crash_report_t::const_iterator it; + for (it = pCrashReport.begin(); it != pCrashReport.end(); it++) + { + if (it->second[CD_TYPE] == CD_TXT || it->second[CD_TYPE] == CD_ATT) + { + if (it->first != FILENAME_UUID && + it->first != FILENAME_ARCHITECTURE && + it->first != FILENAME_RELEASE && + it->first != CD_REPRODUCE && + it->first != CD_COMMENT) + { + pDescription += it->first + "\n"; + pDescription += "-----\n"; + pDescription += it->second[CD_CONTENT] + "\n\n"; + } + } + } +} + +void CReporterBugzilla::GetProductAndVersion(const std::string& pRelease, + std::string& pProduct, + std::string& pVersion) +{ + // pattern: Fedora release version (codename) + // TODO: Consider other distribution + pProduct = pRelease.substr(0, pRelease.find(" ")); + pVersion = pRelease.substr(pRelease.find(" ", pRelease.find(" ") + 1) + 1, 2); + if (pVersion == "") + { + pVersion = "rawhide"; + } +} + +void CReporterBugzilla::NewBug(const map_crash_report_t& pCrashReport) +{ + xmlrpc_c::paramList paramList; + map_xmlrpc_params_t bugParams; + map_xmlrpc_params_t ret; + std::string package = pCrashReport.find(FILENAME_PACKAGE)->second[CD_CONTENT]; + std::string component = package.substr(0, package.rfind("-", package.rfind("-")-1)); + std::string description; + std::string release = pCrashReport.find(FILENAME_RELEASE)->second[CD_CONTENT];; + std::string product; + std::string version; + CreateNewBugDescription(pCrashReport, description); + GetProductAndVersion(release, product, version); + + + bugParams["product"] = xmlrpc_c::value_string(product); + bugParams["component"] = xmlrpc_c::value_string(component); + bugParams["version"] = xmlrpc_c::value_string(version); + bugParams["summary"] = xmlrpc_c::value_string("TEST [abrt] crash detected in " + component); + bugParams["description"] = xmlrpc_c::value_string(description); + bugParams["status_whiteboard"] = xmlrpc_c::value_string("abrt_hash:" + pCrashReport.find(FILENAME_UUID)->second[CD_CONTENT]); + bugParams["platform"] = xmlrpc_c::value_string(pCrashReport.find(FILENAME_ARCHITECTURE)->second[CD_CONTENT]); + paramList.add(xmlrpc_c::value_struct(bugParams)); + + xmlrpc_c::rpcPtr rpc(new xmlrpc_c::rpc("Bug.create", paramList)); + try + { + rpc->call(m_pXmlrpcClient, m_pCarriageParm); + ret = xmlrpc_c::value_struct(rpc->getResult()); + std::cerr << "New bug id: " << xmlrpc_c::value_int(ret["id"]) << std::endl; + } + catch (std::exception& e) + { + throw std::string(e.what()); + } + +} + +void CReporterBugzilla::Report(const map_crash_report_t& pCrashReport) +{ + Login(); + if (!CheckUUIDInBugzilla(pCrashReport.find(FILENAME_UUID)->second[CD_CONTENT])) + { + NewBug(pCrashReport); + } + Logout(); +} + +void CReporterBugzilla::LoadSettings(const std::string& pPath) +{ + map_settings_t settings; + plugin_load_settings(pPath, settings); + + if (settings.find("BugzillaURL")!= settings.end()) + { + m_sBugzillaURL = settings["BugzillaURL"]; + } + if (settings.find("Login")!= settings.end()) + { + m_sLogin = settings["Login"]; + } + if (settings.find("Password")!= settings.end()) + { + m_sPassword = settings["Password"]; + } +} diff --git a/lib/Plugins/Bugzilla.h b/lib/Plugins/Bugzilla.h new file mode 100644 index 00000000..53ce05fda --- /dev/null +++ b/lib/Plugins/Bugzilla.h @@ -0,0 +1,47 @@ +#ifndef BUGZILLA_H_ +#define BUGZILLA_H_ + +#include "Plugin.h" +#include "Reporter.h" +#include <xmlrpc-c/client.hpp> + +class CReporterBugzilla : public CReporter +{ + private: + typedef std::map<std::string, xmlrpc_c::value> map_xmlrpc_params_t; + + void Login(); + void Logout(); + bool CheckUUIDInBugzilla(const std::string& pUUID); + void NewBug(const map_crash_report_t& pCrashReport); + void CreateNewBugDescription(const map_crash_report_t& pCrashReport, + std::string& pDescription); + void GetProductAndVersion(const std::string& pRelease, + std::string& pProduct, + std::string& pVersion); + + xmlrpc_c::clientXmlTransport_curl* m_pXmlrpcTransport; + xmlrpc_c::client_xml* m_pXmlrpcClient; + xmlrpc_c::carriageParm_curl0 *m_pCarriageParm; + std::string m_sBugzillaURL; + std::string m_sLogin; + std::string m_sPassword; + + public: + CReporterBugzilla(); + virtual ~CReporterBugzilla(); + virtual void LoadSettings(const std::string& pPath); + virtual void Report(const map_crash_report_t& pCrashReport); +}; + +PLUGIN_INFO(REPORTER, + CReporterBugzilla, + "Bugzilla", + "0.0.1", + "Check if a bug isn't already reported in a bugzilla " + "and if not, report it.", + "zprikryl@redhat.com", + "https://fedorahosted.org/crash-catcher/wiki"); + + +#endif /* BUGZILLA_H_ */ diff --git a/lib/Plugins/Makefile.am b/lib/Plugins/Makefile.am index 5475e32e..4b5697ab 100644 --- a/lib/Plugins/Makefile.am +++ b/lib/Plugins/Makefile.am @@ -6,10 +6,11 @@ pluginslib_LTLIBRARIES = libCCpp.la \ libLogger.la \ libKerneloopsReporter.la\ libKerneloops.la \ - libRunApp.la + libRunApp.la \ + libBugzilla.la pluginsconfdir=$(PLUGINS_CONF_DIR) -dist_pluginsconf_DATA = CCpp.conf Mailx.conf SQLite3.conf Logger.conf Kerneloops.conf KerneloopsReporter.conf +dist_pluginsconf_DATA = CCpp.conf Mailx.conf SQLite3.conf Logger.conf Kerneloops.conf KerneloopsReporter.conf Bugzilla.conf # CCpp libCCpp_la_SOURCES = CCpp.cpp CCpp.h PluginSettings.h @@ -44,4 +45,10 @@ libLogger_la_LDFLAGS = -avoid-version # RunApp libRunApp_la_SOURCES = RunApp.h RunApp.cpp -libRunApp_la_LDFLAGS = -avoid-version
\ No newline at end of file +libRunApp_la_LDFLAGS = -avoid-version + +# Bugzilla +libBugzilla_la_SOURCES = Bugzilla.h Bugzilla.cpp +libBugzilla_la_LIBADD = $(XMLRPC_CPP_LIBS) $(XMLRPC_CLIENT_CPP_LIBS) +libBugzilla_la_LDFLAGS = -avoid-version +libBugzilla_la_CPPFLAGS = $(XMLRPC_CPP_CFLAGS) $(XMLRPC_CLIENT_CPP_CFLAGS) -I$(srcdir)/../MiddleWare -I$(srcdir)/../Utils |