diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index fd502aa3d..a95959ae2 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -85,6 +85,13 @@ jobs: rm -rf workdir/ out/ mkdir -p out/ + # Fix the profiledef.sh file to ensure correct SquashFS options + sed -i 's/-threads/-Xcompression-threads/' profiledef.sh || true + + # Verify SquashFS options + echo '=== Checking SquashFS options in profiledef.sh ===' + grep 'airootfs_image_tool_options' profiledef.sh + # Build the ISO with verbose output mkarchiso -v -w workdir/ -o out/ . 2>&1 | tee build.log || { echo '::error::ISO build failed!' diff --git a/.github/workflows/dockerfile-check.yaml b/.github/workflows/dockerfile-check.yaml index ed690462d..af0832bcd 100644 --- a/.github/workflows/dockerfile-check.yaml +++ b/.github/workflows/dockerfile-check.yaml @@ -6,18 +6,57 @@ on: workflow_dispatch: schedule: # Run the workflow on the 1st of every month at midnight - - cron: 0 0 * * * + - cron: '0 0 1 * *' jobs: build: - runs-on: ubuntu-latest # Use a standard runner + runs-on: ubuntu-latest + timeout-minutes: 120 # Add a timeout to prevent hung builds steps: - name: Checkout Repository uses: actions/checkout@v4 - - name: Build and Run Docker container + - name: Set up Environment run: | - set -e # Exit immediately if a command exits with a non-zero status - docker build -t arch-iso-builder . || { echo "Docker build failed"; exit 1; } - docker run --rm --privileged -v "$(pwd)":/workdir arch-iso-builder bash -c "mkarchiso -v -w workdir/ -o out/ ." || { echo "ISO creation failed"; exit 1; } + echo "Setting up environment..." + mkdir -p out + chmod +x scripts/entrypoint.sh + chmod +x scripts/select-mirrors.sh + chmod +x profiledef.sh + + - name: Build Docker Image + run: | + echo "Building Docker image..." + docker build -t arch-iso-builder . || { + echo "::error::Docker build failed" + exit 1 + } + + - name: Validate Configuration + run: | + echo "Validating configuration..." + docker run --rm -v "$(pwd)":/workdir arch-iso-builder validate || { + echo "::error::Configuration validation failed" + exit 1 + } + + - name: Build ISO + run: | + echo "Building ISO..." + # Create a small-scale test build with output to verify the process works + docker run --rm --privileged \ + -v "$(pwd)":/workdir \ + arch-iso-builder build out work || { + echo "::error::ISO build failed" + exit 1 + } + + # Verify that output directory contains files + if [ ! -d "out" ] || [ -z "$(ls -A out 2>/dev/null)" ]; then + echo "::error::Output directory is empty or does not exist" + exit 1 + else + echo "ISO build process completed successfully!" + ls -la out + fi diff --git a/airootfs/etc/inputrc b/airootfs/etc/inputrc new file mode 100644 index 000000000..ee25be4dc --- /dev/null +++ b/airootfs/etc/inputrc @@ -0,0 +1,14 @@ +# Disable all bell sounds in readline applications +set bell-style none + +# Make Tab autocomplete regardless of filename case +set completion-ignore-case on + +# Show all autocomplete results at once +set page-completions off + +# If there are more than 200 possible completions for a word, ask to show them all +set completion-query-items 200 + +# Show extra file information when completing, like `ls -F` does +set visible-stats on \ No newline at end of file diff --git a/airootfs/etc/mkinitcpio.conf.d/performance.conf b/airootfs/etc/mkinitcpio.conf.d/performance.conf new file mode 100644 index 000000000..474a34925 --- /dev/null +++ b/airootfs/etc/mkinitcpio.conf.d/performance.conf @@ -0,0 +1,9 @@ +# Performance optimizations for mkinitcpio +# Use all available CPU cores for compression +COMPRESSION_OPTIONS=(-T0) + +# Use faster zstd compression with good ratio +COMPRESSION="zstd" + +# Use better hooks order for faster boot +HOOKS=(base udev autodetect modconf block filesystems keyboard) \ No newline at end of file diff --git a/airootfs/etc/modprobe.d/alsa-no-beep.conf b/airootfs/etc/modprobe.d/alsa-no-beep.conf new file mode 100644 index 000000000..7c68e171f --- /dev/null +++ b/airootfs/etc/modprobe.d/alsa-no-beep.conf @@ -0,0 +1,5 @@ +# Disable PC speaker beeps through ALSA +options snd_hda_intel beep_mode=0 +options snd_hda_core beep_mode=0 +# Some hardware may require this as well +options snd-pcsp index=-2 \ No newline at end of file diff --git a/airootfs/etc/modprobe.d/nobeep.conf b/airootfs/etc/modprobe.d/nobeep.conf new file mode 100644 index 000000000..3747ce781 --- /dev/null +++ b/airootfs/etc/modprobe.d/nobeep.conf @@ -0,0 +1,17 @@ +# Disable PC Speaker +blacklist pcspkr +blacklist snd_pcsp + +# Disable additional beep modules +blacklist hpilo +blacklist ipmi_si +blacklist hpwdt +blacklist toshiba_acpi + +# PC speaker options if module is loaded anyway +options pcspkr enable=0 +options snd_pcsp enable=0 + +# Explicitly install the dummy module instead +install pcspkr /bin/true +install snd_pcsp /bin/true \ No newline at end of file diff --git a/airootfs/etc/skel/.bashrc b/airootfs/etc/skel/.bashrc new file mode 100644 index 000000000..95dc7f121 --- /dev/null +++ b/airootfs/etc/skel/.bashrc @@ -0,0 +1,25 @@ +# ~/.bashrc: executed by bash for non-login shells + +# Disable terminal bell in bash +bind 'set bell-style none' + +# If not running interactively, don't do anything else +[[ $- != *i* ]] && return + +# Color prompt +PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' + +# Enable color support +alias ls='ls --color=auto' +alias grep='grep --color=auto' +alias fgrep='fgrep --color=auto' +alias egrep='egrep --color=auto' + +# Add useful aliases +alias ll='ls -l' +alias la='ls -la' + +# History settings +HISTCONTROL=ignoreboth +HISTSIZE=1000 +HISTFILESIZE=2000 \ No newline at end of file diff --git a/airootfs/etc/systemd/system/no-beep.service b/airootfs/etc/systemd/system/no-beep.service new file mode 100644 index 000000000..7396b1d51 --- /dev/null +++ b/airootfs/etc/systemd/system/no-beep.service @@ -0,0 +1,17 @@ +[Unit] +Description=Disable system beeps +Documentation=https://github.com/Githubguy132010/Arch-Linux-without-the-beeps +DefaultDependencies=no +Before=sysinit.target +After=local-fs.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/bash -c "rmmod pcspkr snd_pcsp 2>/dev/null || true" +ExecStart=/bin/bash -c "echo 'blacklist pcspkr' > /etc/modprobe.d/nobeep.conf" +ExecStart=/bin/bash -c "echo 'blacklist snd_pcsp' >> /etc/modprobe.d/nobeep.conf" +ExecStart=/bin/bash -c "if [ -f /sys/module/i8042/parameters/nopnp ]; then echo 1 > /sys/module/i8042/parameters/nopnp; fi" + +[Install] +WantedBy=sysinit.target \ No newline at end of file diff --git a/airootfs/etc/systemd/system/sysinit.target.wants/no-beep.service b/airootfs/etc/systemd/system/sysinit.target.wants/no-beep.service new file mode 120000 index 000000000..b237e6dfc --- /dev/null +++ b/airootfs/etc/systemd/system/sysinit.target.wants/no-beep.service @@ -0,0 +1 @@ +/etc/systemd/system/no-beep.service \ No newline at end of file diff --git a/dockerfile b/dockerfile index 9deedfead..73ff93777 100644 --- a/dockerfile +++ b/dockerfile @@ -1,15 +1,35 @@ -FROM archlinux:latest +FROM archlinux:latest AS builder -# Install necessary packages +# Set up parallel downloads and other optimizations +COPY pacman.conf /etc/pacman.conf + +# Update system and install necessary packages RUN pacman -Syu --noconfirm && \ - pacman -S --noconfirm git archiso grub + pacman -S --noconfirm --needed \ + git \ + archiso \ + grub \ + base-devel \ + && pacman -Scc --noconfirm + +# Set the working directory +WORKDIR /build + +# Copy only necessary files for package installation +COPY packages.x86_64 bootstrap_packages.x86_64 profiledef.sh ./ + +# Create a new final image +FROM builder AS final # Set the working directory WORKDIR /workdir -# Copy files into the container +# Copy the rest of the files COPY . . -# Instead of running mkarchiso here, we leave it for later execution -# Create an entrypoint or leave it to manual execution -CMD ["/bin/bash"] +# Use an entrypoint script for better flexibility +COPY ./scripts/entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] +CMD ["build"] diff --git a/grub/grub.cfg b/grub/grub.cfg index 25194a36f..e67e6e058 100644 --- a/grub/grub.cfg +++ b/grub/grub.cfg @@ -45,7 +45,8 @@ fi # Set default menu entry default=archlinux -timeout=15 +# Reduced timeout for faster boot +timeout=5 timeout_style=menu @@ -53,7 +54,7 @@ timeout_style=menu menuentry "Arch Linux install medium (%ARCH%, ${archiso_platform})" --class arch --class gnu-linux --class gnu --class os --id 'archlinux' { set gfxpayload=keep - linux /%INSTALL_DIR%/boot/%ARCH%/vmlinuz-linux archisobasedir=%INSTALL_DIR% archisosearchuuid=%ARCHISO_UUID% + linux /%INSTALL_DIR%/boot/%ARCH%/vmlinuz-linux archisobasedir=%INSTALL_DIR% archisosearchuuid=%ARCHISO_UUID% quiet loglevel=3 udev.log_level=3 vt.global_cursor_default=0 initrd /%INSTALL_DIR%/boot/%ARCH%/initramfs-linux.img } @@ -102,6 +103,4 @@ menuentry 'System restart' --class reboot --class restart { reboot } - -# GRUB init tune for accessibility -play 600 988 1 1319 4 +# Removed accessibility beep diff --git a/pacman.conf b/pacman.conf index 2c5a344ae..ec38b27f1 100644 --- a/pacman.conf +++ b/pacman.conf @@ -11,14 +11,14 @@ # If you wish to use different paths, uncomment and update the paths. #RootDir = / #DBPath = /var/lib/pacman/ -#CacheDir = /var/cache/pacman/pkg/ +CacheDir = /var/cache/pacman/pkg/ #LogFile = /var/log/pacman.log #GPGDir = /etc/pacman.d/gnupg/ #HookDir = /etc/pacman.d/hooks/ HoldPkg = pacman glibc -#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +XferCommand = /usr/bin/curl -L -C - -f -o %o %u --retry 3 --retry-delay 3 --connect-timeout 10 #XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u -#CleanMethod = KeepInstalled +CleanMethod = KeepInstalled Architecture = auto # Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup @@ -30,12 +30,12 @@ Architecture = auto # Misc options #UseSyslog -#Color -#NoProgressBar +Color +ILoveCandy +ParallelDownloads = 16 # We cannot check disk space from within a chroot environment #CheckSpace -#VerbosePkgLists -ParallelDownloads = 64 +VerbosePkgLists DownloadUser = alpm #DisableSandbox @@ -90,8 +90,8 @@ Include = /etc/pacman.d/mirrorlist #[multilib-testing] #Include = /etc/pacman.d/mirrorlist -#[multilib] -#Include = /etc/pacman.d/mirrorlist +[multilib] +Include = /etc/pacman.d/mirrorlist # An example of a custom package repository. See the pacman manpage for # tips on creating your own repositories. diff --git a/profiledef.sh b/profiledef.sh old mode 100644 new mode 100755 index ce26e793d..8f0dd0d26 --- a/profiledef.sh +++ b/profiledef.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash # shellcheck disable=SC2034 -iso_name="archlinux" -iso_label="ARCH_$(date --date="@${SOURCE_DATE_EPOCH:-$(date +%s)}" +%Y%m)" -iso_publisher="Arch Linux " -iso_application="Arch Linux Live/Rescue DVD" +iso_name="archlinux-nobeep" +iso_label="ARCH_NOBEEP_$(date --date="@${SOURCE_DATE_EPOCH:-$(date +%s)}" +%Y%m)" +iso_publisher="Arch Linux No Beep " +iso_application="Arch Linux No Beep Live/Rescue DVD" iso_version="$(date --date="@${SOURCE_DATE_EPOCH:-$(date +%s)}" +%Y.%m.%d)" install_dir="arch" buildmodes=('iso') @@ -14,7 +14,17 @@ bootmodes=('bios.syslinux.mbr' 'bios.syslinux.eltorito' arch="x86_64" pacman_conf="pacman.conf" airootfs_image_type="squashfs" -airootfs_image_tool_options=('-comp' 'xz' '-Xbcj' 'x86' '-b' '1M' '-Xdict-size' '1M') + +# Use better compression options correctly formatted for mksquashfs with XZ +# XZ compressor supports these options: -Xbcj and -Xdict-size +if [ "$(nproc)" -gt 2 ]; then + # For multi-core systems: use XZ with bcj x86 filter for better compression + airootfs_image_tool_options=('-comp' 'xz' '-Xbcj' 'x86' '-b' '1M' '-Xdict-size' '1M') +else + # For single/dual-core systems: use the same options but may be slower + airootfs_image_tool_options=('-comp' 'xz' '-Xbcj' 'x86' '-b' '1M' '-Xdict-size' '75%') +fi + bootstrap_tarball_compression=('zstd' '-c' '-T0' '--auto-threads=logical' '--long' '-19') file_permissions=( ["/etc/shadow"]="0:0:400" diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh new file mode 100755 index 000000000..7d6d8d46f --- /dev/null +++ b/scripts/entrypoint.sh @@ -0,0 +1,171 @@ +#!/bin/bash +set -e + +# Colors for better output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +log() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +error() { + echo -e "${RED}[ERROR]${NC} $1" + exit 1 +} + +# Function to build the ISO +build_iso() { + local output_dir="${1:-out}" + local work_dir="${2:-work}" + + log "Starting Arch Linux ISO build process..." + log "Work directory: $work_dir" + log "Output directory: $output_dir" + + # Create necessary directories + mkdir -p "$output_dir" + + # Run the mirror selection script + log "Selecting fastest mirrors..." + ./scripts/select-mirrors.sh || warn "Mirror selection failed, continuing with default mirrors" + + # Disable PC speaker module if present + if grep -q "pcspkr" /etc/modprobe.d/nobeep.conf 2>/dev/null; then + log "PC speaker already disabled in configuration." + else + log "Disabling PC speaker in configuration..." + mkdir -p airootfs/etc/modprobe.d/ + echo "blacklist pcspkr" > airootfs/etc/modprobe.d/nobeep.conf + echo "blacklist snd_pcsp" >> airootfs/etc/modprobe.d/nobeep.conf + fi + + # Create a custom hook to disable beeps in various config files + if [ ! -f "airootfs/usr/share/libalpm/hooks/99-no-beep.hook" ]; then + log "Creating custom hook to disable beeps..." + mkdir -p airootfs/usr/share/libalpm/hooks/ + cat > airootfs/usr/share/libalpm/hooks/99-no-beep.hook << 'EOF' +[Trigger] +Type = Package +Operation = Install +Operation = Upgrade +Target = * + +[Action] +Description = Disabling system beeps in various configuration files... +When = PostTransaction +Exec = /bin/bash -c "mkdir -p /etc/modprobe.d && echo 'blacklist pcspkr' > /etc/modprobe.d/nobeep.conf && echo 'blacklist snd_pcsp' >> /etc/modprobe.d/nobeep.conf && if [ -f /etc/inputrc ]; then grep -q 'set bell-style none' /etc/inputrc || echo 'set bell-style none' >> /etc/inputrc; fi" +EOF + fi + + # Add settings to disable terminal bell in bash + if [ ! -f "airootfs/etc/skel/.bashrc" ]; then + log "Adding bash configuration to disable terminal bell..." + mkdir -p airootfs/etc/skel/ + echo "# Disable terminal bell" > airootfs/etc/skel/.bashrc + echo "bind 'set bell-style none'" >> airootfs/etc/skel/.bashrc + fi + + # Set bell-style none in global inputrc + if [ ! -f "airootfs/etc/inputrc" ]; then + log "Setting bell-style none in global inputrc..." + echo "set bell-style none" > airootfs/etc/inputrc + fi + + # Optimize the build process with parallel compression + export JOBS=$(nproc) + log "Using $JOBS processors for parallel compression" + + # Run mkarchiso with optimized parameters + log "Building Arch ISO with mkarchiso..." + MKARCHISO_OPTS="-v" + if [ "$JOBS" -gt 1 ]; then + MKARCHISO_OPTS+=" -C xz:threads=$JOBS" + fi + + mkarchiso $MKARCHISO_OPTS -w "$work_dir" -o "$output_dir" . + + # Check if build was successful + if [ $? -eq 0 ]; then + log "ISO build completed successfully!" + log "ISO available at: $output_dir" + else + error "ISO build failed!" + fi +} + +# Function to clean up build artifacts +clean() { + log "Cleaning up build artifacts..." + rm -rf work/* + log "Cleanup complete." +} + +# Function to validate the configuration +validate() { + log "Validating configuration..." + + # Check if packages.x86_64 exists + if [ ! -f "packages.x86_64" ]; then + error "packages.x86_64 file not found!" + fi + + # Check if profiledef.sh exists and is executable + if [ ! -x "profiledef.sh" ]; then + error "profiledef.sh not found or not executable!" + fi + + # Check if pacman.conf exists + if [ ! -f "pacman.conf" ]; then + error "pacman.conf not found!" + fi + + # Sort and deduplicate package lists + log "Sorting and deduplicating package lists..." + if [ -f "packages.x86_64" ]; then + sort -u packages.x86_64 -o packages.x86_64 + fi + + if [ -f "bootstrap_packages.x86_64" ]; then + sort -u bootstrap_packages.x86_64 -o bootstrap_packages.x86_64 + fi + + log "Configuration appears valid." +} + +# Main switch +case "$1" in + build) + validate + build_iso "$2" "$3" + ;; + clean) + clean + ;; + validate) + validate + ;; + shell) + log "Starting interactive shell..." + exec /bin/bash + ;; + *) + log "Usage: $0 {build|clean|validate|shell} [output_dir] [work_dir]" + log "" + log "Commands:" + log " build - Build the Arch Linux ISO" + log " clean - Clean up build artifacts" + log " validate - Validate the configuration" + log " shell - Start an interactive shell" + exit 1 + ;; +esac + +exit 0 \ No newline at end of file diff --git a/scripts/select-mirrors.sh b/scripts/select-mirrors.sh new file mode 100755 index 000000000..17a3fd719 --- /dev/null +++ b/scripts/select-mirrors.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -e + +# Colors for better output +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +NC='\033[0m' # No Color + +log() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log "Selecting fastest mirrors..." + +# Create mirror directory if it doesn't exist +mkdir -p airootfs/etc/pacman.d/ +cp /etc/pacman.d/mirrorlist airootfs/etc/pacman.d/mirrorlist.backup 2>/dev/null || true + +# Install reflector if not already installed +if ! command -v reflector &> /dev/null; then + log "Installing reflector..." + pacman -Sy --noconfirm reflector +fi + +# Generate mirror list with reflector +log "Generating optimized mirror list..." +reflector --latest 20 \ + --sort rate \ + --protocol https \ + --save airootfs/etc/pacman.d/mirrorlist + +log "Mirror selection complete!" \ No newline at end of file