Update CLI help and show commands with Source/Destination terminology

Reorganize help into categorized sections, add all fields to
targets show (source type, SSH/S3/GDrive details, MySQL) and
remotes show (type-specific fields, disk info).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
shuki
2026-03-07 04:57:39 +02:00
parent 8e8d367233
commit 3ba8c6b715

210
bin/gniza
View File

@@ -41,18 +41,53 @@ Options:
--help Show this help --help Show this help
--version Show version --version Show version
Commands: Sources (what to back up):
targets list List all configured sources
targets add --name=NAME --folders=PATHS
Create a new source
targets delete --name=NAME Delete a source
targets show --name=NAME Show source configuration
Destinations (where to store backups):
remotes list List all configured destinations
remotes add --name=NAME Create a new destination
remotes delete --name=NAME Delete a destination
remotes show --name=NAME Show destination configuration
remotes test --name=NAME Validate destination connectivity
remotes disk-info-short --name=NAME Show destination disk usage
Operations:
backup [--target=NAME] [--remote=NAME] [--all] backup [--target=NAME] [--remote=NAME] [--all]
restore --target=NAME [--snapshot=TS] [--remote=NAME] [--dest=DIR] [--folder=PATH] Run backup (all sources if none specified)
targets list|add|delete|show [--name=NAME] [--folders=PATHS] restore --target=NAME --snapshot=TS [--remote=NAME] [--dest=DIR]
remotes list|add|delete|show|test [--name=NAME] [--folder=PATH] [--skip-mysql]
snapshots list [--target=NAME] [--remote=NAME] Restore from a snapshot
retention [--target=NAME] [--remote=NAME] [--all] retention [--target=NAME] [--remote=NAME] [--all]
schedule install|show|remove Enforce snapshot retention policies
logs [--last] [--tail=N]
web start|install-service|remove-service|status [--port=PORT] [--host=HOST] Snapshots:
snapshots list [--target=NAME] [--remote=NAME]
List available snapshots
snapshots browse --target=NAME --snapshot=TS [--remote=NAME]
Browse snapshot contents
Scheduling:
schedule install Install cron entries for all schedules
schedule show Show current cron entries
schedule remove Remove all gniza cron entries
Logs & Info:
logs [--last] [--tail=N] View backup logs
version Show version
Web Dashboard:
web start [--port=PORT] [--host=HOST] Start web server
web install-service Install as systemd service
web remove-service Remove systemd service
web status Show service status
System:
uninstall Run the uninstall script uninstall Run the uninstall script
version
If no command is given, the TUI is launched. If no command is given, the TUI is launched.
EOF EOF
@@ -189,7 +224,7 @@ run_cli() {
if [[ -z "$remote" ]]; then if [[ -z "$remote" ]]; then
remote=$(list_remotes | head -1) remote=$(list_remotes | head -1)
[[ -z "$remote" ]] && die "No remotes configured" [[ -z "$remote" ]] && die "No destinations configured"
fi fi
if [[ -n "$folder" ]]; then if [[ -n "$folder" ]]; then
@@ -209,43 +244,77 @@ run_cli() {
list) list)
local targets; targets=$(list_targets) local targets; targets=$(list_targets)
if [[ -z "$targets" ]]; then if [[ -z "$targets" ]]; then
echo "No targets configured." echo "No sources configured."
else else
echo "$targets" echo "$targets"
fi fi
;; ;;
add) add)
[[ -z "$name" ]] && die "targets add requires --name=NAME" [[ -z "$name" ]] && die "sources add requires --name=NAME"
[[ -z "$folders" ]] && die "targets add requires --folders=PATHS" [[ -z "$folders" ]] && die "sources add requires --folders=PATHS"
create_target "$name" "$folders" create_target "$name" "$folders"
;; ;;
delete) delete)
[[ -z "$name" ]] && die "targets delete requires --name=NAME" [[ -z "$name" ]] && die "sources delete requires --name=NAME"
delete_target "$name" delete_target "$name"
;; ;;
show) show)
[[ -z "$name" ]] && die "targets show requires --name=NAME" [[ -z "$name" ]] && die "sources show requires --name=NAME"
load_target "$name" load_target "$name"
echo "TARGET_NAME=$TARGET_NAME" echo "=== Source: $TARGET_NAME ==="
echo "TARGET_FOLDERS=$TARGET_FOLDERS" echo ""
echo "TARGET_EXCLUDE=$TARGET_EXCLUDE" echo "Name: $TARGET_NAME"
echo "TARGET_REMOTE=$TARGET_REMOTE" echo "Enabled: $TARGET_ENABLED"
echo "TARGET_RETENTION=$TARGET_RETENTION" echo "Folders: $TARGET_FOLDERS"
echo "TARGET_PRE_HOOK=$TARGET_PRE_HOOK" echo "Exclude: ${TARGET_EXCLUDE:-(none)}"
echo "TARGET_POST_HOOK=$TARGET_POST_HOOK" echo "Include: ${TARGET_INCLUDE:-(none)}"
echo "TARGET_ENABLED=$TARGET_ENABLED" echo "Destination: ${TARGET_REMOTE:-(all)}"
echo "TARGET_MYSQL_ENABLED=$TARGET_MYSQL_ENABLED" echo "Retention: ${TARGET_RETENTION:-(default)}"
echo "TARGET_MYSQL_MODE=$TARGET_MYSQL_MODE" echo "Pre-hook: ${TARGET_PRE_HOOK:-(none)}"
echo "TARGET_MYSQL_DATABASES=$TARGET_MYSQL_DATABASES" echo "Post-hook: ${TARGET_POST_HOOK:-(none)}"
echo "TARGET_MYSQL_EXCLUDE=$TARGET_MYSQL_EXCLUDE" echo ""
echo "TARGET_MYSQL_USER=$TARGET_MYSQL_USER" echo "--- Source Type ---"
echo "TARGET_MYSQL_PASSWORD=****" echo "Type: $TARGET_SOURCE_TYPE"
echo "TARGET_MYSQL_HOST=$TARGET_MYSQL_HOST" case "$TARGET_SOURCE_TYPE" in
echo "TARGET_MYSQL_PORT=$TARGET_MYSQL_PORT" ssh)
echo "TARGET_MYSQL_EXTRA_OPTS=$TARGET_MYSQL_EXTRA_OPTS" echo "Host: $TARGET_SOURCE_HOST"
echo "Port: $TARGET_SOURCE_PORT"
echo "User: $TARGET_SOURCE_USER"
echo "Auth method: $TARGET_SOURCE_AUTH_METHOD"
if [[ "$TARGET_SOURCE_AUTH_METHOD" == "key" ]]; then
echo "Key: ${TARGET_SOURCE_KEY:-(default)}"
else
echo "Password: ****"
fi
;;
s3)
echo "Bucket: $TARGET_SOURCE_S3_BUCKET"
echo "Region: $TARGET_SOURCE_S3_REGION"
echo "Endpoint: ${TARGET_SOURCE_S3_ENDPOINT:-(default)}"
echo "Access Key: ${TARGET_SOURCE_S3_ACCESS_KEY_ID:+****}"
echo "Secret Key: ${TARGET_SOURCE_S3_SECRET_ACCESS_KEY:+****}"
;;
gdrive)
echo "SA File: $TARGET_SOURCE_GDRIVE_SERVICE_ACCOUNT_FILE"
echo "Root Folder ID: ${TARGET_SOURCE_GDRIVE_ROOT_FOLDER_ID:-(root)}"
;;
esac
if [[ "$TARGET_MYSQL_ENABLED" == "yes" ]]; then
echo ""
echo "--- MySQL ---"
echo "Enabled: yes"
echo "Mode: $TARGET_MYSQL_MODE"
echo "Databases: ${TARGET_MYSQL_DATABASES:-(all)}"
echo "Exclude: ${TARGET_MYSQL_EXCLUDE:-(none)}"
echo "User: ${TARGET_MYSQL_USER:-(current)}"
echo "Password: ${TARGET_MYSQL_PASSWORD:+****}"
echo "Host: $TARGET_MYSQL_HOST"
echo "Port: $TARGET_MYSQL_PORT"
echo "Extra opts: $TARGET_MYSQL_EXTRA_OPTS"
fi
;; ;;
*) *)
die "Unknown targets action: $action (expected list|add|delete|show)" die "Unknown sources action: $action (expected list|add|delete|show)"
;; ;;
esac esac
;; ;;
@@ -259,46 +328,73 @@ run_cli() {
list) list)
local remotes; remotes=$(list_remotes) local remotes; remotes=$(list_remotes)
if [[ -z "$remotes" ]]; then if [[ -z "$remotes" ]]; then
echo "No remotes configured." echo "No destinations configured."
else else
echo "$remotes" echo "$remotes"
fi fi
;; ;;
add) add)
[[ -z "$name" ]] && die "remotes add requires --name=NAME" [[ -z "$name" ]] && die "destinations add requires --name=NAME"
echo "Use the TUI or manually create $CONFIG_DIR/remotes.d/${name}.conf" echo "Use the TUI or manually create $CONFIG_DIR/remotes.d/${name}.conf to configure the destination."
;; ;;
delete) delete)
[[ -z "$name" ]] && die "remotes delete requires --name=NAME" [[ -z "$name" ]] && die "destinations delete requires --name=NAME"
local conf="$CONFIG_DIR/remotes.d/${name}.conf" local conf="$CONFIG_DIR/remotes.d/${name}.conf"
[[ ! -f "$conf" ]] && die "Remote config not found: $conf" [[ ! -f "$conf" ]] && die "Destination config not found: $conf"
rm -f "$conf" rm -f "$conf"
log_info "Deleted remote config: $conf" log_info "Deleted destination config: $conf"
;; ;;
show) show)
[[ -z "$name" ]] && die "remotes show requires --name=NAME" [[ -z "$name" ]] && die "destinations show requires --name=NAME"
load_remote "$name" load_remote "$name"
echo "REMOTE_TYPE=$REMOTE_TYPE" echo "=== Destination: $name ==="
echo "REMOTE_HOST=${REMOTE_HOST:-}" echo ""
echo "REMOTE_PORT=$REMOTE_PORT" echo "Type: $REMOTE_TYPE"
echo "REMOTE_USER=$REMOTE_USER" case "$REMOTE_TYPE" in
echo "REMOTE_AUTH_METHOD=$REMOTE_AUTH_METHOD" ssh)
echo "REMOTE_BASE=$REMOTE_BASE" echo "Host: $REMOTE_HOST"
echo "BWLIMIT=$BWLIMIT" echo "Port: $REMOTE_PORT"
echo "RETENTION_COUNT=$RETENTION_COUNT" echo "User: $REMOTE_USER"
echo "Auth method: $REMOTE_AUTH_METHOD"
if [[ "$REMOTE_AUTH_METHOD" == "key" ]]; then
echo "Key: ${REMOTE_KEY:-(default)}"
else
echo "Password: ****"
fi
echo "Base path: $REMOTE_BASE"
;;
local)
echo "Base path: $REMOTE_BASE"
;;
s3)
echo "Bucket: ${S3_BUCKET:-}"
echo "Region: ${S3_REGION:-}"
echo "Endpoint: ${S3_ENDPOINT:-(default)}"
echo "Access Key: ${S3_ACCESS_KEY_ID:+****}"
echo "Secret Key: ${S3_SECRET_ACCESS_KEY:+****}"
echo "Base path: $REMOTE_BASE"
;;
gdrive)
echo "SA File: ${GDRIVE_SERVICE_ACCOUNT_FILE:-}"
echo "Root Folder ID: ${GDRIVE_ROOT_FOLDER_ID:-(root)}"
echo "Base path: $REMOTE_BASE"
;;
esac
echo "Bandwidth: ${BWLIMIT:-0} KB/s"
echo "Retention: $RETENTION_COUNT snapshots"
;; ;;
test) test)
[[ -z "$name" ]] && die "remotes test requires --name=NAME" [[ -z "$name" ]] && die "destinations test requires --name=NAME"
validate_remote "$name" validate_remote "$name"
echo "Remote '$name' is valid." echo "Destination '$name' is valid."
;; ;;
disk-info-short) disk-info-short)
[[ -z "$name" ]] && die "remotes disk-info-short requires --name=NAME" [[ -z "$name" ]] && die "destinations disk-info-short requires --name=NAME"
load_remote "$name" load_remote "$name"
remote_disk_info_short remote_disk_info_short
;; ;;
*) *)
die "Unknown remotes action: $action (expected list|add|delete|show|test|disk-info-short)" die "Unknown destinations action: $action (expected list|add|delete|show|test|disk-info-short)"
;; ;;
esac esac
;; ;;
@@ -313,10 +409,10 @@ run_cli() {
list) list)
if [[ -z "$remote" ]]; then if [[ -z "$remote" ]]; then
remote=$(list_remotes | head -1) remote=$(list_remotes | head -1)
[[ -z "$remote" ]] && die "No remotes configured" [[ -z "$remote" ]] && die "No destinations configured"
fi fi
_save_remote_globals _save_remote_globals
load_remote "$remote" || die "Failed to load remote: $remote" load_remote "$remote" || die "Failed to load destination: $remote"
if [[ -n "$target" ]]; then if [[ -n "$target" ]]; then
list_remote_snapshots "$target" list_remote_snapshots "$target"
else else
@@ -336,7 +432,7 @@ run_cli() {
[[ -z "$snapshot" ]] && die "browse requires --snapshot=TS" [[ -z "$snapshot" ]] && die "browse requires --snapshot=TS"
if [[ -z "$remote" ]]; then if [[ -z "$remote" ]]; then
remote=$(list_remotes | head -1) remote=$(list_remotes | head -1)
[[ -z "$remote" ]] && die "No remotes configured" [[ -z "$remote" ]] && die "No destinations configured"
fi fi
list_snapshot_contents "$target" "$snapshot" "$remote" list_snapshot_contents "$target" "$snapshot" "$remote"
;; ;;
@@ -354,10 +450,10 @@ run_cli() {
if [[ -z "$remote" ]]; then if [[ -z "$remote" ]]; then
remote=$(list_remotes | head -1) remote=$(list_remotes | head -1)
[[ -z "$remote" ]] && die "No remotes configured" [[ -z "$remote" ]] && die "No destinations configured"
fi fi
_save_remote_globals _save_remote_globals
load_remote "$remote" || die "Failed to load remote: $remote" load_remote "$remote" || die "Failed to load destination: $remote"
if [[ "$all" == "true" || -z "$target" ]]; then if [[ "$all" == "true" || -z "$target" ]]; then
local targets; targets=$(list_targets) local targets; targets=$(list_targets)