diff --git a/.gitignore b/.gitignore index b1c730115a..a35882ea9e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /Cargo.lock /target **/*.rs.bk +src/__pycache__/* diff --git a/build.sh b/build.sh index 64f0703dab..86379966e0 100755 --- a/build.sh +++ b/build.sh @@ -1,6 +1,17 @@ -#!/usr/bin/bash -set -xeuo pipefail - +#!/usr/bin/env bash +set -euo pipefail + +if [ $# -eq 0 ]; then + echo Usage: "build.sh CMD" + echo "Supported commands:" + echo " configure_user" + echo " configure_yum_repos" + echo " install_rpms" + echo " make_and_makeinstall" + exit 1 +fi + +set -x srcdir=$(pwd) configure_yum_repos() { @@ -14,12 +25,13 @@ configure_yum_repos() { # Until we fix https://github.com/rpm-software-management/libdnf/pull/149 excludes='exclude=ostree ostree-libs ostree-grub2 rpm-ostree' for repo in /etc/yum.repos.d/fedora*.repo; do - cat ${repo} | (while read line; do if echo "$line" | grep -qE -e '^enabled=1'; then echo "${excludes}"; fi; echo $line; done) > ${repo}.new - mv ${repo}.new ${repo} + # reworked to remove useless `cat` - https://github.com/koalaman/shellcheck/wiki/SC2002 + (while read -r line; do if echo "$line" | grep -qE -e '^enabled=1'; then echo "${excludes}"; fi; echo "$line"; done < "${repo}") > "${repo}".new + mv "${repo}".new "${repo}" done # enable `walters/buildtools-fedora` copr - # pulled from https://copr.fedorainfracloud.org/coprs/walters/buildtools-fedora/repo/fedora-28/walters-buildtools-fedora-fedora-28.repo + # pulled from https://copr.fedorainfracloud.org/coprs/walters/buildtools-fedora/repo/fedora-28/walters-buildtools-fedora-fedora-28.repo cat > /etc/yum.repos.d/walters-buildtools-fedora-fedora-28.repo <<'EOF' [walters-buildtools-fedora] name=Copr repo for buildtools-fedora owned by walters @@ -34,7 +46,7 @@ enabled_metadata=1 EOF # enable `dustymabe/ignition` copr - # pulled from https://copr.fedorainfracloud.org/coprs/dustymabe/ignition/repo/fedora-28/dustymabe-ignition-fedora-28.repo + # pulled from https://copr.fedorainfracloud.org/coprs/dustymabe/ignition/repo/fedora-28/dustymabe-ignition-fedora-28.repo cat > /etc/yum.repos.d/dustymabe-ignition-fedora-28.repo <<'EOF' [dustymabe-ignition] name=Copr repo for ignition owned by dustymabe @@ -65,10 +77,10 @@ install_rpms() { # to use the container as a development environment for itself. # Down the line we may strip these out, or have a separate # development version. - self_builddeps=$(grep -v '^#' ${srcdir}/build-deps.txt) + self_builddeps=$(grep -v '^#' "${srcdir}"/build-deps.txt) # Process our base dependencies + build dependencies - (echo ${self_builddeps} && grep -v '^#' ${srcdir}/deps.txt) | xargs dnf -y install + (echo "${self_builddeps}" && grep -v '^#' "${srcdir}"/deps.txt) | xargs dnf -y install # Commented out for now, see above #dnf remove -y ${self_builddeps} @@ -90,7 +102,7 @@ make_and_makeinstall() { # TODO: install these as e.g. # /usr/bin/ostree-releng-script-rsync-repos mkdir -p /usr/app/ - rsync -rlv ${srcdir}/ostree-releng-scripts/ /usr/app/ostree-releng-scripts/ + rsync -rlv "${srcdir}"/ostree-releng-scripts/ /usr/app/ostree-releng-scripts/ if ! test -f mantle/README.md; then echo "Run: git submodule update --init" 1>&2 diff --git a/coreos-assembler b/coreos-assembler index 2d1b3d5a9a..202be6ceb4 100755 --- a/coreos-assembler +++ b/coreos-assembler @@ -6,7 +6,7 @@ set -euo pipefail # docker/podman don't run through PAM, but we want this set for the privileged # (non-virtualized) path -export USER=${USER:-$(id -nu)} +export USER="${USER:-$(id -nu)}" # When trying to connect to libvirt we get "Failed to find user record # for uid" errors if there is no entry for our UID in /etc/passwd. @@ -16,7 +16,7 @@ if ! whoami &> /dev/null; then # We need to make sure we set $HOME in the /etc/passwd file because # if we don't libvirt will try to use `/` and we will get permission # issues - export HOME="/var/tmp/${USER_NAME:-default}" && mkdir -p $HOME + export HOME="/var/tmp/${USER_NAME:-default}" && mkdir -p "$HOME" if [ -w /etc/passwd ]; then echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:${HOME}:/sbin/nologin" >> /etc/passwd fi @@ -26,7 +26,7 @@ fi # the later umount doesn't affect the host potentially if [ -e /sys/fs/selinux/status ]; then if [ -z "${coreos_assembler_unshared:-}" ]; then - exec sudo -- env coreos_assembler_unshared=1 unshare -m -- runuser -u ${USER} -- $0 "$@" + exec sudo -- env coreos_assembler_unshared=1 unshare -m -- runuser -u "${USER}" -- "$0" "$@" else # Work around https://github.com/containers/libpod/issues/1448 sudo umount /sys/fs/selinux @@ -34,7 +34,7 @@ if [ -e /sys/fs/selinux/status ]; then fi cmd=${1:-} -build_commands="init fetch build run prune clean" +build_commands="init fetch build buildextend-ec2 run prune clean" other_commands="shell" utility_commands="gf-oemid virt-install oscontainer" if [ -z "${cmd}" ]; then @@ -59,7 +59,7 @@ shift target=/usr/lib/coreos-assembler/cmd-${cmd} if test -x "${target}"; then - exec ${target} "$@" + exec "${target}" "$@" fi echo "Unknown command: ${cmd}" 1>&2 diff --git a/src/cmd-build b/src/cmd-build index eff7f5f881..093496b601 100755 --- a/src/cmd-build +++ b/src/cmd-build @@ -1,8 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -dn=$(dirname $0) -. ${dn}/cmdlib.sh +dn=$(dirname "$0") +# shellcheck source=src/cmdlib.sh +. "${dn}"/cmdlib.sh print_help() { cat 1>&2 <<'EOF' @@ -61,15 +62,15 @@ ostree --version rpm-ostree --version previous_build= -if [ -L ${workdir}/builds/latest ]; then - previous_build=$(readlink ${workdir}/builds/latest) - previous_builddir=${workdir}/builds/${previous_build} +if [ -L "${workdir:?}"/builds/latest ]; then + previous_build=$(readlink "${workdir}"/builds/latest) + previous_builddir="${workdir}/builds/${previous_build}" echo "Previous build: ${previous_build}" fi previous_commit= if [ -n "${ref:-}" ]; then - previous_commit=$(ostree --repo=${workdir}/repo rev-parse ${ref} 2>/dev/null || true) + previous_commit=$(ostree --repo="${workdir}"/repo rev-parse "${ref}" 2>/dev/null || true) fi # If the ref was unset or missing, look at the previous build if [ -z "${previous_commit}" ] && [ -n "${previous_build}" ]; then @@ -82,8 +83,8 @@ sha256sum_str() { } # Calculate kickstart checksum now and gather previous image build variables if any -kickstart_input=${configdir}/image.ks -kickstart_checksum=$(cat ${kickstart_input} | sha256sum_str) +kickstart_input="${configdir:?}"/image.ks +kickstart_checksum=$(< "${kickstart_input}" sha256sum_str) if [ -n "${previous_build}" ]; then previous_image_input_checksum=$(jq -r '.["coreos-assembler.image-input-checksum"]' < "${previous_builddir}/meta.json") previous_image_genver=$(jq -r '.["coreos-assembler.image-genver"]' < "${previous_builddir}/meta.json") @@ -91,13 +92,13 @@ fi echo "Kickstart checksum: ${kickstart_checksum}" # Generate metadata that's *input* to the ostree commit -config_gitrev=$(cd ${configdir} && git describe --tags --always --abbrev=42) +config_gitrev=$(cd "${configdir}" && git describe --tags --always --abbrev=42) config_dirty=false -if ! git -C ${configdir} diff --quiet --exit-code; then +if ! git -C "${configdir}" diff --quiet --exit-code; then config_dirty=true fi commitmeta_input_json=$(pwd)/tmp/commit-metadata-input.json -cat >${commitmeta_input_json} <"${commitmeta_input_json}" < tmp/meta.json < meta.json +cat "${composejson}" tmp/meta.json "${commitmeta_input_json}" | jq -s add > meta.json # Clean up our temporary data rm tmp -rf # Back to the toplevel build directory, so we can rename this one -cd ${workdir}/builds +cd "${workdir}"/builds # We create a .build-commit file to note that we're in the # middle of a "commit". This may be useful in the future # for having things be transactional. If for example we @@ -217,13 +211,16 @@ cd ${workdir}/builds # things would be inconsistent and future builds would fail # on the `mv`. touch .build-commit -mv -T ${tmp_builddir} ${buildid} +mv -T "${tmp_builddir:?}" "${buildid}" # Replace the latest link ln -Tsfr "${buildid}" latest # Update builds.json -prune_args="" -if [ ${SKIP_PRUNE} = 1 ]; then - prune_args="--insert-only ${buildid}" +# the variables passed to `prune_builds` end up single quoted and +# python treats them as literals, so we workaround this by duplicating +# the command ¯\_(ツ)_/¯ +if [ "${SKIP_PRUNE}" == 1 ]; then + "${dn}"/prune_builds --workdir "${workdir}" --insert-only "${buildid}" +else + "${dn}"/prune_builds --workdir "${workdir}" fi -${dn}/prune_builds --workdir ${workdir} ${prune_args} rm .build-commit diff --git a/src/cmd-clean b/src/cmd-clean index 9d312c0997..ea74f9a280 100755 --- a/src/cmd-clean +++ b/src/cmd-clean @@ -1,8 +1,9 @@ #!/usr/bin/env bash -set -xeuo pipefail +set -euo pipefail -dn=$(dirname $0) -. ${dn}/cmdlib.sh +dn=$(dirname "$0") +# shellcheck source=src/cmdlib.sh +. "${dn}"/cmdlib.sh print_help() { cat 1>&2 <<'EOF' @@ -44,11 +45,12 @@ if [ $# -ne 0 ]; then exit 1 fi +set -x # This has some useful sanity checks prepare_build # But go back to the toplevel -cd ${workdir} +cd "${workdir:?}" # Note we don't prune the cache.qcow2 or the objects # in the repo. If you want that, just rm -rf them. rm -rf repo/refs/heads/* builds/* tmp/* diff --git a/src/cmd-fetch b/src/cmd-fetch index b3e7dd71ed..a68e26a072 100755 --- a/src/cmd-fetch +++ b/src/cmd-fetch @@ -1,8 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -dn=$(dirname $0) -. ${dn}/cmdlib.sh +dn=$(dirname "$0") +# shellcheck source=src/cmdlib.sh +. "${dn}"/cmdlib.sh print_help() { cat 1>&2 <<'EOF' diff --git a/src/cmd-init b/src/cmd-init index 7cbc13f1d0..3f38b54d7d 100755 --- a/src/cmd-init +++ b/src/cmd-init @@ -1,12 +1,12 @@ #!/usr/bin/env bash set -euo pipefail -dn=$(dirname $0) -. ${dn}/cmdlib.sh +dn=$(dirname "$0") +# shellcheck source=src/cmdlib.sh +. "${dn}"/cmdlib.sh # Initialize FORCE to 0 FORCE=0 -SUBDIR= print_help() { cat 1>&2 <<'EOF' @@ -62,7 +62,7 @@ fi # If the current working dir is not empty then error out # unless force provided -if [ "$FORCE" != "1" -a ! -z "$(ls -A ./)" ]; then +if [ "$FORCE" != "1" ] && [ ! -z "$(ls -A ./)" ]; then fatal "init: current directory is not empty, override with --force" fi @@ -72,7 +72,7 @@ subdir=${1:-} preflight if has_privileges; then - sudo chown $USER: . + sudo chown "$USER:" . elif [ ! -w . ]; then fatal "init: running unprivileged, and current directory not writable" fi @@ -89,7 +89,7 @@ mkdir -p src *) git clone "${source}" config if [ -n "${subdir}" ]; then mv config config-git - ln -sr config-git/${subdir} config + ln -sr config-git/"${subdir}" config fi ;; esac @@ -105,12 +105,13 @@ mkdir -p installer installer_bn=$(basename ${INSTALLER}) if ! [ -f "${installer_bn}" ]; then mkdir -p tmp + ( cd tmp curl -L --remote-name-all ${INSTALLER} ${INSTALLER_CHECKSUM} checksums_bn=$(basename ${INSTALLER_CHECKSUM}) - sha256sum -c ${checksums_bn} - mv ${installer_bn} ${checksums_bn} .. - cd .. + sha256sum -c "${checksums_bn}" + mv "${installer_bn}" "${checksums_bn}" .. + ) rm tmp -rf fi ) diff --git a/src/cmd-prune b/src/cmd-prune index ebc5c26316..67938aa933 100755 --- a/src/cmd-prune +++ b/src/cmd-prune @@ -4,8 +4,9 @@ set -euo pipefail # This is just a thin wrapper around prune_builds. That way we still get the # preflight checks to make sure the workdir looks sane. -dn=$(dirname $0) -. ${dn}/cmdlib.sh +dn=$(dirname "$0") +# shellcheck source=src/cmdlib.sh +. "${dn}"/cmdlib.sh print_help() { cat 1>&2 <<'EOF' @@ -18,7 +19,7 @@ EOF } # Parse options -KEEP_LAST_N= +KEEP_LAST_N="3" rc=0 options=$(getopt --options h --longoptions help,keep: -- "$@") || rc=$? [ $rc -eq 0 ] || { @@ -34,7 +35,7 @@ while true; do ;; --keep) shift - KEEP_LAST_N="--keep-last-n $1" + KEEP_LAST_N="$1" ;; --) shift @@ -55,5 +56,4 @@ if [ $# -ne 0 ]; then fi prepare_build - -${dn}/prune_builds ${KEEP_LAST_N} --workdir ${workdir} +"${dn}"/prune_builds --keep-last-n "${KEEP_LAST_N}" --workdir "${workdir:?}" diff --git a/src/cmd-run b/src/cmd-run index 3b4448dd53..ad2fbc2e73 100755 --- a/src/cmd-run +++ b/src/cmd-run @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Forked from https://github.com/coreos/scripts/blob/master/build_library/qemu_template.sh # Changed to have command line arguments, drop non-x86_64/non-KVM support # Automatically uses `-snapshot` if the target disk isn't writable @@ -7,8 +7,9 @@ set -euo pipefail -dn=$(dirname $0) -. ${dn}/cmdlib.sh +dn=$(dirname "$0") +# shellcheck source=src/cmdlib.sh +. "${dn}"/cmdlib.sh VM_DISK= VM_MEMORY=2048 @@ -35,8 +36,8 @@ for more details. " die(){ - echo "${1}" 1>&2 - exit 1 + echo "${1}" 1>&2 + exit 1 } while [ $# -ge 1 ]; do @@ -73,12 +74,13 @@ while [ $# -ge 1 ]; do esac done +set -x preflight if [ -z "${VM_DISK}" ]; then if [ -L ./builds/latest ]; then latest_build=$(readlink builds/latest) - VM_DISK=$(ls builds/${latest_build}/*-qemu.qcow2) + VM_DISK=$(ls builds/"${latest_build}"/*-"${latest_build}"-qemu.qcow2) else die "No builds/latest, and no -d argument provided" fi @@ -88,7 +90,7 @@ fi set -- -machine accel=kvm -cpu host -smp "${VM_NCPUS}" "$@" if [ -n "${VM_SRV_MNT}" ]; then - set -- --fsdev local,id=var-srv,path=${VM_SRV_MNT},security_model=mapped,readonly "$@" + set -- --fsdev local,id=var-srv,path="${VM_SRV_MNT}",security_model=mapped,readonly "$@" ign_var_srv_mount=',{ "name": "var-srv.mount", "enabled": true, @@ -100,7 +102,7 @@ fi if [ -z "${IGNITION_CONFIG_FILE:-}" ]; then f=$(mktemp) - cat > ${f} < "${f}" <${f} - rm -f ${f} + exec 3<>"${f}" + rm -f "${f}" IGNITION_CONFIG_FILE=/proc/self/fd/3 - if ! ignition-validate ${IGNITION_CONFIG_FILE}; then + if ! ignition-validate "${IGNITION_CONFIG_FILE}"; then cat "${IGNITION_CONFIG_FILE}" exit 1 fi @@ -157,7 +159,7 @@ fi set -- -fw_cfg name=opt/com.coreos/config,file="${IGNITION_CONFIG_FILE}" "$@" if [ -n "${SSH_PORT}" ]; then - hostfwd=",hostfwd=tcp::"${SSH_PORT}"-:22" + hostfwd=",hostfwd=tcp::${SSH_PORT}-:22" fi if [ "${VM_PERSIST}" = 0 ]; then @@ -165,10 +167,10 @@ if [ "${VM_PERSIST}" = 0 ]; then vm_drive_args=",cache=unsafe" fi -set -- -drive if=virtio${vm_drive_args:-},file=${VM_DISK} "$@" +set -- -drive if=virtio"${vm_drive_args:-}",file="${VM_DISK}" "$@" -exec qemu-kvm -name coreos -m ${VM_MEMORY} -nographic \ - -netdev user,id=eth0,hostname=coreos${hostfwd:-} \ +exec qemu-kvm -name coreos -m "${VM_MEMORY}" -nographic \ + -netdev user,id=eth0,hostname=coreos"${hostfwd:-}" \ -device virtio-net-pci,netdev=eth0 \ -object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-pci,rng=rng0 \ "$@" diff --git a/src/cmd-shell b/src/cmd-shell index 16580fb085..54988ae486 100755 --- a/src/cmd-shell +++ b/src/cmd-shell @@ -1,6 +1,6 @@ #!/usr/bin/env bash -if [[ -z "$@" ]]; then +if [ $# -eq 0 ]; then # If no arguments then offer user bash prompt inside the container exec /usr/bin/env PS1='[coreos-assembler]$ ' /usr/bin/bash else diff --git a/src/cmdlib.sh b/src/cmdlib.sh index a7bf4245f0..db75ad7c7c 100755 --- a/src/cmdlib.sh +++ b/src/cmdlib.sh @@ -1,9 +1,10 @@ +#!/usr/bin/env bash # Shared shell script library -DIR=$(dirname $0) +DIR=$(dirname "$0") info() { - echo "info: $@" 1>&2 + echo "info: $*" 1>&2 } fatal() { @@ -31,21 +32,25 @@ has_privileges() { preflight() { # Verify we have all dependencies - local deps=$(grep -v '^#' /usr/lib/coreos-assembler/deps.txt) + local deps + deps=$(grep -v '^#' /usr/lib/coreos-assembler/deps.txt) # Explicitly check the packages in one rpm -q to avoid # overhead, only drop down to individual calls if that fails. # We use --whatprovides so we handle file paths too. + # + # We actually want this var to be split on words + # shellcheck disable=SC2086 if ! rpm -q --whatprovides ${deps} &>/dev/null; then local missing="" for dep in ${deps}; do - if ! rpm -q --whatprovides "${dep}" &>/dev/null; then + if ! rpm -q --whatprovides ${dep} &>/dev/null; then missing="$missing $dep" fi done - fatal "Failed to find expected dependencies:$missing" + fatal "Failed to find expected dependencies: $missing" fi - if [ $(stat -f --printf="%T" .) = "overlayfs" ]; then + if [ "$(stat -f --printf="%T" .)" = "overlayfs" ]; then fatal "$(pwd) must be a volume" fi @@ -61,7 +66,7 @@ preflight() { else sudo rm -f /dev/kvm sudo mknod /dev/kvm c 10 232 - sudo setfacl -m u:$USER:rw /dev/kvm + sudo setfacl -m u:"$USER":rw /dev/kvm fi fi } @@ -74,9 +79,10 @@ prepare_build() { fatal "No cache.qcow2 found; did you run coreos-assembler init?" fi - export workdir=$(pwd) - export configdir=${workdir}/src/config - export manifest=${configdir}/manifest.yaml + workdir="$(pwd)" + configdir=${workdir}/src/config + manifest=${configdir}/manifest.yaml + export workdir configdir manifest if ! [ -f "${manifest}" ]; then fatal "Failed to find ${manifest}" @@ -85,30 +91,33 @@ prepare_build() { echo "Using manifest: ${manifest}" manifest_tmp_json=${workdir}/tmp/manifest.json - rpm-ostree compose tree --repo=repo --print-only ${manifest} > ${manifest_tmp_json} + rpm-ostree compose tree --repo=repo --print-only "${manifest}" > "${manifest_tmp_json}" # Abuse the rojig/name as the name of the VM images - export name=$(jq -r '.rojig.name' < ${manifest_tmp_json}) + name=$(jq -r '.rojig.name' < "${manifest_tmp_json}") # TODO - allow this to be unset - export ref=$(jq -r '.ref' < ${manifest_tmp_json}) - rm -f ${manifest_tmp_json} + ref=$(jq -r '.ref' < "${manifest_tmp_json}") + export name ref + rm -f "${manifest_tmp_json}" # This dir is no longer used rm builds/work -rf # Be nice to people who have older versions that # didn't create this in `init`. - mkdir -p ${workdir}/tmp + mkdir -p "${workdir}"/tmp # Needs to be absolute for rpm-ostree today - export changed_stamp=$(pwd)/tmp/treecompose.changed + changed_stamp=$(pwd)/tmp/treecompose.changed + export changed_stamp # Allocate temporary space for this build tmp_builddir=${workdir}/tmp/build - rm ${tmp_builddir} -rf - mkdir ${tmp_builddir} + rm "${tmp_builddir}" -rf + mkdir "${tmp_builddir}" # And everything after this assumes it's in the temp builddir - cd ${tmp_builddir} + # In case `cd` fails: https://github.com/koalaman/shellcheck/wiki/SC2164 + cd "${tmp_builddir}" || exit # *This* tmp directory is truly temporary to this build, and # contains artifacts we definitely don't want to outlive it, unlike # other things in ${workdir}/tmp. But we don't export it since e.g. if it's @@ -119,13 +128,13 @@ prepare_build() { runcompose() { # Implement support for automatic local overrides: # https://github.com/coreos/coreos-assembler/issues/118 - local overridesdir=${workdir}/overrides/ - if [ -d ${overridesdir}/rpm ]; then - (cd ${overridesdir}/rpm && createrepo_c .) + local overridesdir=${workdir}/overrides + if [ -d "${overridesdir}"/rpm ]; then + (cd "${overridesdir}"/rpm && createrepo_c .) echo "Using RPM overrides from: ${overridesdir}/rpm" local tmp_overridesdir=${TMPDIR}/override - mkdir ${tmp_overridesdir} - cat > ${tmp_overridesdir}/coreos-assembler-override-manifest.yaml < "${tmp_overridesdir}"/coreos-assembler-override-manifest.yaml < ${tmp_overridesdir}/coreos-assembler-local-overrides.repo < "${tmp_overridesdir}"/coreos-assembler-local-overrides.repo < ${workdir}/tmp/rc /sbin/fstrim -v ${workdir}/cache /sbin/reboot -f EOF - chmod a+x ${vmpreparedir}/init - (cd ${vmpreparedir} && tar -czf init.tar.gz --remove-files init) + chmod a+x "${vmpreparedir}"/init + (cd "${vmpreparedir}" && tar -czf init.tar.gz --remove-files init) supermin --build "${vmpreparedir}" --size 5G -f ext2 -o "${vmbuilddir}" touch "${vmbuilddir}/.done" fi - echo "$@" > ${TMPDIR}/cmd.sh + echo "$@" > "${TMPDIR}"/cmd.sh # support local dev cases where src/config is a symlink srcvirtfs= @@ -216,10 +224,10 @@ EOF -drive if=none,id=drive-scsi0-0-0-1,discard=unmap,file="${workdir}/cache/cache.qcow2" \ -device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=1,drive=drive-scsi0-0-0-1,id=scsi0-0-0-1 \ -virtfs local,id=workdir,path="${workdir}",security_model=none,mount_tag=workdir \ - ${srcvirtfs} -serial stdio -append "root=/dev/sda console=ttyS0 selinux=1 enforcing=0 autorelabel=1" + "${srcvirtfs}" -serial stdio -append "root=/dev/sda console=ttyS0 selinux=1 enforcing=0 autorelabel=1" - if [ ! -f ${workdir}/tmp/rc ]; then + if [ ! -f "${workdir}"/tmp/rc ]; then fatal "Couldn't find rc file, something went terribly wrong!" fi - return $(cat ${workdir}/tmp/rc) + return "$(cat "${workdir}"/tmp/rc)" } diff --git a/src/gf-oemid b/src/gf-oemid index 6640890d40..0e48985813 100755 --- a/src/gf-oemid +++ b/src/gf-oemid @@ -1,9 +1,11 @@ #!/usr/bin/env bash -set -xeuo pipefail +set -euo pipefail -dn=$(dirname $0) -. ${dn}/cmdlib.sh -. ${dn}/libguestfish.sh +dn=$(dirname "$0") +# shellcheck source=src/cmdlib.sh +. "${dn}"/cmdlib.sh +# shellcheck source=src/libguestfish.sh +. "${dn}"/libguestfish.sh # Usage: gf-oemid OEMID # Example: gf-oemid fedora-coreos.qcow2 fedora-coreos-aws.qcow2 ec2 @@ -12,15 +14,16 @@ dn=$(dirname $0) # be used for Ignition. It's much faster to do this than generate a fresh image # for each provider (and also helps ensure the images are otherwise identical). -src=$1 -dest=$2 -oemid=$3 +src="$1" +dest="$2" +oemid="$3" +set -x tmpd=$(mktemp -td gf-oemid.XXXXXX) tmp_dest=${tmpd}/box.img -cp --reflink=auto ${src} ${tmp_dest} +cp --reflink=auto "${src}" "${tmp_dest}" # I commonly chmod a-w VM images -chmod u+w ${tmp_dest} +chmod u+w "${tmp_dest}" coreos_gf_run_mount "${tmp_dest}" @@ -29,21 +32,21 @@ coreos_gf_run_mount "${tmp_dest}" # * BLS config (for subsequent config regeneration) # First, the grub config. grubcfg_path=/boot/loader/grub.cfg -coreos_gf download ${grubcfg_path} ${tmpd}/grub.cfg +coreos_gf download "${grubcfg_path}" "${tmpd}"/grub.cfg # Remove any oemid currently there -sed -i -e 's, coreos.oem.id=[a-zA-Z0-9]*,,g' ${tmpd}/grub.cfg +sed -i -e 's, coreos.oem.id=[a-zA-Z0-9]*,,g' "${tmpd}"/grub.cfg # Insert our new oemid -sed -i -e 's,^\(linux16 .*\),\1 coreos.oem.id='${oemid}',' ${tmpd}/grub.cfg -coreos_gf upload ${tmpd}/grub.cfg ${grubcfg_path} +sed -i -e 's,^\(linux16 .*\),\1 coreos.oem.id='"${oemid}"',' "${tmpd}"/grub.cfg +coreos_gf upload "${tmpd}"/grub.cfg "${grubcfg_path}" # Now the BLS version blscfg_path=$(coreos_gf glob-expand /boot/loader/entries/ostree-*.conf) -coreos_gf download ${blscfg_path} ${tmpd}/bls.conf +coreos_gf download "${blscfg_path}" "${tmpd}"/bls.conf # Remove any oemid currently there -sed -i -e 's, coreos.oem.id=[a-zA-Z0-9]*,,g' ${tmpd}/bls.conf -sed -i -e 's,^\(options .*\),\1 coreos.oem.id='${oemid}',' ${tmpd}/bls.conf -coreos_gf upload ${tmpd}/bls.conf ${blscfg_path} +sed -i -e 's, coreos.oem.id=[a-zA-Z0-9]*,,g' "${tmpd}"/bls.conf +sed -i -e 's,^\(options .*\),\1 coreos.oem.id='"${oemid}"',' "${tmpd}"/bls.conf +coreos_gf upload "${tmpd}"/bls.conf "${blscfg_path}" coreos_gf_shutdown mv "${tmp_dest}" "${dest}" -rm ${tmpd} -rf +rm "${tmpd}" -rf diff --git a/src/libguestfish.sh b/src/libguestfish.sh index 32b64cff9a..4691eda6b9 100755 --- a/src/libguestfish.sh +++ b/src/libguestfish.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env bash # Helper library for using libguestfs on CoreOS-style images. # A major assumption here is that the disk image uses OSTree # and also has `boot` and `root` filesystem labels. @@ -15,7 +16,7 @@ coreos_gf_launch() { guestfish[3]="-a" guestfish[4]="${src}" - eval $("${guestfish[@]}") + eval "$("${guestfish[@]}")" if [ -z "$GUESTFISH_PID" ]; then fatal "guestfish didn't start up, see error messages above" fi @@ -35,14 +36,17 @@ coreos_gf() { coreos_gf_run_mount() { coreos_gf_launch "$@" coreos_gf run - local root=$(coreos_gf findfs-label root) + local root + root=$(coreos_gf findfs-label root) coreos_gf mount "${root}" / - local boot=$(coreos_gf findfs-label boot) + local boot + boot=$(coreos_gf findfs-label boot) coreos_gf mount "${boot}" /boot # Export these variables for further use stateroot=/ostree/deploy/$(coreos_gf ls /ostree/deploy) - deploydir=${stateroot}/deploy/$(coreos_gf ls ${stateroot}/deploy | grep -v \.origin) + deploydir="${stateroot}"/deploy/$(coreos_gf ls "${stateroot}"/deploy | grep -v \.origin) + export stateroot deploydir } # Cleanly unmount all filesystems and terminate the helper VM. diff --git a/src/supermin-init-prelude.sh b/src/supermin-init-prelude.sh index d7ed5b40bd..8f468b6e9e 100644 --- a/src/supermin-init-prelude.sh +++ b/src/supermin-init-prelude.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env bash mount -t proc /proc /proc mount -t sysfs /sys /sys mount -t devtmpfs devtmpfs /dev @@ -15,13 +16,14 @@ LANG=C /sbin/load_policy -i /usr/sbin/dhclient eth0 # set up workdir -mkdir -p ${workdir} -mount -t 9p -o rw,trans=virtio,version=9p2000.L workdir ${workdir} -if [ -L ${workdir}/src/config ]; then - mkdir -p $(readlink ${workdir}/src/config) - mount -t 9p -o rw,trans=virtio,version=9p2000.L source ${workdir}/src/config +mkdir -p "${workdir:?}" +mount -t 9p -o rw,trans=virtio,version=9p2000.L workdir "${workdir}" +if [ -L "${workdir}"/src/config ]; then + mkdir -p "$(readlink "${workdir}"/src/config)" + mount -t 9p -o rw,trans=virtio,version=9p2000.L source "${workdir}"/src/config fi -mkdir -p ${workdir}/cache -mount /dev/sdb1 ${workdir}/cache +mkdir -p "${workdir}"/cache +mount /dev/sdb1 "${workdir}"/cache -cd ${workdir} +# https://github.com/koalaman/shellcheck/wiki/SC2164 +cd "${workdir}" || exit diff --git a/tests/check.sh b/tests/check.sh index ff1b9b785e..572c305377 100755 --- a/tests/check.sh +++ b/tests/check.sh @@ -1,11 +1,14 @@ #!/usr/bin/bash set -euo pipefail -dn=$(dirname $0) -srcdir=$(cd ${dn}/.. && pwd)/src +dn=$(dirname "$0") +srcdir=$(cd "${dn}"/.. && pwd)/src # Verify syntax for sources -for f in $(find ${srcdir} -type f -executable); do - shebang=$(head -1 $f) +# see https://github.com/koalaman/shellcheck/wiki/SC2044 +# for explanation of this use of while +while IFS= read -r -d '' f +do + shebang=$(head -1 "$f") if [[ $shebang =~ ^#!/.*/python ]]; then python3 -m py_compile "${f}" echo "OK ${f}" @@ -16,4 +19,4 @@ for f in $(find ${srcdir} -type f -executable); do echo "OK ${f}" continue fi -done +done < <(find "${srcdir}" -type f -executable -print0)