summaryrefslogtreecommitdiff
path: root/tools/initlog.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/initlog.py')
-rwxr-xr-xtools/initlog.py107
1 files changed, 61 insertions, 46 deletions
diff --git a/tools/initlog.py b/tools/initlog.py
index 3ef5720..9b30979 100755
--- a/tools/initlog.py
+++ b/tools/initlog.py
@@ -15,10 +15,11 @@ import errno
from time import time
from base64 import b64encode
from certtools import build_merkle_tree, write_file, generate_tree_head_signature
-from mergetools import get_sth, perm, get_logorder
+from mergetools import get_sth, perm, get_logorder, hexencode
def parse_args():
parser = argparse.ArgumentParser(description="")
+ parser.add_argument('--promote-secondary', action='store_true')
parser.add_argument('--config', help="System configuration",
required=True)
parser.add_argument('--localconfig', help="Local configuration",
@@ -30,70 +31,84 @@ def parse_args():
return (args, config, localconfig)
+# TODO: Add a `--init-secondary' option too?
+
def main():
"""
- Initialise a log by creating
- - sth file
- - must not exist before
- - consulting 'logorder' if it exists
- - perm database if it doesn't exist
+ Initialise a log, either from scratch or by promoting a secondary
+ merge node (--promote-secondary).
+
+ Refuse to do anything if there's an sth file present.
+
+ When initialising from scratch, do
+ - touch logorder
+ - write -1 to fetched
+ - write 0 to minsize
+ - create perm database if it doesn't exist
+
+ When promoting a secondary (--promote-secondary), do
+ - read logorder, let n = length of logorder
+ - write n-1 to fetched
+ - write n to minsize
+ - create perm database if it doesn't exist
"""
args, config, localconfig = parse_args()
- signingnodes = config["signingnodes"]
paths = localconfig["paths"]
own_key = (localconfig["nodename"],
"%s/%s-private.pem" % (paths["privatekeys"],
localconfig["nodename"]))
mergedb = paths["mergedb"]
- logorderfile = mergedb + "/logorder"
sthfile = mergedb + "/sth"
+ logorderfile = mergedb + "/logorder"
+ currentsizefile = mergedb + "/fetched"
+ minsizefile = mergedb + "/minsize"
+
+ # Make sure that we can find our keyfile.
+ if not file_exists(own_key[1]):
+ print >>sys.stderr, "Unable to open keyfile: %s" % own_key[1]
+ return 1
# Don't do anything if there's already an sth file.
- sth = get_sth(sthfile)
- if sth['tree_size'] >= 0:
- print >>sys.stderr, \
- "This log has an STH file with tree size %s." % sth['tree_size']
+ if file_exists(sthfile):
+ print >>sys.stderr, "This log already has an STH file: %s" % sthfile
print >>sys.stderr, "I refuse to destroy this log."
- return 1
+ return 2
- # Ensure that we can find our keyfile.
- try:
- os.stat(own_key[1])
- except OSError, e:
- if e.errno == errno.ENOENT:
- print >>sys.stderr, "Unable to open keyfile: %s" % own_key[1]
- return 1
- raise
+ # Read or touch logorder.
+ if args.promote_secondary:
+ logorder = get_logorder(logorderfile)
+ size = len(logorder)
+ last_hash = logorder[size-1]
+ else:
+ if file_exists(logorderfile):
+ print >>sys.stderr, "This log already has logorder file: %s" % logorderfile
+ print >>sys.stderr, "I refuse to destroy this log."
+ return 3
+ open(logorderfile, "a").close()
+ size = 0
+ last_hash = ''
- # Create a chains database.
- chainsdb = perm(localconfig.get("dbbackend", "filedb"), mergedb + "/chains")
+ # Write fetched.
+ currentsize = {"index": size - 1, "hash": hexencode(last_hash)}
+ write_file(currentsizefile, currentsize)
- # Create sth file.
- tree_size = 0
- root_hash = build_merkle_tree('')[-1][0]
- try:
- logorder = get_logorder(logorderfile)
- tree_size = len(logorder)
- root_hash = build_merkle_tree(logorder[:tree_size])[-1][0]
- except IOError, e:
- if e.errno == errno.ENOENT:
- pass
- timestamp = int(time() * 1000)
- tree_head_signature = \
- generate_tree_head_signature(signingnodes, own_key,
- tree_size, timestamp, root_hash)
- if tree_head_signature == None:
- return 1
+ # Write minsize.
+ minsize = {"size": size}
+ write_file(minsizefile, minsize)
- sth = {"tree_size": tree_size,
- "timestamp": timestamp,
- "sha256_root_hash": b64encode(root_hash),
- "tree_head_signature": b64encode(tree_head_signature)}
- print "Creating sth file with tree size", tree_size, \
- "and timestamp", timestamp
- write_file(sthfile, sth)
+ # Create a chains database.
+ perm(localconfig.get("dbbackend", "filedb"), mergedb + "/chains")
return 0
+def file_exists(path):
+ try:
+ os.stat(path)
+ except OSError, e:
+ if e.errno == errno.ENOENT:
+ return False
+ raise
+ return True
+
if __name__ == '__main__':
sys.exit(main())