def select_build(build, release): """Work out build_info for build or release""" if release and build: raise AmbiguousRequest(build, release) if build: if isdir(build): print 'INFO: using', build, 'directory for build' bi = inspect_build(build, None) if len(bi) != 1: raise InvalidBuildTree(build, len(bi)) else: branch = extract_branch(build) print 'HEADLINE: setting PXE to install', build, 'on', branch orig_build_directory = find_build(branch, build, build_path=BUILD_PATH) print 'INFO: build is located at', orig_build_directory bi = inspect_build(orig_build_directory, build) if bi == []: raise UnknownBuild(branch, build, orig_build_directory) return bi[0] else: assert release for releasec in scan_releases(): if releasec['alias'] == release: return releasec raise UnknownRelease(release)
def scan_builds(branch_parent_directories, verbose=True): """Return a sequence of dictionaries describing builds in branch_parent_directories.""" builds = [] for branch_parent_directory in branch_parent_directories: for branch in listdir(branch_parent_directory): # 23 is experimentally shown to be safe if len(branch) > 23: if verbose: # this warning is going to happen but better not to spam cron email # so the warning is only produced in verbose mode print 'WARNING: skipping', branch, 'since the labels may crash pxelinux' continue if branch == 'netboots': continue branchd = join(branch_parent_directory, branch) if isfile(branchd): continue try: tagfiles = listdir(branchd) except OSError: print 'WARNING: unable to access', branchd continue for tag in tagfiles: if not is_tag(tag): continue branch_from_tag = extract_branch(tag) if branch_from_tag != branch: print 'WARNING: branch/tag confusion in', print join(branchd, tag), print 'so leaving that build out' continue root = join(branchd, tag) builds += inspect_build(root, tag, 'build', tag) return builds
def scan_releases(releases_directory): """Return a sequence of dictionaries describing releases. Will not cope with many of these inconsistent releases that predate release.py; they are ignored.""" releases = [] rnames = {} for release in listdir(releases_directory): nfd_dir = join(releases_directory, release, NOT_FOR_DISTRIBUTION) if isdir(nfd_dir): nfd_tags = [f for f in listdir(nfd_dir) if is_tag(f)] if len(nfd_tags) == 0: # no tags, which happens for manual releases # eg 2014-01-30-XT-3.2.0-SyncXT-Fix continue if len(nfd_tags) != 1: print >>stderr, 'WARNING: found', nfd_tags, print >>stderr, 'rather than exactly one tag in', nfd_dir, print >>stderr, 'so skipping', release continue tag = nfd_tags[0] builddir = join(nfd_dir, tag) name = release if DATE_REGEXP.match(name): name = name[11:] name = name.replace('XT-', '').replace('-Release', '').lower() if name in rnames: print >>stderr, 'WARNING: name clash on', release, name, print >>stderr, nfd_dir, rnames[name] else: releases += inspect_build(builddir, tag, 'release', name) rnames[name] = nfd_dir return releases
def scan_releases(releases_directory): """Return a sequence of dictionaries describing releases. Will not cope with many of these inconsistent releases that predate release.py; they are ignored.""" releases = [] rnames = {} for release in listdir(releases_directory): nfd_dir = join(releases_directory, release, NOT_FOR_DISTRIBUTION) if isdir(nfd_dir): nfd_tags = [f for f in listdir(nfd_dir) if is_tag(f)] if len(nfd_tags) == 0: # no tags, which happens for manual releases # eg 2014-01-30-XT-3.2.0-SyncXT-Fix continue if len(nfd_tags) != 1: print >> stderr, 'WARNING: found', nfd_tags, print >> stderr, 'rather than exactly one tag in', nfd_dir, print >> stderr, 'so skipping', release continue tag = nfd_tags[0] builddir = join(nfd_dir, tag) name = release if DATE_REGEXP.match(name): name = name[11:] name = name.replace('XT-', '').replace('-Release', '').lower() if name in rnames: print >> stderr, 'WARNING: name clash on', release, name, print >> stderr, nfd_dir, rnames[name] else: releases += inspect_build(builddir, tag, 'release', name) rnames[name] = nfd_dir return releases
def main(): """Entry point""" args = get_args() if args.build_output: if not isdir(args.build_output): print 'ERROR:', args.build_output, 'not found' exit(1) build = populate(inspect_build(args.build_output, None)[0], args.netboot_url, args.autoinstall_url) write_netboot(build, args.output_directory, pretend=not args.apply) check_call(['rsync', '-raP', args.build_output+'/repository/', args.output_directory]) atomic_write(join(args.output_directory, 'pxelinux.cfg'), ('#autogenerated by genpxe at %s\n' % (asctime()))+ generate_pxelinux_cfg(build) + '\nlabel local\n localboot 0\ndefault=build\nprompt 1\n') return if args.verbose: print 'INFO: scanning builds' builds = order_by('build_number', scan_builds(args.scan_directory, verbose=args.verbose)) if args.verbose: print 'INFO: found', len(builds), 'builds' if args.verbose: print 'INFO: scanning releases' releases = order_by('alias', scan_releases(args.releases_directory)) if args.clean_old_netboots: clean_old_netboots(args.output_directory, builds+releases, verbose=args.verbose, pretend=not args.apply) if args.generate_netboots: count = len(releases+builds) if args.verbose: print 'INFO: updating netboot material for', count, print 'builds' for build in releases + builds: write_netboot(populate(build, args.netboot_url, args.autoinstall_url), join(args.output_directory, 'builds', build['branch'], build['tag']), pretend=not args.apply) if args.generate_pxelinux_includes: generate_pxelinux_includes(args.output_directory, builds, releases, args, verbose=args.verbose)