diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-25 14:22:15 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-25 14:22:15 +0100 |
commit | bb36076a03ce7bb40113d618db6d0343b8477c3f (patch) | |
tree | 917dbbeadcbfa235434d51891feafc13dfe97e2e /lib | |
parent | 7b721840773a6faf2fa93562aeae1cc4c7d05804 (diff) | |
download | abrt-bb36076a03ce7bb40113d618db6d0343b8477c3f.tar.gz abrt-bb36076a03ce7bb40113d618db6d0343b8477c3f.tar.xz abrt-bb36076a03ce7bb40113d618db6d0343b8477c3f.zip |
rhfastcheck: a new reporter plugin based on Gavin's work
Plugin quickly checks RH support DB for known solutions.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Plugins/Makefile.am | 9 | ||||
-rw-r--r-- | lib/Plugins/rhfastcheck.cpp | 128 | ||||
-rw-r--r-- | lib/Plugins/rhfastcheck.h | 45 | ||||
-rw-r--r-- | lib/Plugins/rhticket.cpp | 2 | ||||
-rw-r--r-- | lib/Utils/Makefile.am | 1 | ||||
-rw-r--r-- | lib/Utils/abrt_curl.cpp | 7 | ||||
-rw-r--r-- | lib/Utils/abrt_rh_support.cpp | 256 | ||||
-rw-r--r-- | lib/Utils/abrt_rh_support.h | 41 |
8 files changed, 485 insertions, 4 deletions
diff --git a/lib/Plugins/Makefile.am b/lib/Plugins/Makefile.am index 0c505fd4..fe6a6d9e 100644 --- a/lib/Plugins/Makefile.am +++ b/lib/Plugins/Makefile.am @@ -11,6 +11,7 @@ pluginslib_LTLIBRARIES = \ libRunApp.la \ libSOSreport.la \ libBugzilla.la \ + librhfastcheck.la \ librhticket.la \ libCatcut.la \ libTicketUploader.la \ @@ -121,6 +122,14 @@ libBugzilla_la_CPPFLAGS = $(XMLRPC_CFLAGS) $(XMLRPC_CLIENT_CFLAGS) \ -I$(srcdir)/../../inc -I$(srcdir)/../Utils -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" +# rhfastcheck +librhfastcheck_la_SOURCES = rhfastcheck.h rhfastcheck.cpp +librhfastcheck_la_LIBADD = +librhfastcheck_la_LDFLAGS = -avoid-version +librhfastcheck_la_CPPFLAGS = \ + -I$(srcdir)/../../inc -I$(srcdir)/../Utils -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ + -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" + # rhticket librhticket_la_SOURCES = rhticket.h rhticket.cpp librhticket_la_LIBADD = diff --git a/lib/Plugins/rhfastcheck.cpp b/lib/Plugins/rhfastcheck.cpp new file mode 100644 index 00000000..1519f87a --- /dev/null +++ b/lib/Plugins/rhfastcheck.cpp @@ -0,0 +1,128 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 RedHat Inc + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "abrtlib.h" +#include "abrt_rh_support.h" +#include "CrashTypes.h" +#include "DebugDump.h" +#include "ABRTException.h" +#include "CommLayerInner.h" +#include "rhfastcheck.h" +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +using namespace std; + +/* + * CReporterRHfastcheck + */ +CReporterRHfastcheck::CReporterRHfastcheck() : + m_bSSLVerify(true), + m_sStrataURL("http://support-services-devel.gss.redhat.com:8080/Strata") +{} + +CReporterRHfastcheck::~CReporterRHfastcheck() +{} + +string CReporterRHfastcheck::Report(const map_crash_data_t& pCrashData, + const map_plugin_settings_t& pSettings, + const char *pArgs) +{ + reportfile_t* file = new_reportfile(); + + // TODO: some files are totally useless: + // "Reported", "Message" (plugin's output), "DumpDir", + // "Description" (package description) - maybe skip those? + map_crash_data_t::const_iterator it = pCrashData.begin(); + for (; it != pCrashData.end(); it++) + { + const char *content = it->second[CD_CONTENT].c_str(); + if (it->second[CD_TYPE] == CD_TXT) + { + reportfile_add_binding_from_string(file, it->first.c_str(), content); + } + else if (it->second[CD_TYPE] == CD_BIN) + { + reportfile_add_binding_from_namedfile(file, content, it->first.c_str(), content, /*binary:*/ 1); + } + } + + update_client(_("Creating a signature...")); + const char* signature = reportfile_as_string(file); + char* result = post_signature(m_sStrataURL.c_str(), signature); + + reportfile_free(file); + string retval = result; + free(result); + + if (strncasecmp(retval.c_str(), "error", 5) == 0) + { + throw CABRTException(EXCEP_PLUGIN, "%s", retval.c_str()); + } + return retval; +} + +void CReporterRHfastcheck::SetSettings(const map_plugin_settings_t& pSettings) +{ + m_pSettings = pSettings; + + map_plugin_settings_t::const_iterator end = pSettings.end(); + map_plugin_settings_t::const_iterator it; + it = pSettings.find("URL"); + if (it != end) + { + m_sStrataURL = 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("SSLVerify"); + if (it != end) + { + m_bSSLVerify = string_to_bool(it->second.c_str()); + } +} + +/* Should not be deleted (why?) */ +const map_plugin_settings_t& CReporterRHfastcheck::GetSettings() +{ + m_pSettings["URL"] = m_sStrataURL; + m_pSettings["Login"] = m_sLogin; + m_pSettings["Password"] = m_sPassword; + m_pSettings["SSLVerify"] = m_bSSLVerify ? "yes" : "no"; + + return m_pSettings; +} + +PLUGIN_INFO(REPORTER, + CReporterRHfastcheck, + "RHfastcheck", + "0.0.4", + "Reports bugs to Red Hat support", + "Denys Vlasenko <dvlasenk@redhat.com>", + "https://fedorahosted.org/abrt/wiki", + "" /*PLUGINS_LIB_DIR"/RHfastcheck.GTKBuilder"*/); diff --git a/lib/Plugins/rhfastcheck.h b/lib/Plugins/rhfastcheck.h new file mode 100644 index 00000000..6cd954dd --- /dev/null +++ b/lib/Plugins/rhfastcheck.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 RedHat Inc + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#ifndef RHFASKCHECK_H_ +#define RHFASKCHECK_H_ + +#include "Plugin.h" +#include "Reporter.h" + +class CReporterRHfastcheck: public CReporter +{ + private: + bool m_bSSLVerify; + std::string m_sStrataURL; + std::string m_sLogin; + std::string m_sPassword; + + public: + CReporterRHfastcheck(); + virtual ~CReporterRHfastcheck(); + + virtual std::string Report(const map_crash_data_t& pCrashData, + const map_plugin_settings_t& pSettings, + const char *pArgs); + + virtual void SetSettings(const map_plugin_settings_t& pSettings); + virtual const map_plugin_settings_t& GetSettings(); +}; + +#endif diff --git a/lib/Plugins/rhticket.cpp b/lib/Plugins/rhticket.cpp index b5abf9df..ab364c26 100644 --- a/lib/Plugins/rhticket.cpp +++ b/lib/Plugins/rhticket.cpp @@ -20,11 +20,11 @@ #define _GNU_SOURCE 1 /* for stpcpy */ #include "abrtlib.h" #include "abrt_curl.h" -#include "rhticket.h" #include "CrashTypes.h" #include "DebugDump.h" #include "ABRTException.h" #include "CommLayerInner.h" +#include "rhticket.h" #ifdef HAVE_CONFIG_H # include <config.h> #endif diff --git a/lib/Utils/Makefile.am b/lib/Utils/Makefile.am index aff324d6..2667b18a 100644 --- a/lib/Utils/Makefile.am +++ b/lib/Utils/Makefile.am @@ -45,6 +45,7 @@ libABRTdUtils_la_SOURCES = \ make_descr.cpp \ CommLayerInner.h CommLayerInner.cpp \ abrt_xmlrpc.h abrt_xmlrpc.cpp \ + abrt_rh_support.h abrt_rh_support.cpp \ abrt_curl.h abrt_curl.cpp \ Plugin.h Plugin.cpp \ Polkit.h Polkit.cpp \ diff --git a/lib/Utils/abrt_curl.cpp b/lib/Utils/abrt_curl.cpp index f327bd8c..6dc8582f 100644 --- a/lib/Utils/abrt_curl.cpp +++ b/lib/Utils/abrt_curl.cpp @@ -69,7 +69,7 @@ save_headers(void *buffer_pv, size_t count, size_t nmemb, void *ptr) char *h = xstrndup((char*)buffer_pv, size); strchrnul(h, '\r')[0] = '\0'; strchrnul(h, '\n')[0] = '\0'; - VERB3 log("save_headers: state:%p header %d: '%s'", state, cnt, h); + VERB3 log("save_headers: header %d: '%s'", cnt, h); state->headers[cnt] = h; state->header_cnt = ++cnt; state->headers[cnt] = NULL; @@ -81,9 +81,9 @@ int curl_post(curl_post_state_t* state, const char* url, const char* data) { CURLcode curl_err; + long response_code; struct curl_slist *httpheader_list = NULL; FILE* body_stream = NULL; - long response_code; curl_post_state_t localstate; VERB3 log("curl_post('%s','%s')", url, data); @@ -95,7 +95,6 @@ curl_post(curl_post_state_t* state, const char* url, const char* data) } state->http_resp_code = response_code = -1; - state->curl_error_msg = NULL; CURL *handle = xcurl_easy_init(); @@ -145,6 +144,8 @@ curl_post(curl_post_state_t* state, const char* url, const char* data) die_if_curl_error(curl_err); state->http_resp_code = response_code; + VERB3 log("after curl_easy_perform: http code %ld body:'%s'", response_code, state->body); + ret: curl_easy_cleanup(handle); curl_slist_free_all(httpheader_list); diff --git a/lib/Utils/abrt_rh_support.cpp b/lib/Utils/abrt_rh_support.cpp new file mode 100644 index 00000000..75f8d863 --- /dev/null +++ b/lib/Utils/abrt_rh_support.cpp @@ -0,0 +1,256 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 RedHat Inc + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +//#define _GNU_SOURCE + +#include <libxml/encoding.h> +#include <libxml/xmlwriter.h> +#include <curl/curl.h> +#include "abrtlib.h" +#include "abrt_xmlrpc.h" +#include "ABRTException.h" +#include "abrt_rh_support.h" + +using namespace std; + +struct reportfile { + xmlTextWriterPtr writer; + xmlBufferPtr buf; +}; + +#define die_xml_oom() error_msg_and_die("can't create XML attribute (out of memory?)") + +static void +xxmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const char *name, const char *content) +{ + // these bright guys REDEFINED CHAR (!) to unsigned char... + if (xmlTextWriterWriteAttribute(writer, (unsigned char*)name, (unsigned char*)content) < 0) + die_xml_oom(); +} + +static void +xxmlTextWriterStartElement(xmlTextWriterPtr writer, const char *name) +{ + if (xmlTextWriterStartElement(writer, (unsigned char*)name) < 0) + die_xml_oom(); +} + +static void +xxmlTextWriterEndElement(xmlTextWriterPtr writer) +{ + if (xmlTextWriterEndElement(writer) < 0) + die_xml_oom(); +} + +// +// End the reportfile, and prepare it for delivery. +// No more bindings can be added after this. +// +static void +close_writer(reportfile_t* file) +{ + if (!file->writer) + return; + + // close off the end of the xml file + int rc = xmlTextWriterEndDocument(file->writer); + if (rc < 0) + die_xml_oom(); + xmlFreeTextWriter(file->writer); + file->writer = NULL; +} + +// +// This allocates a reportfile_t structure and initializes it. +// +reportfile_t* +new_reportfile(void) +{ + // create a new reportfile_t + reportfile_t* file = (reportfile_t*)xmalloc(sizeof(*file)); + + // set up a libxml 'buffer' and 'writer' to that buffer + file->buf = xmlBufferCreate(); + if (file->buf == NULL) + die_xml_oom(); + file->writer = xmlNewTextWriterMemory(file->buf, /*compression:*/ 0); + if (file->writer == NULL) + die_xml_oom(); + + // start a new xml document: + // <report xmlns="http://www.redhat.com/gss/strata">... + int rc = xmlTextWriterStartDocument(file->writer, /*version:*/ NULL, /*encoding:*/ NULL, /*standalone:*/ NULL); + if (rc < 0) + die_xml_oom(); + xxmlTextWriterStartElement(file->writer, "report"); + xxmlTextWriterWriteAttribute(file->writer, "xmlns", "http://www.redhat.com/gss/strata"); + + return file; +} + +static void +internal_reportfile_start_binding(reportfile_t* file, const char* name, int isbinary, const char* filename) +{ + // <binding name=NAME [fileName=FILENAME] type=text/binary... + xxmlTextWriterStartElement(file->writer, "binding"); + xxmlTextWriterWriteAttribute(file->writer, "name", name); + if (filename) + xxmlTextWriterWriteAttribute(file->writer, "fileName", filename); + if (isbinary) + xxmlTextWriterWriteAttribute(file->writer, "type", "binary"); + else + xxmlTextWriterWriteAttribute(file->writer, "type", "text"); +} + +// +// Add a new text binding +// +void +reportfile_add_binding_from_string(reportfile_t* file, const char* name, const char* value) +{ + // <binding name=NAME type=text value=VALUE> + internal_reportfile_start_binding(file, name, /*isbinary:*/ 0, /*filename:*/ NULL); + xxmlTextWriterWriteAttribute(file->writer, "value", value); + xxmlTextWriterEndElement(file->writer); +} + +// +// Add a new binding to a report whose value is represented as a file. +// +void +reportfile_add_binding_from_namedfile(reportfile_t* file, + const char* on_disk_filename, /* unused so far */ + const char* binding_name, + const char* recorded_filename, + int isbinary) +{ + // <binding name=NAME fileName=FILENAME type=text/binary... + internal_reportfile_start_binding(file, binding_name, isbinary, recorded_filename); + // ... href=content/NAME> + string href_name = concat_path_file("content", binding_name); + xxmlTextWriterWriteAttribute(file->writer, "href", href_name.c_str()); +} + +// +// Return the contents of the reportfile as a string. +// +const char* +reportfile_as_string(reportfile_t* file) +{ + close_writer(file); + // unsigned char -> char + return (char*)file->buf->content; +} + +void +reportfile_free(reportfile_t* file) +{ + if (!file) + return; + close_writer(file); + xmlBufferFree(file->buf); + free(file); +} + + +char* +post_signature(const char* baseURL, const char* signature) +{ + string URL = concat_path_file(baseURL, "/signatures"); + + curl_post_state *state = new_curl_post_state(0 + + ABRT_CURL_POST_WANT_HEADERS + + ABRT_CURL_POST_WANT_BODY + + ABRT_CURL_POST_WANT_ERROR_MSG); + int http_resp_code = curl_post(state, URL.c_str(), signature); + + char *retval; + const char *strata_msg; + switch (http_resp_code) + { + case 200: + case 201: + if (state->body) + { + retval = state->body; + state->body = NULL; + break; + } + strata_msg = find_header_in_curl_post_state(state, "Strata-Message:"); + if (strata_msg && strcmp(strata_msg, "CREATED") != 0) { + retval = xstrdup(strata_msg); + break; + } + retval = xstrdup("Signature submitted successfully"); + break; + + default: + strata_msg = find_header_in_curl_post_state(state, "Strata-Message:"); + if (strata_msg) + { + retval = xasprintf("Error (HTTP response %d): %s", + http_resp_code, + strata_msg); + break; + } + retval = xasprintf("Error (HTTP response %d), body:\n%s", http_resp_code, state->body); + } + + free_curl_post_state(state); + return retval; +} + +#if 0 +const char* +create_case(const char* baseURL, const char* description) +{ + const char* URL = concat_path_file(baseURL, "/cases"); + const char* retval; + + response_data_t* response_data = post(URL, description); + if (!response_data) + return NULL; + + switch (response_data->code) { + case 200: + case 201: + if (response_data->body && strlen(response_data->body) > 0) { + retval = response_data->body; + response_data->body = NULL; + } + else + retval = ssprintf("Case Created: %s\n", response_data->location); + break; + default: + if (response_data->strata_message) + retval = ssprintf("Error: %s (http code %ld)", + response_data->strata_message, + response_data->code ); + else + retval = ssprintf("Error: Response Code: %ld\nBody:\n%s", response_data->code, response_data->body); + } + free_curl_post_state(state); + + free((void*)response_data->strata_message); + free((void*)response_data->body); + free((void*)response_data->location); + free((void *)response_data); + free((void*)URL); + return retval; +} +#endif diff --git a/lib/Utils/abrt_rh_support.h b/lib/Utils/abrt_rh_support.h new file mode 100644 index 00000000..567fd0e9 --- /dev/null +++ b/lib/Utils/abrt_rh_support.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2010 ABRT team + Copyright (C) 2010 RedHat Inc + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#ifndef ABRT_RH_SUPPORT_H_ +#define ABRT_RH_SUPPORT_H_ 1 + +typedef struct reportfile reportfile_t; + +reportfile_t *new_reportfile(void); +void reportfile_free(reportfile_t* file); + +void reportfile_add_binding_from_string(reportfile_t* file, const char* name, const char* value); +void reportfile_add_binding_from_namedfile(reportfile_t* file, + const char* on_disk_filename, /* unused so far */ + const char* binding_name, + const char* recorded_filename, + int isbinary); + +const char* reportfile_as_string(reportfile_t* file); + +char* post_signature(const char* baseURL, const char* signature); +#if 0 +char* create_case(const char* baseURL, const char* description); +#endif + +#endif |