mirror of
https://git.pleroma.social/pleroma/relay.git
synced 2024-11-23 06:57:59 +00:00
Compare commits
4 commits
0d24aea764
...
f192f1c35c
Author | SHA1 | Date | |
---|---|---|---|
f192f1c35c | |||
85f062c8f3 | |||
098998084d | |||
5a9d1836d0 |
|
@ -16,7 +16,8 @@ Run the relay.
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
Run the setup wizard to configure your relay.
|
Run the setup wizard to configure your relay. For the PostgreSQL backend, the database has to be
|
||||||
|
created first.
|
||||||
|
|
||||||
activityrelay setup
|
activityrelay setup
|
||||||
|
|
||||||
|
@ -29,6 +30,16 @@ not specified, the config will get backed up as `relay.backup.yaml` before conve
|
||||||
activityrelay convert --old-config relaycfg.yaml
|
activityrelay convert --old-config relaycfg.yaml
|
||||||
|
|
||||||
|
|
||||||
|
## Switch Backend
|
||||||
|
|
||||||
|
Change the database backend from the current one to the other. The config will be updated after
|
||||||
|
running the command.
|
||||||
|
|
||||||
|
Note: If switching to PostgreSQL, make sure the database exists first.
|
||||||
|
|
||||||
|
activityrelay switch-backend
|
||||||
|
|
||||||
|
|
||||||
## Edit Config
|
## Edit Config
|
||||||
|
|
||||||
Open the config file in a text editor. If an editor is not specified with `--editor`, the default
|
Open the config file in a text editor. If an editor is not specified with `--editor`, the default
|
||||||
|
|
|
@ -4,7 +4,7 @@ import secrets
|
||||||
|
|
||||||
from argon2 import PasswordHasher
|
from argon2 import PasswordHasher
|
||||||
from blib import Date, convert_to_boolean
|
from blib import Date, convert_to_boolean
|
||||||
from bsql import Connection as SqlConnection, Row, Update
|
from bsql import BackendType, Connection as SqlConnection, Row, Update
|
||||||
from collections.abc import Iterator
|
from collections.abc import Iterator
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
@ -51,6 +51,17 @@ class Connection(SqlConnection):
|
||||||
yield instance
|
yield instance
|
||||||
|
|
||||||
|
|
||||||
|
def drop_tables(self) -> None:
|
||||||
|
with self.cursor() as cur:
|
||||||
|
for table in self.get_tables():
|
||||||
|
query = f"DROP TABLE IF EXISTS {table}"
|
||||||
|
|
||||||
|
if self.database.backend.backend_type == BackendType.POSTGRESQL:
|
||||||
|
query += " CASCADE"
|
||||||
|
|
||||||
|
cur.execute(query)
|
||||||
|
|
||||||
|
|
||||||
def fix_timestamps(self) -> None:
|
def fix_timestamps(self) -> None:
|
||||||
for app in self.select('apps').all(schema.App):
|
for app in self.select('apps').all(schema.App):
|
||||||
data = {'created': app.created.timestamp(), 'accessed': app.accessed.timestamp()}
|
data = {'created': app.created.timestamp(), 'accessed': app.accessed.timestamp()}
|
||||||
|
|
|
@ -102,34 +102,7 @@ def cli_setup(ctx: click.Context, skip_questions: bool) -> None:
|
||||||
)
|
)
|
||||||
|
|
||||||
elif ctx.obj.config.db_type == 'postgres':
|
elif ctx.obj.config.db_type == 'postgres':
|
||||||
ctx.obj.config.pg_name = click.prompt(
|
config_postgresql(ctx.obj.config)
|
||||||
'What is the name of the database?',
|
|
||||||
default = ctx.obj.config.pg_name
|
|
||||||
)
|
|
||||||
|
|
||||||
ctx.obj.config.pg_host = click.prompt(
|
|
||||||
'What IP address, hostname, or unix socket does the server listen on?',
|
|
||||||
default = ctx.obj.config.pg_host,
|
|
||||||
type = int
|
|
||||||
)
|
|
||||||
|
|
||||||
ctx.obj.config.pg_port = click.prompt(
|
|
||||||
'What port does the server listen on?',
|
|
||||||
default = ctx.obj.config.pg_port,
|
|
||||||
type = int
|
|
||||||
)
|
|
||||||
|
|
||||||
ctx.obj.config.pg_user = click.prompt(
|
|
||||||
'Which user will authenticate with the server?',
|
|
||||||
default = ctx.obj.config.pg_user
|
|
||||||
)
|
|
||||||
|
|
||||||
ctx.obj.config.pg_pass = click.prompt(
|
|
||||||
'User password',
|
|
||||||
hide_input = True,
|
|
||||||
show_default = False,
|
|
||||||
default = ctx.obj.config.pg_pass or ""
|
|
||||||
) or None
|
|
||||||
|
|
||||||
ctx.obj.config.ca_type = click.prompt(
|
ctx.obj.config.ca_type = click.prompt(
|
||||||
'Which caching backend?',
|
'Which caching backend?',
|
||||||
|
@ -214,21 +187,18 @@ def cli_run(ctx: click.Context, dev: bool = False) -> None:
|
||||||
|
|
||||||
|
|
||||||
@cli.command('db-maintenance')
|
@cli.command('db-maintenance')
|
||||||
@click.option('--fix-timestamps', '-t', is_flag = True,
|
|
||||||
help = 'Make sure timestamps in the database are float values')
|
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
def cli_db_maintenance(ctx: click.Context, fix_timestamps: bool) -> None:
|
def cli_db_maintenance(ctx: click.Context) -> None:
|
||||||
'Perform maintenance tasks on the database'
|
'Perform maintenance tasks on the database'
|
||||||
|
|
||||||
if fix_timestamps:
|
|
||||||
with ctx.obj.database.session(True) as conn:
|
|
||||||
conn.fix_timestamps()
|
|
||||||
|
|
||||||
if ctx.obj.config.db_type == "postgres":
|
if ctx.obj.config.db_type == "postgres":
|
||||||
return
|
return
|
||||||
|
|
||||||
with ctx.obj.database.session(False) as conn:
|
with ctx.obj.database.session(False) as s:
|
||||||
with conn.execute("VACUUM"):
|
with s.transaction():
|
||||||
|
s.fix_timestamps()
|
||||||
|
|
||||||
|
with s.execute("VACUUM"):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -347,9 +317,24 @@ def cli_switchbackend(ctx: click.Context) -> None:
|
||||||
|
|
||||||
config = Config(ctx.obj.config.path, load = True)
|
config = Config(ctx.obj.config.path, load = True)
|
||||||
config.db_type = "sqlite" if config.db_type == "postgres" else "postgres"
|
config.db_type = "sqlite" if config.db_type == "postgres" else "postgres"
|
||||||
|
|
||||||
|
if config.db_type == "postgres":
|
||||||
|
if click.confirm("Setup PostgreSQL configuration?"):
|
||||||
|
config_postgresql(config)
|
||||||
|
|
||||||
|
order = ("SQLite", "PostgreSQL")
|
||||||
|
click.pause("Make sure the database and user already exist before continuing")
|
||||||
|
|
||||||
|
else:
|
||||||
|
order = ("PostgreSQL", "SQLite")
|
||||||
|
|
||||||
|
click.echo(f"About to convert from {order[0]} to {order[1]}...")
|
||||||
database = get_database(config, migrate = False)
|
database = get_database(config, migrate = False)
|
||||||
|
|
||||||
with database.session(True) as new, ctx.obj.database.session(False) as old:
|
with database.session(True) as new, ctx.obj.database.session(False) as old:
|
||||||
|
if click.confirm("All tables in the destination database will be dropped. Continue?"):
|
||||||
|
new.drop_tables()
|
||||||
|
|
||||||
new.create_tables()
|
new.create_tables()
|
||||||
|
|
||||||
for table in schema.TABLES.keys():
|
for table in schema.TABLES.keys():
|
||||||
|
@ -357,7 +342,7 @@ def cli_switchbackend(ctx: click.Context) -> None:
|
||||||
new.insert(table, row).close()
|
new.insert(table, row).close()
|
||||||
|
|
||||||
config.save()
|
config.save()
|
||||||
click.echo(f"Converted database to {repr(config.db_type)}")
|
click.echo("Done!")
|
||||||
|
|
||||||
|
|
||||||
@cli.group('config')
|
@cli.group('config')
|
||||||
|
@ -1018,6 +1003,35 @@ def cli_whitelist_import(ctx: click.Context) -> None:
|
||||||
click.echo('Imported whitelist from inboxes')
|
click.echo('Imported whitelist from inboxes')
|
||||||
|
|
||||||
|
|
||||||
|
def config_postgresql(config: Config) -> None:
|
||||||
|
config.pg_name = click.prompt(
|
||||||
|
'What is the name of the database?',
|
||||||
|
default = config.pg_name
|
||||||
|
)
|
||||||
|
|
||||||
|
config.pg_host = click.prompt(
|
||||||
|
'What IP address, hostname, or unix socket does the server listen on?',
|
||||||
|
default = config.pg_host,
|
||||||
|
)
|
||||||
|
|
||||||
|
config.pg_port = click.prompt(
|
||||||
|
'What port does the server listen on?',
|
||||||
|
default = config.pg_port,
|
||||||
|
type = int
|
||||||
|
)
|
||||||
|
|
||||||
|
config.pg_user = click.prompt(
|
||||||
|
'Which user will authenticate with the server?',
|
||||||
|
default = config.pg_user
|
||||||
|
)
|
||||||
|
|
||||||
|
config.pg_pass = click.prompt(
|
||||||
|
'User password',
|
||||||
|
hide_input = True,
|
||||||
|
show_default = False,
|
||||||
|
default = config.pg_pass or ""
|
||||||
|
) or None
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
cli(prog_name='activityrelay')
|
cli(prog_name='activityrelay')
|
||||||
|
|
|
@ -171,9 +171,9 @@ async def handle_follow(view: ActorView, conn: Connection) -> None:
|
||||||
|
|
||||||
|
|
||||||
async def handle_undo(view: ActorView, conn: Connection) -> None:
|
async def handle_undo(view: ActorView, conn: Connection) -> None:
|
||||||
# If the object is not a Follow, forward it
|
|
||||||
if view.message.object['type'] != 'Follow':
|
if view.message.object['type'] != 'Follow':
|
||||||
await handle_forward(view, conn)
|
# forwarding deletes does not work, so don't bother
|
||||||
|
# await handle_forward(view, conn)
|
||||||
return
|
return
|
||||||
|
|
||||||
# prevent past unfollows from removing an instance
|
# prevent past unfollows from removing an instance
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import aputils
|
import aputils
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
from aiohttp import ClientConnectorError
|
||||||
from aiohttp.web import Request
|
from aiohttp.web import Request
|
||||||
from blib import HttpError
|
from blib import HttpError
|
||||||
|
|
||||||
|
@ -104,6 +105,10 @@ class ActorView(View):
|
||||||
logging.debug('HTTP Status %i: %s', e.status, e.message)
|
logging.debug('HTTP Status %i: %s', e.status, e.message)
|
||||||
raise HttpError(400, 'failed to fetch actor')
|
raise HttpError(400, 'failed to fetch actor')
|
||||||
|
|
||||||
|
except ClientConnectorError as e:
|
||||||
|
logging.warning('Error when trying to fetch actor: %s, %s', self.signature.keyid, str(e))
|
||||||
|
raise HttpError(400, 'failed to fetch actor')
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
raise HttpError(500, 'unexpected error when fetching actor')
|
raise HttpError(500, 'unexpected error when fetching actor')
|
||||||
|
|
Loading…
Reference in a new issue