Debug image (#131)
* config: get_settings_files_paths: Return first existing path. * tests: Set SETTINGS_FOR_DYNACONF at import time. * config: get_settings_files_paths: Log config path. * manifest.scm: Add docker-compose. * build_docker_image.sh: Allow building debug image. * storage: db: Use the same configuration for Tortoise and Aerich. * Distribuite migration queries. * storage: implement_db_changes: Use pkg_resources.
This commit is contained in:
parent
e109106af9
commit
1f1ff2e5c2
|
@ -12,4 +12,4 @@
|
||||||
'("git-cal" "man-db" "texinfo"
|
'("git-cal" "man-db" "texinfo"
|
||||||
"python-pre-commit"
|
"python-pre-commit"
|
||||||
"ripgrep" "python-semver"
|
"ripgrep" "python-semver"
|
||||||
"fd"))))
|
"fd" "docker-compose"))))
|
||||||
|
|
|
@ -20,22 +20,11 @@ async def init():
|
||||||
dictConfig(settings["logging"])
|
dictConfig(settings["logging"])
|
||||||
db_path = Path(settings.db_path)
|
db_path = Path(settings.db_path)
|
||||||
db = MoReDB(db_path)
|
db = MoReDB(db_path)
|
||||||
db_setup = asyncio.create_task(db.setup())
|
await db.setup()
|
||||||
_, _ = await asyncio.wait({db_setup}, return_when=asyncio.FIRST_EXCEPTION)
|
|
||||||
if db_setup.exception():
|
|
||||||
logging.critical("exception during db setup")
|
|
||||||
raise db_setup.exception()
|
|
||||||
|
|
||||||
|
|
||||||
async def _safe_execution(f):
|
async def _safe_execution(f):
|
||||||
init_task = asyncio.create_task(init())
|
await init()
|
||||||
_, _ = await asyncio.wait({init_task}, return_when=asyncio.FIRST_EXCEPTION)
|
|
||||||
if init_task.exception():
|
|
||||||
logging.critical("exception during init")
|
|
||||||
# raise init_task.exception()
|
|
||||||
# sys.exit(1)
|
|
||||||
loop = asyncio.get_event_loop()
|
|
||||||
loop.stop()
|
|
||||||
|
|
||||||
return_code = 1
|
return_code = 1
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import importlib.resources
|
import importlib.resources
|
||||||
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
@ -11,6 +12,8 @@ from mobilizon_reshare.config import strategies, publishers, notifiers
|
||||||
from mobilizon_reshare.config.notifiers import notifier_names
|
from mobilizon_reshare.config.notifiers import notifier_names
|
||||||
from mobilizon_reshare.config.publishers import publisher_names
|
from mobilizon_reshare.config.publishers import publisher_names
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
base_validators = [
|
base_validators = [
|
||||||
# strategy to decide events to publish
|
# strategy to decide events to publish
|
||||||
Validator("selection.strategy", must_exist=True, is_type_of=str),
|
Validator("selection.strategy", must_exist=True, is_type_of=str),
|
||||||
|
@ -39,17 +42,14 @@ def get_settings_files_paths():
|
||||||
bundled_settings_path = pkg_resources.resource_filename(
|
bundled_settings_path = pkg_resources.resource_filename(
|
||||||
"mobilizon_reshare", "settings.toml"
|
"mobilizon_reshare", "settings.toml"
|
||||||
)
|
)
|
||||||
bundled_secrets_path = pkg_resources.resource_filename(
|
for config_path in [
|
||||||
"mobilizon_reshare", ".secrets.toml"
|
|
||||||
)
|
|
||||||
return [
|
|
||||||
Path(dirs.user_config_dir, "mobilizon_reshare.toml").absolute(),
|
Path(dirs.user_config_dir, "mobilizon_reshare.toml").absolute(),
|
||||||
Path(dirs.site_config_dir, "mobilizon_reshare.toml").absolute(),
|
Path(dirs.site_config_dir, "mobilizon_reshare.toml").absolute(),
|
||||||
Path(dirs.site_config_dir, ".secrets.toml").absolute(),
|
|
||||||
Path(dirs.site_config_dir, ".secrets.toml").absolute(),
|
|
||||||
bundled_settings_path,
|
bundled_settings_path,
|
||||||
bundled_secrets_path,
|
]:
|
||||||
]
|
if config_path and Path(config_path).exists():
|
||||||
|
logger.debug(f"Loading configuration from {config_path}")
|
||||||
|
return config_path
|
||||||
|
|
||||||
|
|
||||||
def build_settings(validators: Optional[list[Validator]] = None):
|
def build_settings(validators: Optional[list[Validator]] = None):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pkg_resources
|
||||||
from tortoise import Tortoise
|
from tortoise import Tortoise
|
||||||
from aerich import Command
|
from aerich import Command
|
||||||
from mobilizon_reshare.config.publishers import publisher_names
|
from mobilizon_reshare.config.publishers import publisher_names
|
||||||
|
@ -38,6 +39,8 @@ def get_tortoise_orm():
|
||||||
"default_connection": "default",
|
"default_connection": "default",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
# always store UTC time in database
|
||||||
|
"use_tz": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,34 +57,21 @@ class MoReDB:
|
||||||
|
|
||||||
async def _implement_db_changes(self):
|
async def _implement_db_changes(self):
|
||||||
logging.info("Updating database to latest version")
|
logging.info("Updating database to latest version")
|
||||||
try:
|
migration_queries_location = pkg_resources.resource_filename(
|
||||||
|
"mobilizon_reshare", "migrations"
|
||||||
command = Command(
|
)
|
||||||
tortoise_config=get_tortoise_orm(),
|
command = Command(
|
||||||
app="models",
|
tortoise_config=TORTOISE_ORM,
|
||||||
location="./migrations",
|
app="models",
|
||||||
)
|
location=migration_queries_location,
|
||||||
await command.init()
|
)
|
||||||
await command.upgrade()
|
await command.init()
|
||||||
except FileNotFoundError:
|
await command.upgrade()
|
||||||
logging.critical("aerich configuration not found, fatal error")
|
|
||||||
await tear_down()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
async def setup(self):
|
async def setup(self):
|
||||||
await self._implement_db_changes()
|
await self._implement_db_changes()
|
||||||
await Tortoise.init(
|
await Tortoise.init(
|
||||||
db_url=get_db_url(),
|
config=TORTOISE_ORM,
|
||||||
modules={
|
|
||||||
"models": [
|
|
||||||
"mobilizon_reshare.models.event",
|
|
||||||
"mobilizon_reshare.models.notification",
|
|
||||||
"mobilizon_reshare.models.publication",
|
|
||||||
"mobilizon_reshare.models.publisher",
|
|
||||||
]
|
|
||||||
},
|
|
||||||
# always store UTC time in database
|
|
||||||
use_tz=True,
|
|
||||||
)
|
)
|
||||||
if not self.is_init:
|
if not self.is_init:
|
||||||
await Tortoise.generate_schemas()
|
await Tortoise.generate_schemas()
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
|
if [ "$#" -ge 1 ] && [ "$1" = "-d" ]; then
|
||||||
|
conf_path="docker/image-debug.scm"
|
||||||
|
else
|
||||||
|
conf_path="docker/image.scm"
|
||||||
|
fi
|
||||||
|
|
||||||
guix time-machine -C channels-lock.scm -- build -L . -f guix.scm
|
guix time-machine -C channels-lock.scm -- build -L . -f guix.scm
|
||||||
|
|
||||||
guix time-machine -C channels-lock.scm -- system image -t docker -L . --root=docker-image.tar.gz docker/image.scm
|
guix time-machine -C channels-lock.scm -- system image -t docker -L . --root=docker-image.tar.gz "$conf_path"
|
||||||
|
|
|
@ -25,6 +25,11 @@ from mobilizon_reshare.publishers.exceptions import PublisherError, InvalidRespo
|
||||||
from mobilizon_reshare.storage.query.write import get_publisher_by_name
|
from mobilizon_reshare.storage.query.write import get_publisher_by_name
|
||||||
from tests import today
|
from tests import today
|
||||||
|
|
||||||
|
with importlib.resources.path(
|
||||||
|
mobilizon_reshare, ".secrets.toml"
|
||||||
|
) as bundled_secrets_path:
|
||||||
|
os.environ["SECRETS_FOR_DYNACONF"] = str(bundled_secrets_path)
|
||||||
|
|
||||||
|
|
||||||
def generate_publication_status(published):
|
def generate_publication_status(published):
|
||||||
return PublicationStatus.COMPLETED if published else PublicationStatus.WAITING
|
return PublicationStatus.COMPLETED if published else PublicationStatus.WAITING
|
||||||
|
@ -124,15 +129,8 @@ def initialize_db_tests() -> None:
|
||||||
db_url=db_url,
|
db_url=db_url,
|
||||||
app_label="models",
|
app_label="models",
|
||||||
)
|
)
|
||||||
with importlib.resources.path(
|
yield None
|
||||||
mobilizon_reshare, ".secrets.toml"
|
finalizer()
|
||||||
) as bundled_secrets_path:
|
|
||||||
os.environ["SECRETS_FOR_DYNACONF"] = str(bundled_secrets_path)
|
|
||||||
|
|
||||||
yield None
|
|
||||||
|
|
||||||
os.environ["SECRETS_FOR_DYNACONF"] = ""
|
|
||||||
finalizer()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
|
@ -164,7 +162,9 @@ def event_model_generator():
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def publisher_model_generator():
|
def publisher_model_generator():
|
||||||
def _publisher_model_generator(idx=1,):
|
def _publisher_model_generator(
|
||||||
|
idx=1,
|
||||||
|
):
|
||||||
return Publisher(name=f"publisher_{idx}", account_ref=f"account_ref_{idx}")
|
return Publisher(name=f"publisher_{idx}", account_ref=f"account_ref_{idx}")
|
||||||
|
|
||||||
return _publisher_model_generator
|
return _publisher_model_generator
|
||||||
|
@ -304,7 +304,10 @@ def mock_mobilizon_success_answer(mobilizon_answer, mobilizon_url):
|
||||||
with responses.RequestsMock() as rsps:
|
with responses.RequestsMock() as rsps:
|
||||||
|
|
||||||
rsps.add(
|
rsps.add(
|
||||||
responses.POST, mobilizon_url, json=mobilizon_answer, status=200,
|
responses.POST,
|
||||||
|
mobilizon_url,
|
||||||
|
json=mobilizon_answer,
|
||||||
|
status=200,
|
||||||
)
|
)
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue