Skip to content

Commit d6849ff

Browse files
prandlaveluca93
authored andcommitted
Use toml for configuration
1 parent f0a69e9 commit d6849ff

24 files changed

+291
-292
lines changed

Dockerfile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ RUN sudo pip3 install --break-system-packages .
4949

5050
RUN sudo python3 prerequisites.py --yes --cmsuser=cmsuser install
5151

52-
RUN sed 's|/cmsuser:your_password_here@localhost:5432/cmsdb"|/postgres@testdb:5432/cmsdbfortesting"|' ./config/cms.conf.sample \
53-
| sudo tee /usr/local/etc/cms-testdb.conf
54-
RUN sed -e 's|/cmsuser:your_password_here@localhost:5432/cmsdb"|/postgres@devdb:5432/cmsdb"|' -e 's/127.0.0.1/0.0.0.0/' ./config/cms.conf.sample \
55-
| sudo tee /usr/local/etc/cms-devdb.conf
56-
RUN sed 's/127.0.0.1/0.0.0.0/' ./config/cms.ranking.conf.sample | sudo tee /usr/local/etc/cms.ranking.conf
52+
RUN sed 's|/cmsuser:your_password_here@localhost:5432/cmsdb"|/postgres@testdb:5432/cmsdbfortesting"|' ./config/cms.sample.toml \
53+
| sudo tee /usr/local/etc/cms-testdb.toml
54+
RUN sed -e 's|/cmsuser:your_password_here@localhost:5432/cmsdb"|/postgres@devdb:5432/cmsdb"|' -e 's/127.0.0.1/0.0.0.0/' ./config/cms.sample.toml \
55+
| sudo tee /usr/local/etc/cms-devdb.toml
56+
RUN sed 's/127.0.0.1/0.0.0.0/' ./config/cms_ranking.sample.toml | sudo tee /usr/local/etc/cms_ranking.toml
5757

5858
ENV LANG C.UTF-8
5959

cms/conf.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2323

2424
import errno
25-
import json
25+
import tomllib
2626
import logging
2727
import os
2828
import sys
@@ -81,7 +81,7 @@ class AsyncConfig:
8181
class Config:
8282
"""This class will contain the configuration for CMS. This needs
8383
to be populated at the initilization stage. This is loaded by
84-
default with some sane data. See cms.conf.sample in the config
84+
default with some sane data. See cms.sample.toml in the config
8585
directory for information on the meaning of the fields.
8686
8787
"""
@@ -166,13 +166,21 @@ def __init__(self):
166166
self.max_jobs_per_user = 10
167167
self.pdf_printing_allowed = False
168168

169+
# PrometheusExporter
170+
self.prometheus_listen_address = "127.0.0.1"
171+
self.prometheus_listen_port = 8811
172+
173+
# TelegramBot
174+
self.telegram_bot_token = None
175+
self.telegram_bot_chat_id = None
176+
169177
self.log_dir = os.path.join("/", "var", "local", "log", "cms")
170178
self.cache_dir = os.path.join("/", "var", "local", "cache", "cms")
171179
self.data_dir = os.path.join("/", "var", "local", "lib", "cms")
172180
self.run_dir = os.path.join("/", "var", "local", "run", "cms")
173181
paths = [
174-
os.path.join("/", "usr", "local", "etc", "cms.conf"),
175-
os.path.join("/", "etc", "cms.conf"),
182+
os.path.join("/", "usr", "local", "etc", "cms.toml"),
183+
os.path.join("/", "etc", "cms.toml"),
176184
]
177185

178186
# Allow user to override config file path using environment
@@ -202,23 +210,21 @@ def _load(self, paths: list[str]):
202210

203211
def _load_unique(self, path: str):
204212
"""Populate the Config class with everything that sits inside
205-
the JSON file path (usually something like /etc/cms.conf). The
213+
the TOML file path (usually something like /etc/cms.toml). The
206214
only pieces of data treated differently are the elements of
207215
core_services and other_services that are sent to async
208216
config.
209217
210-
Services whose name begins with an underscore are ignored, so
211-
they can be commented out in the configuration file.
212-
213-
path: the path of the JSON config file.
218+
path: the path of the TOML config file.
214219
215220
"""
216221
# Load config file.
217222
try:
218-
with open(path, 'rt', encoding='utf-8') as f:
219-
data = json.load(f)
223+
with open(path, 'rb') as f:
224+
data = tomllib.load(f)
220225
except FileNotFoundError:
221-
logger.debug("Couldn't find config file %s.", path)
226+
logger.debug("Couldn't find config file %s (maybe you need to "
227+
"convert it from cms.conf to cms.toml?).", path)
222228
return False
223229
except OSError as error:
224230
logger.warning("I/O error while opening file %s: [%s] %s",
@@ -257,6 +263,8 @@ def _load_unique(self, path: str):
257263

258264
# Put everything else in self.
259265
for key, value in data.items():
266+
if not hasattr(self, key):
267+
logger.warning("Unrecognized key %s in config!", key)
260268
setattr(self, key, value)
261269

262270
return True

cms/db/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def test_db_connection():
7474
except OperationalError as e:
7575
logger.error(e)
7676
raise ConfigError("Operational error while talking to the DB. "
77-
"Is the connection string in cms.conf correct?")
77+
"Is the connection string in cms.toml correct?")
7878

7979

8080
def get_contest_list(session: "Session | None" = None) -> list[Contest]:

cms/io/service.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def __init__(self, shard: int = 0):
9797
address = get_service_address(self._my_coord)
9898
except KeyError:
9999
raise ConfigError("Unable to find address for service %r. "
100-
"Is it specified in core_services in cms.conf?" %
100+
"Is it specified in core_services in cms.toml?" %
101101
(self._my_coord,))
102102

103103
self.rpc_server = StreamServer(address, self._connection_handler)
@@ -197,7 +197,7 @@ def connect_to(
197197
# the service was optional.
198198
if must_be_present:
199199
raise ConfigError("Missing address and port for %s "
200-
"in cms.conf." % (coord, ))
200+
"in cms.toml." % (coord, ))
201201
else:
202202
service = FakeRemoteServiceClient(coord, None)
203203
service.connect()

cms/server/admin/templates/base.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ <h1 class="child">{{ contest.name }}</h1>
8585
</div>
8686
{% if config.secret_key == config.secret_key_default %}
8787
<div class="secret_notice">
88-
Change secret_key in cms.conf!<br/>
88+
Change secret_key in cms.toml!<br/>
8989
For example,<br/>
9090
{{ get_hex_random_key() }}
9191
</div>

cms/server/contest/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def __init__(self, shard: int, contest_id: int | None = None):
8080
raise ConfigError("Wrong shard number for %s, or missing "
8181
"address/port configuration. Please check "
8282
"contest_listen_address and contest_listen_port "
83-
"in cms.conf." % __name__)
83+
"in cms.toml." % __name__)
8484

8585
self.contest_id = contest_id
8686

cmsranking/Config.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1818

1919
import errno
20-
import json
2120
import logging
2221
import os
2322
import sys
23+
import tomllib
2424
import typing
2525

2626
import pkg_resources
@@ -63,8 +63,8 @@ def __init__(self):
6363
self.log_dir = os.path.join("/", "var", "local", "log", "cms", "ranking")
6464
self.lib_dir = os.path.join("/", "var", "local", "lib", "cms", "ranking")
6565
self.conf_paths = [
66-
os.path.join("/", "usr", "local", "etc", "cms.ranking.conf"),
67-
os.path.join("/", "etc", "cms.ranking.conf"),
66+
os.path.join("/", "usr", "local", "etc", "cms_ranking.toml"),
67+
os.path.join("/", "etc", "cms_ranking.toml"),
6868
]
6969

7070
# Allow users to override config file path using environment
@@ -121,7 +121,7 @@ def _load_many(self, conf_paths: list[str]) -> bool:
121121
"""
122122
for conf_path in conf_paths:
123123
try:
124-
with open(conf_path, "rt", encoding="utf-8") as conf_fobj:
124+
with open(conf_path, "rb") as conf_fobj:
125125
logger.info("Using config file %s.", conf_path)
126126
return self._load_one(conf_fobj)
127127
except FileNotFoundError:
@@ -135,10 +135,10 @@ def _load_many(self, conf_paths: list[str]) -> bool:
135135
logger.warning("No config file found, using hardcoded defaults.")
136136
return True
137137

138-
def _load_one(self, conf_fobj: typing.TextIO) -> bool:
138+
def _load_one(self, conf_fobj: typing.BinaryIO) -> bool:
139139
"""Populate config parameters from the given file.
140140
141-
Parse it as JSON and store in self all configuration properties
141+
Parse it as TOML and store in self all configuration properties
142142
it defines. Log critical message and return False if anything
143143
goes wrong or seems odd.
144144
@@ -148,19 +148,16 @@ def _load_one(self, conf_fobj: typing.TextIO) -> bool:
148148
"""
149149
# Parse config file.
150150
try:
151-
data = json.load(conf_fobj)
151+
data = tomllib.load(conf_fobj)
152152
except ValueError:
153-
logger.critical("Config file is invalid JSON.")
153+
logger.critical("Config file is invalid TOML.")
154154
return False
155155

156156
# Store every config property.
157157
for key, value in data.items():
158-
if key.startswith("_"):
159-
continue
160158
if not hasattr(self, key):
161159
logger.critical("Invalid field %s in config file, maybe a "
162-
"typo? (use leading underscore to ignore).",
163-
key)
160+
"typo?", key)
164161
return False
165162
setattr(self, key, value)
166163
return True

cmsranking/RankingWebServer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ def main() -> int:
526526
"""
527527
parser = argparse.ArgumentParser(
528528
description="Ranking for CMS.")
529-
parser.add_argument("--config", type=argparse.FileType("rt"),
529+
parser.add_argument("--config", type=argparse.FileType("rb"),
530530
help="override config file")
531531
parser.add_argument("-d", "--drop", action="store_true",
532532
help="drop the data already stored")

cmstestsuite/functionaltestframework.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import re
2828
import sys
2929
import time
30+
import tomllib
3031

3132
from cmstestsuite import CONFIG, TestException, sh
3233
from cmstestsuite.web import Browser
@@ -73,7 +74,7 @@ def __new__(cls):
7374
return FunctionalTestFramework.__instance
7475

7576
def __init__(self):
76-
# This holds the decoded-JSON of the cms.conf configuration file.
77+
# This holds the decoded-TOML of the cms.toml configuration file.
7778
# Lazily loaded, to be accessed through the getter method.
7879
self._cms_config = None
7980

@@ -141,8 +142,8 @@ def initialize_aws(self) -> str:
141142

142143
def get_cms_config(self):
143144
if self._cms_config is None:
144-
with open("%(CONFIG_PATH)s" % CONFIG, "rt", encoding="utf-8") as f:
145-
self._cms_config = json.load(f)
145+
with open("%(CONFIG_PATH)s" % CONFIG, "rb") as f:
146+
self._cms_config = tomllib.load(f)
146147
return self._cms_config
147148

148149
def admin_req(self, path, args=None, files=None):

cmstestsuite/testrunner.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,10 @@ def load_cms_conf(self):
9494
except subprocess.CalledProcessError:
9595
git_root = None
9696
CONFIG["TEST_DIR"] = git_root
97-
CONFIG["CONFIG_PATH"] = "%s/config/cms.conf" % CONFIG["TEST_DIR"]
97+
# TODO: this probably doesn't work: config/cms.toml doesn't even exist
98+
CONFIG["CONFIG_PATH"] = "%s/config/cms.toml" % CONFIG["TEST_DIR"]
9899
if CONFIG["TEST_DIR"] is None:
99-
CONFIG["CONFIG_PATH"] = "/usr/local/etc/cms.conf"
100+
CONFIG["CONFIG_PATH"] = "/usr/local/etc/cms.toml"
100101

101102
# Override CMS config path when environment variable is present
102103
CMS_CONFIG_ENV_VAR = "CMS_CONFIG"

0 commit comments

Comments
 (0)