diff options
70 files changed, 2927 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..5966153 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +.gitattributes export-ignore +.gitignore export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7d71495 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*~ +archiso-*.tar.gz* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8a7ef4e --- /dev/null +++ b/Makefile @@ -0,0 +1,57 @@ +V=2013.09.01 + +INSTALL_SRC_DIR=parabolaiso/initcpio/install +HOOKS_SRC_DIR=parabolaiso/initcpio/hooks +SCRIPT_SRC_DIR=parabolaiso/initcpio/script + +INSTALL_DIR=$(DESTDIR)/usr/lib/initcpio/install +HOOKS_DIR=$(DESTDIR)/usr/lib/initcpio/hooks +SCRIPT_DIR=$(DESTDIR)/usr/lib/initcpio +DOC_DIR=$(DESTDIR)/usr/share/doc/parabolaiso + + +all: install dist + +install: install-program install-initcpio install-examples install-doc + +install-program: + install -D -m 755 parabolaiso/mkparabolaiso "$(DESTDIR)/usr/bin/mkparabolaiso" + +install-initcpio: + install -d "$(SCRIPT_DIR)" "$(HOOKS_DIR)" "$(INSTALL_DIR)" + install -m 755 -t "$(SCRIPT_DIR)" $(wildcard $(SCRIPT_SRC_DIR)/*) + install -m 644 -t "$(HOOKS_DIR)" $(wildcard $(HOOKS_SRC_DIR)/*) + install -m 644 -t "$(INSTALL_DIR)" $(wildcard $(INSTALL_SRC_DIR)/*) + +install-examples: + install -d -m 755 "$(DESTDIR)/usr/share/parabolaiso/" + cp -a --no-preserve=ownership configs "$(DESTDIR)/usr/share/parabolaiso/" + +install-doc: + install -d "$(DOC_DIR)" + install -m 644 -t "$(DOC_DIR)" $(wildcard docs/*) + +uninstall: uninstall-program uninstall-initcpio uninstall-examples uninstall-doc + +uninstall-program: + rm "$(DESTDIR)/usr/bin/mkparabolaiso" + +uninstall-initcpio: + $(foreach file,$(wildcard $(SCRIPT_SRC_DIR)/*),rm -r "$(subst $(SCRIPT_SRC_DIR),$(SCRIPT_DIR),$(file))";) + $(foreach file,$(wildcard $(HOOKS_SRC_DIR)/*),rm -r "$(subst $(HOOKS_SRC_DIR),$(HOOKS_DIR),$(file))";) + $(foreach file,$(wildcard $(INSTALL_SRC_DIR)/*),rm -r "$(subst $(INSTALL_SRC_DIR),$(INSTALL_DIR),$(file))";) + +uninstall-examples: + rm -rfd "$(DESTDIR)/usr/share/parabolaiso/configs" + rm -d "$(DESTDIR)/usr/share/parabolaiso" + +uninstall-doc: + rm -rf "$(DOC_DIR)" + +dist: + ./expand $(V) dist + +dist-branches: + ./expand $(V) dist-branches + +.PHONY: install install-program install-initcpio install-examples install-doc dist dist-branches uninstall uninstall-program uninstall-initcpio uninstall-examples uninstall-doc @@ -0,0 +1,2 @@ +* Add lots and lots of help to the syslinux menu +* Add keymaps list to syslinux diff --git a/configs/releng/aitab b/configs/releng/aitab new file mode 100644 index 0000000..b7e9a17 --- /dev/null +++ b/configs/releng/aitab @@ -0,0 +1,3 @@ +# <img> <mnt> <arch> <sfs_comp> <fs_type> <fs_size> +root-image / i686 xz ext4 50% +root-image / x86_64 xz ext4 50% diff --git a/configs/releng/build.sh b/configs/releng/build.sh new file mode 100755 index 0000000..a978772 --- /dev/null +++ b/configs/releng/build.sh @@ -0,0 +1,253 @@ +#!/bin/bash + +set -e -u + +iso_name=parabola +iso_label="PARA_$(date +%Y%m)" +iso_version=$(date +%Y.%m.%d) +install_dir=parabola +work_dir=work +out_dir=out +data_dir=/usr/share/parabolaiso/data + +arch=$(uname -m) +verbose="" +pacman_conf=${work_dir}/pacman.conf +script_path=$(readlink -f ${0%/*}) + +_usage () +{ + echo "usage ${0} [options]" + echo + echo " General options:" + echo " -N <iso_name> Set an iso filename (prefix)" + echo " Default: ${iso_name}" + echo " -V <iso_version> Set an iso version (in filename)" + echo " Default: ${iso_version}" + echo " -L <iso_label> Set an iso label (disk label)" + echo " Default: ${iso_label}" + echo " -D <install_dir> Set an install_dir (directory inside iso)" + echo " Default: ${install_dir}" + echo " -w <work_dir> Set the working directory" + echo " Default: ${work_dir}" + echo " -o <out_dir> Set the output directory" + echo " Default: ${out_dir}" + echo " -v Enable verbose output" + echo " -h This help message" + exit ${1} +} + +# Helper function to run make_*() only one time per architecture. +run_once() { + if [[ ! -e ${work_dir}/build.${1}_${arch} ]]; then + $1 + touch ${work_dir}/build.${1}_${arch} + fi +} + +# Setup custom pacman.conf with current cache directories. +make_pacman_conf() { + local _cache_dirs + _cache_dirs=($(pacman -v 2>&1 | grep '^Cache Dirs:' | sed 's/Cache Dirs:\s*//g')) + sed -r "s|^#?\\s*CacheDir.+|CacheDir = $(echo -n ${_cache_dirs[@]})|g" ${script_path}/pacman.conf > ${pacman_conf} +} + +# Base installation, plus needed packages (root-image) +make_basefs() { + setarch ${arch} mkparabolaiso ${verbose} -w "${work_dir}/${arch}" -C "${pacman_conf}" -D "${install_dir}" init + setarch ${arch} mkparabolaiso ${verbose} -w "${work_dir}/${arch}" -C "${pacman_conf}" -D "${install_dir}" -p "memtest86+ mkinitcpio-nfs-utils nbd" install +} + +# Additional packages (root-image) +make_packages() { + setarch ${arch} mkparabolaiso ${verbose} -w "${work_dir}/${arch}" -C "${pacman_conf}" -D "${install_dir}" -p "$(grep -h -v ^# ${script_path}/packages.{both,${arch}})" install +} + +# Copy mkinitcpio parabolaiso hooks and build initramfs (root-image) +make_setup_mkinitcpio() { + local _hook + for _hook in parabolaiso parabolaiso_shutdown parabolaiso_pxe_common parabolaiso_pxe_nbd parabolaiso_pxe_http parabolaiso_pxe_nfs parabolaiso_loop_mnt; do + cp /usr/lib/initcpio/hooks/${_hook} ${work_dir}/${arch}/root-image/usr/lib/initcpio/hooks + cp /usr/lib/initcpio/install/${_hook} ${work_dir}/${arch}/root-image/usr/lib/initcpio/install + done + cp /usr/lib/initcpio/install/parabolaiso_kms ${work_dir}/${arch}/root-image/usr/lib/initcpio/install + cp /usr/lib/initcpio/parabolaiso_shutdown ${work_dir}/${arch}/root-image/usr/lib/initcpio + cp ${script_path}/mkinitcpio.conf ${work_dir}/${arch}/root-image/etc/mkinitcpio-parabolaiso.conf + setarch ${arch} mkparabolaiso ${verbose} -w "${work_dir}/${arch}" -C "${pacman_conf}" -D "${install_dir}" -r 'mkinitcpio -c /etc/mkinitcpio-parabolaiso.conf -k /boot/vmlinuz-linux-libre -g /boot/parabolaiso.img' run +} + +# Customize installation (root-image) +make_customize_root_image() { + cp -af ${script_path}/root-image ${work_dir}/${arch} + + setarch ${arch} mkparabolaiso ${verbose} -w "${work_dir}/${arch}" -C "${pacman_conf}" -D "${install_dir}" -r '/root/customize_root_image.sh' run + rm ${work_dir}/${arch}/root-image/root/customize_root_image.sh +} + +# Prepare kernel/initramfs ${install_dir}/boot/ +make_boot() { + mkdir -p ${work_dir}/iso/${install_dir}/boot/${arch} + cp ${work_dir}/${arch}/root-image/boot/parabolaiso.img ${work_dir}/iso/${install_dir}/boot/${arch}/parabolaiso.img + cp ${work_dir}/${arch}/root-image/boot/vmlinuz-linux-libre ${work_dir}/iso/${install_dir}/boot/${arch}/vmlinuz +} + +# Add other aditional/extra files to ${install_dir}/boot/ +make_boot_extra() { + cp ${work_dir}/${arch}/root-image/boot/memtest86+/memtest.bin ${work_dir}/iso/${install_dir}/boot/memtest + cp ${work_dir}/${arch}/root-image/usr/share/licenses/common/GPL2/license.txt ${work_dir}/iso/${install_dir}/boot/memtest.COPYING +} + +# Prepare /${install_dir}/boot/syslinux +make_syslinux() { + mkdir -p ${work_dir}/iso/${install_dir}/boot/syslinux + for _cfg in ${script_path}/syslinux/*.cfg; do + sed "s|%PARABOLAISO_LABEL%|${iso_label}|g; + s|%INSTALL_DIR%|${install_dir}|g" ${_cfg} > ${work_dir}/iso/${install_dir}/boot/syslinux/${_cfg##*/} + done + cp ${data_dir}/splash.png ${work_dir}/iso/${install_dir}/boot/syslinux + cp ${work_dir}/${arch}/root-image/usr/lib/syslinux/*.c32 ${work_dir}/iso/${install_dir}/boot/syslinux + cp ${work_dir}/${arch}/root-image/usr/lib/syslinux/*.com ${work_dir}/iso/${install_dir}/boot/syslinux + cp ${work_dir}/${arch}/root-image/usr/lib/syslinux/*.0 ${work_dir}/iso/${install_dir}/boot/syslinux + cp ${work_dir}/${arch}/root-image/usr/lib/syslinux/memdisk ${work_dir}/iso/${install_dir}/boot/syslinux + mkdir -p ${work_dir}/iso/${install_dir}/boot/syslinux/hdt + gzip -c -9 ${work_dir}/${arch}/root-image/usr/share/hwdata/pci.ids > ${work_dir}/iso/${install_dir}/boot/syslinux/hdt/pciids.gz + gzip -c -9 ${work_dir}/${arch}/root-image/usr/lib/modules/*-LIBRE/modules.alias > ${work_dir}/iso/${install_dir}/boot/syslinux/hdt/modalias.gz +} + +# Prepare /isolinux +make_isolinux() { + mkdir -p ${work_dir}/iso/isolinux + sed "s|%INSTALL_DIR%|${install_dir}|g" ${script_path}/isolinux/isolinux.cfg > ${work_dir}/iso/isolinux/isolinux.cfg + cp ${work_dir}/${arch}/root-image/usr/lib/syslinux/isolinux.bin ${work_dir}/iso/isolinux/ + cp ${work_dir}/${arch}/root-image/usr/lib/syslinux/isohdpfx.bin ${work_dir}/iso/isolinux/ +} + +# Prepare /EFI +make_efi() { + mkdir -p ${work_dir}/iso/EFI/boot + cp ${work_dir}/x86_64/root-image/usr/lib/gummiboot/gummibootx64.efi ${work_dir}/iso/EFI/boot/bootx64.efi + + mkdir -p ${work_dir}/iso/loader/entries + cp ${script_path}/efiboot/loader/loader.conf ${work_dir}/iso/loader/ + cp ${script_path}/efiboot/loader/entries/uefi-shell-v2-x86_64.conf ${work_dir}/iso/loader/entries/ + cp ${script_path}/efiboot/loader/entries/uefi-shell-v1-x86_64.conf ${work_dir}/iso/loader/entries/ + + sed "s|%PARABOLAISO_LABEL%|${iso_label}|g; + s|%INSTALL_DIR%|${install_dir}|g" \ + ${script_path}/efiboot/loader/entries/parabolaiso-x86_64-usb.conf > ${work_dir}/iso/loader/entries/parabolaiso-x86_64.conf + + # EFI Shell 2.0 for UEFI 2.3+ ( http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=UEFI_Shell ) + cp ${data_dir}/Shell.efi ${work_dir}/iso/EFI/shellx64_v2.efi + # EFI Shell 1.0 for non UEFI 2.3+ ( http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=Efi-shell ) + cp ${data_dir}/Shell_Full.efi ${work_dir}/iso/EFI/shellx64_v1.efi +} + +# Prepare efiboot.img::/EFI for "El Torito" EFI boot mode +make_efiboot() { + mkdir -p ${work_dir}/iso/EFI/parabolaiso + truncate -s 31M ${work_dir}/iso/EFI/parabolaiso/efiboot.img + mkfs.vfat -n PARABOLAISO_EFI ${work_dir}/iso/EFI/parabolaiso/efiboot.img + + mkdir -p ${work_dir}/efiboot + mount ${work_dir}/iso/EFI/parabolaiso/efiboot.img ${work_dir}/efiboot + + mkdir -p ${work_dir}/efiboot/EFI/parabolaiso + cp ${work_dir}/iso/${install_dir}/boot/x86_64/vmlinuz ${work_dir}/efiboot/EFI/parabolaiso/vmlinuz.efi + cp ${work_dir}/iso/${install_dir}/boot/x86_64/parabolaiso.img ${work_dir}/efiboot/EFI/parabolaiso/parabolaiso.img + + mkdir -p ${work_dir}/efiboot/EFI/boot + cp ${work_dir}/x86_64/root-image/usr/lib/gummiboot/gummibootx64.efi ${work_dir}/efiboot/EFI/boot/bootx64.efi + + mkdir -p ${work_dir}/efiboot/loader/entries + cp ${script_path}/efiboot/loader/loader.conf ${work_dir}/efiboot/loader/ + cp ${script_path}/efiboot/loader/entries/uefi-shell-v2-x86_64.conf ${work_dir}/efiboot/loader/entries/ + cp ${script_path}/efiboot/loader/entries/uefi-shell-v1-x86_64.conf ${work_dir}/efiboot/loader/entries/ + + sed "s|%PARABOLAISO_LABEL%|${iso_label}|g; + s|%INSTALL_DIR%|${install_dir}|g" \ + ${script_path}/efiboot/loader/entries/parabolaiso-x86_64-cd.conf > ${work_dir}/efiboot/loader/entries/parabolaiso-x86_64.conf + + cp ${work_dir}/iso/EFI/shellx64_v2.efi ${work_dir}/efiboot/EFI/ + cp ${work_dir}/iso/EFI/shellx64_v1.efi ${work_dir}/efiboot/EFI/ + + umount ${work_dir}/efiboot +} + +# Copy aitab +make_aitab() { + mkdir -p ${work_dir}/iso/${install_dir} + cp ${script_path}/aitab ${work_dir}/iso/${install_dir}/aitab +} + +# Build all filesystem images specified in aitab (.fs.sfs .sfs) +make_prepare() { + cp -a -l -f ${work_dir}/${arch}/root-image ${work_dir} + setarch ${arch} mkparabolaiso ${verbose} -w "${work_dir}" -D "${install_dir}" pkglist + setarch ${arch} mkparabolaiso ${verbose} -w "${work_dir}" -D "${install_dir}" prepare + rm -rf ${work_dir}/root-image + # rm -rf ${work_dir}/${arch}/root-image (if low space, this helps) +} + +# Build ISO +make_iso() { + mkparabolaiso ${verbose} -w "${work_dir}" -D "${install_dir}" checksum + mkparabolaiso ${verbose} -w "${work_dir}" -D "${install_dir}" -L "${iso_label}" -o "${out_dir}" iso "${iso_name}-${iso_version}-dual.iso" +} + +if [[ ${EUID} -ne 0 ]]; then + echo "This script must be run as root." + _usage 1 +fi + +if [[ ${arch} != x86_64 ]]; then + echo "This script needs to be run on x86_64" + _usage 1 +fi + +while getopts 'N:V:L:D:w:o:vh' arg; do + case "${arg}" in + N) iso_name="${OPTARG}" ;; + V) iso_version="${OPTARG}" ;; + L) iso_label="${OPTARG}" ;; + D) install_dir="${OPTARG}" ;; + w) work_dir="${OPTARG}" ;; + o) out_dir="${OPTARG}" ;; + v) verbose="-v" ;; + h) _usage 0 ;; + *) + echo "Invalid argument '${arg}'" + _usage 1 + ;; + esac +done + +mkdir -p ${work_dir} + +run_once make_pacman_conf + +# Do all stuff for each root-image +for arch in i686 x86_64; do + run_once make_basefs + run_once make_packages + run_once make_setup_mkinitcpio + run_once make_customize_root_image +done + +for arch in i686 x86_64; do + run_once make_boot +done + +# Do all stuff for "iso" +run_once make_boot_extra +run_once make_syslinux +run_once make_isolinux +run_once make_efi +run_once make_efiboot + +run_once make_aitab + +for arch in i686 x86_64; do + run_once make_prepare +done + +run_once make_iso diff --git a/configs/releng/efiboot/loader/entries/parabolaiso-x86_64-cd.conf b/configs/releng/efiboot/loader/entries/parabolaiso-x86_64-cd.conf new file mode 100644 index 0000000..057e14f --- /dev/null +++ b/configs/releng/efiboot/loader/entries/parabolaiso-x86_64-cd.conf @@ -0,0 +1,4 @@ +title Parabola GNU/Linux-libre parabolaiso x86_64 UEFI CD +linux /EFI/parabolaiso/vmlinuz.efi +initrd /EFI/parabolaiso/parabolaiso.img +options parabolaisobasedir=%INSTALL_DIR% parabolaisolabel=%PARABOLAISO_LABEL% diff --git a/configs/releng/efiboot/loader/entries/parabolaiso-x86_64-usb.conf b/configs/releng/efiboot/loader/entries/parabolaiso-x86_64-usb.conf new file mode 100644 index 0000000..3863799 --- /dev/null +++ b/configs/releng/efiboot/loader/entries/parabolaiso-x86_64-usb.conf @@ -0,0 +1,4 @@ +title Parabola GNU/Linux-libre parabolaiso x86_64 UEFI USB +linux /%INSTALL_DIR%/boot/x86_64/vmlinuz +initrd /%INSTALL_DIR%/boot/x86_64/parabolaiso.img +options parabolaisobasedir=%INSTALL_DIR% parabolaisolabel=%PARABOLAISO_LABEL% diff --git a/configs/releng/efiboot/loader/entries/uefi-shell-v1-x86_64.conf b/configs/releng/efiboot/loader/entries/uefi-shell-v1-x86_64.conf new file mode 100644 index 0000000..9597ff2 --- /dev/null +++ b/configs/releng/efiboot/loader/entries/uefi-shell-v1-x86_64.conf @@ -0,0 +1,2 @@ +title UEFI Shell x86_64 v1 +efi /EFI/shellx64_v1.efi diff --git a/configs/releng/efiboot/loader/entries/uefi-shell-v2-x86_64.conf b/configs/releng/efiboot/loader/entries/uefi-shell-v2-x86_64.conf new file mode 100644 index 0000000..0dde77a --- /dev/null +++ b/configs/releng/efiboot/loader/entries/uefi-shell-v2-x86_64.conf @@ -0,0 +1,2 @@ +title UEFI Shell x86_64 v2 +efi /EFI/shellx64_v2.efi diff --git a/configs/releng/efiboot/loader/loader.conf b/configs/releng/efiboot/loader/loader.conf new file mode 100644 index 0000000..ba02c50 --- /dev/null +++ b/configs/releng/efiboot/loader/loader.conf @@ -0,0 +1,2 @@ +timeout 3 +default parabolaiso-x86_64 diff --git a/configs/releng/isolinux/isolinux.cfg b/configs/releng/isolinux/isolinux.cfg new file mode 100644 index 0000000..3ee24e0 --- /dev/null +++ b/configs/releng/isolinux/isolinux.cfg @@ -0,0 +1,5 @@ +DEFAULT loadconfig + +LABEL loadconfig + CONFIG /%INSTALL_DIR%/boot/syslinux/parabolaiso.cfg + APPEND /%INSTALL_DIR%/ diff --git a/configs/releng/mkinitcpio.conf b/configs/releng/mkinitcpio.conf new file mode 100644 index 0000000..1006d1d --- /dev/null +++ b/configs/releng/mkinitcpio.conf @@ -0,0 +1,2 @@ +HOOKS="base udev memdisk parabolaiso_shutdown parabolaiso parabolaiso_loop_mnt parabolaiso_pxe_common parabolaiso_pxe_nbd parabolaiso_pxe_http parabolaiso_pxe_nfs parabolaiso_kms block pcmcia filesystems keyboard" +COMPRESSION="xz" diff --git a/configs/releng/packages.both b/configs/releng/packages.both new file mode 100644 index 0000000..65d5651 --- /dev/null +++ b/configs/releng/packages.both @@ -0,0 +1,57 @@ +arch-install-scripts +btrfs-progs +crda +darkhttpd +ddrescue +dhclient +dialog +dmraid +dnsmasq +dnsutils +dosfstools +elinks +ethtool +f2fs-tools +fsarchiver +gnu-netcat +gpm +gptfdisk +grml-zsh-config +grub +haveged +hdparm +irssi +lftp +linux-atm +lynx +mc +mtools +nfs-utils +nilfs-utils +nmap +ntfs-3g +ntp +openconnect +openssh +openvpn +partclone +parted +partimage +pptpclient +ppp +rfkill +rp-pppoe +rsync +smartmontools +sudo +tcpdump +testdisk +usb_modeswitch +vpnc +wget +wireless_tools +wpa_actiond +zile +wvdial +xl2tpd +zsh diff --git a/configs/releng/packages.i686 b/configs/releng/packages.i686 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/configs/releng/packages.i686 diff --git a/configs/releng/packages.x86_64 b/configs/releng/packages.x86_64 new file mode 100644 index 0000000..956e946 --- /dev/null +++ b/configs/releng/packages.x86_64 @@ -0,0 +1,2 @@ +gummiboot +refind-efi diff --git a/configs/releng/pacman.conf b/configs/releng/pacman.conf new file mode 100644 index 0000000..746df64 --- /dev/null +++ b/configs/releng/pacman.conf @@ -0,0 +1,97 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -C - -f %u > %o +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +#UseDelta = 0.7 +Architecture = auto + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +#TotalDownload +# We cannot check disk space from within a chroot environment +#CheckSpace +#VerbosePkgLists + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux and Parabola +# packagers with `pacman-key --populate archlinux` and `pacman-key --populate parabola`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +#[libre-testing] +#Include = /etc/pacman.d/mirrorlist + +[libre] +Include = /etc/pacman.d/mirrorlist + +#[testing] +#Include = /etc/pacman.d/mirrorlist + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +#[community-testing] +#Include = /etc/pacman.d/mirrorlist + +[community] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/configs/releng/root-image/etc/fstab b/configs/releng/root-image/etc/fstab new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/configs/releng/root-image/etc/fstab diff --git a/configs/releng/root-image/etc/hostname b/configs/releng/root-image/etc/hostname new file mode 100644 index 0000000..8aaf41b --- /dev/null +++ b/configs/releng/root-image/etc/hostname @@ -0,0 +1 @@ +parabolaiso diff --git a/configs/releng/root-image/etc/locale.conf b/configs/releng/root-image/etc/locale.conf new file mode 100644 index 0000000..01ec548 --- /dev/null +++ b/configs/releng/root-image/etc/locale.conf @@ -0,0 +1 @@ +LANG=en_US.UTF-8 diff --git a/configs/releng/root-image/etc/motd b/configs/releng/root-image/etc/motd new file mode 100644 index 0000000..05ab207 --- /dev/null +++ b/configs/releng/root-image/etc/motd @@ -0,0 +1,14 @@ + +[01;34m=============================================================================== + + [01;36mParabola live media _DATE_[00;37m + + To install Parabola, the system must be connected to the internet. + For instructions, enter this command: + [01;37mlynx network.html[00;37m + + Press the number keys while holding Alt to switch virtual terminals. + This allows entering commands without closing lynx. + +[01;34m=============================================================================== +[00;37m diff --git a/configs/releng/root-image/etc/pam.d/su b/configs/releng/root-image/etc/pam.d/su new file mode 100644 index 0000000..a291042 --- /dev/null +++ b/configs/releng/root-image/etc/pam.d/su @@ -0,0 +1,6 @@ +#%PAM-1.0 +auth sufficient pam_rootok.so +auth sufficient pam_wheel.so trust use_uid +auth required pam_unix.so +account required pam_unix.so +session required pam_unix.so diff --git a/configs/releng/root-image/etc/sudoers.d/g_wheel b/configs/releng/root-image/etc/sudoers.d/g_wheel new file mode 100644 index 0000000..8c45359 --- /dev/null +++ b/configs/releng/root-image/etc/sudoers.d/g_wheel @@ -0,0 +1 @@ +%wheel ALL=(ALL) NOPASSWD: ALL diff --git a/configs/releng/root-image/etc/systemd/scripts/choose-mirror b/configs/releng/root-image/etc/systemd/scripts/choose-mirror new file mode 100755 index 0000000..13c9f69 --- /dev/null +++ b/configs/releng/root-image/etc/systemd/scripts/choose-mirror @@ -0,0 +1,26 @@ +#!/bin/bash + +get_cmdline() { + local param + for param in $(< /proc/cmdline); do + case "${param}" in + $1=*) echo "${param##*=}"; + return 0 + ;; + esac + done +} + +mirror=$(get_cmdline mirror) +[[ $mirror = auto ]] && mirror=$(get_cmdline parabolaiso_http_srv) +[[ $mirror ]] || exit 0 + +mv /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.orig +cat >/etc/pacman.d/mirrorlist << EOF +# +# Parabola GNU/Linux-libre repository mirrorlist +# Generated by parabolaiso +# + +Server = ${mirror%%/}/\$repo/os/\$arch +EOF diff --git a/configs/releng/root-image/etc/systemd/system/choose-mirror.service b/configs/releng/root-image/etc/systemd/system/choose-mirror.service new file mode 100644 index 0000000..1e4d771 --- /dev/null +++ b/configs/releng/root-image/etc/systemd/system/choose-mirror.service @@ -0,0 +1,10 @@ +[Unit] +Description=Choose mirror from the kernel command line +ConditionKernelCommandLine=mirror + +[Service] +Type=oneshot +ExecStart=/etc/systemd/scripts/choose-mirror + +[Install] +WantedBy=multi-user.target diff --git a/configs/releng/root-image/etc/systemd/system/etc-pacman.d-gnupg.mount b/configs/releng/root-image/etc/systemd/system/etc-pacman.d-gnupg.mount new file mode 100644 index 0000000..4eab551 --- /dev/null +++ b/configs/releng/root-image/etc/systemd/system/etc-pacman.d-gnupg.mount @@ -0,0 +1,8 @@ +[Unit] +Description=Temporary /etc/pacman.d/gnupg directory + +[Mount] +What=tmpfs +Where=/etc/pacman.d/gnupg +Type=tmpfs +Options=mode=0755 diff --git a/configs/releng/root-image/etc/systemd/system/getty@tty1.service.d/autologin.conf b/configs/releng/root-image/etc/systemd/system/getty@tty1.service.d/autologin.conf new file mode 100644 index 0000000..d1d8474 --- /dev/null +++ b/configs/releng/root-image/etc/systemd/system/getty@tty1.service.d/autologin.conf @@ -0,0 +1,3 @@ +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin root --noclear %I 38400 linux diff --git a/configs/releng/root-image/etc/systemd/system/pacman-init.service b/configs/releng/root-image/etc/systemd/system/pacman-init.service new file mode 100644 index 0000000..3414ebc --- /dev/null +++ b/configs/releng/root-image/etc/systemd/system/pacman-init.service @@ -0,0 +1,16 @@ +[Unit] +Description=Initializes Pacman keyring +Wants=haveged.service +After=haveged.service +Requires=etc-pacman.d-gnupg.mount +After=etc-pacman.d-gnupg.mount + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/bin/pacman-key --init +ExecStart=/usr/bin/pacman-key --populate archlinux +ExecStart=/usr/bin/pacman-key --populate parabola + +[Install] +WantedBy=multi-user.target diff --git a/configs/releng/root-image/etc/udev/rules.d/81-dhcpcd.rules b/configs/releng/root-image/etc/udev/rules.d/81-dhcpcd.rules new file mode 100644 index 0000000..970da69 --- /dev/null +++ b/configs/releng/root-image/etc/udev/rules.d/81-dhcpcd.rules @@ -0,0 +1 @@ +ACTION=="add", SUBSYSTEM=="net", ENV{SYSTEMD_WANTS}="dhcpcd@$name.service" diff --git a/configs/releng/root-image/root/.automated_script.sh b/configs/releng/root-image/root/.automated_script.sh new file mode 100755 index 0000000..fb106da --- /dev/null +++ b/configs/releng/root-image/root/.automated_script.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +script_cmdline () +{ + local param + for param in $(< /proc/cmdline); do + case "${param}" in + script=*) echo "${param##*=}" ; return 0 ;; + esac + done +} + +automated_script () +{ + local script rt + script="$(script_cmdline)" + if [[ -n "${script}" && ! -x /tmp/startup_script ]]; then + if [[ "${script}" =~ ^http:// || "${script}" =~ ^ftp:// ]]; then + wget "${script}" --retry-connrefused -q -O /tmp/startup_script >/dev/null + rt=$? + else + cp "${script}" /tmp/startup_script + rt=$? + fi + if [[ ${rt} -eq 0 ]]; then + chmod +x /tmp/startup_script + /tmp/startup_script + fi + fi +} + +if [[ $(tty) == "/dev/tty1" ]]; then + automated_script +fi diff --git a/configs/releng/root-image/root/.zlogin b/configs/releng/root-image/root/.zlogin new file mode 100644 index 0000000..f598e43 --- /dev/null +++ b/configs/releng/root-image/root/.zlogin @@ -0,0 +1 @@ +~/.automated_script.sh diff --git a/configs/releng/root-image/root/customize_root_image.sh b/configs/releng/root-image/root/customize_root_image.sh new file mode 100755 index 0000000..9c980f1 --- /dev/null +++ b/configs/releng/root-image/root/customize_root_image.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -e -u + +sed -i 's/#\(en_US\.UTF-8\)/\1/' /etc/locale.gen +locale-gen + +ln -sf /usr/share/zoneinfo/UTC /etc/localtime + +usermod -s /usr/bin/zsh root +cp -aT /etc/skel/ /root/ + +useradd -m -p "" -g users -G "adm,audio,floppy,log,network,rfkill,scanner,storage,optical,power,wheel" -s /usr/bin/zsh parabola + +chmod 750 /etc/sudoers.d +chmod 440 /etc/sudoers.d/g_wheel + +sed -i "s/#Server/Server/g" /etc/pacman.d/mirrorlist + +systemctl enable multi-user.target pacman-init.service choose-mirror.service + +sed -i "s/_DATE_/${iso_version}/" /etc/motd diff --git a/configs/releng/root-image/root/network.html b/configs/releng/root-image/root/network.html new file mode 100644 index 0000000..057e680 --- /dev/null +++ b/configs/releng/root-image/root/network.html @@ -0,0 +1,191 @@ +Online version: <a href="https://wiki.parabolagnulinux.org/Start_installing">https://wiki.parabolagnulinux.org/Start_installing</a> +<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<ul> +<li class="toclevel-1 tocsection-1"><a href="#Start_installing"><span class="tocnumber">1</span> <span class="toctext">Start installing</span></a> +<ul> +<li class="toclevel-2 tocsection-2"><a href="#Change_the_language"><span class="tocnumber">1.1</span> <span class="toctext">Change the language</span></a></li> +<li class="toclevel-2 tocsection-3"><a href="#Establish_an_internet_connection"><span class="tocnumber">1.2</span> <span class="toctext">Establish an internet connection</span></a> +<ul> +<li class="toclevel-3 tocsection-4"><a href="#Wired"><span class="tocnumber">1.2.1</span> <span class="toctext">Wired</span></a></li> +<li class="toclevel-3 tocsection-5"><a href="#Wireless"><span class="tocnumber">1.2.2</span> <span class="toctext">Wireless</span></a></li> +<li class="toclevel-3 tocsection-6"><a href="#Analog_modem.2C_ISDN_or_PPPoE_DSL"><span class="tocnumber">1.2.3</span> <span class="toctext">Analog modem, ISDN or PPPoE DSL</span></a></li> +<li class="toclevel-3 tocsection-7"><a href="#Behind_a_proxy_server"><span class="tocnumber">1.2.4</span> <span class="toctext">Behind a proxy server</span></a></li> +</ul> +</li> +</ul> +</li> +</ul> +</td></tr></table> +<h2> <span class="mw-headline" id="Start_installing"> Start installing </span></h2> +<p>You are now presented with a shell prompt, automatically logged in as root. +</p> +<h3> <span class="mw-headline" id="Change_the_language"> Change the language </span></h3> +<div style="padding: 5px; margin: 0.50em 0; background-color: #DDFFDD; border: thin solid #BBDDBB"><strong> Tip: </strong>These are optional for the majority of users. Useful only if you plan on writing in your own language in any of the configuration files, if you use diacritical marks in the Wi-Fi password, or if you would like to receive system messages (e.g. possible errors) in your own language.</div> +<p>By default, the keyboard layout is set to <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">us</span>. If you have a non-<a href="http://en.wikipedia.org/wiki/File:KB_United_States-NoAltGr.svg" class="extiw" title="wikipedia:File:KB United States-NoAltGr.svg">US</a> keyboard layout, run: +</p> +<pre># loadkeys <i>layout</i> +</pre> +<p>...where <i>layout</i> can be <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">fr</span>, <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">uk</span>, <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">dvorak</span>, <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">be-latin1</span>, etc. See <a href="https://wiki.parabolagnulinux.org/KEYMAP#Keyboard_layouts" title="KEYMAP">here</a> for a comprehensive list. +</p><p>The font should also be changed, because most languages use more glyphs than the 26 letter <a href="http://en.wikipedia.org/wiki/English_alphabet" class="extiw" title="wikipedia:English alphabet">English alphabet</a>. Otherwise some foreign characters may show up as white squares or as other symbols. Note that the name is case-sensitive, so please type it <i>exactly</i> as you see it: +</p> +<pre># setfont Lat2-Terminus16 +</pre> +<p>By default, the language is set to English (US). If you would like to change the language for the install process <i>(German, in this example)</i>, remove the <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">#</span> in front of the <a rel="nofollow" class="external text" href="http://www.greendesktiny.com/support/knowledgebase_detail.php?ref=EUH-483">locale</a> you want from <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">/etc/locale.gen</span>, along with English (US). Please choose the <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">UTF-8</span> entry. +</p><p>Use <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">Ctrl+X</span> to exit, and when prompted to save changes, press <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">Y</span> and <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">Enter</span> to use the same filename. +</p> +<pre style="margin-bottom: 0; border-bottom:none; padding-bottom:0.8em; overflow: auto;"># nano /etc/locale.gen</pre> +<pre style="margin-top: 0; border-top-style:dashed; padding-top: 0.8em; overflow: auto;"> +en_US.UTF-8 UTF-8 +de_DE.UTF-8 UTF-8</pre> +<pre># locale-gen +# export LANG=de_DE.UTF-8 +</pre> +<p>Remember, <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">LAlt+LShift</span> activates and deactivates the keymap. +</p> +<h3> <span class="mw-headline" id="Establish_an_internet_connection"> Establish an internet connection </span></h3> +<div style="padding: 5px; margin: 0.50em 0; background-color: #FFDDDD; border: thin solid #DDBBBB"><strong> Warning: </strong>As of v197, udev no longer assigns network interface names according to the wlanX and ethX naming scheme. If you are coming from a different distribution or are reinstalling Parabola and not aware of the new interface naming style, please do not assume that your wireless interface is named wlan0, or that your wired interface is named eth0. You can use the command <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">ip link</span> to discover the names of your interfaces.</div> +<p>The <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">dhcpcd</span> network daemon starts automatically during boot and it will attempt to start a wired connection. Try to ping a server to see if a connection was established. For example, gnu.org: +</p> +<pre style="margin-bottom: 0; border-bottom:none; padding-bottom:0.8em; overflow: auto;"># ping -c 3 gnu.org</pre> +<pre style="margin-top: 0; border-top-style:dashed; padding-top: 0.8em; overflow: auto;">PING gnu.org (208.118.235.148) 56(84) bytes of data. +64 bytes from wildebeest.gnu.org (208.118.235.148): icmp_seq=1 ttl=47 time=183 ms +64 bytes from wildebeest.gnu.org (208.118.235.148): icmp_seq=2 ttl=47 time=168 ms +64 bytes from wildebeest.gnu.org (208.118.235.148): icmp_seq=3 ttl=47 time=183 ms + +--- gnu.org ping statistics --- +3 packets transmitted, 3 received, 0% packet loss, time 2002ms +rtt min/avg/max/mdev = 168.131/178.357/183.914/7.248 ms</pre> +<p>If you get a <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">ping: unknown host</span> error, first check if there is an issue with your cable or wireless signal strength. If not, you will need to set up the network manually, as explained below. Once a connection is established move on to <a href="https://wiki.parabolagnulinux.org/Installation_Guide" title="Installation Guide">Installation Guide</a>. +</p> +<h4> <span class="mw-headline" id="Wired"> Wired </span></h4> +<p>Follow this procedure if you need to set up a wired connection via a static IP address. +</p><p>First, disable the dhcpcd service which was started automatically at boot: +</p> +<pre># systemctl stop dhcpcd.service +</pre> +<p>Identify the name of your Ethernet interface. +</p> +<pre style="margin-bottom: 0; border-bottom:none; padding-bottom:0.8em; overflow: auto;"># ip link</pre> +<pre style="margin-top: 0; border-top-style:dashed; padding-top: 0.8em; overflow: auto;"> +1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 +2: enp2s0f0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 + link/ether 00:11:25:31:69:20 brd ff:ff:ff:ff:ff:ff +3: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT qlen 1000 + link/ether 01:02:03:04:05:06 brd ff:ff:ff:ff:ff:ff</pre> +<p>In this example, the Ethernet interface is <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">enp2s0f0</span>. If you are unsure, your Ethernet interface is likely to start with the letter "e", and unlikely to be "lo" or start with the letter "w". You can also use <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">iwconfig</span> and see which interfaces are not wireless: +</p> +<pre style="margin-bottom: 0; border-bottom:none; padding-bottom:0.8em; overflow: auto;"># iwconfig</pre> +<pre style="margin-top: 0; border-top-style:dashed; padding-top: 0.8em; overflow: auto;">enp2s0f0 no wireless extensions. +wlp3s0 IEEE 802.11bgn ESSID:"NETGEAR97" + Mode:Managed Frequency:2.427 GHz Access Point: 2C:B0:5D:9C:72:BF + Bit Rate=65 Mb/s Tx-Power=16 dBm + Retry long limit:7 RTS thr:off Fragment thr:off + Power Management:on + Link Quality=61/70 Signal level=-49 dBm + Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 + Tx excessive retries:0 Invalid misc:430 Missed beacon:0 +lo no wireless extensions.</pre> +<p>In this example, neither <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">enp2s0f0</span> nor the loopback device have wireless extensions, meaning <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">enp2s0f0</span> is our Ethernet interface. +</p><p>You also need to know these settings: +</p> +<ul><li> Static IP address. +</li><li> Subnet mask. +</li><li> Gateway's IP address. +</li><li> Name servers' (DNS) IP addresses. +</li><li> Domain name (unless you are on a local LAN, in which case you can make it up). +</li></ul> +<p>Activate the connected Ethernet interface (e.g. <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">enp2s0f0</span>): +</p> +<pre># ip link set enp2s0f0 up +</pre> +<p>Add the address: +</p> +<pre># ip addr add <i>ip_address</i>/<i>subnetmask</i> dev <i>interface_name</i> +</pre> +<p>For example: +</p> +<pre># ip addr add 192.168.1.2/24 dev enp2s0f0 +</pre> +<p>For more options, run <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">man ip</span>. +</p><p>Add your gateway like this, substituting your own gateway's IP address: +</p> +<pre># ip route add default via <i>ip_address</i> +</pre> +<p>For example: +</p> +<pre># ip route add default via 192.168.1.1 +</pre> +<p>Edit <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">resolv.conf</span>, substituting your name servers' IP addresses and your local domain name: +</p> +<pre style="margin-bottom: 0; border-bottom:none; padding-bottom:0.8em; overflow: auto;"># nano /etc/resolv.conf</pre> +<pre style="margin-top: 0; border-top-style:dashed; padding-top: 0.8em; overflow: auto;"> +nameserver 61.23.173.5 +nameserver 61.95.849.8 +search example.com</pre> +<div style="padding: 5px; margin: 0.50em 0; background-color: #DDDDFF; border: thin solid #BBBBDD"><strong> Note: </strong>Currently, you may include a maximum of three <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">nameserver</span> lines. In order to overcome this limitation, you can use a locally caching nameserver like <a href="https://wiki.parabolagnulinux.org/Dnsmasq" title="Dnsmasq" class="mw-redirect">Dnsmasq</a>. </div> +<p>You should now have a working network connection. If you do not, check the detailed <a href="https://wiki.parabolagnulinux.org/Network_Configuration" title="Network Configuration" class="mw-redirect">Network Configuration</a> page. +</p> +<h4> <span class="mw-headline" id="Wireless"> Wireless </span></h4> +<p>Follow this procedure if you need wireless connectivity (Wi-Fi) during the installation process. +</p><p>First, identify the name of your wireless interface. +</p> +<pre style="margin-bottom: 0; border-bottom:none; padding-bottom:0.8em; overflow: auto;"># iw dev</pre> +<pre style="margin-top: 0; border-top-style:dashed; padding-top: 0.8em; overflow: auto;">phy#0 + Interface wlp3s0 + ifindex 3 + wdev 0x1 + addr 00:21:6a:5e:52:bc + type managed</pre> +<p>In this example, <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">wlp3s0</span> is the available wireless interface. If you are unsure, your wireless interface is likely to start with the letter "w", and unlikely to be "lo" or start with the letter "e". +</p> +<div style="padding: 5px; margin: 0.50em 0; background-color: #DDDDFF; border: thin solid #BBBBDD"><strong> Note: </strong>If you do not see output similar to this, then your wireless driver has not been loaded. Please see <a href="https://wiki.parabolagnulinux.org/Wireless_Setup" title="Wireless Setup">Wireless Setup</a> for more detailed information.</div> +<p>Bring the interface up with: +</p> +<pre># ip link set wlp3s0 up +</pre> +<p>If you get this error message: <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">SIOCSIFFLAGS: No such file or directory</span>, your wireless chipset could need a non-free firmware to function. This is not supported on Parabola. Please see <a href="https://wiki.parabolagnulinux.org/Wireless_Setup" title="Wireless Setup">Wireless Setup</a> if you are unsure if this is the true for your particular chipset. +</p><p>Next, use <span style="font-family: monospace"><a rel="nofollow" class="external text" href="https://parabolagnulinux.org/packages/?name=netctl">netctl</a></span>'s <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">wifi-menu</span> to connect to a network: +</p> +<pre># wifi-menu wlp3s0 +</pre> +<p>You should now have a working network connection. If you do not, check the detailed <a href="https://wiki.parabolagnulinux.org/Wireless_Setup" title="Wireless Setup">Wireless Setup</a> page. +</p><p>Alternatively, use <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">iw dev wlp3s0 scan | grep SSID</span> to scan for available networks, then connect to a network with: +</p> +<pre># wpa_supplicant -B -i wlp3s0 -c <(wpa_passphrase "<i>ssid</i>" "<i>psk</i>") +</pre> +<p>You need to replace <i>ssid</i> with the name of your network (e.g. "Linksys etc...") and <i>psk</i> with your wireless password, <b>leaving the quotes around the network name and password.</b> +</p><p>Finally, you have to give your interface an IP address. This can be set manually or using the dhcp: +</p> +<pre># dhcpcd wlp3s0 +</pre> +<p>If that does not work, issue the following commands: +</p> +<pre># echo 'ctrl_interface=DIR=/run/wpa_supplicant' > /etc/wpa_supplicant.conf +# wpa_passphrase <ssid> <passphrase> >> /etc/wpa_supplicant.conf +# ip link set <interface> up # May not be needed as dhcpcd should bring it up but may be needed for wpa_supplicant. +# wpa_supplicant -B -D nl80211 -c /foobar.conf -i <interface name> +# dhcpcd -A <interface name> +</pre> +<h4> <span class="mw-headline" id="Analog_modem.2C_ISDN_or_PPPoE_DSL"> Analog modem, ISDN or PPPoE DSL </span></h4> +<p>For xDSL, dial-up and ISDN connections, see <a href="https://wiki.parabolagnulinux.org/Direct_Modem_Connection" title="Direct Modem Connection" class="mw-redirect">Direct Modem Connection</a>. +</p> +<h4> <span class="mw-headline" id="Behind_a_proxy_server"> Behind a proxy server </span></h4> +<p>If you are behind a proxy server, you will need to export the <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">http_proxy</span> and <span style="display:inline-block; background-color:#ebf1f5; padding: 0.1em 0.2em; font-family:monospace; color:#222;">ftp_proxy</span> environment variables. See <a href="https://wiki.parabolagnulinux.org/Proxy_settings" title="Proxy settings" class="mw-redirect">Proxy settings</a> for more information. +</p> +<br> +<p>This page was retrieved from: <a href="https://wiki.parabolagnulinux.org/index.php?title=Start_installing&oldid=5138">https://wiki.parabolagnulinux.org/index.php?title=Start_installing&oldid=5138</a> +</p> +<p>Content is available under <a class="external" href="http://www.gnu.org/copyleft/fdl.html">GNU Free Documentation License 1.3 (or at your option, any later version)</a>. +</p> +<!-- +NewPP limit report +Preprocessor visited node count: 462/1000000 +Preprocessor generated node count: 1260/1000000 +Post‐expand include size: 13122/2097152 bytes +Template argument size: 5931/2097152 bytes +Highest expansion depth: 7/40 +Expensive parser function count: 0/100 +--> + +<!-- Saved in parser cache with key wiki_parabolagnulinux_org:pcache:idhash:1857-1!*!0!!en!*!* and timestamp 20130806172112 --> diff --git a/configs/releng/syslinux/parabolaiso.cfg b/configs/releng/syslinux/parabolaiso.cfg new file mode 100644 index 0000000..473e245 --- /dev/null +++ b/configs/releng/syslinux/parabolaiso.cfg @@ -0,0 +1,11 @@ +DEFAULT select + +LABEL select +COM32 boot/syslinux/whichsys.c32 +APPEND -pxe- pxe -sys- sys -iso- sys + +LABEL pxe +CONFIG boot/syslinux/parabolaiso_pxe_choose.cfg + +LABEL sys +CONFIG boot/syslinux/parabolaiso_sys_choose.cfg diff --git a/configs/releng/syslinux/parabolaiso_head.cfg b/configs/releng/syslinux/parabolaiso_head.cfg new file mode 100644 index 0000000..a245309 --- /dev/null +++ b/configs/releng/syslinux/parabolaiso_head.cfg @@ -0,0 +1,25 @@ +SERIAL 0 38400 +UI boot/syslinux/vesamenu.c32 +MENU TITLE Parabola GNU/Linux-libre +MENU BACKGROUND boot/syslinux/splash.png + +MENU WIDTH 78 +MENU MARGIN 4 +MENU ROWS 7 +MENU VSHIFT 10 +MENU TABMSGROW 14 +MENU CMDLINEROW 14 +MENU HELPMSGROW 16 +MENU HELPMSGENDROW 29 + +# Refer to http://syslinux.zytor.com/wiki/index.php/Doc/menu + +MENU COLOR border 35;40 #ff777caa #a0000000 std +MENU COLOR title 1;35;40 #ff777caa #a0000000 std +MENU COLOR sel 7;35;47 #e0ffffff #20777caa all +MENU COLOR unsel 35;40 #ff777caa #a0000000 std +MENU COLOR help 35;40 #c0b2b2b2 #a0000000 std +MENU COLOR timeout_msg 35;40 #ff777caa #00000000 std +MENU COLOR timeout 1;35;40 #ff777caa #00000000 std +MENU COLOR msg07 35;40 #ff777caa #a0000000 std +MENU COLOR tabmsg 35;40 #ff777caa #00000000 std diff --git a/configs/releng/syslinux/parabolaiso_pxe32.cfg b/configs/releng/syslinux/parabolaiso_pxe32.cfg new file mode 100644 index 0000000..60bc713 --- /dev/null +++ b/configs/releng/syslinux/parabolaiso_pxe32.cfg @@ -0,0 +1,32 @@ +LABEL parabola32_nbd +TEXT HELP +Boot the Parabola GNU/Linux-libre (i686) live medium (Using NBD). +It allows you to install Parabola GNU/Linux-libre or perform system maintenance. +ENDTEXT +MENU LABEL Boot Parabola GNU/Linux-libre (i686) (NBD) +LINUX boot/i686/vmlinuz +INITRD boot/i686/parabolaiso.img +APPEND parabolaisobasedir=%INSTALL_DIR% parabolaisolabel=%PARABOLAISO_LABEL% parabolaiso_nbd_srv=${pxeserver} +IPAPPEND 3 + +LABEL parabola32_nfs +TEXT HELP +Boot the Parabola GNU/Linux-libre (i686) live medium (Using NFS). +It allows you to install Parabola GNU/Linux-libre or perform system maintenance. +ENDTEXT +MENU LABEL Boot Parabola GNU/Linux-libre (i686) (NFS) +LINUX boot/i686/vmlinuz +INITRD boot/i686/parabolaiso.img +APPEND parabolaisobasedir=%INSTALL_DIR% parabolaiso_nfs_srv=${pxeserver}:/run/parabolaiso/bootmnt +IPAPPEND 3 + +LABEL parabola32_http +TEXT HELP +Boot the Parabola GNU/Linux-libre (i686) live medium (Using HTTP). +It allows you to install Parabola GNU/Linux-libre or perform system maintenance. +ENDTEXT +MENU LABEL Boot Parabola GNU/Linux-libre (i686) (HTTP) +LINUX boot/i686/vmlinuz +INITRD boot/i686/parabolaiso.img +APPEND parabolaisobasedir=%INSTALL_DIR% parabolaiso_http_srv=http://${pxeserver}/ +IPAPPEND 3 diff --git a/configs/releng/syslinux/parabolaiso_pxe64.cfg b/configs/releng/syslinux/parabolaiso_pxe64.cfg new file mode 100644 index 0000000..34bf7d7 --- /dev/null +++ b/configs/releng/syslinux/parabolaiso_pxe64.cfg @@ -0,0 +1,32 @@ +LABEL parabola64_nbd +TEXT HELP +Boot the Parabola GNU/Linux-libre (x86_64) live medium (Using NBD). +It allows you to install Parabola GNU/Linux-libre or perform system maintenance. +ENDTEXT +MENU LABEL Boot Parabola GNU/Linux-libre (x86_64) (NBD) +LINUX boot/x86_64/vmlinuz +INITRD boot/x86_64/parabolaiso.img +APPEND parabolaisobasedir=%INSTALL_DIR% parabolaisolabel=%PARABOLAISO_LABEL% parabolaiso_nbd_srv=${pxeserver} +IPAPPEND 3 + +LABEL parabola64_nfs +TEXT HELP +Boot the Parabola GNU/Linux-libre (x86_64) live medium (Using NFS). +It allows you to install Parabola GNU/Linux-libre or perform system maintenance. +ENDTEXT +MENU LABEL Boot Parabola GNU/Linux-libre (x86_64) (NFS) +LINUX boot/x86_64/vmlinuz +INITRD boot/x86_64/parabolaiso.img +APPEND parabolaisobasedir=%INSTALL_DIR% parabolaiso_nfs_srv=${pxeserver}:/run/parabolaiso/bootmnt +IPAPPEND 3 + +LABEL parabola64_http +TEXT HELP +Boot the Parabola GNU/Linux-libre (x86_64) live medium (Using HTTP). +It allows you to install Parabola GNU/Linux-libre or perform system maintenance. +ENDTEXT +MENU LABEL Boot Parabola GNU/Linux-libre (x86_64) (HTTP) +LINUX boot/x86_64/vmlinuz +INITRD boot/x86_64/parabolaiso.img +APPEND parabolaisobasedir=%INSTALL_DIR% parabolaiso_http_srv=http://${pxeserver}/ +IPAPPEND 3 diff --git a/configs/releng/syslinux/parabolaiso_pxe_32_inc.cfg b/configs/releng/syslinux/parabolaiso_pxe_32_inc.cfg new file mode 100644 index 0000000..ba514cb --- /dev/null +++ b/configs/releng/syslinux/parabolaiso_pxe_32_inc.cfg @@ -0,0 +1,3 @@ +INCLUDE boot/syslinux/parabolaiso_head.cfg +INCLUDE boot/syslinux/parabolaiso_pxe32.cfg +INCLUDE boot/syslinux/parabolaiso_tail.cfg diff --git a/configs/releng/syslinux/parabolaiso_pxe_both_inc.cfg b/configs/releng/syslinux/parabolaiso_pxe_both_inc.cfg new file mode 100644 index 0000000..9396d9b --- /dev/null +++ b/configs/releng/syslinux/parabolaiso_pxe_both_inc.cfg @@ -0,0 +1,4 @@ +INCLUDE boot/syslinux/parabolaiso_head.cfg +INCLUDE boot/syslinux/parabolaiso_pxe64.cfg +INCLUDE boot/syslinux/parabolaiso_pxe32.cfg +INCLUDE boot/syslinux/parabolaiso_tail.cfg diff --git a/configs/releng/syslinux/parabolaiso_pxe_choose.cfg b/configs/releng/syslinux/parabolaiso_pxe_choose.cfg new file mode 100644 index 0000000..a3a768f --- /dev/null +++ b/configs/releng/syslinux/parabolaiso_pxe_choose.cfg @@ -0,0 +1,11 @@ +DEFAULT choose + +LABEL choose +COM32 boot/syslinux/ifcpu64.c32 +APPEND have64 -- nohave64 + +LABEL have64 +CONFIG boot/syslinux/parabolaiso_pxe_both_inc.cfg + +LABEL nohave64 +CONFIG boot/syslinux/parabolaiso_pxe_32_inc.cfg diff --git a/configs/releng/syslinux/parabolaiso_sys32.cfg b/configs/releng/syslinux/parabolaiso_sys32.cfg new file mode 100644 index 0000000..4abdf7a --- /dev/null +++ b/configs/releng/syslinux/parabolaiso_sys32.cfg @@ -0,0 +1,9 @@ +LABEL parabola32 +TEXT HELP +Boot the Parabola GNU/Linux-libre (i686) live medium. +It allows you to install Parabola GNU/Linux-libre or perform system maintenance. +ENDTEXT +MENU LABEL Boot Parabola GNU/Linux-libre (i686) +LINUX boot/i686/vmlinuz +INITRD boot/i686/parabolaiso.img +APPEND parabolaisobasedir=%INSTALL_DIR% parabolaisolabel=%PARABOLAISO_LABEL% diff --git a/configs/releng/syslinux/parabolaiso_sys64.cfg b/configs/releng/syslinux/parabolaiso_sys64.cfg new file mode 100644 index 0000000..b154459 --- /dev/null +++ b/configs/releng/syslinux/parabolaiso_sys64.cfg @@ -0,0 +1,9 @@ +LABEL parabola64 +TEXT HELP +Boot the Parabola GNU/Linux-libre (x86_64) live medium. +It allows you to install Parabola GNU/Linux-libre or perform system maintenance. +ENDTEXT +MENU LABEL Boot Parabola GNU/Linux-libre (x86_64) +LINUX boot/x86_64/vmlinuz +INITRD boot/x86_64/parabolaiso.img +APPEND parabolaisobasedir=%INSTALL_DIR% parabolaisolabel=%PARABOLAISO_LABEL% diff --git a/configs/releng/syslinux/parabolaiso_sys_32_inc.cfg b/configs/releng/syslinux/parabolaiso_sys_32_inc.cfg new file mode 100644 index 0000000..c641201 --- /dev/null +++ b/configs/releng/syslinux/parabolaiso_sys_32_inc.cfg @@ -0,0 +1,3 @@ +INCLUDE boot/syslinux/parabolaiso_head.cfg +INCLUDE boot/syslinux/parabolaiso_sys32.cfg +INCLUDE boot/syslinux/parabolaiso_tail.cfg diff --git a/configs/releng/syslinux/parabolaiso_sys_both_inc.cfg b/configs/releng/syslinux/parabolaiso_sys_both_inc.cfg new file mode 100644 index 0000000..9dfb87f --- /dev/null +++ b/configs/releng/syslinux/parabolaiso_sys_both_inc.cfg @@ -0,0 +1,4 @@ +INCLUDE boot/syslinux/parabolaiso_head.cfg +INCLUDE boot/syslinux/parabolaiso_sys64.cfg +INCLUDE boot/syslinux/parabolaiso_sys32.cfg +INCLUDE boot/syslinux/parabolaiso_tail.cfg diff --git a/configs/releng/syslinux/parabolaiso_sys_choose.cfg b/configs/releng/syslinux/parabolaiso_sys_choose.cfg new file mode 100644 index 0000000..d436062 --- /dev/null +++ b/configs/releng/syslinux/parabolaiso_sys_choose.cfg @@ -0,0 +1,11 @@ +DEFAULT choose + +LABEL choose +COM32 boot/syslinux/ifcpu64.c32 +APPEND have64 -- nohave64 + +LABEL have64 +CONFIG boot/syslinux/parabolaiso_sys_both_inc.cfg + +LABEL nohave64 +CONFIG boot/syslinux/parabolaiso_sys_32_inc.cfg diff --git a/configs/releng/syslinux/parabolaiso_tail.cfg b/configs/releng/syslinux/parabolaiso_tail.cfg new file mode 100644 index 0000000..5d95b3b --- /dev/null +++ b/configs/releng/syslinux/parabolaiso_tail.cfg @@ -0,0 +1,27 @@ +LABEL existing +TEXT HELP +Boot an existing operating system. +Press TAB to edit the disk and partition number to boot. +ENDTEXT +MENU LABEL Boot existing OS +COM32 boot/syslinux/chain.c32 +APPEND hd0 0 + +# http://www.memtest.org/ +LABEL memtest +MENU LABEL Run Memtest86+ (RAM test) +LINUX boot/memtest + +# http://hdt-project.org/ +LABEL hdt +MENU LABEL Hardware Information (HDT) +COM32 boot/syslinux/hdt.c32 +APPEND modules_alias=boot/syslinux/hdt/modalias.gz pciids=boot/syslinux/hdt/pciids.gz + +LABEL reboot +MENU LABEL Reboot +COM32 boot/syslinux/reboot.c32 + +LABEL poweroff +MENU LABEL Power Off +COMBOOT boot/syslinux/poweroff.com diff --git a/configs/releng/syslinux/syslinux.cfg b/configs/releng/syslinux/syslinux.cfg new file mode 100644 index 0000000..0869ed2 --- /dev/null +++ b/configs/releng/syslinux/syslinux.cfg @@ -0,0 +1,5 @@ +DEFAULT loadconfig + +LABEL loadconfig + CONFIG parabolaiso.cfg + APPEND ../../ diff --git a/docs/README.altbootmethods b/docs/README.altbootmethods new file mode 100644 index 0000000..d9acc89 --- /dev/null +++ b/docs/README.altbootmethods @@ -0,0 +1,125 @@ +INDEX +----- + +* Alternative boot methods (configs/releng) + * ISO in loopback mode + * ISO in memdisk mode + * Network booting (PXE) [first stage] + * DHCP + TFTP + * DHCP + HTTP + * HTTP/NFS/NBD [second stage] + + + +*** Alternative boot methods (configs/releng) + +ISO images names consist of: parabola-<YYYY>.<MM>.<DD>-dual.iso + +Where: + <YYYY> Year + <MM> Month + <DD> Day + + +** ISO in loopback mode. + +Note: Described method is for using with GRUB2. + GRUB2 is installed on target media and parabola-<YYYY>.<MM>.<DD>-dual.iso + is at path <TARGET-PATH> on disk <D> and partition <P>, + where filesystem is labeled as <TARGET-FS-LABEL>. + +menuentry "Parabola GNU/Linux-libre (x86_64)" { + set isofile="/<TARGET-PATH>/parabola-<YYYY>.<MM>.<DD>-dual.iso" + loopback loop (hd<D>,<P>)$isofile + linux (loop)/parabola/boot/x86_64/vmlinuz parabolaisolabel=<FS-LABEL> img_label=<TARGET-FS-LABEL> img_loop=$isofile + initrd (loop)/parabola/boot/x86_64/parabolaiso.img +} + +menuentry "Parabola GNU/Linux-libre (i686)" { + set isofile="/<TARGET-PATH>/parabola-<YYYY>.<MM>.<DD>-dual.iso" + loopback loop (hd<D>,<P>)$isofile + linux (loop)/parabola/boot/i686/vmlinuz parabolaisolabel=<FS-LABEL> img_label=<TARGET-FS-LABEL> img_loop=$isofile + initrd (loop)/parabola/boot/i686/parabolaiso.img +} + + +** ISO in memdisk mode. + +Note: Described method is for using with SYSLINUX. Anyway MEMDISK from SYSLINUX can work + with other bootloaders. + SYSLINUX is installed on target media and parabola-<YYYY>.<MM>.<DD>-dual.iso + is at path <TARGET-PATH>. + On 32-bit systems, is needed to pass vmalloc=nnM to the kernel, where nn is the size + of the ISO image plus 64 MiB (or 128 MiB). + + +LABEL parabola_x64 + LINUX memdisk + INITRD /<TARGET-PATH>/parabola-<YYYY>.<MM>.<DD>-dual.iso + APPEND iso + +LABEL parabola_x32 + LINUX memdisk + INITRD /<TARGET-PATH>/parabola-<YYYY>.<MM>.<DD>-dual.iso + APPEND iso + + +** Network booting (PXE). + +All ISOs are ready to act as PXE server, some manual steps are needed +to setup the desired PXE boot mode. +Alternatively it is possible to use an existing PXE server following the same logic. +Note: Setup network first, adjust IP adresses, and respect all slashes "/". + +First stage is for loading kernel and initramfs via PXE, two methods described here: + +* DHCP + TFTP + +Note: All NIC firmwares should support this. + +# dnsmasq --port=0 \ + --enable-tftp \ + --tftp-root=/run/parabolaiso/bootmnt \ + --dhcp-range=192.168.0.2,192.168.0.254,86400 \ + --dhcp-boot=/parabola/boot/syslinux/gpxelinux.0 \ + --dhcp-option-force=209,boot/syslinux/parabolaiso.cfg \ + --dhcp-option-force=210,/parabola/ + +* DHCP + HTTP + +Note: Not all NIC firmware supports HTTP and DNS (if domain name is used). + At least this works with iPXE and gPXE. + +# dnsmasq --port=0 \ + --dhcp-range=192.168.0.2,192.168.0.254,86400 \ + --dhcp-boot=http://192.168.0.7/parabola/boot/syslinux/gpxelinux.0 \ + --dhcp-option-force=209,boot/syslinux/parabolaiso.cfg \ + --dhcp-option-force=210,http://192.168.0.7/parabola/ + + +Once the kernel is started from PXE, SquashFS files and other misc files +inside "parabola" directory must be loaded (second stage). One of the following +methods can be used to serve the rest of live-medium. + +* HTTP + +# darkhttpd /run/parabolaiso/bootmnt + + +* NFS + +# echo "/run/parabolaiso/bootmnt 192.168.0.*(ro,no_subtree_check,no_root_squash)" >> /etc/exports +# systemctl start rpc-mountd.service + + +* NBD + +Note: Adjust PARA_201302 as needed. + +# cat << EOF > /tmp/nbd-server.conf +[generic] +[parabolaiso] + readonly = true + exportname = /dev/disk/by-label/PARA_201302 +EOF +# nbd-server -C /tmp/nbd-server.conf diff --git a/docs/README.bootparams b/docs/README.bootparams new file mode 100644 index 0000000..7139976 --- /dev/null +++ b/docs/README.bootparams @@ -0,0 +1,141 @@ +INDEX +----- + +* Boot parameters (initramfs stage) + * hooks/parabolaiso + * hooks/parabolaiso_pxe_common + * hooks/parabolaiso_pxe_nbd + * hooks/parabolaiso_pxe_http + * hooks/parabolaiso_pxe_nfs + * hooks/parabolaiso_loop_mnt + +* Boot parameters (configs/releng) + * scripts/choose-mirror + + +*** Boot parameters (initramfs stage) + +** hooks/parabolaiso + +* parabolaisolabel= Set the filesystem label where parabolaiso files reside. + Default: (unset) +* parabolaisodevice= Set the device node where parabolaiso medium is located. + Default: "/dev/disk/by-label/${parabolaisolabel}" +* parabolaisobasedir= Set the base directory where all files reside. + Default: "parabola" +* aitab= Set the path for "aitab" file. + Default: ${parabolaisobasedir}/aitab +* copytoram= If set to "y" or just "copytoram" without arguments, + all SquashFS are copied to "RAM". + Default: (unset) +* checksum= If set to "y" or just "checksum" without arguments, + performs a self-test of all files inside ${install_dir}, + and continue booting if ok. + Default: (unset) +* cow_label= Set the filesystem label where COW (dm-snapshot) + files must be stored. + Default: (unset) +* cow_device= Set the device node where COW (dm-snapshot) files + must be stored. + Default: (unset) or "/dev/disk/by-label/${cow_label}" +* cow_directory= Set a directory inside ${cow_device}. + Default: "/persistent_${parabolaisolabel}/${arch}" +* cow_persistent= Set if snapshots are persistent "P" or non-persistent "N". + Default: "N" (if no ${cow_device} is used) otherwise "P". +* cowspace_size= Set the size of tmpfs /cowspace. This space is used for + Copy-On-Write files of dm-snapshot. + Size is in bytes (suffix with "k", "m" and "g") or + in percentage of available RAM. + Default: "75%" +* cowfile_size= Set the size for all files to be used as COW (dm-snapshot), + in percentage of the ro-device.fs file. This is mostly useful + when cow_device= is used and filesystem does not support + sparse files (ie VFAT). + Default: "100%" +* copytoram_size= Set the size of tmpfs. This space is used for + copy of all SquashFS images used, if copytoram=y. + Size is in bytes (suffix with "k", "m" and "g") or + in percentage of available RAM. + Default: "75%" +* dm_snap_prefix= Set a prefix for device-mapper snapshot node names. + Default: "parabola" +* arch= Force an architecture type (i686 | x86_64). + Do not set it for normal operations. + Useful for running a 64 bit kernel / 32 bit userspace. + Default: (architecture of running kernel) + + +** hooks/parabolaiso_pxe_common + +* ip= This parameter is setup automatically by PXELINUX + when option "IPAPPEND" is set to 1 or 2 in config. + ip=<client-ip>:<boot-server-ip>:<gw-ip>:<netmask> + Default: (set via PXE server) +* BOOTIF= This parameter is setup automatically by PXELINUX + when option "IPAPPEND" is set to 2 or 3 in config. + BOOTIF=<hardware-address-of-boot-interface> + Default: (set via PXELINUX) +* copy_resolvconf= Copy /etc/resolv.conf from initramfs to live-enviroment. + Set to "n" to skip them. + Default: "y" + + +** hooks/parabolaiso_pxe_nbd + +* parabolaiso_nbd_name= Set NBD export name used by the server. + Default: parabolaiso +* parabolaiso_nbd_srv= Set an IP address where NBD reside. + If ${pxeserver} is used, PXE IP will be used. + Default: (unset) + + +** hooks/parabolaiso_pxe_http + +* parabolaiso_http_srv= Set an HTTP URL (must end with /) where ${parabolaisobasedir} + is found with all *.sfs files. + In the IP/domain part if ${pxeserver} is used, use PXE IP. + Default: (unset) +* parabolaiso_http_spc= Set the size of tmpfs where *.sfs files are downloaded. + Default: "75%" + + +** hooks/parabolaiso_pxe_nfs + +* parabolaiso_nfs_srv= Set the NFS-IP:/path of the server + In the IP part if ${pxeserver} is used, PXE IP will be used. + Default: (unset) +* parabolaiso_nfs_opt= Set NFS mount options separated by comma. + Default: (unset, see below) + These are the implicit options: + port = as given by server portmap daemon + rsize = 1024 + wsize = 1024 + timeo = 7 + retrans = 3 + acregmin = 3 + acregmax = 60 + acdirmin = 30 + acdirmax = 60 + flags = hard, nointr, noposix, cto, ac + + +** hooks/parabolaiso_loop_mnt + +* img_label= Set the filesystem label where parabolaiso-image.iso. + Default: (unset) +* img_dev= Device where parabolaiso-image.iso reside. + Default: (unset) or "/dev/disk/by-label/${img_label}" +* img_loop= Full path where parabolaiso-image.iso is located on ${img_dev} + Default: (unset) + + + +*** Boot parameters (configs/releng) + +** scripts/choose-mirror + +* mirror= Takes a mirror URL and creates a new mirrorlist. + When setting mirror=auto, the mirror is taken from + archiso_http_srv= in order to keep using the mirror + selected in the netboot menu. + Default: (unset) diff --git a/docs/README.build b/docs/README.build new file mode 100644 index 0000000..f2fb594 --- /dev/null +++ b/docs/README.build @@ -0,0 +1,111 @@ +INDEX +----- + +* Build requirements +* Image types generated by mkparabolaiso. +* File format for aitab. +* Why the /isolinux and /parabola/boot/syslinux directories? +* Building the most basic Parabola GNU/Linux-libre live media. (configs/baseline) +* Building official Parabola GNU/Linux-libre live media. (configs/releng) + + + +*** Build requirements + +** For mkparabolaiso script needs these packages (build host): + + squashfs-tools for mksquashfs + + libisoburn for xorriso + + btrfs-progs for mkfs.btrfs (optional) + +** For configs/releng build.sh needs theses packages (build host): + + dosfstools for mkfs.vfat + + lynx for fetching the latest installation guide + +** For these hooks needs these packages (on target root-image) +* parabolaiso + + (none) +* parabolaiso_loop_mnt + + (none) +* parabolaiso_pxe_common + + mkinitcpio-nfs-utils for ipconfig +* parabolaiso_pxe_nbd + + nbd for nbd-client +* parabolaiso_pxe_http + + curl for curl +* parabolaiso_pxe_nfs + + mkinitcpio-nfs-utils for nfsmount +* parabolaiso_shutdown + + (none) + + +*** Image types generated by mkparabolaiso. + +* image-name.sfs SquashFS image with all files directly on it. + [read-only, no dm-snapshot is used] +* image-name.fs.sfs SquashFS with only one file inside (image-name.fs), + which is an image of some type of filesystem + (ext4, ext3, ext2, xfs, btrfs), all files reside on it. + [read-write, via COW image with dm-snapshot] + + +*** File format for aitab. + +The aitab file holds information about the filesystems images that must be +created by mkparabolaiso and mounted at initramfs stage from the parabolaiso hook. +It consists of some fields which define the behaviour of images. + +# <img> <mnt> <arch> <sfs_comp> <fs_type> <fs_size> + +<img> Image name without extension (.fs .fs.sfs .sfs). +<mnt> Mount point. +<arch> Architecture { i686 | x86_64 | any }. +<sfs_comp> SquashFS compression type { gzip | lzo | xz }. +<fs_type> Set the filesystem type of the image + { ext4 | ext3 | ext2 | xfs | btrfs }. + A special value of "none" denotes no usage of a filesystem. + In that case all files are pushed directly to SquashFS filesystem. +<fs_size> An absolute value of file system image size in MiB. + (example: 100, 1000, 4096, etc) + A relative value of file system free space [in percent]. + {1%..99%} (example 50%, 10%, 7%). + This is an estimation, and calculated in a simple way. + Space used + 10% (estimated for metadata overhead) + desired % + + +*** Why the /isolinux and /parabola/boot/syslinux directories? + +The /isolinux directory holds files needed for the ISOLINUX boot loader +module of SYSLINUX. ISOLINUX can not find config files on +/parabola/boot/syslinux, like other boot loaders modules (SYSLINUX, PXELINUX). + + + +*** Building the most basic Parabola GNU/Linux-libre live media. (configs/baseline) + +* Install needed packages. + # pacman -S git make squashfs-tools libisoburn rsync --needed + +* Install parabolaiso. + # git clone git://projects.parabolagnulinux.org/parabolaiso.git + # make -C parabolaiso install + +* Build a basic iso. + # /usr/share/parabolaiso/configs/baseline/build.sh + +Note: If you want to customize, just see the configs/releng directory which is +used to build official images with much more things. + + +*** Building official Parabola GNU/Linux-libre live media. (configs/releng) + +* Install needed packages. + # pacman -S git make squashfs-tools libisoburn dosfstools lynx --needed + +* Install parabolaiso. + # git clone git://projects.parabolagnulinux.org/parabolaiso.git + # make -C parabolaiso install + +* Build them! + # /usr/share/parabolaiso/configs/releng/build.sh + +Note: See build.sh -h for more options. This only runs on x86_64. diff --git a/docs/README.knownissues b/docs/README.knownissues new file mode 100644 index 0000000..7002c5e --- /dev/null +++ b/docs/README.knownissues @@ -0,0 +1,12 @@ +*** Know issues + +** (1) On shutdown lots of messages from systemd like: + + "Could not unmount /run/parabolaiso/<ABC>: Device or resource busy" + "Could not delete loopback /dev/loop<N>: Device or resource busy" + This is not a real issue since, all mounted filesystem, loopback devices + and device mapper devices made by parabolaiso will be "free" on "shutdown tmpfs" + (A.K.A deinitramfs), build at initramfs by [parabolaiso_shutdown] initcpio hook. + Proper shutdown is mostly important when persistent is used. + + diff --git a/docs/README.transfer b/docs/README.transfer new file mode 100644 index 0000000..f6879e0 --- /dev/null +++ b/docs/README.transfer @@ -0,0 +1,133 @@ +INDEX +----- + +* Transfer ISO file to target medium (configs/releng) + * To -> CD / DVD / BD + * To -> USB-key / SD / HDD / SSD + * PC-BIOS (MBR) + * PC-BIOS (ISOHYBRID-MBR) + * PC-EFI (GPT) [x86_64 only] + * PC-EFI (ISOHYBRID-GPT) [x86_64 only] + + + +*** Transfer ISO image to target medium (configs/releng) + +ISO images names consist of: parabola-<YYYY>.<MM>.<DD>-dual.iso + +Where: + <YYYY> Year + <MM> Month + <DD> Day + + +** To -> CD / DVD / BD + +Note: All ISO images are booteable on a PC-BIOS via "El Torito" in no-emulation mode, + All x86_64 ISO images are booteable on a PC-EFI via "El Torito" in no-emulation mode. + +Nomeclature: + <B> scsibus number + <T> target number + <L> lun number + (Note: see cdrecord -scanbus, for these numbers) + + +1) Write it directly using your favorite recording program. +# cdrecord dev=<B>,<T>,<L> -dao parabola-<YYYY>.<MM>.<DD>-dual.iso + + +** To -> USB Flash Drive (USB-key) / Memory card (SD) / + Hard-Disk Drive (HDD) / Solid-State Drive (SSD) + +Note: These steps are the general workflow, you can skip some of them, + using another filesystem if your bootloader supports it, + installing to another directory than "parabola/" or using more than + one partition. Just ensure that main boot params options + (parabolaisolabel= and parabolaisobasedir=) are set correctly according to your setup. + +Nomeclature: +<DEV-TARGET>: Device node of the drive where ISO contents should be copied + (example: /dev/sdx) +<DEV-TARGET-N>: Device node of the partition on <DEV-TARGET> + (example: /dev/sdx1) +<MNT-TARGET-N>: Mount point path where <DEV-TARGET-N> is mounted + (example: /mnt/sdx/1) +<ISO-SOURCE>: Path to the ISO file parabola-<YYYY>.<MM>.<DD>-dual.iso + (example: ~/parabola-2012.07.22-dual.iso) +<FS-LABEL>: Represents the filesystem label of the <ISO-SOURCE> + (example: PARA_201302) + + +* PC-BIOS (MBR): + +Note: Using here a MBR partition mode as example, but GPT should also works + if machine firmware is not broken. + Just ensure that partition is set with attribute "2: legacy BIOS bootable" + and use gptmbr.bin instead of mbr.bin for syslinux. + +1) Create one partition entry in MBR and mark it as "active" (booteable). +Note: Type "b" for FAT32, "83" for EXTFS or "7" for NTFS. +# fdisk <DEV-TARGET> + +2) Create a FAT32, EXTFS or NTFS filesystem on such partition and setup a label. +Note: COW is not supported on NTFS. +# mkfs.vfat -F 32 -n <FS-LABEL> <DEV-TARGET-N> +# mkfs.ext4 -L <FS-LABEL> <DEV-TARGET-N> +# mkfs.ntfs -L <FS-LABEL> <DEV-TARGET-N> + +3) Mount target filesystem. +# mount <DEV-TARGET-N> <MNT-TARGET-N> + +4) Extract ISO image on target filesystem. +# bsdtar -x --exclude=isolinux/ --exclude=EFI/ --exclude=loader/ -f <ISO-SOURCE> -C <MNT-TARGET-N> + +5) Install syslinux bootloader on target filesystem. +# extlinux -i <MNT-TARGET-N>/parabola/boot/syslinux + +6) Unmount target filesystem. +# umount <MNT-TARGET-N> + +7) Install syslinux MBR boot code on target drive. +# dd bs=440 count=1 conv=notrunc if=/usr/lib/syslinux/mbr.bin of=<DEV-TARGET> + + +* PC-BIOS (ISOHYBRID-MBR): + +Note: This method is the most easily, quick and dirty, but is the most limited + if you want to use your target medium for other purposes. + If using this does not work, use PC-BIOS (MBR) method instead. + +1) Dump ISO file to target medium. +# dd if=<ISO-SOURCE> of=<DEV-TARGET> + + +* PC-EFI (GPT) [x86_64 only] + +Note: Using here a GPT partition mode as example, but MBR should also works + if machine firmware is not broken. + +1) Create one partition entry in GPT (of type "ef00") +# gdisk <DEV-TARGET> + +2) Create a FAT32 filesystem on such partition and setup a label. +# mkfs.vfat -F 32 -n <FS-LABEL> <DEV-TARGET-N> + +3) Mount target filesystem. +# mount <DEV-TARGET-N> <MNT-TARGET-N> + +4) Extract ISO image on target filesystem. +# bsdtar -x --exclude=isolinux/ --exclude=EFI/parabolaiso/ --exclude=parabola/boot/syslinux/ -f <ISO-SOURCE> -C <MNT-TARGET-N> + +5) Unmount target filesystem. +# umount <MNT-TARGET-N> + + +* PC-EFI (ISOHYBRID-GPT) [x86_64 only] + +Note: This method is the most easily, quick and dirty, but is the most limited + if you want to use your target medium for other purposes. + If using this does not work, use PC-EFI (GPT) method instead. + +1) Dump ISO file to target medium. +# dd if=<ISO-SOURCE> of=<DEV-TARGET> @@ -0,0 +1,181 @@ +#!/bin/bash + +set -e + +version="$1" + +type="$2" + +### CONFIGURATION OPTIONS + +# Profiles to package in addition to the profile releng for the make target "dist-branches" +branches_dist_branches=(baseline gnome toolkit) + +# Profiles to package in addition to the profile releng for the make target "dist" +branches_dist=(baseline) + +### END OF CONFIGURATION OPTIONS + +error() { + echo "${@}. Stop." >&2 + exit 1 +} + +dist_branches() { + branches="${branches_dist_branches}" + # Refs to package (the branches) + refs="${branches[@]}" + # Ref of the releng profile to package + releng="master" + # Release branch. This branch only has commits to prepare the package. + release_branch="release-branches" + # Release ref. It is a branch for dist_branches. The package is created from this ref. + release="${release_branch}" + # Refs that should exist for the make target dist-branches. This branches will be packaged. + allrefs=( ${releng} ${branches[@]} ) +} + +dist() { + branches="${branches_dist}" + # Refs to package (branch names appending the date, like "baseline/2013.08.12") + refs="${branches_dist[@]/%//${version}}" + # Ref of the releng profile to package + releng="master/${version}" + # Release branch. This branch only has commits to prepare the package. + release_branch="release" + # Release ref. Tag of commit in release_branch. The package is created from this ref. + release="release/${version}" + # These refs should exist to package for the make target dist. + allrefs=( ${releng} ${refs[@]} ) +} + +expand() { + ref="$1" + dir="$2" + + GIT_INDEX_FILE="${index}" git read-tree --empty + GIT_INDEX_FILE="${index}".release git read-tree --empty + + # Find the current head of ${ref} + head="$(git show-ref --hash "refs/${ref_type}/${ref}")" + # Find the current head of the release branch. + head_release="$(git show-ref --hash refs/heads/"${release_branch}")" + if [[ $dir == releng ]] ; then + # Read the tree of "$ref" with profile path rename into an index file. + git ls-tree -z -r "${head}" | sed -z "s|configs/profile|configs/${dir}|" | GIT_INDEX_FILE="${index}" git update-index -z --index-info + # Remove the master branch from the release index, that is, leave everything from configs/ excluding configs/releng + git ls-tree -z -r "${head_release}" | grep -zZP 'configs/(?!releng)' | GIT_INDEX_FILE="${index}".release git update-index -z --index-info + # This combines the two indexes (obtained in the last two commands). + GIT_INDEX_FILE="${index}".release git ls-files -z -s | GIT_INDEX_FILE="${index}" git update-index -z --add --index-info + else + # Read only paths configs/profile of "$ref" with profile path rename into an index file. + git ls-tree -z -r "${head}" -- configs/profile | sed -z "s|configs/profile|configs/${dir}|" | GIT_INDEX_FILE="${index}" git update-index -z --index-info + # Remove configs/${dir} from the release index. + git ls-tree -z -r "${head_release}" | grep -zZv configs/"${dir}" | GIT_INDEX_FILE="${index}".release git update-index -z --index-info + # This combines the two indexes (obtained in the last two commands). + GIT_INDEX_FILE="${index}".release git ls-files -z -s | GIT_INDEX_FILE="${index}" git update-index -z --add --index-info + fi + # Write the index file into the repo as a tree. + tree="$(GIT_INDEX_FILE="${index}" git write-tree)" + # Write a commit to the repo. + commit="$(echo "Update profile ${dir}" | git commit-tree "$tree" -p "${head_release}")" + # Update the head of the repository to be the new commit. + git update-ref refs/heads/"${release_branch}" "$commit" "${head_release}" +} + +expand_empty() { + ref="${releng}" + dir="releng" + + GIT_INDEX_FILE="${index}" git read-tree --empty + + # Find the current head of ${ref} + head="$(git show-ref --hash "refs/${ref_type}/${ref}")" + # Read the tree of "$ref" with profile path rename into an index file. + git ls-tree -z -r "${head}" | sed -z "s|configs/profile|configs/${dir}|" | GIT_INDEX_FILE="${index}" git update-index -z --index-info + # Write the index file into the repo as a tree. + tree="$(GIT_INDEX_FILE="${index}" git write-tree)" + # Write a commit to the repo. + commit="$(echo "Update profile ${dir}" | git commit-tree "$tree")" + # Update the head of the repository to be the new commit. + git update-ref refs/heads/"${release_branch}" "$commit" 0000000000000000000000000000000000000000 +} + +ref_test() { + es=0 + git show-ref --quiet "$1" || es=$? + + if [[ $es == 1 ]] ; then + error "$2" + elif [[ $es > 1 ]] ; then + error "$3" + fi +} + +ref_test_negative() { + es=0 + git show-ref --quiet "$1" || es=$? + + if [[ $es == 0 ]] ; then + error "$2" + elif [[ $es > 1 ]] ; then + error "$3" + fi +} + +release_prepare() { + ref_test_negative "refs/tags/${release}" "Release tag ${release} can not be created because it already exists" "Error testing the release tag" +} + +show_ref() { + for ref in ${allrefs[@]} ; do + ref_test "refs/${ref_type}/${ref}" "Git reference refs/${ref_type}/${ref} should exist" "Error testing git reference refs/${ref_type}/${ref}" + done +} + +archive_ref() { + git archive --format=tar.gz --prefix=parabolaiso-"${version}"/ "refs/${ref_type}/${release}" > parabolaiso-"${version}".tar.gz +} + +archive() { + git tag -s -m "tag ${release}" "${release}" "${release_branch}" + archive_ref + gpg --detach-sign --use-agent parabolaiso-"${version}".tar.gz +} + +dist_expand() { + index="$(mktemp)" + + es=0 + git show-ref --quiet "refs/heads/${release_branch}" || es=$? + + if [[ $es == 0 ]] ; then + expand "${releng}" releng + elif [[ $es == 1 ]] ; then + expand_empty + echo "Release branch created." + elif [[$es > 1 ]] ; then + error "Error testing the release branch" + fi + + for i in ${!branches[@]} ; do + expand ${refs[$i]} ${branches[$i]} + done +} + +if [[ ${type} == dist ]] ; then + ref_type="tags" + dist + release_prepare + show_ref + dist_expand + archive +elif [[ ${type} == dist-branches ]] ; then + ref_type="heads" + dist_branches + show_ref + dist_expand + archive_ref +else + error "Second argument is not correct" +fi diff --git a/parabolaiso/initcpio/hooks/parabolaiso b/parabolaiso/initcpio/hooks/parabolaiso new file mode 100644 index 0000000..c23fd3d --- /dev/null +++ b/parabolaiso/initcpio/hooks/parabolaiso @@ -0,0 +1,208 @@ +# args: source, newroot, mountpoint +_mnt_fs() { + local img="${1}" + local newroot="${2}" + local mnt="${3}" + local img_fullname="${img##*/}"; + local img_name="${img_fullname%%.*}" + local dm_snap_name="${dm_snap_prefix}_${img_name}" + local ro_dev ro_dev_size rw_dev + + ro_dev=$(losetup --find --show --read-only "${img}") + echo ${ro_dev} >> /run/parabolaiso/used_block_devices + ro_dev_size=$(blockdev --getsz ${ro_dev}) + if [[ "${cowfile_size}" == "100" ]]; then + rw_dev_size=${ro_dev_size} + else + # size calculation done in this way to avoid integer overflow when ro_dev_size is > 10.2G + rw_dev_size=$((ro_dev_size/100*cowfile_size)) + fi + + if [[ "${cow_persistent}" == "P" ]]; then + if [[ -f "/run/parabolaiso/cowspace/${cow_directory}/${img_name}.cow" ]]; then + msg ":: Found '/run/parabolaiso/cowspace/${cow_directory}/${img_name}.cow', using as persistent." + else + msg ":: Creating '/run/parabolaiso/cowspace/${cow_directory}/${img_name}.cow' as persistent." + dd of="/run/parabolaiso/cowspace/${cow_directory}/${img_name}.cow" count=0 seek=${rw_dev_size} &> /dev/null + fi + else + if [[ -f "/run/parabolaiso/cowspace/${cow_directory}/${img_name}.cow" ]]; then + msg ":: Found '/run/parabolaiso/cowspace/${cow_directory}/${img_name}.cow' but non-persistent requested, removing." + rm -f "/run/parabolaiso/cowspace/${cow_directory}/${img_name}.cow" + fi + msg ":: Creating '/run/parabolaiso/cowspace/${cow_directory}/${img_name}.cow' as non-persistent." + dd of="/run/parabolaiso/cowspace/${cow_directory}/${img_name}.cow" count=0 seek=${rw_dev_size} &> /dev/null + fi + + rw_dev=$(losetup --find --show "/run/parabolaiso/cowspace/${cow_directory}/${img_name}.cow") + echo ${rw_dev} >> /run/parabolaiso/used_block_devices + + echo "0 ${ro_dev_size} snapshot ${ro_dev} ${rw_dev} ${cow_persistent} 8" | dmsetup create ${dm_snap_name} + + _mnt_dev "/dev/mapper/${dm_snap_name}" "${newroot}${mnt}" "-w" + echo $(readlink -f /dev/mapper/${dm_snap_name}) >> /run/parabolaiso/used_block_devices +} + +# args: /path/to/image_file, mountpoint +_mnt_sfs() { + local img="${1}" + local mnt="${2}" + local img_fullname="${img##*/}" + local sfs_dev + + if [[ "${copytoram}" == "y" ]]; then + msg -n ":: Copying squashfs image to RAM..." + if ! cp "${img}" "/run/parabolaiso/copytoram/${img_fullname}" ; then + echo "ERROR: while copy '${img}' to '/run/parabolaiso/copytoram/${img_fullname}'" + launch_interactive_shell + fi + img="/run/parabolaiso/copytoram/${img_fullname}" + msg "done." + fi + sfs_dev=$(losetup --find --show --read-only "${img}") + echo ${sfs_dev} >> /run/parabolaiso/used_block_devices + _mnt_dev "${sfs_dev}" "${mnt}" "-r" +} + +# args: device, mountpoint, flags +_mnt_dev() { + local dev="${1}" + local mnt="${2}" + local flg="${3}" + + mkdir -p "${mnt}" + + msg ":: Mounting '${dev}' to '${mnt}'" + + while ! poll_device "${dev}" 30; do + echo "ERROR: '${dev}' device did not show up after 30 seconds..." + echo " Falling back to interactive prompt" + echo " You can try to fix the problem manually, log out when you are finished" + launch_interactive_shell + done + + if mount "${flg}" "${dev}" "${mnt}"; then + msg ":: Device '${dev}' mounted successfully." + else + echo "ERROR; Failed to mount '${dev}'" + echo " Falling back to interactive prompt" + echo " You can try to fix the problem manually, log out when you are finished" + launch_interactive_shell + fi +} + +_verify_checksum() { + local _status + cd "/run/parabolaiso/bootmnt/${parabolaisobasedir}" + md5sum -c checksum.${arch}.md5 > /tmp/checksum.${arch}.log 2>&1 + _status=$? + cd "${OLDPWD}" + return ${_status} +} + +run_hook() { + [[ -z "${arch}" ]] && arch="$(uname -m)" + [[ -z "${cowspace_size}" ]] && cowspace_size="75%" + [[ -z "${copytoram_size}" ]] && copytoram_size="75%" + [[ -z "${parabolaisobasedir}" ]] && parabolaisobasedir="parabola" + [[ -z "${dm_snap_prefix}" ]] && dm_snap_prefix="parabola" + [[ -z "${parabolaisodevice}" ]] && parabolaisodevice="/dev/disk/by-label/${parabolaisolabel}" + if [[ -z "${cowfile_size}" ]]; then + cowfile_size="100" + else + cowfile_size=${cowfile_size/%} + fi + + if [[ -z "${aitab}" ]]; then + aitab="/run/parabolaiso/bootmnt/${parabolaisobasedir}/aitab" + else + aitab="/run/parabolaiso/bootmnt/${parabolaisobasedir}/${aitab}" + fi + + if [[ -n "${cow_label}" ]]; then + cow_device="/dev/disk/by-label/${cow_label}" + [[ -z "${cow_persistent}" ]] && cow_persistent="P" + elif [[ -n "${cow_device}" ]]; then + [[ -z "${cow_persistent}" ]] && cow_persistent="P" + else + cow_persistent="N" + fi + + [[ -z "${cow_directory}" ]] && cow_directory="persistent_${parabolaisolabel}/${arch}" + + # set mount handler for parabolaiso + mount_handler="parabolaiso_mount_handler" +} + +# This function is called normally from init script, but it can be called +# as chain from other mount handlers. +# args: /path/to/newroot +parabolaiso_mount_handler() { + local newroot="${1}" + + if ! mountpoint -q "/run/parabolaiso/bootmnt"; then + _mnt_dev "${parabolaisodevice}" "/run/parabolaiso/bootmnt" "-r" + if [[ "${copytoram}" != "y" ]]; then + echo $(readlink -f ${parabolaisodevice}) >> /run/parabolaiso/used_block_devices + fi + fi + + + if [[ ! -f "${aitab}" ]]; then + echo "ERROR: '${aitab}' file does not exist." + echo " Falling back to interactive prompt" + echo " You can try to fix the problem manually, log out when you are finished" + launch_interactive_shell + fi + + if [[ "${checksum}" == "y" ]]; then + if [[ -f "/run/parabolaiso/bootmnt/${parabolaisobasedir}/checksum.${arch}.md5" ]]; then + msg -n ":: Self-test requested, please wait..." + if _verify_checksum; then + msg "done. Checksum is OK, continue booting." + else + echo "ERROR: one or more files are corrupted" + echo "see /tmp/checksum.${arch}.log for details" + launch_interactive_shell + fi + else + echo "ERROR: checksum=y option specified but checksum.${arch}.md5 not found" + launch_interactive_shell + fi + fi + + if [[ "${copytoram}" == "y" ]]; then + msg ":: Mounting /run/parabolaiso/copytoram (tmpfs) filesystem, size=${copytoram_size}" + mkdir -p /run/parabolaiso/copytoram + mount -t tmpfs -o "size=${copytoram_size}",mode=0755 copytoram /run/parabolaiso/copytoram + fi + + if [[ -n "${cow_device}" ]]; then + _mnt_dev "${cow_device}" "/run/parabolaiso/cowspace" "-r" + echo $(readlink -f ${cow_device}) >> /run/parabolaiso/used_block_devices + mount -o remount,rw "/run/parabolaiso/cowspace" + else + msg ":: Mounting /run/parabolaiso/cowspace (tmpfs) filesystem, size=${cowspace_size}..." + mkdir -p /run/parabolaiso/cowspace + mount -t tmpfs -o "size=${cowspace_size}",mode=0755 cowspace /run/parabolaiso/cowspace + fi + mkdir -p "/run/parabolaiso/cowspace/${cow_directory}" + + local aitab_img aitab_mnt aitab_arch aitab_sfs_comp aitab_fs_type aitab_fs_size + while read aitab_img aitab_mnt aitab_arch aitab_sfs_comp aitab_fs_type aitab_fs_size; do + [[ "${aitab_img#\#}" != "${aitab_img}" ]] && continue + [[ "${aitab_arch}" != "any" && "${aitab_arch}" != "${arch}" ]] && continue + if [[ "${aitab_fs_type}" != "none" ]]; then + _mnt_sfs "/run/parabolaiso/bootmnt/${parabolaisobasedir}/${aitab_arch}/${aitab_img}.fs.sfs" "/run/parabolaiso/sfs/${aitab_img}" + _mnt_fs "/run/parabolaiso/sfs/${aitab_img}/${aitab_img}.fs" "${newroot}" "${aitab_mnt}" + else + _mnt_sfs "/run/parabolaiso/bootmnt/${parabolaisobasedir}/${aitab_arch}/${aitab_img}.sfs" "${newroot}${aitab_mnt}" + fi + done < "${aitab}" + + if [[ "${copytoram}" == "y" ]]; then + umount /run/parabolaiso/bootmnt + fi +} + +# vim:ft=sh:ts=4:sw=4:et: diff --git a/parabolaiso/initcpio/hooks/parabolaiso_loop_mnt b/parabolaiso/initcpio/hooks/parabolaiso_loop_mnt new file mode 100644 index 0000000..772c3b6 --- /dev/null +++ b/parabolaiso/initcpio/hooks/parabolaiso_loop_mnt @@ -0,0 +1,32 @@ +# vim: set ft=sh: + +run_hook () { + [[ -n "${img_label}" ]] && img_dev="/dev/disk/by-label/${img_label}" + if [[ -n "${img_dev}" && -n "${img_loop}" ]]; then + mount_handler="parabolaiso_loop_mount_handler" + fi +} + +parabolaiso_loop_mount_handler () { + newroot="${1}" + + local _dev_loop + + msg ":: Setup a loop device from ${img_loop} located at device ${img_dev}" + _mnt_dev "${img_dev}" "/run/parabolaiso/img_dev" "-r" + if [[ "${copytoram}" != "y" ]]; then + echo $(readlink -f ${img_dev}) >> /run/parabolaiso/used_block_devices + fi + + if ! _dev_loop=$(losetup --find --show --read-only "/run/parabolaiso/img_dev/${img_loop}"); then + echo "ERROR: Setting loopback device for file '/run/parabolaiso/img_dev/${img_loop}'" + launch_interactive_shell + fi + + parabolaiso_mount_handler ${newroot} + + if [[ "${copytoram}" == "y" ]]; then + losetup -d ${_dev_loop} + umount /run/parabolaiso/img_dev + fi +} diff --git a/parabolaiso/initcpio/hooks/parabolaiso_pxe_common b/parabolaiso/initcpio/hooks/parabolaiso_pxe_common new file mode 100644 index 0000000..d8ac709 --- /dev/null +++ b/parabolaiso/initcpio/hooks/parabolaiso_pxe_common @@ -0,0 +1,50 @@ +# vim: set ft=sh: + +run_hook () { + local i net_mac bootif_mac bootif_dev + # These variables will be parsed from /tmp/net-*.conf generated by ipconfig + local DEVICE + local IPV4ADDR IPV4BROADCAST IPV4NETMASK IPV4GATEWAY IPV4DNS0 IPV4DNS1 + local HOSTNAME DNSDOMAIN NISDOMAIN ROOTSERVER ROOTPATH + local filename + # /tmp/net-*.conf + + if [[ -n "${ip}" ]]; then + if [[ -n "${BOOTIF}" ]]; then + bootif_mac=${BOOTIF#01-} + bootif_mac=${bootif_mac//-/:} + for i in /sys/class/net/*/address; do + read net_mac < ${i} + if [[ "${bootif_mac}" == "${net_mac}" ]]; then + bootif_dev=${i#/sys/class/net/} + bootif_dev=${bootif_dev%/address} + break + fi + done + ip="${ip}::${bootif_dev}" + fi + + # setup network and save some values + ipconfig "ip=${ip}" + + . /tmp/net-*.conf + + pxeserver=${ROOTSERVER} + + # setup DNS resolver + if [[ "${IPV4DNS0}" != "0.0.0.0" ]]; then + echo "nameserver ${IPV4DNS0}" > /etc/resolv.conf + fi + if [[ "${IPV4DNS1}" != "0.0.0.0" ]]; then + echo "nameserver ${IPV4DNS1}" >> /etc/resolv.conf + fi + fi +} + +run_latehook () { + [[ -z "${copy_resolvconf}" ]] && copy_resolvconf="y" + + if [[ "${copy_resolvconf}" != "n" && -f /etc/resolv.conf ]]; then + cp /etc/resolv.conf /new_root/etc/resolv.conf + fi +} diff --git a/parabolaiso/initcpio/hooks/parabolaiso_pxe_http b/parabolaiso/initcpio/hooks/parabolaiso_pxe_http new file mode 100644 index 0000000..97de91f --- /dev/null +++ b/parabolaiso/initcpio/hooks/parabolaiso_pxe_http @@ -0,0 +1,61 @@ +# vim: set ft=sh: + +run_hook() { + if [[ -n "${ip}" && -n "${parabolaiso_http_srv}" ]]; then + + parabolaiso_http_srv=$(eval echo ${parabolaiso_http_srv}) + [[ -z "${parabolaiso_http_spc}" ]] && parabolaiso_http_spc="75%" + + mount_handler="parabolaiso_pxe_http_mount_handler" + fi +} + +# Fetch a file with CURL +# +# $1 URL +# $2 Destination directory inside httpspace/${parabolaisobasedir} +_curl_get() { + local _url="${1}" + local _dst="${2}" + + msg ":: Downloading '${_url}'" + if ! curl -L -f -o "/run/parabolaiso/httpspace/${parabolaisobasedir}${_dst}/${_url##*/}" --create-dirs "${_url}"; then + echo "ERROR: Downloading '${_url}'" + echo " Falling back to interactive prompt" + echo " You can try to fix the problem manually, log out when you are finished" + launch_interactive_shell + fi +} + +parabolaiso_pxe_http_mount_handler () { + newroot="${1}" + + msg ":: Mounting /run/parabolaiso/httpspace (tmpfs) filesystem, size='${parabolaiso_http_spc}'" + mkdir -p "/run/parabolaiso/httpspace" + mount -t tmpfs -o size="${parabolaiso_http_spc}",mode=0755 httpspace "/run/parabolaiso/httpspace" + + local _aitab_url="${parabolaiso_http_srv}${aitab#/run/parabolaiso/bootmnt/}" + local _aitab_file="/run/parabolaiso/httpspace/${aitab#/run/parabolaiso/bootmnt/}" + + _curl_get "${_aitab_url}" "/" + + local aitab_img aitab_mnt aitab_arch aitab_sfs_comp aitab_fs_type aitab_fs_size + while read aitab_img aitab_mnt aitab_arch aitab_sfs_comp aitab_fs_type aitab_fs_size; do + [[ "${aitab_img#\#}" != "${aitab_img}" ]] && continue + [[ "${aitab_arch}" != "any" && "${aitab_arch}" != "${arch}" ]] && continue + if [[ "${aitab_fs_type}" != "none" ]]; then + _curl_get "${parabolaiso_http_srv}${parabolaisobasedir}/${aitab_arch}/${aitab_img}.fs.sfs" "/${aitab_arch}" + else + _curl_get "${parabolaiso_http_srv}${parabolaisobasedir}/${aitab_arch}/${aitab_img}.sfs" "/${aitab_arch}" + fi + done < "${_aitab_file}" + + if [[ "${checksum}" == "y" ]]; then + _curl_get "${parabolaiso_http_srv}${parabolaisobasedir}/checksum.${arch}.md5" "/" + fi + + mkdir -p "/run/parabolaiso/bootmnt" + mount -o bind /run/parabolaiso/httpspace /run/parabolaiso/bootmnt + + parabolaiso_mount_handler ${newroot} +} diff --git a/parabolaiso/initcpio/hooks/parabolaiso_pxe_nbd b/parabolaiso/initcpio/hooks/parabolaiso_pxe_nbd new file mode 100644 index 0000000..1bb8cbb --- /dev/null +++ b/parabolaiso/initcpio/hooks/parabolaiso_pxe_nbd @@ -0,0 +1,40 @@ +# vim: set ft=sh: + +run_hook() { + if [[ -n "${ip}" && -n "${parabolaiso_nbd_srv}" ]]; then + + parabolaiso_nbd_srv=$(eval echo ${parabolaiso_nbd_srv}) + [[ -z "${parabolaiso_nbd_name}" ]] && parabolaiso_nbd_name="parabolaiso" + + mount_handler="parabolaiso_pxe_nbd_mount_handler" + fi +} + +parabolaiso_pxe_nbd_mount_handler () { + newroot="${1}" + + # Module autoloading like with loop devices does not work, doing manually... + modprobe nbd 2> /dev/null + + msg ":: Waiting for boot device..." + while ! poll_device /dev/nbd0 30; do + echo "ERROR: boot device didn't show up after 30 seconds..." + echo " Falling back to interactive prompt" + echo " You can try to fix the problem manually, log out when you are finished" + launch_interactive_shell + done + + msg ":: Setup NBD from ${parabolaiso_nbd_srv} at /dev/nbd0" + nbd-client ${parabolaiso_nbd_srv} -N ${parabolaiso_nbd_name} /dev/nbd0 + + if [[ "${copytoram}" != "n" ]]; then + copytoram="y" + fi + + parabolaisodevice=/dev/nbd0 + + parabolaiso_mount_handler ${newroot} + + msg ":: Disconnect NBD from ${parabolaiso_nbd_srv} at /dev/nbd0" + nbd-client -d /dev/nbd0 +} diff --git a/parabolaiso/initcpio/hooks/parabolaiso_pxe_nfs b/parabolaiso/initcpio/hooks/parabolaiso_pxe_nfs new file mode 100644 index 0000000..6eba5b7 --- /dev/null +++ b/parabolaiso/initcpio/hooks/parabolaiso_pxe_nfs @@ -0,0 +1,30 @@ +# vim: set ft=sh: + +run_hook() { + if [[ -n "${ip}" && -n "${parabolaiso_nfs_srv}" ]]; then + + parabolaiso_nfs_srv=$(eval echo ${parabolaiso_nfs_srv}) + [[ -n "${parabolaiso_nfs_opt}" ]] && parabolaiso_nfs_opt="-o ${parabolaiso_nfs_opt}" + + mount_handler="parabolaiso_nfs_mount_handler" + fi +} + +parabolaiso_nfs_mount_handler() { + newroot="${1}" + mkdir -p "/run/parabolaiso/bootmnt" + msg ":: Mounting '${parabolaiso_nfs_srv}'" + # Do not put "${parabolaiso_nfs_opt}" nfsmount fails! + if ! nfsmount ${parabolaiso_nfs_opt} "${parabolaiso_nfs_srv}" "/run/parabolaiso/bootmnt"; then + echo "ERROR: Mounting '${parabolaiso_nfs_srv}'" + echo " Falling back to interactive prompt" + echo " You can try to fix the problem manually, log out when you are finished" + launch_interactive_shell + fi + + if [[ "${copytoram}" != "n" ]]; then + copytoram="y" + fi + + parabolaiso_mount_handler ${newroot} +} diff --git a/parabolaiso/initcpio/hooks/parabolaiso_shutdown b/parabolaiso/initcpio/hooks/parabolaiso_shutdown new file mode 100644 index 0000000..e50dedb --- /dev/null +++ b/parabolaiso/initcpio/hooks/parabolaiso_shutdown @@ -0,0 +1,6 @@ +run_cleanuphook() { + rm -rf /usr/lib/modules + cp -ax / /run/initramfs +} + +# vim: set ft=sh ts=4 sw=4 et: diff --git a/parabolaiso/initcpio/install/parabolaiso b/parabolaiso/initcpio/install/parabolaiso new file mode 100644 index 0000000..8893667 --- /dev/null +++ b/parabolaiso/initcpio/install/parabolaiso @@ -0,0 +1,22 @@ +#!/bin/bash + +build() { + add_module "cdrom" + add_module "loop" + add_module "dm-snapshot" + + add_runscript + + add_binary /usr/lib/udev/cdrom_id + add_binary blockdev + add_binary dmsetup + add_binary losetup + add_binary mountpoint + + add_file /usr/lib/udev/rules.d/60-cdrom_id.rules + add_file /usr/lib/udev/rules.d/10-dm.rules + add_file /usr/lib/udev/rules.d/95-dm-notify.rules + add_file /usr/lib/initcpio/udev/11-dm-initramfs.rules /usr/lib/udev/rules.d/11-dm-initramfs.rules +} + +# vim: set ft=sh ts=4 sw=4 et: diff --git a/parabolaiso/initcpio/install/parabolaiso_kms b/parabolaiso/initcpio/install/parabolaiso_kms new file mode 100644 index 0000000..3ff31f3 --- /dev/null +++ b/parabolaiso/initcpio/install/parabolaiso_kms @@ -0,0 +1,26 @@ +#!/bin/bash + +build() { + add_module "radeon" + add_module "nouveau" + add_module "i915" + add_module "via-agp" + add_module "sis-agp" + add_module "intel-agp" + + if [[ $(uname -m) == i686 ]]; then + add_module "amd64-agp" + add_module "ati-agp" + add_module "sworks-agp" + add_module "ali-agp" + add_module "amd-k7-agp" + add_module "nvidia-agp" + add_module "efficeon-agp" + fi +} + +help() { + cat << HELPEOF +Adds all common KMS drivers to the initramfs image. +HELPEOF +} diff --git a/parabolaiso/initcpio/install/parabolaiso_loop_mnt b/parabolaiso/initcpio/install/parabolaiso_loop_mnt new file mode 100644 index 0000000..59f1d94 --- /dev/null +++ b/parabolaiso/initcpio/install/parabolaiso_loop_mnt @@ -0,0 +1,13 @@ +#!/bin/bash + +build() { + add_runscript +} + +help() { +cat<<HELPEOF + This hook loads the necessary modules for boot via loop device. +HELPEOF +} + +# vim: set ft=sh ts=4 sw=4 et: diff --git a/parabolaiso/initcpio/install/parabolaiso_pxe_common b/parabolaiso/initcpio/install/parabolaiso_pxe_common new file mode 100644 index 0000000..eec9a7e --- /dev/null +++ b/parabolaiso/initcpio/install/parabolaiso_pxe_common @@ -0,0 +1,26 @@ +#!/bin/bash + +build() { + add_checked_modules -f "(irda|phy|wimax|wireless|ppp_|plip|pppoe)" "/drivers/net/" + + add_runscript + + add_binary /usr/lib/initcpio/ipconfig /bin/ipconfig + + # Add hosts support files+dns + add_symlink /usr/lib/libnss_files.so.2 $(readlink /usr/lib/libnss_files.so.2) + add_binary $(readlink -f /usr/lib/libnss_files.so.2) + add_symlink /usr/lib/libnss_dns.so.2 $(readlink /usr/lib/libnss_dns.so.2) + add_binary $(readlink -f /usr/lib/libnss_dns.so.2) + + add_dir /etc + echo "hosts: files dns" > $BUILDROOT/etc/nsswitch.conf +} + +help() { +cat<<HELPEOF + This hook loads the necessary modules for boot via PXE. +HELPEOF +} + +# vim: set ft=sh ts=4 sw=4 et: diff --git a/parabolaiso/initcpio/install/parabolaiso_pxe_http b/parabolaiso/initcpio/install/parabolaiso_pxe_http new file mode 100644 index 0000000..4e02f98 --- /dev/null +++ b/parabolaiso/initcpio/install/parabolaiso_pxe_http @@ -0,0 +1,15 @@ +#!/bin/bash + +build() { + add_runscript + + add_binary curl +} + +help() { +cat<<HELPEOF + This hook loads the necessary modules for boot via PXE and HTTP. +HELPEOF +} + +# vim: set ft=sh ts=4 sw=4 et: diff --git a/parabolaiso/initcpio/install/parabolaiso_pxe_nbd b/parabolaiso/initcpio/install/parabolaiso_pxe_nbd new file mode 100644 index 0000000..47d98ce --- /dev/null +++ b/parabolaiso/initcpio/install/parabolaiso_pxe_nbd @@ -0,0 +1,17 @@ +#!/bin/bash + +build() { + add_module "nbd" + + add_runscript + + add_binary nbd-client +} + +help() { +cat<<HELPEOF + This hook loads the necessary modules for boot via PXE and NBD. +HELPEOF +} + +# vim: set ft=sh ts=4 sw=4 et: diff --git a/parabolaiso/initcpio/install/parabolaiso_pxe_nfs b/parabolaiso/initcpio/install/parabolaiso_pxe_nfs new file mode 100644 index 0000000..f8226e5 --- /dev/null +++ b/parabolaiso/initcpio/install/parabolaiso_pxe_nfs @@ -0,0 +1,17 @@ +#!/bin/bash + +build() { + add_module "nfs" + + add_runscript + + add_binary /usr/lib/initcpio/nfsmount /bin/nfsmount +} + +help() { + cat <<HELPEOF + This hook loads the necessary modules for boot via PXE and NFS. +HELPEOF +} + +# vim: set ft=sh ts=4 sw=4 et: diff --git a/parabolaiso/initcpio/install/parabolaiso_shutdown b/parabolaiso/initcpio/install/parabolaiso_shutdown new file mode 100644 index 0000000..d7bffa7 --- /dev/null +++ b/parabolaiso/initcpio/install/parabolaiso_shutdown @@ -0,0 +1,20 @@ +#!/bin/bash + +build() { + add_binary cp + + add_runscript + + add_file /usr/lib/initcpio/parabolaiso_shutdown /shutdown +} + +help() { + cat <<HELPEOF +This hook will create a shutdown initramfs in /run/initramfs +that we can pivot to on shutdown in order to unmount / and +and others mount points, dm-snapshot devices and loopback devices. +Mostly usefull for dm-snapshot persistent. +HELPEOF +} + +# vim: set ft=sh ts=4 sw=4 et: diff --git a/parabolaiso/initcpio/script/parabolaiso_shutdown b/parabolaiso/initcpio/script/parabolaiso_shutdown new file mode 100644 index 0000000..143df04 --- /dev/null +++ b/parabolaiso/initcpio/script/parabolaiso_shutdown @@ -0,0 +1,37 @@ +#!/bin/ash + +# /oldroot depends on things inside /oldroot/run/parabolaiso... +mkdir /oldrun +mount -n --move /oldroot/run /oldrun + +# Unmount all mounts now. +umount $(mount | awk '$3 ~/^\/oldroot/ {print $3}' | sort -r) + +# Remove all dm-snapshot devices. +dmsetup remove_all + +# Remove all loopback devices. +for _lup in $(grep ^/dev/loop /oldrun/parabolaiso/used_block_devices | tac); do + if ! losetup -d ${_lup} 2> /dev/null; then + umount -d ${_lup} + fi +done + +# Unmount the space used to store *.cow. +umount /oldrun/parabolaiso/cowspace + +# Unmount boot device if needed (no copytoram=y used) +if [[ ! -d /oldrun/parabolaiso/copytoram ]]; then + if [[ -d /oldrun/parabolaiso/img_dev ]]; then + umount /oldrun/parabolaiso/img_dev + else + umount /oldrun/parabolaiso/bootmnt + fi +fi + +# reboot / poweroff / halt, depending on the argument passed by init +# if something invalid is passed, we halt +case "$1" in + reboot|poweroff|halt) "$1" -f ;; + *) halt -f;; +esac diff --git a/parabolaiso/mkparabolaiso b/parabolaiso/mkparabolaiso new file mode 100755 index 0000000..93e6995 --- /dev/null +++ b/parabolaiso/mkparabolaiso @@ -0,0 +1,587 @@ +#!/bin/bash + +set -e -u + +export LANG=C + +app_name=${0##*/} +arch=$(uname -m) +pkg_list="" +run_cmd="" +quiet="y" +pacman_conf="/etc/pacman.conf" +export iso_label="PARA_$(date +%Y%m)" +iso_publisher="Parabola GNU/Linux-libre <https://parabolagnulinux.org>" +iso_application="Parabola GNU/Linux-libre Live/Rescue CD" +install_dir="parabola" +work_dir="work" +out_dir="out" + +# Show an INFO message +# $1: message string +_msg_info() { + local _msg="${1}" + echo "[mkparabolaiso] INFO: ${_msg}" +} + +# Show an ERROR message then exit with status +# $1: message string +# $2: exit code number (with 0 does not exit) +_msg_error() { + local _msg="${1}" + local _error=${2} + echo + echo "[mkparabolaiso] ERROR: ${_msg}" + echo + if [[ ${_error} -gt 0 ]]; then + exit ${_error} + fi +} + +# Show space usage similar to df, but better formatted. +# $1: mount-point or mounted device. +_show_space_usage () { + local _where="${1}" + local _fs _total _used _avail _pct_u=0 _mnt + read _fs _total _used _avail _pct_u _mnt < <(df -m "${_where}" | tail -1) &> /dev/null + _msg_info "Total: ${_total} MiB (100%) | Used: ${_used} MiB (${_pct_u}) | Avail: ${_avail} MiB ($((100 - ${_pct_u%\%}))%)" +} + +_chroot_mount () { + mount -t devtmpfs dev "${work_dir}/root-image/dev" + mount -t devpts devpts "${work_dir}/root-image/dev/pts" + mount -t tmpfs devshm "${work_dir}/root-image/dev/shm" + mount -t proc proc "${work_dir}/root-image/proc" + mount -t tmpfs run "${work_dir}/root-image/run" + mount -t sysfs sys "${work_dir}/root-image/sys" + mount -t tmpfs tmp "${work_dir}/root-image/tmp" + + trap '_chroot_umount' EXIT HUP INT TERM +} + +_chroot_umount () { + umount "${work_dir}/root-image/tmp" + umount "${work_dir}/root-image/sys" + umount "${work_dir}/root-image/run" + umount "${work_dir}/root-image/proc" + umount "${work_dir}/root-image/dev/shm" + umount "${work_dir}/root-image/dev/pts" + umount "${work_dir}/root-image/dev" + + trap - EXIT HUP INT TERM +} + +_chroot_init() { + if [[ ! -d ${work_dir}/root-image/var/cache/pacman ]]; then + mkdir -p ${work_dir}/root-image/{dev,proc,run,sys,tmp,var/lib/pacman} + _pacman "base" + _pacman "syslinux" + fi +} + +_chroot_run() { + _chroot_mount + eval chroot ${work_dir}/root-image "${run_cmd}" + _chroot_umount +} + +# Mount a filesystem (trap signals in case of error for unmounting it +# $1: source image +# $2: mount-point +_mount_fs() { + local _src="${1}" + local _dst="${2}" + trap "_umount_fs ${_src}" EXIT HUP INT TERM + mkdir -p "${_dst}" + _msg_info "Mounting '${_src}' on '${_dst}'" + mount "${_src}" "${_dst}" + _show_space_usage "${_dst}" +} + +# Unmount a filesystem (and untrap signals) +# $1: mount-point or device/image +_umount_fs() { + local _dst="${1}" + _show_space_usage "${_dst}" + _msg_info "Unmounting '${_dst}'" + umount "${_dst}" + rmdir "${_dst}" + trap - EXIT HUP INT TERM +} + +# Compare if a file/directory (source) is newer than other file (target) +# $1: source file/directory +# $2: target file +# return: 0 if target does not exists or if target is older than source. +# 1 if target is newer than source +_is_directory_changed() { + local _src="${1}" + local _dst="${2}" + + if [ -e "${_dst}" ]; then + if [[ $(find ${_src} -newer ${_dst} | wc -l) -gt 0 ]]; then + _msg_info "Target '${_dst}' is older than '${_src}', updating." + rm -f "${_dst}" + return 0 + else + _msg_info "Target '${_dst}' is up to date with '${_src}', skipping." + return 1 + fi + else + _msg_info "Target '${_dst}' does not exist, making it from '${_src}'" + return 0 + fi +} + +# Show help usage, with an exit status. +# $1: exit status number. +_usage () +{ + echo "usage ${app_name} [options] command <command options>" + echo " general options:" + echo " -p PACKAGE(S) Package(s) to install, can be used multiple times" + echo " -r <command> Run <command> inside root-image" + echo " -C <file> Config file for pacman." + echo " Default: '${pacman_conf}'" + echo " -L <label> Set a label for the disk" + echo " Default: '${iso_label}'" + echo " -P <publisher> Set a publisher for the disk" + echo " Default: '${iso_publisher}'" + echo " -A <application> Set an application name for the disk" + echo " Default: '${iso_application}'" + echo " -D <install_dir> Set an install_dir. All files will by located here." + echo " Default: '${install_dir}'" + echo " NOTE: Max 8 characters, use only [a-z0-9]" + echo " -w <work_dir> Set the working directory" + echo " Default: '${work_dir}'" + echo " -o <out_dir> Set the output directory" + echo " Default: '${out_dir}'" + echo " -v Enable verbose output" + echo " -h This message" + echo " commands:" + echo " init" + echo " Make base layout and install base group" + echo " install" + echo " Install all specified packages (-p)" + echo " run" + echo " run command specified by -r" + echo " prepare" + echo " build all images" + echo " checksum" + echo " make a checksum.md5 for self-test" + echo " pkglist" + echo " make a pkglist.txt of packages installed on root-image" + echo " iso <image name>" + echo " build an iso image from the working dir" + exit ${1} +} + +# Shows configuration according to command mode. +# $1: init | install | run | prepare | checksum | iso +_show_config () { + local _mode="$1" + echo + _msg_info "Configuration settings" + _msg_info " Command: ${command_name}" + _msg_info " Architecture: ${arch}" + _msg_info " Working directory: ${work_dir}" + _msg_info " Installation directory: ${install_dir}" + case "${_mode}" in + init) + _msg_info " Pacman config file: ${pacman_conf}" + ;; + install) + _msg_info " Pacman config file: ${pacman_conf}" + _msg_info " Packages: ${pkg_list}" + ;; + run) + _msg_info " Run command: ${run_cmd}" + ;; + prepare) + ;; + checksum) + ;; + pkglist) + ;; + iso) + _msg_info " Image name: ${img_name}" + _msg_info " Disk label: ${iso_label}" + _msg_info " Disk publisher: ${iso_publisher}" + _msg_info " Disk application: ${iso_application}" + ;; + esac + echo +} + +# Install desired packages to root-image +_pacman () +{ + _msg_info "Installing packages to '${work_dir}/root-image/'..." + + _chroot_mount + + if [[ "${quiet}" = "y" ]]; then + pacman -Sy -r "${work_dir}/root-image" --config "${pacman_conf}" --needed --noconfirm $* &> /dev/null + else + pacman -Sy -r "${work_dir}/root-image" --config "${pacman_conf}" --needed --noconfirm $* + fi + + _chroot_umount + + _msg_info "Packages installed successfully!" +} + +# Cleanup root-image +_cleanup () { + _msg_info "Cleaning up what we can on root-image..." + + # Delete initcpio image(s) + if [[ -d "${work_dir}/root-image/boot" ]]; then + find "${work_dir}/root-image/boot" -type f -name '*.img' -delete + fi + # Delete kernel(s) + if [[ -d "${work_dir}/root-image/boot" ]]; then + find "${work_dir}/root-image/boot" -type f -name 'vmlinuz*' -delete + fi + # Delete pacman database sync cache files (*.tar.gz) + if [[ -d "${work_dir}/root-image/var/lib/pacman" ]]; then + find "${work_dir}/root-image/var/lib/pacman" -maxdepth 1 -type f -delete + fi + # Delete pacman database sync cache + if [[ -d "${work_dir}/root-image/var/lib/pacman/sync" ]]; then + find "${work_dir}/root-image/var/lib/pacman/sync" -delete + fi + # Delete pacman package cache + if [[ -d "${work_dir}/root-image/var/cache/pacman/pkg" ]]; then + find "${work_dir}/root-image/var/cache/pacman/pkg" -type f -delete + fi + # Delete all log files, keeps empty dirs. + if [[ -d "${work_dir}/root-image/var/log" ]]; then + find "${work_dir}/root-image/var/log" -type f -delete + fi + # Avoid journald use permanent storage (Storage=auto) + if [[ -d "${work_dir}/root-image/var/log/journal" ]]; then + rm -rf "${work_dir}/root-image/var/log/journal" + fi + # Delete all temporary files and dirs + if [[ -d "${work_dir}/root-image/var/tmp" ]]; then + find "${work_dir}/root-image/var/tmp" -mindepth 1 -delete + fi + # Delete package pacman related files. + find "${work_dir}" \( -name "*.pacnew" -o -name "*.pacsave" -o -name "*.pacorig" \) -delete + _msg_info "Done!" +} + +# Makes a SquashFS filesystem image of file/directory passes as argument with desired compression. +# $1: Source file/directory +# $2: SquashFS compression type (gzip | lzo | xz) +_mksfs () { + local _src="${1}" + local _sfs_comp="${2}" + + if [[ ! -e "${work_dir}/${_src}" ]]; then + _msg_error "The path '${work_dir}/${_src}' does not exist" 1 + fi + + local _sfs_img="${work_dir}/${_src}.sfs" + + _msg_info "Creating SquashFS image for '${work_dir}/${_src}', This may take some time..." + local _seconds=${SECONDS} + if [[ "${quiet}" = "y" ]]; then + mksquashfs "${work_dir}/${_src}" "${_sfs_img}" -noappend -comp "${_sfs_comp}" -no-progress &> /dev/null + else + mksquashfs "${work_dir}/${_src}" "${_sfs_img}" -noappend -comp "${_sfs_comp}" -no-progress + fi + _seconds=$((SECONDS - _seconds)) + printf "[mkparabolaiso] INFO: Image creation done in %02d:%02d minutes\n" $((_seconds / 60)) $((_seconds % 60)) +} + +# Makes a filesystem from a source directory. +# $1: Source directory +# $2: Target filesystem type (ext4 | ext3 | ext2 | xfs | btrfs) +# $3: Size of target filesystem. Can be an absolute value in MiB, or relative value of desired free space (1% - 99%) +_mkfs () { + local _src="${1}" + local _fs_type="${2}" + local _fs_size="${3}" + + local _fs_src="${work_dir}/${_src}" + local _fs_img="${work_dir}/${_src}.fs" + + if [[ ! -e "${_fs_src}" ]]; then + _msg_error "The path '${_fs_src}' does not exist" 1 + fi + + local _spc_used + _spc_used=$(du -sxm "${_fs_src}" | awk '{print $1}') + + # Caculate FS size with desired % of free space, adds 10% overhead to used space. + if [[ ${_fs_size} != ${_fs_size%\%} ]]; then + if [[ ${_fs_size%\%} -le 0 || ${_fs_size%\%} -ge 100 ]]; then + _msg_error "Invalid percentage of free space specified '${_fs_size}' on '${_src}', should be 0% < x < 100%" 1 + fi + _fs_size=$((_spc_used * 110 / (100 - ${_fs_size%\%}))) + else + local _spc_used_over=$((_spc_used * 11 / 10)) + if [[ ${_fs_size} -lt ${_spc_used_over} ]]; then + _msg_error "Filesystem size specified '${_fs_size}' MiB for '${_src}' is too small, must be at least '${_spc_used_over}' MiB" 1 + fi + fi + + _msg_info "Creating ${_fs_type} image of ${_fs_size} MiB..." + rm -f "${_fs_img}" + truncate -s ${_fs_size}M "${_fs_img}" + local _qflag="" + if [[ ${quiet} == "y" ]]; then + _qflag="-q" + fi + case "${_fs_type}" in + ext4) + mkfs.ext4 ${_qflag} -O ^has_journal -E lazy_itable_init=0 -m 0 -F "${_fs_img}" + tune2fs -c 0 -i 0 "${_fs_img}" &> /dev/null + ;; + ext3) + mkfs.ext3 ${_qflag} -m 0 -F "${_fs_img}" + tune2fs -c 0 -i 0 "${_fs_img}" &> /dev/null + ;; + ext2) + mkfs.ext2 ${_qflag} -m 0 -F "${_fs_img}" + tune2fs -c 0 -i 0 "${_fs_img}" &> /dev/null + ;; + xfs) + mkfs.xfs ${_qflag} "${_fs_img}" + ;; + btrfs) + mkfs.btrfs -M "${_fs_img}" + ;; + *) + _msg_error "Invalid filesystem: ${_fs_type}" 1 + ;; + esac + _msg_info "Done!" + _mount_fs "${_fs_img}" "${work_dir}/mnt/${_src}" + _msg_info "Copying '${_fs_src}/' to '${work_dir}/mnt/${_src}/'..." + cp -aT "${_fs_src}/" "${work_dir}/mnt/${_src}/" + _msg_info "Done!" + _umount_fs "${work_dir}/mnt/${_src}" +} + +command_checksum () { + _show_config checksum + + local _chk_arch + + for _chk_arch in i686 x86_64; do + if _is_directory_changed "${work_dir}/iso/${install_dir}" "${work_dir}/iso/${install_dir}/checksum.${_chk_arch}.md5"; then + _msg_info "Creating checksum file for self-test (${_chk_arch})..." + cd "${work_dir}/iso/${install_dir}" + if [[ -d "${_chk_arch}" ]]; then + md5sum aitab > checksum.${_chk_arch}.md5 + find ${_chk_arch} -type f -print0 | xargs -0 md5sum >> checksum.${_chk_arch}.md5 + if [[ -d "any" ]]; then + find any -type f -print0 | xargs -0 md5sum >> checksum.${_chk_arch}.md5 + fi + fi + cd ${OLDPWD} + _msg_info "Done!" + fi + done +} + +command_pkglist () { + _show_config pkglist + + if _is_directory_changed "${work_dir}/root-image/var/lib/pacman/local" "${work_dir}/iso/${install_dir}/pkglist.${arch}.txt"; then + _msg_info "Creating a list of installed packages on live-enviroment..." + pacman -Sl -r "${work_dir}/root-image" --config "${pacman_conf}" | \ + awk '/\[installed\]$/ {print $1 "/" $2 "-" $3}' > \ + "${work_dir}/iso/${install_dir}/pkglist.${arch}.txt" + _msg_info "Done!" + fi + +} + +# Create an ISO9660 filesystem from "iso" directory. +command_iso () { + local _iso_efi_boot_args="" + + if [[ ! -f "${work_dir}/iso/isolinux/isolinux.bin" ]]; then + _msg_error "The file '${work_dir}/iso/isolinux/isolinux.bin' does not exist." 1 + fi + if [[ ! -f "${work_dir}/iso/isolinux/isohdpfx.bin" ]]; then + _msg_error "The file '${work_dir}/iso/isolinux/isohdpfx.bin' does not exist." 1 + fi + + # If exists, add an EFI "El Torito" boot image (FAT filesystem) to ISO-9660 image. + if [[ -f "${work_dir}/iso/EFI/parabolaiso/efiboot.img" ]]; then + _iso_efi_boot_args="-eltorito-alt-boot + -e EFI/parabolaiso/efiboot.img + -no-emul-boot + -isohybrid-gpt-basdat" + fi + + _show_config iso + + if _is_directory_changed "${work_dir}/iso" "${out_dir}/${img_name}"; then + mkdir -p ${out_dir} + _msg_info "Creating ISO image..." + local _qflag="" + if [[ ${quiet} == "y" ]]; then + _qflag="-quiet" + fi + xorriso -as mkisofs ${_qflag} \ + -iso-level 3 \ + -full-iso9660-filenames \ + -volid "${iso_label}" \ + -appid "${iso_application}" \ + -publisher "${iso_publisher}" \ + -preparer "prepared by mkparabolaiso" \ + -eltorito-boot isolinux/isolinux.bin \ + -eltorito-catalog isolinux/boot.cat \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + -isohybrid-mbr ${work_dir}/iso/isolinux/isohdpfx.bin \ + ${_iso_efi_boot_args} \ + -output "${out_dir}/${img_name}" \ + "${work_dir}/iso/" + _msg_info "Done! | $(ls -sh ${out_dir}/${img_name})" + fi +} + +# Parse aitab and create each filesystem specified on that, and push it in "iso" directory. +command_prepare () { + if [[ ! -f "${work_dir}/iso/${install_dir}/aitab" ]]; then + _msg_error "The file '${work_dir}/iso/${install_dir}/aitab' does not exist." 1 + fi + _show_config prepare + + _cleanup + local _aitab_img _aitab_mnt _aitab_arch _aitab_sfs_comp _aitab_fs_type _aitab_fs_size + while read _aitab_img _aitab_mnt _aitab_arch _aitab_sfs_comp _aitab_fs_type _aitab_fs_size ; do + if [[ ${_aitab_img} =~ ^# ]]; then + continue + fi + if [[ "${_aitab_arch}" != "any" && "${_aitab_arch}" != "${arch}" ]]; then + continue + fi + local _src="${work_dir}/${_aitab_img}" + local _dst="${work_dir}/iso/${install_dir}/${_aitab_arch}" + mkdir -p "${_dst}" + if [[ ${_aitab_fs_type} != "none" ]]; then + if _is_directory_changed "${_src}" "${_dst}/${_aitab_img}.fs.sfs"; then + _mkfs ${_aitab_img} ${_aitab_fs_type} ${_aitab_fs_size} + _mksfs ${_aitab_img}.fs ${_aitab_sfs_comp} + mv "${_src}.fs.sfs" "${_dst}" + rm "${_src}.fs" + fi + else + if _is_directory_changed "${_src}" "${_dst}/${_aitab_img}.sfs"; then + _mksfs ${_aitab_img} ${_aitab_sfs_comp} + mv "${work_dir}/${_aitab_img}.sfs" "${_dst}" + fi + fi + done < "${work_dir}/iso/${install_dir}/aitab" +} + +# Install packages on root-image. +# A basic check to avoid double execution/reinstallation is done via hashing package names. +command_install () { + if [[ ! -f "${pacman_conf}" ]]; then + _msg_error "Pacman config file '${pacman_conf}' does not exist" 1 + fi + + #trim spaces + pkg_list="$(echo ${pkg_list})" + + if [[ -z ${pkg_list} ]]; then + _msg_error "Packages must be specified" 0 + _usage 1 + fi + + _show_config install + + local _pkg_list_hash + _pkg_list_hash=$(echo ${pkg_list} | sort -u | md5sum | cut -c1-32) + if [[ -f "${work_dir}/install.${_pkg_list_hash}" ]]; then + _msg_info "These packages are already installed, skipping." + else + _pacman "${pkg_list}" + : > "${work_dir}/install.${_pkg_list_hash}" + fi +} + +command_init() { + _show_config init + _chroot_init +} + +command_run() { + _show_config run + _chroot_run +} + +if [[ ${EUID} -ne 0 ]]; then + _msg_error "This script must be run as root." 1 +fi + +while getopts 'p:r:C:L:P:A:D:w:o:vh' arg; do + case "${arg}" in + p) pkg_list="${pkg_list} ${OPTARG}" ;; + r) run_cmd="${OPTARG}" ;; + C) pacman_conf="${OPTARG}" ;; + L) iso_label="${OPTARG}" ;; + P) iso_publisher="${OPTARG}" ;; + A) iso_application="${OPTARG}" ;; + D) install_dir="${OPTARG}" ;; + w) work_dir="${OPTARG}" ;; + o) out_dir="${OPTARG}" ;; + v) quiet="n" ;; + h|?) _usage 0 ;; + *) + _msg_error "Invalid argument '${arg}'" 0 + _usage 1 + ;; + esac +done + +shift $((OPTIND - 1)) + +if [[ $# -lt 1 ]]; then + _msg_error "No command specified" 0 + _usage 1 +fi +command_name="${1}" + +case "${command_name}" in + init) + command_init + ;; + install) + command_install + ;; + run) + command_run + ;; + prepare) + command_prepare + ;; + checksum) + command_checksum + ;; + pkglist) + command_pkglist + ;; + iso) + if [[ $# -lt 2 ]]; then + _msg_error "No image specified" 0 + _usage 1 + fi + img_name="${2}" + command_iso + ;; + *) + _msg_error "Invalid command name '${command_name}'" 0 + _usage 1 + ;; +esac + +# vim:ts=4:sw=4:et: |