summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-11-10 14:57:53 -0500
committerPatrick Uiterwijk <puiterwijk@redhat.com>2014-11-12 23:46:52 +0100
commit5e0b9747121eab67c5a3ee3bb42a677e35da7fd6 (patch)
treec93728a60d98385637c9dc82f05fa46fdf858e8f
parent0087ad1e0824b4b1c49ce1468bfbb2e492ac7992 (diff)
downloadipsilon-5e0b9747121eab67c5a3ee3bb42a677e35da7fd6.tar.gz
ipsilon-5e0b9747121eab67c5a3ee3bb42a677e35da7fd6.tar.xz
ipsilon-5e0b9747121eab67c5a3ee3bb42a677e35da7fd6.zip
Add simple SqlSession implementation
This allows us to store session data in the DB. This way session data can be shared by multiple servers behind a balancer. Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-by: Patrick Uiterwijk <puiterwijk@redhat.com>
-rwxr-xr-xipsilon/install/ipsilon-server-install12
-rwxr-xr-xipsilon/ipsilon2
-rwxr-xr-xipsilon/util/sessions.py74
-rwxr-xr-xquickrun.py3
-rw-r--r--templates/install/ipsilon.conf4
-rwxr-xr-xtests/helpers/common.py2
-rwxr-xr-xtests/pgdb.py2
7 files changed, 96 insertions, 3 deletions
diff --git a/ipsilon/install/ipsilon-server-install b/ipsilon/install/ipsilon-server-install
index c6d656d..df2a965 100755
--- a/ipsilon/install/ipsilon-server-install
+++ b/ipsilon/install/ipsilon-server-install
@@ -112,6 +112,18 @@ def install(plugins, args):
'datadir': args['data_dir'], 'dbname': 'transactions'},
'secure': "False" if args['secure'] == "no" else "True",
'debugging': "True" if args['server_debugging'] else "False"}
+ # Testing database sessions
+ if 'session_type' in args:
+ confopts['sesstype'] = args['session_type']
+ else:
+ confopts['sesstype'] = 'file'
+ if 'session_dburi' in args:
+ confopts['sessopt'] = 'dburi'
+ confopts['sessval'] = args['session_dburi']
+ else:
+ confopts['sessopt'] = 'path'
+ confopts['sessval'] = os.path.join(args['data_dir'], 'sessions')
+ # Whetehr to disable security (for testing)
if args['secure'] == 'no':
confopts['secure'] = "False"
confopts['sslrequiressl'] = ""
diff --git a/ipsilon/ipsilon b/ipsilon/ipsilon
index 681600d..094a09d 100755
--- a/ipsilon/ipsilon
+++ b/ipsilon/ipsilon
@@ -27,6 +27,7 @@ from ipsilon.util.data import AdminStore
from ipsilon.util import page
from ipsilon.root import Root
from jinja2 import Environment, FileSystemLoader
+import ipsilon.util.sessions
def nuke_session_locks():
@@ -51,6 +52,7 @@ elif os.path.isfile('/etc/ipsilon/ipsilon.conf'):
else:
raise IOError("Configuration file not found")
+cherrypy.lib.sessions.SqlSession = ipsilon.util.sessions.SqlSession
cherrypy.config.update(cfgfile)
nuke_session_locks()
diff --git a/ipsilon/util/sessions.py b/ipsilon/util/sessions.py
new file mode 100755
index 0000000..b724471
--- /dev/null
+++ b/ipsilon/util/sessions.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2014 Ipsilon project Contributors, for licensee see COPYING
+
+import base64
+from cherrypy.lib.sessions import Session
+from ipsilon.util.data import SqlStore, SqlQuery
+import threading
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+
+
+SESSION_COLUMNS = ['id', 'data', 'expiration_time']
+
+
+class SqlSession(Session):
+
+ dburi = None
+ _db = None
+ _proto = 2
+ locks = {}
+
+ @classmethod
+ def setup(cls, **kwargs):
+ """Initialization from cherrypy"""
+
+ for k, v in kwargs.items():
+ if k == 'storage_dburi':
+ cls.dburi = v
+
+ cls._db = SqlStore(cls.dburi)
+
+ def _exists(self):
+ q = SqlQuery(self._db, 'sessions', SESSION_COLUMNS)
+ result = q.select({'id': self.id})
+ return True if result.fetchone() else False
+
+ def _load(self):
+ q = SqlQuery(self._db, 'sessions', SESSION_COLUMNS)
+ result = q.select({'id': self.id})
+ r = result.fetchone()
+ if r:
+ data = str(base64.b64decode(r[1]))
+ return pickle.loads(data)
+
+ def _save(self, expiration_time):
+ q = None
+ try:
+ q = SqlQuery(self._db, 'sessions', SESSION_COLUMNS, trans=True)
+ q.delete({'id': self.id})
+ data = pickle.dumps((self._data, expiration_time), self._proto)
+ q.insert((self.id, base64.b64encode(data), expiration_time))
+ q.commit()
+ except Exception: # pylint: disable=broad-except
+ if q:
+ q.rollback()
+ raise
+
+ def _delete(self):
+ q = SqlQuery(self._db, 'sessions', SESSION_COLUMNS)
+ q.delete({'id': self.id})
+
+ # copy what RamSession does for now
+ def acquire_lock(self):
+ """Acquire an exclusive lock on the currently-loaded session data."""
+ self.locked = True
+ self.locks.setdefault(self.id, threading.RLock()).acquire()
+
+ def release_lock(self):
+ """Release the lock on the currently-loaded session data."""
+ self.locks[self.id].release()
+ self.locked = False
diff --git a/quickrun.py b/quickrun.py
index 852f8b0..0546fcc 100755
--- a/quickrun.py
+++ b/quickrun.py
@@ -77,6 +77,9 @@ def config(workdir):
'admindb': admin_db,
'usersdb': users_db,
'transdb': trans_db,
+ 'sesstype': 'file',
+ 'sessopt': 'path',
+ 'sessval': os.path.join(workdir, 'sessions'),
'secure': 'False'})
conf = os.path.join(workdir, 'ipsilon.conf')
with open(conf, 'w+') as f:
diff --git a/templates/install/ipsilon.conf b/templates/install/ipsilon.conf
index 2e402a3..4b170ca 100644
--- a/templates/install/ipsilon.conf
+++ b/templates/install/ipsilon.conf
@@ -11,8 +11,8 @@ transactions.db = "${transdb}"
tools.sessions.on = True
tools.sessions.name = "${instance}_ipsilon_session_id"
-tools.sessions.storage_type = "file"
-tools.sessions.storage_path = "${datadir}/sessions"
+tools.sessions.storage_type = "${sesstype}"
+tools.sessions.storage_${sessopt} = "${sessval}"
tools.sessions.path = "/${instance}"
tools.sessions.timeout = 60
tools.sessions.httponly = ${secure}
diff --git a/tests/helpers/common.py b/tests/helpers/common.py
index a0adfae..e316718 100755
--- a/tests/helpers/common.py
+++ b/tests/helpers/common.py
@@ -138,7 +138,7 @@ class IpsilonTestBase(object):
env=env, preexec_fn=os.setsid)
self.processes.append(p)
p.wait()
- for d in ['adminconfig', 'userprefs', 'transactions']:
+ for d in ['adminconfig', 'userprefs', 'transactions', 'sessions']:
cmd = ['/usr/bin/createdb', '-h', addr, '-p', port, d]
subprocess.check_call(cmd, env=env)
diff --git a/tests/pgdb.py b/tests/pgdb.py
index 12f1cf2..14ffd36 100755
--- a/tests/pgdb.py
+++ b/tests/pgdb.py
@@ -37,6 +37,8 @@ idp_g = {'TEMPLATES': '${TESTDIR}/templates/install',
idp_a = {'hostname': '${ADDRESS}:${PORT}',
'database_url': 'postgresql://@127.0.0.10:45432/%(dbname)s',
+ 'session_type': 'sql',
+ 'session_dburi': 'postgresql://@127.0.0.10:45432/sessions',
'admin_user': '${TEST_USER}',
'system_user': '${TEST_USER}',
'instance': '${NAME}',