summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--abrt.spec14
-rw-r--r--configure.ac2
-rw-r--r--lib/Plugins/Bugzilla.conf6
-rw-r--r--lib/Plugins/Bugzilla.cpp192
-rw-r--r--lib/Plugins/Bugzilla.h47
-rw-r--r--lib/Plugins/Makefile.am13
6 files changed, 271 insertions, 3 deletions
diff --git a/abrt.spec b/abrt.spec
index a9b72f79..5e12fd36 100644
--- a/abrt.spec
+++ b/abrt.spec
@@ -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