Commit 37943a26 authored by Julien Muchembled's avatar Julien Muchembled

Remove type specifier on config.value column

For the registry at least, we'll want to store integers
without having to convert to/from strings.

To upgrade 'registry.db':
- dump it to a file
- fix create table statements
- load it

Nodes will restart with an empty cache.
parent 648e6774
import logging, sqlite3, socket, subprocess, time
import logging, os, sqlite3, socket, subprocess, time
from re6st.registry import RegistryClient
from . import utils
class PeerDB(object):
......@@ -11,20 +12,16 @@ class PeerDB(object):
self._registry = RegistryClient(registry, cert)
logging.info('Initialize cache ...')
self._db = sqlite3.connect(db_path, isolation_level=None)
self._db.text_factory = str
try:
self._db = self._open(db_path)
except sqlite3.OperationalError:
logging.exception("Start with empty cache")
os.rename(db_path, db_path + '.bak')
self._db = self._open(db_path)
q = self._db.execute
q("PRAGMA synchronous = OFF")
q("PRAGMA journal_mode = MEMORY")
q("""CREATE TABLE IF NOT EXISTS peer (
prefix TEXT PRIMARY KEY,
address TEXT NOT NULL)""")
q("""CREATE TABLE IF NOT EXISTS config (
name text primary key,
value text)""")
q('ATTACH DATABASE ":memory:" AS volatile')
q("""CREATE TABLE volatile.stat (
peer TEXT PRIMARY KEY,
peer TEXT PRIMARY KEY NOT NULL,
try INTEGER NOT NULL DEFAULT 0)""")
q("CREATE INDEX volatile.stat_try ON stat(try)")
q("INSERT INTO volatile.stat (peer) SELECT prefix FROM peer")
......@@ -49,6 +46,19 @@ class PeerDB(object):
logging.info("Cache initialized. Prefix of registry node is %s/%u",
int(a, 2), len(a))
def _open(self, path):
db = sqlite3.connect(path, isolation_level=None)
db.text_factory = str
db.execute("PRAGMA synchronous = OFF")
db.execute("PRAGMA journal_mode = MEMORY")
utils.sqliteCreateTable(db, "peer",
"prefix TEXT PRIMARY KEY NOT NULL",
"address TEXT NOT NULL")
utils.sqliteCreateTable(db, "config",
"name TEXT PRIMARY KEY NOT NULL",
"value")
return db
def log(self):
if logging.getLogger().isEnabledFor(5):
logging.trace("Cache:")
......
......@@ -55,28 +55,19 @@ class RegistryServer(object):
utils.makedirs(os.path.dirname(self.config.db))
self.db = sqlite3.connect(self.config.db, isolation_level=None,
check_same_thread=False)
self.db.execute("""CREATE TABLE IF NOT EXISTS config (
name text primary key,
value text)""")
try:
(self.prefix,), = self.db.execute(
"SELECT value FROM config WHERE name='prefix'")
except ValueError:
self.prefix = None
self.db.execute("""CREATE TABLE IF NOT EXISTS token (
token text primary key not null,
email text not null,
prefix_len integer not null,
date integer not null)""")
try:
self.db.execute("""CREATE TABLE cert (
prefix text primary key not null,
email text,
cert text)""")
except sqlite3.OperationalError, e:
if e.args[0] != 'table cert already exists':
raise RuntimeError
else:
utils.sqliteCreateTable(self.db, "config",
"name TEXT PRIMARY KEY NOT NULL",
"value")
self.prefix = self.getConfig("prefix", None)
utils.sqliteCreateTable(self.db, "token",
"token TEXT PRIMARY KEY NOT NULL",
"email TEXT NOT NULL",
"prefix_len INTEGER NOT NULL",
"date INTEGER NOT NULL")
if utils.sqliteCreateTable(self.db, "cert",
"prefix TEXT PRIMARY KEY NOT NULL",
"email TEXT",
"cert TEXT"):
self.db.execute("INSERT INTO cert VALUES ('',null,null)")
self.cert = x509.Cert(self.config.ca, self.config.key)
......@@ -92,6 +83,15 @@ class RegistryServer(object):
self.onTimeout()
def getConfig(self, name, *default):
r, = next(self.db.execute(
"SELECT value FROM config WHERE name=?", (name,)), default)
return r
def setConfig(self, *name_value):
self.db.execute("INSERT OR REPLACE INTO config VALUES (?, ?)",
name_value)
def sendto(self, prefix, code):
self.sock.sendto("%s\0%c" % (prefix, code), ('::1', tunnel.PORT))
......@@ -302,8 +302,7 @@ class RegistryServer(object):
(email, prefix))
if self.prefix is None:
self.prefix = prefix
self.db.execute(
"INSERT INTO config VALUES ('prefix',?)", (prefix,))
self.setConfig('prefix', prefix)
return self.createCertificate(prefix, req.get_subject(),
req.get_pubkey())
......
import argparse, errno, hashlib, logging, os, select as _select, shlex, signal
import socket, struct, subprocess, sys, textwrap, threading, time, traceback
import argparse, errno, hashlib, logging, os, select as _select
import shlex, signal, socket, sqlite3, struct, subprocess
import sys, textwrap, threading, time, traceback
HMAC_LEN = len(hashlib.sha1('').digest())
......@@ -236,3 +237,15 @@ def newHmacSecret():
assert len(pack(0,0,0)) == HMAC_LEN
return lambda x=None: pack(g(64) if x is None else x, g(64), g(32))
newHmacSecret = newHmacSecret()
def sqliteCreateTable(db, name, *columns):
sql = "CREATE TABLE %s (%s)" % (name, ','.join('\n ' + x for x in columns))
for x, in db.execute(
"SELECT sql FROM sqlite_master WHERE type='table' and name=?""",
(name,)):
if x == sql:
return
raise sqlite3.OperationalError(
"table %r already exists with unexpected schema" % name)
db.execute(sql)
return True
#!/usr/bin/python
import atexit, errno, logging, os, signal, socket
import sqlite3, subprocess, sys, time, threading
import subprocess, sys, time, threading
from collections import deque
from re6st import ctl, db, plib, tunnel, utils, version, x509
from re6st.utils import exit, ReexecException
......@@ -393,9 +393,6 @@ def main():
except:
pass
exit.release()
except sqlite3.Error:
logging.exception("Restarting with empty cache")
os.rename(db_path, db_path + '.bak')
except ReexecException, e:
logging.info(e)
except Exception:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment