9a94329dd0
- bin/pos-system-health: host dashboard (disk, RAM, failed units, backup age,
fail2ban, docker); exits 1 on any FAIL; --send/--markdown via Telegram
- lib/notify.sh: self-contained opt-in alerting helper; silent-fails, wired
into pos-system-backup (success + ERR trap) and pos-system-firewall
- systemd/pos-health.{service,timer}: 08:00 digest as installing user;
postinstall enables timer once telegram.env exists, now copies *.timer
- AGENT_TODO.md: worklist with Now/Next/Later/Done history; linked from AGENTS.md
190 lines
6.7 KiB
Bash
190 lines
6.7 KiB
Bash
#!/usr/bin/env bash
|
|
# Bash completion for pos — dynamically discovers pos-* subcommands
|
|
# Install: source this file in ~/.bashrc or place in /etc/bash_completion.d/
|
|
# GEN:START posflags
|
|
declare -A _pos_flags
|
|
_pos_flags[communication-telegram]="--send --type --caption --parse-mode --no-preview --token --chat-id"
|
|
_pos_flags[entertainment-send]="--print --markdown"
|
|
_pos_flags[network-hotspot]="--foreground"
|
|
_pos_flags[system-backup]="--service"
|
|
_pos_flags[system-health]="--send --markdown"
|
|
_pos_flags[usb-server]="--ls --ls-shared --share --unshare --auto-share --callback --close-callback --auto-connect --disconnect --nickname --timeout --port --info --version"
|
|
# GEN:END posflags
|
|
|
|
_pos() {
|
|
local cur prev words cword
|
|
|
|
# Manual init if bash-completion package is not loaded
|
|
if declare -F _init_completion &>/dev/null; then
|
|
_init_completion || return
|
|
else
|
|
COMPREPLY=()
|
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
|
words=("${COMP_WORDS[@]}")
|
|
cword=$COMP_CWORD
|
|
fi
|
|
|
|
local pos_bin="${COMP_WORDS[0]}"
|
|
local pos_dir
|
|
pos_dir="$(dirname "$(command -v "$pos_bin" 2>/dev/null || echo "$pos_bin")")"
|
|
|
|
# ── Collect all pos-* subcommands ──────────────────────────
|
|
local all_cmds=()
|
|
local f
|
|
for f in "$pos_dir"/pos-*; do
|
|
[ -x "$f" ] || continue
|
|
all_cmds+=("${f##*/pos-}")
|
|
done
|
|
|
|
# ── Build category→subcommand map ──────────────────────────
|
|
local -A cat_cmds
|
|
for cmd in "${all_cmds[@]}"; do
|
|
local cat="${cmd%%-*}"
|
|
local sub="${cmd#*-}"
|
|
if [ "$cat" != "$cmd" ]; then
|
|
cat_cmds["$cat"]+="${sub} "
|
|
fi
|
|
done
|
|
|
|
# ── Helpers ────────────────────────────────────────────────
|
|
_pos_complete_categories() {
|
|
COMPREPLY=($(compgen -W "${!cat_cmds[*]}" -- "$cur"))
|
|
}
|
|
|
|
_pos_complete_subcats() {
|
|
local cat="${words[1]}"
|
|
COMPREPLY=($(compgen -W "${cat_cmds[$cat]:-} --help" -- "$cur"))
|
|
}
|
|
|
|
_pos_complete_compose_services() {
|
|
local scale_dir="/usr/local/share/linux_post_install/scale-tail/services"
|
|
if [ -d "$scale_dir" ]; then
|
|
local svcs=()
|
|
for d in "$scale_dir"/*/; do
|
|
[ -d "$d" ] && svcs+=("$(basename "$d")")
|
|
done
|
|
COMPREPLY=($(compgen -W "${svcs[*]}" -- "$cur"))
|
|
fi
|
|
}
|
|
|
|
_pos_complete_compose_cmds() {
|
|
COMPREPLY=($(compgen -W "ls installed up down restart logs update config" -- "$cur"))
|
|
}
|
|
|
|
_pos_complete_docker_vbox_cmds() {
|
|
COMPREPLY=($(compgen -W "create enter stop start rm ls" -- "$cur"))
|
|
}
|
|
|
|
_pos_complete_docker_vbox_names() {
|
|
local names
|
|
names=$(docker ps -a --filter label=linux_post_install.vbox=true --format '{{.Names}}' 2>/dev/null)
|
|
COMPREPLY=($(compgen -W "$names" -- "$cur"))
|
|
}
|
|
|
|
_pos_complete_flags() {
|
|
local tool="$1"
|
|
COMPREPLY=($(compgen -W "${_pos_flags[$tool]:-} --help" -- "$cur"))
|
|
}
|
|
|
|
_pos_entertainment_plugins() {
|
|
local d f name out=()
|
|
for d in /usr/local/bin "$pos_dir/../entertainment"; do
|
|
[ -d "$d" ] || continue
|
|
for f in "$d"/*.sh; do
|
|
[ -f "$f" ] || continue
|
|
name="$(grep -m1 '^# POS_PLUGIN:' "$f" 2>/dev/null | sed 's/^# POS_PLUGIN:[[:space:]]*//;s/[[:space:]]*$//')"
|
|
[ -n "$name" ] && out+=("$name")
|
|
done
|
|
done
|
|
COMPREPLY=($(compgen -W "${out[*]}" -- "$cur"))
|
|
}
|
|
|
|
# ── Dispatch ───────────────────────────────────────────────
|
|
case "${#words[@]}" in
|
|
2)
|
|
_pos_complete_categories
|
|
;;
|
|
3)
|
|
_pos_complete_subcats
|
|
;;
|
|
4)
|
|
case "${words[1]}-${words[2]}" in
|
|
docker-compose)
|
|
case "${words[3]}" in
|
|
up|down|restart|logs)
|
|
_pos_complete_compose_services
|
|
;;
|
|
*)
|
|
_pos_complete_compose_cmds
|
|
;;
|
|
esac
|
|
;;
|
|
docker-vbox)
|
|
_pos_complete_docker_vbox_cmds
|
|
;;
|
|
usb-server)
|
|
_pos_complete_flags usb-server
|
|
;;
|
|
communication-telegram)
|
|
_pos_complete_flags communication-telegram
|
|
;;
|
|
entertainment-send)
|
|
_pos_complete_flags entertainment-send
|
|
;;
|
|
entertainment-enable|entertainment-disable)
|
|
_pos_entertainment_plugins
|
|
;;
|
|
entertainment-config)
|
|
COMPREPLY=($(compgen -W "set --help" -- "$cur"))
|
|
;;
|
|
network-hotspot)
|
|
_pos_complete_flags network-hotspot
|
|
;;
|
|
system-backup)
|
|
_pos_complete_flags system-backup
|
|
;;
|
|
esac
|
|
;;
|
|
5)
|
|
case "${words[1]}-${words[2]}" in
|
|
docker-compose)
|
|
case "${words[3]}" in
|
|
up|down|restart|logs)
|
|
_pos_complete_compose_services
|
|
;;
|
|
esac
|
|
;;
|
|
docker-vbox)
|
|
case "${words[3]}" in
|
|
create|enter|stop|start|rm)
|
|
_pos_complete_docker_vbox_names
|
|
;;
|
|
esac
|
|
;;
|
|
communication-telegram)
|
|
case "${words[3]}" in
|
|
send|--send) _pos_complete_flags communication-telegram ;;
|
|
esac
|
|
;;
|
|
esac
|
|
;;
|
|
6)
|
|
case "${words[1]}-${words[2]}" in
|
|
communication-telegram)
|
|
case "${words[3]}:${words[4]}" in
|
|
send:--type|--send:--type)
|
|
COMPREPLY=($(compgen -W "message file link sticker photo video audio voice animation" -- "$cur"))
|
|
;;
|
|
send:--parse-mode|--send:--parse-mode)
|
|
COMPREPLY=($(compgen -W "plain markdown html" -- "$cur"))
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
}
|
|
|
|
complete -F _pos pos
|