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 <noreply@anthropic.com>
This commit is contained in:
@@ -7,8 +7,10 @@
|
|||||||
- [x] `das-welcome`: вікно першого входу (встановлення в live-сесії, мова, теки, оновлення, налаштування, довідка).
|
- [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] Англійські назви тек: 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` і під час збирання пакета).
|
- [x] Тести `go test ./...` (`make test` і під час збирання пакета).
|
||||||
- [ ] Перевірити оновлення зі знімком у встановленій системі на Btrfs (у live-сесії перевірено лише гілку без знімків).
|
- [x] Перевірено у встановленій системі на Btrfs (QEMU, UEFI): оновлення з вікна й `--cli` створює пару знімків pre/post, вони з'являються в меню GRUB, завантаження в знімок і `snapper-rollback` повертають попередню версію пакета; вибір мови в `das-welcome` діє після перезавантаження.
|
||||||
- [ ] Перевірити вибір мови в `das-welcome` (AccountsService і `~/.dmrc`): у live-образі зібрано лише одну локаль, тому рядок мови не показується.
|
- [x] Виправлено після перевірки: версія в Calamares береться з `VERSION`; значок у треї ховається, коли оновлення встановлено поза ним (стежить за базою пакетів xbps); інструменти VirtualBox прибираються з не-VirtualBox машин (у KVM було повідомлення при кожному вході); live-сесія не блокує екран під час встановлення.
|
||||||
|
- [ ] Перевірити в наступному live ISO, що екран більше не блокується (властивості xfconf звірено з двійковими файлами).
|
||||||
|
- [ ] Вікно автентифікації polkit (`xfce-polkit`) англійською: перекласти або замінити агент.
|
||||||
- [ ] Повідомити авторів xdg-user-dirs про помилку з `XDG_DATA_DIRS`.
|
- [ ] Повідомити авторів xdg-user-dirs про помилку з `XDG_DATA_DIRS`.
|
||||||
- [ ] Пункт «Профіль розробника» в `das-welcome` (разом з етапом 7).
|
- [ ] Пункт «Профіль розробника» в `das-welcome` (разом з етапом 7).
|
||||||
|
|
||||||
@@ -42,7 +44,7 @@ Live ISO без графіки з консольним інсталятором:
|
|||||||
- [ ] Перевірити на реальному залізі: видалення гостьових інструментів VM, Wi-Fi, NVIDIA/AMD.
|
- [ ] Перевірити на реальному залізі: видалення гостьових інструментів VM, Wi-Fi, NVIDIA/AMD.
|
||||||
- [ ] Шифрування диска (LUKS): `luksbootkeyfile`, crypttab, dracut, `GRUB_ENABLE_CRYPTODISK`.
|
- [ ] Шифрування диска (LUKS): `luksbootkeyfile`, crypttab, dracut, `GRUB_ENABLE_CRYPTODISK`.
|
||||||
- [ ] Перевірити ручну розмітку з Btrfs (чи створюються підтоми) і встановлення на ext4/XFS (знімки мають вимкнутися без помилок).
|
- [ ] Перевірити ручну розмітку з Btrfs (чи створюються підтоми) і встановлення на ext4/XFS (знімки мають вимкнутися без помилок).
|
||||||
- [ ] Перевірити вибір автологіну й розкладки, відмінної від `us,ua`.
|
- [ ] Перевірити розкладку, відмінну від `us,ua` (автологін перевірено).
|
||||||
|
|
||||||
## Знімки й відкат
|
## Знімки й відкат
|
||||||
- [ ] Перевірити, що cron справді робить щогодинні знімки й очищує старі.
|
- [ ] Перевірити, що cron справді робить щогодинні знімки й очищує старі.
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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/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/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/
|
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.
|
# 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).
|
# Rebrand its defaults in this container's copy (the image itself stays untouched).
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ navigation: widget
|
|||||||
strings:
|
strings:
|
||||||
productName: "Das OS"
|
productName: "Das OS"
|
||||||
shortProductName: "Das OS"
|
shortProductName: "Das OS"
|
||||||
version: "0.2.0"
|
version: "@VERSION@"
|
||||||
shortVersion: "0.2"
|
shortVersion: "@SHORT_VERSION@"
|
||||||
versionedName: "Das OS 0.2.0"
|
versionedName: "Das OS @VERSION@"
|
||||||
shortVersionedName: "Das OS 0.2"
|
shortVersionedName: "Das OS @SHORT_VERSION@"
|
||||||
bootloaderEntryName: "Das OS"
|
bootloaderEntryName: "Das OS"
|
||||||
productUrl: "https://git.das.org.ua/das/Das-OS"
|
productUrl: "https://git.das.org.ua/das/Das-OS"
|
||||||
supportUrl: "https://git.das.org.ua/das/Das-OS/issues"
|
supportUrl: "https://git.das.org.ua/das/Das-OS/issues"
|
||||||
|
|||||||
@@ -22,12 +22,27 @@ if ! grep -q '^[^#]*[[:space:]]/tmp[[:space:]]' /etc/fstab; then
|
|||||||
echo "tmpfs /tmp tmpfs defaults,nosuid,nodev 0 0" >>/etc/fstab
|
echo "tmpfs /tmp tmpfs defaults,nosuid,nodev 0 0" >>/etc/fstab
|
||||||
fi
|
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
|
if ! grep -q '^flags.* hypervisor' /proc/cpuinfo; then
|
||||||
msg "real hardware: removing virtual machine guest tools"
|
machine="real hardware"
|
||||||
rm -f /etc/runit/runsvdir/default/spice-vdagentd
|
|
||||||
xbps-remove -Ry spice-vdagent qemu-ga virtualbox-ose-guest || true
|
|
||||||
fi
|
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).
|
# Snapper, hourly snapshots and the GRUB snapshot menu (Btrfs only).
|
||||||
das-snapper-setup
|
das-snapper-setup
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Template file for 'das-installer'
|
# Template file for 'das-installer'
|
||||||
pkgname=das-installer
|
pkgname=das-installer
|
||||||
version=0.1.0
|
version=0.2.0
|
||||||
revision=1
|
revision=1
|
||||||
depends="calamares das-snapshots das-theme sudo"
|
depends="calamares das-snapshots das-theme sudo"
|
||||||
short_desc="Das OS installer: Calamares configuration and branding for the live ISO"
|
short_desc="Das OS installer: Calamares configuration and branding for the live ISO"
|
||||||
|
|||||||
@@ -4,6 +4,21 @@
|
|||||||
# which is only known inside the session. Runs once per user.
|
# which is only known inside the session. Runs once per user.
|
||||||
set -u
|
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"
|
marker="${XDG_CONFIG_HOME:-$HOME/.config}/das/session-init.done"
|
||||||
[[ -e $marker ]] && exit 0
|
[[ -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
|
wallpaper=/usr/share/backgrounds/das/das-dark.svg
|
||||||
fi
|
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.
|
# "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 }')
|
monitors=$(xrandr --listactivemonitors 2>/dev/null | awk 'NR > 1 { print $NF }')
|
||||||
if [[ -z $monitors ]]; then
|
if [[ -z $monitors ]]; then
|
||||||
@@ -28,8 +36,8 @@ fi
|
|||||||
|
|
||||||
for monitor in $monitors; do
|
for monitor in $monitors; do
|
||||||
base="/backdrop/screen0/monitor${monitor}/workspace0"
|
base="/backdrop/screen0/monitor${monitor}/workspace0"
|
||||||
set_prop "$base/last-image" string "$wallpaper"
|
set_prop xfce4-desktop "$base/last-image" string "$wallpaper"
|
||||||
set_prop "$base/image-style" int 5 # zoomed: fill the screen, keep proportions
|
set_prop xfce4-desktop "$base/image-style" int 5 # zoomed: fill the screen, keep proportions
|
||||||
done
|
done
|
||||||
|
|
||||||
mkdir -p "${marker%/*}" && touch "$marker"
|
mkdir -p "${marker%/*}" && touch "$marker"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
# Defaults go to /etc/xdg/das, which /etc/profile.d/das-xdg.sh puts in front of
|
# 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.
|
# /etc/xdg: stock Xfce files stay untouched and users' own changes still win.
|
||||||
pkgname=das-settings
|
pkgname=das-settings
|
||||||
version=0.3.0
|
version=0.4.0
|
||||||
revision=1
|
revision=1
|
||||||
create_wrksrc=yes
|
create_wrksrc=yes
|
||||||
depends="das-theme lightdm lightdm-gtk-greeter xfce4-notifyd xfce4-panel
|
depends="das-theme lightdm lightdm-gtk-greeter xfce4-notifyd xfce4-panel
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ const (
|
|||||||
firstCheck = 2 * time.Minute
|
firstCheck = 2 * time.Minute
|
||||||
checkInterval = 6 * time.Hour
|
checkInterval = 6 * time.Hour
|
||||||
checkTimeout = 5 * time.Minute
|
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 {
|
type trayApp struct {
|
||||||
@@ -29,6 +32,7 @@ type trayApp struct {
|
|||||||
checking bool
|
checking bool
|
||||||
notified []string // the updates the last notification was about
|
notified []string // the updates the last notification was about
|
||||||
window *exec.Cmd
|
window *exec.Cmd
|
||||||
|
pkgdb time.Time // package database time at the last check
|
||||||
}
|
}
|
||||||
|
|
||||||
func runTray() int {
|
func runTray() int {
|
||||||
@@ -69,6 +73,12 @@ func runTray() int {
|
|||||||
})
|
})
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
glib.TimeoutSecondsAdd(uint(pkgdbInterval.Seconds()), func() bool {
|
||||||
|
if t.notified != nil && !xbps.PkgdbTime().Equal(t.pkgdb) {
|
||||||
|
t.check()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
gtk.Main()
|
gtk.Main()
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -78,6 +88,7 @@ func (t *trayApp) check() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.checking = true
|
t.checking = true
|
||||||
|
t.pkgdb = xbps.PkgdbTime()
|
||||||
go func() {
|
go func() {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), checkTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), checkTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|||||||
@@ -4,11 +4,17 @@ package xbps
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"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.
|
// Update is one package that a full system update would change.
|
||||||
type Update struct {
|
type Update struct {
|
||||||
Name string
|
Name string
|
||||||
@@ -46,6 +52,19 @@ func Check(ctx context.Context) ([]Update, error) {
|
|||||||
return updates, nil
|
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
|
// ParseDryRun parses "xbps-install -un" output: one transaction entry per
|
||||||
// line, "<pkgver> <action> <arch> <repository> [sizes]". Other lines are skipped.
|
// line, "<pkgver> <action> <arch> <repository> [sizes]". Other lines are skipped.
|
||||||
func ParseDryRun(out string) []Update {
|
func ParseDryRun(out string) []Update {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Template file for 'das-tools'
|
# Template file for 'das-tools'
|
||||||
# In-tree package: Go sources are in files/src (FILESDIR).
|
# In-tree package: Go sources are in files/src (FILESDIR).
|
||||||
pkgname=das-tools
|
pkgname=das-tools
|
||||||
version=0.1.0
|
version=0.2.0
|
||||||
revision=1
|
revision=1
|
||||||
create_wrksrc=yes
|
create_wrksrc=yes
|
||||||
# Like build_style=go: the Go linker decides about PIE, xbps-src must not check it
|
# Like build_style=go: the Go linker decides about PIE, xbps-src must not check it
|
||||||
|
|||||||
Reference in New Issue
Block a user