Update documentation and features

This commit is contained in:
shuki
2026-03-07 17:08:49 +02:00
parent 821ae26d7f
commit 51f5abe21f
2 changed files with 125 additions and 12 deletions

View File

@@ -23,6 +23,7 @@ Complete reference for gniza, a Linux backup manager that works as a stand-alone
- [CLI Reference](#cli-reference) - [CLI Reference](#cli-reference)
- [Global Settings](#global-settings) - [Global Settings](#global-settings)
- [Security](#security) - [Security](#security)
- [Development](#development)
- [Troubleshooting](#troubleshooting) - [Troubleshooting](#troubleshooting)
--- ---
@@ -647,9 +648,19 @@ gniza --cli schedule remove
Cron entries are tagged with `# gniza4linux:<name>` for clean management. Running `schedule install` replaces existing entries cleanly. Cron entries are tagged with `# gniza4linux:<name>` for clean management. Running `schedule install` replaces existing entries cleanly.
### How Scheduled Backups Run
Each cron entry calls `gniza scheduled-run --schedule=<name>`. This internal command:
1. Reads the schedule config to determine which sources and destinations to back up.
2. Runs the backup (same as `gniza --cli backup`).
3. On success, stamps `LAST_RUN="YYYY-MM-DD HH:MM"` in the schedule config file.
The `LAST_RUN` timestamp is displayed in the Schedules screen of the TUI.
### Cron Logs ### Cron Logs
Scheduled backups log output to `<log_dir>/cron.log`. Scheduled backups log output to `<log_dir>/cron.log`. Each run also creates a timestamped log file in the log directory (using local time).
--- ---
@@ -750,6 +761,19 @@ Notification emails include:
- Log file path - Log file path
- Hostname and timestamp - Hostname and timestamp
### Test Email
Verify your SMTP settings by sending a test email:
**TUI**: Settings > Send Test Email (automatically saves settings first).
**CLI**:
```bash
gniza --cli test-email
```
Requires `NOTIFY_EMAIL` and `SMTP_HOST` to be configured.
### Fallback ### Fallback
If SMTP is not configured, gniza falls back to the system `mail` or `sendmail` command. If SMTP is not configured, gniza falls back to the system `mail` or `sendmail` command.
@@ -783,16 +807,32 @@ gniza web start --port=8080 # Custom port
gniza web start --host=127.0.0.1 # Bind to localhost only gniza web start --host=127.0.0.1 # Bind to localhost only
``` ```
### Authentication ### Configuration
Credentials are configured in `gniza.conf`: Web dashboard settings are in `gniza.conf`:
```ini ```ini
WEB_USER="admin" WEB_PORT="2323" # Dashboard port
WEB_API_KEY="generated-during-install" WEB_HOST="0.0.0.0" # Bind address (0.0.0.0 = all interfaces)
WEB_USER="admin" # HTTP Basic Auth username
WEB_API_KEY="generated-during-install" # HTTP Basic Auth password
``` ```
The API key is generated automatically during installation if you enable the web dashboard. You can change it manually. The API key is generated automatically during installation if you enable the web dashboard. You can change it in Settings or directly in `gniza.conf`.
After changing web settings, restart the service:
```bash
systemctl --user restart gniza-web.service # user mode
sudo systemctl restart gniza-web.service # root mode
```
### Mobile Access
The web dashboard works on mobile browsers. On small screens:
- Font size auto-adjusts to fit approximately 50 columns
- Button rows scroll horizontally
- The documentation panel hides automatically on narrow screens
- Touch scrolling is supported in all scrollable areas
### Root vs User Mode ### Root vs User Mode
@@ -814,10 +854,25 @@ Launch with `gniza` (no arguments). Requires Python 3 and Textual.
| **Backup** | Select sources and destinations, run backups | | **Backup** | Select sources and destinations, run backups |
| **Restore** | Browse snapshots, restore to original or custom location | | **Restore** | Browse snapshots, restore to original or custom location |
| **Running Tasks** | Monitor active jobs with live log output and progress | | **Running Tasks** | Monitor active jobs with live log output and progress |
| **Schedules** | Create and manage cron schedules | | **Schedules** | Create and manage cron schedules, view last run time |
| **Snapshots** | Browse stored snapshots | | **Snapshots** | Browse stored snapshots |
| **Logs** | View backup history with pagination | | **Logs** | View backup history with pagination |
| **Settings** | Configure global options | | **Settings** | Configure global options in organized sections |
### Navigation
Every screen has a **← Back** button in the top-left corner next to the screen title. Press `Escape` or click the button to return to the previous screen.
### Settings Screen
The Settings screen organizes options into four bordered sections:
| Section | Contents |
|---------|----------|
| **General** | Log level, log retention, retention count, bandwidth limit, disk threshold, rsync options |
| **Email Notifications** | Email address, notify mode, SMTP host/port/user/password/from/security, Send Test Email button |
| **SSH** | SSH timeout, SSH retries |
| **Web Dashboard** | Port, host, API key |
### Features ### Features
@@ -826,7 +881,7 @@ Launch with `gniza` (no arguments). Requires Python 3 and Textual.
- **Remote Folder Browser**: Browse SSH destination directories - **Remote Folder Browser**: Browse SSH destination directories
- **Connection Testing**: Test destination connectivity from the edit screen - **Connection Testing**: Test destination connectivity from the edit screen
- **Documentation Panel**: Inline help on wide screens, help modal on narrow ones - **Documentation Panel**: Inline help on wide screens, help modal on narrow ones
- **Responsive Layout**: Adapts to terminal width - **Responsive Layout**: Adapts to terminal width; button rows scroll horizontally on narrow screens
- **Job Manager**: Run backups/restores in background with live log streaming - **Job Manager**: Run backups/restores in background with live log streaming
### Keyboard Shortcuts ### Keyboard Shortcuts
@@ -912,6 +967,7 @@ gniza --cli retention --destination=NAME # One destination
gniza --cli schedule install # Install cron entries gniza --cli schedule install # Install cron entries
gniza --cli schedule show # Show current entries gniza --cli schedule show # Show current entries
gniza --cli schedule remove # Remove all entries gniza --cli schedule remove # Remove all entries
gniza scheduled-run --schedule=NAME # Run a schedule (used by cron)
``` ```
### Logs ### Logs
@@ -932,6 +988,12 @@ gniza web remove-service # Remove service
gniza web status # Check status gniza web status # Check status
``` ```
### Notifications
```bash
gniza --cli test-email # Send a test email
```
### System ### System
```bash ```bash
@@ -967,9 +1029,11 @@ All global settings are in `gniza.conf` in the config directory.
| Setting | Default | Description | | Setting | Default | Description |
|---------|---------|-------------| |---------|---------|-------------|
| `LOG_LEVEL` | `info` | `info` or `debug` | | `LOG_LEVEL` | `info` | `debug`, `info`, `warn`, or `error` |
| `LOG_RETAIN` | `90` | Days to keep log files | | `LOG_RETAIN` | `90` | Days to keep log files |
Log files are named using local time (e.g., `gniza-20260307-040001.log`) to match cron schedules which also run in local time.
### Notifications ### Notifications
| Setting | Default | Description | | Setting | Default | Description |
@@ -1019,6 +1083,23 @@ All global settings are in `gniza.conf` in the config directory.
--- ---
## Development
### Deploy Script
For developers, `scripts/deploy.sh` automates the deploy workflow:
```bash
bash scripts/deploy.sh "commit message"
```
This script:
1. Commits and pushes all changes to git
2. Syncs updated files to the local install directory (`~/.local/share/gniza`)
3. Restarts the web dashboard service if running
---
## Troubleshooting ## Troubleshooting
### Checking Logs ### Checking Logs
@@ -1048,11 +1129,11 @@ Create at least one destination in `<config_dir>/remotes.d/`.
**Backup aborted due to disk space** **Backup aborted due to disk space**
The destination disk usage exceeds the threshold. Free space or adjust `DISK_USAGE_THRESHOLD` in `gniza.conf`. The destination disk usage exceeds the threshold. Free space or adjust `DISK_USAGE_THRESHOLD` in `gniza.conf`.
**Cron not running** **Cron not running or using stale flags**
- Check that cron entries are installed: `gniza --cli schedule show` - Check that cron entries are installed: `gniza --cli schedule show`
- Verify the cron daemon is running: `systemctl status cron` - Verify the cron daemon is running: `systemctl status cron`
- Check cron logs: `<log_dir>/cron.log` - Check cron logs: `<log_dir>/cron.log`
- Re-install entries: `gniza --cli schedule install` - Re-install entries: `gniza --cli schedule install` (this regenerates all entries with current flags)
**rclone required** **rclone required**
S3 and Google Drive sources/destinations require rclone. Install from https://rclone.org/install/. S3 and Google Drive sources/destinations require rclone. Install from https://rclone.org/install/.

View File

@@ -213,3 +213,35 @@
{"timestamp": "2026-03-07 01:23:59.732166+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Registered documentation tools", "module": "server", "function": "_register_tools", "line": 65, "taskName": null} {"timestamp": "2026-03-07 01:23:59.732166+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Registered documentation tools", "module": "server", "function": "_register_tools", "line": 65, "taskName": null}
{"timestamp": "2026-03-07 01:23:59.732197+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Documentation search will be indexed on first use", "module": "server", "function": "__init__", "line": 41, "taskName": null} {"timestamp": "2026-03-07 01:23:59.732197+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Documentation search will be indexed on first use", "module": "server", "function": "__init__", "line": 41, "taskName": null}
{"timestamp": "2026-03-07 01:23:59.732219+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Textual MCP Server initialized", "module": "server", "function": "__init__", "line": 47, "taskName": null} {"timestamp": "2026-03-07 01:23:59.732219+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Textual MCP Server initialized", "module": "server", "function": "__init__", "line": 47, "taskName": null}
{"timestamp": "2026-03-07 14:46:21.277593+00:00", "level": "INFO", "logger": "textual_mcp.validation_tools", "message": "Registered validation tools: validate_tcss, validate_tcss_file, validate_inline_styles, check_selector", "module": "validation_tools", "function": "register_validation_tools", "line": 360, "taskName": null}
{"timestamp": "2026-03-07 14:46:21.277653+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Registered validation tools", "module": "server", "function": "_register_tools", "line": 53, "taskName": null}
{"timestamp": "2026-03-07 14:46:21.278141+00:00", "level": "INFO", "logger": "textual_mcp.analysis_tools", "message": "Registered analysis tools: analyze_selectors, extract_css_variables, detect_style_conflicts", "module": "analysis_tools", "function": "register_analysis_tools", "line": 99, "taskName": null}
{"timestamp": "2026-03-07 14:46:21.278173+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Registered analysis tools", "module": "server", "function": "_register_tools", "line": 56, "taskName": null}
{"timestamp": "2026-03-07 14:46:21.279706+00:00", "level": "INFO", "logger": "textual_mcp.widget_tools", "message": "Registered widget tools: generate_widget, list_widget_types, list_event_handlers, validate_widget_name", "module": "widget_tools", "function": "register_widget_tools", "line": 343, "taskName": null}
{"timestamp": "2026-03-07 14:46:21.279741+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Registered widget tools", "module": "server", "function": "_register_tools", "line": 59, "taskName": null}
{"timestamp": "2026-03-07 14:46:21.280789+00:00", "level": "INFO", "logger": "textual_mcp.layout_tools", "message": "Registered layout tools: generate_grid_layout", "module": "layout_tools", "function": "register_layout_tools", "line": 139, "taskName": null}
{"timestamp": "2026-03-07 14:46:21.280843+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Registered layout tools", "module": "server", "function": "_register_tools", "line": 62, "taskName": null}
{"timestamp": "2026-03-07 14:46:21.284105+00:00", "level": "INFO", "logger": "textual_mcp.documentation_tools", "message": "Registered documentation tools: search_textual_docs, index_textual_docs, search_textual_code_examples, get_css_property_info, list_css_properties", "module": "documentation_tools", "function": "register_documentation_tools", "line": 613, "taskName": null}
{"timestamp": "2026-03-07 14:46:21.284143+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Registered documentation tools", "module": "server", "function": "_register_tools", "line": 65, "taskName": null}
{"timestamp": "2026-03-07 14:46:26.899447+00:00", "level": "INFO", "logger": "faiss.loader", "message": "Loading faiss with AVX2 support.", "module": "loader", "function": "<module>", "line": 125, "taskName": null}
{"timestamp": "2026-03-07 14:46:26.918799+00:00", "level": "INFO", "logger": "faiss.loader", "message": "Successfully loaded faiss with AVX2 support.", "module": "loader", "function": "<module>", "line": 127, "taskName": null}
{"timestamp": "2026-03-07 14:46:26.921141+00:00", "level": "INFO", "logger": "faiss", "message": "Failed to load GPU Faiss: name 'GpuIndexIVFFlat' is not defined. Will not load constructor refs for GPU indexes. This is only an error if you're trying to use GPU Faiss.", "module": "__init__", "function": "<module>", "line": 174, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.175775+00:00", "level": "INFO", "logger": "textual_mcp.textual_docs_memory", "message": "Initialized VectorDB with embeddings: BAAI/bge-base-en-v1.5, persisting to: data/textual_docs.db", "module": "memory", "function": "__init__", "line": 45, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.175846+00:00", "level": "INFO", "logger": "textual_mcp.documentation_tools", "message": "Auto-indexing documentation on first use", "module": "documentation_tools", "function": "get_docs_memory", "line": 45, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.175887+00:00", "level": "WARNING", "logger": "textual_mcp.server", "message": "Failed to initialize documentation search: no running event loop", "module": "server", "function": "__init__", "line": 45, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.177468+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Textual MCP Server initialized", "module": "server", "function": "__init__", "line": 47, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.183325+00:00", "level": "INFO", "logger": "textual_mcp.validation_tools", "message": "Registered validation tools: validate_tcss, validate_tcss_file, validate_inline_styles, check_selector", "module": "validation_tools", "function": "register_validation_tools", "line": 360, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.183371+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Registered validation tools", "module": "server", "function": "_register_tools", "line": 53, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.183789+00:00", "level": "INFO", "logger": "textual_mcp.analysis_tools", "message": "Registered analysis tools: analyze_selectors, extract_css_variables, detect_style_conflicts", "module": "analysis_tools", "function": "register_analysis_tools", "line": 99, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.183823+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Registered analysis tools", "module": "server", "function": "_register_tools", "line": 56, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.185413+00:00", "level": "INFO", "logger": "textual_mcp.widget_tools", "message": "Registered widget tools: generate_widget, list_widget_types, list_event_handlers, validate_widget_name", "module": "widget_tools", "function": "register_widget_tools", "line": 343, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.185446+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Registered widget tools", "module": "server", "function": "_register_tools", "line": 59, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.186426+00:00", "level": "INFO", "logger": "textual_mcp.layout_tools", "message": "Registered layout tools: generate_grid_layout", "module": "layout_tools", "function": "register_layout_tools", "line": 139, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.186465+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Registered layout tools", "module": "server", "function": "_register_tools", "line": 62, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.189657+00:00", "level": "INFO", "logger": "textual_mcp.documentation_tools", "message": "Registered documentation tools: search_textual_docs, index_textual_docs, search_textual_code_examples, get_css_property_info, list_css_properties", "module": "documentation_tools", "function": "register_documentation_tools", "line": 613, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.189708+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Registered documentation tools", "module": "server", "function": "_register_tools", "line": 65, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.189753+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Documentation search will be indexed on first use", "module": "server", "function": "__init__", "line": 41, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.189784+00:00", "level": "INFO", "logger": "textual_mcp.server", "message": "Textual MCP Server initialized", "module": "server", "function": "__init__", "line": 47, "taskName": null}
{"timestamp": "2026-03-07 14:46:29.202417+00:00", "level": "INFO", "logger": "mcp.server.lowlevel.server", "message": "Processing request of type ListToolsRequest", "module": "server", "function": "_handle_request", "line": 625, "taskName": "mcp.server.lowlevel.server.Server._handle_message"}
{"timestamp": "2026-03-07 14:46:29.204064+00:00", "level": "INFO", "logger": "mcp.server.lowlevel.server", "message": "Processing request of type ListPromptsRequest", "module": "server", "function": "_handle_request", "line": 625, "taskName": "mcp.server.lowlevel.server.Server._handle_message"}
{"timestamp": "2026-03-07 14:46:29.204920+00:00", "level": "INFO", "logger": "mcp.server.lowlevel.server", "message": "Processing request of type ListResourcesRequest", "module": "server", "function": "_handle_request", "line": 625, "taskName": "mcp.server.lowlevel.server.Server._handle_message"}