An installer that had only ever met Arch

`deploy/lxc-install.sh` had never been executed -- there was no Proxmox host
to run it on, and PLAN.md said so rather than letting it read as tested. It
was reviewed and `bash -n` checked, which is not the same claim. Running it
for the first time found two Arch-isms in `install.sh`, the script it wraps,
and only a Debian machine could have found either.

`python -m venv` is the one that mattered. On Arch `python` is Python 3, so
the bare name had worked on the only machine this had ever run on. Debian has
no `python` at all unless somebody installed `python-is-python3`, and the LXC
bootstrap installs `python3` -- so the install aborted at the virtualenv step,
with the service user, the bind mount and the clone already in place. It is
`python3` now, which is right on both.

`--shell /usr/bin/nologin` is the one that did not. That is where Arch keeps
nologin and not where Debian does, but nothing ever invoked it: `sudo -u`
execs the command directly and systemd's `User=` never reads a shell. The
account worked while pointing at a file that was not there. `/usr/sbin/nologin`
is correct on Debian and resolves on Arch too, whose `/usr/sbin` is a symlink
to `bin`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-09 19:42:28 +02:00
parent 25aa208d04
commit 172d15514d
3 changed files with 32 additions and 3 deletions
+20
View File
@@ -16,6 +16,26 @@ for 1.0.0 have something to be assembled from.
## Unreleased ## Unreleased
## 1.0.3
Two Arch-isms in the installer, both of which only a Debian machine could find.
`deploy/lxc-install.sh` had never been executed — it was reviewed and
syntax-checked, which is not the same claim — and running it is what found them.
- Fixed: **`deploy/install.sh` could not create its virtualenv on Debian**, and
so `deploy/lxc-install.sh` could not finish. It called bare `python`, which is
Python 3 on Arch — the machine this was written and only ever run on — and
does not exist on Debian at all unless `python-is-python3` is installed. The
LXC bootstrap installs `python3`, so the install aborted at the virtualenv
step with the service user, the bind mount and the clone already made. It now
calls `python3`, which is right on both.
- Fixed: the service account was created with `--shell /usr/bin/nologin`, which
is where Arch keeps it and where Debian does not. Nothing invoked it — `sudo -u`
execs directly and systemd's `User=` never reads a shell — so the account
worked either way, but it was created pointing at a file that was not there.
Now `/usr/sbin/nologin`, which is correct on Debian and resolves on Arch too,
since Arch's `/usr/sbin` is a symlink to `bin`.
## 1.0.2 ## 1.0.2
- **The documentation moved to the [wiki](https://git.houmeres.sk/Houmeres/LLeMbas/wiki).** - **The documentation moved to the [wiki](https://git.houmeres.sk/Houmeres/LLeMbas/wiki).**
+11 -2
View File
@@ -95,9 +95,13 @@ fi
echo "== service user ==" echo "== service user =="
# --system: no ageing, no mail spool. Home under /home, not /var/lib, so the # --system: no ageing, no mail spool. Home under /home, not /var/lib, so the
# venv and database sit on the larger volume. # venv and database sit on the larger volume.
#
# `/usr/sbin/nologin` is Debian's path and works on both: Arch keeps `nologin`
# in /usr/bin, but its /usr/sbin is a symlink to bin, so the Debian spelling
# resolves there while the Arch one does not resolve on Debian at all.
if ! getent passwd "$SERVICE_USER" >/dev/null; then if ! getent passwd "$SERVICE_USER" >/dev/null; then
sudo useradd --system --create-home --home-dir "$HOME_DIR" \ sudo useradd --system --create-home --home-dir "$HOME_DIR" \
--shell /usr/bin/nologin --comment "LLeMbas" "$SERVICE_USER" --shell /usr/sbin/nologin --comment "LLeMbas" "$SERVICE_USER"
else else
echo " user $SERVICE_USER already exists" echo " user $SERVICE_USER already exists"
fi fi
@@ -120,8 +124,13 @@ else
fi fi
echo "== virtualenv ==" echo "== virtualenv =="
# `python3`, not `python`. On Arch -- the machine this was written on and the
# only one it had ever run on -- `python` is Python 3 and the bare name worked.
# On Debian it does not exist unless somebody installed `python-is-python3`, so
# the LXC bootstrap aborted here, after the service user, the bind mount and the
# clone were already in place. `python3` is correct on both.
if [[ ! -x "$VENV/bin/python" ]]; then if [[ ! -x "$VENV/bin/python" ]]; then
sudo -u "$SERVICE_USER" python -m venv "$VENV" sudo -u "$SERVICE_USER" python3 -m venv "$VENV"
fi fi
sudo -u "$SERVICE_USER" "$VENV/bin/pip" install --quiet --upgrade pip sudo -u "$SERVICE_USER" "$VENV/bin/pip" install --quiet --upgrade pip
# The extras a deployment gets. `search` because DuckDuckGo is the default web # The extras a deployment gets. `search` because DuckDuckGo is the default web
+1 -1
View File
@@ -1,3 +1,3 @@
"""LLeMbas - a Middle-earth themed web UI for OpenAI-compatible LLM endpoints.""" """LLeMbas - a Middle-earth themed web UI for OpenAI-compatible LLM endpoints."""
__version__ = "1.0.2" __version__ = "1.0.3"