#!/bin/bash # This script load zfs kernel module for any archiso. # github.com/eoli3n # Thanks to CalimeroTeknik on #archlinux-fr, FFY00 on #archlinux-projects, JohnDoe2 on #regex set -e ### Functions print () { echo -e "\n\033[1m> $1\033[0m" } get_running_kernel_version () { # Returns running kernel version # Get running kernel version kernel_version=$(uname -r) print "Current kernel version is $kernel_version" } get_iso_build_date () { # Returns running kernel build date formated as 'YYYY/MM/DD' # Get running kernel build date kernel_date=$(date +%Y/%m/%d -d "$(LANG=C pacman -Qi linux |sed -n 's/^Install Date\s*: //p')") } init_archzfs () { if pacman -Sl archzfs >/dev/null 2>&1; then print "archzfs repo was already added" return fi print "Adding archzfs repo" pacman -Sy archlinux-keyring --noconfirm &>/dev/null pacman-key --populate archlinux &>/dev/null pacman-key --recv-keys F75D9D76 --keyserver keyserver.ubuntu.com &>/dev/null pacman-key --lsign-key F75D9D76 &>/dev/null cat >> /etc/pacman.conf <<"EOF" [archzfs] Server = http://archzfs.com/archzfs/x86_64 Server = http://mirror.sum7.eu/archlinux/archzfs/archzfs/x86_64 Server = https://mirror.biocrafting.net/archlinux/archzfs/archzfs/x86_64 EOF pacman -Sy &>/dev/null } init_archlinux_archive () { # $1 is date formated as 'YYYY/MM/DD' # Returns False if repo does not exists # Set repo repo="https://archive.archlinux.org/repos/$1/\$repo/os/\$arch" # If repo exists, set it curl -s "$repo" && echo "Server=$repo" > /etc/pacman.d/mirrorlist } search_package () { # $1 is package name to search # $2 is version to match # Set regex to match package local regex='href="\K(?![^"]*\.sig)'"$1"'-(?=\d)[^"]*'"$2"'[^"]*x86_64[^"]*' # href=" # match href=" # \K # don't return anything matched prior to this point # (?![^"]*\.sig) # remove .sig matches # '"$1"'-(?=\d) # find me '$package-' escaped by shell and ensure that after "-" is a digit # [^"]* # match anything between '"' # '"$2"' # match version escaped by shell # [^"]* # match anything between '"' # x86_64 # now match architecture # [^"]* # match anything between '"' # Set archzfs URLs list local urls="http://archzfs.com/archzfs/x86_64/ http://archzfs.com/archive_archzfs/" # Loop search for url in $urls do print "Searching $1 on $url..." # Query url and try to match package local package=$(curl -s "$url" | grep -Po "$regex" | tail -n 1) # If a package is found if [[ -n $package ]] then print "Package \"$package\" found" # Build package url package_url="$url$package" # Break loop break fi done } download_package () { # $1 is package url to download in tmp # It returns downloaded file path local filename="${1##*/}" # Download package in tmp cd /tmp curl -sO "$1" cd - # Set out file package_file="/tmp/$filename" print "Downloading to $package_file ..." } dkms_init () { #print "Installing linux-headers for current running kernel" #pacman -U "https://archive.org/download/archlinux_pkg_linux-headers/linux-headers-$1-x86_64.pkg.tar.zst" --noconfirm print "Init Archlinux Archive repository" archiso_version=$(sed 's-\.-/-g' /version) init_archlinux_archive "$archiso_version" print "Download Archlinux Archives package lists and upgrade" pacman -Syyuu --noconfirm print "Install base-devel" pacman -S --noconfirm base-devel } ### Main print "Testing if archiso is running" grep archiso /proc/cmdline >/dev/null print "Increasing cowspace to half of RAM" mount -o remount,size=50% /run/archiso/cowspace # Init archzfs repository init_archzfs # Search kernel package # https://github.com/archzfs/archzfs/issues/337#issuecomment-624312576 get_running_kernel_version kernel_version_fixed="${kernel_version//-/\.}" kernel_version_fixed_for_headers="${kernel_version/-/\.}" # Search zfs-linux package matching running kernel version search_package "zfs-linux" "$kernel_version_fixed" zfs_linux_url="$package_url" # If a package is found if [[ -n $zfs_linux_url ]] then # Download package download_package $zfs_linux_url zfs_linux_package="$package_file" print "Extracting zfs-utils version from zfs-linux PKGINFO" # Extract zfs-utils version from zfs-linux PKGINFO zfs_utils_version=$(bsdtar -qxO -f "$zfs_linux_package" .PKGINFO | grep -Po 'depend = zfs-utils=\K.*') # Search zfs-utils package matching zfs-linux package dependency search_package "zfs-utils" "$zfs_utils_version" zfs_utils_url="$package_url" if [[ -n $zfs_utils_url ]] then print "Installing zfs-utils and zfs-linux" # Install packages pacman -U "$zfs_utils_url" --noconfirm &>/dev/null pacman -U "$zfs_linux_package" --noconfirm &>/dev/null && zfs=1 fi else # DKMS fallback print "No zfs-linux package was found for current running kernel, fallback on DKMS method" dkms_init "$kernel_version_fixed_for_headers" print "Install zfs-dkms" # Install package pacman -S zfs-dkms --noconfirm && zfs=1 fi # Load kernel module if [[ "$zfs" == "1" ]] then modprobe zfs && echo -e "\n\e[32mZFS is ready\n" else print "No ZFS module found" fi