summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Kreen2013-03-01 21:35:00 +0000
committerMarko Kreen2013-03-01 22:59:20 +0000
commitecc1dc6a4f9e89f469233c27a070ef0a33022b0d (patch)
tree0e7b0e46161275af32c02176405476b99a54d2fe
parent47221b5b347f92b2842d3051336974351a4638ae (diff)
create-node: validate, accept public location from config
-rw-r--r--python/londiste/playback.py4
-rw-r--r--python/pgq/cascade/admin.py81
-rwxr-xr-xtests/londiste/regen.sh11
3 files changed, 80 insertions, 16 deletions
diff --git a/python/londiste/playback.py b/python/londiste/playback.py
index 4f509dcf..4fa87014 100644
--- a/python/londiste/playback.py
+++ b/python/londiste/playback.py
@@ -277,6 +277,10 @@ class Replicator(CascadedWorker):
# target database
db = dbname=somedb host=127.0.0.1
+ # public connect string for target node, which other nodes use
+ # to access this one.
+ #public_node_location =
+
# how many tables can be copied in parallel
#parallel_copies = 1
diff --git a/python/pgq/cascade/admin.py b/python/pgq/cascade/admin.py
index ed44dad7..e7ac8605 100644
--- a/python/pgq/cascade/admin.py
+++ b/python/pgq/cascade/admin.py
@@ -29,9 +29,9 @@ command_usage = """\
%prog [options] INI CMD [subcmd args]
Node Initialization:
- create-root NAME PUBLIC_CONNSTR
- create-branch NAME PUBLIC_CONNSTR --provider=<public_connstr>
- create-leaf NAME PUBLIC_CONNSTR --provider=<public_connstr>
+ create-root NAME [PUBLIC_CONNSTR]
+ create-branch NAME [PUBLIC_CONNSTR] --provider=<public_connstr>
+ create-leaf NAME [PUBLIC_CONNSTR] --provider=<public_connstr>
Initializes node.
Node Administration:
@@ -141,24 +141,43 @@ class CascadeAdmin(skytools.AdminScript):
db = self.get_database("db")
self.install_code(db)
- def cmd_create_root(self, node_name, node_location):
- return self.create_node('root', node_name, node_location)
+ def cmd_create_root(self, node_name, *args):
+ return self.create_node('root', node_name, args)
- def cmd_create_branch(self, node_name, node_location):
- return self.create_node('branch', node_name, node_location)
+ def cmd_create_branch(self, node_name, *args):
+ return self.create_node('branch', node_name, args)
- def cmd_create_leaf(self, node_name, node_location):
- return self.create_node('leaf', node_name, node_location)
+ def cmd_create_leaf(self, node_name, *args):
+ return self.create_node('leaf', node_name, args)
- def create_node(self, node_type, node_name, node_location):
+ def create_node(self, node_type, node_name, args):
"""Generic node init."""
provider_loc = self.options.provider
if node_type not in ('root', 'branch', 'leaf'):
raise Exception('unknown node type')
+ # load public location
+ if len(args) > 1:
+ raise UsageError('Too many args, only public connect string allowed')
+ elif len(args) == 1:
+ node_location = args[0]
+ else:
+ node_location = self.cf.get('public_node_location', '')
+ if not node_location:
+ raise UsageError('Node public location must be given either in command line or config')
+
+ # check if sane
+ ok = 0
+ for k, v in skytools.parse_connect_string(node_location):
+ if k in ('host', 'service'):
+ ok = 1
+ break
+ if not ok:
+ raise UsageError('No host= in public connect string, bad idea')
+
# connect to database
- db = self.get_database("new_node", connstr = node_location)
+ db = self.get_database("db")
# check if code is installed
self.install_code(db)
@@ -170,6 +189,9 @@ class CascadeAdmin(skytools.AdminScript):
self.log.info("Node is already initialized as %s", info['node_type'])
return
+ # check if public connstr is sane
+ self.check_public_connstr(db, node_location)
+
self.log.info("Initializing node")
node_attrs = {}
@@ -257,6 +279,43 @@ class CascadeAdmin(skytools.AdminScript):
self.log.info("Done")
+ def check_public_connstr(self, db, pub_connstr):
+ """Look if public and local connect strings point to same db's.
+ """
+ pub_db = self.get_database("pub_db", connstr = pub_connstr)
+ curs1 = db.cursor()
+ curs2 = pub_db.cursor()
+ q = "select oid, datname, txid_current() as txid, txid_current_snapshot() as snap"\
+ " from pg_catalog.pg_database where datname = current_database()"
+ curs1.execute(q)
+ res1 = curs1.fetchone()
+ db.commit()
+
+ curs2.execute(q)
+ res2 = curs2.fetchone()
+ pub_db.commit()
+
+ curs1.execute(q)
+ res3 = curs1.fetchone()
+ db.commit()
+
+ self.close_database("pub_db")
+
+ failure = 0
+ if (res1['oid'], res1['datname']) != (res2['oid'], res2['datname']):
+ failure += 1
+
+ sn1 = skytools.Snapshot(res1['snap'])
+ tx = res2['txid']
+ sn2 = skytools.Snapshot(res3['snap'])
+ if sn1.contains(tx):
+ failure += 2
+ elif not sn2.contains(tx):
+ failure += 4
+
+ if failure:
+ raise UsageError("Public connect string points to different database than local connect string (fail=%d)" % failure)
+
def extra_init(self, node_type, node_db, provider_db):
"""Callback to do specific init."""
pass
diff --git a/tests/londiste/regen.sh b/tests/londiste/regen.sh
index b40ae4ec..031d29ad 100755
--- a/tests/londiste/regen.sh
+++ b/tests/londiste/regen.sh
@@ -33,6 +33,7 @@ cat > conf/londiste_$db.ini <<EOF
[londiste3]
job_name = londiste_$db
db = dbname=$db
+public_node_location = dbname=$db host=/tmp
queue_name = replika
logfile = log/%(job_name)s.log
pidfile = pid/%(job_name)s.pid
@@ -68,11 +69,11 @@ run cat conf/pgqd.ini
run cat conf/londiste_db1.ini
msg "Install londiste3 and initialize nodes"
-run londiste3 $v conf/londiste_db1.ini create-root node1 'dbname=db1'
-run londiste3 $v conf/londiste_db2.ini create-branch node2 'dbname=db2' --provider='dbname=db1'
-run londiste3 $v conf/londiste_db3.ini create-branch node3 'dbname=db3' --provider='dbname=db1'
-run londiste3 $v conf/londiste_db4.ini create-branch node4 'dbname=db4' --provider='dbname=db2' --sync-watermark=node4,node5
-run londiste3 $v conf/londiste_db5.ini create-branch node5 'dbname=db5' --provider='dbname=db3' --sync-watermark=node4,node5
+run londiste3 $v conf/londiste_db1.ini create-root node1
+run londiste3 $v conf/londiste_db2.ini create-branch node2 --provider='dbname=db1'
+run londiste3 $v conf/londiste_db3.ini create-branch node3 --provider='dbname=db1'
+run londiste3 $v conf/londiste_db4.ini create-branch node4 --provider='dbname=db2' --sync-watermark=node4,node5
+run londiste3 $v conf/londiste_db5.ini create-branch node5 --provider='dbname=db3' --sync-watermark=node4,node5
msg "Run ticker"
run pgqd $v -d conf/pgqd.ini