Compare commits

..

No commits in common. "b1a2989ba76f695fb2e8c88fedfee9c9584ec94d" and "65b6c0a5adeec74f6dbf10999cfada908d9ea1fe" have entirely different histories.

8 changed files with 165 additions and 181 deletions

View file

@ -5,7 +5,7 @@ ENV DOCKER_RUNNING=true
# setup various container properties # setup various container properties
VOLUME ["/data"] VOLUME ["/data"]
CMD ["python3", "-m", "relay", "run"] CMD ["python3", "-m", "relay"]
EXPOSE 8080/tcp EXPOSE 8080/tcp
WORKDIR /opt/activityrelay WORKDIR /opt/activityrelay

View file

@ -2,21 +2,9 @@
case $1 in case $1 in
install) install)
if [[ -z ${2#$} ]]; then
host=127.0.0.1
else
host=$2
fi
if [[ -z ${3#$} ]]; then
port=8080
else
port=$3
fi
docker build -f Dockerfile -t activityrelay . && \ docker build -f Dockerfile -t activityrelay . && \
docker volume create activityrelay-data && \ docker volume create activityrelay-data && \
docker run -it -p target=8080,published=${host}:${port} -v activityrelay-data:/data --name activityrelay activityrelay docker run -it -p 8080:8080 -v activityrelay-data:/data --name activityrelay activityrelay
;; ;;
uninstall) uninstall)
@ -34,10 +22,6 @@ case $1 in
docker stop activityrelay docker stop activityrelay
;; ;;
restart)
docker restart activityrelay
;;
manage) manage)
shift shift
docker exec -it activityrelay python3 -m relay "$@" docker exec -it activityrelay python3 -m relay "$@"
@ -77,7 +61,10 @@ case $1 in
printf "$COLS" "- edit" "Edit the relay's config in \$EDITOR" printf "$COLS" "- edit" "Edit the relay's config in \$EDITOR"
printf "$COLS" "- shell" "Drop into a bash shell on the running container" printf "$COLS" "- shell" "Drop into a bash shell on the running container"
printf "$COLS" "- rescue" "Drop into a bash shell on a temp container with the data volume mounted" printf "$COLS" "- rescue" "Drop into a bash shell on a temp container with the data volume mounted"
printf "$COLS" "- install [address] [port]" "Build the image, create a new container and volume, and run relay setup" printf "$COLS" "- install" "Build the image, create a new container and volume, and run relay setup"
printf "$COLS" "- uninstall" "Delete the relay image, container, and volume" printf "$COLS" "- uninstall" "Delete the relay image, container, and volume"
echo ""
echo "Note: This script may not work. It is recommended to manually install and manage the container if you know what you're doing."
;; ;;
esac esac

View file

@ -154,8 +154,6 @@ When enabled, instances that try to follow the relay will have to be manually ap
Maximum level of messages to log. Maximum level of messages to log.
Note: Changing this setting via CLI does not actually take effect until restart.
Valid values: `DEBUG`, `VERBOSE`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` Valid values: `DEBUG`, `VERBOSE`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
log-level: INFO log-level: INFO

View file

@ -13,9 +13,9 @@ the [official pipx docs](https://pypa.github.io/pipx/installation/) for more in-
python3 -m pip install pipx python3 -m pip install pipx
Now simply install ActivityRelay from pypi Now simply install ActivityRelay directly from git
pipx install activityrelay pipx install git+https://git.pleroma.social/pleroma/relay@0.3.0
Or from a cloned git repo. Or from a cloned git repo.
@ -36,9 +36,10 @@ be installed via [pyenv](https://github.com/pyenv/pyenv).
## Pip ## Pip
The instructions for installation via pip are very similar to pipx The instructions for installation via pip are very similar to pipx. Installation can be done from
git
python3 -m pip install activityrelay python3 -m pip install git+https://git.pleroma.social/pleroma/relay@0.3.0
or a cloned git repo. or a cloned git repo.
@ -57,11 +58,10 @@ And start the relay when finished
Installation and management via Docker can be handled with the `docker.sh` script. To install Installation and management via Docker can be handled with the `docker.sh` script. To install
ActivityRelay, run the install command. Once the image is built and the container is created, ActivityRelay, run the install command. Once the image is built and the container is created,
you will be asked to fill out some config options for your relay. An address and port can be your will be asked to fill out some config options for your relay.
specified to change what the relay listens on.
./docker.sh install 0.0.0.0 6942 ./docker.sh install
Finally start it up. It will be listening on TCP localhost:8080 by default. Finally start it up. It will be listening on TCP port 8080.
./docker.sh start ./docker.sh start

View file

@ -55,7 +55,7 @@ class Application(web.Application):
DEFAULT: Application | None = None DEFAULT: Application | None = None
def __init__(self, cfgpath: Path | None, dev: bool = False): def __init__(self, cfgpath: str | None, dev: bool = False):
web.Application.__init__(self, web.Application.__init__(self,
middlewares = [ middlewares = [
handle_api_path, handle_api_path,

View file

@ -33,7 +33,7 @@ else:
DOCKER_VALUES = { DOCKER_VALUES = {
'listen': '0.0.0.0', 'listen': '0.0.0.0',
'port': 8080, 'port': 8080,
'sq_path': '/data/relay.sqlite3' 'sq_path': '/data/relay.jsonld'
} }
@ -65,7 +65,7 @@ class Config:
rd_prefix: str = 'activityrelay' rd_prefix: str = 'activityrelay'
def __init__(self, path: Path | None = None, load: bool = False): def __init__(self, path: str | None = None, load: bool = False):
self.path = Config.get_config_dir(path) self.path = Config.get_config_dir(path)
self.reset() self.reset()
@ -92,12 +92,9 @@ class Config:
@staticmethod @staticmethod
def get_config_dir(path: Path | str | None = None) -> Path: def get_config_dir(path: str | None = None) -> Path:
if isinstance(path, str): if path:
path = Path(path) return Path(path).expanduser().resolve()
if path is not None:
return path.expanduser().resolve()
paths = ( paths = (
Path("relay.yaml").resolve(), Path("relay.yaml").resolve(),

17
dev.py → relay/dev.py Executable file → Normal file
View file

@ -1,4 +1,3 @@
#!/usr/bin/env python3
import click import click
import platform import platform
import shutil import shutil
@ -8,10 +7,12 @@ import time
from datetime import datetime, timedelta from datetime import datetime, timedelta
from pathlib import Path from pathlib import Path
from relay import __version__, logger as logging
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory
from typing import Sequence from typing import Sequence
from . import __version__
from . import logger as logging
try: try:
from watchdog.observers import Observer from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler from watchdog.events import PatternMatchingEventHandler
@ -21,7 +22,8 @@ except ImportError:
pass pass
REPO = Path(__file__).parent SCRIPT = Path(__file__).parent
REPO = SCRIPT.parent
IGNORE_EXT = { IGNORE_EXT = {
'.py', '.py',
'.pyc' '.pyc'
@ -56,8 +58,8 @@ def cli_lint(path: Path, strict: bool, watch: bool) -> None:
handle_run_watcher([sys.executable, "-m", "relay.dev", "lint", str(path)], wait = True) handle_run_watcher([sys.executable, "-m", "relay.dev", "lint", str(path)], wait = True)
return return
flake8 = [sys.executable, '-m', 'flake8', "dev.py", str(path)] flake8 = [sys.executable, '-m', 'flake8', str(path)]
mypy = [sys.executable, '-m', 'mypy', "dev.py", str(path)] mypy = [sys.executable, '-m', 'mypy', str(path)]
if strict: if strict:
mypy.append('--strict') mypy.append('--strict')
@ -106,7 +108,7 @@ def cli_build():
cmd.append('--console') cmd.append('--console')
# putting the spec path on a different drive than the source dir breaks # putting the spec path on a different drive than the source dir breaks
if str(REPO)[0] == tmp[0]: if str(SCRIPT)[0] == tmp[0]:
cmd.extend(['--specpath', tmp]) cmd.extend(['--specpath', tmp])
else: else:
@ -134,7 +136,7 @@ def handle_run_watcher(*commands: Sequence[str], wait: bool = False):
handler.run_procs() handler.run_procs()
watcher = Observer() watcher = Observer()
watcher.schedule(handler, str(REPO), recursive=True) watcher.schedule(handler, str(SCRIPT), recursive=True)
watcher.start() watcher.start()
try: try:
@ -149,6 +151,7 @@ def handle_run_watcher(*commands: Sequence[str], wait: bool = False):
watcher.join() watcher.join()
class WatchHandler(PatternMatchingEventHandler): class WatchHandler(PatternMatchingEventHandler):
patterns = ['*.py'] patterns = ['*.py']

View file

@ -1,10 +1,11 @@
from __future__ import annotations from __future__ import annotations
import Crypto
import aputils import aputils
import asyncio import asyncio
import click import click
import json
import os import os
import platform
import typing import typing
from pathlib import Path from pathlib import Path
@ -31,44 +32,31 @@ def check_alphanumeric(text: str) -> str:
return text return text
@click.group('cli', context_settings = {'show_default': True}) @click.group('cli', context_settings={'show_default': True}, invoke_without_command=True)
@click.option('--config', '-c', type = Path, help = 'path to the relay\'s config') @click.option('--config', '-c', help='path to the relay\'s config')
@click.version_option(version=__version__, prog_name='ActivityRelay') @click.version_option(version=__version__, prog_name='ActivityRelay')
@click.pass_context @click.pass_context
def cli(ctx: click.Context, config: Path | None) -> None: def cli(ctx: click.Context, config: str | None) -> None:
if IS_DOCKER:
config = Path("/data/relay.yaml")
# The database was named "relay.jsonld" even though it's an sqlite file. Fix it.
db = Path('/data/relay.sqlite3')
wrongdb = Path('/data/relay.jsonld')
if wrongdb.exists() and not db.exists():
try:
with wrongdb.open('rb') as fd:
json.load(fd)
except json.JSONDecodeError:
wrongdb.rename(db)
ctx.obj = Application(config) ctx.obj = Application(config)
if not ctx.invoked_subcommand:
if ctx.obj.config.domain.endswith('example.com'):
cli_setup.callback() # type: ignore
else:
click.echo(
'[DEPRECATED] Running the relay without the "run" command will be removed in the ' +
'future.'
)
cli_run.callback() # type: ignore
@cli.command('setup') @cli.command('setup')
@click.option('--skip-questions', '-s', is_flag = True, help = 'Just setup the database')
@click.pass_context @click.pass_context
def cli_setup(ctx: click.Context, skip_questions: bool) -> None: def cli_setup(ctx: click.Context) -> None:
'Generate a new config and create the database' 'Generate a new config and create the database'
if ctx.obj.signer is not None:
if not click.prompt('The database is already setup. Are you sure you want to continue?'):
return
if skip_questions and ctx.obj.config.domain.endswith('example.com'):
click.echo('You cannot skip the questions if the relay is not configured yet')
return
if not skip_questions:
while True: while True:
ctx.obj.config.domain = click.prompt( ctx.obj.config.domain = click.prompt(
'What domain will the relay be hosted on?', 'What domain will the relay be hosted on?',
@ -98,7 +86,7 @@ def cli_setup(ctx: click.Context, skip_questions: bool) -> None:
type = click.Choice(['postgres', 'sqlite'], case_sensitive = False) type = click.Choice(['postgres', 'sqlite'], case_sensitive = False)
) )
if ctx.obj.config.db_type == 'sqlite' and not IS_DOCKER: if ctx.obj.config.db_type == 'sqlite':
ctx.obj.config.sq_path = click.prompt( ctx.obj.config.sq_path = click.prompt(
'Where should the database be stored?', 'Where should the database be stored?',
default = ctx.obj.config.sq_path default = ctx.obj.config.sq_path
@ -186,11 +174,7 @@ def cli_setup(ctx: click.Context, skip_questions: bool) -> None:
for key, value in config.items(): for key, value in config.items():
conn.put_config(key, value) conn.put_config(key, value)
if IS_DOCKER: if not IS_DOCKER and click.confirm('Relay all setup! Would you like to run it now?'):
click.echo("Relay all setup! Start the container to run the relay.")
return
if click.confirm('Relay all setup! Would you like to run it now?'):
cli_run.callback() # type: ignore cli_run.callback() # type: ignore
@ -200,13 +184,28 @@ def cli_setup(ctx: click.Context, skip_questions: bool) -> None:
def cli_run(ctx: click.Context, dev: bool = False) -> None: def cli_run(ctx: click.Context, dev: bool = False) -> None:
'Run the relay' 'Run the relay'
if ctx.obj.config.domain.endswith('example.com') or ctx.obj.signer is None: if ctx.obj.config.domain.endswith('example.com') or not ctx.obj.signer:
if not IS_DOCKER: click.echo(
click.echo('Relay is not set up. Please run "activityrelay setup".') 'Relay is not set up. Please edit your relay config or run "activityrelay setup".'
)
return return
cli_setup.callback() # type: ignore vers_split = platform.python_version().split('.')
pip_command = 'pip3 uninstall pycrypto && pip3 install pycryptodome'
if Crypto.__version__ == '2.6.1':
if int(vers_split[1]) > 7:
click.echo(
'Error: PyCrypto is broken on Python 3.8+. Please replace it with pycryptodome ' +
'before running again. Exiting...'
)
click.echo(pip_command)
return
click.echo('Warning: PyCrypto is old and should be replaced with pycryptodome')
click.echo(pip_command)
return return
ctx.obj['dev'] = dev ctx.obj['dev'] = dev