update_database 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Copyright 2019 The Matrix.org Foundation C.I.C.
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. import argparse
  17. import logging
  18. import sys
  19. import yaml
  20. from twisted.internet import defer, reactor
  21. from synapse.config.homeserver import HomeServerConfig
  22. from synapse.metrics.background_process_metrics import run_as_background_process
  23. from synapse.server import HomeServer
  24. from synapse.storage import DataStore
  25. logger = logging.getLogger("update_database")
  26. class MockHomeserver(HomeServer):
  27. DATASTORE_CLASS = DataStore
  28. def __init__(self, config, **kwargs):
  29. super(MockHomeserver, self).__init__(
  30. config.server_name, reactor=reactor, config=config, **kwargs
  31. )
  32. if __name__ == "__main__":
  33. parser = argparse.ArgumentParser(
  34. description=(
  35. "Updates a synapse database to the latest schema and runs background updates"
  36. " on it."
  37. )
  38. )
  39. parser.add_argument("-v", action="store_true")
  40. parser.add_argument(
  41. "--database-config",
  42. type=argparse.FileType("r"),
  43. required=True,
  44. help="A database config file for either a SQLite3 database or a PostgreSQL one.",
  45. )
  46. args = parser.parse_args()
  47. logging_config = {
  48. "level": logging.DEBUG if args.v else logging.INFO,
  49. "format": "%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(message)s",
  50. }
  51. logging.basicConfig(**logging_config)
  52. # Load, process and sanity-check the config.
  53. hs_config = yaml.safe_load(args.database_config)
  54. if "database" not in hs_config:
  55. sys.stderr.write("The configuration file must have a 'database' section.\n")
  56. sys.exit(4)
  57. config = HomeServerConfig()
  58. config.parse_config_dict(hs_config, "", "")
  59. # Instantiate and initialise the homeserver object.
  60. hs = MockHomeserver(config)
  61. # Setup instantiates the store within the homeserver object and updates the
  62. # DB.
  63. hs.setup()
  64. store = hs.get_datastore()
  65. @defer.inlineCallbacks
  66. def run_background_updates():
  67. yield store.db.updates.run_background_updates(sleep=False)
  68. # Stop the reactor to exit the script once every background update is run.
  69. reactor.stop()
  70. # Apply all background updates on the database.
  71. reactor.callWhenRunning(
  72. lambda: run_as_background_process("background_updates", run_background_updates)
  73. )
  74. reactor.run()