From 5349a028c87a4e9998b8cb636afbcc5eb18363b6 Mon Sep 17 00:00:00 2001 From: Anry Das Date: Mon, 19 Oct 2026 19:43:51 +0300 Subject: [PATCH] Fix issues found testing stage 5 in a VM - Calamares branding takes the version from VERSION at ISO build time - das-update tray hides its icon when updates were installed elsewhere (watches the xbps package database) - Installer removes guest tools of other hypervisors; the live image starts VBoxClient only inside VirtualBox - Live session no longer locks the screen while the installer runs - das-tools 0.2.0, das-installer 0.2.0, das-settings 0.4.0 Co-Authored-By: Claude Opus 5.5 --- TODO.md | 8 +++--- .../etc/xdg/autostart/vboxclient.desktop | 8 ++++++ scripts/container/build-iso.sh | 5 ++++ .../calamares/branding/dasos/branding.desc | 8 +++--- srcpkgs/das-installer/files/postinstall | 23 +++++++++++++--- srcpkgs/das-installer/template | 2 +- .../das-settings/files/bin/das-session-init | 26 ++++++++++++------- srcpkgs/das-settings/template | 2 +- .../files/src/cmd/das-update/tray.go | 11 ++++++++ .../das-tools/files/src/internal/xbps/xbps.go | 19 ++++++++++++++ srcpkgs/das-tools/template | 2 +- 11 files changed, 91 insertions(+), 23 deletions(-) create mode 100644 live/include/etc/xdg/autostart/vboxclient.desktop diff --git a/TODO.md b/TODO.md index 4094fc2..5f585bb 100644 --- a/TODO.md +++ b/TODO.md @@ -7,8 +7,10 @@ - [x] `das-welcome`: вікно першого входу (встановлення в live-сесії, мова, теки, оновлення, налаштування, довідка). - [x] Англійські назви тек: xdg-user-dirs 0.20 шукає переклади лише в першій теці `XDG_DATA_DIRS` з підкаталогом `locale` (порожня `/usr/local/share/locale`). Виправлено в `das-settings` (`/etc/X11/xinit/xinitrc.d/50-das-user-dirs`), уже створені теки перейменовує `das-welcome`. - [x] Тести `go test ./...` (`make test` і під час збирання пакета). -- [ ] Перевірити оновлення зі знімком у встановленій системі на Btrfs (у live-сесії перевірено лише гілку без знімків). -- [ ] Перевірити вибір мови в `das-welcome` (AccountsService і `~/.dmrc`): у live-образі зібрано лише одну локаль, тому рядок мови не показується. +- [x] Перевірено у встановленій системі на Btrfs (QEMU, UEFI): оновлення з вікна й `--cli` створює пару знімків pre/post, вони з'являються в меню GRUB, завантаження в знімок і `snapper-rollback` повертають попередню версію пакета; вибір мови в `das-welcome` діє після перезавантаження. +- [x] Виправлено після перевірки: версія в Calamares береться з `VERSION`; значок у треї ховається, коли оновлення встановлено поза ним (стежить за базою пакетів xbps); інструменти VirtualBox прибираються з не-VirtualBox машин (у KVM було повідомлення при кожному вході); live-сесія не блокує екран під час встановлення. +- [ ] Перевірити в наступному live ISO, що екран більше не блокується (властивості xfconf звірено з двійковими файлами). +- [ ] Вікно автентифікації polkit (`xfce-polkit`) англійською: перекласти або замінити агент. - [ ] Повідомити авторів xdg-user-dirs про помилку з `XDG_DATA_DIRS`. - [ ] Пункт «Профіль розробника» в `das-welcome` (разом з етапом 7). @@ -42,7 +44,7 @@ Live ISO без графіки з консольним інсталятором: - [ ] Перевірити на реальному залізі: видалення гостьових інструментів VM, Wi-Fi, NVIDIA/AMD. - [ ] Шифрування диска (LUKS): `luksbootkeyfile`, crypttab, dracut, `GRUB_ENABLE_CRYPTODISK`. - [ ] Перевірити ручну розмітку з Btrfs (чи створюються підтоми) і встановлення на ext4/XFS (знімки мають вимкнутися без помилок). -- [ ] Перевірити вибір автологіну й розкладки, відмінної від `us,ua`. +- [ ] Перевірити розкладку, відмінну від `us,ua` (автологін перевірено). ## Знімки й відкат - [ ] Перевірити, що cron справді робить щогодинні знімки й очищує старі. diff --git a/live/include/etc/xdg/autostart/vboxclient.desktop b/live/include/etc/xdg/autostart/vboxclient.desktop new file mode 100644 index 0000000..6a5d7c4 --- /dev/null +++ b/live/include/etc/xdg/autostart/vboxclient.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +# Replaces the file from virtualbox-ose-guest: start the VirtualBox clients +# only inside VirtualBox, other hypervisors get a "kernel service is not +# running" notification at every login. +Type=Application +Name=VirtualBox User Session +Exec=sh -c "grep -qs VirtualBox /sys/class/dmi/id/product_name && exec /usr/bin/VBoxClient-all" +NoDisplay=true diff --git a/scripts/container/build-iso.sh b/scripts/container/build-iso.sh index 6346c8e..488d993 100755 --- a/scripts/container/build-iso.sh +++ b/scripts/container/build-iso.sh @@ -32,6 +32,11 @@ ln -sf /usr/share/examples/wireplumber/10-wireplumber.conf "$include"/etc/pipewi ln -sf /usr/share/examples/pipewire/20-pipewire-pulse.conf "$include"/etc/pipewire/pipewire.conf.d/ ln -sf /usr/share/alsa/alsa.conf.d/50-pipewire.conf "$include"/etc/alsa/conf.d/ ln -sf /usr/share/alsa/alsa.conf.d/99-pipewire-default.conf "$include"/etc/alsa/conf.d/ +# The installer shows the Das OS version, which lives in VERSION, not in the package +branding=usr/share/calamares/branding/dasos +mkdir -p "$include/$branding" +sed -e "s/@VERSION@/$version/g" -e "s/@SHORT_VERSION@/${version%.*}/g" \ + "/work/srcpkgs/das-installer/files/calamares/branding/dasos/branding.desc" >"$include/$branding/branding.desc" # mklive's dracut module creates the live user, hostname and passwords at boot. # Rebrand its defaults in this container's copy (the image itself stays untouched). diff --git a/srcpkgs/das-installer/files/calamares/branding/dasos/branding.desc b/srcpkgs/das-installer/files/calamares/branding/dasos/branding.desc index de7c469..84d3be6 100644 --- a/srcpkgs/das-installer/files/calamares/branding/dasos/branding.desc +++ b/srcpkgs/das-installer/files/calamares/branding/dasos/branding.desc @@ -12,10 +12,10 @@ navigation: widget strings: productName: "Das OS" shortProductName: "Das OS" - version: "0.2.0" - shortVersion: "0.2" - versionedName: "Das OS 0.2.0" - shortVersionedName: "Das OS 0.2" + version: "@VERSION@" + shortVersion: "@SHORT_VERSION@" + versionedName: "Das OS @VERSION@" + shortVersionedName: "Das OS @SHORT_VERSION@" bootloaderEntryName: "Das OS" productUrl: "https://git.das.org.ua/das/Das-OS" supportUrl: "https://git.das.org.ua/das/Das-OS/issues" diff --git a/srcpkgs/das-installer/files/postinstall b/srcpkgs/das-installer/files/postinstall index b01cbd6..408a3c1 100755 --- a/srcpkgs/das-installer/files/postinstall +++ b/srcpkgs/das-installer/files/postinstall @@ -22,12 +22,27 @@ if ! grep -q '^[^#]*[[:space:]]/tmp[[:space:]]' /etc/fstab; then echo "tmpfs /tmp tmpfs defaults,nosuid,nodev 0 0" >>/etc/fstab fi -# Guest tools are only useful inside a virtual machine. +# Guest tools only help inside their own hypervisor (VirtualBox's ones even +# complain at every login elsewhere). +machine=$(cat /sys/class/dmi/id/sys_vendor /sys/class/dmi/id/product_name 2>/dev/null || true) if ! grep -q '^flags.* hypervisor' /proc/cpuinfo; then - msg "real hardware: removing virtual machine guest tools" - rm -f /etc/runit/runsvdir/default/spice-vdagentd - xbps-remove -Ry spice-vdagent qemu-ga virtualbox-ose-guest || true + machine="real hardware" fi +case $machine in +*VirtualBox* | *innotek*) unused="spice-vdagent qemu-ga" ;; +*QEMU* | *KVM*) unused="virtualbox-ose-guest" ;; +*) unused="spice-vdagent qemu-ga virtualbox-ose-guest" ;; +esac +msg "removing guest tools not needed here: $unused" +case $unused in +*spice-vdagent*) rm -f /etc/runit/runsvdir/default/spice-vdagentd ;; +esac +case $unused in +# The live image replaces this autostart file, so xbps keeps it as modified +*virtualbox*) rm -f /etc/xdg/autostart/vboxclient.desktop ;; +esac +# shellcheck disable=SC2086 +xbps-remove -Ry $unused || true # Snapper, hourly snapshots and the GRUB snapshot menu (Btrfs only). das-snapper-setup diff --git a/srcpkgs/das-installer/template b/srcpkgs/das-installer/template index 5d5ed6a..f2f0317 100644 --- a/srcpkgs/das-installer/template +++ b/srcpkgs/das-installer/template @@ -1,6 +1,6 @@ # Template file for 'das-installer' pkgname=das-installer -version=0.1.0 +version=0.2.0 revision=1 depends="calamares das-snapshots das-theme sudo" short_desc="Das OS installer: Calamares configuration and branding for the live ISO" diff --git a/srcpkgs/das-settings/files/bin/das-session-init b/srcpkgs/das-settings/files/bin/das-session-init index f82ba16..75e057a 100755 --- a/srcpkgs/das-settings/files/bin/das-session-init +++ b/srcpkgs/das-settings/files/bin/das-session-init @@ -4,6 +4,21 @@ # which is only known inside the session. Runs once per user. set -u +# Sets an xfconf property, creating it when it does not exist yet. +set_prop() { + local channel=$1 prop=$2 type=$3 value=$4 + xfconf-query -c "$channel" -p "$prop" -s "$value" 2>/dev/null || + xfconf-query -c "$channel" -p "$prop" -n -t "$type" -s "$value" +} + +# The live session must not lock the screen: the installer runs for minutes +# without input, and the live user's password is not something people know. +# Static files would reach the installed system, which copies the live image. +if grep -q '\(^\| \)root=live:' /proc/cmdline; then + set_prop xfce4-screensaver /lock/enabled bool false + set_prop xfce4-power-manager /xfce4-power-manager/lock-screen-suspend-hibernate bool false +fi + marker="${XDG_CONFIG_HOME:-$HOME/.config}/das/session-init.done" [[ -e $marker ]] && exit 0 @@ -12,13 +27,6 @@ if [[ $(xfconf-query -c xsettings -p /Net/ThemeName 2>/dev/null) == *-Dark ]]; t wallpaper=/usr/share/backgrounds/das/das-dark.svg fi -# Sets an xfconf property, creating it when it does not exist yet. -set_prop() { - local prop=$1 type=$2 value=$3 - xfconf-query -c xfce4-desktop -p "$prop" -s "$value" 2>/dev/null || - xfconf-query -c xfce4-desktop -p "$prop" -n -t "$type" -s "$value" -} - # "xrandr --listactivemonitors" prints a header, then one line per monitor ending in its connector name. monitors=$(xrandr --listactivemonitors 2>/dev/null | awk 'NR > 1 { print $NF }') if [[ -z $monitors ]]; then @@ -28,8 +36,8 @@ fi for monitor in $monitors; do base="/backdrop/screen0/monitor${monitor}/workspace0" - set_prop "$base/last-image" string "$wallpaper" - set_prop "$base/image-style" int 5 # zoomed: fill the screen, keep proportions + set_prop xfce4-desktop "$base/last-image" string "$wallpaper" + set_prop xfce4-desktop "$base/image-style" int 5 # zoomed: fill the screen, keep proportions done mkdir -p "${marker%/*}" && touch "$marker" diff --git a/srcpkgs/das-settings/template b/srcpkgs/das-settings/template index 4fed944..3ff28fe 100644 --- a/srcpkgs/das-settings/template +++ b/srcpkgs/das-settings/template @@ -4,7 +4,7 @@ # Defaults go to /etc/xdg/das, which /etc/profile.d/das-xdg.sh puts in front of # /etc/xdg: stock Xfce files stay untouched and users' own changes still win. pkgname=das-settings -version=0.3.0 +version=0.4.0 revision=1 create_wrksrc=yes depends="das-theme lightdm lightdm-gtk-greeter xfce4-notifyd xfce4-panel diff --git a/srcpkgs/das-tools/files/src/cmd/das-update/tray.go b/srcpkgs/das-tools/files/src/cmd/das-update/tray.go index 6976b47..5be6fd8 100644 --- a/srcpkgs/das-tools/files/src/cmd/das-update/tray.go +++ b/srcpkgs/das-tools/files/src/cmd/das-update/tray.go @@ -22,6 +22,9 @@ const ( firstCheck = 2 * time.Minute checkInterval = 6 * time.Hour checkTimeout = 5 * time.Minute + // How often to look for updates installed outside the tray: from a + // separately started window, das-update --cli or xbps-install. + pkgdbInterval = time.Minute ) type trayApp struct { @@ -29,6 +32,7 @@ type trayApp struct { checking bool notified []string // the updates the last notification was about window *exec.Cmd + pkgdb time.Time // package database time at the last check } func runTray() int { @@ -69,6 +73,12 @@ func runTray() int { }) return false }) + glib.TimeoutSecondsAdd(uint(pkgdbInterval.Seconds()), func() bool { + if t.notified != nil && !xbps.PkgdbTime().Equal(t.pkgdb) { + t.check() + } + return true + }) gtk.Main() return 0 } @@ -78,6 +88,7 @@ func (t *trayApp) check() { return } t.checking = true + t.pkgdb = xbps.PkgdbTime() go func() { ctx, cancel := context.WithTimeout(context.Background(), checkTimeout) defer cancel() diff --git a/srcpkgs/das-tools/files/src/internal/xbps/xbps.go b/srcpkgs/das-tools/files/src/internal/xbps/xbps.go index 0295c42..f67d64d 100644 --- a/srcpkgs/das-tools/files/src/internal/xbps/xbps.go +++ b/srcpkgs/das-tools/files/src/internal/xbps/xbps.go @@ -4,11 +4,17 @@ package xbps import ( "context" "fmt" + "os" "os/exec" + "path/filepath" "sort" "strings" + "time" ) +// pkgdbGlob matches the package database, which xbps rewrites on every transaction. +const pkgdbGlob = "/var/db/xbps/pkgdb-*.plist" + // Update is one package that a full system update would change. type Update struct { Name string @@ -46,6 +52,19 @@ func Check(ctx context.Context) ([]Update, error) { return updates, nil } +// PkgdbTime tells when the installed packages last changed: the modification +// time of the package database, zero when it can't be read. +func PkgdbTime() time.Time { + paths, _ := filepath.Glob(pkgdbGlob) + var latest time.Time + for _, p := range paths { + if fi, err := os.Stat(p); err == nil && fi.ModTime().After(latest) { + latest = fi.ModTime() + } + } + return latest +} + // ParseDryRun parses "xbps-install -un" output: one transaction entry per // line, " [sizes]". Other lines are skipped. func ParseDryRun(out string) []Update { diff --git a/srcpkgs/das-tools/template b/srcpkgs/das-tools/template index d4b58b0..5e49edb 100644 --- a/srcpkgs/das-tools/template +++ b/srcpkgs/das-tools/template @@ -1,7 +1,7 @@ # Template file for 'das-tools' # In-tree package: Go sources are in files/src (FILESDIR). pkgname=das-tools -version=0.1.0 +version=0.2.0 revision=1 create_wrksrc=yes # Like build_style=go: the Go linker decides about PIE, xbps-src must not check it