From def010c97607a66e5b7c77d06d1744799de16dc8 Mon Sep 17 00:00:00 2001 From: CroneKorkN Date: Sun, 10 May 2026 17:32:19 +0200 Subject: [PATCH] left4me: git_deploy + venv/pip/alembic/seed action chain Mirrors deploy-test-server.sh:233-242 + :329-333. Single pip command installs both editable packages (l4d2host + l4d2web) from the same checkout. Alembic and seed-overlays run as the left4me user with JOB_WORKER_ENABLED=false sourced from web.env. --- bundles/left4me/items.py | 93 +++++++++++++++++++++++++++++++++++++ bundles/left4me/metadata.py | 4 ++ 2 files changed, 97 insertions(+) diff --git a/bundles/left4me/items.py b/bundles/left4me/items.py index 7daee66..773fde8 100644 --- a/bundles/left4me/items.py +++ b/bundles/left4me/items.py @@ -120,3 +120,96 @@ actions = { 'triggered': True, }, } + +git_deploy = { + '/opt/left4me/src': { + 'repo': node.metadata.get('left4me/git_url'), + 'rev': node.metadata.get('left4me/git_branch'), + 'triggers': [ + 'action:left4me_create_venv', + 'action:left4me_pip_install', + ], + }, +} + +actions['left4me_create_venv'] = { + 'command': 'sudo -u left4me /usr/bin/python3 -m venv /opt/left4me/.venv', + 'unless': 'test -x /opt/left4me/.venv/bin/python', + 'cascade_skip': False, + 'needs': [ + 'directory:/opt/left4me', + 'pkg_apt:python3-venv', + 'user:left4me', + ], + 'triggers': [ + 'action:left4me_pip_upgrade', + ], +} + +actions['left4me_pip_upgrade'] = { + 'command': 'sudo -u left4me /opt/left4me/.venv/bin/python -m pip install --upgrade pip', + 'triggered': True, + 'cascade_skip': False, + 'needs': [ + 'pkg_apt:python3-pip', + ], + 'triggers': [ + 'action:left4me_pip_install', + ], +} + +actions['left4me_pip_install'] = { + # Single pip invocation installs both editable packages from the same checkout. + 'command': 'sudo -u left4me /opt/left4me/.venv/bin/pip install -e /opt/left4me/src/l4d2host -e /opt/left4me/src/l4d2web', + 'triggered': True, + 'cascade_skip': False, + 'needs': [ + 'git_deploy:/opt/left4me/src', + 'action:left4me_create_venv', + ], + 'triggers': [ + 'action:left4me_alembic_upgrade', + ], +} + +actions['left4me_alembic_upgrade'] = { + # Mirrors deploy-test-server.sh:239-242. Runs as left4me with both env + # files sourced; JOB_WORKER_ENABLED=false so a stray worker doesn't race + # with the migration. + 'command': ( + 'sudo -u left4me sh -c "' + 'cd /opt/left4me/src/l4d2web && ' + 'set -a && . /etc/left4me/host.env && . /etc/left4me/web.env && set +a && ' + 'env JOB_WORKER_ENABLED=false PYTHONPATH=/opt/left4me/src ' + '/opt/left4me/.venv/bin/alembic -c /opt/left4me/src/l4d2web/alembic.ini upgrade head' + '"' + ), + 'triggered': True, + 'cascade_skip': False, + 'needs': [ + 'action:left4me_pip_install', + 'file:/etc/left4me/host.env', + 'file:/etc/left4me/web.env', + ], + 'triggers': [ + 'action:left4me_seed_overlays', + 'svc_systemd:left4me-web.service:restart', + ], +} + +actions['left4me_seed_overlays'] = { + # Idempotent: refreshes script bodies in place; existing overlay rows keep their ids. + 'command': ( + 'sudo -u left4me sh -c "' + 'set -a && . /etc/left4me/host.env && . /etc/left4me/web.env && set +a && ' + 'env JOB_WORKER_ENABLED=false PYTHONPATH=/opt/left4me/src ' + '/opt/left4me/.venv/bin/flask --app l4d2web.app:create_app ' + 'seed-script-overlays /opt/left4me/src/examples/script-overlays' + '"' + ), + 'triggered': True, + 'cascade_skip': False, + 'needs': [ + 'action:left4me_alembic_upgrade', + ], +} diff --git a/bundles/left4me/metadata.py b/bundles/left4me/metadata.py index 2a320db..327db22 100644 --- a/bundles/left4me/metadata.py +++ b/bundles/left4me/metadata.py @@ -13,6 +13,10 @@ defaults = { 'iproute2': {}, 'curl': {}, 'ca-certificates': {}, + 'python3': {}, + 'python3-venv': {}, + 'python3-pip': {}, + 'python3-dev': {}, }, }, }