Stage 4: Calamares installer and Btrfs snapshots (0.2.0)

- Package Calamares 3.4.3 (Qt6, widgets UI) with xbps-src.
- das-installer: Calamares setup for Void/runit with Das OS branding and
  slides. It copies the clean live image (live-base), builds locales and the
  host-only initramfs, rewrites kernels without sparse tails (GRUB 2.12 cannot
  read Btrfs holes at the end of a file), then removes itself.
- das-snapshots: flat Btrfs layout (@, @home, @snapshots, @var_log,
  @var_cache_xbps), snapper with hourly snapshots via cronie, grub-btrfs menu,
  snapper-rollback, and a dracut module that boots read-only snapshots with
  a RAM overlay.
- das-settings 0.2.0: start LightDM with the system locale.
- Live image: GRUB, efibootmgr and the new packages; Das OS /etc/issue.
- Build: wipe stale destdirs before building packages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
das
2026-10-19 08:59:09 +03:00
co-authored by Claude Opus 5.5
parent b7399031c7
commit ecced4e3f4
51 changed files with 849 additions and 14 deletions
@@ -0,0 +1,37 @@
---
componentName: dasos
welcomeStyleCalamares: false
welcomeExpandingLogo: true
windowExpanding: normal
windowSize: 960px,640px
windowPlacement: center
sidebar: widget
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"
bootloaderEntryName: "Das OS"
productUrl: "https://git.das.org.ua/das/Das-OS"
supportUrl: "https://git.das.org.ua/das/Das-OS/issues"
images:
productIcon: "/usr/share/icons/hicolor/scalable/apps/das-logo.svg"
productLogo: "/usr/share/icons/hicolor/scalable/apps/das-logo.svg"
productWelcome: "welcome.svg"
slideshow:
- "slide-1.svg"
- "slide-2.svg"
- "slide-3.svg"
style:
SidebarBackground: "#1b1f27"
SidebarText: "#e3e6ec"
SidebarTextCurrent: "#1b1f27"
SidebarBackgroundCurrent: "#ffd23f"
@@ -0,0 +1,28 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="440" viewBox="0 0 800 440">
<defs>
<path id="petal" d="M0 0 L19.13 -46.19 L0 -92.39 L-19.13 -46.19 Z"/>
<path id="core" d="M0 -25.4 L8.61 -46.19 L0 -66.98 L-8.61 -46.19 Z"/>
<g id="pb"><use xlink:href="#petal" fill="#2f6fde"/><use xlink:href="#core" fill="#ffd23f"/></g>
<g id="py"><use xlink:href="#petal" fill="#f5c400"/><use xlink:href="#core" fill="#1f4fa8"/></g>
<g id="star">
<use xlink:href="#pb"/><use xlink:href="#py" transform="rotate(45)"/>
<use xlink:href="#pb" transform="rotate(90)"/><use xlink:href="#py" transform="rotate(135)"/>
<use xlink:href="#pb" transform="rotate(180)"/><use xlink:href="#py" transform="rotate(225)"/>
<use xlink:href="#pb" transform="rotate(270)"/><use xlink:href="#py" transform="rotate(315)"/>
</g>
<pattern id="stitch" patternUnits="userSpaceOnUse" width="28" height="20">
<path d="M14 0 L24 10 L14 20 L4 10 Z" fill="#2f6fde"/>
<path d="M14 6 L18 10 L14 14 L10 10 Z" fill="#f5c400"/>
</pattern>
</defs>
<rect width="800" height="440" fill="#f6f7fa"/>
<rect y="420" width="800" height="20" fill="url(#stitch)"/>
<use xlink:href="#star" transform="translate(150 210) scale(1.15)"/>
<g font-family="Inter, sans-serif" fill="#1f2430">
<text x="300" y="150" font-size="34" font-weight="600">Ласкаво просимо!</text>
<text x="300" y="205" font-size="19">Das OS — легка система на Void Linux</text>
<text x="300" y="235" font-size="19">з робочим столом Xfce, українською</text>
<text x="300" y="265" font-size="19">мовою та звичними програмами.</text>
<text x="300" y="295" font-size="19"></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1,28 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="440" viewBox="0 0 800 440">
<defs>
<path id="petal" d="M0 0 L19.13 -46.19 L0 -92.39 L-19.13 -46.19 Z"/>
<path id="core" d="M0 -25.4 L8.61 -46.19 L0 -66.98 L-8.61 -46.19 Z"/>
<g id="pb"><use xlink:href="#petal" fill="#2f6fde"/><use xlink:href="#core" fill="#ffd23f"/></g>
<g id="py"><use xlink:href="#petal" fill="#f5c400"/><use xlink:href="#core" fill="#1f4fa8"/></g>
<g id="star">
<use xlink:href="#pb"/><use xlink:href="#py" transform="rotate(45)"/>
<use xlink:href="#pb" transform="rotate(90)"/><use xlink:href="#py" transform="rotate(135)"/>
<use xlink:href="#pb" transform="rotate(180)"/><use xlink:href="#py" transform="rotate(225)"/>
<use xlink:href="#pb" transform="rotate(270)"/><use xlink:href="#py" transform="rotate(315)"/>
</g>
<pattern id="stitch" patternUnits="userSpaceOnUse" width="28" height="20">
<path d="M14 0 L24 10 L14 20 L4 10 Z" fill="#2f6fde"/>
<path d="M14 6 L18 10 L14 14 L10 10 Z" fill="#f5c400"/>
</pattern>
</defs>
<rect width="800" height="440" fill="#f6f7fa"/>
<rect y="420" width="800" height="20" fill="url(#stitch)"/>
<use xlink:href="#star" transform="translate(150 210) scale(1.15)"/>
<g font-family="Inter, sans-serif" fill="#1f2430">
<text x="300" y="150" font-size="34" font-weight="600">Знімки системи</text>
<text x="300" y="205" font-size="19">Btrfs і snapper щогодини зберігають</text>
<text x="300" y="235" font-size="19">стан системи. Попередній знімок можна</text>
<text x="300" y="265" font-size="19">завантажити з меню GRUB і повернути</text>
<text x="300" y="295" font-size="19">командою sudo snapper-rollback.</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1,28 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="440" viewBox="0 0 800 440">
<defs>
<path id="petal" d="M0 0 L19.13 -46.19 L0 -92.39 L-19.13 -46.19 Z"/>
<path id="core" d="M0 -25.4 L8.61 -46.19 L0 -66.98 L-8.61 -46.19 Z"/>
<g id="pb"><use xlink:href="#petal" fill="#2f6fde"/><use xlink:href="#core" fill="#ffd23f"/></g>
<g id="py"><use xlink:href="#petal" fill="#f5c400"/><use xlink:href="#core" fill="#1f4fa8"/></g>
<g id="star">
<use xlink:href="#pb"/><use xlink:href="#py" transform="rotate(45)"/>
<use xlink:href="#pb" transform="rotate(90)"/><use xlink:href="#py" transform="rotate(135)"/>
<use xlink:href="#pb" transform="rotate(180)"/><use xlink:href="#py" transform="rotate(225)"/>
<use xlink:href="#pb" transform="rotate(270)"/><use xlink:href="#py" transform="rotate(315)"/>
</g>
<pattern id="stitch" patternUnits="userSpaceOnUse" width="28" height="20">
<path d="M14 0 L24 10 L14 20 L4 10 Z" fill="#2f6fde"/>
<path d="M14 6 L18 10 L14 14 L10 10 Z" fill="#f5c400"/>
</pattern>
</defs>
<rect width="800" height="440" fill="#f6f7fa"/>
<rect y="420" width="800" height="20" fill="url(#stitch)"/>
<use xlink:href="#star" transform="translate(150 210) scale(1.15)"/>
<g font-family="Inter, sans-serif" fill="#1f2430">
<text x="300" y="150" font-size="34" font-weight="600">Ваші файли в безпеці</text>
<text x="300" y="205" font-size="19">Домашня тека лежить в окремому</text>
<text x="300" y="235" font-size="19">підтомі й не входить до знімків,</text>
<text x="300" y="265" font-size="19">тому відкат системи її не зачіпає.</text>
<text x="300" y="295" font-size="19"></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1,20 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="480" height="300" viewBox="0 0 480 300">
<defs>
<path id="petal" d="M0 0 L19.13 -46.19 L0 -92.39 L-19.13 -46.19 Z"/>
<path id="core" d="M0 -25.4 L8.61 -46.19 L0 -66.98 L-8.61 -46.19 Z"/>
<g id="pb"><use xlink:href="#petal" fill="#2f6fde"/><use xlink:href="#core" fill="#ffd23f"/></g>
<g id="py"><use xlink:href="#petal" fill="#f5c400"/><use xlink:href="#core" fill="#1f4fa8"/></g>
<g id="star">
<use xlink:href="#pb"/><use xlink:href="#py" transform="rotate(45)"/>
<use xlink:href="#pb" transform="rotate(90)"/><use xlink:href="#py" transform="rotate(135)"/>
<use xlink:href="#pb" transform="rotate(180)"/><use xlink:href="#py" transform="rotate(225)"/>
<use xlink:href="#pb" transform="rotate(270)"/><use xlink:href="#py" transform="rotate(315)"/>
</g>
<pattern id="stitch" patternUnits="userSpaceOnUse" width="28" height="20">
<path d="M14 0 L24 10 L14 20 L4 10 Z" fill="#2f6fde"/>
<path d="M14 6 L18 10 L14 14 L10 10 Z" fill="#f5c400"/>
</pattern>
</defs>
<use xlink:href="#star" transform="translate(240 130) scale(1.15)"/>
<text x="240" y="285" text-anchor="middle" font-family="Inter, sans-serif" font-size="34" font-weight="600" fill="#2f6fde">Das OS</text>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1,13 @@
---
efiBootLoader: "grub"
kernelSearchPath: "/boot"
kernelPattern: "^vmlinuz.*"
kernelParams: [ "quiet", "loglevel=3" ]
grubInstall: "grub-install"
grubMkconfig: "grub-mkconfig"
grubCfg: "/boot/grub/grub.cfg"
grubProbe: "grub-probe"
efiBootMgr: "efibootmgr"
efiBootloaderId: "dasos"
installEFIFallback: true
installHybridGRUB: false
@@ -0,0 +1,10 @@
---
displaymanagers:
- lightdm
defaultDesktopEnvironment:
executable: "startxfce4"
desktopFile: "xfce"
basicSetup: false
sysconfigSetup: false
lightdm:
preferred_greeters: ["lightdm-gtk-greeter.desktop"]
@@ -0,0 +1,4 @@
---
restartNowMode: user-unchecked
restartNowCommand: "loginctl reboot"
notifyOnFinished: false
@@ -0,0 +1,9 @@
---
crypttabOptions: luks
tmpOptions:
default:
tmpfs: true
options: "defaults,nosuid,nodev,mode=1777"
ssd:
tmpfs: true
options: "defaults,noatime,nosuid,nodev,mode=1777"
@@ -0,0 +1,13 @@
---
overwrite: false
prefer_grub_d: false
keep_distributor: false
kernel_params: [ "quiet", "loglevel=3" ]
defaults:
GRUB_TIMEOUT: 5
GRUB_DEFAULT: "saved"
GRUB_DISABLE_SUBMENU: true
GRUB_TERMINAL_OUTPUT: "console"
GRUB_DISABLE_RECOVERY: true
GRUB_DISABLE_OS_PROBER: false
always_use_defaults: false
@@ -0,0 +1,7 @@
---
xOrgConfFileName: "/etc/X11/xorg.conf.d/00-keyboard.conf"
convertedKeymapPath: "/usr/share/kbd/keymaps/xkb"
writeEtcDefaultKeyboard: false
configure:
kwin: false
gnome: false
@@ -0,0 +1,5 @@
---
region: "Europe"
zone: "Kyiv"
geoip:
style: none
@@ -0,0 +1,6 @@
# Void has no systemd: only D-Bus needs a machine id (/var/lib/dbus/machine-id).
---
systemd: false
dbus: true
dbus-symlink: false
entropy-copy: false
@@ -0,0 +1,48 @@
---
extraMounts:
- device: proc
fs: proc
mountPoint: /proc
- device: sys
fs: sysfs
mountPoint: /sys
- device: /dev
mountPoint: /dev
options: [ bind ]
- device: tmpfs
fs: tmpfs
mountPoint: /run
- device: /run/udev
mountPoint: /run/udev
options: [ bind ]
- device: efivarfs
fs: efivarfs
mountPoint: /sys/firmware/efi/efivars
efi: true
# The flat layout that snapper-rollback expects: the root in @ and snapshots
# in @snapshots. Home, logs and the package cache stay out of root snapshots,
# so a rollback never touches personal files.
btrfsSubvolumes:
- mountPoint: /
subvolume: /@
- mountPoint: /home
subvolume: /@home
- mountPoint: /.snapshots
subvolume: /@snapshots
- mountPoint: /var/log
subvolume: /@var_log
- mountPoint: /var/cache/xbps
subvolume: /@var_cache_xbps
mountOptions:
- filesystem: default
options: [ defaults ]
- filesystem: efi
options: [ defaults, umask=0077 ]
- filesystem: btrfs
options: [ defaults, noatime, compress=zstd:1 ]
- filesystem: ext4
options: [ defaults, noatime ]
- filesystem: xfs
options: [ defaults, noatime ]
@@ -0,0 +1,10 @@
# The target is a copy of the live system: drop the installer and whatever was
# installed only for it.
---
backend: xbps
skip_if_no_internet: false
update_db: false
update_system: false
operations:
- try_remove:
- das-installer
@@ -0,0 +1,29 @@
---
efi:
mountPoint: "/boot/efi"
recommendedSize: 512MiB
minimumSize: 64MiB
label: "EFI"
userSwapChoices:
- none
- small
- suspend
initialSwapChoice: none
drawNestedPartitions: false
alwaysShowPartitionLabels: true
allowManualPartitioning: true
initialPartitioningChoice: none
# Btrfs subvolumes (see mount.conf) give snapper snapshots and rollback.
defaultFileSystemType: "btrfs"
availableFileSystemTypes: [ "btrfs", "ext4", "xfs" ]
# Disk encryption needs extra initramfs and GRUB setup that Das OS does not
# have yet.
enableLuksAutomatedPartitioning: false
essentialMounts: [ "live-*", "control", "ventoy" ]
lvm:
enable: false
@@ -0,0 +1,7 @@
---
dontChroot: false
timeout: 900
verbose: true
script:
- command: "/usr/libexec/das/installer/postinstall"
timeout: 900
@@ -0,0 +1,9 @@
# The first snapshot is the freshly installed system. grub-mkconfig then adds
# it to the boot menu through grub-btrfs.
---
dontChroot: false
timeout: 300
verbose: true
script:
- "-snapper --no-dbus -c root create -d 'Fresh install' -c number --userdata important=yes"
- "-grub-mkconfig -o /boot/grub/grub.cfg"
@@ -0,0 +1,5 @@
---
dontChroot: true
timeout: 60
script:
- "/usr/libexec/das/installer/mount-source"
@@ -0,0 +1,7 @@
# Copy the clean live image that shellprocess@source mounts, not the running
# live root (see mount-source).
---
unpack:
- source: "/run/das-installer/root"
sourcefs: "file"
destination: ""
@@ -0,0 +1,53 @@
---
defaultGroups:
- name: users
must_exist: true
system: true
- name: wheel
must_exist: true
system: true
- audio
- video
- input
- storage
- network
- optical
- scanner
- lp
- kvm
- plugdev
- name: bluetooth
must_exist: false
system: true
sudoersGroup: wheel
sudoersConfigureWithGroup: true
autologinGroup: autologin
setRootPassword: true
doReusePassword: true
displayAutologin: true
doAutologin: false
passwordRequirements:
minLength: 4
maxLength: -1
allowWeakPasswords: true
allowWeakPasswordsDefault: true
user:
shell: /bin/bash
forbidden_names: [ root, live ]
home_permissions: "o700"
hostname:
location: EtcFile
writeHostsFile: true
template: "${login}-dasos"
forbidden_names: [ localhost ]
presets:
fullName:
editable: true
loginName:
editable: true
@@ -0,0 +1,24 @@
---
showSupportUrl: true
showKnownIssuesUrl: false
showReleaseNotesUrl: false
showDonateUrl: false
requirements:
requiredStorage: 15
requiredRam: 1.5
internetCheckUrl: https://voidlinux.org
check:
- storage
- ram
- power
- internet
- root
- screen
required:
- storage
- ram
- root
geoip:
style: none
@@ -0,0 +1,54 @@
# Calamares settings for Das OS (Void Linux, runit).
---
modules-search: [ local ]
instances:
- id: source
module: shellprocess
config: shellprocess-source.conf
- id: postinstall
module: shellprocess
config: shellprocess-postinstall.conf
- id: snapshot
module: shellprocess
config: shellprocess-snapshot.conf
sequence:
- show:
- welcome
- locale
- keyboard
- partition
- users
- summary
- exec:
- partition
- mount
- shellprocess@source
- unpackfs
- machineid
- locale
- keyboard
- localecfg
- fstab
- users
- displaymanager
- networkcfg
- hwclock
- grubcfg
- shellprocess@postinstall
- packages
- bootloader
- shellprocess@snapshot
- umount
- show:
- finished
branding: dasos
prompt-install: true
dont-chroot: false
oem-setup: false
disable-cancel: false
disable-cancel-during-exec: false
hide-back-and-next-during-exec: true
quit-at-end: false