Terminal: Das prompt, dprompt and dbanner (0.9.1)
build / build (push) Successful in 38m26s

- das-shell 0.1.0: the Das two-line bash prompt by default (replaces the
  PS1 of Void's skel .bashrc once), dprompt (Textual prompt builder with
  presets and live preview) and dbanner (SSH login banner editor: canvas
  tools, fields with values, widgets, das-banner service for cached ones,
  Das OS logo and tryzub pictures). Python tests in make test.
- das-server 0.3.0 depends on das-shell; the server installer mentions
  dprompt and dbanner; the desktop image includes it.
- run-qemu.sh forwards the guest's SSH to localhost:2222.
- Hardware fixes: Ventoy menu icon, boot menu titles "Das OS <version>".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
das
2026-10-21 09:17:10 +03:00
co-authored by Claude Opus 5.5
parent 66ea614e0d
commit a2bffc7fe9
72 changed files with 5506 additions and 23 deletions
+15
View File
@@ -0,0 +1,15 @@
#!/bin/bash
# dbanner-title-uk: Контейнери Docker
# dbanner-title-en: Docker containers
# dbanner-mode: live
# Running and stopped containers; nothing when Docker is not there or not reachable.
. "${0%/*}/lib.sh"
command -v docker >/dev/null || exit 0
mapfile -t states < <(timeout 1 docker ps -a --format '{{.State}}' 2>/dev/null) || exit 0
((${#states[@]})) || exit 0
running=0
for s in "${states[@]}"; do [[ $s == running ]] && ((running++)); done
stopped=$((${#states[@]} - running))
color=$Green
((stopped)) && color=$Yellow
echo "$Bold$(say "Docker:" "Docker:")$Off $color$running$Off $(say "працює" "running"), $stopped $(say "зупинено" "stopped")"
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# dbanner-title-uk: Заблоковані fail2ban адреси
# dbanner-title-en: Addresses banned by fail2ban
# dbanner-mode: cached
# dbanner-interval: 300
# How many addresses fail2ban keeps banned now and in total; needs root.
. "${0%/*}/lib.sh"
command -v fail2ban-client >/dev/null || exit 0
((EUID == 0)) || exit 0
out=$(timeout 5 fail2ban-client status sshd 2>/dev/null) || exit 0
now=$(awk -F: '/Currently banned/ {gsub(/ /, "", $2); print $2}' <<<"$out")
total=$(awk -F: '/Total banned/ {gsub(/ /, "", $2); print $2}' <<<"$out")
echo "$Bold$(say "fail2ban (sshd):" "fail2ban (sshd):")$Off $Yellow${now:-0}$Off $(say "заблоковано зараз, усього" "banned now, total") ${total:-0}"
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# dbanner-title-uk: Попередній вхід
# dbanner-title-en: Previous login
# dbanner-mode: live
# The login before this one of the user who logs in (from last).
. "${0%/*}/lib.sh"
command -v last >/dev/null || exit 0
user=${USER:-$(id -un)}
line=$(timeout 1 last -n 2 -w --time-format iso "$user" 2>/dev/null | sed -n 2p)
[[ -n $line && $line != wtmp* ]] || exit 0
read -r _ tty from when _ <<<"$line"
[[ $from == :* || $from =~ ^tty ]] && from=$tty
echo "$Bold$(say "Попередній вхід:" "Previous login:")$Off ${when%+*} $(say "з" "from") $Cyan$from$Off"
@@ -0,0 +1,14 @@
# Shared by the dbanner widget scripts: colors and the user's language.
# shellcheck shell=bash
# shellcheck disable=SC2034
Off=$'\e[0m' Bold=$'\e[1;37m' Red=$'\e[1;31m' Green=$'\e[1;32m' Yellow=$'\e[1;33m' Cyan=$'\e[1;36m' Gray=$'\e[0;90m'
# say UKRAINIAN ENGLISH
say() {
if [[ ${DBANNER_LANG:-} == uk ]]; then echo "$1"; else echo "$2"; fi
}
# level VALUE WARN CRIT: green below WARN, yellow below CRIT, red otherwise
level() {
if (($1 < $2)); then echo -n "$Green"; elif (($1 < $3)); then echo -n "$Yellow"; else echo -n "$Red"; fi
}
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
# dbanner-title-uk: Служби, що не працюють
# dbanner-title-en: Services that are down
# dbanner-mode: live
# Enabled runit services that are not running; nothing when all of them are up.
. "${0%/*}/lib.sh"
dir=/var/service
[[ -d $dir ]] || exit 0
down=()
for s in "$dir"/*/; do
s=${s%/}
[[ -f $s/down ]] && continue
state=$(timeout 1 sv status "$s" 2>/dev/null) || state=down
[[ $state == run:* ]] || down+=("${s##*/}")
done
((${#down[@]})) || exit 0
echo "$Bold$(say "Не працюють:" "Down:")$Off $Red${down[*]}$Off $(say "(dsv status)" "(dsv status)")"
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
# dbanner-title-uk: Стан дисків (SMART)
# dbanner-title-en: Disk health (SMART)
# dbanner-mode: cached
# dbanner-interval: 21600
# Health, temperature and power-on hours of every disk; needs root and smartmontools.
. "${0%/*}/lib.sh"
command -v smartctl >/dev/null || exit 0
((EUID == 0)) || exit 0
first=1
for dev in /sys/block/*; do
name=${dev##*/}
[[ $name == @(loop|ram|zram|sr|dm-|md)* ]] && continue
out=$(smartctl -H -A -i "/dev/$name" 2>/dev/null) || [[ -n $out ]] || continue
model=$(sed -n 's/^\(Device Model\|Model Number\|Product\): *//p' <<<"$out" | head -1)
health=$(sed -n 's/.*\(overall-health\|Health Status\).*: *//p' <<<"$out" | head -1)
temp=$(awk '/Temperature_Celsius|Airflow_Temperature/ {print $10; exit} /^Temperature:/ {print $2; exit}' <<<"$out")
hours=$(awk '/Power_On_Hours/ {print $10; exit} /^Power On Hours:/ {gsub(",", "", $4); print $4; exit}' <<<"$out")
[[ -n $health ]] || continue
if ((first)); then echo "$Bold$(say "Стан дисків:" "Disk health:")$Off"; first=0; fi
hcolor=$Green
[[ $health == PASSED || $health == OK ]] || hcolor=$Red
line=" /dev/$name ${model:+($model) }$hcolor$health$Off"
[[ $temp =~ ^[0-9]+$ ]] && line+=", $(level "$temp" 55 70)$temp °C$Off"
[[ $hours =~ ^[0-9]+$ ]] && line+=", $Cyan$hours $(say "год" "h")$Off"
echo "$line"
done
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# dbanner-title-uk: Знімки Btrfs (snapper)
# dbanner-title-en: Btrfs snapshots (snapper)
# dbanner-mode: cached
# dbanner-interval: 3600
# Number of snapper snapshots of / and the date of the last one; needs root.
. "${0%/*}/lib.sh"
command -v snapper >/dev/null || exit 0
((EUID == 0)) || exit 0
mapfile -t rows < <(timeout 10 snapper -c root --csvout list --columns number,date 2>/dev/null | tail -n +3)
((${#rows[@]})) || exit 0
last=${rows[-1]#*,}
echo "$Bold$(say "Знімки:" "Snapshots:")$Off ${#rows[@]}, $(say "останній" "last") $Cyan${last%:*}$Off"
+15
View File
@@ -0,0 +1,15 @@
#!/bin/bash
# dbanner-title-uk: Доступні оновлення
# dbanner-title-en: Available updates
# dbanner-mode: cached
# dbanner-interval: 21600
# Package updates (xbps-install -Mun downloads the repository index, so it runs
# from the das-banner service, not at login).
. "${0%/*}/lib.sh"
command -v xbps-install >/dev/null || exit 0
count=$(xbps-install -Mun 2>/dev/null | wc -l) || exit 0
if ((count)); then
echo "$Bold$(say "Оновлення:" "Updates:")$Off $Yellow$count$Off $(say "пакетів — das-update" "packages — das-update")"
else
echo "$Bold$(say "Оновлення:" "Updates:")$Off $Green$(say "система оновлена" "up to date")$Off"
fi
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# dbanner-title-uk: Погода (wttr.in)
# dbanner-title-en: Weather (wttr.in)
# dbanner-mode: cached
# dbanner-interval: 1800
# Weather from wttr.in for the "city" variable of the banner (DBANNER_CITY).
. "${0%/*}/lib.sh"
command -v curl >/dev/null || exit 0
city=${DBANNER_CITY:-}
lang=${DBANNER_LANG:-en}
line=$(curl -fsS -m 15 -H "Accept-Language: $lang" "https://wttr.in/${city// /+}?format=%l:+%c+%t+(%f),+%w,+%h&lang=$lang" 2>/dev/null) || exit 0
[[ $line == *"Unknown location"* || -z $line ]] && exit 0
echo "$Bold$(say "Погода:" "Weather:")$Off $Cyan$line$Off"