#!/bin/bash # # Copyright (C) 2017 Purism SPC # # SPDX-License-Identifier: GPL-3.0+ # # Parmeters passed in via image builder: # Mandatory : "${apt_sources:?'apt_sources' not set}" : "${distro:?'distro' not set}" : "${packages:?'packages' not set}" : "${pureos_board:?'pureos_board' not set}" # Optional : "${build_tarball:-}" : "${ci_pkgs:-}" : "${fdt_file:-}" : "${kernel_deb:-}" : "${patched:-}" : "${qemu:-}" # distro and basedir set by calling script basedir="$1" image_name="$2" target_qemu="${basedir}/${qemu}" stamp="${basedir}/var/log/gitrev.log" for env_var in distro pureos_board packages; do if [ -z "${!env_var}" ]; then echo "Must pass in \$${env_var} via the environment" 1>&2 exit 1 fi done set -e set -u set -x echo "Configuring ${distro} in ${basedir} for board ${pureos_board}" # bindmount qemu into the rootfs so we can chroot into it if needed function setup_qemu() { [ -f "${target_qemu}" ] || cp "${qemu}" "${target_qemu}" } function setup_kernel() { local link local fdt_source fdt_source="" mkdir -p tmp/ mkdir -p "${basedir}/boot/dtbs" case "${pureos_board}" in imx6) fdt_source="${basedir}/usr/lib/linux-image-*/${fdt_file}" link=$(basename "${basedir}"/boot/vmlinuz-*) rm -f "${basedir}/boot/zImage" ln -s "${link}" "${basedir}/boot/zImage" cp data/update-zImage-link "${basedir}/etc/kernel/postinst.d/" cp "${basedir}/boot/zImage" "tmp/" ;; ec-som|imx8) fdt_source="${basedir}/usr/lib/linux-image-*/freescale/${fdt_file}" cp "${basedir}/boot/${link}" "${basedir}/boot/Image.gz" gunzip "${basedir}/boot/Image.gz" ;; devkit*) # Reconfigure kernel package to trigger kernel hooks chroot "${basedir}" dpkg-reconfigure "$(basename "${kernel_deb%%_*}")" ;; esac [ -z "${fdt_source}" ] || cp "${fdt_source}" "${basedir}/boot/dtbs/" } function setup_uboot() { sed -e "s/##DTBNAME##/${fdt_file}/" "data/boot-${pureos_board}.txt.in" > "${basedir}/boot/boot_emmc.txt" sed -e "s/##RFSPART##/0/" -i "${basedir}/boot/boot_emmc.txt" mkimage -A arm -T script -O linux -d "${basedir}/boot/boot_emmc.txt" "${basedir}/boot/boot_emmc.scr" sed -e "s/##DTBNAME##/${fdt_file}/" "data/boot-${pureos_board}.txt.in" > "${basedir}/boot/boot_sd.txt" sed -e "s/##RFSPART##/1/" -i "${basedir}/boot/boot_sd.txt" mkimage -A arm -T script -O linux -d "${basedir}/boot/boot_sd.txt" "${basedir}/boot/boot_sd.scr" if [ "${pureos_board}" == "imx6" ]; then ln -fs boot_sd.scr "${basedir}/boot/6x_bootscript" elif [ "${pureos_board}" == "devkit" ]; then ln -fs boot_emmc.scr "${basedir}/boot/boot.scr" else ln -fs boot_sd.scr "${basedir}/boot/boot.scr" fi [ ! -d "files/uboot-${pureos_board}" ] || cp -a "files/uboot-${pureos_board}/"* "${basedir}/boot/" } function build_tarball() { tarball=$(basename "${image_name}" .img).tar.xz echo -n "Taring up rootfs to $PWD/${tarball}..." tar --acl \ --exclude='./run/*' \ --exclude='./dev/*' \ --exclude='./sys/*' \ --exclude='./proc/*' \ -acf "${PWD}/${tarball}" -C "${basedir}" . echo "Done." } function check_patched() { if [ -z "${patched}" ]; then return fi for pkg in ${patched}; do # Not all architectures have all packages, so check this first if chroot "${basedir}" dpkg -s "${pkg}"; then if ! chroot "${basedir}" dpkg -s "${pkg}" | grep -qs "^Version: .*pureos"; then echo "${pkg} is not a patched version." exit 1 fi fi done } function cleanup_chroot() { chroot "${basedir}" apt-get clean rm "${basedir}/etc/resolv.conf" mv "${basedir}/etc/resolv.conf.bak" "${basedir}/etc/resolv.conf" rm "${basedir}/usr/sbin/policy-rc.d" umount "${basedir}/dev/pts" umount "${basedir}/dev" umount "${basedir}/sys" umount "${basedir}/proc" # existence of stamp indicates success if [ -f "${stamp}" ]; then [ -z "${build_tarball}" ] || build_tarball else exit 1 fi } function prepare_chroot() { trap cleanup_chroot EXIT mount -t proc chproc "${basedir}/proc" mount -t sysfs chsys "${basedir}/sys" mount -t devtmpfs chdev "${basedir}/dev" || mount --bind /dev "${basedir}/dev" mount -t devpts chpts "${basedir}/dev/pts" echo -e '#!/bin/sh\nexit 101' > "${basedir}/usr/sbin/policy-rc.d" chmod 755 "${basedir}/usr/sbin/policy-rc.d" mv "${basedir}/etc/resolv.conf" "${basedir}/etc/resolv.conf.bak" cp /etc/resolv.conf "${basedir}/etc" } function create_stamp() { git log --format=format:%H -1 > "${stamp}" } function setup_gui() { chroot "${basedir}" systemctl enable phosh.service } function setup_journal() { # Enable systemd journal chroot "${basedir}" mkdir -p /var/log/journal chroot "${basedir}" systemd-tmpfiles --create --prefix /var/log/journal chroot "${basedir}" apt-get -y remove rsyslog for l in daemon messages syslog kern mail user; do chroot "${basedir}" rm -f /var/log/${l}.* done } function setup_sshd() { [ -x "${basedir}/usr/sbin/sshd" ] || return # Make sure unique host keys are generated on first boot chroot "${basedir}" rm -f /etc/ssh/ssh_host_* } function setup_locale() { echo "en_US.UTF-8 UTF-8" > "${basedir}/etc/locale.gen" chroot "${basedir}" dpkg-reconfigure locales } # We have to do this because task packages don't work with debootstrap # (and won't). See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=841649 # other packages are better installed late to not confuse deboostrap about # systemd and systemd-shim (e.g. libpam-systemd) function install_pkgs() { chroot "${basedir}" apt-get -y update # Need to split package list # shellcheck disable=SC2086 if ! chroot "${basedir}" apt -y install ${packages}; then echo "Package installation failed, this might help to diagnose the problem:" # shellcheck disable=SC2086 chroot "${basedir}" apt -y -o Debug::pkgProblemResolver=yes install -y --simulate ${packages} fi } function setup_apt() { # shellcheck disable=SC2001 echo "${apt_sources}" | sed 's/|/\n/g' > "${basedir}/etc/apt/sources.list" echo "Set sources list to:" cat "${basedir}/etc/apt/sources.list" cat << EOF > "${basedir}/etc/apt/apt.conf.d/71-no-recommends" APT::Install-Recommends "0"; APT::Install-Suggests "0"; EOF chroot "${basedir}" apt-get install -y gnupg if [ "${ci_pkgs}" -gt 0 ]; then cat << EOF > "${basedir}/etc/apt/sources.list.d/ci.list" deb http://ci.puri.sm/ scratch librem5 EOF cat data/ci-repo.key | chroot "${basedir}" apt-key add - fi } function setup_network() { cat << EOF > "${basedir}/etc/hosts" 127.0.0.1 pureos localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters EOF cat << EOF > "${basedir}/etc/network/interfaces" auto lo iface lo inet loopback source-directory interfaces.d EOF # Don't setup resolv.conf if it's a symlink # DHCP will later handle this just fine if [ -f "${basedir}/etc/resolv.conf" ]; then cat < "${basedir}/etc/resolv.conf" nameserver 208.67.220.220 nameserver 208.67.222.222 EOF fi } function create_report() { echo "Installed packages:" chroot "${basedir}" dpkg -l echo -e "\\nInstalled apt keys:" chroot "${basedir}" apt-key list echo -e "\\nKernels:" ls -l "${basedir}/boot" } # create the directories so that this script can be tested without the generated filesystem mkdir -p "${basedir}/etc/apt/apt.conf.d/" mkdir -p "${basedir}/etc/network" export MALLOC_CHECK_=0 # workaround for LP: #520465 export LC_ALL=C export DEBIAN_FRONTEND=noninteractive export DEBCONF_NONINTERACTIVE_SEEN=true cat << EOF > "${basedir}/debconf.set" console-common console-data/keymap/policy select Select keymap from full list console-common console-data/keymap/full select en-latin1-nodeadkeys EOF setup_network prepare_chroot setup_qemu setup_apt install_pkgs setup_locale setup_gui setup_journal setup_sshd # Skip setup until we have hardware, not needed for qemu case "${pureos_board}" in imx6|imx8|ec-som|devkit) setup_kernel setup_uboot ;; ?) echo "No kernel or u-boot setup for ${pureos_board}" ;; esac check_patched create_report > "./tmp/${pureos_board}-report.log" create_stamp if [ -x files/local.sh ]; then echo "Warning: local.sh found, image is tainted" echo "tainted: true" >> files/meta.yml ./files/local.sh "$@" fi