diff --git a/argos/commands.py b/argos/commands.py index 156df73..ec694e5 100644 --- a/argos/commands.py +++ b/argos/commands.py @@ -60,13 +60,13 @@ def server(): def agent(server_url, auth, max_tasks, wait_time, log_level): """Get and run tasks to the provided server. Will wait for new tasks. - Usage: argos agent https://argos.server "auth-token-here" + Usage: argos agent https://argos.example.org "auth-token-here" Alternatively, you can use the following environment variables to avoid passing arguments to the agent on the command line: \b - ARGOS_AGENT_SERVER_URL=https://argos.server + ARGOS_AGENT_SERVER_URL=https://argos.example.org ARGOS_AGENT_TOKEN=auth-token-here """ click.echo("Starting argos agent. Will retry forever.") @@ -83,7 +83,7 @@ def agent(server_url, auth, max_tasks, wait_time, log_level): @click.option("--config", default="config.yaml", help="Path the the configuration file") @click.option("--reload", is_flag=True, help="Enable hot reloading") def start(host, port, config, reload): - """Starts the server.""" + """Starts the server""" os.environ["ARGOS_YAML_FILE"] = config uvicorn.run("argos.server:app", host=host, port=port, reload=reload) @@ -136,7 +136,7 @@ async def cleandb(max_results, max_lock_seconds): @server.command() @coroutine async def reload_config(): - """Read tasks config and add/delete tasks in database if needed""" + """Read tasks configuration and add/delete tasks in database if needed""" # The imports are made here otherwise the agent will need server configuration files. from argos.server import queries from argos.server.main import get_application, read_config diff --git a/conf/systemd-agent.service b/conf/systemd-agent.service index fdadc28..93e7e9f 100644 --- a/conf/systemd-agent.service +++ b/conf/systemd-agent.service @@ -17,5 +17,5 @@ WantedBy=multi-user.target # NB: it may be better to # - use a dedicated user -# - use a EnvironmentFile=/etc/default/argos-agent in order enable configuration -# changes without doing a systemctl daemon-reload \ No newline at end of file +# - use a EnvironmentFile=/etc/default/argos-agent in order to enable configuration +# changes without doing a systemctl daemon-reload diff --git a/conf/systemd-server.service b/conf/systemd-server.service index f5116a9..285d37e 100644 --- a/conf/systemd-server.service +++ b/conf/systemd-server.service @@ -8,11 +8,16 @@ PartOf=postgresql.service [Service] User=www-data WorkingDirectory=/var/www/argos/ +Environment="ARGOS_SERVER_WORKERS=4" ExecStartPre=/var/www/argos/venv/bin/argos server migrate ExecStartPre=/var/www/argos/venv/bin/argos server reload-config -ExecStart=/var/www/argos/venv/bin/argos server start +ExecStart=/var/www/argos/venv/bin/gunicorn "argos.server.main:get_application()" -w $ARGOS_SERVER_WORKERS -k uvicorn.workers.UvicornWorker ExecReload=/var/www/argos/venv/bin/argos server reload SyslogIdentifier=argos-server [Install] WantedBy=multi-user.target + +# NB: it may be better to +# - use a EnvironmentFile=/etc/default/argos-server in order to enable configuration +# changes without doing a systemctl daemon-reload diff --git a/docs/cli.md b/docs/cli.md index 4062581..711f834 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -40,19 +40,21 @@ Commands: .. ]]] --> ```man -Usage: argos agent [OPTIONS] SERVER AUTH +Usage: argos agent [OPTIONS] SERVER_URL AUTH Get and run tasks to the provided server. Will wait for new tasks. - Usage: argos agent https://argos.server "auth-token-here" + Usage: argos agent https://argos.example.org "auth-token-here" Alternatively, you can use the following environment variables to avoid passing arguments to the agent on the command line: - ARGOS_AGENT_SERVER_URL=https://argos.server ARGOS_AGENT_TOKEN=auth-token- - here + + ARGOS_AGENT_SERVER_URL=https://argos.example.org + ARGOS_AGENT_TOKEN=auth-token-here Options: - --max-tasks INTEGER Number of concurrent tasks this agent can run + --max-tasks INTEGER Number of concurrent tasks this agent can + run --wait-time INTEGER Waiting time between two polls on the server (seconds) --log-level [DEBUG|INFO|WARNING|ERROR|CRITICAL] @@ -75,8 +77,10 @@ Options: --help Show this message and exit. Commands: - cleandb Clean the database (to run routinely) - start Starts the server. + cleandb Clean the database (to run routinely) + migrate Run database migrations + reload-config Read tasks config and add/delete tasks in database if... + start Starts the server ``` +### Server migrate + + + +```man +Usage: argos server migrate [OPTIONS] + + Run database migrations + +Options: + --help Show this message and exit. +``` + + + + ### Server clean + +### Server reload-config + + + +```man +Usage: argos server reload-config [OPTIONS] + + Read tasks configuration and add/delete tasks in database if needed + +Options: + --help Show this message and exit. +``` + + + diff --git a/docs/deployment/systemd.md b/docs/deployment/systemd.md index 106db12..04fa7e2 100644 --- a/docs/deployment/systemd.md +++ b/docs/deployment/systemd.md @@ -17,9 +17,3 @@ caption: /etc/systemd/system/argos-agent.service caption: /etc/systemd/system/argos-server.service --- ``` - -Please note that it might be better to use Gunicorn with a Uvicorn worker, [as specified in the Uvicorn docs](https://www.uvicorn.org/#running-with-gunicorn): - -```bash -gunicorn example:app -w 4 -k uvicorn.workers.UvicornWorker -b '127.0.0.1:8000' -``` diff --git a/docs/developer/migrations.md b/docs/developer/migrations.md index 12746cd..a5190e8 100644 --- a/docs/developer/migrations.md +++ b/docs/developer/migrations.md @@ -9,3 +9,5 @@ you're done, you can create a new migration. ```bash venv/bin/alembic revision --autogenerate -m "migration reason" ``` + +Edit the created file to remove comments and adapt it to make sure the migration is complete (Alembic is not powerful enough to cover all the corner cases). diff --git a/docs/developer/models.md b/docs/developer/models.md index 79bc219..d7f8bfc 100644 --- a/docs/developer/models.md +++ b/docs/developer/models.md @@ -13,11 +13,12 @@ class Task { - selected_at - completed_at - next_run + - severity + - last_severity_update } class Result{ - task : Task - task_id - - task - agent_id - submitted_at - status @@ -27,9 +28,11 @@ class Result{ Result "*" o-- "1" Task : has many ``` +The `severity` attribute in `Task` is the severity of the last `Result` submitted by an agent. + ```{literalinclude} ../../argos/server/models.py --- caption: models.py --- -``` \ No newline at end of file +``` diff --git a/docs/developer/overview.md b/docs/developer/overview.md index 252729b..fdaf0a8 100644 --- a/docs/developer/overview.md +++ b/docs/developer/overview.md @@ -27,3 +27,4 @@ The server acts like a job queue. When an agent asks for work, the server will: When it receives the results, it will: - Remove the "selected by" and "selected at" fields - Compute the next execution date. +- Send alerts if needed diff --git a/docs/developer/projects.md b/docs/developer/projects.md index 459c836..41ff401 100644 --- a/docs/developer/projects.md +++ b/docs/developer/projects.md @@ -10,7 +10,8 @@ - [SQLAlchemy](https://www.sqlalchemy.org/) is the ORM we use, to connect to our database and issue queries; - [Alembic](https://alembic.sqlalchemy.org) is used for DB migrations; - [Tenacity](https://github.com/jd/tenacity) a small utility to retry a function in case an error occured; -- [Uvicorn](https://www.uvicorn.org/) is the tool used to run our server. +- [Uvicorn](https://www.uvicorn.org/) is the tool used to run our server; +- [Gunicorn](https://gunicorn.org/) is the recommended WSGI HTTP server for production. ## CSS framework diff --git a/docs/index.md b/docs/index.md index cbc7966..823469d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -51,6 +51,12 @@ cli api ``` +```{toctree} +:caption: Deployment +:hidden: +deployment/systemd +``` + ```{toctree} :caption: Configuration :hidden: @@ -69,9 +75,3 @@ developer/projects changelog ``` -```{toctree} -:caption: Deployment -:hidden: -deployment/systemd -``` - diff --git a/docs/installation/getting-started.md b/docs/installation/getting-started.md index 2eeb828..374899a 100644 --- a/docs/installation/getting-started.md +++ b/docs/installation/getting-started.md @@ -3,7 +3,7 @@ ## Requirements - Python 3.11+ -- PostgreSQL 13+ +- PostgreSQL 13+ (for production) ## Getting dependencies @@ -35,6 +35,8 @@ caption: .env --- ``` +Please note that the only supported database engines are SQLite for development and PostgreSQL for production. + Then you can start the server: ```bash diff --git a/docs/installation/postgresql.md b/docs/installation/postgresql.md index 27f767e..89fe344 100644 --- a/docs/installation/postgresql.md +++ b/docs/installation/postgresql.md @@ -1,12 +1,12 @@ -# Installing PostgreSQL +# Use with PostgreSQL -If you intend to use argos with Postgresql, you can install it with the following commands: +If you intend to use argos with Postgresql, which is recommended for production, you can install it with the following commands: ```bash pip install -e ".[postgres]" ``` -Here are a few steps for you to install postgresql on your system: +Here are a few steps for you to install PostgreSQL on your system: ## Debian diff --git a/pyproject.toml b/pyproject.toml index a9375e7..6de83f8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ dependencies = [ "sqlalchemy-utils>=0.41,<1", "tenacity>=8.2,<9", "uvicorn>=0.23,<1", + "gunicorn>=21.2,<22", ] [project.optional-dependencies]