summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Kreen2009-06-05 10:29:05 +0000
committerMarko Kreen2009-06-07 15:18:48 +0000
commit49e87a1c2e41ab613f0c383c8749066be92e14d2 (patch)
tree6da1eb793b1763c617d53ba86fe41008cd26c250
parente9f032912997443878fdd70634ec644d73fef1c8 (diff)
pkgloader module to be able to coexist with 2.x
Use scheme that pygtk uses to support parallel installations: import pkgloader pkgloader.require('skytools', '3.0') import skytools This will allow keeping old module installed by default and new version is used only by request.
-rwxr-xr-xpython/londiste.py7
-rwxr-xr-xpython/pgqadm.py4
-rw-r--r--python/pkgloader.py89
-rwxr-xr-xpython/qadmin.py7
-rwxr-xr-xpython/setadm.py7
-rwxr-xr-xpython/walmgr.py5
-rwxr-xr-xscripts/queue_loader.py7
-rwxr-xr-xscripts/queue_mover.py7
-rwxr-xr-xscripts/queue_splitter.py7
-rwxr-xr-xscripts/scriptmgr.py7
-rwxr-xr-xscripts/skytools_upgrade.py5
11 files changed, 143 insertions, 9 deletions
diff --git a/python/londiste.py b/python/londiste.py
index 6b6ae2e8..745968ea 100755
--- a/python/londiste.py
+++ b/python/londiste.py
@@ -22,7 +22,12 @@ Config template::
"""
-import sys, os, os.path, optparse, skytools
+import sys, os, os.path, optparse
+
+import pkgloader
+pkgloader.require('skytools', '3.0')
+
+import skytools
# python 2.3 will try londiste.py first...
if os.path.exists(os.path.join(sys.path[0], 'londiste.py')) \
diff --git a/python/pgqadm.py b/python/pgqadm.py
index 672f7abf..bd1ff8a6 100755
--- a/python/pgqadm.py
+++ b/python/pgqadm.py
@@ -26,6 +26,10 @@ Config template::
"""
import sys
+
+import pkgloader
+pkgloader.require('skytools', '3.0')
+
import skytools, pgq
from pgq.cascade.admin import CascadeAdmin
diff --git a/python/pkgloader.py b/python/pkgloader.py
new file mode 100644
index 00000000..cf7fac87
--- /dev/null
+++ b/python/pkgloader.py
@@ -0,0 +1,89 @@
+"""Loader for Skytools modules.
+
+Primary idea is to allow several major versions to co-exists.
+Secondary idea - allow checking minimal minor version.
+
+"""
+
+import sys, os, os.path, re
+
+__all__ = ['require']
+
+_top = os.path.dirname(os.path.abspath(os.path.normpath(__file__)))
+
+_pkg_cache = None
+_import_cache = {}
+_pat = re.compile('^([a-z]+)-([0-9]+).([0-9]+)$')
+
+def _load_pkg_cache():
+ global _pkg_cache
+ if _pkg_cache is not None:
+ return _pkg_cache
+ _pkg_cache = {}
+ for dir in os.listdir(_top):
+ m = _pat.match(dir)
+ if not m:
+ continue
+ modname = m.group(1)
+ modver = (int(m.group(2)), int(m.group(3)))
+ _pkg_cache.setdefault(modname, []).append((modver, dir))
+ for vlist in _pkg_cache.itervalues():
+ vlist.sort(reverse = True)
+ return _pkg_cache
+
+def _install_path(pkg, newpath):
+ for p in sys.path:
+ pname = os.path.basename(p)
+ m = _pat.match(pname)
+ if m and m.group(1) == pkg:
+ sys.path.remove(p)
+ sys.path.insert(0, newpath)
+
+def require(pkg, reqver):
+ # parse arg
+ reqval = tuple([int(n) for n in reqver.split('.')])
+ need = reqval[:2] # cut minor ver
+
+ # check if we already have one installed
+ if pkg in _import_cache:
+ got = _import_cache[pkg]
+ if need[0] != got[0] or reqval > got:
+ raise ImportError("Request for package '%s' ver '%s', have '%s'" % (
+ pkg, reqver, '.'.join(_skytools_required_version)))
+ return
+
+ # pick best ver from available ones
+ _pkg_cache = _load_pkg_cache()
+ if pkg not in _pkg_cache:
+ return
+
+ for pkgver, pkgdir in _pkg_cache[pkg]:
+ if pkgver[0] == need[0] and pkgver >= need:
+ # install the best on
+ _install_path(pkg, os.path.join(_top, pkgdir))
+ break
+
+ # now import whatever is available
+ inst_ver = reqval
+ try:
+ mod = __import__(pkg)
+ ver_str = mod.__version__
+ # check if it is actually useful
+ full_ver = tuple([int(x) for x in full_str.split('.')])
+ if full_ver[0] != reqval[0] or reqval > full_ver:
+ raise ImportError("Request for Skytools ver '%s', got '%s'" % (
+ reqver, full_str))
+ raise ImportError("Request for package '%s' ver '%s', have '%s'" % (
+ pkg, reqver, full_str))
+ inst_ver = full_ver
+ except ImportError:
+ pass
+ except AttributeError:
+ pass
+
+ # remember full version
+ _import_cache[pkg] = inst_ver
+
+ return mod
+
+
diff --git a/python/qadmin.py b/python/qadmin.py
index 1d193fcf..4ab3999d 100755
--- a/python/qadmin.py
+++ b/python/qadmin.py
@@ -52,7 +52,12 @@ General options:
--version
'''
-import sys, os, readline, skytools, getopt, re
+import sys, os, readline, getopt, re
+
+import pkgloader
+pkgloader.require('skytools', '3.0')
+
+import skytools
script = None
diff --git a/python/setadm.py b/python/setadm.py
index 2c93d4ef..1d9520a8 100755
--- a/python/setadm.py
+++ b/python/setadm.py
@@ -3,7 +3,12 @@
"""SetAdmin launcher.
"""
-import sys, pgq.cascade.admin
+import sys
+
+import pkgloader
+pkgloader.require('skytools', '3.0')
+
+import pgq.cascade.admin
if __name__ == '__main__':
script = pgq.cascade.admin.CascadeAdmin('cascade_admin', 'node_db', sys.argv[1:], worker_setup = False)
diff --git a/python/walmgr.py b/python/walmgr.py
index c3e8fc86..2acf4e08 100755
--- a/python/walmgr.py
+++ b/python/walmgr.py
@@ -50,6 +50,11 @@ Additional features:
import os, sys, skytools, re, signal, time, traceback
import errno, glob, ConfigParser, shutil
+import pkgloader
+pkgloader.require('skytools', '3.0')
+
+import skytools
+
MASTER = 1
SLAVE = 0
diff --git a/scripts/queue_loader.py b/scripts/queue_loader.py
index 1b3090df..97742b82 100755
--- a/scripts/queue_loader.py
+++ b/scripts/queue_loader.py
@@ -79,10 +79,13 @@ Config template::
create_sql =
"""
-import sys, time, skytools
+import sys, time
-from pgq.cascade.worker import CascadedWorker
+import pkgloader
+pkgloader.require('skytools', '3.0')
+import skytools
+from pgq.cascade.worker import CascadedWorker
from skytools import quote_ident, quote_fqident, UsageError
# todo: auto table detect
diff --git a/scripts/queue_mover.py b/scripts/queue_mover.py
index 92fe5370..f52ae7a5 100755
--- a/scripts/queue_mover.py
+++ b/scripts/queue_mover.py
@@ -19,7 +19,12 @@ Config template::
use_skylog = 0
"""
-import sys, os, pgq
+import sys, os
+
+import pkgloader
+pkgloader.require('skytools', '3.0')
+
+import pgq
class QueueMover(pgq.SerialConsumer):
__doc__ = __doc__
diff --git a/scripts/queue_splitter.py b/scripts/queue_splitter.py
index dab23982..6fed65c6 100755
--- a/scripts/queue_splitter.py
+++ b/scripts/queue_splitter.py
@@ -20,7 +20,12 @@ Config template::
use_skylog = 0
"""
-import sys, pgq
+import sys
+
+import pkgloader
+pkgloader.require('skytools', '3.0')
+
+import pgq
class QueueSplitter(pgq.SerialConsumer):
__doc__ = __doc__
diff --git a/scripts/scriptmgr.py b/scripts/scriptmgr.py
index 34bdc35d..03b3aa31 100755
--- a/scripts/scriptmgr.py
+++ b/scripts/scriptmgr.py
@@ -43,7 +43,12 @@ Config template:
disabled = 1
"""
-import sys, os, skytools, signal, glob, ConfigParser, time
+import sys, os, signal, glob, ConfigParser, time
+
+import pkgloader
+pkgloader.require('skytools', '3.0')
+
+import skytools
command_usage = """
%prog [options] INI CMD [subcmd args]
diff --git a/scripts/skytools_upgrade.py b/scripts/skytools_upgrade.py
index 557dbd9c..90866611 100755
--- a/scripts/skytools_upgrade.py
+++ b/scripts/skytools_upgrade.py
@@ -2,7 +2,10 @@
"""Upgrade script for versioned schemas."""
-import sys, os, re, skytools
+import sys, os, re
+
+import pkgloader
+pkgloader.require('skytools', '3.0')
ver_rx = r"(\d+)([.](\d+)([.](\d+))?)?"
ver_rc = re.compile(ver_rx)