From c2cc3866f3d7d79f859c8c476c3780d930234899 Mon Sep 17 00:00:00 2001 From: CroneKorkN Date: Sun, 10 May 2026 18:52:37 +0200 Subject: [PATCH] left4me: chown /opt/left4me/src after git_deploy bw's git_deploy extracts the git archive as the connecting user (root after sudo), so files end up root-owned. The subsequent pip install runs as left4me and needs to write .egg-info/ inside each editable package, which fails with "permission denied". Add action:left4me_chown_src triggered by git_deploy and required by pip_install. Idempotent (chown -R is fine to re-run). --- bundles/left4me/items.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/bundles/left4me/items.py b/bundles/left4me/items.py index 9544ec0..b45c169 100644 --- a/bundles/left4me/items.py +++ b/bundles/left4me/items.py @@ -130,6 +130,10 @@ git_deploy = { 'repo': node.metadata.get('left4me/git_url'), 'rev': node.metadata.get('left4me/git_branch'), 'triggers': [ + # bw extracts the git archive as the connecting user (root after + # sudo) — files end up root-owned. Chown so subsequent + # `pip install -e` running as left4me can write .egg-info/. + 'action:left4me_chown_src', # create_venv is gated by `unless` for idempotency and doesn't # need to refire on git updates — once the venv exists, it # persists. pip_install IS retriggered so editable installs @@ -139,6 +143,17 @@ git_deploy = { }, } +actions['left4me_chown_src'] = { + 'command': 'chown -R left4me:left4me /opt/left4me/src', + 'triggered': True, + 'cascade_skip': False, + 'needs': [ + 'git_deploy:/opt/left4me/src', + 'user:left4me', + 'group:left4me', + ], +} + actions['left4me_create_venv'] = { 'command': 'sudo -u left4me /usr/bin/python3 -m venv /opt/left4me/.venv', 'unless': 'test -x /opt/left4me/.venv/bin/python', @@ -173,6 +188,7 @@ actions['left4me_pip_install'] = { 'needs': [ 'git_deploy:/opt/left4me/src', 'action:left4me_create_venv', + 'action:left4me_chown_src', ], 'triggers': [ 'action:left4me_alembic_upgrade',