summaryrefslogtreecommitdiffstats
path: root/lib/plugins/SOSreport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/plugins/SOSreport.cpp')
-rw-r--r--lib/plugins/SOSreport.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/lib/plugins/SOSreport.cpp b/lib/plugins/SOSreport.cpp
new file mode 100644
index 00000000..6c8ab1f8
--- /dev/null
+++ b/lib/plugins/SOSreport.cpp
@@ -0,0 +1,162 @@
+/*
+ SOSreport.cpp
+
+ Copyright (C) 2009 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_types.h"
+#include "abrt_exception.h"
+#include "SOSreport.h"
+#include "debug_dump.h"
+#include "abrt_exception.h"
+#include "comm_layer_inner.h"
+
+using namespace std;
+
+static char *ParseFilename(char *p)
+{
+ /*
+ the sosreport's filename is embedded in sosreport's output.
+ It appears on the line after the string in 'sosreport_filename_marker',
+ it has leading spaces, and a trailing newline. This function trims
+ any leading and trailing whitespace from the filename.
+ */
+ static const char sosreport_filename_marker[] =
+ "Your sosreport has been generated and saved in:";
+
+ p = strstr(p, sosreport_filename_marker);
+ if (!p)
+ return p;
+ p = skip_whitespace(p + sizeof(sosreport_filename_marker)-1);
+ char *end = strchrnul(p, '\n');
+ while (end > p && isspace(*end))
+ *end-- = '\0';
+ return p[0] == '/' ? p : NULL;
+}
+
+void CActionSOSreport::Run(const char *pActionDir, const char *pArgs, int force)
+{
+ if (!force)
+ {
+ CDebugDump dd;
+ dd.Open(pActionDir);
+ bool bt_exists = dd.Exist("sosreport.tar.bz2") || dd.Exist("sosreport.tar.xz");
+ if (bt_exists)
+ {
+ VERB3 log("%s already exists, not regenerating", "sosreport.tar.bz2");
+ return;
+ }
+ }
+
+ static const char command_default[] =
+ "cd -- '%s' || exit 1;"
+ "nice sosreport --tmp-dir . --batch"
+ " --only=anaconda --only=bootloader"
+ " --only=devicemapper --only=filesys --only=hardware --only=kernel"
+ " --only=libraries --only=memory --only=networking --only=nfsserver"
+ " --only=pam --only=process --only=rpm -k rpm.rpmva=off --only=ssh"
+ " --only=startup --only=yum 2>&1;"
+ "rm sosreport*.md5 2>/dev/null;"
+ "mv sosreport*.tar.bz2 sosreport.tar.bz2 2>/dev/null;"
+ "mv sosreport*.tar.xz sosreport.tar.xz 2>/dev/null;"
+ ;
+ static const char command_prefix[] =
+ "cd -- '%s' || exit 1;"
+ "nice sosreport --tmp-dir . --batch %s 2>&1;"
+ "rm sosreport*.md5 2>/dev/null;"
+ "mv sosreport*.tar.bz2 sosreport.tar.bz2 2>/dev/null;"
+ "mv sosreport*.tar.xz sosreport.tar.xz 2>/dev/null;"
+ ;
+ string command;
+
+ vector_string_t args;
+ parse_args(pArgs, args, '"');
+
+ if (args.size() == 0 || args[0] == "")
+ {
+ command = ssprintf(command_default, pActionDir);
+ }
+ else
+ {
+ command = ssprintf(command_prefix, pActionDir, args[0].c_str());
+ }
+
+ update_client(_("Running sosreport: %s"), command.c_str());
+ string output = command;
+ output += '\n';
+ char *command_out = run_in_shell_and_save_output(/*flags:*/ 0, command.c_str(), /*dir:*/ NULL, /*size_p:*/ NULL);
+ output += command_out;
+ update_client(_("Finished running sosreport"));
+ VERB3 log("sosreport output:'%s'", output.c_str());
+
+// Not needed: now we use "sosreport --tmp-dir DUMPDIR"
+#if 0
+ // Parse:
+ // "Your sosreport has been generated and saved in:
+ // /tmp/sosreport-XXXX.tar.bz2"
+ // Note: ParseFilename modifies its parameter and returns pointer
+ // which points somewhere inside it.
+ char *sosreport_filename = xstrdup(ParseFilename(command_out));
+ free(command_out);
+ if (!sosreport_filename)
+ {
+ throw CABRTException(EXCEP_PLUGIN, "Can't find filename in sosreport output");
+ }
+
+ string sosreport_dd_filename = concat_path_file(pActionDir, "sosreport.tar");
+ char *ext = strrchr(sosreport_filename, '.');
+ if (ext && strcmp(ext, ".tar") != 0)
+ {
+ // Assuming it's .bz2, .gz or some such
+ sosreport_dd_filename += ext;
+ }
+ CDebugDump dd;
+ dd.Open(pActionDir);
+ //Not useful: dd.SaveText("sosreportoutput", output);
+ off_t sz = copy_file(sosreport_filename, sosreport_dd_filename.c_str(), 0644);
+
+ // don't want to leave sosreport-XXXX.tar.bz2 in /tmp
+ unlink(sosreport_filename);
+ // sosreport-XXXX.tar.bz2.md5 too
+ unsigned len = strlen(sosreport_filename);
+ sosreport_filename = (char*)xrealloc(sosreport_filename, len + sizeof(".md5")-1 + 1);
+ strcpy(sosreport_filename + len, ".md5");
+ unlink(sosreport_filename);
+
+ if (sz < 0)
+ {
+ dd.Close();
+ CABRTException e(EXCEP_PLUGIN,
+ "Can't copy '%s' to '%s'",
+ sosreport_filename,
+ sosreport_dd_filename.c_str()
+ );
+ free(sosreport_filename);
+ throw e;
+ }
+ free(sosreport_filename);
+#endif
+}
+
+PLUGIN_INFO(ACTION,
+ CActionSOSreport,
+ "SOSreport",
+ "0.0.2",
+ _("Runs sosreport, saves the output"),
+ "gavin@redhat.com",
+ "https://fedorahosted.org/abrt/wiki",
+ "");