Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Generate missing configuration files at startup #13615

Merged
merged 3 commits into from
Aug 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/13615.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Change the default startup behaviour so that any missing "additional" configuration files (signing key, etc) are generated automatically.
8 changes: 7 additions & 1 deletion docs/usage/configuration/config_documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2139,6 +2139,9 @@ allows the shared secret to be specified in an external file.

The file should be a plain text file, containing only the shared secret.

If this file does not exist, Synapse will create a new signing
key on startup and store it in this file.

Example configuration:
```yaml
registration_shared_secret_file: /path/to/secrets/file
Expand Down Expand Up @@ -2555,7 +2558,10 @@ Config options relating to signing keys
---
### `signing_key_path`

Path to the signing key to sign messages with.
Path to the signing key to sign events and federation requests with.

*New in Synapse 1.67*: If this file does not exist, Synapse will create a new signing
key on startup and store it in this file.

Example configuration:
```yaml
Expand Down
59 changes: 48 additions & 11 deletions synapse/config/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import os
import re
from collections import OrderedDict
from enum import Enum, auto
from hashlib import sha256
from textwrap import dedent
from typing import (
Expand Down Expand Up @@ -603,18 +604,44 @@ def load_or_generate_config(
" may specify directories containing *.yaml files.",
)

generate_group = parser.add_argument_group("Config generation")
generate_group.add_argument(
# we nest the mutually-exclusive group inside another group so that the help
# text shows them in their own group.
generate_mode_group = parser.add_argument_group(
"Config generation mode",
)
generate_mode_exclusive = generate_mode_group.add_mutually_exclusive_group()
generate_mode_exclusive.add_argument(
# hidden option to make the type and default work
"--generate-mode",
help=argparse.SUPPRESS,
type=_ConfigGenerateMode,
default=_ConfigGenerateMode.GENERATE_MISSING_AND_RUN,
)
generate_mode_exclusive.add_argument(
"--generate-config",
action="store_true",
help="Generate a config file, then exit.",
action="store_const",
const=_ConfigGenerateMode.GENERATE_EVERYTHING_AND_EXIT,
dest="generate_mode",
)
generate_group.add_argument(
generate_mode_exclusive.add_argument(
"--generate-missing-configs",
"--generate-keys",
action="store_true",
help="Generate any missing additional config files, then exit.",
action="store_const",
const=_ConfigGenerateMode.GENERATE_MISSING_AND_EXIT,
dest="generate_mode",
)
generate_mode_exclusive.add_argument(
"--generate-missing-and-run",
help="Generate any missing additional config files, then run. This is the "
"default behaviour.",
action="store_const",
const=_ConfigGenerateMode.GENERATE_MISSING_AND_RUN,
dest="generate_mode",
)

generate_group = parser.add_argument_group("Details for --generate-config")
generate_group.add_argument(
"-H", "--server-name", help="The server name to generate a config file for."
)
Expand Down Expand Up @@ -670,11 +697,12 @@ def load_or_generate_config(
config_dir_path = os.path.abspath(config_dir_path)
data_dir_path = os.getcwd()

generate_missing_configs = config_args.generate_missing_configs

obj = cls(config_files)

if config_args.generate_config:
if (
config_args.generate_mode
== _ConfigGenerateMode.GENERATE_EVERYTHING_AND_EXIT
):
if config_args.report_stats is None:
parser.error(
"Please specify either --report-stats=yes or --report-stats=no\n\n"
Expand Down Expand Up @@ -732,11 +760,14 @@ def load_or_generate_config(
)
% (config_path,)
)
generate_missing_configs = True

config_dict = read_config_files(config_files)
if generate_missing_configs:
obj.generate_missing_files(config_dict, config_dir_path)
obj.generate_missing_files(config_dict, config_dir_path)

if config_args.generate_mode in (
_ConfigGenerateMode.GENERATE_EVERYTHING_AND_EXIT,
_ConfigGenerateMode.GENERATE_MISSING_AND_EXIT,
):
return None

obj.parse_config_dict(
Expand Down Expand Up @@ -965,6 +996,12 @@ def read_file(file_path: Any, config_path: Iterable[str]) -> str:
raise ConfigError("Error accessing file %r" % (file_path,), config_path) from e


class _ConfigGenerateMode(Enum):
GENERATE_MISSING_AND_RUN = auto()
GENERATE_MISSING_AND_EXIT = auto()
GENERATE_EVERYTHING_AND_EXIT = auto()


__all__ = [
"Config",
"RootConfig",
Expand Down