Fix install.sh failing on offline Raspberry Pi at the venv step
install.sh ran 'pip install .', which builds the project: pip downloads
setuptools into an isolated build environment. With no internet it fails at
the 'Building the virtual environment' step with
Could not find a version that satisfies the requirement setuptools>=68
(from versions: none)
even though the runtime libraries are already in the wheel directory. The
build backend is only needed to package, never to run.
- Install the runtime deps straight from the bundled wheels with --no-index,
and put src/ on the path via a .pth file, so no build step happens at all.
- Generate the console script with the venv's interpreter as an absolute
shebang. '#\!/usr/bin/env python3' resolves to the *system* python when the
venv is not activated, so the package was not importable from the unit.
- apt-get update/install and 'pip install --upgrade pip' are now best-effort:
all three need the network and none should abort the install.
- Detect a failed 'python3 -m venv' and name python3-venv as the usual cause.
- Sanity-check the install with --version before enabling the service.
- The unit falls back to 'python -m rdm_card_reader' if the console script is
ever absent (no shell in ExecStart, so the installer picks the path).
Reproduced the failure offline, then verified the fix offline as well: a venv
created on a copy of the tree self-provisions from the bundled wheels and runs
from cwd=/ with no PYTHONPATH and no venv activation.
Added tests/test_deploy.py (20 tests) covering the installer and the deploy
artifacts, including a regression test for 'pip install .' that was confirmed
to fail when the bug is reintroduced.
This commit is contained in:
@@ -53,18 +53,45 @@ without its library is worse than one that refuses to start.
|
||||
|
||||
## Install
|
||||
|
||||
On a machine **with internet**:
|
||||
|
||||
```bash
|
||||
pip install .
|
||||
```
|
||||
|
||||
On a Raspberry Pi OS install with an externally-managed Python, add
|
||||
`--break-system-packages` or use a virtual environment:
|
||||
`rdm6300` and `pyserial` are pulled in automatically. On Raspberry Pi OS with
|
||||
an externally-managed Python, add `--break-system-packages` or use a venv:
|
||||
|
||||
```bash
|
||||
python3 -m venv .venv && . .venv/bin/activate && pip install .
|
||||
```
|
||||
|
||||
`rdm6300` and `pyserial` are pulled in automatically.
|
||||
### On a device with no internet
|
||||
|
||||
`pip install .` will **not** work offline. It builds the project, which makes
|
||||
pip download `setuptools` into an isolated build environment, and that fails
|
||||
with:
|
||||
|
||||
```
|
||||
ERROR: Could not find a version that satisfies the requirement setuptools>=68
|
||||
(from versions: none)
|
||||
```
|
||||
|
||||
The runtime dependencies are bundled in `src/rdm_card_reader/wheels/`, so
|
||||
install those directly and put `src` on the path — no build step, no network:
|
||||
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
.venv/bin/pip install --no-index \
|
||||
--find-links src/rdm_card_reader/wheels rdm6300 pyserial
|
||||
echo "$PWD/src" > "$( .venv/bin/python -c \
|
||||
'import sysconfig; print(sysconfig.get_paths()["purelib"])' )/rdm_card_reader_src.pth"
|
||||
.venv/bin/python -m rdm_card_reader --demo # verify, no hardware needed
|
||||
```
|
||||
|
||||
`deploy/install.sh` does exactly this, plus the service setup. Running the
|
||||
app directly also works: it installs anything missing from the same bundled
|
||||
wheels on first start.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user