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@406: **variables)).splitlines() bricks@406: treepkginfo = 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@406: return destmd5sum == packagemd5sum bricks@406: bricks@406: def copy_to_cache(variables, track, revision, quiet, architectures=None): bricks@406: scp_flags = [] bricks@406: if quiet: bricks@406: scp_flags.append("-q") bricks@406: treepkginfo = get_treepkg_info(variables) bricks@406: treepkgroot = treepkginfo.root bricks@406: binaryarchs = [] bricks@406: # change e.g. armel in binary-armel bricks@406: for arch in architectures: bricks@406: binaryarchs.append(get_binary_arch(arch)) bricks@406: # add binary-all to requested packages bricks@406: if not binaryarchs is None: bricks@406: binaryarchs.append("binary-all") bricks@406: bricks@406: for track in treepkgroot.tracks: bricks@406: files = [] bricks@406: for rev in track.revisions: bricks@406: for package in rev.packages: bricks@406: # only copy requested archs (+ all) bricks@406: if not binaryarchs is None and \ bricks@406: not package.arch in binaryarchs: bricks@406: break bricks@406: destdir = os.path.join(variables["cachedir"], bricks@406: package.arch, bricks@406: track.name) bricks@406: print "package: %s, destdir: %s" % (package.name, destdir) bricks@406: md5sum = "" bricks@406: for checksum in package.checksums: bricks@406: if checksum.type == "md5": bricks@406: md5sum = checksum.checksum bricks@406: break bricks@406: # update only if the packages differ bricks@406: if check_package_is_new(package.name, destdir, md5sum): bricks@406: files.append(package.path) bricks@406: # scp the packages of a track to the cache dir bricks@406: #call(cmdexpand("scp -p @scp_flags @files $cachedir/", files=files, bricks@406: # scp_flags=scp_flagsd, cachedir=destdir)) 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()