mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-08-28 22:28:19 +00:00
docs: align service upgrade guidance with hardened layout
This commit is contained in:
@@ -109,7 +109,7 @@ sudo ./install-service.sh
|
||||
|
||||
2. Configure the bot:
|
||||
```bash
|
||||
sudo nano /opt/meshcore-bot/config.ini
|
||||
sudo nano /etc/meshcore-bot/config.ini
|
||||
```
|
||||
|
||||
3. Start the service:
|
||||
@@ -133,7 +133,9 @@ make deb
|
||||
sudo dpkg -i dist/meshcore-bot_*.deb
|
||||
```
|
||||
|
||||
The package installs the bot to `/opt/meshcore-bot/`, installs a systemd unit, and creates a `meshcore-bot` system user.
|
||||
The package installs root-owned code in `/opt/meshcore-bot/`, configuration in
|
||||
`/etc/meshcore-bot/`, mutable state in `/var/lib/meshcore-bot/`, logs in
|
||||
`/var/log/meshcore-bot/`, and creates a `meshcore-bot` system user.
|
||||
|
||||
### Docker Deployment
|
||||
For containerized deployment using Docker:
|
||||
|
||||
@@ -58,7 +58,7 @@ Run the bot as a system service on Linux:
|
||||
|
||||
```bash
|
||||
sudo ./install-service.sh
|
||||
sudo nano /opt/meshcore-bot/config.ini # configure
|
||||
sudo nano /etc/meshcore-bot/config.ini # configure
|
||||
sudo systemctl start meshcore-bot
|
||||
sudo systemctl status meshcore-bot
|
||||
```
|
||||
|
||||
@@ -5,10 +5,15 @@ This guide explains how to install the MeshCore Bot as a systemd service on Linu
|
||||
## Prerequisites
|
||||
|
||||
- Linux system with systemd
|
||||
- Python 3.7+ (Python 3.12+ recommended; on 3.11 the meshcore dependency has an f-string bug — the install script patches it automatically)
|
||||
- Python 3.10+
|
||||
- `rsync`
|
||||
- Root/sudo access
|
||||
- MeshCore-compatible device
|
||||
|
||||
You can install from a Debian package instead of the standalone script. See the
|
||||
[README](https://github.com/agessaman/meshcore-bot#debian-package-deb) for build
|
||||
instructions.
|
||||
|
||||
## Quick Installation
|
||||
|
||||
1. **Clone and navigate to the bot directory:**
|
||||
@@ -24,7 +29,7 @@ This guide explains how to install the MeshCore Bot as a systemd service on Linu
|
||||
|
||||
3. **Configure the bot:**
|
||||
```bash
|
||||
sudo nano /opt/meshcore-bot/config.ini
|
||||
sudo nano /etc/meshcore-bot/config.ini
|
||||
```
|
||||
|
||||
4. **Start the service:**
|
||||
@@ -37,40 +42,94 @@ This guide explains how to install the MeshCore Bot as a systemd service on Linu
|
||||
sudo systemctl status meshcore-bot
|
||||
```
|
||||
|
||||
## Upgrading
|
||||
|
||||
After updating the source checkout, run:
|
||||
|
||||
```bash
|
||||
sudo ./install-service.sh --upgrade
|
||||
```
|
||||
|
||||
The upgrader rebuilds the virtual environment, updates the service unit, and migrates
|
||||
legacy relative paths into the current service layout. It preserves the active
|
||||
configuration, database, logs, local plugins, and installed-only alternative command
|
||||
files. If an upgrade fails after stopping an active service, it makes one best-effort
|
||||
attempt to restart that service while preserving the original failure status.
|
||||
|
||||
Read the [upgrade guide](upgrade.md) before upgrading an existing installation.
|
||||
|
||||
## Manual Installation
|
||||
|
||||
If you prefer to install manually:
|
||||
|
||||
### 1. Create Service User
|
||||
|
||||
```bash
|
||||
sudo useradd --system --no-create-home --shell /bin/false meshcore
|
||||
```
|
||||
|
||||
### 2. Create Directories
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /opt/meshcore-bot
|
||||
sudo mkdir -p /var/log/meshcore-bot
|
||||
sudo install -d -o root -g root -m 0755 /opt/meshcore-bot
|
||||
sudo install -d -o meshcore -g meshcore -m 0700 /etc/meshcore-bot
|
||||
sudo install -d -o meshcore -g meshcore -m 0700 /var/lib/meshcore-bot
|
||||
sudo install -d -o meshcore -g meshcore -m 0750 /var/log/meshcore-bot
|
||||
```
|
||||
|
||||
### 3. Copy Bot Files
|
||||
|
||||
This manual copy sequence is for a clean installation. Use the supported upgrader
|
||||
above for an existing installation so installed-only alternative commands and runtime
|
||||
state are preserved.
|
||||
|
||||
```bash
|
||||
sudo cp -r . /opt/meshcore-bot/
|
||||
sudo chown -R meshcore:meshcore /opt/meshcore-bot
|
||||
sudo chown -R meshcore:meshcore /var/log/meshcore-bot
|
||||
sudo rsync -a --delete \
|
||||
--exclude=.git --exclude=venv --exclude=.venv \
|
||||
--exclude=config.ini --exclude=local/ \
|
||||
./ /opt/meshcore-bot/
|
||||
sudo chown -R root:root /opt/meshcore-bot
|
||||
sudo chmod -R go-w /opt/meshcore-bot
|
||||
```
|
||||
|
||||
### 4. Install Service File
|
||||
Keep custom plugins under `/var/lib/meshcore-bot/local/`; do not make the executable
|
||||
tree writable by the service account.
|
||||
|
||||
### 4. Create the Virtual Environment
|
||||
|
||||
```bash
|
||||
sudo cp meshcore-bot.service /etc/systemd/system/
|
||||
sudo python3 -m venv /opt/meshcore-bot/venv
|
||||
sudo /opt/meshcore-bot/venv/bin/pip install \
|
||||
-r /opt/meshcore-bot/requirements.txt
|
||||
```
|
||||
|
||||
### 5. Install Configuration
|
||||
|
||||
```bash
|
||||
sudo cp /opt/meshcore-bot/config.ini.example /etc/meshcore-bot/config.ini
|
||||
sudo chown meshcore:meshcore /etc/meshcore-bot/config.ini
|
||||
sudo chmod 0600 /etc/meshcore-bot/config.ini
|
||||
```
|
||||
|
||||
Set these paths in the active configuration:
|
||||
|
||||
```ini
|
||||
[Bot]
|
||||
db_path = /var/lib/meshcore-bot/meshcore_bot.db
|
||||
local_dir_path = /var/lib/meshcore-bot/local
|
||||
|
||||
[Logging]
|
||||
log_file = /var/log/meshcore-bot/meshcore_bot.log
|
||||
```
|
||||
|
||||
### 6. Install the Service File
|
||||
|
||||
```bash
|
||||
sudo cp /opt/meshcore-bot/meshcore-bot.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable meshcore-bot
|
||||
```
|
||||
|
||||
### 5. Install Dependencies
|
||||
```bash
|
||||
sudo pip3 install -r /opt/meshcore-bot/requirements.txt
|
||||
```
|
||||
|
||||
## Service Management
|
||||
|
||||
### Start/Stop/Restart
|
||||
@@ -105,10 +164,10 @@ sudo systemctl disable meshcore-bot # Don't start on boot
|
||||
|
||||
## Configuration
|
||||
|
||||
The bot configuration is located at `/opt/meshcore-bot/config.ini`. Edit it with:
|
||||
The active bot configuration is `/etc/meshcore-bot/config.ini`. Edit it with:
|
||||
|
||||
```bash
|
||||
sudo nano /opt/meshcore-bot/config.ini
|
||||
sudo nano /etc/meshcore-bot/config.ini
|
||||
```
|
||||
|
||||
After changing configuration, you can reload in place (no process restart):
|
||||
@@ -126,9 +185,11 @@ sudo systemctl restart meshcore-bot
|
||||
## Service Features
|
||||
|
||||
### Security
|
||||
|
||||
- Runs as dedicated `meshcore` user
|
||||
- No shell access for service user
|
||||
- Restricted file system access
|
||||
- Executable code and the virtual environment are root-owned
|
||||
- Only configuration, state, and log directories are service-writable
|
||||
- Resource limits (512MB RAM, 50% CPU)
|
||||
|
||||
### Reliability
|
||||
@@ -147,22 +208,21 @@ sudo systemctl restart meshcore-bot
|
||||
### Service Won't Start
|
||||
1. Check service status: `sudo systemctl status meshcore-bot`
|
||||
2. View logs: `sudo journalctl -u meshcore-bot -n 50`
|
||||
3. Check configuration: `sudo nano /opt/meshcore-bot/config.ini`
|
||||
4. Verify dependencies: `sudo pip3 list | grep meshcore`
|
||||
3. Check configuration: `sudo nano /etc/meshcore-bot/config.ini`
|
||||
4. Verify dependencies: `/opt/meshcore-bot/venv/bin/pip list | grep meshcore`
|
||||
|
||||
### SyntaxError: f-string: unmatched '[' (Python 3.11)
|
||||
If the bot fails on import with this error in `meshcore/commands/contact.py`, you are on Python 3.11 and the **meshcore** dependency uses an f-string that only works on Python 3.12+.
|
||||
### Dependency Import or Syntax Errors
|
||||
|
||||
**Options:**
|
||||
- **Recommended:** Use Python 3.12+ (create the venv with `python3.12` if available, then re-run `./install-service.sh --upgrade`).
|
||||
- **Or:** Re-run the install script so it can patch the installed package:
|
||||
`sudo ./install-service.sh --upgrade`
|
||||
The script detects Python 3.11 and patches the meshcore file in the venv.
|
||||
- **Manual patch:** Edit `/opt/meshcore-bot/venv/lib/python3.11/site-packages/meshcore/commands/contact.py`, find the line containing `contact["adv_name"]` inside the f-string, and change it to `contact['adv_name']` (single quotes around `adv_name`).
|
||||
Do not patch installed dependencies in place. Update the source checkout and rerun
|
||||
`sudo ./install-service.sh --upgrade` so the installer creates a fresh virtual
|
||||
environment from the current requirements.
|
||||
|
||||
### Permission Issues
|
||||
|
||||
1. Check file ownership: `ls -la /opt/meshcore-bot/`
|
||||
2. Fix permissions: `sudo chown -R meshcore:meshcore /opt/meshcore-bot`
|
||||
2. Confirm code is root-owned and not writable by `meshcore`.
|
||||
3. Confirm `/etc/meshcore-bot`, `/var/lib/meshcore-bot`, and
|
||||
`/var/log/meshcore-bot` are owned by `meshcore`.
|
||||
|
||||
### Connection Issues
|
||||
1. Verify device connection (serial port, BLE, etc.)
|
||||
@@ -186,9 +246,12 @@ sudo ./uninstall-service.sh
|
||||
This will:
|
||||
- Stop and disable the service
|
||||
- Remove systemd service file
|
||||
- Remove installation directory
|
||||
- Remove log directory
|
||||
- Remove service user
|
||||
- Optionally remove the installation and log directories
|
||||
- Optionally remove the service user
|
||||
|
||||
The current uninstaller preserves `/etc/meshcore-bot` and `/var/lib/meshcore-bot`.
|
||||
Back up and remove those directories separately if you want to erase all configuration
|
||||
and state.
|
||||
|
||||
## File Locations
|
||||
|
||||
@@ -196,8 +259,9 @@ This will:
|
||||
|-----------|----------|
|
||||
| Service file | `/etc/systemd/system/meshcore-bot.service` |
|
||||
| Bot files | `/opt/meshcore-bot/` |
|
||||
| Configuration | `/opt/meshcore-bot/config.ini` |
|
||||
| Logs | `/var/log/meshcore-bot/` (if configured) |
|
||||
| Configuration | `/etc/meshcore-bot/config.ini` |
|
||||
| Database and local plugins | `/var/lib/meshcore-bot/` |
|
||||
| Logs | `/var/log/meshcore-bot/` |
|
||||
| System logs | `journalctl -u meshcore-bot` |
|
||||
|
||||
## Advanced Configuration
|
||||
@@ -228,5 +292,5 @@ Environment=CUSTOM_VAR=value
|
||||
|
||||
For issues with the service installation:
|
||||
1. Check the logs: `sudo journalctl -u meshcore-bot -f`
|
||||
2. Verify configuration: `sudo nano /opt/meshcore-bot/config.ini`
|
||||
2. Verify configuration: `sudo nano /etc/meshcore-bot/config.ini`
|
||||
3. Test manually: `sudo -u meshcore python3 /opt/meshcore-bot/meshcore_bot.py`
|
||||
|
||||
@@ -2,6 +2,74 @@
|
||||
|
||||
This document describes changes that may affect users upgrading from previous versions.
|
||||
|
||||
## Upgrading from v0.9.3 to v0.9.4
|
||||
|
||||
### Service Layout and Ownership
|
||||
|
||||
The standalone installer and Debian package now keep executable code root-owned and
|
||||
separate mutable runtime data:
|
||||
|
||||
| Component | Linux | macOS |
|
||||
|-----------|-------|-------|
|
||||
| Code and virtual environment | `/opt/meshcore-bot` | `/usr/local/meshcore-bot` |
|
||||
| Configuration | `/etc/meshcore-bot/config.ini` | `/usr/local/etc/meshcore-bot/config.ini` |
|
||||
| Database and local plugins | `/var/lib/meshcore-bot` | `/usr/local/var/lib/meshcore-bot` |
|
||||
| Logs | `/var/log/meshcore-bot` | `/usr/local/var/log/meshcore-bot` |
|
||||
|
||||
Run `sudo ./install-service.sh --upgrade` from an updated source checkout. The
|
||||
installer requires Python 3.10+ and `rsync`. It stops an active service before the
|
||||
database migration, copies relative-path databases coherently, rewrites the migrated
|
||||
configuration, builds a fresh virtual environment, and restarts a service that was
|
||||
active before the upgrade.
|
||||
|
||||
Before upgrading, keep a separate backup of your configuration and database. The
|
||||
installer preserves:
|
||||
|
||||
- the active configuration and absolute custom paths;
|
||||
- relative-path databases, logs, and the `local/` plugin tree;
|
||||
- installed-only files under `modules/commands/alternatives/`.
|
||||
|
||||
Trusted source versions still replace shipped alternative commands. If the upgrade
|
||||
fails after stopping an active service, the installer attempts one best-effort restart
|
||||
and retains the original failure exit status. Inspect the reported error before
|
||||
retrying.
|
||||
|
||||
### Configuration Compatibility
|
||||
|
||||
v0.9.3 shipped configuration examples pass the v0.9.4 strict validator. Normal startup
|
||||
warns about unknown sections or keys without refusing to start. You can check a config
|
||||
before upgrading:
|
||||
|
||||
```bash
|
||||
python3 validate_config.py --config /path/to/config.ini --strict
|
||||
```
|
||||
|
||||
### Outbound HTTP and Feeds
|
||||
|
||||
Outbound HTTP now validates every resolved address and redirect. Private feed URLs
|
||||
remain disabled by default; set `allow_private_urls = true` only for intentional
|
||||
private-network feeds. Cloud metadata and non-unicast destinations remain blocked.
|
||||
Feed responses are bounded by `max_response_bytes` and `max_parsed_items`.
|
||||
|
||||
### Optional Geocoding Data
|
||||
|
||||
`pycountry` and `us` remain optional under the `geo` extra. Install them for improved
|
||||
country and US-state normalization:
|
||||
|
||||
```bash
|
||||
pip install -e ".[geo]"
|
||||
```
|
||||
|
||||
The standalone installer also offers the geocoding extras interactively.
|
||||
|
||||
## Upgrading from v0.8 to v0.9
|
||||
|
||||
- Python 3.10+ is required.
|
||||
- The global `[Aliases]` section was replaced by per-command `aliases =` keys.
|
||||
- Database migrations run automatically at startup.
|
||||
- Review web-viewer authentication before binding beyond localhost.
|
||||
- Connection and radio settings still require a process restart after changes.
|
||||
|
||||
## Upgrading from v0.7
|
||||
|
||||
### Config Compatibility
|
||||
|
||||
@@ -67,6 +67,26 @@ def test_standalone_installer_separates_code_and_private_state():
|
||||
assert "Previously active service was restarted after the failed upgrade" in installer
|
||||
|
||||
|
||||
def test_service_documentation_matches_hardened_layout() -> None:
|
||||
readme = (REPO_ROOT / "README.md").read_text(encoding="utf-8")
|
||||
getting_started = (REPO_ROOT / "docs/getting-started.md").read_text(encoding="utf-8")
|
||||
service_docs = (REPO_ROOT / "docs/service-installation.md").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
upgrade_docs = (REPO_ROOT / "docs/upgrade.md").read_text(encoding="utf-8")
|
||||
|
||||
for text in (readme, getting_started, service_docs):
|
||||
assert "sudo nano /opt/meshcore-bot/config.ini" not in text
|
||||
assert "sudo nano /etc/meshcore-bot/config.ini" in text
|
||||
|
||||
assert "Python 3.10+" in service_docs
|
||||
assert "`rsync`" in service_docs
|
||||
assert "sudo chown -R meshcore:meshcore /opt/meshcore-bot" not in service_docs
|
||||
assert "patches the meshcore file" not in service_docs
|
||||
assert "/var/lib/meshcore-bot" in service_docs
|
||||
assert "Upgrading from v0.9.3 to v0.9.4" in upgrade_docs
|
||||
|
||||
|
||||
def test_service_sync_preserves_only_installed_only_alternatives(tmp_path: Path) -> None:
|
||||
source = tmp_path / "source"
|
||||
installed = tmp_path / "installed"
|
||||
|
||||
Reference in New Issue
Block a user