Compare commits
19
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d2d6303d3 | ||
|
|
2df559d0ae | ||
|
|
dd26a367ac | ||
|
|
edab4fe6a6 | ||
|
|
18476a6bec | ||
|
|
51963c4223 | ||
|
|
7b7789fbfa | ||
|
|
2afe810d73 | ||
|
|
2e7ea3e5b5 | ||
|
|
80b378fd06 | ||
|
|
824e27c133 | ||
|
|
c96fb4925c | ||
|
|
ac2eaf49d5 | ||
|
|
ad23a62417 | ||
|
|
d657dca512 | ||
|
|
8e182a7311 | ||
|
|
191460437f | ||
|
|
ae581d456b | ||
|
|
abde918683 |
@@ -256,7 +256,7 @@ jobs:
|
||||
# ------------------------------------------------------------
|
||||
|
||||
- name: Install envsubst dependencies
|
||||
if: github.event_name != 'pull_request' && env.IS_TEST_BUILD == 'false'
|
||||
if: github.event_name != 'pull_request'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y gettext
|
||||
@@ -264,9 +264,12 @@ jobs:
|
||||
# ------------------------------------------------------------
|
||||
# Install Cosign
|
||||
# ------------------------------------------------------------
|
||||
# HINWEIS (labwc-Zweig): Auch Test-Tags werden signiert, damit sie die
|
||||
# lokale sigstoreSigned-Policy bestehen. Test-Images bleiben an ihrem
|
||||
# test-*-Tag erkennbar; :stable wird dadurch nicht beruehrt.
|
||||
|
||||
- name: Install Cosign
|
||||
if: github.event_name != 'pull_request' && env.IS_TEST_BUILD == 'false'
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: sigstore/cosign-installer@v4.1.2
|
||||
|
||||
# ------------------------------------------------------------
|
||||
@@ -274,7 +277,7 @@ jobs:
|
||||
# ------------------------------------------------------------
|
||||
|
||||
- name: Sign container image (Recursive Digest)
|
||||
if: github.event_name != 'pull_request' && env.IS_TEST_BUILD == 'false'
|
||||
if: github.event_name != 'pull_request'
|
||||
env:
|
||||
COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }}
|
||||
COSIGN_PASSWORD: ""
|
||||
@@ -291,7 +294,7 @@ jobs:
|
||||
OUTER_DIGEST=$(
|
||||
skopeo inspect \
|
||||
--creds "${{ github.repository_owner }}:${{ secrets.REGISTRY }}" \
|
||||
"docker://${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }}" \
|
||||
"docker://${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}" \
|
||||
| jq -r .Digest
|
||||
)
|
||||
|
||||
|
||||
+99
-5
@@ -26,7 +26,10 @@ COPY build /build
|
||||
###############################################################################
|
||||
# BASE IMAGE
|
||||
###############################################################################
|
||||
FROM quay.io/fedora/fedora-kinoite:44
|
||||
# labwc/Noctalia-Zweig: minimale fedora-bootc-Basis statt Kinoite.
|
||||
# Der komplette Desktop (labwc, greetd, Noctalia) wird in den Layern unten
|
||||
# aufgebaut. Der Kinoite-Stand bleibt auf Branch main / Tag :stable erhalten.
|
||||
FROM quay.io/fedora/fedora-bootc:44
|
||||
|
||||
### /opt (Unverändert)
|
||||
# RUN rm /opt && mkdir /opt
|
||||
@@ -42,13 +45,42 @@ RUN --mount=type=bind,from=build-ctx,source=/build/10-repos.sh,target=/tmp/10-re
|
||||
--mount=type=tmpfs,dst=/tmp \
|
||||
bash /tmp/10-repos.sh && dnf5 clean all
|
||||
|
||||
# LAYER 2: Unerwünschte Pakete entfernen (Bereinigungsschicht - vorgezogen)
|
||||
# LAYER 2: Unerwünschte Pakete entfernen (Guard - auf bootc-Basis meist No-Op)
|
||||
RUN --mount=type=bind,from=build-ctx,source=/build/20-remove-packages.sh,target=/tmp/20-remove-packages.sh \
|
||||
--mount=type=cache,dst=/var/cache \
|
||||
--mount=type=cache,dst=/var/log \
|
||||
--mount=type=tmpfs,dst=/tmp \
|
||||
bash /tmp/20-remove-packages.sh
|
||||
|
||||
# LAYER 2b: labwc Desktop-Basis (Compositor, Portale, Audio, Docking-Tools)
|
||||
RUN --mount=type=bind,from=build-ctx,source=/build/20-desktop-labwc.sh,target=/tmp/20-desktop-labwc.sh \
|
||||
--mount=type=cache,dst=/var/cache \
|
||||
--mount=type=cache,dst=/var/log \
|
||||
--mount=type=tmpfs,dst=/tmp \
|
||||
bash /tmp/20-desktop-labwc.sh
|
||||
|
||||
# LAYER 2c: Login-Stack (greetd + tuigreet-Fallback + Noctalia-Greeter)
|
||||
RUN --mount=type=bind,from=build-ctx,source=/build/21-greetd.sh,target=/tmp/21-greetd.sh \
|
||||
--mount=type=cache,dst=/var/cache \
|
||||
--mount=type=cache,dst=/var/log \
|
||||
--mount=type=tmpfs,dst=/tmp \
|
||||
bash /tmp/21-greetd.sh
|
||||
|
||||
# LAYER 2d: Noctalia Shell v5 (nativ, aus Fedora-Repos)
|
||||
RUN --mount=type=bind,from=build-ctx,source=/build/22-noctalia.sh,target=/tmp/22-noctalia.sh \
|
||||
--mount=type=cache,dst=/var/cache \
|
||||
--mount=type=cache,dst=/var/log \
|
||||
--mount=type=tmpfs,dst=/tmp \
|
||||
bash /tmp/22-noctalia.sh
|
||||
|
||||
# LAYER 2e: Plymouth Bootsplash (Text-Theme + Initramfs-Rebuild)
|
||||
RUN --mount=type=bind,from=build-ctx,source=/build/23-plymouth.sh,target=/tmp/23-plymouth.sh \
|
||||
--mount=type=bind,from=build-ctx,source=/build/plymouth-theme,target=/tmp/plymouth-theme \
|
||||
--mount=type=cache,dst=/var/cache \
|
||||
--mount=type=cache,dst=/var/log \
|
||||
--mount=type=tmpfs,dst=/tmp \
|
||||
bash /tmp/23-plymouth.sh
|
||||
|
||||
# LAYER 3: Virtualisierung & Tools (Großer Download - stark gecacht)
|
||||
RUN --mount=type=bind,from=build-ctx,source=/build/30-virt.sh,target=/tmp/30-virt.sh \
|
||||
--mount=type=cache,dst=/var/cache \
|
||||
@@ -90,24 +122,86 @@ RUN chmod 0644 /etc/containers/policy.json /etc/pki/containers/cosign.pub && \
|
||||
# 2. Kopiere die Systemd-Overrides als Vendor-Drop-ins (kein /etc/-Override im Image)
|
||||
COPY configs/bootc-timer-override.conf /usr/lib/systemd/system/bootc-fetch-apply-updates.timer.d/override.conf
|
||||
COPY configs/bootc-override.conf /usr/lib/systemd/system/bootc-fetch-apply-updates.service.d/override.conf
|
||||
COPY configs/remount-fs-ostree-skip.conf /usr/lib/systemd/system/systemd-remount-fs.service.d/skip-on-ostree.conf
|
||||
|
||||
# 3. Kopiere das Benachrichtigungs-Skript
|
||||
# 2b. Kernel-Args (Bootsplash: rhgb quiet)
|
||||
COPY configs/kargs-plymouth.toml /usr/lib/bootc/kargs.d/plymouth.toml
|
||||
|
||||
# 3. Kopiere die Session-Helfer und Desktop-Defaults
|
||||
COPY --chmod=755 scripts/notify-bootc-user.sh /usr/bin/
|
||||
COPY --chmod=755 scripts/kanshi-autoconfig /usr/bin/kanshi-autoconfig
|
||||
COPY --chmod=755 scripts/seed-labwc-skel.sh /usr/bin/seed-labwc-skel
|
||||
COPY --chmod=755 scripts/bing-wallpaper.sh /usr/bin/bing-wallpaper.sh
|
||||
COPY --chmod=755 scripts/bing-wallpaper-toggle.sh /usr/bin/bing-wallpaper-toggle.sh
|
||||
|
||||
# Desktop-Datei fuer den Toggle (Noctalia-Launcher findet ihn als App)
|
||||
COPY configs/applications/bing-wallpaper-toggle.desktop /usr/share/applications/bing-wallpaper-toggle.desktop
|
||||
|
||||
# User-Units (Bing-Wallpaper-Timer). --chmod: In-Image-Units muessen 644
|
||||
# sein (world-writable Units warnt systemd lautstark an).
|
||||
COPY --chmod=644 configs/systemd/user/bing-wallpaper.service /usr/lib/systemd/user/bing-wallpaper.service
|
||||
COPY --chmod=644 configs/systemd/user/bing-wallpaper.timer /usr/lib/systemd/user/bing-wallpaper.timer
|
||||
|
||||
# labwc/kanshi-Defaults fuer neue Benutzer (Bestand bleibt via seed-labwc-skel)
|
||||
COPY configs/skel/ /etc/skel/
|
||||
|
||||
# Wayland-Session fuer Display-Manager (Greeter-Auswahl)
|
||||
COPY configs/wayland-sessions/labwc.desktop /usr/share/wayland-sessions/labwc.desktop
|
||||
|
||||
# Fontconfig-Defaults (Noto statt DejaVu)
|
||||
COPY configs/fontconfig/60-fluffy-noto.conf /usr/share/fontconfig/conf.d/60-fluffy-noto.conf
|
||||
|
||||
# greetd-Konfiguration (Noctalia-Greeter + tuigreet-Fallback dokumentiert)
|
||||
COPY configs/greetd/config.toml /etc/greetd/config.toml
|
||||
|
||||
# Noctalia-Greeter Standardwerte (de-Tastatur etc., werden per tmpfiles
|
||||
# beim Erst-Boot nach /var/lib/noctalia-greeter/greeter.toml kopiert)
|
||||
COPY configs/noctalia-greeter/greeter.toml.default /usr/share/noctalia-greeter/greeter.toml.default
|
||||
COPY configs/tmpfiles/noctalia-greeter-seed.conf /usr/lib/tmpfiles.d/noctalia-greeter-seed.conf
|
||||
|
||||
# Fail-fast + Selbstheilung: Der Session-Wrapper-Pfad wird aus dem real
|
||||
# installierten Paket aufgeloest und in die greetd-Config uebernommen.
|
||||
# (Terra paketiert eigenstaendig, z.B. /usr/sbin statt /usr/bin.)
|
||||
# Fehlt Wrapper, D-Bus, polkit oder Session -> Build-Abbruch statt
|
||||
# defektem Login-Screen.
|
||||
RUN set -u; \
|
||||
id greeter >/dev/null || { echo "FEHLER: Service-User greeter fehlt (21-greetd.sh pruefen)"; exit 1; }; \
|
||||
grep -q 'pam_gnome_keyring\.so' /etc/pam.d/greetd || { echo "FEHLER: Keyring-PAM in /etc/pam.d/greetd fehlt"; exit 1; }; \
|
||||
test -f /usr/lib64/security/pam_gnome_keyring.so || { echo "FEHLER: pam_gnome_keyring.so fehlt (Paket gnome-keyring-pam?)"; exit 1; }; \
|
||||
wrapper="$(command -v noctalia-greeter-session || true)"; \
|
||||
echo "Gefundener Wrapper: ${wrapper}"; \
|
||||
test -n "${wrapper}" || { echo "FEHLER: noctalia-greeter-session nicht installiert (Terra-Repo/includepkgs pruefen)"; exit 1; }; \
|
||||
sed -i "s|^command = \".*\"|command = \"${wrapper}\"|" /etc/greetd/config.toml; \
|
||||
grep -Eq "^command = \"${wrapper}\"" /etc/greetd/config.toml || { echo "FEHLER: Wrapper-Pfad konnte nicht in /etc/greetd/config.toml uebernommen werden"; exit 1; }; \
|
||||
command -v dbus-run-session >/dev/null || { echo "FEHLER: dbus-run-session fehlt"; exit 1; }; \
|
||||
test -x /usr/bin/pkexec || { echo "FEHLER: pkexec fehlt"; exit 1; }; \
|
||||
test -f /usr/share/wayland-sessions/labwc.desktop || { echo "FEHLER: labwc-Session fehlt"; exit 1; }; \
|
||||
echo "Greeter-Check OK (${wrapper})"
|
||||
|
||||
# =============================================================================
|
||||
# SYSTEMD SERVICES (Modern Bootc Architecture)
|
||||
# =============================================================================
|
||||
|
||||
# 4. Kopiere den Systemd-Service für den Erst-Boot von Flatpak
|
||||
COPY configs/flatpak-preinstall.service /usr/lib/systemd/system/flatpak-preinstall.service
|
||||
COPY --chmod=644 configs/flatpak-preinstall.service /usr/lib/systemd/system/flatpak-preinstall.service
|
||||
|
||||
# 5. Aktiviere Services (Presets greifen nicht bei COPY-Dateien)
|
||||
# HINWEIS: greetd wird bereits in 21-greetd.sh enabled; hier als
|
||||
# Doku/Netz doppelt abgesichert (idempotent).
|
||||
RUN systemctl enable \
|
||||
# libvirtd.service \
|
||||
# virtlogd.service \
|
||||
podman.socket \
|
||||
bootc-fetch-apply-updates.timer \
|
||||
flatpak-preinstall.service
|
||||
flatpak-preinstall.service \
|
||||
greetd.service
|
||||
|
||||
# User-Units (Bing) liegen bereit, werden aber NICHT global aktiviert:
|
||||
# Bing-Timer ist Opt-in per Launcher-App "Bing-Wallpaper an/aus".
|
||||
|
||||
# SELinux-Labels fuer Greeter/Skel/Sessions (Fehler tolerieren, Labels
|
||||
# werden beim Deployment ggf. erneut gesetzt)
|
||||
RUN restorecon -Rv /etc/greetd /etc/skel /usr/share/wayland-sessions 2>/dev/null || true
|
||||
|
||||
###############################################################################
|
||||
# FINAL CLEANUP
|
||||
|
||||
@@ -124,6 +124,9 @@ _rootful_load_image $target_image $tag=default_tag:
|
||||
fi
|
||||
|
||||
# Build a bootc bootable image using Bootc Image Builder (BIB)
|
||||
# HINWEIS: Bei Typ "iso" wird die Image-Referenz im Kickstart (iso/iso.toml)
|
||||
# automatisch auf $target_image:$tag umgeschrieben. So installiert eine lokal
|
||||
# gebaute Test-ISO auch das Test-Image und nicht :stable.
|
||||
_build-bib $target_image $tag $type $config: (_rootful_load_image target_image tag)
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
@@ -134,6 +137,16 @@ _build-bib $target_image $tag $type $config: (_rootful_load_image target_image t
|
||||
|
||||
BUILDTMP=$(mktemp -p "${PWD}" -d -t _build-bib.XXXXXXXXXX)
|
||||
|
||||
CONFIG_ABS="$(pwd)/${config}"
|
||||
CONFIGTMP=""
|
||||
if [[ "${type}" == "iso" ]]; then
|
||||
CONFIGTMP=$(mktemp -p "${PWD}" -d -t _build-bib-config.XXXXXXXXXX)
|
||||
sed "s|humocs-man.duckdns.org/humocs-man/fluffy-pancake:stable|{{ target_image }}:{{ tag }}|g" \
|
||||
"${CONFIG_ABS}" > "$CONFIGTMP/config.toml"
|
||||
CONFIG_ABS="$CONFIGTMP/config.toml"
|
||||
echo "==> ISO-Kickstart zeigt auf {{ target_image }}:{{ tag }}"
|
||||
fi
|
||||
|
||||
sudo podman run \
|
||||
--rm \
|
||||
-it \
|
||||
@@ -141,7 +154,7 @@ _build-bib $target_image $tag $type $config: (_rootful_load_image target_image t
|
||||
--pull=newer \
|
||||
--net=host \
|
||||
--security-opt label=type:unconfined_t \
|
||||
-v "$(pwd)/${config}":/config.toml:ro \
|
||||
-v "${CONFIG_ABS}":/config.toml:ro \
|
||||
-v "$BUILDTMP":/output \
|
||||
-v /var/lib/containers/storage:/var/lib/containers/storage \
|
||||
"${bib_image}" \
|
||||
@@ -151,6 +164,7 @@ _build-bib $target_image $tag $type $config: (_rootful_load_image target_image t
|
||||
mkdir -p output
|
||||
sudo mv -f $BUILDTMP/* output/
|
||||
sudo rmdir $BUILDTMP
|
||||
if [[ -n "$CONFIGTMP" ]]; then rm -rf "$CONFIGTMP"; fi
|
||||
sudo chown -R $USER:$USER output/
|
||||
|
||||
# Rebuild-Schritt: Führt vor BIB ein lokales 'podman build' aus
|
||||
@@ -188,6 +202,41 @@ rebuild-raw $target_image=("localhost/" + image_name) $tag=default_tag: && (_reb
|
||||
[group('Build Virtual Machine Image')]
|
||||
rebuild-iso $target_image=("localhost/" + image_name) $tag=default_tag: && (_rebuild-bib target_image tag "iso" "iso/iso.toml")
|
||||
|
||||
# ==============================================================================
|
||||
# TEST TARGETS (nur lokale Test-Disks, Image bleibt sauber)
|
||||
# ==============================================================================
|
||||
|
||||
# Injiziert einen Test-User in ein gebautes Plattenabbild (qcow2/raw).
|
||||
# Das Container-Image wird NICHT veraendert - nur die lokale Test-Disk.
|
||||
# ISO braucht das nicht (Anaconda legt den User bei Installation an).
|
||||
# Passwort: keine ':' und keine Shell-Sonderzeichen ($, `, !, \).
|
||||
[group('Test')]
|
||||
seed-testuser type="qcow2" user="test" password="test123":
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
if [[ "{{ type }}" == "iso" ]]; then
|
||||
echo "FEHLER: Bei ISO den User im Anaconda-Installer anlegen, kein Seed noetig."
|
||||
exit 1
|
||||
fi
|
||||
if [[ "{{ password }}" == *:* ]]; then
|
||||
echo "FEHLER: Passwort darf kein ':' enthalten (chpasswd-Format)."
|
||||
exit 1
|
||||
fi
|
||||
image_file="output/{{ type }}/disk.{{ type }}"
|
||||
if [[ ! -f "${image_file}" ]]; then
|
||||
echo "FEHLER: ${image_file} nicht gefunden. Erst 'just build-{{ type }} ...' ausfuehren."
|
||||
exit 1
|
||||
fi
|
||||
if ! command -v virt-customize >/dev/null; then
|
||||
echo "FEHLER: virt-customize fehlt. Installieren mit: sudo dnf install -y guestfs-tools"
|
||||
exit 1
|
||||
fi
|
||||
echo "==> Injiziere Test-User '{{ user }}' in ${image_file} (nur Test-Disk)"
|
||||
sudo virt-customize -a "${image_file}" \
|
||||
--selinux-relabel \
|
||||
--run-command "useradd -m -G wheel '{{ user }}' && echo '{{ user }}:{{ password }}' | chpasswd"
|
||||
echo "==> Fertig. Login als '{{ user }}', sudo via wheel-Gruppe."
|
||||
|
||||
# ==============================================================================
|
||||
# RUN TARGETS
|
||||
# ==============================================================================
|
||||
|
||||
+24
-1
@@ -6,4 +6,27 @@ dnf5 install -y \
|
||||
https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-${FEDORA_VERSION}.noarch.rpm \
|
||||
https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-${FEDORA_VERSION}.noarch.rpm
|
||||
|
||||
dnf5 clean all
|
||||
# Terra-Repository (Fyralabs) fuer noctalia-greeter.
|
||||
# Die Shell (Paket `noctalia`, v5) liegt in den offiziellen Fedora-Repos,
|
||||
# der Greeter aktuell NUR in Terra (Stand: Fedora 44).
|
||||
# Siehe https://docs.noctalia.dev/greeter/installation/
|
||||
dnf5 install -y --nogpgcheck \
|
||||
--repofrompath "terra,https://repos.fyralabs.com/terra${FEDORA_VERSION}" \
|
||||
terra-release
|
||||
|
||||
# Terra strikt einschraenken: NUR noctalia-greeter darf von dort kommen.
|
||||
# Schuetzt Fedora- und RPMFusion-Pakete vor Shadowing/Konflikten durch das
|
||||
# Dritt-Repo (Terra ist ein Voll-Repo mit eigener Paketierung).
|
||||
# skip_if_unavailable: Terras CDN liefert wiederkehrend inkonsistente
|
||||
# repomd.xml (bekannte Incidents). Ein hickup dort darf weder den Image-
|
||||
# noch den ISO-Build (BIB-Depsolve liest alle aktiven Repos) killen -
|
||||
# der Greeter ist zu dem Zeitpunkt laengst installiert.
|
||||
for repo in /etc/yum.repos.d/terra*.repo; do
|
||||
[[ -e "${repo}" ]] || continue
|
||||
grep -q '^includepkgs=' "${repo}" || sed -i '/^\[/a includepkgs=noctalia-greeter*' "${repo}"
|
||||
grep -q '^skip_if_unavailable=' "${repo}" || sed -i '/^\[/a skip_if_unavailable=True' "${repo}"
|
||||
echo "--- ${repo} ---"
|
||||
cat "${repo}"
|
||||
done
|
||||
|
||||
dnf5 clean all
|
||||
|
||||
Executable
+101
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/bash
|
||||
set -eoux pipefail
|
||||
|
||||
###############################################################################
|
||||
# Transaction: labwc Desktop-Basis (Compositor + Wayland-Stack + Docking)
|
||||
# Basiert auf fedora-bootc (kein KDE). Noctalia-Shell und Greeter kommen
|
||||
# in eigenen Layern (21/22), damit sie unabhaengig gecacht werden.
|
||||
###############################################################################
|
||||
echo "Installing labwc desktop base..."
|
||||
|
||||
# Kern-Pakete (hart erforderlich)
|
||||
dnf5 install -y \
|
||||
--allowerasing \
|
||||
labwc \
|
||||
xorg-x11-server-Xwayland \
|
||||
kanshi \
|
||||
wlr-randr \
|
||||
swaybg \
|
||||
xdg-desktop-portal \
|
||||
xdg-desktop-portal-wlr \
|
||||
xdg-desktop-portal-gtk \
|
||||
pipewire \
|
||||
pipewire-pulseaudio \
|
||||
wireplumber \
|
||||
NetworkManager \
|
||||
kitty \
|
||||
wl-clipboard \
|
||||
xdg-user-dirs \
|
||||
libnotify \
|
||||
upower \
|
||||
power-profiles-daemon \
|
||||
bolt \
|
||||
bluez \
|
||||
cups \
|
||||
ipp-usb \
|
||||
system-config-printer \
|
||||
avahi \
|
||||
accountsservice \
|
||||
google-noto-sans-fonts \
|
||||
google-noto-sans-mono-fonts \
|
||||
google-noto-color-emoji-fonts \
|
||||
glibc-langpack-de \
|
||||
adwaita-icon-theme \
|
||||
adwaita-cursor-theme \
|
||||
gnome-keyring \
|
||||
gnome-keyring-pam \
|
||||
libsecret \
|
||||
thunar \
|
||||
thunar-volman \
|
||||
thunar-archive-plugin \
|
||||
file-roller \
|
||||
tumbler \
|
||||
gvfs \
|
||||
firewalld \
|
||||
firewall-config \
|
||||
nss-mdns \
|
||||
wdisplays \
|
||||
brightnessctl \
|
||||
swaylock \
|
||||
playerctl \
|
||||
evince \
|
||||
loupe \
|
||||
gnome-text-editor \
|
||||
seahorse \
|
||||
cups-browsed
|
||||
|
||||
# Optionale Pakete (duerfen fehlen -> --skip-unavailable, eigener Aufruf,
|
||||
# damit ein fehlendes Optionales den Kern nicht zu Fall bringt)
|
||||
dnf5 install -y \
|
||||
--allowerasing \
|
||||
--skip-unavailable \
|
||||
ddcutil \
|
||||
fwupd \
|
||||
cliphist \
|
||||
wlsunset \
|
||||
pipewire-codec-aptx \
|
||||
|| true
|
||||
|
||||
# User-Services fuer Audio (Presets greifen nicht fuer nachinstallierte
|
||||
# Pakete auf bootc-Basis -> explizit global enablen, Fehler tolerieren)
|
||||
systemctl --global enable pipewire.socket pipewire-pulse.socket wireplumber.service || true
|
||||
|
||||
# Bluetooth-Daemon (System-Service, kein --global)
|
||||
systemctl enable bluetooth.service
|
||||
|
||||
# Thunderbolt-Dock-Autorisierung (ohne boltd bleibt das Dock stumm)
|
||||
systemctl enable bolt.service
|
||||
|
||||
# Drucken per Socket-Activation (Fedora-Standard: cups.socket statt Service)
|
||||
systemctl enable cups.socket
|
||||
|
||||
# Netzwerkdrucker automatisch als Warteschlangen anlegen
|
||||
systemctl enable cups-browsed.service
|
||||
|
||||
# mDNS-Discovery (Netzwerkdrucker finden, .local-Aufloesung)
|
||||
systemctl enable avahi-daemon.socket
|
||||
|
||||
# Firewall (Laptop!) per Default an
|
||||
systemctl enable firewalld.service
|
||||
|
||||
dnf5 clean all
|
||||
@@ -1,18 +1,22 @@
|
||||
#!/usr/bin/bash
|
||||
set -eoux pipefail
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Cleanup of Unwanted Packages
|
||||
# Bereinigung unerwuenschter Pakete (Guard-Layer)
|
||||
###############################################################################
|
||||
echo "Removing Firefox and langpacks..."
|
||||
# Auf fedora-bootc-Basis gibt es kein Plasma/Firefox/Discover mehr.
|
||||
# Das Skript bleibt als Sicherheitsnetz, falls unerwuenschte Pakete
|
||||
# ueber Abhaengigkeiten hereinkommen. Fehlende Pakete sind kein Fehler.
|
||||
echo "Removing unwanted packages (if present)..."
|
||||
dnf5 remove -y \
|
||||
firefox \
|
||||
firefox-langpacks* \
|
||||
firefox-langpacks\* \
|
||||
plasma-discover \
|
||||
plasma-discover-flatpak \
|
||||
plasma-discover-notifier
|
||||
plasma-discover-notifier \
|
||||
sddm \
|
||||
|| true
|
||||
|
||||
rm -f /etc/xdg/autostart/org.kde.discover.notifier.desktop
|
||||
|
||||
dnf5 clean all
|
||||
rm -f /etc/xdg/autostart/org.kde.discover.notifier.desktop || true
|
||||
|
||||
dnf5 clean all
|
||||
|
||||
Executable
+93
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/bash
|
||||
set -eoux pipefail
|
||||
|
||||
###############################################################################
|
||||
# Transaction: Login-Stack (greetd + tuigreet-Fallback + Noctalia-Greeter)
|
||||
###############################################################################
|
||||
# - greetd ist der Display-Manager (leicht, Wayland-nativ).
|
||||
# - noctalia-greeter (aus Terra, siehe 10-repos.sh) ist die Login-UI in
|
||||
# Noctalia-Optik. Braucht ZWINGEND greetd als Unterbau.
|
||||
# - tuigreet bleibt als sparsamer Fallback, falls der grafische Greeter
|
||||
# je streikt (in /etc/greetd/config.toml per Kommentar umschaltbar).
|
||||
###############################################################################
|
||||
echo "Installing login stack (greetd + Noctalia greeter)..."
|
||||
|
||||
# greetd + D-Bus + polkit sind harte Voraussetzungen des Noctalia-Greeters
|
||||
# (https://docs.noctalia.dev/greeter/installation/) und werden hier explizit
|
||||
# installiert statt von der Basis vorausgesetzt.
|
||||
dnf5 install -y \
|
||||
--allowerasing \
|
||||
greetd \
|
||||
greetd-selinux \
|
||||
dbus-daemon \
|
||||
polkit \
|
||||
tuigreet \
|
||||
noctalia-greeter \
|
||||
fprintd
|
||||
|
||||
dnf5 clean all
|
||||
|
||||
# Fingerprint (Framework u.a.): System-Auth per authselect erweitern, damit
|
||||
# sudo/Polkit/login-Pfade Finger anbieten (nach fprintd-enroll auf Hardware).
|
||||
# Greeter-PAM (/etc/pam.d/greetd) bewusst NICHT angefasst: Feinschliff erst
|
||||
# auf echter Hardware mit Reader testbar, kein VM-Test moeglich.
|
||||
authselect enable-feature with-fingerprint || echo "WARN: with-fingerprint nicht aktivierbar - auf Hardware pruefen"
|
||||
|
||||
# accounts-daemon: liefert User-Avatare auf dem Login-Screen.
|
||||
systemctl enable accounts-daemon.service
|
||||
|
||||
# Service-Account fuer die Greeter-Session. Weder greetd- noch Greeter-Paket
|
||||
# legen ihn verlaesslich an - ohne ihn stirbt greetd ("user not found").
|
||||
# WICHTIG (bootc/altfiles): video/render existieren nur in /usr/lib/group
|
||||
# (read-only Image-Default). useradd -G scheitert daran ("group does not
|
||||
# exist"), weil es die Mitgliedschaft nicht nach /etc mergen kann.
|
||||
# systemd-sysusers ist das einzige Werkzeug, das den Split korrekt schreibt.
|
||||
# Build-Zeit (statt Erst-Boot): Eintrag ab Boot 1 vorhanden, kein Race.
|
||||
mkdir -p /usr/lib/sysusers.d
|
||||
cat > /usr/lib/sysusers.d/noctalia-greeter.conf <<'EOF'
|
||||
u greeter - "Greeter" - /usr/sbin/nologin
|
||||
m greeter video
|
||||
m greeter render
|
||||
EOF
|
||||
systemd-sysusers /usr/lib/sysusers.d/noctalia-greeter.conf
|
||||
id greeter
|
||||
|
||||
# System-Setup des Greeters: richtet u.a. /etc/pam.d/greetd ein.
|
||||
# Pfad laut PACKAGING.md: share/noctalia-greeter/setup_greeter_system.sh
|
||||
if [[ -x /usr/share/noctalia-greeter/setup_greeter_system.sh ]]; then
|
||||
/usr/share/noctalia-greeter/setup_greeter_system.sh || true
|
||||
else
|
||||
echo "WARN: setup_greeter_system.sh nicht gefunden - Greeter-State wird erst beim Boot angelegt"
|
||||
fi
|
||||
|
||||
# GNOME-Keyring beim Login still mit entsperren (wie GDM/SDDM). greetd
|
||||
# authentifiziert via PAM, daher kann pam_gnome_keyring das Login-Passwort
|
||||
# abgreifen und den "login"-Keyring oeffnen - ohne den Dialog
|
||||
# "Choose password for new keyring" bei der ersten Secrets-Anfrage.
|
||||
# Nach dem Greeter-Setup anhaengen (dessen PAM-Anpassungen bleiben vorn).
|
||||
if ! grep -q 'pam_gnome_keyring\.so' /etc/pam.d/greetd 2>/dev/null; then
|
||||
cat >> /etc/pam.d/greetd <<'EOF'
|
||||
auth optional pam_gnome_keyring.so
|
||||
session optional pam_gnome_keyring.so auto_start
|
||||
EOF
|
||||
fi
|
||||
|
||||
# bootc-Hygiene: /var-Inhalte aus dem Build werden beim Deployment verworfen
|
||||
# und wuerden nur den var-tmpfiles-Lint triggern. Die /etc-Anteile des Setups
|
||||
# (PAM) bleiben erhalten; /var/lib/noctalia-greeter wird zur Laufzeit via
|
||||
# tmpfiles.d angelegt (Paket-eigen + unsere Seed-Regel).
|
||||
rm -rf /var/lib/noctalia-greeter
|
||||
|
||||
# Terra nach der Installation wieder entfernen: Der Greeter ist das einzige
|
||||
# Paket von dort (includepkgs in 10-repos.sh), Updates kommen ueber
|
||||
# Image-Rebuilds (Atomic-Prinzip: kein dnf-Upgrade einzelner Pakete).
|
||||
# So sieht weder ein spaeterer Layer noch BIB-Depsolve noch das laufende
|
||||
# System das Dritt-Repo je wieder (keine CDN-Hickups, kein Shadowing).
|
||||
rm -f /etc/yum.repos.d/terra*.repo
|
||||
dnf5 clean all
|
||||
|
||||
# Alte Display-Manager explizit aus (zwei DMs = Blackscreen).
|
||||
# Auf fedora-bootc-Basis existieren sie i.d.R. nicht -> Fehler tolerieren.
|
||||
systemctl disable sddm.service gdm.service lightdm.service 2>/dev/null || true
|
||||
systemctl enable greetd.service
|
||||
systemctl set-default graphical.target || true
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/bash
|
||||
set -eoux pipefail
|
||||
|
||||
###############################################################################
|
||||
# Transaction: Noctalia Shell v5 (nativer Wayland-Desktop-Shell)
|
||||
###############################################################################
|
||||
# Paket `noctalia` aus den offiziellen Fedora-Repos (ab F44).
|
||||
# KEIN COPR noetig. Start via labwc-autostart (siehe configs/skel).
|
||||
# Doku: https://docs.noctalia.dev/noctalia/getting-started/installation/
|
||||
###############################################################################
|
||||
echo "Installing Noctalia Shell v5..."
|
||||
|
||||
# Versionsdynamik: Wallpaper-Pakete heissen f<VER>-backgrounds*.
|
||||
# Bei Basis-Wechsel (z.B. F44 -> F45 im Containerfile) kommen automatisch
|
||||
# die neuen Motive mit. Bricht das Schema je, knallt der Build laut
|
||||
# (kein stiller leerer Picker).
|
||||
FEDORA_VERSION="$(rpm -E %fedora)"
|
||||
|
||||
# Nur das Paket selbst: v5 ist nativ (C++/OpenGL ES), Bildformate und
|
||||
# Theming sind einkompiliert bzw. kommen als RPM-Abhaengigkeiten mit.
|
||||
# ImageMagick/Python/git waren v4-Bedarf und entfallen.
|
||||
#
|
||||
# Theming-Unterbau fuer die aktivierten Templates (siehe
|
||||
# configs/skel/.config/noctalia/templates.toml):
|
||||
# - flatpak: fehlt in der fedora-bootc-Basis, wird aber vom
|
||||
# Flatpak-Preinstall-Layer/Service (50-xxx, Bazaar/Brave) benoetigt
|
||||
# - adw-gtk3-theme: GTK-Theme, das Noctalias gtk-Hook umfaerbt (inkl. -dark).
|
||||
# HINWEIS: Paket heisst -theme, nicht -gtk3!
|
||||
# - dconf + Schemas: damit der Hook gtk-theme/color-scheme setzen kann.
|
||||
# (nwg-look gibt es nicht in Fedora (nur COPR) und wird nicht gebraucht -
|
||||
# der Hook setzt das Theme selbst.)
|
||||
dnf5 install -y \
|
||||
--allowerasing \
|
||||
noctalia \
|
||||
flatpak \
|
||||
adw-gtk3-theme \
|
||||
dconf \
|
||||
gsettings-desktop-schemas \
|
||||
f${FEDORA_VERSION}-backgrounds \
|
||||
fedora-workstation-backgrounds \
|
||||
gnome-backgrounds
|
||||
|
||||
dnf5 clean all
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/bash
|
||||
set -eoux pipefail
|
||||
|
||||
###############################################################################
|
||||
# Transaction: Plymouth Bootsplash (Text-Theme "fluffy-pancake")
|
||||
###############################################################################
|
||||
# - Eigenes Theme aus build/plymouth-theme/ installieren, als Default setzen.
|
||||
# - Initramfs neu bauen (Plymouth-Modul muss rein, sonst kein Early-Splash).
|
||||
# no-hostonly = laeuft auf jeder Hardware (VM + Laptop).
|
||||
# Kernel aus dem IMAGE (/usr/lib/modules), NICHT uname -r (Host-Kernel!).
|
||||
###############################################################################
|
||||
echo "Installing Plymouth splash (fluffy-pancake)..."
|
||||
|
||||
dnf5 install -y \
|
||||
--allowerasing \
|
||||
plymouth \
|
||||
plymouth-system-theme \
|
||||
plymouth-plugin-script
|
||||
|
||||
mkdir -p /usr/share/plymouth/themes/fluffy
|
||||
cp /tmp/plymouth-theme/fluffy.plymouth /tmp/plymouth-theme/fluffy.script \
|
||||
/usr/share/plymouth/themes/fluffy/
|
||||
plymouth-set-default-theme fluffy
|
||||
|
||||
for kdir in /usr/lib/modules/*; do
|
||||
kver="$(basename "${kdir}")"
|
||||
dracut --force --no-hostonly --kver "${kver}" "${kdir}/initramfs.img"
|
||||
done
|
||||
|
||||
systemctl enable plymouth-start.service || true
|
||||
|
||||
dnf5 clean all
|
||||
+7
-10
@@ -2,26 +2,23 @@
|
||||
set -eoux pipefail
|
||||
|
||||
###############################################################################
|
||||
# Transaction 2: Virtualization, Tools & Hardware Helpers
|
||||
# Transaction: Virtualization, Tools & Hardware Helpers
|
||||
# Zusammengefasst für effizientere Paketauflösung.
|
||||
# HINWEIS (labwc-Zweig): plasma-setup und noctalia sind hier raus.
|
||||
# plasma-setup war KDE-spezifisch, noctalia liegt in 22-noctalia.sh.
|
||||
# webkit2gtk/javascriptcore sind ebenfalls raus: Bazaar laeuft als Flatpak
|
||||
# und bundelt WebKit selbst; nativen Verbraucher gibt es im Image keinen.
|
||||
###############################################################################
|
||||
echo "Installing Virtualization, Plasma Setup and Hardware Helpers..."
|
||||
echo "Installing Virtualization, Tools and Hardware Helpers..."
|
||||
dnf5 install -y \
|
||||
--allowerasing \
|
||||
--skip-unavailable \
|
||||
distrobox \
|
||||
toolbox \
|
||||
plasma-setup \
|
||||
libva-utils \
|
||||
micro \
|
||||
fuse \
|
||||
fuse-libs \
|
||||
fuse3 \
|
||||
webkit2gtk4.1 \
|
||||
javascriptcoregtk4.1 \
|
||||
noctalia
|
||||
fuse3
|
||||
|
||||
dnf5 clean all
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,5 +4,6 @@ set -oue pipefail
|
||||
echo "Downloading Flathub repository definition..."
|
||||
mkdir -p /usr/share/flatpak/remotes.d/
|
||||
curl -f --retry 3 --retry-delay 5 -o /usr/share/flatpak/remotes.d/flathub.flatpakrepo https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
echo "Configuring Flatpak system-wide extra languages..."
|
||||
flatpak config --set extra-languages "de"
|
||||
# HINWEIS: `flatpak config --set extra-languages` steht bewusst NICHT hier:
|
||||
# Es schreibt nach /var (verworfen beim Deployment) und laeuft stattdessen
|
||||
# im flatpak-preinstall.service beim Erstboot (dort ist /var live).
|
||||
+5
-2
@@ -8,8 +8,11 @@ Scripts are named with a number prefix and run in ascending order during the con
|
||||
|
||||
## Included Scripts
|
||||
|
||||
- **`10-repos.sh`** - RPM Fusion repositories einrichten (frei + nonfree)
|
||||
- **`20-remove-packages.sh`** - Entfernt unerwuenschte Pakete (Firefox, Plasma Discover)
|
||||
- **`10-repos.sh`** - RPM Fusion (frei + nonfree) + Terra-Repo (fuer noctalia-greeter)
|
||||
- **`20-remove-packages.sh`** - Guard-Layer: entfernt unerwuenschte Pakete, falls vorhanden (auf fedora-bootc-Basis meist No-Op)
|
||||
- **`20-desktop-labwc.sh`** - labwc-Compositor, XWayland, kanshi, Portale, Pipewire, Docking-Tools (bolt), PolicyKit, Fonts
|
||||
- **`21-greetd.sh`** - greetd + tuigreet-Fallback + Noctalia-Greeter, SDDM/GDM aus, graphical.target
|
||||
- **`22-noctalia.sh`** - Noctalia Shell v5 aus den Fedora-Repos
|
||||
- **`30-virt.sh`** - Virtualisierungstools, Distrobox, Toolbox, Micro, etc.
|
||||
- **`40-multimedia.sh`** - Mesa Freeworld, Codecs, FFmpeg, GStreamer, Intel-Media-Treiber
|
||||
- **`50-prepare-flatpak-for-bazaar.sh`** - Laedt Flathub-Repo-Definition fuer Bazaar
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[Plymouth Theme]
|
||||
Name=fluffy-pancake
|
||||
Description=fluffy-pancake text splash
|
||||
ModuleName=script
|
||||
|
||||
[script]
|
||||
ImageDir=/usr/share/plymouth/themes/fluffy
|
||||
ScriptFile=/usr/share/plymouth/themes/fluffy/fluffy.script
|
||||
@@ -0,0 +1,51 @@
|
||||
# fluffy-pancake Plymouth-Theme (script-Plugin).
|
||||
# API-Stand: verifiziert gegen funktionierende Referenz-Themes
|
||||
# (nur Image.Text, Sprite/SetPosition/SetImage/SetOpacity,
|
||||
# Window.GetWidth/GetHeight/SetBackground*, Plymouth.Set*Function).
|
||||
# Dunkler Hintergrund (Noctalia-nah), zentrierter Schriftzug,
|
||||
# Boot-Meldungen unten links.
|
||||
|
||||
Window.SetBackgroundTopColor (0.101, 0.105, 0.149);
|
||||
Window.SetBackgroundBottomColor (0.101, 0.105, 0.149);
|
||||
|
||||
title.sprite = Sprite ();
|
||||
status.sprite = Sprite ();
|
||||
|
||||
global.layout_width = 0;
|
||||
global.layout_height = 0;
|
||||
|
||||
fun layout () {
|
||||
global.layout_width = Window.GetWidth ();
|
||||
global.layout_height = Window.GetHeight ();
|
||||
|
||||
title.image = Image.Text ("fluffy-pancake", 1, 1, 1);
|
||||
title.sprite.SetImage (title.image);
|
||||
title.sprite.SetPosition (global.layout_width / 2 - title.image.GetWidth () / 2,
|
||||
global.layout_height / 2 - title.image.GetHeight () / 2, 10);
|
||||
status.sprite.SetPosition (10, global.layout_height - 40, 10000);
|
||||
}
|
||||
|
||||
fun refresh_callback () {
|
||||
# Displays koennen spaeter dazukommen (z.B. Docking-Monitor) -
|
||||
# dann neu zentrieren.
|
||||
if (Window.GetWidth () != global.layout_width || Window.GetHeight () != global.layout_height) {
|
||||
layout ();
|
||||
}
|
||||
}
|
||||
|
||||
Plymouth.SetRefreshFunction (refresh_callback);
|
||||
|
||||
fun display_message_callback (text) {
|
||||
message = Image.Text (text, 1, 1, 1);
|
||||
status.sprite.SetImage (message);
|
||||
status.sprite.SetOpacity (1);
|
||||
}
|
||||
|
||||
fun hide_message_callback (text) {
|
||||
status.sprite.SetOpacity (0);
|
||||
}
|
||||
|
||||
Plymouth.SetDisplayMessageFunction (display_message_callback);
|
||||
Plymouth.SetHideMessageFunction (hide_message_callback);
|
||||
|
||||
layout ();
|
||||
@@ -0,0 +1,10 @@
|
||||
[Desktop Entry]
|
||||
Name=Bing-Wallpaper an/aus
|
||||
GenericName=Tages-Wallpaper umschalten
|
||||
Comment=Tägliches Bing-Wallpaper ein- oder ausschalten
|
||||
Exec=/usr/bin/bing-wallpaper-toggle.sh
|
||||
Icon=preferences-desktop-wallpaper
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Settings;DesktopSettings;
|
||||
Keywords=wallpaper;bing;hintergrund;
|
||||
@@ -7,7 +7,23 @@ ConditionPathExists=!/var/lib/flatpak/.preinstall-done
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStartPre=/usr/bin/flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
ExecStart=/usr/bin/flatpak install -y flathub io.github.kolunmi.Bazaar com.brave.Browser
|
||||
# Systemweite Extra-Sprachen (hier, nicht im Build-Skript: schreibt nach
|
||||
# /var, das es nur zur Laufzeit gibt). VOR install, damit Locale-
|
||||
# Extensions gleich mitkommen.
|
||||
ExecStart=/usr/bin/flatpak config --set extra-languages "de"
|
||||
# Bazaar + Brave + GTK-Theme-Runtimes, damit Flatpak-GTK3-Apps dem
|
||||
# Noctalia-Theme (adw-gtk3/-dark) folgen koennen. Laeuft einmalig.
|
||||
# HINWEIS: org.kde.KStyle.Adwaita steht bewusst NICHT hier - es existiert
|
||||
# in mehreren Branches (6.x), die sich non-interaktiv nicht aufloesen
|
||||
# lassen ("No ref chosen", Service wuerde ewig failen). Bei Bedarf (erste
|
||||
# Qt-Flatpak-App) interaktiv nachinstallieren, dort darf flatpak fragen:
|
||||
# flatpak install flathub org.kde.KStyle.Adwaita
|
||||
ExecStart=/usr/bin/flatpak install -y flathub io.github.kolunmi.Bazaar com.brave.Browser org.gtk.Gtk3theme.adw-gtk3 org.gtk.Gtk3theme.adw-gtk3-dark
|
||||
# Noctalia-CSS fuer ALLE Flatpaks lesbar machen (read-only, systemweit):
|
||||
# volle Palette statt nur Hell/Dunkel - gilt auch fuer spaeter per Bazaar
|
||||
# installierte Apps (kein Override pro App noetig, Neustart genuegt).
|
||||
# Chromium/Brave ignoriert GTK-CSS ohnehin (nur Hell/Dunkel per Portal).
|
||||
ExecStart=/usr/bin/flatpak override --system --filesystem=xdg-config/gtk-3.0:ro --filesystem=xdg-config/gtk-4.0:ro
|
||||
ExecStartPost=/usr/bin/touch /var/lib/flatpak/.preinstall-done
|
||||
ExecStartPost=/usr/bin/systemctl disable flatpak-preinstall.service
|
||||
RemainAfterExit=yes
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||
<!-- fluffy-pancake: Noto als Default (statt DejaVu) für stimmiges
|
||||
Gesamtbild mit Noctalia/Adwaita. Emoji kommen aus
|
||||
google-noto-color-emoji-fonts (eigene fontconfig-Regel des Pakets). -->
|
||||
<fontconfig>
|
||||
<alias>
|
||||
<family>sans-serif</family>
|
||||
<prefer><family>Noto Sans</family></prefer>
|
||||
</alias>
|
||||
<alias>
|
||||
<family>monospace</family>
|
||||
<prefer><family>Noto Sans Mono</family></prefer>
|
||||
</alias>
|
||||
</fontconfig>
|
||||
@@ -0,0 +1,19 @@
|
||||
# greetd-Konfiguration – fluffy-pancake (labwc/Noctalia-Zweig)
|
||||
# Greeter ist der Noctalia-Greeter (Login-UI in Noctalia-Optik).
|
||||
# Er braucht greetd als Unterbau und wird via Session-Wrapper gestartet,
|
||||
# NICHT direkt als Binary (der Wrapper startet den Compositor mit).
|
||||
# Doku: https://docs.noctalia.dev/greeter/installation/
|
||||
|
||||
[terminal]
|
||||
vt = 1
|
||||
|
||||
[default_session]
|
||||
# HINWEIS: Der Pfad wird beim Image-Build automatisch auf den real
|
||||
# installierten Wrapper normalisiert (Terra: /usr/sbin/ statt /usr/bin/).
|
||||
command = "/usr/sbin/noctalia-greeter-session"
|
||||
user = "greeter"
|
||||
|
||||
# --- Fallback, falls der grafische Greeter je streikt ---
|
||||
# Dafuer diese Zeile einkommentieren und die obere auskommentieren,
|
||||
# danach `systemctl restart greetd`:
|
||||
# command = "tuigreet --cmd labwc --time --asterisks --remember"
|
||||
@@ -0,0 +1,4 @@
|
||||
# Bootsplash aktivieren (Plymouth-Theme "fluffy-pancake" liegt im Image).
|
||||
# quiet: Boot-Log ausblenden (per Esc im Splash einblendbar).
|
||||
# bootc wertet kargs.d bei Installation und Upgrade aus.
|
||||
kargs = ["rhgb", "quiet"]
|
||||
@@ -0,0 +1,20 @@
|
||||
# Noctalia-Greeter Standardwerte – fluffy-pancake (Noctalia-Zweig)
|
||||
# Diese Datei wird als /usr/share/noctalia-greeter/greeter.toml.default
|
||||
# installiert und beim ERSTEN Boot via tmpfiles.d nach
|
||||
# /var/lib/noctalia-greeter/greeter.toml kopiert (nur wenn dort noch
|
||||
# keine Datei liegt - Hand-Edits bleiben erhalten).
|
||||
# Referenz aller Keys: https://docs.noctalia.dev/greeter/configuration/
|
||||
# Feintuning danach: Noctalia Shell -> Einstellungen -> Sicherheit ->
|
||||
# Noctalia Greeter -> Sync Now (Wallpaper/Palette syncen).
|
||||
|
||||
[keyboard]
|
||||
layout = "de"
|
||||
variant = "nodeadkeys"
|
||||
|
||||
[idle]
|
||||
timeout = 300
|
||||
|
||||
# [output] bewusst nicht gesetzt: Greeter spiegelt auf allen Monitoren
|
||||
# mit nativer Aufloesung. Bei Bedarf pinnen, z.B.:
|
||||
# [output]
|
||||
# name = "DP-1"
|
||||
@@ -0,0 +1,7 @@
|
||||
# systemd-remount-fs scheitert auf bootc/composefs deterministisch
|
||||
# (Overlay-Root laesst sich nicht remounten: "No changes allowed").
|
||||
# Die Mounts kommen bereits mit fstab-Optionen hoch - der Remount ist
|
||||
# hier redundant. Auf klassischen Systemen (ohne ostree) laeuft der
|
||||
# Service durch diese Bedingung unveraendert weiter.
|
||||
[Unit]
|
||||
ConditionPathExists=!/run/ostree-booted
|
||||
@@ -0,0 +1,32 @@
|
||||
# kanshi-Template – fluffy-pancake (Noctalia-Zweig)
|
||||
# Reine Doku- und Beispiel-Datei (liegt in /etc/skel). Die echte,
|
||||
# wirksame Config ~/.config/kanshi/config schreibt NUR kanshi-autoconfig
|
||||
# (--apply) - dieses Template wird nie dorthin kopiert.
|
||||
#
|
||||
# EMPFOHLEN: nichts von Hand raten, sondern generieren lassen:
|
||||
# kanshi-autoconfig --print # zeigt erkannte Outputs + Vorschlag
|
||||
# kanshi-autoconfig --apply # schreibt ~/.config/kanshi/config
|
||||
# wdisplays # grafisches Feintuning (optional)
|
||||
#
|
||||
# Die generierte Config enthaelt drei Profile:
|
||||
# docked – externe Monitore in einer Reihe, internes Panel aus
|
||||
# (Deckel-zu am Dock; bei offenem Deckel ggf. anpassen)
|
||||
# undocked – nur internes Panel
|
||||
# fallback – letzter Ausweg: alles an (uebereinander auf 0,0)
|
||||
#
|
||||
# Beispiel einer generierten Config (Namen/Modi kommen live via wlr-randr):
|
||||
# profile docked {
|
||||
# output eDP-1 disable
|
||||
# output DP-1 mode 2560x1440@59.95 position 0,0 scale 1
|
||||
# output DP-2 mode 2560x1440@59.95 position 2560,0 scale 1
|
||||
# }
|
||||
# profile undocked {
|
||||
# output eDP-1 mode 2256x1504@60 position 0,0 scale 1
|
||||
# }
|
||||
# profile fallback {
|
||||
# output * enable
|
||||
# }
|
||||
|
||||
profile fallback {
|
||||
output * enable
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Kitty – fluffy-pancake (Noctalia-Zweig)
|
||||
# Das Noctalia-Template "kitty" schreibt themes/noctalia.conf
|
||||
# (Platzhalter liegt bei, Live-Reload per USR1 macht der Hook).
|
||||
include themes/noctalia.conf
|
||||
|
||||
font_family Noto Sans Mono
|
||||
font_size 10.0
|
||||
@@ -0,0 +1,2 @@
|
||||
# Platzhalter, verwaltet vom Noctalia-Template "kitty".
|
||||
# Wird beim ersten Theme-Resolve mit der Palette befuellt.
|
||||
@@ -0,0 +1,26 @@
|
||||
# labwc-Autostart – fluffy-pancake (Noctalia-Zweig)
|
||||
# Tastatur/Locale stehen in ~/.config/labwc/environment.
|
||||
|
||||
# 0. XDG-Standardordner (Dokumente, Bilder, Videos, ...) anlegen bzw.
|
||||
# bei Locale-Wechsel umbenennen. Laeuft unter labwc sonst nie
|
||||
# (kein X-Session-Autostart); u.a. braucht Noctalias Wallpaper-Picker
|
||||
# ~/Bilder. Idempotent - macht bei existierenden Ordnern nichts.
|
||||
xdg-user-dirs-update >/dev/null 2>&1 || true
|
||||
|
||||
# 1. Output-Profile (gedockt/ungedockt). Schreibt die kanshi-Config nur,
|
||||
# wenn sie fehlt oder von kanshi-autoconfig verwaltet wird.
|
||||
# Eigene Hand-Edits bleiben unangetastet.
|
||||
kanshi-autoconfig --apply-if-managed >/dev/null 2>&1 || true
|
||||
kanshi >/dev/null 2>&1 &
|
||||
|
||||
# 2. Hintergrund-Fallback (Noctalia setzt das Wallpaper selbst)
|
||||
swaybg -c '#1a1b26' >/dev/null 2>&1 &
|
||||
|
||||
# 3. PolicyKit: kein externer Agent noetig - Noctalia bringt einen nativen
|
||||
# mit (per Default aktiv, siehe ~/.config/noctalia/shell.toml ->
|
||||
# [shell] polkit_agent). Genau EIN Agent pro Session!
|
||||
# (Historie: lxqt-policykit-agent unter /usr/libexec/ - ausgebaut.)
|
||||
|
||||
# 4. Desktop-Shell: Bar, Dock, Launcher, Control-Center, Lock, OSDs,
|
||||
# Idle-Handling (nativ: Lock/Screen-off, siehe noctalia idle.toml)
|
||||
noctalia >/dev/null 2>&1 &
|
||||
@@ -0,0 +1,13 @@
|
||||
# labwc-Umgebung – fluffy-pancake (Noctalia-Zweig)
|
||||
# Wird von labwc beim Start eingelesen (~/.config/labwc/environment).
|
||||
# Sprache bewusst hier (nicht nur Installer-locale.conf): gilt
|
||||
# deterministisch fuer jede Session.
|
||||
LANG=de_DE.UTF-8
|
||||
XKB_DEFAULT_LAYOUT=de
|
||||
XKB_DEFAULT_VARIANT=nodeadkeys
|
||||
QT_QPA_PLATFORM=wayland
|
||||
GDK_BACKEND=wayland
|
||||
XDG_CURRENT_DESKTOP=labwc
|
||||
XDG_SESSION_TYPE=wayland
|
||||
MOZ_ENABLE_WAYLAND=1
|
||||
TERMINAL=kitty
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- labwc Root-Menue (Rechtsklick) – fluffy-pancake (Noctalia-Zweig) -->
|
||||
<openbox_menu>
|
||||
<menu id="root-menu" label="">
|
||||
<item label="Terminal (Kitty)">
|
||||
<action name="Execute" command="kitty" />
|
||||
</item>
|
||||
<item label="Dateimanager (Thunar)">
|
||||
<action name="Execute" command="thunar" />
|
||||
</item>
|
||||
<item label="Browser (Brave, Flatpak)">
|
||||
<action name="Execute" command="flatpak run com.brave.Browser" />
|
||||
</item>
|
||||
<item label="App-Store (Bazaar, Flatpak)">
|
||||
<action name="Execute" command="flatpak run io.github.kolunmi.Bazaar" />
|
||||
</item>
|
||||
<separator />
|
||||
<item label="Reconfigure">
|
||||
<action name="Reconfigure" />
|
||||
</item>
|
||||
<item label="Exit">
|
||||
<action name="Exit" />
|
||||
</item>
|
||||
</menu>
|
||||
</openbox_menu>
|
||||
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- labwc rc.xml – fluffy-pancake (Noctalia-Zweig), Tastatur: de -->
|
||||
<labwc_config>
|
||||
<core>
|
||||
<gap>8</gap>
|
||||
</core>
|
||||
<desktops number="4" />
|
||||
<theme>
|
||||
<name>Clearlooks</name>
|
||||
<font name="sans" size="10" />
|
||||
</theme>
|
||||
<resize>
|
||||
<drawContents>no</drawContents>
|
||||
</resize>
|
||||
<keyboard>
|
||||
<default />
|
||||
<!-- Terminal -->
|
||||
<keybind key="W-Return">
|
||||
<action name="Execute" command="kitty" />
|
||||
</keybind>
|
||||
<!-- Dateimanager -->
|
||||
<keybind key="W-e">
|
||||
<action name="Execute" command="thunar" />
|
||||
</keybind>
|
||||
<!-- Noctalia: App-Launcher -->
|
||||
<keybind key="W-d">
|
||||
<action name="Execute" command="noctalia msg panel-toggle launcher" />
|
||||
</keybind>
|
||||
<!-- Noctalia: Control-Center -->
|
||||
<keybind key="W-s">
|
||||
<action name="Execute" command="noctalia msg panel-toggle control-center" />
|
||||
</keybind>
|
||||
<!-- Noctalia: Einstellungen -->
|
||||
<keybind key="W-S-s">
|
||||
<action name="Execute" command="noctalia msg settings-toggle" />
|
||||
</keybind>
|
||||
<!-- Sperren (Noctalia-Lockscreen) -->
|
||||
<keybind key="W-l">
|
||||
<action name="Execute" command="noctalia msg session lock" />
|
||||
</keybind>
|
||||
<!-- Medien-Tasten (Laptop): PipeWire-Mixer, Helligkeit, Player.
|
||||
Noctalia-OSDs reagieren von selbst auf die Aenderungen. -->
|
||||
<keybind key="XF86AudioRaiseVolume">
|
||||
<action name="Execute" command="wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+" />
|
||||
</keybind>
|
||||
<keybind key="XF86AudioLowerVolume">
|
||||
<action name="Execute" command="wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-" />
|
||||
</keybind>
|
||||
<keybind key="XF86AudioMute">
|
||||
<action name="Execute" command="wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" />
|
||||
</keybind>
|
||||
<keybind key="XF86AudioMicMute">
|
||||
<action name="Execute" command="wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle" />
|
||||
</keybind>
|
||||
<keybind key="XF86MonBrightnessUp">
|
||||
<action name="Execute" command="brightnessctl set 5%+" />
|
||||
</keybind>
|
||||
<keybind key="XF86MonBrightnessDown">
|
||||
<action name="Execute" command="brightnessctl set 5%-" />
|
||||
</keybind>
|
||||
<keybind key="XF86AudioPlay">
|
||||
<action name="Execute" command="playerctl play-pause" />
|
||||
</keybind>
|
||||
<keybind key="XF86AudioNext">
|
||||
<action name="Execute" command="playerctl next" />
|
||||
</keybind>
|
||||
<keybind key="XF86AudioPrev">
|
||||
<action name="Execute" command="playerctl previous" />
|
||||
</keybind>
|
||||
<!-- Fenster schliessen -->
|
||||
<keybind key="A-F4">
|
||||
<action name="Close" />
|
||||
</keybind>
|
||||
</keyboard>
|
||||
<mouse>
|
||||
<default />
|
||||
</mouse>
|
||||
</labwc_config>
|
||||
@@ -0,0 +1,7 @@
|
||||
# Standard-Anwendungen – fluffy-pancake (Noctalia-Zweig)
|
||||
[Default Applications]
|
||||
inode/directory=thunar.desktop
|
||||
text/plain=org.gnome.TextEditor.desktop
|
||||
application/pdf=org.gnome.Evince.desktop
|
||||
image/png=org.gnome.Loupe.desktop
|
||||
image/jpeg=org.gnome.Loupe.desktop
|
||||
@@ -0,0 +1,18 @@
|
||||
# Idle-Verantwortung liegt bei Noctalia (nativ): Fade-Overlay, Lock nach
|
||||
# 5 Minuten, Screen-off mit Auto-Resume nach 10 Minuten. swayidle ist
|
||||
# ausgebaut (kein Paket, keine Autostart-Zeile mehr).
|
||||
# Suspend-Behavior bleibt aus (kein Idle-Suspend gewuenscht);
|
||||
# Lock-vor-Suspend greift ueber den Lockscreen-Default.
|
||||
# GUI-Aenderung landet in settings.toml und gewinnt ueber dieser Datei.
|
||||
[idle.behavior.lock]
|
||||
enabled = true
|
||||
timeout = 300
|
||||
action = "lock"
|
||||
|
||||
[idle.behavior.screen-off]
|
||||
enabled = true
|
||||
timeout = 600
|
||||
action = "screen_off"
|
||||
|
||||
[idle.behavior.suspend]
|
||||
enabled = false
|
||||
@@ -0,0 +1,11 @@
|
||||
# Noctalia Shell-Defaults – fluffy-pancake (Noctalia-Zweig)
|
||||
# Nativer Polkit-Agent der Shell (statt externem lxqt-policykit-agent):
|
||||
# Auth-Dialoge kommen als Noctalia-UI (floating, zentriert).
|
||||
# Braucht eine logind-Session (via greetd+PAM gegeben).
|
||||
# GUI-Aenderung (Settings -> Security) landet in settings.toml und gewinnt.
|
||||
[shell]
|
||||
polkit_agent = true
|
||||
# UI-Sprache fest auf Deutsch (Katalog de.json ist gebuendelt).
|
||||
# Auto-Detect wuerde bei fehlender Session-Locale auf Englisch fallen.
|
||||
# GUI-Aenderung gewinnt ueber dieser Datei.
|
||||
lang = "de"
|
||||
@@ -0,0 +1,20 @@
|
||||
# Noctalia Template-Defaults – fluffy-pancake (Noctalia-Zweig)
|
||||
# Schaltet App-Theming an: Terminal, GTK3/4 und labwc-Deko folgen der
|
||||
# Noctalia-Palette (IDs aus dem Built-in-Katalog:
|
||||
# `noctalia theme --list-templates`).
|
||||
# - kitty: schreibt ~/.config/kitty/themes/noctalia.conf
|
||||
# (braucht das include in kitty.conf + Platzhalter, beides in /etc/skel)
|
||||
# - gtk3/gtk4: schreibt noctalia.css + haengt den Import in gtk.css ein,
|
||||
# setzt adw-gtk3(-dark) und color-scheme (braucht Paket adw-gtk3)
|
||||
# - labwc: schreibt das openbox-Theme + setzt <name>noctalia</name> in rc.xml
|
||||
# Aenderung per GUI (Settings -> Templates) landet in settings.toml und
|
||||
# gewinnt ueber dieser Datei. Qt/KDE-Apps: Templates "qt"/"kcolorscheme"
|
||||
# sind absichtlich aus (keine Qt-Apps installiert).
|
||||
[theme.templates]
|
||||
enable_builtin_templates = true
|
||||
builtin_ids = ["kitty", "gtk3", "gtk4", "labwc"]
|
||||
|
||||
# labwc nach jedem Theme-Resolve live neu laden (Deko + Root-Menue),
|
||||
# sonst bleibt die alte Optik bis zum Relogin stehen.
|
||||
[hooks]
|
||||
colors_changed = "labwc --reconfigure"
|
||||
@@ -0,0 +1,8 @@
|
||||
# Noctalia Wallpaper-Defaults – fluffy-pancake (Noctalia-Zweig)
|
||||
# Picker zeigt die GNOME-Motive (Standard-Fundus, flach in einem Ordner).
|
||||
# Mehr Auswahl: im Panel auf /usr/share/backgrounds wechseln (dort mit
|
||||
# Flatten alle Fedora-Motive) oder ~/Bilder fuer eigene Fotos.
|
||||
# Täglich-Bing ist Opt-in per Launcher-App "Bing-Wallpaper an/aus".
|
||||
# GUI-Aenderung landet in settings.toml und gewinnt ueber dieser Datei.
|
||||
[wallpaper]
|
||||
directory = "/usr/share/backgrounds/gnome"
|
||||
@@ -0,0 +1,8 @@
|
||||
[Unit]
|
||||
Description=Tages-Wallpaper von Bing laden und setzen
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/bing-wallpaper.sh
|
||||
@@ -0,0 +1,12 @@
|
||||
# Taeglich frisches Bing-Wallpaper (06:00, bei ausgeschaltetem Rechner
|
||||
# nachgeholt). Abschalten pro User mit:
|
||||
# systemctl --user disable --now bing-wallpaper.timer
|
||||
[Unit]
|
||||
Description=Taeglich Bing-Wallpaper laden
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 06:00:00
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -0,0 +1,4 @@
|
||||
# Noctalia-Greeter Standardwerte seeden (nur Erst-Boot, Hand-Edits bleiben).
|
||||
# Das Paket legt das Verzeichnis bereits per tmpfiles.d an; diese Regel
|
||||
# kopiert zusaetzlich unsere de-Defaults, falls noch keine greeter.toml da ist.
|
||||
C /var/lib/noctalia-greeter/greeter.toml 0640 greeter greeter - /usr/share/noctalia-greeter/greeter.toml.default
|
||||
@@ -0,0 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Name=labwc
|
||||
Comment=Lab Wayland Compositor (fluffy-pancake Noctalia-Desktop)
|
||||
Exec=labwc
|
||||
Type=Application
|
||||
DesktopNames=labwc
|
||||
@@ -1,8 +1,14 @@
|
||||
# ISO configuration for a bootc-based installer ISO
|
||||
|
||||
# --- Kickstart: post-install bootc switch ---
|
||||
# HINWEIS: lang/keyboard laesst Anaconda u.a. /etc/vconsole.conf schreiben
|
||||
# (deutsche TTYs). Die :stable-Referenz unten wird beim lokalen ISO-Build
|
||||
# per Justfile auf $target_image:$tag umgeschrieben (Test-ISOs!).
|
||||
[customizations.installer.kickstart]
|
||||
contents = """
|
||||
lang de_DE.UTF-8
|
||||
keyboard --vckeymap=de --xlayouts='de'
|
||||
timezone Europe/Berlin --utc
|
||||
%post
|
||||
# Switch to the custom bootc image after installation
|
||||
bootc switch --mutate-in-place --transport registry humocs-man.duckdns.org/humocs-man/fluffy-pancake:stable
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
# bing-wallpaper-toggle: Bing-Tages-Wallpaper an/aus schalten (User-Timer).
|
||||
# Fuer den Noctalia-Launcher (.desktop-Datei) - kein Terminal noetig.
|
||||
set -euo pipefail
|
||||
|
||||
NOTIFY="/usr/bin/notify-send"
|
||||
|
||||
# Altlast-Erkennung: Falls der Timer GLOBAL enabled ist (Opt-out-Image
|
||||
# vor dem Opt-in-Umbau), greift kein User-Disable. Einmalig per sudo
|
||||
# aufraeumen, danach arbeitet der Toggle rein im User-Scope.
|
||||
if systemctl --global is-enabled --quiet bing-wallpaper.timer 2>/dev/null; then
|
||||
msg="Global aktiviert (Image-Altlast). Einmalig: sudo rm -f /etc/systemd/user/timers.target.wants/bing-wallpaper.timer && systemctl --user daemon-reload"
|
||||
echo "${msg}"
|
||||
if command -v "$NOTIFY" >/dev/null; then
|
||||
"$NOTIFY" "Bing-Wallpaper" "$msg" --app-name="Bing-Wallpaper" --icon=preferences-desktop-wallpaper || true
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if systemctl --user is-enabled --quiet bing-wallpaper.timer; then
|
||||
systemctl --user disable --now bing-wallpaper.timer
|
||||
msg="Bing-Wallpaper ausgeschaltet"
|
||||
else
|
||||
systemctl --user enable --now bing-wallpaper.timer
|
||||
msg="Bing-Wallpaper eingeschaltet (taeglich 06:00 Uhr)"
|
||||
fi
|
||||
|
||||
if command -v "$NOTIFY" >/dev/null; then
|
||||
"$NOTIFY" "Bing-Wallpaper" "$msg" --app-name="Bing-Wallpaper" --icon=preferences-desktop-wallpaper || true
|
||||
else
|
||||
echo "$msg"
|
||||
fi
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
# bing-wallpaper: Tages-Wallpaper von Bing laden und direkt setzen.
|
||||
# Quelle: HPImageArchive-API (inoffiziell, aber seit Jahren stabil),
|
||||
# Markt de-DE, UHD-Aufloesung. Lizenz: nur zur privaten Nutzung als
|
||||
# Hintergrund (keine Redistribution - es wird nur heruntergeladen).
|
||||
# Ablage: ~/Bilder/Bing/bing-YYYY-MM-DD.jpg, Retention 7 Tage.
|
||||
# Setzen via Noctalia-IPC (persistiert + triggert Theme-Resolve neu).
|
||||
# Laeuft die Shell gerade nicht, bleibt die Datei fuer spaeter liegen.
|
||||
set -euo pipefail
|
||||
|
||||
API="https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=de-DE"
|
||||
OUTDIR="${HOME}/Bilder/Bing"
|
||||
[[ -d "${HOME}/Bilder" ]] || OUTDIR="${HOME}/Pictures/Bing"
|
||||
mkdir -p "${OUTDIR}"
|
||||
|
||||
TODAY="$(date +%F)"
|
||||
TARGET="${OUTDIR}/bing-${TODAY}.jpg"
|
||||
|
||||
if [[ ! -s "${TARGET}" ]]; then
|
||||
JSON="$(curl -fsSL --retry 3 --retry-delay 5 "${API}")"
|
||||
URLBASE="$(printf '%s' "${JSON}" | jq -r '.images[0].urlbase // empty')"
|
||||
[[ -n "${URLBASE}" ]] || { echo "Bing-Antwort ohne urlbase"; exit 1; }
|
||||
curl -fsSL --retry 3 --retry-delay 5 -o "${TARGET}" "https://www.bing.com${URLBASE}_UHD.jpg"
|
||||
echo "Geladen: ${TARGET}"
|
||||
else
|
||||
echo "Bereits vorhanden: ${TARGET}"
|
||||
fi
|
||||
|
||||
# Alte behalten wir 7 Tage (Rotation via Noctalia-Automation moeglich)
|
||||
ls -t "${OUTDIR}"/bing-*.jpg 2>/dev/null | tail -n +8 | xargs -r rm -f --
|
||||
echo "Bereinigt, behalten: $(ls "${OUTDIR}"/bing-*.jpg 2>/dev/null | wc -l)"
|
||||
|
||||
# Direkt setzen (schlaegt fehl ohne laufende Shell -> Datei bleibt liegen)
|
||||
noctalia msg wallpaper-set "${TARGET}" && echo "Gesetzt: ${TARGET}" || echo "Noctalia laeuft nicht - Datei liegt bereit"
|
||||
Executable
+237
@@ -0,0 +1,237 @@
|
||||
#!/usr/bin/env python3
|
||||
"""kanshi-autoconfig - generiert kanshi-Profile aus live erkannten Outputs.
|
||||
|
||||
Liest die angeschlossenen Monitore via `wlr-randr --json` aus (EDID-Namen,
|
||||
bevorzugte Modi, aktuelle Skalierung) und schreibt daraus eine
|
||||
funktionsfaehige ~/.config/kanshi/config mit den Profilen
|
||||
docked / undocked / fallback.
|
||||
|
||||
Verhalten:
|
||||
--print Vorschlag auf stdout, schreibt nichts.
|
||||
--apply Schreibt (mit Backup *.bak), fragt nicht.
|
||||
--apply-if-managed Schreibt nur, wenn die Config fehlt oder den Marker
|
||||
'# kanshi-autoconfig: managed' enthaelt. Bei
|
||||
unveraendertem Output-Set bleibt eine verwaltete Config
|
||||
unangetastet (Modus-Tweaks inklusive). Wird vom
|
||||
labwc-Autostart bei jedem Login aufgerufen.
|
||||
|
||||
Moduswahl: Auf echter Hardware der EDID-preferred-Modus (meist nativ =
|
||||
richtig). In VMs meldet die Firmware oft einen Kleinstmodus als preferred
|
||||
(QEMU: 1280x800) - dort wird 1920x1080@60 genommen, wenn angeboten, sonst
|
||||
preferred. Einmal geschrieben bleibt die Config bei gleichem Output-Set
|
||||
erhalten (Modus-Tweaks inklusive); neu generiert wird nur bei geaendertem
|
||||
Output-Set (Docking) oder per --apply.
|
||||
|
||||
Faellt die Erkennung fehl (kein Wayland, kein wlr-randr), wird eine
|
||||
reine Fallback-Config geschrieben, damit nie ein schwarzer Bildschirm
|
||||
ohne Layout dasteht.
|
||||
"""
|
||||
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
MARKER = "# kanshi-autoconfig: managed"
|
||||
CONFIG_PATH = Path.home() / ".config" / "kanshi" / "config"
|
||||
|
||||
|
||||
def detect_vm():
|
||||
"""True, wenn wir virtualisiert laufen (QEMU/Boxes-Test)."""
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
["systemd-detect-virt", "--vm"], capture_output=True, timeout=10
|
||||
)
|
||||
except (FileNotFoundError, subprocess.TimeoutExpired):
|
||||
return False
|
||||
return proc.returncode == 0
|
||||
|
||||
|
||||
def norm_rate(value):
|
||||
if isinstance(value, (int, float)) and value > 1000:
|
||||
return value / 1000 # mHz -> Hz
|
||||
return value
|
||||
|
||||
|
||||
def choose_mode(modes, current, in_vm):
|
||||
"""Modus waehlen: VM-Heuristik, sonst preferred, sonst current/erster."""
|
||||
if in_vm:
|
||||
for m in modes:
|
||||
rate = norm_rate(m.get("refresh") or m.get("rate")) or 0
|
||||
if m.get("width") == 1920 and m.get("height") == 1080 and round(rate) == 60:
|
||||
return m
|
||||
for m in modes:
|
||||
if m.get("preferred"):
|
||||
return m
|
||||
return current or (modes[0] if modes else None)
|
||||
|
||||
|
||||
def detect_outputs():
|
||||
"""Liste von Dicts: name, internal, width, height, rate, scale."""
|
||||
in_vm = detect_vm()
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
["wlr-randr", "--json"], capture_output=True, text=True, timeout=10
|
||||
)
|
||||
except (FileNotFoundError, subprocess.TimeoutExpired):
|
||||
return []
|
||||
if proc.returncode != 0:
|
||||
return []
|
||||
try:
|
||||
data = json.loads(proc.stdout)
|
||||
except json.JSONDecodeError:
|
||||
return []
|
||||
outputs = []
|
||||
for out in data:
|
||||
name = out.get("name", "?")
|
||||
# Nur verbundene Outputs betrachten (kanshi matcht nur angesteckte)
|
||||
if out.get("connected") is False:
|
||||
continue
|
||||
modes = out.get("modes", []) or []
|
||||
current = out.get("current_mode") or out.get("mode")
|
||||
chosen = choose_mode(modes, current, in_vm)
|
||||
if not chosen:
|
||||
continue
|
||||
outputs.append(
|
||||
{
|
||||
"name": name,
|
||||
"internal": name.startswith(("eDP-", "LVDS-", "DSI-")),
|
||||
"width": chosen.get("width"),
|
||||
"height": chosen.get("height"),
|
||||
"rate": norm_rate(chosen.get("refresh") or chosen.get("rate")),
|
||||
"scale": out.get("scale", 1) or 1,
|
||||
}
|
||||
)
|
||||
return outputs
|
||||
|
||||
|
||||
def mode_str(o):
|
||||
s = f"{o['width']}x{o['height']}"
|
||||
if o["rate"]:
|
||||
s += f"@{o['rate']:.2f}" if isinstance(o["rate"], float) else f"@{o['rate']}"
|
||||
return s
|
||||
|
||||
|
||||
def render(outputs):
|
||||
lines = [
|
||||
MARKER,
|
||||
f"# generiert am {datetime.now().isoformat(timespec='seconds')}",
|
||||
"# Quelle: wlr-randr (live). Feintuning: wdisplays oder Modus direkt",
|
||||
"# in dieser Datei anpassen - bei unveraendertem Output-Set bleibt",
|
||||
"# die Datei (inkl. deiner Modus-Tweaks) bei jedem Login erhalten.",
|
||||
"# Neu generiert wird nur bei geaendertem Output-Set (Docking) oder",
|
||||
"# per --apply. Marker-Zeile loeschen = ganz hand-gepflegt.",
|
||||
"",
|
||||
]
|
||||
externals = [o for o in outputs if not o["internal"]]
|
||||
internals = [o for o in outputs if o["internal"]]
|
||||
|
||||
if externals:
|
||||
lines.append("profile docked {")
|
||||
for i in internals:
|
||||
lines.append(f" output {i['name']} disable")
|
||||
x = 0
|
||||
for o in externals:
|
||||
lines.append(
|
||||
f" output {o['name']} mode {mode_str(o)} position {x},0 scale {o['scale']}"
|
||||
)
|
||||
x += o["width"] or 0
|
||||
lines.append("}")
|
||||
lines.append("")
|
||||
|
||||
if internals:
|
||||
lines.append("profile undocked {")
|
||||
for o in internals:
|
||||
lines.append(
|
||||
f" output {o['name']} mode {mode_str(o)} position 0,0 scale {o['scale']}"
|
||||
)
|
||||
lines.append("}")
|
||||
lines.append("")
|
||||
elif not externals:
|
||||
# Gar nichts erkannt -> reiner Fallback, nie leer lassen
|
||||
lines.append("# Keine Outputs erkannt (ausserhalb einer Wayland-Session")
|
||||
lines.append("# aufgerufen?) - nur Fallback geschrieben.")
|
||||
lines.append("")
|
||||
|
||||
lines.append("profile fallback {")
|
||||
lines.append(" output * enable")
|
||||
lines.append("}")
|
||||
lines.append("")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def is_managed(path: Path):
|
||||
if not path.exists():
|
||||
return True
|
||||
try:
|
||||
return MARKER in path.read_text()
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
|
||||
def apply(text):
|
||||
CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||
if CONFIG_PATH.exists():
|
||||
backup = CONFIG_PATH.with_suffix(".bak")
|
||||
shutil.copy2(CONFIG_PATH, backup)
|
||||
print(f"Backup: {backup}")
|
||||
CONFIG_PATH.write_text(text)
|
||||
print(f"Geschrieben: {CONFIG_PATH}")
|
||||
|
||||
|
||||
def config_output_names(path: Path):
|
||||
"""Output-Namen aus einer bestehenden kanshi-Config (ohne '*' Fallback)."""
|
||||
names = set()
|
||||
try:
|
||||
for line in path.read_text().splitlines():
|
||||
parts = line.strip().split()
|
||||
if len(parts) >= 2 and parts[0] == "output" and parts[1] != "*":
|
||||
names.add(parts[1].strip("'\""))
|
||||
except OSError:
|
||||
pass
|
||||
return names
|
||||
|
||||
|
||||
def main(argv):
|
||||
outputs = detect_outputs()
|
||||
if not outputs:
|
||||
print("WARN: keine Outputs erkannt", file=sys.stderr)
|
||||
text = render(outputs)
|
||||
# Default ohne Schreib-Flag: nur anzeigen, nichts schreiben (sicher).
|
||||
if "--print" in argv or ("--apply" not in argv and "--apply-if-managed" not in argv):
|
||||
if not outputs:
|
||||
print("# (Fallback-Anteil, da keine Outputs erkannt)", file=sys.stderr)
|
||||
print(text)
|
||||
if outputs:
|
||||
print(
|
||||
f"# Erkannt: {', '.join(o['name'] for o in outputs)}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 0
|
||||
if "--apply-if-managed" in argv:
|
||||
if not CONFIG_PATH.exists():
|
||||
apply(text) # Erst-Login: anlegen
|
||||
return 0
|
||||
if not is_managed(CONFIG_PATH):
|
||||
print(f"{CONFIG_PATH} ist hand-gepflegt - lasse sie unangetastet.")
|
||||
return 0
|
||||
if not outputs:
|
||||
# Erkennung fehlgeschlagen -> niemals eine gute Config clobbern.
|
||||
print("WARN: Erkennung fehlgeschlagen - lasse verwaltete Config unangetastet.",
|
||||
file=sys.stderr)
|
||||
return 0
|
||||
if {o["name"] for o in outputs} == config_output_names(CONFIG_PATH):
|
||||
# Gleiches Output-Set (z.B. jeden Boot dieselbe VM-Anzeige):
|
||||
# Modus-Tweaks des Users bleiben erhalten, kein Rewrite.
|
||||
print(f"Outputs unveraendert ({', '.join(sorted(config_output_names(CONFIG_PATH)))})"
|
||||
" - behalte Config (inkl. Modus-Tweaks) bei.")
|
||||
return 0
|
||||
# Output-Set geaendert (angedockt/abgedockt): neu generieren.
|
||||
apply(text)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv))
|
||||
@@ -38,9 +38,10 @@ $LOGGER -t "$TAG" "Update gestaged. Suche aktiven Desktop-User..."
|
||||
# =============================================================================
|
||||
# 3. Aktiven Desktop-User auf seat0 ermitteln
|
||||
# =============================================================================
|
||||
# Wir filtern direkt aus der Session-Liste den Eintrag, der auf 'seat0' laeuft
|
||||
# Wir filtern direkt aus der Session-Liste den Eintrag, der auf 'seat0' laeuft
|
||||
# und die Klasse 'user' (echter Desktop-Nutzer, kein Login-Screen) hat.
|
||||
USER_ID=$($LOGINCTL list-sessions --no-legend 2>/dev/null | awk '$4 == "seat0" && $6 == "user" {print $2; exit}' || echo "")
|
||||
# 'greeter' wird explizit ausgeschlossen (eigene greetd-Session, kein Daemon).
|
||||
USER_ID=$($LOGINCTL list-sessions --no-legend 2>/dev/null | awk '$4 == "seat0" && $6 == "user" && $3 != "greeter" {print $2; exit}' || echo "")
|
||||
|
||||
if [[ -z "$USER_ID" ]]; then
|
||||
$LOGGER -t "$TAG" "Update bereit, aber kein aktiver Desktop-User (Klasse: user) auf seat0 gefunden."
|
||||
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
# seed-labwc-skel: kopiert fehlende Desktop-Defaults aus /etc/skel.
|
||||
# Nuetzlich nach Rebase auf den labwc-Zweig, weil /home (/var/home)
|
||||
# erhalten bleibt und /etc/skel nur bei NEU angelegten Benutzern greift.
|
||||
# Bestehende Dateien werden NIEMALS ueberschrieben (cp -n).
|
||||
set -euo pipefail
|
||||
|
||||
SKEL="/etc/skel"
|
||||
TARGETS=(
|
||||
".config/labwc/environment"
|
||||
".config/labwc/autostart"
|
||||
".config/labwc/rc.xml"
|
||||
".config/labwc/menu.xml"
|
||||
".config/kanshi/config.template"
|
||||
".config/kitty/kitty.conf"
|
||||
".config/kitty/themes/noctalia.conf"
|
||||
".config/noctalia/templates.toml"
|
||||
".config/noctalia/shell.toml"
|
||||
".config/noctalia/wallpaper.toml"
|
||||
".config/noctalia/idle.toml"
|
||||
".config/mimeapps.list"
|
||||
)
|
||||
|
||||
for rel in "${TARGETS[@]}"; do
|
||||
src="${SKEL}/${rel}"
|
||||
dst="${HOME}/${rel}"
|
||||
if [[ ! -e "${dst}" ]]; then
|
||||
mkdir -p "$(dirname "${dst}")"
|
||||
cp -n "${src}" "${dst}"
|
||||
echo "angelegt: ${dst}"
|
||||
else
|
||||
echo "bleibt: ${dst}"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ! -e "${HOME}/.config/kanshi/config" ]]; then
|
||||
echo ""
|
||||
echo "Keine kanshi-Config gefunden. Erzeugen mit:"
|
||||
echo " kanshi-autoconfig --apply (schreibt ~/.config/kanshi/config)"
|
||||
fi
|
||||
|
||||
# Migration: swayidle-Block aus bestehender Autostart entfernen
|
||||
# (Idle macht Noctalia nativ; Doppel-Feuerung vermeiden). Mit Backup.
|
||||
AUTOSTART="${HOME}/.config/labwc/autostart"
|
||||
if [[ -f "${AUTOSTART}" ]] && grep -q 'swayidle' "${AUTOSTART}"; then
|
||||
cp -n "${AUTOSTART}" "${AUTOSTART}.bak" 2>/dev/null || true
|
||||
sed -i '/^# 5\. Idle-Handling/,/before-sleep.*&$/d' "${AUTOSTART}"
|
||||
echo "migriert: swayidle-Block aus ${AUTOSTART} entfernt (Backup .bak)"
|
||||
fi
|
||||
Reference in New Issue
Block a user