File config.sh of Package shift-os-deck
#!/bin/bash
# Ensure KIWI_ROOT is set (KIWI sets this when running in the build root).
KIWI_ROOT="${KIWI_ROOT:-/}"
# ============================================================
# Shift OS - KIWI Image Configuration (OBS "production" safe)
# Target: openSUSE Tumbleweed
# Desktop: Plasma 6 (minimal)
# Bootloader: GRUB2 (UEFI)
#
# Fixes in this revision:
# - Make sudo reliable on minimal images:
# * ensure /etc/sudoers exists and includes /etc/sudoers.d
# * disable Defaults rootpw/targetpw which cause "[sudo] password for root:"
# * install a sudoers drop-in with correct owner/mode
# - Keep OBS-safe behavior (no interactive prompts).
# ============================================================
set -euo pipefail
log() { echo "[shiftos-config] $*"; }
have() { command -v "$1" >/dev/null 2>&1; }
ensure_group() {
local g="$1"
getent group "$g" >/dev/null 2>&1 && return 0
log "Creating group: $g"
groupadd "$g" || true
}
ensure_user() {
local u="$1" home="$2" shell="$3"
id "$u" >/dev/null 2>&1 && return 0
log "Creating user: $u"
useradd -m -d "$home" -s "$shell" "$u"
}
set_user_password() {
local u="$1" p="$2"
if have chpasswd; then
echo "${u}:${p}" | chpasswd
else
log "WARNING: chpasswd not found; cannot set password for ${u}"
fi
}
write_file() {
# write_file <path> <mode-octal> (content via stdin)
local path="$1" mode="$2"
install -D -m "$mode" /dev/stdin "$path"
}
# ---------- Live user ----------
LIVE_USER="shiftos"
LIVE_PASS="shift"
LIVE_HOME="/home/${LIVE_USER}"
LIVE_SHELL="/bin/bash"
ensure_group users
ensure_group audio
ensure_group video
ensure_group lp
ensure_group wheel
ensure_user "${LIVE_USER}" "${LIVE_HOME}" "${LIVE_SHELL}"
usermod -aG users,audio,video,lp,wheel "${LIVE_USER}" 2>/dev/null || true
set_user_password "${LIVE_USER}" "${LIVE_PASS}"
# ---------- Sudo (robust) ----------
# If you see: "[sudo] password for root:"
# that's usually because /etc/sudoers contains:
# Defaults rootpw (or targetpw)
# This block makes sudo work on minimal KIWI images.
if rpm -q sudo >/dev/null 2>&1; then
log "sudo package is installed"
else
log "WARNING: sudo package is NOT installed at build time (add 'sudo' to the KIWI packages list)."
fi
# Ensure /etc/sudoers exists and includes drop-ins
if [ ! -f /etc/sudoers ]; then
log "Creating minimal /etc/sudoers"
cat <<'EOF' | write_file /etc/sudoers 0440
## Shift OS minimal sudoers
Defaults env_reset
Defaults secure_path="/usr/sbin:/usr/bin:/sbin:/bin"
root ALL=(ALL:ALL) ALL
#includedir /etc/sudoers.d
EOF
chown root:root /etc/sudoers || true
fi
# Disable rootpw/targetpw so sudo won't ask for root's password
sed -i -E 's/^\s*Defaults\s+(rootpw|targetpw)\b/# &/g' /etc/sudoers || true
# Ensure drop-in dir is present + safe permissions
mkdir -p /etc/sudoers.d
chmod 0755 /etc/sudoers.d
chown root:root /etc/sudoers.d || true
# Ensure sudoers includes the drop-in dir (some minimal configs omit it)
if ! grep -Eq '^\s*#includedir\s+/etc/sudoers\.d\s*$' /etc/sudoers; then
printf "\n# Include drop-ins\n#includedir /etc/sudoers.d\n" >> /etc/sudoers
fi
# Allow live user to sudo without password (avoids auth issues on live media)
cat <<EOF | write_file /etc/sudoers.d/90-shiftos 0440
# Shift OS live sudo policy
${LIVE_USER} ALL=(ALL:ALL) NOPASSWD: ALL
EOF
chown root:root /etc/sudoers.d/90-shiftos || true
# ---------- Display manager defaults (optional) ----------
if [ -f /etc/sysconfig/displaymanager ]; then
sed -i -e 's/^DISPLAYMANAGER=.*/DISPLAYMANAGER="sddm"/' -e 's/^DEFAULT_WM=.*/DEFAULT_WM="plasma"/' /etc/sysconfig/displaymanager || true
fi
# Configure SDDM greeter theme
mkdir -p /etc/sddm.conf.d
cat > /etc/sddm.conf.d/00-shiftos.conf <<'EOF'
[Theme]
Current=breeze
EOF
chmod 0644 /etc/sddm.conf.d/00-shiftos.conf
if have systemctl; then
systemctl enable NetworkManager.service >/dev/null 2>&1 || true
# Ensure only SDDM is enabled
systemctl disable gdm.service 2>/dev/null || true
systemctl disable gdm3.service 2>/dev/null || true
systemctl disable lightdm.service 2>/dev/null || true
systemctl disable lxdm.service 2>/dev/null || true
systemctl disable xdm.service 2>/dev/null || true
systemctl enable sddm.service >/dev/null 2>&1 || true
fi
log "config.sh completed successfully."
# Ensure graphical boot with SDDM (and avoid falling back to multi-user.target)
systemctl set-default graphical.target || true
systemctl enable sddm.service || true
# --- ShiftOS Live first-boot verifier/fixer (runs once per boot) ---
install -d "$KIWI_ROOT/usr/local/sbin"
cat > "$KIWI_ROOT/usr/local/sbin/shiftos-live-firstboot.sh" <<'EOF'
#!/bin/bash
set -euo pipefail
# Runs at every LiveCD boot, but uses a marker so it only does work once per boot.
MARKER="/run/shiftos-live-firstboot.done"
LOGTAG="shiftos-firstboot"
if [[ -e "$MARKER" ]]; then
exit 0
fi
log() { echo "[$LOGTAG] $*"; }
# --- What we need for a functional GUI login ---
declare -a MISSING_BINS=()
declare -a WANT_PKGS=()
need_bin() {
local bin="$1" pkg="$2" note="${3:-}"
if ! command -v "$bin" >/dev/null 2>&1; then
MISSING_BINS+=("$bin${note:+ ($note)}")
WANT_PKGS+=("$pkg")
fi
}
# SDDM + Plasma (X11 fallback) + basic Xorg server.
need_bin sddm sddm "display manager"
need_bin startplasma-wayland patterns-kde-kde "Plasma (Wayland entrypoint)"
need_bin startplasma-x11 patterns-kde-kde "Plasma (X11 entrypoint)"
need_bin X xorg-x11-server "Xorg server"
# If we are missing nothing, just try to start the display stack and exit.
if [[ ${#MISSING_BINS[@]} -eq 0 ]]; then
log "All required binaries are present."
systemctl restart display-manager || true
touch "$MARKER"
exit 0
fi
log "Missing components detected:"
printf ' - %s\n' "${MISSING_BINS[@]}"
# De-duplicate WANT_PKGS (preserve order)
declare -a PKGS=()
for p in "${WANT_PKGS[@]}"; do
skip=0
for q in "${PKGS[@]}"; do [[ "$p" == "$q" ]] && { skip=1; break; }; done
[[ $skip -eq 0 ]] && PKGS+=("$p")
done
echo
echo "[${LOGTAG}] Proposed packages to install:"
printf ' - %s\n' "${PKGS[@]}"
echo
read -r -p "[${LOGTAG}] Would you like to add repos (if needed) and install missing packages now? [y/N]: " ans
case "${ans:-}" in
y|Y|yes|YES)
;;
*)
log "Skipped package installation. You can still install manually with zypper."
read -r -p "[${LOGTAG}] Press Enter to continue booting..." _
systemctl restart display-manager || true
touch "$MARKER"
exit 0
;;
esac
# --- Repos: if the Live image has none (or refresh fails), add sane defaults ---
log "Refreshing repositories..."
if ! zypper -q --gpg-auto-import-keys ref; then
log "Repo refresh failed. Adding default openSUSE Tumbleweed repos (with trailing slashes)."
# Remove invalid repos to avoid repeated failures
while read -r num _; do
[[ "$num" =~ ^[0-9]+$ ]] || continue
zypper -q rr "$num" || true
done < <(zypper -q lr | awk 'NR>2 {print $1}')
zypper -q ar -f "https://download.opensuse.org/tumbleweed/repo/oss/" repo-oss || true
zypper -q ar -f "https://download.opensuse.org/tumbleweed/repo/non-oss/" repo-non-oss || true
# Tumbleweed "update" repos exist on download.opensuse.org; keep them optional.
zypper -q ar -f "https://download.opensuse.org/update/tumbleweed/" repo-update || true
zypper -q ar -f "https://download.opensuse.org/update/tumbleweed-non-oss/" repo-update-non-oss || true
# Your OBS project repo (harmless if it doesn't resolve in this build).
zypper -q ar -f "obs://home:QTechStudios:shiftos-package-center/openSUSE_Tumbleweed" shiftos-pkgs || true
zypper -q --gpg-auto-import-keys ref || true
fi
log "Installing missing packages..."
zypper -n --gpg-auto-import-keys in --no-recommends "${PKGS[@]}" || true
# Re-check after install attempt
declare -a STILL_MISSING=()
for b in sddm startplasma-wayland startplasma-x11 X; do
command -v "$b" >/dev/null 2>&1 || STILL_MISSING+=("$b")
done
if [[ ${#STILL_MISSING[@]} -gt 0 ]]; then
log "Some components are still missing after install attempt:"
printf ' - %s\n' "${STILL_MISSING[@]}"
read -r -p "[${LOGTAG}] Press Enter to continue booting..." _
else
log "All components present after install."
fi
# Ensure SDDM is enabled and try to start it.
systemctl enable sddm.service >/dev/null 2>&1 || true
systemctl restart display-manager || true
touch "$MARKER"
exit 0
EOF
chmod 0755 "$KIWI_ROOT/usr/local/sbin/shiftos-live-firstboot.sh"
install -d "$KIWI_ROOT/etc/systemd/system"
cat > "$KIWI_ROOT/etc/systemd/system/shiftos-live-firstboot.service" <<'EOF'
[Unit]
Description=ShiftOS Live First-Boot Verify/Fix
DefaultDependencies=no
Before=display-manager.service
After=local-fs.target
ConditionPathExists=!/run/shiftos-live-firstboot.done
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/shiftos-live-firstboot.sh
[Install]
WantedBy=multi-user.target
EOF
# ShiftOS: force display-manager to SDDM (do NOT call systemctl in the build root)
# Some images come with display-manager.service -> display-manager-legacy.service; replace it.
install -d "$KIWI_ROOT/etc/systemd/system"
ln -snf /usr/lib/systemd/system/sddm.service "$KIWI_ROOT/etc/systemd/system/display-manager.service" || true
# Also set the traditional sysconfig knob used by SUSE tooling
if [ -f "$KIWI_ROOT/etc/sysconfig/displaymanager" ]; then
sed -i 's/^DISPLAYMANAGER=.*/DISPLAYMANAGER="sddm"/' "$KIWI_ROOT/etc/sysconfig/displaymanager" || true
else
install -d "$KIWI_ROOT/etc/sysconfig"
printf 'DISPLAYMANAGER="sddm"\n' > "$KIWI_ROOT/etc/sysconfig/displaymanager"
fi
# Enable the service in the image
install -d "$KIWI_ROOT/etc/systemd/system/multi-user.target.wants"
ln -sf ../shiftos-live-firstboot.service "$KIWI_ROOT/etc/systemd/system/multi-user.target.wants/shiftos-live-firstboot.service"
# Also ensure sddm is enabled (harmless if already)
install -d "$KIWI_ROOT/etc/systemd/system/display-manager.service.wants" 2>/dev/null || true
install -d "$KIWI_ROOT/etc/systemd/system/multi-user.target.wants"
ln -sf /usr/lib/systemd/system/sddm.service "$KIWI_ROOT/etc/systemd/system/multi-user.target.wants/sddm.service" 2>/dev/null || true