feat: add pos system nfs-server and nfs-client (systemd persistent mounts)
This commit is contained in:
@@ -10,19 +10,19 @@
|
||||
|
||||
<!-- GEN:START docmap -->
|
||||
| ## 1. Project Overview | 28–43 |
|
||||
| ## 2. Directory Structure | 44–165 |
|
||||
| ## 3. Installation Flow | 166–217 |
|
||||
| ## 4. The `pos` CLI System | 218–275 |
|
||||
| ## 5. Shared Library — `lib/common.sh` | 276–306 |
|
||||
| ## 6. Docker Compose / ScaleTail | 307–349 |
|
||||
| ## 7. Optional Apps (`apps/`) | 350–379 |
|
||||
| ## 8. Entertainment Module | 380–393 |
|
||||
| ## 9. Systemd Services | 394–404 |
|
||||
| ## 10. Configuration Files | 405–428 |
|
||||
| ## 11. Coding Conventions | 429–461 |
|
||||
| ## 12. Development Workflow | 462–513 |
|
||||
| ## 13. Key File Quick Reference | 514–556 |
|
||||
| ## 14. Common Tasks for Agents | 557–581 |
|
||||
| ## 2. Directory Structure | 44–167 |
|
||||
| ## 3. Installation Flow | 168–219 |
|
||||
| ## 4. The `pos` CLI System | 220–279 |
|
||||
| ## 5. Shared Library — `lib/common.sh` | 280–310 |
|
||||
| ## 6. Docker Compose / ScaleTail | 311–353 |
|
||||
| ## 7. Optional Apps (`apps/`) | 354–383 |
|
||||
| ## 8. Entertainment Module | 384–397 |
|
||||
| ## 9. Systemd Services | 398–408 |
|
||||
| ## 10. Configuration Files | 409–432 |
|
||||
| ## 11. Coding Conventions | 433–465 |
|
||||
| ## 12. Development Workflow | 466–517 |
|
||||
| ## 13. Key File Quick Reference | 518–562 |
|
||||
| ## 14. Common Tasks for Agents | 563–587 |
|
||||
<!-- GEN:END docmap -->
|
||||
|
||||
## 1. Project Overview
|
||||
@@ -77,6 +77,8 @@ Linux_post_install/
|
||||
│ ├── pos-system-backup # Encrypted (AES-256) folder snapshots (tar + gpg)
|
||||
│ ├── pos-system-firewall # Interactive UFW management
|
||||
│ ├── pos-system-health # Host health dashboard (disk, RAM, services, backup age, fail2ban, docker); exit 1 if any FAIL
|
||||
│ ├── pos-system-nfs-client # Mount NFS shares (ephemeral or persistent systemd mount units)
|
||||
│ ├── pos-system-nfs-server # Manage the NFS kernel server (status, share/unshare exports, enable/disable)
|
||||
│ ├── pos-usb-server # USB Redirector server control (--ls, --share; prompts when args omitted)
|
||||
<!-- GEN:END tree -->
|
||||
│ ├── flag-reader # Inspect feature flags (list/status/--raw)
|
||||
@@ -254,6 +256,8 @@ All non-interactive `pos` commands log output to `~/.local/share/linux_post_inst
|
||||
| system | backup | `pos-system-backup` | Encrypted (AES-256) folder snapshots (tar + gpg) |
|
||||
| system | firewall | `pos-system-firewall` | Interactive UFW management |
|
||||
| system | health | `pos-system-health` | Host health dashboard (disk, RAM, services, backup age, fail2ban, docker); exit 1 if any FAIL |
|
||||
| system | nfs-client | `pos-system-nfs-client` | Mount NFS shares (ephemeral or persistent systemd mount units) |
|
||||
| system | nfs-server | `pos-system-nfs-server` | Manage the NFS kernel server (status, share/unshare exports, enable/disable) |
|
||||
| usb | server | `pos-usb-server` | USB Redirector server control (--ls, --share; prompts when args omitted) |
|
||||
<!-- GEN:END dispatch -->
|
||||
|
||||
@@ -526,7 +530,7 @@ Use conventional prefixes: `feat:`, `fix:`, `docs:`, `refactor:`, `chore:`
|
||||
| `bin/flag-clear` | 21 | Unset a flag |
|
||||
| `features/autostart.sh` | 14 | Boot-time feature (moved from `bin/`, flag-gated service) |
|
||||
<!-- GEN:START filetable -->
|
||||
| `bin/pos` | 213 | CLI dispatcher with smart arg matching + logging + category help |
|
||||
| `bin/pos` | 216 | CLI dispatcher with smart arg matching + logging + category help |
|
||||
| `bin/pos-communication-telegram` | 274 | Send Telegram messages/files/links/stickers via Bot API (send, test, config set) |
|
||||
| `bin/pos-docker-compose` | 364 | Docker Compose service manager (ls/up/down/restart/logs/update/config) |
|
||||
| `bin/pos-docker-health` | 110 | One-glance container health dashboard (exits 1 if unhealthy) |
|
||||
@@ -547,6 +551,8 @@ Use conventional prefixes: `feat:`, `fix:`, `docs:`, `refactor:`, `chore:`
|
||||
| `bin/pos-system-backup` | 125 | Encrypted (AES-256) folder snapshots (tar + gpg) |
|
||||
| `bin/pos-system-firewall` | 291 | Interactive UFW management |
|
||||
| `bin/pos-system-health` | 243 | Host health dashboard (disk, RAM, services, backup age, fail2ban, docker); exit 1 if any FAIL |
|
||||
| `bin/pos-system-nfs-client` | 138 | Mount NFS shares (ephemeral or persistent systemd mount units) |
|
||||
| `bin/pos-system-nfs-server` | 134 | Manage the NFS kernel server (status, share/unshare exports, enable/disable) |
|
||||
| `bin/pos-usb-server` | 218 | USB Redirector server control (--ls, --share; prompts when args omitted) |
|
||||
| `completions/pos.bash` | 189 | Dynamic bash completion |
|
||||
<!-- GEN:END filetable -->
|
||||
|
||||
@@ -155,6 +155,8 @@ The standalone `vbox` command still works and forwards to `pos docker vbox` (see
|
||||
| `pos system backup <folder-path>` | `bin/pos-system-backup` | Create a gpg-encrypted (AES-256) `tar.gz` snapshot of a folder and verify it | Prompts twice for a password (never stored). Uses `sudo tar`; needs `gnupg` (in `preinstall.sh` PACKAGES). Artifact `<name>_<date>.tar.gz.gpg` in the current directory, `chmod 600`. Success/failure are announced via `lib/notify.sh` |
|
||||
| `pos system backup --service` | `bin/pos-system-backup` | Lists folders under `/srv` and `~/srv`, lets you pick one, then runs the same backup | Roots via `BACKUP_SERVICE_ROOTS` (space-separated, default `/srv $HOME/srv`) or `~/.config/linux_post_install/system.env` |
|
||||
| `pos system health [--send] [--markdown]` | `bin/pos-system-health` | Host health dashboard: disk per mount, RAM/swap, failed systemd units, backup age, fail2ban, docker containers. Exits 1 if any check FAILs | `--send`/`--markdown` send the summary via `lib/notify.sh` to every platform in `NOTIFY_PLATFORM`. `HEALTH_BACKUP_MAX_AGE_DAYS` (default 2) and `BACKUP_SERVICE_ROOTS` come from `~/.config/linux_post_install/system.env`; `--help` shows the effective values. Platform list from `~/.config/linux_post_install/notify.env` |
|
||||
| `pos system nfs-server <cmd>` | `bin/pos-system-nfs-server` | Manage the NFS kernel server: `status`, `share <path> [client]`, `unshare <path>`, `list`, `reload`, `enable`, `disable` | Requires `nfs-kernel-server` (added to `preinstall.sh` PACKAGES). Exports live in `/etc/exports`; `share` is idempotent (replaces any existing line for the path) and runs `exportfs -ra`. Default client `*(rw,sync,no_subtree_check)` — the tool warns you to restrict it; help prints Tailscale CGNAT (`100.64.0.0/10`), WireGuard (`10.10.0.0/24`) and LAN examples. Mutating commands announce via `lib/notify.sh` |
|
||||
| `pos system nfs-client <cmd>` | `bin/pos-system-nfs-client` | Mount and manage NFS shares: `mount <server:export> <local-dir>`, `unmount <local-dir>`, `list`, `persist <server:export> <local-dir>`, `unpersist <local-dir>` | Requires `nfs-common` (added to `preinstall.sh` PACKAGES). `persist` writes a systemd `.mount` unit (`systemd-escape --path --suffix=mount`) with `After=network-online.target` / `Wants=network-online.target` — mounts only once all interfaces are up, no fstab edits to break boot — then `daemon-reload` + `enable --now`. `unpersist` stops/disables/removes the unit. `mount`/`persist` announce via `lib/notify.sh` |
|
||||
|
||||
`systemd/pos-health.service` + `systemd/pos-health.timer` run `pos system health --send --markdown` daily at 08:00 as the installing user. `postinstall.sh` enables the timer automatically once `~/.config/linux_post_install/telegram.env` exists — re-run postinstall after configuring a notify platform to pick it up. The service also loads `system.env` + `notify.env` via `EnvironmentFile=`.
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ Host care: encrypted backups, firewall, and the health dashboard. Tools:
|
||||
| `pos system health` | Host health dashboard (disk, RAM, services, backup age, fail2ban, docker) |
|
||||
| `pos system backup` | gpg-encrypted (AES-256) folder snapshots |
|
||||
| `pos system firewall` | Interactive UFW ("UFW POWER") management |
|
||||
| `pos system nfs-server` | Manage the NFS kernel server (exports, enable/disable) |
|
||||
| `pos system nfs-client` | Mount NFS shares (ephemeral or persistent systemd units) |
|
||||
|
||||
---
|
||||
|
||||
@@ -143,6 +145,90 @@ not).
|
||||
|
||||
---
|
||||
|
||||
## `pos system nfs-server` — NFS kernel server
|
||||
|
||||
Requires `nfs-kernel-server` (in `preinstall.sh` PACKAGES). Writes to
|
||||
`/etc/exports` and reloads via `exportfs -ra`; mutating commands announce via
|
||||
`notify_send`.
|
||||
|
||||
```bash
|
||||
pos system nfs-server status # server active? + current exports
|
||||
pos system nfs-server share /mnt/hdd # export (generic, warns)
|
||||
pos system nfs-server share /mnt/hdd '100.64.0.0/10(rw,sync,no_subtree_check)'
|
||||
pos system nfs-server list # exportfs -v
|
||||
pos system nfs-server unshare /mnt/hdd # remove the export
|
||||
pos system nfs-server reload # re-apply /etc/exports after hand edits
|
||||
pos system nfs-server enable # start + boot-persist the server
|
||||
pos system nfs-server disable
|
||||
```
|
||||
|
||||
`share <path> [client]` is idempotent: an existing line for the same path is
|
||||
replaced. With no client it uses `*(rw,sync,no_subtree_check)` and **warns you
|
||||
to restrict it** — print the restricted form:
|
||||
|
||||
- Tailscale (CGNAT): `pos system nfs-server share /mnt/hdd '100.64.0.0/10(rw,sync,no_subtree_check)'`
|
||||
- WireGuard: `pos system nfs-server share /mnt/hdd '10.10.0.0/24(rw,sync,no_subtree_check)'`
|
||||
- LAN: `pos system nfs-server share /mnt/backups '192.168.1.0/24(ro,sync,no_subtree_check)'`
|
||||
|
||||
**Recipes:**
|
||||
- **Share the media drive to the tailnet:**
|
||||
```bash
|
||||
pos system nfs-server share /mnt/hdd '100.64.0.0/10(rw,sync,no_subtree_check)'
|
||||
pos system nfs-server enable
|
||||
```
|
||||
- **Read-only backups to a LAN host:** use `(ro,sync,no_subtree_check)` and only
|
||||
`enable` the server where it's needed.
|
||||
|
||||
**Troubleshooting:**
|
||||
- "exportfs not found" → `nfs-kernel-server` isn't installed; `sudo apt install nfs-kernel-server`
|
||||
- Client sees "mount.nfs: Permission denied" → your `/etc/exports` client rule
|
||||
doesn't cover the client's IP (check with `pos system nfs-server list`); use
|
||||
`showmount -e <server>` on the client to see what's exported
|
||||
- After editing `/etc/exports` by hand, run `pos system nfs-server reload`
|
||||
- NFS is blocked → allow the ports in `pos system firewall` (or `ufw`)
|
||||
- Changes to `/etc/exports` are root-required → the tool uses `sudo`
|
||||
|
||||
---
|
||||
|
||||
## `pos system nfs-client` — mount NFS shares
|
||||
|
||||
Requires `nfs-common` (in `preinstall.sh` PACKAGES).
|
||||
|
||||
```bash
|
||||
pos system nfs-client mount <server:export> <local-dir> # one-shot (mkdir -p first)
|
||||
pos system nfs-client persist <server:export> <local-dir> # persistent systemd mount
|
||||
pos system nfs-client list # active NFS mounts
|
||||
pos system nfs-client unmount <local-dir>
|
||||
pos system nfs-client unpersist <local-dir> # remove the systemd unit
|
||||
```
|
||||
|
||||
**Persistent mounts use systemd, not fstab.** `persist` writes a
|
||||
`/etc/systemd/system/<mnt-nfs-name>.mount` unit ordered after
|
||||
`network-online.target`, so the share is mounted only once all interfaces are
|
||||
up — a down/unreachable NFS server can't break boot (with fstab it could).
|
||||
`enable --now` mounts it immediately too.
|
||||
|
||||
**Recipes:**
|
||||
- **Mount the server's media share and keep it across reboots:**
|
||||
```bash
|
||||
pos system nfs-client persist 100.100.100.1:/mnt/hdd /mnt/nfs/media
|
||||
pos system nfs-client list
|
||||
```
|
||||
- **One-off mount (no persistence):**
|
||||
`pos system nfs-client mount 10.0.0.5:/srv/data /mnt/data`
|
||||
|
||||
**Troubleshooting:**
|
||||
- "mount.nfs not found" → `nfs-common` isn't installed; `sudo apt install nfs-common`
|
||||
- Mount hangs → check the server export (`pos system nfs-server list` on the
|
||||
server) and that the client IP is allowed; `showmount -e <server>` lists
|
||||
exports; NFS timeouts take ~2min by default, add `timeo=50,retrans=2` via the
|
||||
unit if needed
|
||||
- Persistent mount fails at boot when the server is off → intended: the unit
|
||||
waits for network-online and fails cleanly, and boot continues (unlike fstab);
|
||||
`pos system nfs-client unpersist` removes it
|
||||
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
- Reference: [DOC/POS.md → system](../POS.md)
|
||||
|
||||
Reference in New Issue
Block a user