| #!/usr/bin/python |
| # |
| # (C) International Business Machines 2008 |
| # Author: Andy Whitcroft |
| # |
| # Inspired by kernelexpand by: |
| # (C) Martin J. Bligh 2003 |
| # |
| # Released under the GPL, version 2 |
| |
| import sys, re, os |
| |
| kernel = 'http://www.kernel.org/pub/linux/kernel/' |
| mappings = [ |
| [ r'^\d+\.\d+\.\d+$', '', True, [ |
| kernel + 'v%(major)s/linux-%(full)s.tar.bz2' |
| ]], |
| [ r'^\d+\.\d+\.\d+\.\d+$', '', True, [ |
| kernel + 'v%(major)s/linux-%(full)s.tar.bz2' |
| ]], |
| [ r'-rc\d+$', '%(minor-prev)s', True, [ |
| kernel + 'v%(major)s/testing/v%(minor)s/linux-%(full)s.tar.bz2', |
| kernel + 'v%(major)s/testing/linux-%(full)s.tar.bz2', |
| ]], |
| [ r'-(git|bk)\d+$', '%(base)s', False, [ |
| kernel + 'v%(major)s/snapshots/old/patch-%(full)s.bz2', |
| kernel + 'v%(major)s/snapshots/patch-%(full)s.bz2', |
| ]], |
| [ r'-mm\d+$', '%(base)s', False, [ |
| kernel + 'people/akpm/patches/' + |
| '%(major)s/%(base)s/%(full)s/%(full)s.bz2' |
| ]], |
| [ r'-mjb\d+$', '%(base)s', False, [ |
| kernel + 'people/mbligh/%(base)s/patch-%(full)s.bz2' |
| ]] |
| ]; |
| |
| def decompose_kernel_once(kernel): |
| ##print "S<" + kernel + ">" |
| for mapping in mappings: |
| (suffix, becomes, is_full, patch_templates) = mapping |
| |
| params = {} |
| |
| match = re.search(r'^(.*)' + suffix, kernel) |
| if not match: |
| continue |
| |
| # Generate the parameters for the patches: |
| # full => full kernel name |
| # base => all but the matches suffix |
| # minor => 2.n.m |
| # major => 2.n |
| # minor-prev => 2.n.m-1 |
| params['full'] = kernel |
| params['base'] = match.group(1) |
| |
| match = re.search(r'^((\d+\.\d+)\.(\d+))', kernel) |
| if not match: |
| raise "unable to determine major/minor version" |
| params['minor'] = match.group(1) |
| params['major'] = match.group(2) |
| params['minor-prev'] = match.group(2) + '.%d' % (int(match.group(3)) -1) |
| |
| # Build the new kernel and patch list. |
| new_kernel = becomes % params |
| patch_list = [] |
| for template in patch_templates: |
| patch_list.append(template % params) |
| |
| return (is_full, new_kernel, patch_list) |
| |
| return (True, kernel, None) |
| |
| |
| def decompose_kernel(kernel): |
| kernel_patches = [] |
| |
| done = False |
| while not done: |
| (done, kernel, patch_list) = decompose_kernel_once(kernel) |
| if patch_list: |
| kernel_patches.insert(0, patch_list) |
| if not len(kernel_patches): |
| raise NameError('kernelexpand: %s: unknown kernel' % (kernel)) |
| |
| return kernel_patches |
| |
| |
| # Look for and add potential mirrors. |
| def mirror_kernel_components(mirrors, components): |
| new_components = [] |
| for component in components: |
| new_patches = [] |
| for mirror in mirrors: |
| (prefix, local) = mirror |
| for patch in component: |
| if patch.startswith(prefix): |
| new_patch = local + patch[len(prefix):] |
| new_patches.append(new_patch) |
| for patch in component: |
| new_patches.append(patch) |
| new_components.append(new_patches) |
| |
| return new_components |
| |
| |
| def url_accessible(url): |
| status = os.system("wget --spider -q '%s'" % (url)) |
| #print url + ": status=%d" % (status) |
| |
| return status == 0 |
| |
| |
| def select_kernel_components(components): |
| new_components = [] |
| for component in components: |
| new_patches = [] |
| for patch in component: |
| if url_accessible(patch): |
| new_patches.append(patch) |
| break |
| if not len(new_patches): |
| new_patches.append(component[-1]) |
| new_components.append(new_patches) |
| return new_components |
| |
| |
| def expand_classic(kernel, mirrors): |
| components = decompose_kernel(kernel) |
| if mirrors: |
| components = mirror_kernel_components(mirrors, components) |
| components = select_kernel_components(components) |
| |
| patches = [] |
| for component in components: |
| patches.append(component[0]) |
| |
| return patches |
| |
| |
| if __name__ == '__main__': |
| from optparse import OptionParser |
| |
| parser = OptionParser() |
| |
| parser.add_option("-m", "--mirror", type="string", dest="mirror", |
| action="append", nargs=2, help="mirror prefix") |
| parser.add_option("-v", "--no-validate", dest="validate", |
| action="store_false", default=True, help="prune invalid entries") |
| |
| def usage(): |
| parser.print_help() |
| sys.exit(1) |
| |
| options, args = parser.parse_args() |
| |
| # Check for a kernel version |
| if len(args) != 1: |
| usage() |
| kernel = args[0] |
| |
| #mirrors = [ |
| # [ 'http://www.kernel.org/pub/linux/kernel/v2.4', |
| # 'http://kernel.beaverton.ibm.com/mirror/v2.4' ], |
| # [ 'http://www.kernel.org/pub/linux/kernel/v2.6', |
| # 'http://kernel.beaverton.ibm.com/mirror/v2.6' ], |
| # [ 'http://www.kernel.org/pub/linux/kernel/people/akpm/patches', |
| # 'http://kernel.beaverton.ibm.com/mirror/akpm' ], |
| #] |
| mirrors = options.mirror |
| |
| try: |
| components = decompose_kernel(kernel) |
| except NameError, e: |
| sys.stderr.write(e.args[0] + "\n") |
| sys.exit(1) |
| |
| if mirrors: |
| components = mirror_kernel_components(mirrors, components) |
| |
| if options.validate: |
| components = select_kernel_components(components) |
| |
| # Dump them out. |
| for component in components: |
| print " ".join(component) |