bricks@406: #! /usr/bin/python bricks@406: # Copyright (C) 2007 - 2010 by Intevation GmbH bricks@406: # Authors: bricks@406: # Bernhard Herzog bricks@406: # Bjoern Ricks bricks@406: # bricks@406: # This program is free software under the GPL (>=v2) bricks@406: # Read the file COPYING coming with the software for details. bricks@406: bricks@406: """Publishes selected packages created by treepkg""" bricks@406: bricks@406: import os bricks@406: import sys bricks@406: import shlex bricks@406: bricks@406: from optparse import OptionParser bricks@406: from ConfigParser import SafeConfigParser bricks@406: bricks@406: import treepkgcmd bricks@406: from treepkg.readconfig import read_config_section, convert_bool bricks@406: from treepkg.run import call, capture_output bricks@406: from treepkg.cmdexpand import cmdexpand bricks@406: from treepkg.publish import * bricks@406: from treepkg.util import md5sum bricks@406: from treepkg.info.status import TreepkgInfo bricks@406: bricks@406: config_desc = ["distribution", "section", "num_newest", bricks@406: "build_user", "build_host", "build_listpackages", bricks@406: "publish_user", "publish_host", bricks@406: ("architectures", shlex.split, "i386, source"), bricks@406: ("after_upload_hook", shlex.split), bricks@406: ("publish_remove_old_packages", convert_bool), bricks@406: ("publish_dir", remove_trailing_slashes), bricks@406: ("cachedir", bricks@406: lambda s: expand_filename(remove_trailing_slashes(s)))] bricks@406: bricks@406: def read_config(filename): bricks@406: if not os.path.exists(filename): bricks@406: print >>sys.stderr, "Config file %s does not exist" % filename bricks@406: sys.exit(1) bricks@406: parser = SafeConfigParser() bricks@406: parser.read([filename]) bricks@406: return read_config_section(parser, "publishpackages", config_desc) bricks@406: bricks@406: def parse_commandline(): bricks@406: parser = OptionParser() bricks@406: parser.set_defaults(config_file=os.path.join(treepkgcmd.topdir, bricks@406: "publishpackages.cfg"), bricks@406: quiet=False) bricks@406: parser.add_option("--config-file", bricks@406: help=("The configuration file." bricks@406: " Default is publishpackages.cfg")) bricks@406: parser.add_option("--dist", bricks@406: help=("The debian distribution name to use on" bricks@406: " the publishing system")) bricks@406: parser.add_option("--section", bricks@406: help=("The debian distribution section name to use on" bricks@406: " the publishing system")) bricks@406: parser.add_option("--track", bricks@406: help=("The package track whose files are to be" bricks@406: " published. If not given, files of all tracks" bricks@406: " will be published")) bricks@406: parser.add_option("--quiet", action="store_true", bricks@406: help=("Do not print progress meters or other" bricks@406: " informational output")) bricks@406: return parser.parse_args() bricks@406: bricks@406: def get_treepkg_info(variables): bricks@406: runremote = prefix_for_remote_command(variables["build_user"], bricks@406: variables["build_host"]) bricks@406: xml = capture_output(cmdexpand("@runremote $build_listpackages" bricks@406: " --newest=$num_newest", bricks@406: #runremote=runremote, bricks@406: runremote="", bricks@409: **variables)) bricks@408: return TreepkgInfo.fromxml(xml) bricks@406: bricks@406: def get_binary_arch(arch): bricks@406: if not arch == "source": bricks@406: if not arch.startswith("binary"): bricks@406: arch = "binary-" + arch bricks@406: return arch bricks@406: bricks@406: def check_package_is_new(packagename, destdir, packagemd5sum): bricks@406: destpackage = os.path.join(destdir, packagename) bricks@406: if not os.path.isfile(destpackage): bricks@406: return True bricks@406: destmd5sum = md5sum(destpackage) bricks@408: return (destmd5sum != packagemd5sum) bricks@408: bricks@408: def copy_to_destdir(package, dir, arch, subdir): bricks@408: scp_flags = [] bricks@408: destdir = os.path.join(dir, arch, subdir) bricks@408: print "package: %s, destdir: %s" % (package.name, destdir) bricks@408: md5sum = "" bricks@408: for checksum in package.checksums: bricks@408: if checksum.type == "md5": bricks@408: md5sum = checksum.checksum bricks@408: break bricks@408: # update only if the packages differ bricks@408: if check_package_is_new(package.name, destdir, md5sum): bricks@408: pass bricks@408: # scp the packages to the cache dir bricks@408: #call(cmdexpand("scp -p @scp_flags $file $cachedir/", file=package.path, bricks@408: # scp_flags=scp_flags, cachedir=destdir)) bricks@406: bricks@406: def copy_to_cache(variables, track, revision, quiet, architectures=None): bricks@408: cachedir = variables["cachedir"] bricks@406: if quiet: bricks@406: scp_flags.append("-q") bricks@406: treepkginfo = get_treepkg_info(variables) bricks@408: allowedarchs = set([]) # contains all wanted architectures (incl. source) bricks@408: allarchs = set([]) # contains all present architectures (incl. source) bricks@408: binaryallpackages = [] bricks@406: # change e.g. armel in binary-armel bricks@408: if not architectures is None: bricks@408: for arch in architectures: bricks@408: allowedarchs.append(get_binary_arch(arch)) bricks@408: bricks@408: for track in treepkginfo.tracks: bricks@406: for rev in track.revisions: bricks@406: for package in rev.packages: bricks@408: # handle binary-all bricks@408: if package.arch == "binary-all": bricks@408: # add trackname for subdir name bricks@408: package.tackname = track.name bricks@408: binaryallpackages.append(package) bricks@406: break bricks@408: allarchs.append(package.arch) bricks@408: # only copy requested archs bricks@408: if len(allowedarchs) == 0 or \ bricks@408: package.arch in allowedarchs: bricks@408: copy_to_destdir(package, cachedir, package.arch, track.name) bricks@408: bricks@408: # copy binary-all packages bricks@408: if len(allowedarchs) == 0: bricks@408: binallarchs = allarchs - set(["source"]) bricks@408: else: bricks@408: binallarchs = allowedarchs & allarchs - set(["source"]) bricks@408: for package in binaryallpackages: bricks@408: for arch in binallarchs: bricks@408: copy_to_destdir(package, cachedir, arch, package.trackname) bricks@406: bricks@406: def publish_packages_arch(variables, track, revision, dist, section, bricks@406: quiet, architectures): bricks@406: copy_to_cache(variables, track, revision, quiet, architectures) bricks@406: # copy_to_publishdir(variables, dist, section, arch, quiet) bricks@406: bricks@406: def publish_packages(config_filename, track, revision, dist, section, quiet): bricks@406: config = read_config(config_filename) bricks@406: bricks@406: if dist is None: bricks@406: dist = config["distribution"] bricks@406: if section is None: bricks@406: section = config["section"] bricks@406: bricks@406: architectures = config["architectures"] bricks@406: publish_packages_arch(config, track, revision, dist, section, bricks@406: quiet, architectures) bricks@406: bricks@406: # update apt archive bricks@406: # call(config["after_upload_hook"]) bricks@406: bricks@406: def main(): bricks@406: options, args = parse_commandline() bricks@406: revision = None # for future use cases bricks@406: publish_packages(options.config_file, options.track, revision, bricks@406: options.dist, options.section, options.quiet) bricks@406: bricks@406: if __name__ == "__main__": bricks@406: main()