diff --git a/scripts/export_signing_key b/scripts/export_signing_key
new file mode 100755
index 0000000000..8aec9d802b
--- /dev/null
+++ b/scripts/export_signing_key
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright 2019 The Matrix.org Foundation C.I.C.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import argparse
+import sys
+import time
+from typing import Optional
+
+import nacl.signing
+from signedjson.key import encode_verify_key_base64, get_verify_key, read_signing_keys
+
+
+def exit(status: int = 0, message: Optional[str] = None):
+ if message:
+ print(message, file=sys.stderr)
+ sys.exit(status)
+
+
+def format_plain(public_key: nacl.signing.VerifyKey):
+ print(
+ "%s:%s %s"
+ % (public_key.alg, public_key.version, encode_verify_key_base64(public_key),)
+ )
+
+
+def format_for_config(public_key: nacl.signing.VerifyKey, expiry_ts: int):
+ print(
+ ' "%s:%s": { key: "%s", expired_ts: %i }'
+ % (
+ public_key.alg,
+ public_key.version,
+ encode_verify_key_base64(public_key),
+ expiry_ts,
+ )
+ )
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser()
+
+ parser.add_argument(
+ "key_file", nargs="+", type=argparse.FileType("r"), help="The key file to read",
+ )
+
+ parser.add_argument(
+ "-x",
+ action="store_true",
+ dest="for_config",
+ help="format the output for inclusion in the old_signing_keys config setting",
+ )
+
+ parser.add_argument(
+ "--expiry-ts",
+ type=int,
+ default=int(time.time() * 1000) + 6*3600000,
+ help=(
+ "The expiry time to use for -x, in milliseconds since 1970. The default "
+ "is (now+6h)."
+ ),
+ )
+
+ args = parser.parse_args()
+
+ formatter = (
+ (lambda k: format_for_config(k, args.expiry_ts))
+ if args.for_config
+ else format_plain
+ )
+
+ keys = []
+ for file in args.key_file:
+ try:
+ res = read_signing_keys(file)
+ except Exception as e:
+ exit(
+ status=1,
+ message="Error reading key from file %s: %s %s"
+ % (file.name, type(e), e),
+ )
+ res = []
+ for key in res:
+ formatter(get_verify_key(key))
diff --git a/scripts/synapse_port_db b/scripts/synapse_port_db
index e393a9b2f7..eb927f2094 100755
--- a/scripts/synapse_port_db
+++ b/scripts/synapse_port_db
@@ -30,6 +30,7 @@ import yaml
from twisted.enterprise import adbapi
from twisted.internet import defer, reactor
+from synapse.config.database import DatabaseConnectionConfig
from synapse.config.homeserver import HomeServerConfig
from synapse.logging.context import PreserveLoggingContext
from synapse.storage._base import LoggingTransaction
@@ -50,12 +51,13 @@ from synapse.storage.data_stores.main.registration import (
from synapse.storage.data_stores.main.room import RoomBackgroundUpdateStore
from synapse.storage.data_stores.main.roommember import RoomMemberBackgroundUpdateStore
from synapse.storage.data_stores.main.search import SearchBackgroundUpdateStore
-from synapse.storage.data_stores.main.state import StateBackgroundUpdateStore
+from synapse.storage.data_stores.main.state import MainStateBackgroundUpdateStore
from synapse.storage.data_stores.main.stats import StatsStore
from synapse.storage.data_stores.main.user_directory import (
UserDirectoryBackgroundUpdateStore,
)
-from synapse.storage.database import Database
+from synapse.storage.data_stores.state.bg_updates import StateBackgroundUpdateStore
+from synapse.storage.database import Database, make_conn
from synapse.storage.engines import create_engine
from synapse.storage.prepare_database import prepare_database
from synapse.util import Clock
@@ -137,6 +139,7 @@ class Store(
RoomMemberBackgroundUpdateStore,
SearchBackgroundUpdateStore,
StateBackgroundUpdateStore,
+ MainStateBackgroundUpdateStore,
UserDirectoryBackgroundUpdateStore,
StatsStore,
):
@@ -165,23 +168,17 @@ class Store(
class MockHomeserver:
- def __init__(self, config, database_engine, db_conn, db_pool):
- self.database_engine = database_engine
- self.db_conn = db_conn
- self.db_pool = db_pool
+ def __init__(self, config):
self.clock = Clock(reactor)
self.config = config
self.hostname = config.server_name
- def get_db_conn(self):
- return self.db_conn
-
- def get_db_pool(self):
- return self.db_pool
-
def get_clock(self):
return self.clock
+ def get_reactor(self):
+ return reactor
+
class Porter(object):
def __init__(self, **kwargs):
@@ -445,45 +442,36 @@ class Porter(object):
else:
return
- def setup_db(self, db_config, database_engine):
- db_conn = database_engine.module.connect(
- **{
- k: v
- for k, v in db_config.get("args", {}).items()
- if not k.startswith("cp_")
- }
- )
-
- prepare_database(db_conn, database_engine, config=None)
+ def setup_db(self, db_config: DatabaseConnectionConfig, engine):
+ db_conn = make_conn(db_config, engine)
+ prepare_database(db_conn, engine, config=None)
db_conn.commit()
return db_conn
@defer.inlineCallbacks
- def build_db_store(self, config):
+ def build_db_store(self, db_config: DatabaseConnectionConfig):
"""Builds and returns a database store using the provided configuration.
Args:
- config: The database configuration, i.e. a dict following the structure of
- the "database" section of Synapse's configuration file.
+ config: The database configuration
Returns:
The built Store object.
"""
- engine = create_engine(config)
-
- self.progress.set_state("Preparing %s" % config["name"])
- conn = self.setup_db(config, engine)
+ self.progress.set_state("Preparing %s" % db_config.config["name"])
- db_pool = adbapi.ConnectionPool(config["name"], **config["args"])
+ engine = create_engine(db_config.config)
+ conn = self.setup_db(db_config, engine)
- hs = MockHomeserver(self.hs_config, engine, conn, db_pool)
+ hs = MockHomeserver(self.hs_config)
- store = Store(Database(hs), conn, hs)
+ store = Store(Database(hs, db_config, engine), conn, hs)
yield store.db.runInteraction(
- "%s_engine.check_database" % config["name"], engine.check_database,
+ "%s_engine.check_database" % db_config.config["name"],
+ engine.check_database,
)
return store
@@ -509,7 +497,9 @@ class Porter(object):
@defer.inlineCallbacks
def run(self):
try:
- self.sqlite_store = yield self.build_db_store(self.sqlite_config)
+ self.sqlite_store = yield self.build_db_store(
+ DatabaseConnectionConfig("master-sqlite", self.sqlite_config)
+ )
# Check if all background updates are done, abort if not.
updates_complete = (
@@ -524,7 +514,7 @@ class Porter(object):
defer.returnValue(None)
self.postgres_store = yield self.build_db_store(
- self.hs_config.database_config
+ self.hs_config.get_single_database()
)
yield self.run_background_updates_on_postgres()
|