summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-03-25 14:22:15 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-03-25 14:22:15 +0100
commitbb36076a03ce7bb40113d618db6d0343b8477c3f (patch)
tree917dbbeadcbfa235434d51891feafc13dfe97e2e /lib
parent7b721840773a6faf2fa93562aeae1cc4c7d05804 (diff)
downloadabrt-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.am9
-rw-r--r--lib/Plugins/rhfastcheck.cpp128
-rw-r--r--lib/Plugins/rhfastcheck.h45
-rw-r--r--lib/Plugins/rhticket.cpp2
-rw-r--r--lib/Utils/Makefile.am1
-rw-r--r--lib/Utils/abrt_curl.cpp7
-rw-r--r--lib/Utils/abrt_rh_support.cpp256
-rw-r--r--lib/Utils/abrt_rh_support.h41
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