fixes/utils: split nvidia_troubleshoot 336 -> 169+181, passwordless 374 -> 195+193

Two single-use scripts with no deployed copy, so the entry+lib shape is
safe. Each keeps the ordering, the safety checks and the user-facing output;
the configuration writers move to a library beside it.

Both scripts write `set -e # Exit on any error`, so extract_shell_functions.py
now matches the directive rather than the whole line. Regression-checked by
re-deriving the committed fresh-install/main.sh split byte-for-byte.

Verified: all 6 and all 9 top-level functions verbatim via the shfmt
harness; both libraries source with no side effects and define every
function moved into them; bash -n passes on all four.

Neither script was run. nvidia_troubleshoot.sh writes /etc/X11 config and
installs pyroveil; setup_passwordless_system.sh writes sudoers and lightdm
autologin, which is what this machine's login depends on.

Over-cap files 31 -> 29.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
This commit is contained in:
Krzysztof Rudnicki 2026-08-17 14:18:06 +02:00
parent 94f4a5adb7
commit efd7f022fd
7 changed files with 451 additions and 355 deletions

View File

@ -0,0 +1,17 @@
{
"title": "Split nvidia_troubleshoot.sh and setup_passwordless_system.sh",
"objective": "Two single-use fix scripts sit over the 250-line cap with no deployed copy, making them safe targets for the entry+lib shape. Move each script's configuration writers into a sourced library beside it, leaving the entry script owning the ordering, the safety checks and the user-facing output. Code moves verbatim; neither script is executed, because both write system configuration this machine depends on.",
"acceptance_criteria": [
"All four resulting files are under 250 lines; the over-cap total falls 31 -> 29",
"Every top-level function is verbatim, proved by meta/scripts/verify_shell_split.sh",
"Each library sources with no side effects and defines every function moved into it",
"bash -n passes on all four files",
"No suppression of any kind, and no shellcheck directive added beyond the standard source= comment"
],
"out_of_scope": [
"Running either script: one writes /etc/X11 and installs pyroveil, the other writes sudoers and lightdm autologin",
"nvidia_troubleshoot.sh's trace blocker, which prevents a runtime trace but not a static verification",
"The phone_focus_mode scripts, which need deploy.sh's copy list to grow in the same commit"
],
"verifier": "bash meta/scripts/verify_shell_split.sh HEAD <entry> <lib> <entry> for the verbatim claim; sourcing each library in a subshell and checking declare -F for every moved function; bash -n on all four; pre-commit run --files; bash ~/utils/scripts/check_file_length.sh --all."
}

View File

@ -0,0 +1,54 @@
{
"intent": "Split nvidia_troubleshoot.sh (336) and setup_passwordless_system.sh (374) into entry scripts plus sourced configuration libraries, all four files under the 250-line cap.",
"scope": [
"nvidia_troubleshoot.sh 336 -> 169, new fixes/lib/nvidia_config.sh 181",
"setup_passwordless_system.sh 374 -> 195, new utils/lib/passwordless_config.sh 193",
"meta/scripts/extract_shell_functions.py: match the set -e directive rather than the whole line",
"Non-goal: any behaviour change; neither script was executed"
],
"changes": [
"Moved the four configuration writers out of each script, leaving the entry script owning the ordering, the safety checks and the user-facing output.",
"Both scripts write `set -e # Exit on any error`, so the extractor's anchor was loosened to match the directive rather than an exact line. The change was regression-checked by re-deriving the already-verified fresh-install/main.sh split and diffing byte-for-byte.",
"nvidia_troubleshoot.sh keeps suggest_kernel_params and suggest_desktop_settings, which only print advice; setup_passwordless_system.sh keeps check_sudo, backup_file, test_configurations and the two output functions."
],
"verification": [
{
"command": "bash meta/scripts/verify_shell_split.sh HEAD <entry> <lib> <entry>, for each",
"result": "pass",
"evidence": "nvidia_troubleshoot: IDENTICAL, all 6 top-level functions verbatim. setup_passwordless_system: IDENTICAL, all 9 verbatim."
},
{
"command": "bash -c '. <lib>; declare -F <each moved function>'",
"result": "pass",
"evidence": "Both libraries source with no side effects and define every function moved into them. This is the check that caught the discarded first attempt at the main.sh split, where interleaved top-level commands ended up in the library."
},
{
"command": "bash -n on all four files",
"result": "pass",
"evidence": "All parse. Neither script was executed: nvidia_troubleshoot.sh writes /etc/X11 configuration and installs pyroveil, and setup_passwordless_system.sh writes sudoers and lightdm autologin - the two things this machine's login depends on."
},
{
"command": "Regression check of the extractor after loosening the set -e match",
"result": "pass",
"evidence": "Re-derived the committed fresh-install/main.sh split in a throwaway worktree at HEAD~2; both files came out byte-for-byte identical, so the anchor change did not alter existing behaviour."
},
{
"command": "pre-commit run --files <all four>",
"result": "pass",
"evidence": "All hooks pass, including shfmt and shellcheck."
},
{
"command": "bash ~/utils/scripts/check_file_length.sh --all",
"result": "pass",
"evidence": "29 files over cap, down from 31."
}
],
"risks": [
"Neither script has a test or CI coverage - both are hand-run single-use fixes. The verbatim proof, the source-time check and bash -n are the whole of the evidence.",
"nvidia_troubleshoot.sh's known trace blocker is unaddressed: its trace dies at step 3 because backup_file writes into an unbound /etc, so most of the file never executes under the harness. That blocks a runtime trace, not this split, which is verified statically instead."
],
"rollback": [
"git revert the commit; both entry scripts return to their original size and the two libraries disappear.",
"After rollback, confirm bash -n passes on both and that each file again contains all of its function definitions."
]
}

View File

@ -0,0 +1,180 @@
#!/usr/bin/env bash
# Xorg, GCC-workaround and pyroveil configuration for nvidia_troubleshoot.sh.
#
# Sourced by the entry script, which owns the ordering; this file defines
# functions only, so sourcing it has no side effects.
# Function to backup file if it exists
backup_file() {
local file="$1"
if [[ -f $file ]]; then
cp "$file" "$file.backup.$(date +%Y%m%d_%H%M%S)"
echo "✓ Backed up $file"
fi
}
# Function to add or update xorg.conf for RenderAccel
configure_xorg() {
echo ""
echo "2. Configuring Xorg Settings..."
echo "==============================="
XORG_CONF="/etc/X11/xorg.conf"
XORG_CONF_D="/etc/X11/xorg.conf.d"
NVIDIA_CONF="$XORG_CONF_D/20-nvidia.conf"
# Create xorg.conf.d directory if it doesn't exist
mkdir -p "$XORG_CONF_D"
# Backup existing xorg.conf if it exists
backup_file "$XORG_CONF"
backup_file "$NVIDIA_CONF"
# Create NVIDIA-specific configuration
# NOTE: RenderAccel must be "true" (or omitted, since it defaults to true).
# Setting it to "false" forces software rendering, causing Xorg to consume
# 30%+ CPU on the desktop and making the system feel extremely sluggish.
cat >"$NVIDIA_CONF" <<EOF
# NVIDIA configuration - hardware acceleration enabled
# Created by nvidia_troubleshoot.sh on $(date)
Section "Device"
Identifier "NVIDIA Card"
Driver "nvidia"
Option "RenderAccel" "true"
EndSection
EOF
echo "✓ Created $NVIDIA_CONF with RenderAccel enabled"
}
# Function to add GCC mismatch workaround
configure_gcc_workaround() {
echo ""
echo "3. Configuring GCC Mismatch Workaround..."
echo "=========================================="
local PROFILE_FILE="/etc/profile"
local timestamp
timestamp=$(date)
backup_file "$PROFILE_FILE"
# Check if IGNORE_CC_MISMATCH is already set
if ! grep -q "IGNORE_CC_MISMATCH" "$PROFILE_FILE"; then
{
printf '\n'
printf '# NVIDIA GCC version mismatch workaround\n'
printf '# Added by nvidia_troubleshoot.sh on %s\n' "$timestamp"
printf 'export IGNORE_CC_MISMATCH=1\n'
} >>"$PROFILE_FILE"
echo "✓ Added IGNORE_CC_MISMATCH=1 to $PROFILE_FILE"
else
echo "✓ IGNORE_CC_MISMATCH already configured in $PROFILE_FILE"
fi
}
# Function to install pyroveil for mesh shader issues
install_pyroveil() {
echo ""
echo "4. Pyroveil Setup for Mesh Shader Issues..."
echo "==========================================="
local user_home="/home/$SUDO_USER"
local pyroveil_dir="$user_home/pyroveil"
echo "Mesh shaders have poor support on NVIDIA drivers, causing issues in games"
echo "like Final Fantasy VII Rebirth. Pyroveil can work around these problems."
echo ""
local install_pyroveil=true
if [[ $INTERACTIVE_MODE == "true" ]]; then
read -p "Would you like to install Pyroveil? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
install_pyroveil=false
fi
else
echo "Auto-installing Pyroveil (use --interactive to prompt)"
fi
if [[ $install_pyroveil == "true" ]]; then
# Check for required dependencies
local missing_deps=()
for dep in git cmake ninja gcc; do
if ! command -v "$dep" &>/dev/null; then
missing_deps+=("$dep")
fi
done
if [[ ${#missing_deps[@]} -gt 0 ]]; then
echo "Missing dependencies: ${missing_deps[*]}"
echo "Please install them first. On Arch Linux:"
echo "pacman -S base-devel git cmake ninja"
return 1
fi
# Clone and build pyroveil as the original user
echo "Installing Pyroveil to $pyroveil_dir..."
if [[ -d $pyroveil_dir ]]; then
echo "Pyroveil directory already exists. Updating..."
sudo -u "$SUDO_USER" bash -c "cd '$pyroveil_dir' && git pull"
else
sudo -u "$SUDO_USER" git clone https://github.com/HansKristian-Work/pyroveil.git "$pyroveil_dir"
fi
sudo -u "$SUDO_USER" bash -c "
cd '$pyroveil_dir'
git submodule update --init
cmake . -Bbuild -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$user_home/.local
ninja -C build install
"
echo "✓ Pyroveil installed successfully"
echo ""
echo "To use Pyroveil with games that have mesh shader issues:"
echo "1. For Final Fantasy VII Rebirth:"
echo " PYROVEIL=1 PYROVEIL_CONFIG=$pyroveil_dir/hacks/ffvii-rebirth-nvidia/pyroveil.json %command%"
echo ""
echo "2. For Steam games, add to launch options:"
echo " PYROVEIL=1 PYROVEIL_CONFIG=/path/to/config/pyroveil.json %command%"
echo ""
echo "Available configs in: $pyroveil_dir/hacks/"
# Create a helper script
cat >"$user_home/run-with-pyroveil.sh" <<EOF
#!/bin/bash
# Helper script to run games with Pyroveil
# Usage: ./run-with-pyroveil.sh <config-name> <command>
PYROVEIL_DIR="$pyroveil_dir"
if [[ \$# -lt 2 ]]; then
echo "Usage: \$0 <config-name> <command>"
echo "Available configs:"
ls "\$PYROVEIL_DIR/hacks/"
exit 1
fi
CONFIG_NAME="\$1"
shift
export PYROVEIL=1
export PYROVEIL_CONFIG="\$PYROVEIL_DIR/hacks/\$CONFIG_NAME/pyroveil.json"
echo "Running with Pyroveil config: \$CONFIG_NAME"
echo "Config file: \$PYROVEIL_CONFIG"
exec "\$@"
EOF
chown "$SUDO_USER:$SUDO_USER" "$user_home/run-with-pyroveil.sh"
chmod +x "$user_home/run-with-pyroveil.sh"
echo "✓ Created helper script: $user_home/run-with-pyroveil.sh"
else
echo "Skipping Pyroveil installation"
echo "Note: You can manually install it later for mesh shader issues"
fi
}

View File

@ -5,6 +5,9 @@
set -e # Exit on any error
# shellcheck source=lib/nvidia_config.sh
. "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/nvidia_config.sh"
# Source common library for shared functions
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
# shellcheck source=../../lib/common.sh
@ -42,180 +45,9 @@ EOF
echo "✓ Configuration written to: $CONFIG_FILE"
# Function to backup file if it exists
backup_file() {
local file="$1"
if [[ -f $file ]]; then
cp "$file" "$file.backup.$(date +%Y%m%d_%H%M%S)"
echo "✓ Backed up $file"
fi
}
# Function to add or update xorg.conf for RenderAccel
configure_xorg() {
echo ""
echo "2. Configuring Xorg Settings..."
echo "==============================="
XORG_CONF="/etc/X11/xorg.conf"
XORG_CONF_D="/etc/X11/xorg.conf.d"
NVIDIA_CONF="$XORG_CONF_D/20-nvidia.conf"
# Create xorg.conf.d directory if it doesn't exist
mkdir -p "$XORG_CONF_D"
# Backup existing xorg.conf if it exists
backup_file "$XORG_CONF"
backup_file "$NVIDIA_CONF"
# Create NVIDIA-specific configuration
# NOTE: RenderAccel must be "true" (or omitted, since it defaults to true).
# Setting it to "false" forces software rendering, causing Xorg to consume
# 30%+ CPU on the desktop and making the system feel extremely sluggish.
cat >"$NVIDIA_CONF" <<EOF
# NVIDIA configuration - hardware acceleration enabled
# Created by nvidia_troubleshoot.sh on $(date)
Section "Device"
Identifier "NVIDIA Card"
Driver "nvidia"
Option "RenderAccel" "true"
EndSection
EOF
echo "✓ Created $NVIDIA_CONF with RenderAccel enabled"
}
# Function to add GCC mismatch workaround
configure_gcc_workaround() {
echo ""
echo "3. Configuring GCC Mismatch Workaround..."
echo "=========================================="
local PROFILE_FILE="/etc/profile"
local timestamp
timestamp=$(date)
backup_file "$PROFILE_FILE"
# Check if IGNORE_CC_MISMATCH is already set
if ! grep -q "IGNORE_CC_MISMATCH" "$PROFILE_FILE"; then
{
printf '\n'
printf '# NVIDIA GCC version mismatch workaround\n'
printf '# Added by nvidia_troubleshoot.sh on %s\n' "$timestamp"
printf 'export IGNORE_CC_MISMATCH=1\n'
} >>"$PROFILE_FILE"
echo "✓ Added IGNORE_CC_MISMATCH=1 to $PROFILE_FILE"
else
echo "✓ IGNORE_CC_MISMATCH already configured in $PROFILE_FILE"
fi
}
# Function to install pyroveil for mesh shader issues
install_pyroveil() {
echo ""
echo "4. Pyroveil Setup for Mesh Shader Issues..."
echo "==========================================="
local user_home="/home/$SUDO_USER"
local pyroveil_dir="$user_home/pyroveil"
echo "Mesh shaders have poor support on NVIDIA drivers, causing issues in games"
echo "like Final Fantasy VII Rebirth. Pyroveil can work around these problems."
echo ""
local install_pyroveil=true
if [[ $INTERACTIVE_MODE == "true" ]]; then
read -p "Would you like to install Pyroveil? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
install_pyroveil=false
fi
else
echo "Auto-installing Pyroveil (use --interactive to prompt)"
fi
if [[ $install_pyroveil == "true" ]]; then
# Check for required dependencies
local missing_deps=()
for dep in git cmake ninja gcc; do
if ! command -v "$dep" &>/dev/null; then
missing_deps+=("$dep")
fi
done
if [[ ${#missing_deps[@]} -gt 0 ]]; then
echo "Missing dependencies: ${missing_deps[*]}"
echo "Please install them first. On Arch Linux:"
echo "pacman -S base-devel git cmake ninja"
return 1
fi
# Clone and build pyroveil as the original user
echo "Installing Pyroveil to $pyroveil_dir..."
if [[ -d $pyroveil_dir ]]; then
echo "Pyroveil directory already exists. Updating..."
sudo -u "$SUDO_USER" bash -c "cd '$pyroveil_dir' && git pull"
else
sudo -u "$SUDO_USER" git clone https://github.com/HansKristian-Work/pyroveil.git "$pyroveil_dir"
fi
sudo -u "$SUDO_USER" bash -c "
cd '$pyroveil_dir'
git submodule update --init
cmake . -Bbuild -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$user_home/.local
ninja -C build install
"
echo "✓ Pyroveil installed successfully"
echo ""
echo "To use Pyroveil with games that have mesh shader issues:"
echo "1. For Final Fantasy VII Rebirth:"
echo " PYROVEIL=1 PYROVEIL_CONFIG=$pyroveil_dir/hacks/ffvii-rebirth-nvidia/pyroveil.json %command%"
echo ""
echo "2. For Steam games, add to launch options:"
echo " PYROVEIL=1 PYROVEIL_CONFIG=/path/to/config/pyroveil.json %command%"
echo ""
echo "Available configs in: $pyroveil_dir/hacks/"
# Create a helper script
cat >"$user_home/run-with-pyroveil.sh" <<EOF
#!/bin/bash
# Helper script to run games with Pyroveil
# Usage: ./run-with-pyroveil.sh <config-name> <command>
PYROVEIL_DIR="$pyroveil_dir"
if [[ \$# -lt 2 ]]; then
echo "Usage: \$0 <config-name> <command>"
echo "Available configs:"
ls "\$PYROVEIL_DIR/hacks/"
exit 1
fi
CONFIG_NAME="\$1"
shift
export PYROVEIL=1
export PYROVEIL_CONFIG="\$PYROVEIL_DIR/hacks/\$CONFIG_NAME/pyroveil.json"
echo "Running with Pyroveil config: \$CONFIG_NAME"
echo "Config file: \$PYROVEIL_CONFIG"
exec "\$@"
EOF
chown "$SUDO_USER:$SUDO_USER" "$user_home/run-with-pyroveil.sh"
chmod +x "$user_home/run-with-pyroveil.sh"
echo "✓ Created helper script: $user_home/run-with-pyroveil.sh"
else
echo "Skipping Pyroveil installation"
echo "Note: You can manually install it later for mesh shader issues"
fi
}
# Function to check for kernel parameter modifications
suggest_kernel_params() {

View File

@ -0,0 +1,192 @@
#!/usr/bin/env bash
# sudoers, lightdm autologin, i3 session and misc configuration writers.
#
# Sourced by setup_passwordless_system.sh, which owns the ordering and the
# safety checks; this file defines functions only.
# Function to configure passwordless sudo
configure_passwordless_sudo() {
echo ""
echo "1. Configuring Passwordless Sudo..."
echo "=================================="
local sudoers_file="/etc/sudoers.d/99-passwordless-${TARGET_USER}"
# Create sudoers configuration for passwordless access
cat > "$sudoers_file" << EOF
# Passwordless sudo configuration for user: ${TARGET_USER}
# Created by setup_passwordless_system.sh on $(date)
# WARNING: This allows the user to run any command without password
# Allow user to run all commands without password
${TARGET_USER} ALL=(ALL) NOPASSWD: ALL
# Ensure user can run sudo without TTY (useful for scripts)
Defaults:${TARGET_USER} !requiretty
# Keep environment variables for user convenience
Defaults:${TARGET_USER} env_keep += "HOME PATH DISPLAY XAUTHORITY"
EOF
# Set proper permissions for sudoers file
chmod 440 "$sudoers_file"
# Verify the sudoers file syntax
if visudo -c -f "$sudoers_file"; then
echo "✓ Passwordless sudo configured for user: $TARGET_USER"
echo "✓ Sudoers file created: $sudoers_file"
else
echo "✗ Error: Invalid sudoers syntax. Removing file for safety."
rm -f "$sudoers_file"
exit 1
fi
}
# Function to configure lightdm auto-login
configure_lightdm_autologin() {
echo ""
echo "2. Configuring LightDM Auto-Login..."
echo "==================================="
local lightdm_conf="/etc/lightdm/lightdm.conf"
local lightdm_conf_dir="/etc/lightdm/lightdm.conf.d"
local custom_conf="$lightdm_conf_dir/50-autologin.conf"
# Create lightdm config directory if it doesn't exist
mkdir -p "$lightdm_conf_dir"
# Backup existing lightdm configuration
backup_file "$lightdm_conf"
# Check if lightdm is installed
if ! command -v lightdm &> /dev/null; then
echo "Warning: LightDM not found. Installing lightdm..."
pacman -S --noconfirm lightdm lightdm-gtk-greeter
fi
# Method 1: Update the main lightdm.conf file directly
sed -i "/^#autologin-user=/c\autologin-user=${TARGET_USER}" "$lightdm_conf"
sed -i "/^#autologin-user-timeout=/c\autologin-user-timeout=0" "$lightdm_conf"
sed -i "/^#autologin-session=/c\autologin-session=i3" "$lightdm_conf"
sed -i "/^#autologin-in-background=/c\autologin-in-background=false" "$lightdm_conf"
# Also set user-session to i3 as fallback
sed -i "/^#user-session=/c\user-session=i3" "$lightdm_conf"
echo "✓ LightDM auto-login configured in main config file"
# Method 2: Also create the separate config file for redundancy
cat > "$custom_conf" << EOF
# LightDM Auto-Login Configuration
# Created by setup_passwordless_system.sh on $(date)
[Seat:*]
# Enable auto-login
autologin-user=${TARGET_USER}
autologin-user-timeout=0
autologin-session=i3
# Disable user switching and guest account
allow-user-switching=false
allow-guest=false
# Set session defaults
user-session=i3
greeter-session=lightdm-gtk-greeter
# Disable screen lock timeout during login
autologin-in-background=false
EOF
echo "✓ LightDM auto-login also configured in separate config file: $custom_conf"
# Enable lightdm service
systemctl enable lightdm.service
echo "✓ LightDM service enabled"
# Restart lightdm to apply changes only if --logout flag is provided
if [[ $ALLOW_LOGOUT == true ]]; then
echo "Restarting LightDM to apply auto-login settings..."
systemctl restart lightdm.service
echo "✓ LightDM restarted"
else
echo "✓ LightDM configuration complete (restart lightdm or reboot to activate auto-login)"
fi
}
# Function to configure i3 session
configure_i3_session() {
echo ""
echo "3. Configuring i3 Session..."
echo "==========================="
local xsessions_dir="/usr/share/xsessions"
local i3_desktop="$xsessions_dir/i3.desktop"
# Create xsessions directory if it doesn't exist
mkdir -p "$xsessions_dir"
# Check if i3.desktop exists, create if not
if [[ ! -f $i3_desktop ]]; then
cat > "$i3_desktop" << EOF
[Desktop Entry]
Name=i3
Comment=improved dynamic tiling window manager
Exec=i3
TryExec=i3
Type=Application
X-LightDM-DesktopName=i3
DesktopNames=i3
Keywords=tiling;wm;windowmanager;window;manager;
EOF
echo "✓ Created i3 desktop session file: $i3_desktop"
else
echo "✓ i3 desktop session file already exists"
fi
# Ensure user has i3 config directory
local user_home="/home/${TARGET_USER}"
local i3_config_dir="$user_home/.config/i3"
if [[ ! -d $i3_config_dir ]]; then
sudo -u "$TARGET_USER" mkdir -p "$i3_config_dir"
echo "✓ Created i3 config directory for user: $TARGET_USER"
fi
}
# Function to configure additional auto-login settings
configure_additional_settings() {
echo ""
echo "4. Configuring Additional Settings..."
echo "===================================="
# Add user to autologin group if it exists
if getent group autologin &> /dev/null; then
usermod -a -G autologin "$TARGET_USER"
echo "✓ Added $TARGET_USER to autologin group"
else
# Create autologin group
groupadd -r autologin
usermod -a -G autologin "$TARGET_USER"
echo "✓ Created autologin group and added $TARGET_USER"
fi
# Configure pam for auto-login (if needed)
local pam_lightdm="/etc/pam.d/lightdm-autologin"
if [[ ! -f $pam_lightdm ]]; then
cat > "$pam_lightdm" << EOF
#%PAM-1.0
# LightDM auto-login PAM configuration
# Created by setup_passwordless_system.sh on $(date)
auth required pam_unix.so nullok
auth optional pam_permit.so
auth optional pam_gnome_keyring.so
account include system-local-login
password include system-local-login
session include system-local-login
session optional pam_gnome_keyring.so auto_start
EOF
echo "✓ Created PAM configuration for auto-login"
fi
}

View File

@ -8,6 +8,9 @@
set -e # Exit on any error
# shellcheck source=lib/passwordless_config.sh
. "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/passwordless_config.sh"
# Check for flags
OFFER_REBOOT=false
ALLOW_LOGOUT=false
@ -66,192 +69,9 @@ backup_file() {
fi
}
# Function to configure passwordless sudo
configure_passwordless_sudo() {
echo ""
echo "1. Configuring Passwordless Sudo..."
echo "=================================="
local sudoers_file="/etc/sudoers.d/99-passwordless-${TARGET_USER}"
# Create sudoers configuration for passwordless access
cat > "$sudoers_file" << EOF
# Passwordless sudo configuration for user: ${TARGET_USER}
# Created by setup_passwordless_system.sh on $(date)
# WARNING: This allows the user to run any command without password
# Allow user to run all commands without password
${TARGET_USER} ALL=(ALL) NOPASSWD: ALL
# Ensure user can run sudo without TTY (useful for scripts)
Defaults:${TARGET_USER} !requiretty
# Keep environment variables for user convenience
Defaults:${TARGET_USER} env_keep += "HOME PATH DISPLAY XAUTHORITY"
EOF
# Set proper permissions for sudoers file
chmod 440 "$sudoers_file"
# Verify the sudoers file syntax
if visudo -c -f "$sudoers_file"; then
echo "✓ Passwordless sudo configured for user: $TARGET_USER"
echo "✓ Sudoers file created: $sudoers_file"
else
echo "✗ Error: Invalid sudoers syntax. Removing file for safety."
rm -f "$sudoers_file"
exit 1
fi
}
# Function to configure lightdm auto-login
configure_lightdm_autologin() {
echo ""
echo "2. Configuring LightDM Auto-Login..."
echo "==================================="
local lightdm_conf="/etc/lightdm/lightdm.conf"
local lightdm_conf_dir="/etc/lightdm/lightdm.conf.d"
local custom_conf="$lightdm_conf_dir/50-autologin.conf"
# Create lightdm config directory if it doesn't exist
mkdir -p "$lightdm_conf_dir"
# Backup existing lightdm configuration
backup_file "$lightdm_conf"
# Check if lightdm is installed
if ! command -v lightdm &> /dev/null; then
echo "Warning: LightDM not found. Installing lightdm..."
pacman -S --noconfirm lightdm lightdm-gtk-greeter
fi
# Method 1: Update the main lightdm.conf file directly
sed -i "/^#autologin-user=/c\autologin-user=${TARGET_USER}" "$lightdm_conf"
sed -i "/^#autologin-user-timeout=/c\autologin-user-timeout=0" "$lightdm_conf"
sed -i "/^#autologin-session=/c\autologin-session=i3" "$lightdm_conf"
sed -i "/^#autologin-in-background=/c\autologin-in-background=false" "$lightdm_conf"
# Also set user-session to i3 as fallback
sed -i "/^#user-session=/c\user-session=i3" "$lightdm_conf"
echo "✓ LightDM auto-login configured in main config file"
# Method 2: Also create the separate config file for redundancy
cat > "$custom_conf" << EOF
# LightDM Auto-Login Configuration
# Created by setup_passwordless_system.sh on $(date)
[Seat:*]
# Enable auto-login
autologin-user=${TARGET_USER}
autologin-user-timeout=0
autologin-session=i3
# Disable user switching and guest account
allow-user-switching=false
allow-guest=false
# Set session defaults
user-session=i3
greeter-session=lightdm-gtk-greeter
# Disable screen lock timeout during login
autologin-in-background=false
EOF
echo "✓ LightDM auto-login also configured in separate config file: $custom_conf"
# Enable lightdm service
systemctl enable lightdm.service
echo "✓ LightDM service enabled"
# Restart lightdm to apply changes only if --logout flag is provided
if [[ $ALLOW_LOGOUT == true ]]; then
echo "Restarting LightDM to apply auto-login settings..."
systemctl restart lightdm.service
echo "✓ LightDM restarted"
else
echo "✓ LightDM configuration complete (restart lightdm or reboot to activate auto-login)"
fi
}
# Function to configure i3 session
configure_i3_session() {
echo ""
echo "3. Configuring i3 Session..."
echo "==========================="
local xsessions_dir="/usr/share/xsessions"
local i3_desktop="$xsessions_dir/i3.desktop"
# Create xsessions directory if it doesn't exist
mkdir -p "$xsessions_dir"
# Check if i3.desktop exists, create if not
if [[ ! -f $i3_desktop ]]; then
cat > "$i3_desktop" << EOF
[Desktop Entry]
Name=i3
Comment=improved dynamic tiling window manager
Exec=i3
TryExec=i3
Type=Application
X-LightDM-DesktopName=i3
DesktopNames=i3
Keywords=tiling;wm;windowmanager;window;manager;
EOF
echo "✓ Created i3 desktop session file: $i3_desktop"
else
echo "✓ i3 desktop session file already exists"
fi
# Ensure user has i3 config directory
local user_home="/home/${TARGET_USER}"
local i3_config_dir="$user_home/.config/i3"
if [[ ! -d $i3_config_dir ]]; then
sudo -u "$TARGET_USER" mkdir -p "$i3_config_dir"
echo "✓ Created i3 config directory for user: $TARGET_USER"
fi
}
# Function to configure additional auto-login settings
configure_additional_settings() {
echo ""
echo "4. Configuring Additional Settings..."
echo "===================================="
# Add user to autologin group if it exists
if getent group autologin &> /dev/null; then
usermod -a -G autologin "$TARGET_USER"
echo "✓ Added $TARGET_USER to autologin group"
else
# Create autologin group
groupadd -r autologin
usermod -a -G autologin "$TARGET_USER"
echo "✓ Created autologin group and added $TARGET_USER"
fi
# Configure pam for auto-login (if needed)
local pam_lightdm="/etc/pam.d/lightdm-autologin"
if [[ ! -f $pam_lightdm ]]; then
cat > "$pam_lightdm" << EOF
#%PAM-1.0
# LightDM auto-login PAM configuration
# Created by setup_passwordless_system.sh on $(date)
auth required pam_unix.so nullok
auth optional pam_permit.so
auth optional pam_gnome_keyring.so
account include system-local-login
password include system-local-login
session include system-local-login
session optional pam_gnome_keyring.so auto_start
EOF
echo "✓ Created PAM configuration for auto-login"
fi
}
# Function to test configurations
test_configurations() {

View File

@ -69,7 +69,8 @@ def split_script(
inserted = False
for line in kept:
out.append(line)
if not inserted and line.strip() in ("set -e", "set -eu", "set -euo pipefail"):
# `set -e # comment` is common here, so match the directive, not the line.
if not inserted and re.match(r"^set -[euo pipefail]+\b", line.strip()):
out += ["", f"# shellcheck source={rel}", source_line]
inserted = True
if not inserted: