Stage 7: command-line helpers dsv, duser, dfw, dsys (0.5.0)
- das-helpers replaces the dsv package and adds shared functions in /usr/lib/das/helpers.sh (bilingual messages, sudo re-exec, prompts). - dsv new creates a runit service (command, user, directory, environment, svlogd log) and checks it stays up; dsv rm deletes one not from a package. - duser: list, add (installer groups, --admin, key, password), del, passwd, lock/unlock (key logins too), key add|list|rm, groups +/-. - dfw: allow/deny/status/reload for the tcp_ports and udp_ports sets of the inet das table, kept in /etc/nftables.d/dfw.nft and checked with nft -c. - dsys: info, hostname, timezone, locale, keymap. - xtools-minimal on both images. - nftables.conf no longer suggests restarting the nftables service: its finish script flushes the whole ruleset, fail2ban's and Docker's included. - das-server-install 0.2.0 mentions the helpers when it finishes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Executable
+247
@@ -0,0 +1,247 @@
|
||||
#!/bin/bash
|
||||
# dsys - system settings on Das OS: host name, time zone, language and
|
||||
# console keyboard, in place of hostnamectl, timedatectl and localectl.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source=helpers.sh
|
||||
. "${DAS_HELPERS:-/usr/lib/das/helpers.sh}"
|
||||
|
||||
zoneinfo=/usr/share/zoneinfo
|
||||
libc_locales=/etc/default/libc-locales
|
||||
keymaps=/usr/share/kbd/keymaps
|
||||
|
||||
usage() {
|
||||
if [[ -n $uk ]]; then
|
||||
cat <<'EOF'
|
||||
Використання: dsys [КОМАНДА] [ЗНАЧЕННЯ]
|
||||
|
||||
info огляд системи (типова команда)
|
||||
hostname [ІМ'Я] показати або змінити ім'я хоста
|
||||
timezone [ЗОНА] показати або змінити часовий пояс (Europe/Kyiv,
|
||||
достатньо й частини назви: Kyiv)
|
||||
timezone list [ФІЛЬТР] усі часові пояси
|
||||
locale [МОВА] показати або змінити мову системи (uk_UA, en_US)
|
||||
locale list [ФІЛЬТР] доступні мови; * — уже зібрані
|
||||
keymap [РОЗКЛАДКА] показати або змінити розкладку консолі (us, ua-utf)
|
||||
keymap list [ФІЛЬТР] доступні розкладки консолі
|
||||
|
||||
Мову й розкладку графічного сеансу кожен користувач задає в налаштуваннях
|
||||
Xfce і в das-welcome; dsys змінює типові для системи й консолі.
|
||||
EOF
|
||||
else
|
||||
cat <<'EOF'
|
||||
Usage: dsys [COMMAND] [VALUE]
|
||||
|
||||
info system overview (the default)
|
||||
hostname [NAME] show or change the host name
|
||||
timezone [ZONE] show or change the time zone (Europe/Kyiv,
|
||||
part of the name will do: Kyiv)
|
||||
timezone list [FILTER] all time zones
|
||||
locale [LANGUAGE] show or change the system language (uk_UA, en_US)
|
||||
locale list [FILTER] available languages; * marks the built ones
|
||||
keymap [MAP] show or change the console keyboard map (us, ua-utf)
|
||||
keymap list [FILTER] available console keyboard maps
|
||||
|
||||
In the graphical session every user picks the language and keyboard in the
|
||||
Xfce settings and in das-welcome; dsys changes the system and console defaults.
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
||||
current_hostname() {
|
||||
cat /etc/hostname 2>/dev/null || hostname
|
||||
}
|
||||
|
||||
current_timezone() {
|
||||
local tz
|
||||
tz=$(readlink /etc/localtime 2>/dev/null || true)
|
||||
echo "${tz#*zoneinfo/}"
|
||||
}
|
||||
|
||||
current_locale() {
|
||||
sed -n 's/^LANG=//p' /etc/locale.conf 2>/dev/null | tr -d '"'
|
||||
}
|
||||
|
||||
rc_value() {
|
||||
sed -n "s/^$1=//p" /etc/rc.conf 2>/dev/null | tr -d '"' | tail -n 1
|
||||
}
|
||||
|
||||
# A graphical session keeps its X authority under the old host name
|
||||
session_warning() {
|
||||
if pgrep -x lightdm >/dev/null || [[ -n ${DISPLAY:-} ]]; then
|
||||
say "Перезавантажте комп'ютер: графічний сеанс не відкриватиме нових вікон зі старим іменем." \
|
||||
"Reboot: the graphical session will not open new windows under the old name."
|
||||
fi
|
||||
}
|
||||
|
||||
# 3 д 4 год 5 хв / 3 d 4 h 5 min
|
||||
uptime_text() {
|
||||
local s d h m
|
||||
read -r s _ </proc/uptime
|
||||
s=${s%.*}
|
||||
d=$((s / 86400))
|
||||
h=$((s % 86400 / 3600))
|
||||
m=$((s % 3600 / 60))
|
||||
if ((d > 0)); then
|
||||
say "$d д $h год $m хв" "$d d $h h $m min"
|
||||
elif ((h > 0)); then
|
||||
say "$h год $m хв" "$h h $m min"
|
||||
else
|
||||
say "$m хв" "$m min"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd_info() {
|
||||
local ntp line
|
||||
pad "$(say "Ім'я хоста:" "Host name:")" 16; current_hostname
|
||||
pad "$(say "Система:" "System:")" 16; echo "$(uname -sr), $(uname -m)"
|
||||
pad "$(say "Працює:" "Up:")" 16; uptime_text
|
||||
pad "$(say "Час:" "Time:")" 16; date '+%Y-%m-%d %H:%M:%S %Z'
|
||||
pad "$(say "Часовий пояс:" "Time zone:")" 16; current_timezone
|
||||
if ntp=$(chronyc -n tracking 2>/dev/null); then
|
||||
if grep -q '^Leap status *: Normal' <<<"$ntp"; then
|
||||
ntp=$(say "синхронізовано (chrony)" "synchronized (chrony)")
|
||||
else
|
||||
ntp=$(say "не синхронізовано (chrony)" "not synchronized (chrony)")
|
||||
fi
|
||||
else
|
||||
ntp=$(say "не працює (dsv enable chronyd)" "not running (dsv enable chronyd)")
|
||||
fi
|
||||
pad "$(say "Синхронізація:" "Time sync:")" 16; echo "$ntp"
|
||||
pad "$(say "Мова:" "Language:")" 16; current_locale
|
||||
pad "$(say "Консоль:" "Console:")" 16
|
||||
echo "$(say розкладка keymap) $(rc_value KEYMAP || true), $(say шрифт font) $(rc_value FONT || true)"
|
||||
say "Мережа:" "Network:"
|
||||
ip -brief address 2>/dev/null | while read -r line; do
|
||||
[[ $line == lo\ * ]] || echo " $line"
|
||||
done
|
||||
}
|
||||
|
||||
cmd_hostname() {
|
||||
local new=${1:-} old
|
||||
if [[ -z $new ]]; then
|
||||
current_hostname
|
||||
return
|
||||
fi
|
||||
[[ $new =~ ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$ ]] ||
|
||||
die "'$new': малі латинські літери, цифри й дефіс (не на початку й не в кінці)" \
|
||||
"'$new': lowercase Latin letters, digits and hyphens (not first or last)"
|
||||
need_root hostname "$new"
|
||||
old=$(current_hostname)
|
||||
echo "$new" >/etc/hostname
|
||||
# The installers add "127.0.1.1 <name>"; keep the line in step
|
||||
if grep -qw -- "$old" /etc/hosts; then
|
||||
sed -i "/^[^#]/s/\([[:space:]]\)${old//./\\.}\([[:space:]]\|$\)/\1$new\2/g" /etc/hosts
|
||||
fi
|
||||
grep -qw -- "$new" /etc/hosts || printf '127.0.1.1\t%s\n' "$new" >>/etc/hosts
|
||||
hostname "$new"
|
||||
say "Ім'я хоста: $new" "Host name: $new"
|
||||
session_warning
|
||||
}
|
||||
|
||||
# All time zones, from tzdata's table plus UTC
|
||||
timezones() {
|
||||
{ awk '!/^#/ { print $3 }' "$zoneinfo/zone1970.tab"; echo UTC; } | sort -u
|
||||
}
|
||||
|
||||
cmd_timezone() {
|
||||
local zone=${1:-} matches line
|
||||
if [[ -z $zone ]]; then
|
||||
current_timezone
|
||||
return
|
||||
fi
|
||||
if [[ $zone == list ]]; then
|
||||
timezones | grep -i -- "${2:-}" || true
|
||||
return
|
||||
fi
|
||||
if ! timezones | grep -qx -- "$zone"; then
|
||||
# Kyiv -> Europe/Kyiv, when only one zone matches
|
||||
matches=$(timezones | grep -i -- "$zone" || true)
|
||||
if [[ $(grep -c . <<<"$matches") -eq 1 ]]; then
|
||||
zone=$matches
|
||||
elif [[ -n $matches ]]; then
|
||||
say "Кілька часових поясів підходять, уточніть:" "Several time zones match, be more specific:" >&2
|
||||
head -n 20 <<<"$matches" | while read -r line; do echo " $line"; done >&2
|
||||
(($(grep -c . <<<"$matches") <= 20)) || echo " ..." >&2
|
||||
exit 1
|
||||
else
|
||||
die "невідомий часовий пояс '$zone' (dsys timezone list)" "unknown time zone '$zone' (dsys timezone list)"
|
||||
fi
|
||||
fi
|
||||
need_root timezone "$zone"
|
||||
ln -sfn "$zoneinfo/$zone" /etc/localtime
|
||||
say "Часовий пояс: $zone, зараз $(date '+%H:%M %Z')" "Time zone: $zone, now $(date '+%H:%M %Z')"
|
||||
}
|
||||
|
||||
# Every UTF-8 locale glibc can build, with * for the enabled ones
|
||||
locales() {
|
||||
sed -n 's/^\(#\?\)\([^ ]*\.UTF-8\) UTF-8[[:space:]]*$/\2 \1/p' "$libc_locales" |
|
||||
awk '{ print ($2 == "#" ? " " : "* ") $1 }'
|
||||
}
|
||||
|
||||
cmd_locale() {
|
||||
local lang=${1:-} re
|
||||
if [[ -z $lang ]]; then
|
||||
current_locale
|
||||
return
|
||||
fi
|
||||
if [[ $lang == list ]]; then
|
||||
locales | grep -i -- "${2:-}" || true
|
||||
return
|
||||
fi
|
||||
[[ $lang == *.* ]] || lang+=.UTF-8
|
||||
re=${lang//./\\.}
|
||||
locales | grep -q "^. $re\$" ||
|
||||
die "невідома мова '$lang' (dsys locale list)" "unknown language '$lang' (dsys locale list)"
|
||||
need_root locale "$lang"
|
||||
if grep -q "^#$re " "$libc_locales"; then
|
||||
sed -i "s/^#\($re \)/\1/" "$libc_locales"
|
||||
say "Збираю $lang..." "Building $lang..."
|
||||
xbps-reconfigure -f glibc-locales >/dev/null
|
||||
fi
|
||||
# Keep the other settings, Void's default file also has LC_COLLATE=C
|
||||
if grep -q '^LANG=' /etc/locale.conf 2>/dev/null; then
|
||||
sed -i "s/^LANG=.*/LANG=$lang/" /etc/locale.conf
|
||||
else
|
||||
echo "LANG=$lang" >>/etc/locale.conf
|
||||
fi
|
||||
say "Мова системи: $lang (діє з наступного входу)" "System language: $lang (from the next login)"
|
||||
}
|
||||
|
||||
cmd_keymap() {
|
||||
local map=${1:-}
|
||||
if [[ -z $map ]]; then
|
||||
rc_value KEYMAP
|
||||
return
|
||||
fi
|
||||
if [[ $map == list ]]; then
|
||||
find "$keymaps" -name '*.map.gz' -printf '%f\n' | sed 's/\.map\.gz$//' | sort -u | grep -i -- "${2:-}" || true
|
||||
return
|
||||
fi
|
||||
[[ -n $(find "$keymaps" -name "$map.map.gz" -print -quit) ]] ||
|
||||
die "невідома розкладка '$map' (dsys keymap list)" "unknown keyboard map '$map' (dsys keymap list)"
|
||||
need_root keymap "$map"
|
||||
set_rc KEYMAP "$map"
|
||||
# The default console font has no Cyrillic letters
|
||||
if [[ $map == @(ua|ru|by|bg|mk|sr)* && -z $(rc_value FONT) ]]; then
|
||||
set_rc FONT cyr-sun16
|
||||
fi
|
||||
loadkeys "$map" >/dev/null 2>&1 || true
|
||||
say "Розкладка консолі: $map" "Console keyboard map: $map"
|
||||
}
|
||||
|
||||
cmd=${1:-info}
|
||||
[[ $# -gt 0 ]] && shift
|
||||
|
||||
case $cmd in
|
||||
info | status) cmd_info ;;
|
||||
hostname | host) cmd_hostname "$@" ;;
|
||||
timezone | tz) cmd_timezone "$@" ;;
|
||||
locale | lang) cmd_locale "$@" ;;
|
||||
keymap | keyboard) cmd_keymap "$@" ;;
|
||||
-h | --help | help) usage ;;
|
||||
*)
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user