#!/usr/bin/python -t # 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # rtpatch - a script to check for existance of, fetch, or fetch and apply the # latest of Ingo Molnar's -rt kernel patches # # Copyright 2006 Clark Williams # import os, sys import re import os.path import urllib import HTMLParser from exceptions import IOError, KeyboardInterrupt, ValueError, Exception url = "http://people.redhat.com/~mingo/realtime-preempt" gittree = "linus-kernel.git" patchdir = "sources" class FileParser(HTMLParser.HTMLParser): def __init__(self): HTMLParser.HTMLParser.__init__(self) self.seen = {} def handle_starttag(self, tag, attributes): if tag != 'a': return for name, value in attributes: if name == 'href' and value not in self.seen: self.seen[value] = True return class RTpatchError(Exception): def __init__(self, args=None): self.args = args def findpatches(): try: s = urllib.urlopen(url) except IOError, e: print e sys.exit(1) except KeyboardInterrupt, e: sys.exit(1) fp = FileParser() while True: data = s.read(8192) if not data: break fp.feed(data) s.close() patches = [] for thing in fp.seen.keys(): if thing.find('patch') >= 0: patches.append(thing) fp = None return patches def check(): patches = findpatches() if len(patches): if len(patches) > 1: print "Available RT patches:" else: print "Available RT patch:" for p in patches: print " " + p else: print "No RT patches found" def reporter(bcount, bsize, fsize): done=bcount * bsize percent = float(done) / float(fsize) * 100.0 if percent > 100.0: percent = 100 sys.stdout.write('\r Progress: %3.0f%%' % percent) sys.stdout.flush() def fetch(p): try: print "Downloading %s" % p urllib.urlretrieve("%s/%s" % (url, p), p, reporter) sys.stdout.write('\n') except KeyboardInterrupt, e: print "Aborted" pass def usage(): print "usage: %s [check|get|apply]" % sys.argv[0] print " running with no arguments checks for existance of the patch" sys.exit(-1) def get_version(patchname): r = re.compile(r'^patch-(.+)-rt(\d+)$') m = r.match(patchname) if m == None: print "%s is not a valid realtime patch name" % patchname return None base = m.group(1) ver = m.group(2) return (base, ver) def apply(patch): if not os.path.exists(gittree): print "Can't find Linux git tree: %s" % gittree return (base, version) = get_version(p) if os.path.exists("%s/.git/refs/heads/v%s-rt%s" % (gittree, base, version)): print "patch-%s-rt%s already applied to branch v%s-rt%s" % (base, version, base, version) return if not os.path.exists("%s/.git/refs/tags/v%s" % (gittree, base)): print "can't find base v%s in git tree!" % base return print "about to apply rt patch %s (based on v%s)" % (version, base) # first fetch the patch here = os.getcwd() os.chdir(patchdir) fetch(patch) os.chdir(here) try: os.chdir(gittree) except: print "Can't cd to git tree %s" % gittree return # now set up the git tree run("git checkout -f") run("git branch v%s-rt%s v%s" % (base, version, base)) run("git checkout v%s-rt%s" % (base, version)) run("cat %s/sources/%s | patch -p1" % (here, patch)) run("git add") run('git commit -a -m "Ingo\'s %s-rt%s realtime patch"' % (base, version)) os.chdir(here) print "patch %s applied and committed" % patch def run(cmd): print "running: %s" % cmd retval = os.system(cmd) if retval: raise RTpatchError, "%s failed with status %d" % (cmd, retval) return ###### Main logic try: cmd = sys.argv[1] except: check() sys.exit(1) if cmd == "check": check() elif cmd == "get" or cmd == "fetch": patches = findpatches() for p in patches: fetch(p) elif cmd == "apply": patches = findpatches() for p in patches: apply(p) else: usage()