left4me: ship a /usr/local/sbin/left4me wrapper for the flask CLI
One-liner instead of "ssh + heredoc + sudo + sh -c + double quotes": sudo left4me create-user alice --admin sudo left4me seed-script-overlays /opt/left4me/src/examples/script-overlays sudo left4me routes The wrapper sources host.env + web.env, drops to the left4me user, sets JOB_WORKER_ENABLED=false (admin-side ops shouldn't race the worker) and PYTHONPATH=/opt/left4me/src, then exec's the flask CLI with whatever args followed `left4me`. No env-var enumeration: the sh -c trailing 'sh "$@"' forwards positional args without quoting hell. README updated to drop the verbose recipe.
This commit is contained in:
parent
6f2073847d
commit
b8648cb53f
3 changed files with 31 additions and 6 deletions
|
|
@ -70,12 +70,15 @@ from defaults. None of these need to be declared per-node.
|
||||||
- **CAKE shaping is configured separately**, via
|
- **CAKE shaping is configured separately**, via
|
||||||
`network/<iface>/cake` on the node (consumed by `bundles/network/`),
|
`network/<iface>/cake` on the node (consumed by `bundles/network/`),
|
||||||
not by this bundle.
|
not by this bundle.
|
||||||
- **First-run admin user is manual.** After `bw apply`, run on the host:
|
- **First-run admin user is manual.** After `bw apply`, ssh to the host and
|
||||||
`sudo -u left4me sh -c '. /etc/left4me/host.env && . /etc/left4me/web.env &&
|
bootstrap the admin via the `left4me` wrapper (it sources the env files,
|
||||||
LEFT4ME_ADMIN_PASSWORD=<picked> /opt/left4me/.venv/bin/flask
|
drops to the `left4me` user, and runs the flask CLI):
|
||||||
--app l4d2web.app:create_app create-user <username> --admin'`.
|
`sudo left4me create-user <username> --admin` (prompts for password via
|
||||||
The bundle deliberately doesn't seed an admin to keep credentials out
|
the flask CLI, or set `LEFT4ME_ADMIN_PASSWORD` first). The bundle
|
||||||
of the metadata pipeline.
|
deliberately doesn't seed an admin to keep credentials out of the
|
||||||
|
metadata pipeline. The same `left4me` wrapper accepts any other flask
|
||||||
|
subcommand: `sudo left4me seed-script-overlays <dir>`,
|
||||||
|
`sudo left4me routes`, `sudo left4me shell`, etc.
|
||||||
- **CPU isolation drop-ins are not managed by this bundle.** The
|
- **CPU isolation drop-ins are not managed by this bundle.** The
|
||||||
upstream shell deploy generated `/etc/systemd/system/system.slice.d/
|
upstream shell deploy generated `/etc/systemd/system/system.slice.d/
|
||||||
99-left4me-cpuset.conf` (and siblings for user/build/game slices)
|
99-left4me-cpuset.conf` (and siblings for user/build/game slices)
|
||||||
|
|
|
||||||
17
bundles/left4me/files/usr/local/sbin/left4me
Normal file
17
bundles/left4me/files/usr/local/sbin/left4me
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Run l4d2web flask CLI commands as the left4me user with the deploy env loaded.
|
||||||
|
# Usage: left4me <flask-subcommand> [args...]
|
||||||
|
# Examples:
|
||||||
|
# left4me create-user alice --admin
|
||||||
|
# left4me seed-script-overlays /opt/left4me/src/examples/script-overlays
|
||||||
|
# left4me routes
|
||||||
|
set -eu
|
||||||
|
exec sudo -u left4me sh -c '
|
||||||
|
set -a
|
||||||
|
. /etc/left4me/host.env
|
||||||
|
. /etc/left4me/web.env
|
||||||
|
set +a
|
||||||
|
export JOB_WORKER_ENABLED=false
|
||||||
|
export PYTHONPATH=/opt/left4me/src
|
||||||
|
exec /opt/left4me/.venv/bin/flask --app l4d2web.app:create_app "$@"
|
||||||
|
' sh "$@"
|
||||||
|
|
@ -68,6 +68,11 @@ HELPERS = (
|
||||||
)
|
)
|
||||||
|
|
||||||
files = {
|
files = {
|
||||||
|
'/usr/local/sbin/left4me': {
|
||||||
|
'mode': '0755',
|
||||||
|
'owner': 'root',
|
||||||
|
'group': 'root',
|
||||||
|
},
|
||||||
**{
|
**{
|
||||||
f'/usr/local/libexec/left4me/{h}': {
|
f'/usr/local/libexec/left4me/{h}': {
|
||||||
'source': f'usr/local/libexec/left4me/{h}',
|
'source': f'usr/local/libexec/left4me/{h}',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue