summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Toman <mtoman@redhat.com>2011-02-16 16:16:27 +0100
committerMichal Toman <mtoman@redhat.com>2011-02-16 16:16:27 +0100
commitbbec6cfc80296397ee1de162769b00bb454de936 (patch)
tree17c6db4f77db4ad2357571436d060b0ab4b62d16
parent3014272e774ab2e45ea0be7ca2911615f9ed77b0 (diff)
move logging to worker.py
-rw-r--r--retrace/interface/create.wsgi8
-rw-r--r--retrace/lib/retrace.py17
-rw-r--r--retrace/worker/worker.c74
-rwxr-xr-xretrace/worker/worker.py140
4 files changed, 118 insertions, 121 deletions
diff --git a/retrace/interface/create.wsgi b/retrace/interface/create.wsgi
index dbbc29a0..f3c0079c 100644
--- a/retrace/interface/create.wsgi
+++ b/retrace/interface/create.wsgi
@@ -59,8 +59,8 @@ def application(environ, start_response):
return response(start_response, "500 Internal Server Error", "Unable to create new task")
try:
- os.mkdir(taskdir + "/crash/")
- os.chdir(taskdir + "/crash/")
+ os.mkdir("%s/crash/" % taskdir)
+ os.chdir("%s/crash/" % taskdir)
unpack_retcode = unpack(archive.name)
os.unlink(archive.name)
@@ -79,6 +79,6 @@ def application(environ, start_response):
Popen(["rm", "-rf", taskdir])
return response(start_response, "403 Forbidden")
- Popen(["/usr/sbin/abrt-retrace-worker", taskdir])
+ Popen(["/usr/sbin/abrt-retrace-worker", "%d" % taskid])
- return response(start_response, "201 Created", "", [("X-Task-Id", str(taskid)), ("X-Task-Password", taskpass)])
+ return response(start_response, "201 Created", "", [("X-Task-Id", "%d" % taskid), ("X-Task-Password", taskpass)])
diff --git a/retrace/lib/retrace.py b/retrace/lib/retrace.py
index c764ce18..1cee5505 100644
--- a/retrace/lib/retrace.py
+++ b/retrace/lib/retrace.py
@@ -200,5 +200,22 @@ def save_crashstats(crashstats):
print e
return False
+class logger():
+ def __init__(self, savedir):
+ "Starts logging into savedir."
+ self._logfile = open("%s/log" % savedir, "w")
+
+ def write(self, msg):
+ "Writes msg into log file."
+ if not self._logfile.closed:
+ self._logfile.write(msg)
+ self._logfile.flush()
+
+ def close(self):
+ "Finishes logging and renames file to retrace_log."
+ if not self._logfile.closed:
+ self._logfile.close()
+ os.rename(self._logfile.name, self._logfile.name.replace("/log", "/retrace_log"))
+
### read config on import ###
read_config()
diff --git a/retrace/worker/worker.c b/retrace/worker/worker.c
index 58ee1b35..2020627d 100644
--- a/retrace/worker/worker.c
+++ b/retrace/worker/worker.c
@@ -1,6 +1,6 @@
#include <stdio.h>
+#include <ctype.h>
#include <stdlib.h>
-#include <string.h>
#include <unistd.h>
/*
@@ -10,41 +10,28 @@
int main(int argc, char **argv)
{
- char command[1024], line[256];
- FILE *pipe, *log;
- int retcode;
+ char command[256];
+ FILE *pipe;
+ int i;
if (argc != 2)
{
- printf("Usage: %s retrace_directory\n", argv[0]);
+ fprintf(stderr, "Usage: %s task_id\n", argv[0]);
return 1;
}
- if (setgid(0) != 0 || setuid(0) != 0)
+ if (setuid(0) != 0)
{
- printf("You must run %s with root permissions.\n", argv[0]);
+ fprintf(stderr, "You must run %s with root permissions.\n", argv[0]);
return 2;
}
- /* do not allow double quotes in path */
- if (strchr(argv[1], '"') != NULL){
- puts("Invalid character(s) in retrace_directory.");
- return 3;
- }
-
- sprintf(command, "%s/log", argv[1]);
-
- /* create retrace log */
- log = fopen(command, "w");
- if (log == NULL)
- {
- puts("Error writing log file.");
- return 4;
- }
-
- fputs("Starting retrace\n", log);
-
- sprintf(command, "/usr/bin/python /usr/share/abrt-retrace/worker.py \"%s\"", argv[1]);
+ for (i = 0; argv[1][i]; ++i)
+ if (!isdigit(argv[1][i]))
+ {
+ fputs("Task ID may only contain digits.", stderr);
+ return 3;
+ }
/* needs to be set to make mock work properly */
setenv("SUDO_USER", "root", 1);
@@ -52,40 +39,13 @@ int main(int argc, char **argv)
setenv("SUDO_GID", "0", 1);
/* launch worker.py */
+ sprintf(command, "/usr/bin/python /usr/share/abrt-retrace/worker.py \"%s\"", argv[1]);
pipe = popen(command, "r");
if (pipe == NULL)
{
- puts("Unable to run 'worker.py'.");
- return 5;
- }
-
- /* read worker's output */
- while (fgets(line, 255, pipe) != NULL)
- {
- fputs(line, log);
- fflush(log);
- }
-
- retcode = pclose(pipe) >> 8;
-
- /* make backtrace accessible for clients */
- if (retcode == 0)
- {
- fputs("Retrace successful\n", log);
-
- sprintf(command, "mv \"%s/backtrace\" \"%s/retrace_backtrace\"", argv[1], argv[1]);
- system(command);
- }
- else
- {
- fputs("Retrace failed\n", log);
+ fputs("Unable to run 'worker.py'.", stderr);
+ return 4;
}
- fclose(log);
-
- /* make log accessible for clients */
- sprintf(command, "mv \"%s/log\" \"%s/retrace_log\"", argv[1], argv[1]);
- system(command);
-
- return retcode;
+ return pclose(pipe) >> 8;
}
diff --git a/retrace/worker/worker.py b/retrace/worker/worker.py
index 2ca82cdc..1d0fe936 100755
--- a/retrace/worker/worker.py
+++ b/retrace/worker/worker.py
@@ -4,6 +4,8 @@ import sys
import time
from retrace import *
+LOG = None
+
def retrace_run(errorcode, cmd):
"Runs cmd using subprocess.Popen and kills script with errorcode on failure"
try:
@@ -16,9 +18,8 @@ def retrace_run(errorcode, cmd):
output = "An unhandled exception occured: %s" % ex
if not process or process.returncode != 0:
- print "Error %d" % errorcode
- print "--- OUTPUT ---"
- print output
+ LOG.write("Error %d:\n=== OUTPUT ===\n%s\n" % (errorcode, output))
+ LOG.close()
sys.exit(errorcode)
return output
@@ -27,36 +28,44 @@ if __name__ == "__main__":
starttime = time.time()
if len(sys.argv) != 2:
- print "Usage: %s retrace_directory" % sys.argv[0]
+ sys.stderr.write("Usage: %s task_id\n" % sys.argv[0])
sys.exit(11)
- workdir = sys.argv[1]
-
- if not os.path.isdir(workdir):
- print "'%s' is not a directory" % workdir
+ taskid = sys.argv[1]
+ try:
+ int(taskid)
+ except:
+ sys.stderr.write("Task ID may only contain digits.\n")
sys.exit(12)
- taskid_match = TASKID_PARSER.match(workdir)
- if not taskid_match:
- print "Unable to obtain task ID from given directory"
+ workdir = "%s/%s" % (CONFIG["WorkDir"], taskid)
+
+ if not os.path.isdir(workdir):
+ sys.stderr.write("Task '%s' does not exist.\n" % workdir)
sys.exit(13)
- else:
- taskid = taskid_match.group(1)
+
+ try:
+ LOG = logger(workdir)
+ except Exception as ex:
+ sys.stderr.write("Unable to start logging for task '%s': %s.\n" % (taskid, ex))
+ sys.exit(14)
# check the crash directory for required files
for required_file in REQUIRED_FILES:
if not os.path.isfile("%s/crash/%s" % (workdir, required_file)):
- print "Directory '%s' does not contain required file '%s'" % (workdir, required_file)
- sys.exit(14)
+ LOG.write("Crash directory does not contain required file '%s'.\n" % required_file)
+ LOG.close()
+ sys.exit(15)
# read architecture file
try:
arch_file = open("%s/crash/architecture" % workdir, "r")
arch = repoarch = arch_file.read()
arch_file.close()
- except:
- print "Unable to read architecture from 'architecture' file"
- sys.exit(15)
+ except Exception as ex:
+ LOG.write("Unable to read architecture from 'architecture' file: %s.\n" % ex)
+ LOG.close()
+ sys.exit(16)
# required hack for public repos
if arch == "i686":
@@ -67,9 +76,10 @@ if __name__ == "__main__":
release_file = open("%s/crash/release" % workdir, "r")
release = release_file.read()
release_file.close()
- except:
- print "Unable to read distribution and version from 'release' file"
- sys.exit(16)
+ except Exception as ex:
+ LOG.write("Unable to read distribution and version from 'release' file: %s.\n" % ex)
+ LOG.close()
+ sys.exit(17)
version = distribution = None
for distro in RELEASE_PARSERS.keys():
@@ -80,23 +90,25 @@ if __name__ == "__main__":
break
if not version or not distribution:
- print "Release '%s' is not supported" % release
- sys.exit(17)
+ LOG.write("Release '%s' is not supported.\n" % release)
+ LOG.close()
+ sys.exit(18)
# read package file
try:
package_file = open("%s/crash/package" % workdir, "r")
crash_package = package_file.read()
package_file.close()
- except:
- print "Unable to read crash package from 'package' file"
- sys.exit(18)
+ except Exception as ex:
+ LOG.write("Unable to read crash package from 'package' file: %s.\n" % ex)
+ LOG.close()
+ sys.exit(19)
# read required packages from coredump
packages = "%s.%s" % (crash_package, arch)
try:
# ToDo: deal with not found build-ids
- pipe = Popen(["/usr/share/abrt-retrace/coredump2packages", "%s/crash/coredump" % workdir, "--repos=retrace-%s-%s-%s*" % (distribution, version, arch)], stdout=PIPE).stdout
+ pipe = Popen(["/usr/share/abrt-retrace/coredump2packages.py", "%s/crash/coredump" % workdir, "--repos=retrace-%s-%s-%s*" % (distribution, version, arch)], stdout=PIPE).stdout
for line in pipe.readlines():
if line == "\n":
break
@@ -104,13 +116,14 @@ if __name__ == "__main__":
packages += " %s" % line.rstrip("\n")
pipe.close()
- except:
- print "Unable to obtain packages from 'coredump' file"
- sys.exit(19)
+ except Exception as ex:
+ LOG.write("Unable to obtain packages from 'coredump' file: %s.\n" % ex)
+ LOG.close()
+ sys.exit(20)
# create mock config file
try:
- mockcfg = open(workdir + "/mock.cfg", "w")
+ mockcfg = open("%s/mock.cfg" % workdir, "w")
mockcfg.write("config_opts['root'] = 'chroot'\n")
mockcfg.write("config_opts['target_arch'] = '%s'\n" % arch)
mockcfg.write("config_opts['chroot_setup_cmd'] = 'install %s shadow-utils abrt-addon-ccpp gdb'\n" % packages)
@@ -173,52 +186,52 @@ if __name__ == "__main__":
mockcfg.write("\"\"\"\n")
mockcfg.close()
except Exception as ex:
- print "Unable to create mock config file: %s" % ex
- sys.exit(20)
+ LOG.write("Unable to create mock config file: %s.\n" % ex)
+ LOG.close()
+ sys.exit(21)
# get count of tasks running before starting
prerunning = len(get_active_tasks()) - 1
# run retrace
- mockr = "../../" + workdir + "/mock"
+ mockr = "../../%s/mock" % workdir
- print "Initializing virtual root...",
+ LOG.write("Initializing virtual root... ")
- retrace_run(21, ["mock", "init", "-r", mockr])
- retrace_run(22, ["mock", "-r", mockr, "--copyin", "%s/crash" % workdir, "/var/spool/abrt/crash"])
- retrace_run(23, ["touch", "%s/chroot/root/var/spool/abrt/crash/time" % workdir])
+ retrace_run(25, ["mock", "init", "-r", mockr])
+ retrace_run(26, ["mock", "-r", mockr, "--copyin", "%s/crash" % workdir, "/var/spool/abrt/crash"])
+ retrace_run(27, ["touch", "%s/chroot/root/var/spool/abrt/crash/time" % workdir])
- print "OK"
- sys.stdout.flush()
+ LOG.write("OK\n")
try:
rootfile = open("%s/chroot/result/root.log" % workdir, "r")
rootlog = rootfile.read()
rootfile.close()
except Exception as ex:
- print "Error reading root log: %s" % ex
+ LOG.write("Error reading root log: %s.\n" % ex)
+ rootlog = "Not found"
- print "Generating backtrace...",
+ LOG.write("Generating backtrace... ")
- retrace_run(24, ["mock", "shell", "-r", mockr, "--", "/usr/bin/abrt-action-generate-backtrace", "-d", "/var/spool/abrt/crash/"])
- retrace_run(25, ["mock", "-r", mockr, "--copyout", "/var/spool/abrt/crash/backtrace", workdir])
- retrace_run(26, ["chmod", "a+r", "%s/backtrace" % workdir])
+ retrace_run(28, ["mock", "shell", "-r", mockr, "--", "/usr/bin/abrt-action-generate-backtrace", "-d", "/var/spool/abrt/crash/"])
+ retrace_run(29, ["mock", "-r", mockr, "--copyout", "/var/spool/abrt/crash/backtrace", workdir])
+ retrace_run(30, ["chmod", "a+r", "%s/backtrace" % workdir])
- print "OK"
- sys.stdout.flush()
+ LOG.write("OK\n")
chroot_size = dir_size("%s/chroot/root" % workdir)
- print "Cleaning up...",
- retrace_run(27, ["mock", "-r", mockr, "--scrub=all"])
- retrace_run(28, ["rm", "-rf", "%s/mock.cfg" % workdir, "%s/crash" % workdir])
+ LOG.write("Cleaning up... ")
- print "OK"
- sys.stdout.flush()
+ retrace_run(31, ["mock", "-r", mockr, "--scrub=all"])
+ retrace_run(32, ["rm", "-rf", "%s/mock.cfg" % workdir, "%s/crash" % workdir])
+
+ LOG.write("OK\n")
# save crash statistics
duration = int(time.time() - starttime)
- print "Retrace took %d seconds" % duration
+ LOG.write("Retrace took %d seconds.\n" % duration)
package_match = PACKAGE_PARSER.match(crash_package)
if not package_match:
@@ -243,16 +256,23 @@ if __name__ == "__main__":
"chrootsize": chroot_size
}
- print "Saving crash statistics...",
+ LOG.write("Saving crash statistics... ")
if not init_crashstats_db() or not save_crashstats(crashstats):
- print "Error: %s" % crashstats
+ LOG.write("Error: %s\n" % crashstats)
else:
- print "OK"
+ LOG.write("OK\n")
+
+ LOG.write("Finishing task... ")
- sys.stdout.flush()
+ try:
+ os.rename("%s/backtrace" % workdir, "%s/retrace_backtrace" % workdir)
+ except Exception as ex:
+ LOG.write("Error: %s\n" % ex)
+ LOG.close()
+ sys.exit(35)
+ LOG.write("OK\n")
- print
- print "=== ROOT LOG ==="
- print rootlog
+ LOG.write("\n=== ROOT LOG ===\n%s\n" % rootlog)
+ LOG.close()