diff options
Diffstat (limited to 'compat/bin/ckmake')
-rwxr-xr-x | compat/bin/ckmake | 393 |
1 files changed, 0 insertions, 393 deletions
diff --git a/compat/bin/ckmake b/compat/bin/ckmake deleted file mode 100755 index cd9741ae..00000000 --- a/compat/bin/ckmake +++ /dev/null @@ -1,393 +0,0 @@ -#!/usr/bin/env python - -# ncurses Linux kernel cross kernel compilation utility - -# Copyright (C) 2012 Luis R. Rodriguez <mcgrof@do-not-panic.com> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. - -import locale -import curses -import time -import os -import re -import random -import tempfile -import subprocess -import sys -import signal - -from Queue import * -from threading import Thread, Lock -from shutil import copytree, ignore_patterns, rmtree, copyfileobj -from time import sleep - -releases_processed = [] -releases_baking = [] -processed_lock = Lock() -baking_lock = Lock() -my_cwd = os.getcwd() -ckmake_return = 0 - -tmp_path = my_cwd + "/.tmp.ckmake" -ckmake_log = my_cwd + "/ckmake.log" -ckmake_report = my_cwd + "/ckmake-report.log" - -home = os.getenv("HOME") -ksrc = home + "/" + "compat-ksrc" -modules = ksrc + "/lib/modules" - -def clean(): - if os.path.exists(tmp_path): - rmtree(tmp_path) - -def get_processed_rel(i): - "Because... list.pop(i) didn't work to keep order..." - processed_lock.acquire() - for rel in releases_processed: - if (rel['idx'] == i): - processed_lock.release() - return rel - processed_lock.release() - - baking_lock.acquire() - for rel in releases_baking: - if (rel['idx'] == i): - releases_baking.remove(rel) - baking_lock.release() - return rel - baking_lock.release() - -def get_status_name(status): - if (status == 0): - return 'OK' - elif (status == 130): - return 'TERM' - elif (status == 1234): - return 'INIT' - elif (status == -2): - return 'TERM' - else: - return 'FAIL' - -def get_stat_pos(status): - if (status == 0): - return 34 - elif (status == 130): - return 33 - elif (status == 1234): - return 33 - elif (status == -2): - return 33 - else: - return 33 - -def get_status_color(status): - if (status == 0): - return curses.color_pair(1) - elif (status == 130): - return curses.color_pair(2) - elif (status == 1234): - return curses.color_pair(2) - elif (status == -2): - return curses.color_pair(2) - else: - return curses.color_pair(3) - -def print_report(): - os.system("clear") - sys.stdout.write("\n\n\n") - sys.stdout.write("== ckmake-report.log ==\n\n") - report = open(ckmake_report, 'r+') - copyfileobj(report, sys.stdout) - report.close() - -def process_logs(): - os.system('clear') - log = open(ckmake_log, 'w+') - report = open(ckmake_report, 'w+') - for i in range(0, len(releases_processed)): - rel = get_processed_rel(i) - rel_log = open(rel['log'], 'r+') - log.write(rel_log.read()) - status = get_status_name(rel['status']) - rel_report = "%-4s%-20s[ %s ]\n" % \ - ( rel['idx']+1, rel['version'], status) - report.write(rel_report) - if (rel['status'] != 0 and - rel['status'] != 2): - ckmake_return = -1 - report.close() - log.close() - print_report() - -def process_kernel(num, kset): - while True: - rel = kset.queue.get() - work_dir = tmp_path + '/' + rel['version'] - copytree(my_cwd, \ - work_dir, \ - ignore=ignore_patterns('\.git*', '.tmp*', ".git")) - build = '%s/build/' % rel['full_path'] - jobs = ' -j%d ' % kset.build_jobs - make_args = 'KLIB=%(build)s KLIB_BUILD=%(build)s' % \ - { "build": build } - log_file = work_dir + '/' + 'ckmake.n.log' - rel['log'] = log_file - # XXX: figure out how to properly address logging - # without this nasty ass hack. - log = ' > %(log)s 2>&1' % { "log": log_file } - nice = 'ionice -c 3 nice -n 20 ' - cmd = nice + 'make ' + jobs + make_args + log - - my_env = os.environ.copy() - my_env["KCFLAGS"] = "-Wno-unused-but-set-variable" - - kset.baking(rel) - - p = subprocess.Popen([cmd], - env = my_env, - cwd = work_dir, - stdout=None, - stderr=None, - shell=True) - p.wait() - - kset.update_status(rel, p.returncode) - kset.queue.task_done() - kset.completed(rel) - -def cpu_info_build_jobs(): - if not os.path.exists('/proc/cpuinfo'): - return 1 - f = open('/proc/cpuinfo', 'r') - max_cpus = 1 - for line in f: - m = re.match(r"(?P<PROC>processor\s*:)\s*" \ - "(?P<NUM>\d+)", - line) - if not m: - continue - proc_specs = m.groupdict() - if (proc_specs['NUM'] > max_cpus): - max_cpus = proc_specs['NUM'] - return int(max_cpus) + 1 - -def kill_curses(): - curses.endwin() - sys.stdout = os.fdopen(0, 'w', 0) - -def sig_handler(signal, frame): - kill_curses() - process_logs() - clean() - sys.exit(-2) - -def get_rel_spec(rel): - if ("rc" in rel): - m = re.match(r"v*(?P<VERSION>\d+)\.+" \ - "(?P<PATCHLEVEL>\d+)[.]+" \ - "(?P<SUBLEVEL>\d+)[-]+" \ - "\d+rc(?P<EXTRAVERSION>\d+)\-*", - rel) - else: - m = re.match(r"v*(?P<VERSION>\d+)\.+" \ - "(?P<PATCHLEVEL>\d+)[.]+" \ - "(?P<SUBLEVEL>\d+)[-]+" \ - "(?P<EXTRAVERSION>\d+)\-*", - rel) - if (not m): - return m - rel_specs = m.groupdict() - return rel_specs - -def krel_same_base(new_rel, rel): - if (int(new_rel['ver']) != int(rel['ver'])): - return False - if (int(new_rel['pat']) != int(rel['pat'])): - return False - if (int(new_rel['ver']) == 3): - return True - if (int(new_rel['ver']) != 2): - return False - if (int(new_rel['sub']) == int(rel['sub'])): - return True - return False - -def krel_base_update(new_rel, rel): - if (not krel_same_base(new_rel, rel)): - return False - if (int(new_rel['sub']) > int(rel['sub'])): - return True - if (int(new_rel['sub']) < int(rel['sub'])): - return False - - # Too lazy to deal with 2.x kernels, - if (not new_rel['is_rc']): - return False - - if (int(new_rel['ext']) <= int(rel['ext'])): - return False - return True - -def krel_base_smaller(new_rel, rel): - if (not krel_same_base(new_rel, rel)): - return False - if (int(new_rel['sub']) > int(rel['sub'])): - return False - if (int(new_rel['sub']) < int(rel['sub'])): - return True - return False - -class kernel_set(): - def __init__(self, stdscr): - self.queue = Queue() - self.releases = [] - self.stdscr = stdscr - self.lock = Lock() - signal.signal(signal.SIGINT, sig_handler) - self.build_jobs = cpu_info_build_jobs() - if (curses.has_colors()): - curses.init_pair(1, - curses.COLOR_GREEN, - curses.COLOR_BLACK) - curses.init_pair(2, - curses.COLOR_CYAN, - curses.COLOR_BLACK) - curses.init_pair(3, - curses.COLOR_RED, - curses.COLOR_BLACK) - curses.init_pair(4, - curses.COLOR_BLUE, - curses.COLOR_BLACK) - def baking(self, rel): - baking_lock.acquire() - releases_baking.append(rel) - baking_lock.release() - def completed(self, rel): - processed_lock.acquire() - releases_processed.insert(rel['idx'], rel) - processed_lock.release() - def set_locale(self): - locale.setlocale(locale.LC_ALL, '') - code = locale.getpreferredencoding() - def refresh(self): - self.lock.acquire() - self.stdscr.refresh() - self.lock.release() - def evaluate_new_rel(self, new_rel): - for rel in self.releases: - if (krel_base_update(new_rel, rel)): - new_rel['idx'] = rel['idx'] - self.releases.remove(rel) - break - if (krel_base_smaller(new_rel, rel)): - return - self.releases.insert(new_rel['idx'], new_rel) - def parse_releases(self): - for dirname, dirnames, filenames in os.walk(modules): - dirnames.sort() - for subdirname in dirnames: - specifics = get_rel_spec(subdirname) - if (not specifics): - continue - rc = False - - ver = specifics['VERSION'] + '.' + \ - specifics['PATCHLEVEL'] - - if ("rc" in subdirname): - rc = True - ver = ver + '-rc' + specifics['EXTRAVERSION'] - else: - ver = ver + '.' + specifics['SUBLEVEL'] - - rel = dict(idx=len(self.releases), - name=subdirname, - full_path=dirname + '/' + - subdirname, - version=ver, - is_rc = rc, - ver=specifics['VERSION'], - pat=specifics['PATCHLEVEL'], - sub=specifics['SUBLEVEL'], - ext=specifics['EXTRAVERSION'], - processed=False, - log='', - status=1234) - self.evaluate_new_rel(rel) - self.refresh() - def setup_screen(self): - for i in range(0, len(self.releases)): - rel = self.releases[i] - self.lock.acquire() - self.stdscr.addstr(rel['idx'], 0, - "%-4d" % (rel['idx']+1)) - if (curses.has_colors()): - self.stdscr.addstr(rel['idx'], 5, - "%-20s" % (rel['version']), - curses.color_pair(4)) - else: - self.stdscr.addstr(rel['idx'], 0, - "%-20s" % (rel['version'])) - self.stdscr.addstr(rel['idx'], 30, "[ ]") - self.stdscr.refresh() - self.lock.release() - def create_threads(self): - for rel in self.releases: - th = Thread(target=process_kernel, args=(0, self)) - th.setDaemon(True) - th.start() - def kick_threads(self): - for rel in self.releases: - self.queue.put(rel) - sleep(1) - def wait_threads(self): - self.queue.join() - def update_status(self, rel, status): - self.lock.acquire() - stat_name = get_status_name(status) - stat_pos = get_stat_pos(status) - if (curses.has_colors()): - stat_color = get_status_color(status) - self.stdscr.addstr(rel['idx'], stat_pos, stat_name, - get_status_color(status)) - else: - self.stdscr.addstr(rel['idx'], stat_pos, stat_name) - rel['processed'] = True - rel['status'] = status - self.stdscr.refresh() - self.lock.release() - -def main(stdscr): - kset = kernel_set(stdscr) - - kset.set_locale() - kset.parse_releases() - kset.setup_screen() - kset.create_threads() - kset.kick_threads() - kset.wait_threads() - kset.refresh() - -if __name__ == "__main__": - if not os.path.exists(modules): - print "%s does not exist" % (modules) - sys.exit(1) - if not os.path.exists(my_cwd + '/Makefile'): - print "%s does not exist" % (my_cwd + '/Makefile') - sys.exit(1) - if os.path.exists(ckmake_log): - os.remove(ckmake_log) - if os.path.exists(ckmake_report): - os.remove(ckmake_report) - if os.path.exists(tmp_path): - rmtree(tmp_path) - os.makedirs(tmp_path) - curses.wrapper(main) - kill_curses() - process_logs() - clean() - sys.exit(ckmake_return) |