diff options
| author | Michal Toman <mtoman@redhat.com> | 2011-02-16 16:16:27 +0100 |
|---|---|---|
| committer | Michal Toman <mtoman@redhat.com> | 2011-02-16 16:16:27 +0100 |
| commit | bbec6cfc80296397ee1de162769b00bb454de936 (patch) | |
| tree | 17c6db4f77db4ad2357571436d060b0ab4b62d16 | |
| parent | 3014272e774ab2e45ea0be7ca2911615f9ed77b0 (diff) | |
move logging to worker.py
| -rw-r--r-- | retrace/interface/create.wsgi | 8 | ||||
| -rw-r--r-- | retrace/lib/retrace.py | 17 | ||||
| -rw-r--r-- | retrace/worker/worker.c | 74 | ||||
| -rwxr-xr-x | retrace/worker/worker.py | 140 |
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() |
