changeset 89:3caf4a5ecbf0

Add scripts that help publish the packages produced by the tree packager
author Bernhard Herzog <bh@intevation.de>
date Tue, 11 Sep 2007 13:48:18 +0000
parents 3ae54f99db26
children 6ed1c881ee1b
files bin/listpackages.py bin/publishpackages.py demopublishpackages.cfg
diffstat 3 files changed, 233 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/listpackages.py	Tue Sep 11 13:48:18 2007 +0000
@@ -0,0 +1,73 @@
+#! /usr/bin/python2.4
+# Copyright (C) 2007 by Intevation GmbH
+# Authors:
+# Bernhard Herzog <bh@intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with the software for details.
+
+"""List the absolute filenames of packages created by treepkg"""
+
+import sys
+
+import treepkgcmd
+from treepkg.options import create_parser
+from treepkg.report import get_packager_group
+
+def parse_commandline():
+    parser = create_parser()
+    parser.set_defaults(binary=False, source=False)
+    parser.add_option("--revision", type="int",
+                      help=("The revision whose files are to be listed."
+                            " If not given, the latest revision is used"))
+    parser.add_option("--track",
+                      help=("The package track whose files are to be listed"))
+    parser.add_option("--source", action="store_true",
+                      help=("List source packages"))
+    parser.add_option("--binary", action="store_true",
+                      help=("List binary packages"))
+    return parser.parse_args()
+
+
+def list_track_packages(track, revision, source, binary):
+    revisions = track.get_revisions()
+    if not revisions:
+        print >>sys.stderr, "No revisions have been packaged"
+        sys.exit(1)
+
+    if revision is None:
+        revpkg = revisions[-1]
+    else:
+        for revpkg in revisions:
+            if revpkg.revision == revision:
+                break
+        else:
+            revpkg = None
+
+    if revpkg is not None:
+        if source:
+            for filename in revpkg.list_source_files():
+                print filename
+        if binary:
+            for filename in revpkg.list_binary_files():
+                print filename
+    else:
+        print >>sys.stderr, "No revision", repr(revision)
+        sys.exit(1)
+
+def list_packages(config_file, trackname, revision, source, binary):
+    group = get_packager_group(config_file)
+    for track in group.get_package_tracks():
+        if track.name == trackname:
+            list_track_packages(track, revision, source, binary)
+            break
+    else:
+        print >>sys.stderr, "no track named", trackname
+        sys.exit(1)
+
+def main():
+    options, args = parse_commandline()
+    list_packages(options.config_file, options.track, options.revision,
+                  source=options.source, binary=options.binary)
+
+main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/publishpackages.py	Tue Sep 11 13:48:18 2007 +0000
@@ -0,0 +1,123 @@
+#! /usr/bin/python2.4
+# Copyright (C) 2007 by Intevation GmbH
+# Authors:
+# Bernhard Herzog <bh@intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with the software for details.
+
+"""Publishes selected packages created by treepkg"""
+
+import sys
+import os
+import shutil
+from optparse import OptionParser
+from ConfigParser import SafeConfigParser
+
+import treepkgcmd
+from treepkg.readconfig import read_config_section
+from treepkg.run import call, capture_output
+from treepkg.cmdexpand import cmdexpand
+from treepkg.util import ensure_directory, listdir_abs
+
+
+def remove_trailing_slashes(s):
+    return s.rstrip("/")
+
+def expand_filename(filename):
+    """
+    Applies os.path.expanduser and os.path.expandvars to filename
+    """
+    return os.path.expandvars(os.path.expanduser(filename))
+
+config_desc = ["build_user", "build_host", "build_listpackages",
+               "publish_user", "publish_host", "publish_apt_archive_update",
+               ("publish_dir", remove_trailing_slashes),
+               ("cachedir",
+                lambda s: expand_filename(remove_trailing_slashes(s)))]
+
+def read_config(filename):
+    parser = SafeConfigParser()
+    parser.read([filename])
+    return read_config_section(parser, "publishpackages", config_desc)
+
+def parse_commandline():
+    parser = OptionParser()
+    parser.set_defaults(config_file=os.path.join(treepkgcmd.topdir,
+                                                 "publishpackages.cfg"))
+    parser.add_option("--config-file",
+                      help=("The configuration file."
+                            " Default is publishpackages.cfg"))
+    parser.add_option("--revision",
+                      help=("The revision whose files are to be published."
+                            " If not given, the latest revision is used"))
+    parser.add_option("--dist",
+                      help=("The debian distribution name to use on"
+                            " the publishing system"))
+    parser.add_option("--section",
+                      help=("The debian distribution section name to use on"
+                            " the publishing system"))
+    parser.add_option("--track",
+                      help=("The package track whose files are to be"
+                            " published"))
+    return parser.parse_args()
+
+
+def publish_packages_arch(variables, track, revision, dist, section, arch):
+    # create web-page on build host
+    if arch == "source":
+        variables["pkgtype"] = "--source"
+    else:
+        variables["pkgtype"] = "--binary"
+
+    files = capture_output(cmdexpand("ssh $build_user$@$build_host"
+                                     " $build_listpackages"
+                                     " --track $track @revision $pkgtype",
+                                     **variables)).strip().split("\n")
+    # scp the packages to the cache dir
+    cachedir = variables["cachedir"]
+    shutil.rmtree(cachedir, ignore_errors=True)
+    ensure_directory(cachedir)
+    userhost = "%(build_user)s@%(build_host)s:" % variables
+    call(cmdexpand("scp @files $cachedir/",
+                   files = [userhost + filename for filename in files],
+                   **variables))
+
+    # copy the packages to the remote publishing host.  Create the
+    # destination directory if it doesn't exist yet.
+    destdir = os.path.join(variables["publish_dir"], dist, section, arch)
+    call(cmdexpand("ssh $publish_user$@$publish_host mkdir --parents $destdir",
+                   destdir=destdir, **variables))
+    call(cmdexpand("scp @files $publish_user$@$publish_host:$destdir",
+                   files=listdir_abs(cachedir), destdir=destdir,
+                   **variables))
+
+
+def publish_packages(config_filename, track, revision, dist, section):
+    config = read_config(config_filename)
+
+    variables = config.copy()
+    variables["track"] = track
+    if revision:
+        variables["revision"] = ["--revision", revision]
+    else:
+        variables["revision"] = []
+
+    for arch in ["binary-i386", "source"]:
+        publish_packages_arch(variables, track, revision, dist, section, arch)
+
+    # update apt archive
+    call(cmdexpand("ssh $publish_user$@$publish_host"
+                   " $publish_apt_archive_update",
+                   **variables))
+
+def main():
+    options, args = parse_commandline()
+    for required_opt in ["track", "dist", "section"]:
+        if getattr(options, required_opt) is None:
+            print >>sys.stderr, "The --%s option must be given" % required_opt
+            sys.exit(1)
+    publish_packages(options.config_file, options.track, options.revision,
+                     options.dist, options.section)
+
+main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demopublishpackages.cfg	Tue Sep 11 13:48:18 2007 +0000
@@ -0,0 +1,37 @@
+# Demo configuration file for publishpackages.py.  The default config
+# file used by publishpackages.py is publishpackages.cfg, so to use this
+# file as the basis for your configuration, copy or rename this file and
+# adapt it to your needs.
+
+[publishpackages]
+# Username and host on which the treepackager runs.  publishpackages.py
+# has to be able to connect to that host as the builduser via ssh
+# without knowning the password.  This is best achieved with the
+# ssh-agent.
+build_user: builder
+build_host: localhost
+
+# the program to run on build_host to list the filenames of the packages
+# in question.  Currently publishpackages.py assumes that the default
+# configuration for that program works.
+build_listpackages: ~/treepkg/bin/bin/listpackages.py
+
+# Username and host on which to publish the packages.
+# publishpackages.py uses ssh to execute commands on the publish_host to
+# create directories and scp to copy the files from the local cache to
+# the publish_host.
+publish_user: builder
+publish_host: localhost
+
+# the directory on the publish_host where the apt directories reside.
+publish_dir: /home/ftp/apt/dists/
+
+# Command to execute on the build host to update the apt archive
+publish_apt_archive_update: /home/ftp/apt/update
+
+# local cache directory.  publishpackages.py may delete it and its
+# contents.  The value is passed through the python functions
+# os.expanduser and os.expandvars, so references to home directories of
+# the form ~ or ~user at the beginning of the value and environment
+# variable references of the form $VAR or ${VAR} are expanded.
+cachedir: /tmp/${LOGNAME}/treepkg-package-cache
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)