aboutsummaryrefslogtreecommitdiffstats
path: root/RepSys/binrepo.py
diff options
context:
space:
mode:
Diffstat (limited to 'RepSys/binrepo.py')
-rw-r--r--RepSys/binrepo.py395
1 files changed, 0 insertions, 395 deletions
diff --git a/RepSys/binrepo.py b/RepSys/binrepo.py
deleted file mode 100644
index 4035128..0000000
--- a/RepSys/binrepo.py
+++ /dev/null
@@ -1,395 +0,0 @@
-from RepSys import Error, config, mirror, layout
-from RepSys.util import execcmd, rellink
-from RepSys.svn import SVN
-
-import sys
-import os
-import string
-import stat
-import shutil
-import re
-import tempfile
-import hashlib
-import urlparse
-import threading
-from cStringIO import StringIO
-
-DEFAULT_TARBALLS_REPO = "/tarballs"
-BINARIES_DIR_NAME = "SOURCES"
-BINARIES_CHECKOUT_NAME = "SOURCES-bin"
-
-PROP_USES_BINREPO = "mdv:uses-binrepo"
-PROP_BINREPO_REV = "mdv:binrepo-rev"
-
-BINREPOS_SECTION = "binrepos"
-
-SOURCES_FILE = "sha1.lst"
-
-class ChecksumError(Error):
- pass
-
-def svn_baseurl(target):
- svn = SVN()
- info = svn.info2(target)
- if info is None:
- # unversioned resource
- newtarget = os.path.dirname(target)
- info = svn.info2(newtarget)
- assert info is not None, "svn_basedir should not be used with a "\
- "non-versioned directory"
- root = info["Repository Root"]
- url = info["URL"]
- kind = info["Node Kind"]
- path = url[len(root):]
- if kind == "directory":
- return url
- basepath = os.path.dirname(path)
- baseurl = mirror.normalize_path(url + "/" + basepath)
- return baseurl
-
-def svn_root(target):
- svn = SVN()
- info = svn.info2(target)
- if info is None:
- newtarget = os.path.dirname(target)
- info = svn.info2(newtarget)
- assert info is not None
- return info["Repository Root"]
-
-def enabled(url):
- #TODO use information from url to find out whether we have a binrepo
- # available for this url
- use = config.getbool("global", "use-binaries-repository", False)
- return use
-
-def default_repo():
- base = config.get("global", "binaries-repository", None)
- if base is None:
- default_parent = config.get("global", "default_parent", None)
- if default_parent is None:
- raise Error, "no binaries-repository nor default_parent "\
- "configured"
- comps = urlparse.urlparse(default_parent)
- base = comps[1] + ":" + DEFAULT_TARBALLS_REPO
- return base
-
-def translate_url(url):
- url = mirror.normalize_path(url)
- main = mirror.normalize_path(layout.repository_url())
- subpath = url[len(main)+1:]
- # [binrepos]
- # updates/2009.0 = svn+ssh://svn.mandriva.com/svn/binrepo/20090/
- ## svn+ssh://svn.mandriva.com/svn/packages/2009.0/trafshow/current
- ## would translate to
- ## svn+ssh://svn.mandriva.com/svn/binrepo/20090/updates/trafshow/current/
- binbase = None
- if BINREPOS_SECTION in config.sections():
- for option, value in config.walk(BINREPOS_SECTION):
- if subpath.startswith(option):
- binbase = value
- break
- binurl = mirror._joinurl(binbase or default_repo(), subpath)
- return binurl
-
-def translate_topdir(path):
- """Returns the URL in the binrepo from a given path inside a SVN
- checkout directory.
-
- @path: if specified, returns a URL in the binrepo whose path is the
- same as the path inside the main repository.
- """
- baseurl = svn_baseurl(path)
- binurl = translate_url(baseurl)
- target = mirror.normalize_path(binurl)
- return target
-
-def is_binary(path):
- raw = config.get("binrepo", "upload-match",
- "\.(7z|Z|bin|bz2|cpio|db|deb|egg|gem|gz|jar|jisp|lzma|"\
- "pdf|pgn\\.gz|pk3|png|rpm|run|sdz|smzip|tar|tbz|"\
- "tbz2|tgz|ttf|uqm|wad|war|xar|xpi|xz|zip|wav|mp3|ogg|"\
- "jpg|png|gif|avi|mpg|mpeg|rar)$")
- maxsize = config.getint("binrepo", "upload-match-size", "1048576") # 1MiB
- expr = re.compile(raw)
- name = os.path.basename(path)
- if expr.search(name):
- return True
- st = os.stat(path)
- if st[stat.ST_SIZE] >= maxsize:
- return True
- return False
-
-def find_binaries(paths):
- new = []
- for path in paths:
- if os.path.isdir(path):
- for name in os.listdir(path):
- fpath = os.path.join(path, name)
- if is_binary(fpath):
- new.append(fpath)
- else:
- if is_binary(path):
- new.append(path)
- return new
-
-def make_symlinks(source, dest):
- todo = []
- tomove = []
- for name in os.listdir(source):
- path = os.path.join(source, name)
- if not os.path.isdir(path) and not name.startswith("."):
- destpath = os.path.join(dest, name)
- linkpath = rellink(path, destpath)
- if os.path.exists(destpath):
- if (os.path.islink(destpath) and
- os.readlink(destpath) == linkpath):
- continue
- movepath = destpath + ".repsys-moved"
- if os.path.exists(movepath):
- raise Error, "cannot create symlink, %s already "\
- "exists (%s too)" % (destpath, movepath)
- tomove.append((destpath, movepath))
- todo.append((destpath, linkpath))
- for destpath, movepath in tomove:
- os.rename(destpath, movepath)
- for destpath, linkpath in todo:
- os.symlink(linkpath, destpath)
-
-def download(targetdir, pkgdirurl=None, export=False, show=True,
- revision=None, symlinks=True, check=False):
- assert not export or (export and pkgdirurl)
- svn = SVN()
- sourcespath = os.path.join(targetdir, "SOURCES")
- binpath = os.path.join(targetdir, BINARIES_CHECKOUT_NAME)
- if pkgdirurl:
- topurl = translate_url(pkgdirurl)
- else:
- topurl = translate_topdir(targetdir)
- binrev = None
- if revision:
- if pkgdirurl:
- binrev = mapped_revision(pkgdirurl, revision)
- else:
- binrev = mapped_revision(targetdir, revision, wc=True)
- binurl = mirror._joinurl(topurl, BINARIES_DIR_NAME)
- if export:
- svn.export(binurl, binpath, rev=binrev, show=show)
- else:
- svn.checkout(binurl, binpath, rev=binrev, show=show)
- if symlinks:
- make_symlinks(binpath, sourcespath)
- if check:
- check_sources(targetdir)
-
-def import_binaries(topdir, pkgname):
- """Import all binaries from a given package checkout
-
- (with pending svn adds)
-
- @topdir: the path to the svn checkout
- """
- svn = SVN()
- topurl = translate_topdir(topdir)
- sourcesdir = os.path.join(topdir, "SOURCES")
- bintopdir = tempfile.mktemp("repsys")
- try:
- svn.checkout(topurl, bintopdir)
- checkout = True
- except Error:
- bintopdir = tempfile.mkdtemp("repsys")
- checkout = False
- try:
- bindir = os.path.join(bintopdir, BINARIES_DIR_NAME)
- if not os.path.exists(bindir):
- if checkout:
- svn.mkdir(bindir)
- else:
- os.mkdir(bindir)
- binaries = find_binaries([sourcesdir])
- update = update_sources_threaded(topdir, added=binaries)
- for path in binaries:
- name = os.path.basename(path)
- binpath = os.path.join(bindir, name)
- os.rename(path, binpath)
- try:
- svn.remove(path)
- except Error:
- # file not tracked
- svn.revert(path)
- if checkout:
- svn.add(binpath)
- log = "imported binaries for %s" % pkgname
- if checkout:
- rev = svn.commit(bindir, log=log)
- else:
- rev = svn.import_(bintopdir, topurl, log=log)
- svn.propset(PROP_USES_BINREPO, "yes", topdir)
- svn.propset(PROP_BINREPO_REV, str(rev), topdir)
- update.join()
- svn.add(sources_path(topdir))
- finally:
- shutil.rmtree(bintopdir)
-
-def create_package_dirs(bintopdir):
- svn = SVN()
- binurl = mirror._joinurl(bintopdir, BINARIES_DIR_NAME)
- silent = config.get("log", "ignore-string", "SILENT")
- message = "%s: created binrepo package structure" % silent
- svn.mkdir(binurl, log=message, parents=True)
-
-def parse_sources(path):
- entries = {}
- f = open(path)
- for rawline in f:
- line = rawline.strip()
- try:
- sum, name = line.split(None, 1)
- except ValueError:
- # failed to unpack, line format error
- raise Error, "invalid line in sources file: %s" % rawline
- entries[name] = sum
- return entries
-
-def check_hash(path, sum):
- newsum = file_hash(path)
- if newsum != sum:
- raise ChecksumError, "different checksums for %s: expected %s, "\
- "but %s was found" % (path, sum, newsum)
-
-def check_sources(topdir):
- spath = sources_path(topdir)
- if not os.path.exists(spath):
- raise Error, "'%s' was not found" % spath
- entries = parse_sources(spath)
- for name, sum in entries.iteritems():
- fpath = os.path.join(topdir, "SOURCES", name)
- check_hash(fpath, sum)
-
-def file_hash(path):
- sum = hashlib.sha1()
- f = open(path)
- while True:
- block = f.read(4096)
- if not block:
- break
- sum.update(block)
- f.close()
- return sum.hexdigest()
-
-def sources_path(topdir):
- path = os.path.join(topdir, "SOURCES", SOURCES_FILE)
- return path
-
-def update_sources(topdir, added=[], removed=[]):
- path = sources_path(topdir)
- entries = {}
- if os.path.isfile(path):
- entries = parse_sources(path)
- f = open(path, "w") # open before calculating hashes
- for name in removed:
- entries.pop(removed)
- for added_path in added:
- name = os.path.basename(added_path)
- entries[name] = file_hash(added_path)
- for name in sorted(entries):
- f.write("%s %s\n" % (entries[name], name))
- f.close()
-
-def update_sources_threaded(*args, **kwargs):
- t = threading.Thread(target=update_sources, args=args, kwargs=kwargs)
- t.start()
- t.join()
- return t
-
-def upload(path, message=None):
- from RepSys.rpmutil import getpkgtopdir
- svn = SVN()
- if not os.path.exists(path):
- raise Error, "not found: %s" % path
- # XXX check if the path is under SOURCES/
- paths = find_binaries([path])
- if not paths:
- raise Error, "'%s' does not seem to have any tarballs" % path
- topdir = getpkgtopdir()
- bintopdir = translate_topdir(topdir)
- binurl = mirror._joinurl(bintopdir, BINARIES_DIR_NAME)
- sourcesdir = os.path.join(topdir, "SOURCES")
- bindir = os.path.join(topdir, BINARIES_CHECKOUT_NAME)
- silent = config.get("log", "ignore-string", "SILENT")
- if not os.path.exists(bindir):
- try:
- download(topdir, show=False)
- except Error:
- # possibly the package does not exist
- # (TODO check whether it is really a 'path not found' error)
- pass
- if not os.path.exists(bindir):
- create_package_dirs(bintopdir)
- svn.propset(PROP_USES_BINREPO, "yes", topdir)
- svn.commit(topdir, log="%s: created binrepo structure" % silent)
- download(topdir, show=False)
- for path in paths:
- if svn.info2(path):
- sys.stderr.write("'%s' is already tracked by svn, ignoring\n" %
- path)
- continue
- name = os.path.basename(path)
- binpath = os.path.join(bindir, name)
- os.rename(path, binpath)
- svn.add(binpath)
- if not message:
- message = "%s: new binary files %s" % (silent, " ".join(paths))
- make_symlinks(bindir, sourcesdir)
- update = update_sources_threaded(topdir, added=paths)
- rev = svn.commit(binpath, log=message)
- svn.propset(PROP_BINREPO_REV, str(rev), topdir)
- sources = sources_path(topdir)
- svn.add(sources)
- update.join()
- svn.commit(topdir + " " + sources, log=message, nonrecursive=True)
-
-def mapped_revision(target, revision, wc=False):
- """Maps a txtrepo revision to a binrepo datespec
-
- This datespec can is intended to be used by svn .. -r DATE.
-
- @target: a working copy path or a URL
- @revision: if target is a URL, the revision number used when fetching
- svn info
- @wc: if True indicates that 'target' must be interpreted as a
- the path of a svn working copy, otherwise it is handled as a URL
- """
- svn = SVN()
- binrev = None
- if wc:
- spath = sources_path(target)
- if os.path.exists(spath):
- infolines = svn.info(spath, xml=True)
- if infolines:
- rawinfo = "".join(infolines) # arg!
- found = re.search("<date>(.*?)</date>", rawinfo).groups()
- date = found[0]
- else:
- raise Error, "bogus 'svn info' for '%s'" % spath
- else:
- raise Error, "'%s' was not found" % spath
- else:
- url = mirror._joinurl(target, sources_path(""))
- date = svn.propget("svn:date", url, rev=revision, revprop=True)
- if not date:
- raise Error, "no valid date available for '%s'" % url
- binrev = "{%s}" % date
- return binrev
-
-def markrelease(sourceurl, releasesurl, version, release, revision):
- svn = SVN()
- binrev = mapped_revision(sourceurl, revision)
- binsource = translate_url(sourceurl)
- binreleases = translate_url(releasesurl)
- versiondir = mirror._joinurl(binreleases, version)
- dest = mirror._joinurl(versiondir, release)
- svn.mkdir(binreleases, noerror=1, log="created directory for releases")
- svn.mkdir(versiondir, noerror=1, log="created directory for version %s" % version)
- svn.copy(binsource, dest, rev=binrev,
- log="%%markrelease ver=%s rel=%s rev=%s binrev=%s" % (version, release,
- revision, binrev))