aboutsummaryrefslogtreecommitdiff
path: root/potpourri/ca-pickle.py
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2016-04-27 22:20:19 +0000
committerRob Austein <sra@hactrn.net>2016-04-27 22:20:19 +0000
commit319916e90e1b1f6328effbc7cd9acf74c38c1842 (patch)
tree4914806f2603e40640b536f1d86dfb3e5b561a1b /potpourri/ca-pickle.py
parent3503ee53e0ef4092a393a606c18a6b6b3e17e3a9 (diff)
First step of transition mechanism from trunk/ to tk705/: script to
encapsulate all (well, we hope) relevant configuration and state from a trunk/ CA in a form we can easily load on another machine, or on the same machine after a software upgrade, or .... Transfer format is an ad hoc Python dictionary, encoded in Python's native "Pickle" format, compressed by "xz" with SHA-256 integrity checking enabled. See #807. svn path=/trunk/; revision=6395
Diffstat (limited to 'potpourri/ca-pickle.py')
-rwxr-xr-xpotpourri/ca-pickle.py95
1 files changed, 95 insertions, 0 deletions
diff --git a/potpourri/ca-pickle.py b/potpourri/ca-pickle.py
new file mode 100755
index 00000000..92741853
--- /dev/null
+++ b/potpourri/ca-pickle.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+
+# $Id$
+
+"""
+Package up state of an old (pre-rpkidb, pre-pubdb, pre-Django 1.8)
+RPKI CA installation as a Python pickle database, for later re-loading
+into a more recent version of the code using a companion script.
+"""
+
+import os
+import sys
+import cPickle
+import argparse
+import subprocess
+import rpki.config
+import rpki.version
+import rpki.autoconf
+
+from rpki.mysql_import import MySQLdb, _mysql_exceptions
+
+parser = argparse.ArgumentParser(description = __doc__)
+parser.add_argument("-c", "--config",
+ help = "specify alternate location for rpki.conf")
+parser.add_argument("-p", "--protocol",
+ choices = (0, 1, 2), type = int, default = 2,
+ help = "pickling protocol to use")
+parser.add_argument("output",
+ help = "output file")
+args = parser.parse_args()
+
+cfg = rpki.config.parser(args.config)
+
+databases = {}
+
+for section in ("rpkid", "irdbd", "pubd"):
+ db = MySQLdb.connect(db = cfg.get(section = section, option = "sql-database"),
+ user = cfg.get(section = section, option = "sql-username"),
+ passwd = cfg.get(section = section, option = "sql-password"))
+ tables = {}
+
+ cur = db.cursor()
+ cur.execute("SHOW TABLES")
+ table_names = tuple(row[0] for row in cur.fetchall())
+ cur.close()
+
+ cur = db.cursor(MySQLdb.cursors.DictCursor)
+ for name in table_names:
+ cur.execute("SELECT * FROM " + name)
+ tables[name] = cur.fetchall()
+ cur.close()
+
+ db.close()
+
+ databases[section] = tables
+
+filenames = [cfg.filename]
+raw_config = {}
+cooked_config = {}
+
+for section in cfg.cfg.sections():
+ for option in cfg.cfg.options(section):
+ raw_config[section, option] = cfg.cfg.get(section = section, option = option)
+ cooked_config[section, option] = cfg.get(section = section, option = option)
+ if os.path.isfile(cooked_config[section, option]):
+ filenames.append(cooked_config[section, option])
+
+for i, fn in enumerate(filenames):
+ filenames[i] = os.path.abspath(fn)
+
+files = {}
+
+for filename in filenames:
+ with open(filename, "rb") as f:
+ files[filename] = f.read()
+
+world = dict(
+ version = rpki.version.VERSION,
+ rpki_conf = filenames[0],
+ databases = databases,
+ files = files,
+ raw_config = raw_config,
+ cooked_config = cooked_config)
+
+xz = subprocess.Popen(
+ ("xz", "-C", "sha256"),
+ stdin = subprocess.PIPE,
+ stdout = os.open(args.output, os.O_WRONLY | os.O_CREAT, 0600))
+
+cPickle.dump(world, xz.stdin, args.protocol)
+
+xz.stdin.close()
+
+if xz.wait() != 0:
+ sys.exit("XZ pickling failed with code {}".format(xz.returncode))