Bladeren bron

Add an automatic install option to the initramfs.

Michael Aldridge 9 jaren geleden
bovenliggende
commit
76ea7500b2
4 gewijzigde bestanden met toevoegingen van 423 en 2 verwijderingen
  1. 76 0
      autoinstaller/autoinstall.cfg
  2. 293 0
      autoinstaller/install.sh
  3. 45 0
      autoinstaller/module-setup.sh
  4. 9 2
      mklive.sh.in

+ 76 - 0
autoinstaller/autoinstall.cfg

@@ -0,0 +1,76 @@
+#!/bin/sh
+# Void Linux Automatic Install Configuration
+
+# ===
+# Disk Configuration
+# ===
+# disk: the disk to install to
+# default: the first disk that isn't the installer
+#disk=/dev/hda
+
+# bootpartitionsize: controls how large the boot partition will be
+# default: 500M
+#bootpartitionsize=500M
+
+# swapsize: how large should the swap partition be
+# default: equal to the installed physical memory
+#swapsize=
+
+# ===
+# XBPS Configuration
+# ===
+# xbpsrepository: which repo should the install pull from
+# default: http://repo.voidlinux.eu/current
+#xbpsrepository="http://repo.voidlinux.eu/current"
+
+# pkgs: additional packages to install into the target
+# default: none
+#pkgs=""
+
+# ===
+# Default User
+# ===
+# username: the username of the user to be created
+# default: voidlinux
+#username=""
+
+# password: password to set for the new user
+# default: unset (will prompt during install)
+# Warning: This does not work in musl!
+#password=""
+
+# ===
+# Misc. Options
+# ===
+# timezone: Timezone in TZ format
+# default: America/Chicago
+#timezone="America/Chicago"
+
+# keymap: Keymap to use by default
+# default: us
+#keymap="us"
+
+# locale: initial glibc locale
+# default: en_US.UTF-8
+#libclocale=en.US.UTF-8
+
+# hostname: static hostname for the system
+# default: derived from DNS
+#hostname=VoidLinux
+
+# end_action: what to do at the end of the install
+# default: shutdown
+# alternate values: reboot, script, func
+#end_action=shutdown
+
+# end_script: script to optionally run at end of install
+# the user script must reside somewhere xbps-uhelper fetch
+# can retrieve it from
+# default: not set
+#end_script=""
+
+# end_function: a function to optionally be run at
+# the end of the install.
+#end_function() {
+#
+#}

+ 293 - 0
autoinstaller/install.sh

@@ -0,0 +1,293 @@
+#!/bin/sh
+
+set -e
+
+# These functions pulled from void's excellent mklive.sh
+VAI_info_msg() {
+    printf "\033[1m%s\n\033[m" "$@"
+}
+
+VAI_print_step() {
+    CURRENT_STEP=$((CURRENT_STEP+1))
+    VAI_info_msg "[${CURRENT_STEP}/${STEP_COUNT}] $*"
+}
+
+# ----------------------- Install Functions ------------------------
+
+VAI_welcome() {
+    clear
+    printf "=============================================================\n"
+    printf "================ Void Linux Auto-Installer ==================\n"
+    printf "=============================================================\n"
+}
+
+VAI_get_address() {
+    # Enable the hook for resolv.conf
+    mkdir -p /usr/lib/dhcpcd/dhcpcd-hooks
+    ln -sf /usr/libexec/dhcpcd-hooks/20-resolv.conf /usr/lib/dhcpcd/dhcpcd-hooks/
+
+    # Get an IP address
+    dhcpcd -w -L --timeout 0
+}
+
+VAI_partition_disk() {
+    # Paritition Disk
+    sfdisk "${disk}" <<EOF
+,$bootpartitionsize
+,${swapsize}K
+;
+EOF
+}
+
+VAI_format_disk() {
+    # Make Filesystems
+    mkfs.ext4 -F "${disk}1"
+    mkfs.ext4 -F "${disk}3"
+    if [ "${swapsize}" -ne 0 ] ; then
+        mkswap -f "${disk}2"
+    fi
+}
+
+VAI_mount_target() {
+    # Mount targetfs
+    mkdir -p "${target}"
+    mount "${disk}3" "${target}"
+    mkdir "${target}/boot"
+    mount "${disk}1" "${target}/boot"
+}
+
+VAI_install_xbps_keys() {
+    mkdir -p "${target}/var/db/xbps/keys"
+    cp /var/db/xbps/keys/* "${target}/var/db/xbps/keys"
+}
+
+VAI_install_base_system() {
+    # Install a base system
+    XBPS_ARCH="${XBPS_ARCH}" xbps-install -Sy -R "${xbpsrepository}" -r /mnt base-system grub
+
+    # Install additional packages
+    if [  -n "${pkgs}" ] ; then
+        XBPS_ARCH="${XBPS_ARCH}" xbps-install -Sy -R "${xbpsrepository}" -r /mnt "${pkgs}"
+    fi
+}
+
+VAI_prepare_chroot() {
+    # Mount dev, bind, proc, etc into chroot
+    mount -t proc proc "${target}/proc"
+    mount -t sysfs sys "${target}/sys"
+    mount -o rbind /dev "${target}/dev"
+}
+
+VAI_configure_sudo() {
+    # Give wheel sudo
+    echo "%wheel ALL=(ALL) ALL" > "${target}/etc/sudoers.d/wheel"
+}
+
+VAI_correct_root_permissions() {
+    chroot "${target}" chown root:root /
+    chroot "${target}" chmod 755 /
+}
+
+VAI_configure_hostname() {
+    # Set the hostname
+    echo "${hostname}" > "${target}/etc/hostname"
+}
+
+VAI_configure_rc_conf() {
+    # Set the value of various tokens
+    sed -i "s:Europe/Madrid:${timezone}:" "${target}/etc/rc.conf"
+    sed -i "s:\"es\":\"${keymap}\":" "${target}/etc/rc.conf"
+
+    # Activate various tokens
+    sed -i "s:#HARDWARECLOCK:HARDWARECLOCK:" "${target}/etc/rc.conf"
+    sed -i "s:#TIMEZONE:TIMEZONE:" "${target}/etc/rc.conf"
+    sed -i "s:#KEYMAP:KEYMAP:" "${target}/etc/rc.conf"
+}
+
+VAI_add_user() {
+    chroot "${target}" useradd -m -s /bin/bash -U -G wheel,users,audio,video,cdrom,input "${username}"
+    if [ -z "${password}" ] ; then
+        chroot "${target}" passwd "${username}"
+    else
+        # For reasons that remain unclear, this does not work in musl
+        echo "${username}:${password}" | chpasswd -c SHA512 -R "${target}"
+fi
+}
+
+VAI_configure_grub() {
+    # Set hostonly
+    echo "hostonly=yes" > "${target}/etc/dracut.conf.d/hostonly.conf"
+
+    # Choose the newest kernel
+    kernel_version="$(chroot "${target}" xbps-query linux | awk -F "[-_]" '/pkgver/ {print $2}')"
+
+    # Install grub
+    chroot "${target}" grub-install "${disk}"
+    chroot "${target}" xbps-reconfigure -f "linux${kernel_version}"
+
+    # Correct the grub install
+    chroot "${target}" update-grub
+}
+
+VAI_configure_fstab() {
+    # Grab UUIDs
+    uuid1="$(blkid -s UUID -o value "${disk}1")"
+    uuid2="$(blkid -s UUID -o value "${disk}2")"
+    uuid3="$(blkid -s UUID -o value "${disk}3")"
+
+    # Installl UUIDs into /etc/fstab
+    echo "UUID=$uuid3 / ext4 defaults,errors=remount-ro 0 1" >> "${target}/etc/fstab"
+    echo "UUID=$uuid1 /boot ext4 defaults 0 2" >> "${target}/etc/fstab"
+    if [ "${swapsize}" -ne 0 ] ; then
+        echo "UUID=$uuid2 swap swap defaults 0 0" >> "${target}/etc/fstab"
+    fi
+}
+
+VAI_configure_locale() {
+    # Set the libc-locale iff glibc
+    case "${XBPS_ARCH}" in
+        *-musl)
+            VAI_info_msg "Glibc locales are not supported on musl"
+            ;;
+        *)
+            sed -i "/${libclocale}/s/#//" "${target}/etc/default/libc-locales"
+
+            chroot "${target}" xbps-reconfigure -f glibc-locales
+            ;;
+    esac
+}
+
+VAI_end_action() {
+    case $end_action in
+        reboot)
+            VAI_info_msg "Rebooting the system"
+            sync
+            umount -R "${target}"
+            reboot -f
+            ;;
+        shutdown)
+            VAI_info_msg "Shutting down the system"
+            sync
+            umount -R "${target}"
+            poweroff -f
+            ;;
+        script)
+            VAI_info_msg "Running user provided script"
+            xbps-uhelper fetch "${end_script}>/script"
+            chmod +x /script
+            target=${target} xbpsrepository=${xbpsrepository} /script
+            ;;
+        func)
+            VAI_info_msg "Running user provided function"
+            end_function
+            ;;
+    esac
+}
+
+VAI_configure_autoinstall() {
+    # -------------------------- Setup defaults ---------------------------
+    bootpartitionsize="500M"
+    disk="$(lsblk -ipo NAME,TYPE,MOUNTPOINT | awk '{if ($2=="disk") {disks[$1]=0; last=$1} if ($3=="/") {disks[last]++}} END {for (a in disks) {if(disks[a] == 0){print a; break}}}')"
+    hostname="$(ip -4 -o -r a | awk -F'[ ./]' '{x=$7} END {print x}')"
+    swapsize="$(awk -F"\n" '/MemTotal/ {split($0, b, " "); print b[2] }' /proc/meminfo)";
+    target="/mnt"
+    timezone="America/Chicago"
+    keymap="us"
+    libclocale="en_US.UTF-8"
+    username="voidlinux"
+    end_action="shutdown"
+    end_script="/bin/true"
+
+    XBPS_ARCH="$(xbps-uhelper arch)"
+    case $XBPS_ARCH in
+        *-musl)
+            xbpsrepository="https://repo.voidlinux.eu/current/musl"
+            ;;
+        *)
+            xbpsrepository="https://repo.voidlinux.eu/current"
+            ;;
+    esac
+
+    # --------------- Pull config URL out of kernel cmdline -------------------------
+    if getargbool 0 autourl ; then
+        xbps-uhelper fetch "$(getarg autourl)>/etc/autoinstall.cfg"
+
+    else
+        mv /etc/autoinstall.default /etc/autoinstall.cfg
+    fi
+
+    # Read in the resulting config file which we got via some method
+    if [ -f /etc/autoinstall.cfg ] ; then
+        VAI_info_msg "Reading configuration file"
+        . ./etc/autoinstall.cfg
+    fi
+
+    # Bail out if we didn't get a usable disk
+    if [ -z "$disk" ] ; then
+        die "No valid disk!"
+    fi
+}
+
+VAI_main() {
+    CURRENT_STEP=0
+    STEP_COUNT=16
+
+    VAI_welcome
+
+    VAI_print_step "Bring up the network"
+    VAI_get_address
+
+    VAI_print_step "Configuring installer"
+    VAI_configure_autoinstall
+
+    VAI_print_step "Configuring disk using scheme 'Atomic'"
+    VAI_partition_disk
+    VAI_format_disk
+
+    VAI_print_step "Mounting the target filesystems"
+    VAI_mount_target
+
+    VAI_print_step "Installing XBPS keys"
+    VAI_install_xbps_keys
+
+    VAI_print_step "Installing the base system"
+    VAI_install_base_system
+
+    VAI_print_step "Granting sudo to default user"
+    VAI_configure_sudo
+
+    VAI_print_step "Setting hostname"
+    VAI_configure_hostname
+
+    VAI_print_step "Configure rc.conf"
+    VAI_configure_rc_conf
+
+    VAI_print_step "Preparing the chroot"
+    VAI_prepare_chroot
+
+    VAI_print_step "Fix ownership of /"
+    VAI_correct_root_permissions
+
+    VAI_print_step "Adding default user"
+    VAI_add_user
+
+    VAI_print_step "Configuring GRUB"
+    VAI_configure_grub
+
+    VAI_print_step "Configuring /etc/fstab"
+    VAI_configure_fstab
+
+    VAI_print_step "Configuring libc-locales"
+    VAI_configure_locale
+
+    VAI_print_step "Performing end-action"
+    VAI_end_action
+}
+
+# If we are using the autoinstaller, launch it
+if getargbool 0 auto  ; then
+    VAI_main
+fi
+
+# Very important to release this before returning to dracut code
+set +e

+ 45 - 0
autoinstaller/module-setup.sh

@@ -0,0 +1,45 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+
+check() {
+    return 255
+}
+
+depends() {
+    echo network
+}
+
+install() {
+    inst /usr/bin/awk
+    inst /usr/bin/chmod
+    inst /usr/bin/chroot
+    inst /usr/bin/clear
+    inst /usr/bin/cp
+    inst /usr/bin/chpasswd
+    inst /usr/bin/dhcpcd
+    inst /usr/bin/halt
+    inst /usr/bin/install
+    inst /usr/bin/lsblk
+    inst /usr/bin/mkdir
+    inst /usr/bin/mkfs.ext4
+    inst /usr/bin/mkswap
+    inst /usr/bin/mount
+    inst /usr/bin/sfdisk
+    inst /usr/bin/sync
+    inst /usr/bin/xbps-install
+    inst /usr/bin/xbps-uhelper
+    inst /usr/bin/xbps-query
+
+    inst /usr/libexec/dhcpcd-hooks/20-resolv.conf
+    inst /usr/libexec/dhcpcd-run-hooks
+
+    inst_multiple /var/db/xbps/keys/*
+    inst_multiple /usr/share/xbps.d/*
+
+    inst_multiple /etc/ssl/certs/*
+    inst /etc/ssl/certs.pem
+
+    inst_hook pre-mount 01 "$moddir/install.sh"
+    inst "$moddir/autoinstall.cfg" /etc/autoinstall.default
+}

+ 9 - 2
mklive.sh.in

@@ -30,7 +30,7 @@ trap 'error_out $? $LINENO' INT TERM 0
 umask 022
 
 readonly REQUIRED_PKGS="base-files libgcc dash coreutils sed tar gawk syslinux grub-i386-efi grub-x86_64-efi squashfs-tools xorriso"
-readonly INITRAMFS_PKGS="binutils xz device-mapper"
+readonly INITRAMFS_PKGS="binutils xz device-mapper dhclient dracut-network"
 readonly PROGNAME=$(basename $0)
 
 info_msg() {
@@ -103,6 +103,11 @@ copy_dracut_files() {
     cp dracut/* $1/usr/lib/dracut/modules.d/01vmklive/
 }
 
+copy_autoinstaller_files() {
+    mkdir -p $1/usr/lib/dracut/modules.d/01autoinstaller
+    cp autoinstaller/* $1/usr/lib/dracut/modules.d/01autoinstaller/
+}
+
 install_prereqs() {
     copy_void_conf $VOIDHOSTDIR
     XBPS_ARCH=$ARCH $XBPS_INSTALL_CMD -r $VOIDHOSTDIR $XBPS_REPOSITORY \
@@ -149,13 +154,14 @@ generate_initramfs() {
     local _args
 
     copy_dracut_files $ROOTFS
+    copy_autoinstaller_files $ROOTFS
     if [ "$BASE_SYSTEM_PKG" = "base-system-systemd" ]; then
         _args="--add systemd"
     else
         _args="--omit systemd"
     fi
     chroot $ROOTFS env -i /usr/bin/dracut -N --${INITRAMFS_COMPRESSION} \
-        --add-drivers "ahci" --force-add "vmklive" ${_args} "/boot/initrd" $KERNELVERSION
+        --add-drivers "ahci" --force-add "vmklive autoinstaller" ${_args} "/boot/initrd" $KERNELVERSION
     [ $? -ne 0 ] && die "Failed to generate the initramfs"
 
     mv $ROOTFS/boot/initrd $BOOT_DIR
@@ -172,6 +178,7 @@ cleanup_rootfs() {
         fi
     done
     rm -r $ROOTFS/usr/lib/dracut/modules.d/01vmklive
+    rm -r $ROOTFS/usr/lib/dracut/modules.d/01autoinstaller
 }
 
 generate_isolinux_boot() {