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
openSUSE Build Service is sponsored by