diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-27 14:36:32 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-27 14:36:32 +0100 |
commit | e55e0b21be207ec21bca7cd6c6263a923e974e67 (patch) | |
tree | 07e66c37634fdd7991523d0beb88cd0b3144b486 /lib/Plugins | |
parent | b81581a2e82197325789cb451d5e679e3291278e (diff) | |
download | abrt-e55e0b21be207ec21bca7cd6c6263a923e974e67.tar.gz abrt-e55e0b21be207ec21bca7cd6c6263a923e974e67.tar.xz abrt-e55e0b21be207ec21bca7cd6c6263a923e974e67.zip |
adding experimental Catcut plugin. Run-tested
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'lib/Plugins')
-rw-r--r-- | lib/Plugins/Catcut.conf | 8 | ||||
-rw-r--r-- | lib/Plugins/Catcut.cpp | 365 | ||||
-rw-r--r-- | lib/Plugins/Catcut.h | 26 | ||||
-rw-r--r-- | lib/Plugins/Makefile.am | 11 |
4 files changed, 409 insertions, 1 deletions
diff --git a/lib/Plugins/Catcut.conf b/lib/Plugins/Catcut.conf new file mode 100644 index 00000000..456d7f82 --- /dev/null +++ b/lib/Plugins/Catcut.conf @@ -0,0 +1,8 @@ +# Catcut URL +CatcutURL = http://127.0.0.1:8080/catcut/xmlrpc +# yes means that ssl certificates will not be checked +NoSSLVerify = no +# your login has to exist, if you don have any, please create one +Login = gavin +# your password +Password = junk diff --git a/lib/Plugins/Catcut.cpp b/lib/Plugins/Catcut.cpp new file mode 100644 index 00000000..078ac404 --- /dev/null +++ b/lib/Plugins/Catcut.cpp @@ -0,0 +1,365 @@ +#include <xmlrpc-c/base.h> +#include <xmlrpc-c/client.h> + +#include "abrtlib.h" +#include "Catcut.h" +#include "CrashTypes.h" +#include "DebugDump.h" +#include "ABRTException.h" +#include "CommLayerInner.h" +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +using namespace std; + +static xmlrpc_env env; +static xmlrpc_client* client = NULL; +static struct xmlrpc_clientparms clientParms; +static struct xmlrpc_curl_xportparms curlParms; +static xmlrpc_server_info* server_info = NULL; + + +static string login(const char* login, const char* passwd); +//static void logout(); +static void new_xmlrpc_client(const char* url, bool no_ssl_verify); +static void destroy_xmlrpc_client(); +static void create_new_bug_description(const map_crash_report_t& pCrashReport, string& pDescription); +static void get_product_and_version(const string& pRelease, + string& pProduct, + string& pVersion); + + +static void throw_if_fault_occurred(xmlrpc_env* e) +{ + if (e->fault_occurred) + { + string errmsg = ssprintf("XML-RPC Fault: %s(%d)", e->fault_string, e->fault_code); + error_msg("%s", errmsg.c_str()); // show error in daemon log + throw CABRTException(EXCEP_PLUGIN, errmsg); + } +} + +static void new_xmlrpc_client(const char* url, bool no_ssl_verify) +{ + xmlrpc_env_init(&env); + xmlrpc_client_setup_global_const(&env); + + curlParms.network_interface = NULL; + curlParms.no_ssl_verifypeer = no_ssl_verify; + curlParms.no_ssl_verifyhost = no_ssl_verify; +#ifdef VERSION + curlParms.user_agent = PACKAGE_NAME"/"VERSION; +#else + curlParms.user_agent = "abrt"; +#endif + + clientParms.transport = "curl"; + clientParms.transportparmsP = &curlParms; + clientParms.transportparm_size = XMLRPC_CXPSIZE(user_agent); + + xmlrpc_client_create(&env, XMLRPC_CLIENT_NO_FLAGS, PACKAGE_NAME, VERSION, &clientParms, XMLRPC_CPSIZE(transportparm_size), + &client); + throw_if_fault_occurred(&env); + + server_info = xmlrpc_server_info_new(&env, url); + throw_if_fault_occurred(&env); +} + +static void destroy_xmlrpc_client() +{ + xmlrpc_server_info_free(server_info); + xmlrpc_env_clean(&env); + xmlrpc_client_destroy(client); + xmlrpc_client_teardown_global_const(); +} + +static string login(const char* login, const char* passwd) +{ + xmlrpc_value* param = xmlrpc_build_value(&env, "(ss)", login, passwd); + throw_if_fault_occurred(&env); + + xmlrpc_value* result = NULL; /* paranoia */ + xmlrpc_client_call2(&env, client, server_info, "Catcut.auth", param, &result); + throw_if_fault_occurred(&env); + xmlrpc_DECREF(param); + + const char *cookie = NULL; + xmlrpc_value *cookie_xml = NULL; + xmlrpc_struct_find_value(&env, result, "cookie", &cookie_xml); + throw_if_fault_occurred(&env); + if (cookie_xml) + { + xmlrpc_read_string(&env, cookie_xml, &cookie); + throw_if_fault_occurred(&env); + xmlrpc_DECREF(cookie_xml); + } + + xmlrpc_DECREF(result); + return cookie ? cookie : ""; +} + +// catcut does not have it (yet?) +//static void logout() +//{ +// xmlrpc_value* param = xmlrpc_build_value(&env, "(s)", ""); +// throw_if_fault_occurred(&env); +// +// xmlrpc_value* result = NULL; /* paranoia */ +// xmlrpc_client_call2(&env, client, server_info, "User.logout", param, &result); +// throw_if_fault_occurred(&env); +//} + +static void create_new_bug_description(const map_crash_report_t& pCrashReport, string& pDescription) +{ + string howToReproduce; + string comment; + + if (pCrashReport.find(CD_REPRODUCE) != pCrashReport.end()) + { + howToReproduce = "\n\nHow to reproduce\n" + "-----\n" + + pCrashReport.find(CD_REPRODUCE)->second[CD_CONTENT]; + } + if (pCrashReport.find(CD_COMMENT) != pCrashReport.end()) + { + comment = "\n\nComment\n" + "-----\n" + + pCrashReport.find(CD_COMMENT)->second[CD_CONTENT]; + } + pDescription = "\nabrt detected a crash.\n" + + howToReproduce + + comment + + "\n\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) + { + if (it->first != CD_UUID && + it->first != FILENAME_ARCHITECTURE && + it->first != FILENAME_RELEASE && + it->first != CD_REPRODUCE && + it->first != CD_COMMENT) + { + pDescription += "\n" + it->first + "\n"; + pDescription += "-----\n"; + pDescription += it->second[CD_CONTENT] + "\n\n"; + } + } + else if (it->second[CD_TYPE] == CD_ATT) + { + pDescription += "\n\nAttached files\n" + "----\n"; + pDescription += it->first + "\n"; + } + else if (it->second[CD_TYPE] == CD_BIN) + { + string msg = ssprintf(_("Binary file %s will not be reported."), it->first.c_str()); + warn_client(msg); + //update_client(_("Binary file ")+it->first+_(" will not be reported.")); + } + } +} + +static void get_product_and_version(const string& pRelease, + string& pProduct, + string& pVersion) +{ + if (pRelease.find("Rawhide") != string::npos) + { + pProduct = "Fedora"; + pVersion = "rawhide"; + return; + } + if (pRelease.find("Fedora") != string::npos) + { + pProduct = "Fedora"; + } + else if (pRelease.find("Red Hat Enterprise Linux") != string::npos) + { + pProduct = "Red Hat Enterprise Linux "; + } + string::size_type pos = pRelease.find("release"); + pos = pRelease.find(" ", pos) + 1; + while (pRelease[pos] != ' ') + { + pVersion += pRelease[pos]; + if (pProduct == "Red Hat Enterprise Linux ") + { + pProduct += pRelease[pos]; + } + pos++; + } +} + +static string new_bug(const char *auth_cookie, const map_crash_report_t& pCrashReport) +{ + string package = pCrashReport.find(FILENAME_PACKAGE)->second[CD_CONTENT]; + string component = pCrashReport.find(FILENAME_COMPONENT)->second[CD_CONTENT]; + string release = pCrashReport.find(FILENAME_RELEASE)->second[CD_CONTENT]; + string arch = pCrashReport.find(FILENAME_ARCHITECTURE)->second[CD_CONTENT]; + string uuid = pCrashReport.find(CD_UUID)->second[CD_CONTENT]; + + string summary = "[abrt] crash detected in " + package; + string status_whiteboard = "abrt_hash:" + uuid; + + string description; + create_new_bug_description(pCrashReport, description); + + string product; + string version; + get_product_and_version(release, product, version); + + xmlrpc_value *param = xmlrpc_build_value(&env, "(s{s:s,s:s,s:s,s:s,s:s,s:s,s:s})", + auth_cookie, + "product", product.c_str(), + "component", component.c_str(), + "version", version.c_str(), + "summary", summary.c_str(), + "description", description.c_str(), + "status_whiteboard", status_whiteboard.c_str(), + "platform", arch.c_str() + ); + throw_if_fault_occurred(&env); + + xmlrpc_value *result = NULL; + xmlrpc_client_call2(&env, client, server_info, "Catcut.createTicket", param, &result); + throw_if_fault_occurred(&env); + xmlrpc_DECREF(param); + + const char *bug_id = NULL; + xmlrpc_value *bug_id_xml = NULL; + xmlrpc_struct_find_value(&env, result, "ticket", &bug_id_xml); + throw_if_fault_occurred(&env); + if (bug_id_xml) + { + xmlrpc_read_string(&env, bug_id_xml, &bug_id); + throw_if_fault_occurred(&env); + xmlrpc_DECREF(bug_id_xml); + log("New bug id: %s", bug_id); + update_client(_("New bug id: ") + string(bug_id)); + } + + xmlrpc_DECREF(result); + return bug_id; +} + +//static +//void add_attachments(const string& pBugId, const map_crash_report_t& pCrashReport) +//{ +// xmlrpc_value* result = NULL; +// +// map_crash_report_t::const_iterator it = pCrashReport.begin(); +// for (; it != pCrashReport.end(); it++) +// { +// if (it->second[CD_TYPE] == CD_ATT) +// { +// string description = "File: " + it->first; +// const string& to_encode = it->second[CD_CONTENT]; +// char *encoded64 = encode_base64(to_encode.c_str(), to_encode.length()); +// xmlrpc_value* param = xmlrpc_build_value(&env,"(s{s:s,s:s,s:s,s:s})", +// pBugId.c_str(), +// "description", description.c_str(), +// "filename", it->first.c_str(), +// "contenttype", "text/plain", +// "data", encoded64 +// ); +// free(encoded64); +// throw_if_fault_occurred(&env); +// +//// catcut has this API: +//// struct response requestUpload(string cookie, string ticket, string filename, string description) +////response MUST include "errno", "errmsg" members; if an upload is approved, +////a "URL" MUST be returned in the response. The description string +////should include a brief description of the file. +//// +////The client should upload the file via HTTP PUT to the provided +////URL. The provided URL may be absolute or relative, if relative it must +////be combined with the base URL of the XML-RPC server using the usual +////rules for relative URL's (RFC 3986). +// xmlrpc_client_call2(&env, client, server_info, "catcut.addAttachment", param, &result); +// throw_if_fault_occurred(&env); +// } +// } +//} + +CReporterCatcut::CReporterCatcut() : + m_sCatcutURL("http://127.0.0.1:8080/catcut/xmlrpc"), + m_bNoSSLVerify(false) +{} + +CReporterCatcut::~CReporterCatcut() +{} + +string CReporterCatcut::Report(const map_crash_report_t& pCrashReport, const string& pArgs) +{ + update_client(_("Creating new bug...")); + try + { + new_xmlrpc_client(m_sCatcutURL.c_str(), m_bNoSSLVerify); + string auth_cookie = login(m_sLogin.c_str(), m_sPassword.c_str()); + string bug_id = (auth_cookie != "") ? new_bug(auth_cookie.c_str(), pCrashReport) : ""; +// add_attachments(to_string(bug_id), pCrashReport); +// update_client(_("Logging out...")); +// logout(); + destroy_xmlrpc_client(); + return "New catcut bug ID: " + bug_id; + + } + catch (CABRTException& e) + { + destroy_xmlrpc_client(); + throw CABRTException(EXCEP_PLUGIN, string("CReporterCatcut::Report(): ") + e.what()); + } +} + +void CReporterCatcut::SetSettings(const map_plugin_settings_t& pSettings) +{ + map_plugin_settings_t::const_iterator it; + map_plugin_settings_t::const_iterator end = pSettings.end(); + + it = pSettings.find("CatcutURL"); + if (it != end) + { + m_sCatcutURL = it->second; + } + it = pSettings.find("Login"); + if (it != end) + { + m_sLogin = it->second; + } + it = pSettings.find("Password"); + if (it != end) + { + m_sPassword = it->second; + } + it = pSettings.find("NoSSLVerify"); + if (it != end) + { + m_bNoSSLVerify = it->second == "yes"; + } +} + +map_plugin_settings_t CReporterCatcut::GetSettings() +{ + map_plugin_settings_t ret; + + ret["CatcutURL"] = m_sCatcutURL; + ret["Login"] = m_sLogin; + ret["Password"] = m_sPassword; + ret["NoSSLVerify"] = m_bNoSSLVerify ? "yes" : "no"; + + return ret; +} + +PLUGIN_INFO(REPORTER, + CReporterCatcut, + "Catcut", + "0.0.1", + "Test plugin to report bugs to catcut and if not, report it.", + "dvlasenk@redhat.com", + "https://fedorahosted.org/abrt/wiki", + PLUGINS_LIB_DIR"/Catcut.GTKBuilder"); diff --git a/lib/Plugins/Catcut.h b/lib/Plugins/Catcut.h new file mode 100644 index 00000000..69380387 --- /dev/null +++ b/lib/Plugins/Catcut.h @@ -0,0 +1,26 @@ +#ifndef CATCUT_H_ +#define CATCUT_H_ + +#include "Plugin.h" +#include "Reporter.h" + +class CReporterCatcut : public CReporter +{ + private: + std::string m_sCatcutURL; + std::string m_sLogin; + std::string m_sPassword; + bool m_bNoSSLVerify; + + public: + CReporterCatcut(); + virtual ~CReporterCatcut(); + + virtual void SetSettings(const map_plugin_settings_t& pSettings); + virtual map_plugin_settings_t GetSettings(); + + virtual std::string Report(const map_crash_report_t& pCrashReport, + const std::string& pArgs); +}; + +#endif /* CATCUT_H_ */ diff --git a/lib/Plugins/Makefile.am b/lib/Plugins/Makefile.am index cf46aeea..9165f63c 100644 --- a/lib/Plugins/Makefile.am +++ b/lib/Plugins/Makefile.am @@ -10,19 +10,22 @@ pluginslib_LTLIBRARIES = libCCpp.la \ libRunApp.la \ libSOSreport.la \ libBugzilla.la \ + libCatcut.la \ libTicketUploader.la \ libPython.la \ libFileTransfer.la dist_pluginslib_DATA = KerneloopsReporter.GTKBuilder Logger.GTKBuilder Mailx.GTKBuilder Bugzilla.GTKBuilder TicketUploader.GTKBuilder +# + Catcut.GTKBuilder? pluginsconfdir=$(PLUGINS_CONF_DIR) -dist_pluginsconf_DATA = CCpp.conf Mailx.conf SQLite3.conf Logger.conf KerneloopsScanner.conf KerneloopsReporter.conf Bugzilla.conf TicketUploader.conf FileTransfer.conf +dist_pluginsconf_DATA = CCpp.conf Mailx.conf SQLite3.conf Logger.conf KerneloopsScanner.conf KerneloopsReporter.conf Bugzilla.conf Catcut.conf TicketUploader.conf FileTransfer.conf man_MANS = abrt-FileTransfer.7 abrt-Bugzilla.7 abrt-KerneloopsReporter.7\ abrt-KerneloopsScanner.7 abrt-Logger.7 abrt-Mailx.7 abrt-plugins.7\ abrt-SQLite3.7 abrt-RunApp.7 abrt-TicketUploader.7 +# + abrt-Catcut.7 EXTRA_DIST = $(man_MANS) @@ -84,6 +87,12 @@ libBugzilla_la_LIBADD = $(XMLRPC_LIBS) $(XMLRPC_CLIENT_LIBS) libBugzilla_la_LDFLAGS = -avoid-version libBugzilla_la_CPPFLAGS = $(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) -I$(srcdir)/../../inc -I$(srcdir)/../Utils -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" +# Catcut +libCatcut_la_SOURCES = Catcut.h Catcut.cpp +libCatcut_la_LIBADD = $(XMLRPC_LIBS) $(XMLRPC_CLIENT_LIBS) +libCatcut_la_LDFLAGS = -avoid-version +libCatcut_la_CPPFLAGS = $(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) -I$(srcdir)/../../inc -I$(srcdir)/../Utils -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" + # TicketUploader libTicketUploader_la_SOURCES = TicketUploader.h TicketUploader.cpp libTicketUploader_la_LDFLAGS = -avoid-version |