for now bodhi plugin has only two possibilities how to search updates.
1) give bodhi bugzilla id and if bz id is associate to any updates it returns
them, otherwise json-c dies on sigsegv (bug filled, but maybe I'll have to fix it)
2) give bodhi name of the package
Working on: -r, --release (f14, f15, ...); -s, --status (stable, update, pending)
Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
.gitignore | 1 +
abrt.spec.in | 26 ++++-
configure.ac | 11 ++
src/plugins/Makefile.am | 57 +++++++---
src/plugins/abrt-action-bodhi.c | 241 +++++++++++++++++++++++++++++++++++++++
5 files changed, 319 insertions(+), 17 deletions(-)
create mode 100644 src/plugins/abrt-action-bodhi.c
diff --git a/.gitignore b/.gitignore
index a0c88d8..08df83f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,7 @@ src/plugins/abrt-action-generate-backtrace
src/plugins/abrt-action-upload
src/plugins/abrt-action-mailx
src/plugins/abrt-action-print
+src/plugins/abrt-action-bodhi
src/plugins/abrt-dump-oops
src/plugins/abrt-action-install-debuginfo-to-abrt-cache
src/plugins/abrt-retrace-client
diff --git a/abrt.spec.in b/abrt.spec.in
index d36a4d3..d8c05de 100644
--- a/abrt.spec.in
+++ b/abrt.spec.in
@@ -38,7 +38,7 @@ BuildRequires: asciidoc
BuildRequires: xmlto
# for rhel6
-%if 0%{?rhel} >= 6
+%if 0%{?rhel}
BuildRequires: gnome-keyring-devel
%else
BuildRequires: libgnome-keyring-devel
@@ -170,6 +170,18 @@ Requires: mailx
The simple reporter plugin which sends a report via mailx to a specified
email address.
+%if 0%{?fedora}
+%package plugin-bodhi
+Summary: %{name}'s bodhi plugin
+BuildRequires: json-c-devel
+Group: System Environment/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description plugin-bodhi
+Search for a new updates in bodhi
+%endif
+
+
%package plugin-bugzilla
Summary: %{name}'s bugzilla plugin
Group: System Environment/Libraries
@@ -264,7 +276,13 @@ generation service over a network using HTTP protocol.
%build
autoconf
+
+%if 0%{?rhel}
+%configure --disable-bodhi
+%else
%configure
+%endif
+
sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g'
libtool
sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
CFLAGS="-fno-strict-aliasing"
@@ -549,6 +567,12 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null ||
:
%{_bindir}/abrt-action-print
%{_mandir}/man*/abrt-action-print.*
+%if 0%{?fedora}
+%files plugin-bodhi
+%defattr(-,root,root,-)
+%{_bindir}/abrt-action-bodhi
+%endif
+
%files plugin-mailx
%defattr(-,root,root,-)
%{_sysconfdir}/%{name}/events/report_Mailx.xml
diff --git a/configure.ac b/configure.ac
index c568c43..71cff83 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,6 +20,9 @@ AC_ARG_ENABLE(debug,
[Enable debug information])],
[CFLAGS="$CFLAGS -DDEBUG -ggdb -g"])
+AC_ARG_ENABLE([bodhi],
+ AC_HELP_STRING([--disable-bodhi], [do not use bodhi plugin]))
+
dnl ****** INTERNATIONALIZATION **********************
GETTEXT_PACKAGE=abrt
AC_SUBST(GETTEXT_PACKAGE)
@@ -67,6 +70,14 @@ PKG_CHECK_MODULES([NSS], [nss])
PKG_CHECK_MODULES([XMLRPC], [xmlrpc])
PKG_CHECK_MODULES([XMLRPC_CLIENT], [xmlrpc_client])
PKG_CHECK_MODULES([GNOME_KEYRING], [gnome-keyring-1])
+
+AS_IF([test "x$enable_bodhi" != "xno"], [
+ dnl Do the stuff needed for enabling the feature
+ AC_DEFINE([HAVE_BODHI], [1], [Define if you have bodhi])
+ PKG_CHECK_MODULES([JSON_C], [json])
+])
+AM_CONDITIONAL(HAVE_BODHI, [test "x$enable_bodhi" != "xno"])
+
# Just PKG_CHECK_MODULES([PYTHON], [python]) works only with python2.7+
# Below, if python is not found, we set up for python2.6 w/o checking:
PKG_CHECK_MODULES([PYTHON], [python],,[
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index e3dbcff..903311f 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -7,22 +7,30 @@ bin_SCRIPTS = \
abrt-action-analyze-core.py \
abrt-action-list-dsos.py
-bin_PROGRAMS = \
- abrt-dump-oops \
- abrt-action-analyze-c \
- abrt-action-analyze-python \
- abrt-action-analyze-oops \
- abrt-action-trim-files \
- abrt-action-generate-backtrace \
- abrt-action-analyze-backtrace \
- abrt-action-bugzilla \
- abrt-action-rhtsupport \
- abrt-action-kerneloops \
- abrt-action-upload \
- abrt-action-mailx \
- abrt-action-print \
- abrt-action-install-debuginfo-to-abrt-cache \
- abrt-retrace-client
+BIN =
+
+BIN += abrt-dump-oops
+BIN += abrt-action-analyze-c
+BIN += abrt-action-analyze-python
+BIN += abrt-action-analyze-oops
+BIN += abrt-action-trim-files
+BIN += abrt-action-generate-backtrace
+BIN += abrt-action-analyze-backtrace
+BIN += abrt-action-bugzilla
+BIN += abrt-action-rhtsupport
+BIN += abrt-action-kerneloops
+BIN += abrt-action-upload
+BIN += abrt-action-mailx
+BIN += abrt-action-print
+
+if HAVE_BODHI
+BIN += abrt-action-bodhi
+endif
+
+BIN += abrt-action-install-debuginfo-to-abrt-cache
+BIN += abrt-retrace-client
+
+bin_PROGRAMS = $(BIN)
pluginsconfdir = $(PLUGINS_CONF_DIR)
@@ -260,6 +268,23 @@ abrt_action_bugzilla_LDADD = \
../lib/libabrt_web.la \
../lib/libreport.la
+if HAVE_BODHI
+abrt_action_bodhi_SOURCES = \
+ abrt-action-bodhi.c
+abrt_action_bodhi_CPPFLAGS = \
+ -I$(srcdir)/../include/report -I$(srcdir)/../include \
+ -I$(srcdir)/../lib \
+ $(GLIB_CFLAGS) \
+ $(JSON_C_CFLAGS) \
+ -D_GNU_SOURCE \
+ -Wall -Wwrite-strings
+abrt_action_bodhi_LDADD = \
+ $(GLIB_LIBS) \
+ $(JSON_C_LIBS) \
+ ../lib/libabrt_web.la \
+ ../lib/libreport.la
+endif
+
abrt_action_rhtsupport_SOURCES = \
abrt_rh_support.h abrt_rh_support.c \
abrt-action-rhtsupport.c
diff --git a/src/plugins/abrt-action-bodhi.c b/src/plugins/abrt-action-bodhi.c
new file mode 100644
index 0000000..0133da7
--- /dev/null
+++ b/src/plugins/abrt-action-bodhi.c
@@ -0,0 +1,241 @@
+/*
+ Copyright (C) 2011 ABRT team
+ Copyright (C) 2011 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 <json/json.h>
+
+#include "abrtlib.h"
+#include "abrt_curl.h"
+#include "parse_options.h"
+
+//699198,705037,705036
+
+static const char *bodhi_url = "https://admin.fedoraproject.org/updates/%s";
+
+struct bodhi {
+ const char *package_name;
+ const char *date_pushed;
+ int karma;
+
+ GList *bz_ids;
+};
+
+enum bodhi_flags {
+ BODHI_READ_STR,
+ BODHI_READ_INT,
+};
+
+static void free_bodhi_list(GList *bodhi_list)
+{
+ if (!bodhi_list)
+ return;
+
+ for (GList *li = bodhi_list; li; li = li->next)
+ {
+ struct bodhi *b = (struct bodhi *) li->data;
+ list_free_with_free(b->bz_ids);
+ free(b);
+ }
+
+ g_list_free(bodhi_list);
+}
+
+#define bodhi_read_value_int(item, bodhi, json) \
+ do { \
+ json_object *j; \
+ j = json_object_object_get((json), (item)); \
+ if (!j) \
+ error_msg_and_die("'%s' section is not available", (item));
\
+ bodhi = json_object_get_int(j); \
+ break; \
+ } while(0)
+
+#define bodhi_read_value_str(item, bodhi, json) \
+ do { \
+ json_object *j; \
+ j = json_object_object_get((json), (item)); \
+ if (!j) \
+ error_msg_and_die("'%s' section is not available", (item));
\
+ bodhi = json_object_to_json_string(j); \
+ } while(0)
+
+static void print_bodhi(struct bodhi *b)
+{
+ if (b->package_name)
+ printf("'%s'", b->package_name);
+ if (b->date_pushed)
+ printf(" '%s'", b->date_pushed);
+
+ printf(" %i", b->karma);
+
+ for (GList *li = b->bz_ids; li; li = li->next)
+ printf(" %i", *(int*) li->data);
+
+ puts("");
+}
+
+static GList *bodhi_parse_json(json_object *json)
+{
+ json_object *json_num_items = json_object_object_get(json, "num_items");
+ if (!json_num_items)
+ {
+ error_msg("'num_items' is not available");
+ return NULL;
+ }
+
+ int num_items = json_object_get_int(json_num_items);
+ if (num_items <= 0)
+ return NULL;
+
+ json_object *updates = json_object_object_get(json, "updates");
+ if (!updates)
+ {
+ error_msg("'update' section is not available");
+ return NULL;
+ }
+
+ int updates_len = json_object_array_length(updates);
+ VERB1 log("%i updates", updates_len);
+
+ GList *bodhi_list = NULL;
+ for (int i = 0; i < updates_len; ++i)
+ {
+ json_object *updates_item = json_object_array_get_idx(updates, i);
+
+ /* some of item are null */
+ if (!updates_item)
+ continue;
+
+ struct bodhi *b = xzalloc(sizeof(struct bodhi));
+ bodhi_read_value_str("title", b->package_name, updates_item);
+ bodhi_read_value_str("date_pushed", b->date_pushed, updates_item);
+ bodhi_read_value_int("karma", b->karma, updates_item);
+
+ json_object *bugs = json_object_object_get(updates_item, "bugs");
+ if (bugs)
+ {
+ for (int j = 0; j < json_object_array_length(bugs); ++j)
+ {
+ int *bz_id = xmalloc(sizeof(int));
+ json_object *bug_item = json_object_array_get_idx(bugs, j);
+ bodhi_read_value_int("bz_id", *bz_id, bug_item);
+ b->bz_ids = g_list_append(b->bz_ids, bz_id);
+ }
+ }
+
+ bodhi_list = g_list_append(bodhi_list, b);
+
+ VERB1 print_bodhi(b);
+ }
+
+ return bodhi_list;
+}
+
+static int bodhi_query_list(const char *query, const char *package)
+{
+ if (!query && !package)
+ return -1;
+
+ char *bodhi_url_bugs = xasprintf(bodhi_url, "list");
+
+ abrt_post_state_t *post_state = new_abrt_post_state(
+ ABRT_POST_WANT_BODY|ABRT_POST_WANT_SSL_VERIFY);
+
+ const char *headers[] = {
+ "Accept: application/json",
+ NULL
+ };
+
+ struct strbuf *data = strbuf_new();
+
+ if (query)
+ strbuf_append_str(data, query);
+
+ if (package && query)
+ strbuf_append_strf(data, "&package=%s", package);
+ if (package && !query)
+ strbuf_append_strf(data, "package=%s", package);
+
+ VERB1 log("data: %s", data->buf);
+
+ abrt_post_string(post_state, bodhi_url_bugs,
"application/x-www-form-urlencoded",
+ headers, data->buf);
+ free(bodhi_url_bugs);
+ strbuf_free(data);
+
+ VERB3 log("%s", post_state->body);
+
+ /* when you try to search in bodhi server bug with number 'ss' (some invalid
+ * number or not associate to any updates, bodhi returns not json answer, but
+ * some html page. Bug filled here
https://fedorahosted.org/bodhi/ticket/611
+ *
+ * What is worst is that json_tokener_parse() does not return NULL when
+ * invalid input is passed to function, but returns some rubbish pointer
+ * 0xfffffffffffffffc. Bug filled
https://bugzilla.redhat.com/show_bug.cgi?id=709804
+ */
+ json_object *json = json_tokener_parse(post_state->body);
+ if (!json)
+ error_msg_and_die("unable parse response from bodhi server");
+
+ GList *bodhi_list = bodhi_parse_json(json);
+ free_bodhi_list(bodhi_list);
+ json_object_put(json);
+ free_abrt_post_state(post_state);
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ abrt_init(argv);
+ enum {
+ OPT_v = 1 << 0,
+ OPT_b = 1 << 1,
+ };
+
+ char *bugs = NULL;
+ /* Keep enum above and order of options below in sync! */
+ struct options program_options[] = {
+ OPT__VERBOSE(&g_verbose),
+ OPT_STRING('b', "bugs", &bugs, "id1[,id2,...]" ,
_("List of bug ids")),
+ OPT_END()
+ };
+
+ const char *program_usage_string = _(
+ "\b bodhi [-v] [-b] package-name package-name ...\n"
+ "\n"
+ "Search for a new updates in bodhi"
+ );
+
+ unsigned opts = parse_opts(argc, argv, program_options, program_usage_string);
+
+ int status = 0;
+
+ char *query = NULL;
+ if (opts & OPT_b)
+ query = xasprintf("bugs=%s", bugs);
+
+ if (optind < argc)
+ while (optind < argc)
+ status = bodhi_query_list(query, argv[optind++]);
+ else
+ status = bodhi_query_list(query, NULL);
+
+ free(query);
+ return 0;
+}
--
1.7.1