diff --git a/Makefile b/Makefile index 7a3800c..01c22b8 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,12 @@ DSTREAM_DL_URL ?= http://${HOSTNAME}:8000/update pipelines := common koji release watcher +common_CHECKOPTS := --exclude=2034,2164 common_SRC := $(wildcard *.sh) koji_SRC := $(wildcard $(CURDIR)/koji/*.sh) +release_CHECKOPTS := --exclude=2013,2024,2155 release_SRC := $(wildcard $(CURDIR)/release/*.sh) watcher_SRC := $(wildcard $(CURDIR)/watcher/*.sh) @@ -45,6 +47,6 @@ serve: ${STAGING_DIR} check_PIPELINES = $(addprefix check-,$(pipelines)) $(check_PIPELINES): pipe = $(patsubst check-%,%,$@) $(check_PIPELINES): - shellcheck $($(pipe)_CHECKOPTS) $($(pipe)_SRC) + shellcheck -x $($(pipe)_CHECKOPTS) $($(pipe)_SRC) check: $(check_PIPELINES) diff --git a/common.sh b/common.sh index 5e8c257..7e703e7 100755 --- a/common.sh +++ b/common.sh @@ -20,7 +20,7 @@ log_line() { # ${2} - extra indentation local indent=${1:+$(( (${LOG_INDENT:-0} + ${2:-0}) * 4 ))} - printf "${LOG_DOMAIN:+"[${LOG_DOMAIN}] "}%${indent}s%s\n" "" "${1}" + printf "${LOG_DOMAIN:+"[${LOG_DOMAIN}] "}%${indent}s%s\\n" "" "${1}" } log() { @@ -31,7 +31,7 @@ log() { if (( $# < 2 )); then log_line "${1}" else - log_line "${1}:" ${3} + log_line "${1}:" "${3}" log_line "${2}" $((${3:-0} + 1)) fi } @@ -46,15 +46,15 @@ section() { } error() { - log "[ERROR] ${1}" ${2:+"${2}"} ${3} + log "[ERROR] ${1}" ${2:+"${2}"} "${3}" } info() { - log "[INFO] ${1}" ${2:+"${2}"} ${3} + log "[INFO] ${1}" ${2:+"${2}"} "${3}" } warn() { - log "[WARN] ${1}" ${2:+"${2}"} ${3} + log "[WARN] ${1}" ${2:+"${2}"} "${3}" } run_and_log() { @@ -68,7 +68,7 @@ run_and_log() { local log_err="${2}_err.log" local log_dir=${LOG_DIR:-"./logs"} - mkdir -p ${log_dir} + mkdir -p "${log_dir}" # Log to file if [[ "${LOG_METHOD}" -eq 0 ]]; then @@ -88,15 +88,15 @@ run_and_log() { # ================= curl() { - command curl --silent --fail $@ + command curl --silent --fail "$@" } koji_cmd() { # Downloads fail sometime, try harder! local result="" local ret=1 - for (( i=0; $i < 10; i++ )); do - result=$(koji ${@} 2> /dev/null) \ + for (( i=0; i < 10; i++ )); do + result=$(koji "${@}" 2> /dev/null) \ || continue ret=0 @@ -108,7 +108,7 @@ koji_cmd() { } assert_dep () { - command -v $1 > /dev/null 2>&1 || { error "command '$1' not found"; exit 1; } + command -v "$1" > /dev/null 2>&1 || { error "command '$1' not found"; exit 1; } } assert_dir () { @@ -120,10 +120,10 @@ assert_file() { } silentkill () { - if [ ! -z $2 ]; then - kill $2 $1 > /dev/null 2>&1 || true + if [ ! -z "$2" ]; then + kill "$2" "$1" > /dev/null 2>&1 || true else - kill -KILL $1 > /dev/null 2>&1 || true + kill -KILL "$1" > /dev/null 2>&1 || true fi } @@ -134,7 +134,7 @@ fetch_config_repo() { local REPO_HOST=${CONFIG_REPO_HOST:?"CONFIG_REPO_HOST cannot be Null/Unset"} local REPO_NAME=${NAMESPACE:?"NAMESPACE cannot be Null/Unset"} log_line "Cloning..." 1 - git clone --quiet ${REPO_HOST}${REPO_NAME} config + git clone --quiet "${REPO_HOST}${REPO_NAME}" config log_line "OK!" 2 else log_line "Updating..." 1 @@ -165,13 +165,13 @@ var_save() { # "unsave" if [[ ! -v ${1} ]]; then - rm -f ${VARS_DIR}/${1} + rm -f "${VARS_DIR}/${1}" return 0 fi - [[ -d ${VARS_DIR} ]] || mkdir -p ${VARS_DIR} + [[ -d ${VARS_DIR} ]] || mkdir -p "${VARS_DIR}" - echo "${!1}" > ${VARS_DIR}/${1} + echo "${!1}" > "${VARS_DIR}/${1}" } var_load() { @@ -180,17 +180,18 @@ var_load() { return 1 fi - [[ -f ${VARS_DIR}/${1} ]] && declare -g ${1}="$(cat ${VARS_DIR}/${1})" || true + # shellcheck disable=2015 + [[ -f ${VARS_DIR}/${1} ]] && declare -g "${1}"="$(cat "${VARS_DIR}/${1}")" || true } get_upstream_version() { - CLR_LATEST=${CLR_LATEST:-$(curl ${CLR_PUBLIC_DL_URL}/latest)} || true + CLR_LATEST=${CLR_LATEST:-$(curl "${CLR_PUBLIC_DL_URL}/latest")} || true if [[ -z $CLR_LATEST ]]; then error "Failed to fetch Clear Linux latest version." exit 2 fi - CLR_FORMAT=$(curl ${CLR_PUBLIC_DL_URL}/update/${CLR_LATEST}/format) || true + CLR_FORMAT=$(curl "${CLR_PUBLIC_DL_URL}/update/${CLR_LATEST}/format") || true if [[ -z $CLR_FORMAT ]]; then error "Failed to fetch Clear Linux latest format." exit 2 @@ -198,7 +199,7 @@ get_upstream_version() { } get_downstream_version() { - DS_LATEST=$(cat ${STAGING_DIR}/latest 2>/dev/null) || true + DS_LATEST=$(cat "${STAGING_DIR}/latest" 2>/dev/null) || true if [[ -z $DS_LATEST ]]; then info "Failed to fetch Downstream latest version. First Mix?" DS_FORMAT=${CLR_FORMAT:-1} @@ -206,7 +207,7 @@ get_downstream_version() { error "Downstream Clear Linux version number seems corrupted." exit 2 else - DS_FORMAT=$(cat ${STAGING_DIR}/update/${DS_LATEST}/format 2>/dev/null) || true + DS_FORMAT=$(cat "${STAGING_DIR}/update/${DS_LATEST}/format" 2>/dev/null) || true if [[ -z $DS_FORMAT ]]; then error "Failed to fetch Downstream latest format." exit 2 @@ -215,7 +216,7 @@ get_downstream_version() { DS_UP_VERSION=${DS_LATEST: : -3} DS_DOWN_VERSION=${DS_LATEST: -3} - DS_UP_FORMAT=$(curl ${CLR_PUBLIC_DL_URL}/update/${DS_UP_VERSION}/format) || true + DS_UP_FORMAT=$(curl "${CLR_PUBLIC_DL_URL}/update/${DS_UP_VERSION}/format") || true if [[ -z $DS_UP_FORMAT ]]; then error "Failed to fetch Downstream latest base format." exit 2 @@ -231,9 +232,9 @@ get_latest_versions() { calc_mix_version() { # Compute initial next version (ignoring the need for format bumps) if [[ -z ${DS_LATEST} || ${CLR_LATEST} -gt ${DS_UP_VERSION} ]]; then - MIX_VERSION=$((${CLR_LATEST} * 1000 + ${MIX_INCREMENT})) + MIX_VERSION=$((CLR_LATEST * 1000 + MIX_INCREMENT)) elif [[ ${CLR_LATEST} -eq ${DS_UP_VERSION} ]]; then - MIX_VERSION=$((${DS_LATEST} + ${MIX_INCREMENT})) + MIX_VERSION=$((DS_LATEST + MIX_INCREMENT)) if [[ ${MIX_VERSION: -3} -eq 000 ]]; then error "Invalid Mix Version" \ "No more Downstream versions available for this Upstream version!" diff --git a/koji/update_external_repo.sh b/koji/update_external_repo.sh index e10a1fe..bb0cd4d 100755 --- a/koji/update_external_repo.sh +++ b/koji/update_external_repo.sh @@ -2,12 +2,15 @@ # Copyright (C) 2018 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +# shellcheck source=globals.sh +# shellcheck source=common.sh + set -e -SCRIPT_DIR=$(dirname $(realpath ${BASH_SOURCE[0]})) +SCRIPT_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")") -. ${SCRIPT_DIR}/../globals.sh -. ${SCRIPT_DIR}/../common.sh +. "${SCRIPT_DIR}/../globals.sh" +. "${SCRIPT_DIR}/../common.sh" KOJI_TAG=${KOJI_TAG:-"dist-clear"} repo_name="dist-clear-external-repo" @@ -20,7 +23,7 @@ current_version=${current_version%%${repo_suffix}} get_upstream_version -(( ${CLR_LATEST} <= ${current_version} )) && exit 0 +(( CLR_LATEST <= current_version )) && exit 0 koji edit-external-repo --url="${repo_prefix}${CLR_LATEST}${repo_suffix}" ${repo_name} -koji regen-repo ${KOJI_TAG}-build +koji regen-repo "${KOJI_TAG}-build" diff --git a/release/content.sh b/release/content.sh index 90fe2f6..ebd3dd9 100755 --- a/release/content.sh +++ b/release/content.sh @@ -2,12 +2,15 @@ # Copyright (C) 2018 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +# shellcheck source=globals.sh +# shellcheck source=common.sh + set -e -SCRIPT_DIR=$(dirname $(realpath ${BASH_SOURCE[0]})) +SCRIPT_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")") -. ${SCRIPT_DIR}/../globals.sh -. ${SCRIPT_DIR}/../common.sh +. "${SCRIPT_DIR}/../globals.sh" +. "${SCRIPT_DIR}/../common.sh" . ./config/config.sh @@ -18,15 +21,16 @@ stage "Finalizing Content" log_line "Building package list:" # If no content providers fetched packages, this will act as 'touch' -cat ${WORK_DIR}/${PKG_LIST_TMP}* > ${WORK_DIR}/${PKG_LIST_FILE} 2>/dev/null || true +# shellcheck disable=2086 +cat ${WORK_DIR}/${PKG_LIST_TMP}* > "${WORK_DIR}/${PKG_LIST_FILE}" 2>/dev/null || true log_line "OK!" 1 section "Creating Content Repository" -if [[ -z "$(ls -A ${PKGS_DIR})" ]]; then +if [[ -z "$(ls -A "${PKGS_DIR}")" ]]; then info "Custom Content Not Found" " '${PKGS_DIR}' is empty." exit 0 fi log_line # Output too verbose -createrepo_c ${REPO_DIR}/x86_64/os # TODO: log create_repo output and only print its result +createrepo_c "${REPO_DIR}/x86_64/os" # TODO: log create_repo output and only print its result log_line diff --git a/release/images.sh b/release/images.sh index ed797f2..63ff258 100755 --- a/release/images.sh +++ b/release/images.sh @@ -2,13 +2,16 @@ # Copyright (C) 2018 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +# shellcheck source=globals.sh +# shellcheck source=common.sh + set -e -SCRIPT_DIR=$(dirname $(realpath ${BASH_SOURCE[0]})) +SCRIPT_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")") -. ${SCRIPT_DIR}/../globals.sh -. ${SCRIPT_DIR}/../common.sh -. ${SCRIPT_DIR}/../config/config.sh +. "${SCRIPT_DIR}/../globals.sh" +. "${SCRIPT_DIR}/../common.sh" +. "${SCRIPT_DIR}/../config/config.sh" var_load MIX_VERSION @@ -21,7 +24,7 @@ create_image() { # ${1} - File path to image template file local image=${1} local tempdir=$(mktemp -d) - local name=$(basename ${image%.json}) + local name=$(basename "${image%.json}") local ister_log="${LOG_DIR}/ister-${name}.log" local final_file="${IMGS_DIR}/${DSTREAM_NAME}-${MIX_VERSION}-${name}.img.xz" @@ -30,23 +33,23 @@ create_image() { return 1 fi - pushd ${WORK_DIR} > /dev/null - sudo -E ister.py -s ${BUILD_DIR}/Swupd_Root.pem -L debug -S ${tempdir} \ - -C file://${BUILD_DIR}/update/www -V file://${BUILD_DIR}/update/www \ - -f ${format} -t ${image} > ${ister_log} 2>&1 + pushd "${WORK_DIR}" > /dev/null + sudo -E ister.py -s "${BUILD_DIR}/Swupd_Root.pem" -L debug -S "${tempdir}" \ + -C "file://${BUILD_DIR}/update/www" -V "file://${BUILD_DIR}/update/www" \ + -f "${format}" -t "${image}" > "${ister_log}" 2>&1 local ister_ret=$? - sudo rm -rf ${tempdir} + sudo rm -rf "${tempdir}" - if (( ${ister_ret} )) || [[ ! -s "${name}.img" ]]; then + if (( ister_ret )) || [[ ! -s "${name}.img" ]]; then log "Image '${name}'" "Failed. See log below:" echo - cat ${ister_log} + cat "${ister_log}" echo return 1 fi - xz -3 --stdout ${name}.img > ${final_file} - sudo rm ${name}.img + xz -3 --stdout "${name}.img" > "${final_file}" + sudo rm "${name}.img" if [[ ! -s "${final_file}" ]]; then log "Image '${name}'" "Failed to create compressed file." @@ -54,7 +57,7 @@ create_image() { fi # Only publish template files that successfully built an image - cp -a ${image} ${WORK_DIR}/release/config/ + cp -a "${image}" "${WORK_DIR}/release/config/" popd > /dev/null log "Image '${name}'" "OK!" @@ -62,11 +65,11 @@ create_image() { parallel_fn() { # Intended to be used only by GNU Parallel - . ${SCRIPT_DIR}/../globals.sh - . ${SCRIPT_DIR}/../common.sh - . ${SCRIPT_DIR}/../config/config.sh + . "${SCRIPT_DIR}/../globals.sh" + . "${SCRIPT_DIR}/../common.sh" + . "${SCRIPT_DIR}/../config/config.sh" - create_image $@ + create_image "$@" } # ============================================================================== @@ -74,6 +77,7 @@ parallel_fn() { # ============================================================================== stage "Image Generation" +# shellcheck disable=2086 image_list=$(ls ${TEMPLATES_PATH}/*.json 2>/dev/null || true) if [[ -z "${image_list}" ]]; then warn "Skipping stage." @@ -81,13 +85,13 @@ if [[ -z "${image_list}" ]]; then exit 0 fi -format=$(< ${BUILD_DIR}/update/www/${MIX_VERSION}/format) +format=$(< "${BUILD_DIR}/update/www/${MIX_VERSION}/format") if [[ -z "${format}" ]]; then error "Failed to fetch Downstream current format." exit 1 fi -mkdir -p ${LOG_DIR} +mkdir -p "${LOG_DIR}" export IMGS_DIR export LOG_DIR @@ -97,5 +101,5 @@ export -f create_image export -f parallel_fn export format procs=$(nproc --all) -max_jobs=$(( ${procs:=0} > ${PROCS_PER_IMG} ? ${procs} / ${PROCS_PER_IMG} : 1 )) -parallel -j ${max_jobs} parallel_fn <<< ${image_list} +max_jobs=$(( ${procs:=0} > PROCS_PER_IMG ? procs / PROCS_PER_IMG : 1 )) +parallel -j ${max_jobs} parallel_fn <<< "${image_list}" diff --git a/release/koji.sh b/release/koji.sh index 7b3779d..b0151fa 100755 --- a/release/koji.sh +++ b/release/koji.sh @@ -2,12 +2,15 @@ # Copyright (C) 2018 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +# shellcheck source=globals.sh +# shellcheck source=common.sh + set -e -SCRIPT_DIR=$(dirname $(realpath ${BASH_SOURCE[0]})) +SCRIPT_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")") -. ${SCRIPT_DIR}/../globals.sh -. ${SCRIPT_DIR}/../common.sh +. "${SCRIPT_DIR}/../globals.sh" +. "${SCRIPT_DIR}/../common.sh" . ./config/config.sh @@ -19,8 +22,8 @@ stage "Content Provider - Koji" pkg_list="${WORK_DIR}/${PKG_LIST_TMP}koji" log_line "Fetching Package List:" -if result=$(koji_cmd list-tagged --latest --quiet ${KOJI_TAG}); then - awk '{print $1}' <<< ${result} > ${pkg_list} +if result=$(koji_cmd list-tagged --latest --quiet "${KOJI_TAG}"); then + awk '{print $1}' <<< "${result}" > "${pkg_list}" else log_line "No custom content was found." 1 exit 0 @@ -28,10 +31,10 @@ fi log_line "OK!" 1 section "Downloading RPMs" -pushd ${PKGS_DIR} > /dev/null -for rpm in $(cat ${pkg_list}); do +pushd "${PKGS_DIR}" > /dev/null +for rpm in $(cat "${pkg_list}"); do log_line "${rpm}:" - koji_cmd download-build -a x86_64 --quiet ${rpm} + koji_cmd download-build -a x86_64 --quiet "${rpm}" log_line "OK!" 1 done popd > /dev/null diff --git a/release/mixer.sh b/release/mixer.sh index cea3e2b..202ba17 100755 --- a/release/mixer.sh +++ b/release/mixer.sh @@ -6,12 +6,16 @@ # DS_BUNDLES: Subset of bundles to be used from downstream (instead of all) # MIN_VERSION: If this build should be a min version +# shellcheck source=globals.sh +# shellcheck source=common.sh +# shellcheck disable=SC2013 + set -e -SCRIPT_DIR=$(dirname $(realpath ${BASH_SOURCE[0]})) +SCRIPT_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")") -. ${SCRIPT_DIR}/../globals.sh -. ${SCRIPT_DIR}/../common.sh +. "${SCRIPT_DIR}/../globals.sh" +. "${SCRIPT_DIR}/../common.sh" . ./config/config.sh @@ -29,7 +33,7 @@ var_load MIX_DOWN_VERSION fetch_bundles() { log_line "Fetching downstream bundles:" rm -rf ./local-bundles - git clone --quiet ${BUNDLES_REPO} local-bundles + git clone --quiet "${BUNDLES_REPO}" local-bundles log_line "OK!" 1 } @@ -42,9 +46,11 @@ build_bundles() { log_line # Add the upstream Bundle definitions for this base version of ClearLinux + # shellcheck disable=SC2086 mixer bundle add ${CLR_BUNDLES:-"--all-upstream"} # Add the downstream Bundle definitions + # shellcheck disable=SC2086 mixer bundle add ${DS_BUNDLES:-"--all-local"} log_line @@ -59,7 +65,7 @@ build_update() { section "Build 'Update' Content" if ${MIN_VERSION:-false}; then - sudo -E mixer --native build update --min-version=${mix_ver} + sudo -E mixer --native build update --min-version="${mix_ver}" else sudo -E mixer --native build update fi @@ -70,7 +76,7 @@ build_deltas() { section "Deltas" if [[ -n "${DS_LATEST}" ]]; then - sudo -E mixer --native build delta-packs --from ${DS_LATEST} --to ${mix_ver} + sudo -E mixer --native build delta-packs --from "${DS_LATEST}" --to "${mix_ver}" else log "Skipping Delta Packs creation" "No previous version was found." fi @@ -92,58 +98,58 @@ generate_bump() { # Ghost Build (+10) # Set the Mix Format section "Building +10" - sed -i -E -e "s/(FORMAT = )(.*)/\1\"${mix_format}\"/" mixer.state + sed -i -E -e "s/(FORMAT = )(.*)/\\1\"${mix_format}\"/" mixer.state # Set Upstream and Mix versions - mixer versions update --clear-version ${clear_ver} --mix-version ${mix_ver} + mixer versions update --clear-version "${clear_ver}" --mix-version "${mix_ver}" build_bundles # Delete deprecated bundles section "Bundle Deletion" - for i in $(grep -lir "\[STATUS\]: Deprecated" upstream-bundles/ local-bundles/); do - b=$(basename $i) + for i in $(grep -lir "\\[STATUS\\]: Deprecated" upstream-bundles/ local-bundles/); do + b=$(basename "$i") log "Deleting" "${b}" - sudo -E rm -f update/image/${mix_ver}/${b}-info - sudo -E mkdir -p update/image/${mix_ver}/${b} + sudo -E rm -f "update/image/${mix_ver}/${b}-info" + sudo -E mkdir -p "update/image/${mix_ver}/${b}" done # TODO # Fake version and format - sudo -E sed -i -E -e "s/(VERSION_ID=)(.*)/\1\"${mix_ver_next}\"/" \ - ${BUILD_DIR}/update/image/${mix_ver}/full/usr/lib/os-release - echo -n ${mix_ver_next} | sudo -E \ - tee ${BUILD_DIR}/update/image/${mix_ver}/full/usr/share/clear/version > /dev/null - echo -n ${mix_format_next} | sudo -E \ - tee ${BUILD_DIR}/update/image/${mix_ver}/full/usr/share/defaults/swupd/format > /dev/null + sudo -E sed -i -E -e "s/(VERSION_ID=)(.*)/\\1\"${mix_ver_next}\"/" \ + "${BUILD_DIR}/update/image/${mix_ver}/full/usr/lib/os-release" + echo -n "${mix_ver_next}" | sudo -E \ + tee "${BUILD_DIR}/update/image/${mix_ver}/full/usr/share/clear/version" > /dev/null + echo -n "${mix_format_next}" | sudo -E \ + tee "${BUILD_DIR}/update/image/${mix_ver}/full/usr/share/defaults/swupd/format" > /dev/null - build_update ${mix_ver} + build_update "${mix_ver}" - build_deltas ${mix_ver} + build_deltas "${mix_ver}" # Bumped Build (+20) # Set the Mix Format section "Building +20" - sed -i -E -e "s/(FORMAT = )(.*)/\1\"${mix_format_next}\"/" mixer.state + sed -i -E -e "s/(FORMAT = )(.*)/\\1\"${mix_format_next}\"/" mixer.state # Set Upstream and Mix versions - mixer versions update --clear-version ${clear_ver_next} --mix-version ${mix_ver_next} --offline + mixer versions update --clear-version "${clear_ver_next}" --mix-version "${mix_ver_next}" --offline # Delete deprecated bundles again section "Bundle Deletion" - for i in $(grep -lir "\[STATUS\]: Deprecated" upstream-bundles/ local-bundles/); do - b=$(basename $i) + for i in $(grep -lir "\\[STATUS\\]: Deprecated" upstream-bundles/ local-bundles/); do + b=$(basename "$i") log "Deleting" "${b}" - mixer bundle remove ${b} - sudo -E sed -i -E -e "/\[${b}\]/d;/group=${b}/d" ${BUILD_DIR}/update/groups.ini + mixer bundle remove "${b}" + sudo -E sed -i -E -e "/\\[${b}\\]/d;/group=${b}/d" "${BUILD_DIR}/update/groups.ini" done #TODO: Maybe also delete from bundles repository? # "build bundles" section "Fake Build Bundles" - sudo -E cp -al ${BUILD_DIR}/update/image/${mix_ver} ${BUILD_DIR}/update/image/${mix_ver_next} + sudo -E cp -al "${BUILD_DIR}/update/image/${mix_ver}" "${BUILD_DIR}/update/image/${mix_ver_next}" - MIN_VERSION=true build_update ${mix_ver_next} + MIN_VERSION=true build_update "${mix_ver_next}" - echo -n ${mix_ver_next} | sudo -E tee update/latest > /dev/null + echo -n "${mix_ver_next}" | sudo -E tee update/latest > /dev/null } generate_mix() { @@ -157,28 +163,28 @@ generate_mix() { local mix_format="$3" # Set the Mix Format - sed -i -E -e "s/(FORMAT = )(.*)/\1\"${mix_format}\"/" mixer.state + sed -i -E -e "s/(FORMAT = )(.*)/\\1\"${mix_format}\"/" mixer.state # Set Upstream and Mix versions - mixer versions update --clear-version ${clear_ver} --mix-version ${mix_ver} + mixer versions update --clear-version "${clear_ver}" --mix-version "${mix_ver}" build_bundles - build_update ${mix_ver} + build_update "${mix_ver}" - build_deltas ${mix_ver} + build_deltas "${mix_ver}" - echo -n ${mix_ver} | sudo -E tee update/latest > /dev/null + echo -n "${mix_ver}" | sudo -E tee update/latest > /dev/null } # ============================================================================== # MAIN # ============================================================================== stage Mixer -pushd ${BUILD_DIR} > /dev/null +pushd "${BUILD_DIR}" > /dev/null section "Bootstrapping Mix Workspace" -mixer init --upstream-url ${CLR_PUBLIC_DL_URL} +mixer init --upstream-url "${CLR_PUBLIC_DL_URL}" mixer config set Swupd.CONTENTURL "${DSTREAM_DL_URL}/update" mixer config set Swupd.VERSIONURL "${DSTREAM_DL_URL}/update" @@ -186,53 +192,57 @@ log_line "Looking for previous releases:" if [[ -z ${DS_LATEST} ]]; then log_line "None found. This will be the first Mix!" 1 DS_UP_FORMAT=${CLR_FORMAT} + # shellcheck disable=SC2034 DS_UP_VERSION=${CLR_LATEST} + + var_save DS_UP_FORMAT + var_save DS_UP_VERSION fi section "Preparing Downstream Content" fetch_bundles # Download the Downstream Bundles Repository log_line "Checking Downstream Repo:" -if [[ -n "$(ls -A ${PKGS_DIR})" ]];then - mixer repo set-url content file://${REPO_DIR}/x86_64/os > /dev/null +if [[ -n "$(ls -A "${PKGS_DIR}")" ]];then + mixer repo set-url content "file://${REPO_DIR}/x86_64/os" > /dev/null log_line "Content found. Adding it to the mix!" 1 else log_line "Content not found. Skipping it." 1 fi section "Building" -format_bumps=$(( ${CLR_FORMAT} - ${DS_UP_FORMAT} )) -(( ${format_bumps} )) && info "Format Bumps will be needed" +format_bumps=$(( CLR_FORMAT - DS_UP_FORMAT )) +(( format_bumps )) && info "Format Bumps will be needed" #TODO: Check for required mixer version for the bump here -for (( bump=0 ; bump < ${format_bumps} ; bump++ )); do - section "Format Bump: $(( ${bump} + 1 )) of ${format_bumps}" +for (( bump=0 ; bump < format_bumps ; bump++ )); do + section "Format Bump: $(( bump + 1 )) of ${format_bumps}" - ds_fmt=$(( ${DS_FORMAT} + ${bump} )) - ds_fmt_next=$(( ${ds_fmt} + 1 )) + ds_fmt=$(( DS_FORMAT + bump )) + ds_fmt_next=$(( ds_fmt + 1 )) log "Downstream Format" "From: ${ds_fmt} To: ${ds_fmt_next}" - up_fmt=$(( ${DS_UP_FORMAT} + ${bump} )) - up_fmt_next=$(( ${up_fmt} + 1 )) + up_fmt=$(( DS_UP_FORMAT + bump )) + up_fmt_next=$(( up_fmt + 1 )) log "Upstream Format" "From: ${up_fmt} To: ${up_fmt_next}" # Get the First version for Upstream Next Format - up_ver_next=$(curl ${CLR_PUBLIC_DL_URL}/update/version/format${up_fmt_next}/first) || true + up_ver_next=$(curl "${CLR_PUBLIC_DL_URL}/update/version/format${up_fmt_next}/first") || true if [[ -z ${up_ver_next} ]]; then error "Failed to get First version for Upstream Format: ${up_fmt_next}!" exit 2 fi # Calculate the matching Downstream version - ds_ver_next=$(( ${up_ver_next} * 1000 + ${MIX_INCREMENT} * 2 )) + ds_ver_next=$(( up_ver_next * 1000 + MIX_INCREMENT * 2 )) # Get the Latest version for Upstream "current" Format - up_ver=$(curl ${CLR_PUBLIC_DL_URL}/update/version/format${up_fmt}/latest) || true + up_ver=$(curl "${CLR_PUBLIC_DL_URL}/update/version/format${up_fmt}/latest") || true if [[ -z ${up_ver} ]]; then error "Failed to get Latest version for Upstream Format: ${up_fmt}." exit 2 fi # Calculate the matching Downstream version - ds_ver=$(( ${up_ver} * 1000 + ${MIX_INCREMENT} )) + ds_ver=$(( up_ver * 1000 + MIX_INCREMENT )) log "+10 Mix:" "${ds_ver} (${ds_fmt}) based on: ${up_ver} (${up_fmt})" log "+20 Mix:" "${ds_ver_next} (${ds_fmt_next}) based on: ${up_ver_next} (${up_fmt_next})" @@ -250,7 +260,9 @@ if [[ -z "${ds_ver_next}" || "${MIX_VERSION}" -gt "${ds_ver_next}" ]]; then generate_mix "${CLR_LATEST}" "${MIX_VERSION}" "${DS_FORMAT}" else MIX_VERSION=${ds_ver_next} + # shellcheck disable=SC2034 MIX_UP_VERSION=${MIX_VERSION: : -3} + # shellcheck disable=SC2034 MIX_DOWN_VERSION=${MIX_VERSION: -3} var_save MIX_VERSION diff --git a/release/prologue.sh b/release/prologue.sh index 74e8367..fcbce9f 100755 --- a/release/prologue.sh +++ b/release/prologue.sh @@ -6,12 +6,16 @@ # CLR_BUNDLES: Subset of bundles to be used from upstream (instead of all) # DS_BUNDLES: Subset of bundles to be used from downstream (instead of all) # MIN_VERSION: If this build should be a min version + +# shellcheck source=globals.sh +# shellcheck source=common.sh + set -e -SCRIPT_DIR=$(dirname $(realpath ${BASH_SOURCE[0]})) +SCRIPT_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")") -. ${SCRIPT_DIR}/../globals.sh -. ${SCRIPT_DIR}/../common.sh +. "${SCRIPT_DIR}/../globals.sh" +. "${SCRIPT_DIR}/../common.sh" stage "PROLOGUE" log_line "Sanitizing work environment..." @@ -19,19 +23,19 @@ log_line "Sanitizing work environment..." LOG_INDENT=1 fetch_config_repo . ./config/config.sh -rm -rf ${WORK_DIR} -mkdir -p ${WORK_DIR}/release/{config,images} -mkdir -p ${PKGS_DIR} +rm -rf "${WORK_DIR}" +mkdir -p "${WORK_DIR}"/release/{config,images} +mkdir -p "${PKGS_DIR}" -mkdir -p ${BUILD_DIR} -rm -rf ${BUILD_DIR}/local-rpms ${BUILD_DIR}/local-yum -mkdir -p ${BUILD_DIR}/local-rpms ${BUILD_DIR}/local-yum +mkdir -p "${BUILD_DIR}" +rm -rf "${BUILD_DIR}/local-rpms" "${BUILD_DIR}/local-yum" +mkdir -p "${BUILD_DIR}/local-rpms" "${BUILD_DIR}/local-yum" -mkdir -p ${STAGING_DIR} +mkdir -p "${STAGING_DIR}" log_line "OK!" 1 -echo "=== Build Environment" > ${WORK_DIR}/${BUILD_FILE} -tee -a ${WORK_DIR}/${BUILD_FILE} < "${WORK_DIR}/${BUILD_FILE}" +tee -a "${WORK_DIR}/${BUILD_FILE}" < %s-%s" ${NN} ${VO} ${RO} ${VN} ${RN}) + pkgs_changed+=$(printf "\\n %s %s-%s -> %s-%s" "${NN}" "${VO}" "${RO}" "${VN}" "${RN}") fi found=true break fi done <<< $old_package_list if ! ${found} ; then - pkgs_added+=$(printf "\n %s %s-%s" ${NN} ${VN} ${RN}) + pkgs_added+=$(printf "\\n %s %s-%s" "${NN}" "${VN}" "${RN}") fi done <<< $new_package_list @@ -68,7 +72,7 @@ calculate_diffs() { fi done <<< $new_package_list if ! ${found} ; then - pkgs_removed+=$(printf "\n %s %s-%s" ${NO} ${VO} ${RO}) + pkgs_removed+=$(printf "\\n %s %s-%s" "${NO}" "${VO}" "${RO}") fi done <<< $old_package_list } @@ -76,7 +80,7 @@ calculate_diffs() { generate_release_notes() { calculate_diffs - local downstream_format=$(< ${BUILD_DIR}/update/www/${MIX_VERSION}/format) + local downstream_format=$(< "${BUILD_DIR}/update/www/${MIX_VERSION}/format") cat > ${RELEASE_NOTES} << EOL Release Notes for ${MIX_VERSION} @@ -104,7 +108,7 @@ ${pkgs_changed:-" None"} EOL } -pushd ${WORK_DIR} > /dev/null +pushd "${WORK_DIR}" > /dev/null echo "Generating Release Notes" generate_release_notes echo " Done!" diff --git a/release/stage.sh b/release/stage.sh index b91fa4c..7fe1d39 100755 --- a/release/stage.sh +++ b/release/stage.sh @@ -2,12 +2,15 @@ # Copyright (C) 2018 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +# shellcheck source=globals.sh +# shellcheck source=common.sh + set -e -SCRIPT_DIR=$(dirname $(realpath ${BASH_SOURCE[0]})) +SCRIPT_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")") -. ${SCRIPT_DIR}/../globals.sh -. ${SCRIPT_DIR}/../common.sh +. "${SCRIPT_DIR}/../globals.sh" +. "${SCRIPT_DIR}/../common.sh" . ./config/config.sh @@ -17,49 +20,49 @@ RELEASE_DIR="${WORK_DIR}/release" stage "Staging Release" -assert_dir ${BUILD_DIR}/local-bundles -assert_dir ${REPO_DIR} -assert_dir ${RELEASE_DIR} -assert_dir ${STAGING_DIR} +assert_dir "${BUILD_DIR}/local-bundles" +assert_dir "${REPO_DIR}" +assert_dir "${RELEASE_DIR}" +assert_dir "${STAGING_DIR}" log_line "Finishing 'release' folder" -mv ${WORK_DIR}/${BUILD_FILE} ${RELEASE_DIR}/${BUILD_FILE}-${MIX_VERSION}.txt -mv ${WORK_DIR}/${PKG_LIST_FILE} ${RELEASE_DIR}/${PKG_LIST_FILE}-${MIX_VERSION}.txt -mv ${WORK_DIR}/${RELEASE_NOTES} ${RELEASE_DIR}/${RELEASE_NOTES}-${MIX_VERSION}.txt -mv ${REPO_DIR}/ ${RELEASE_DIR}/repo/ -cp -a ${BUILD_DIR}/Swupd_Root.pem ${RELEASE_DIR}/config/ +mv "${WORK_DIR}/${BUILD_FILE}" "${RELEASE_DIR}/${BUILD_FILE}-${MIX_VERSION}.txt" +mv "${WORK_DIR}/${PKG_LIST_FILE}" "${RELEASE_DIR}/${PKG_LIST_FILE}-${MIX_VERSION}.txt" +mv "${WORK_DIR}/${RELEASE_NOTES}" "${RELEASE_DIR}/${RELEASE_NOTES}-${MIX_VERSION}.txt" +mv "${REPO_DIR}/" "${RELEASE_DIR}/repo/" +cp -a "${BUILD_DIR}/Swupd_Root.pem" "${RELEASE_DIR}/config/" log_line "OK!" 1 log_line "Staging 'update'" -mkdir -p ${STAGING_DIR}/update/ -rsync -ah ${BUILD_DIR}/update/www/ ${STAGING_DIR}/update/ +mkdir -p "${STAGING_DIR}/update/" +rsync -ah "${BUILD_DIR}/update/www/" "${STAGING_DIR}/update/" log_line "OK!" 1 log_line "Staging 'release'" -mkdir -p ${STAGING_DIR}/releases/${MIX_VERSION} -rsync -ah ${RELEASE_DIR}/ ${STAGING_DIR}/releases/${MIX_VERSION}/ +mkdir -p "${STAGING_DIR}/releases/${MIX_VERSION}" +rsync -ah "${RELEASE_DIR}/" "${STAGING_DIR}/releases/${MIX_VERSION}/" log_line "OK!" 1 -pushd ${STAGING_DIR} > /dev/null +pushd "${STAGING_DIR}" > /dev/null log_line "Updating 'latest' pointers" -cp -a ${BUILD_DIR}/update/latest ./ -ln -sfT ./${MIX_VERSION} ./update/latest -ln -sfT ./${MIX_VERSION} ./releases/latest -ln -sfT ./releases/${MIX_VERSION}/images ./images +cp -a "${BUILD_DIR}/update/latest" ./ +ln -sfT "./${MIX_VERSION}" ./update/latest +ln -sfT "./${MIX_VERSION}" ./releases/latest +ln -sfT "./releases/${MIX_VERSION}/images" ./images popd > /dev/null log_line "OK!" 1 log_line "Fixing permissions and ownership" -sudo -E /usr/bin/chown -R ${USER}:httpd ${STAGING_DIR} +sudo -E /usr/bin/chown -R "${USER}:httpd" "${STAGING_DIR}" log_line "OK!" 1 section "Tagging Repositories" log_line "Workflow Configuration:" -git -C config tag -f ${MIX_VERSION} +git -C config tag -f "${MIX_VERSION}" git -C config push --quiet -f --tags origin log_line "Tag: ${MIX_VERSION}. OK!" 1 log_line "Downstream Bundles Repository:" -git -C ${BUILD_DIR}/local-bundles tag -f ${NAMESPACE:-${DSTREAM_NAME}}-${MIX_VERSION} -git -C ${BUILD_DIR}/local-bundles push --quiet -f --tags origin +git -C "${BUILD_DIR}/local-bundles" tag -f "${NAMESPACE:-${DSTREAM_NAME}}-${MIX_VERSION}" +git -C "${BUILD_DIR}/local-bundles" push --quiet -f --tags origin log_line "Tag: ${NAMESPACE:-${DSTREAM_NAME}}-${MIX_VERSION}. OK!" 1 diff --git a/watcher/watcher.sh b/watcher/watcher.sh index 9d4a037..49d9901 100755 --- a/watcher/watcher.sh +++ b/watcher/watcher.sh @@ -2,6 +2,9 @@ # Copyright (C) 2018 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +# shellcheck source=globals.sh +# shellcheck source=common.sh + set -e # return codes: @@ -9,10 +12,10 @@ set -e # 1 = A new release is needed. Pipeline Unstable. # > 1 = Errors. Pipeline Failure. -SCRIPT_DIR=$(dirname $(realpath ${BASH_SOURCE[0]})) +SCRIPT_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")") -. ${SCRIPT_DIR}/../globals.sh -. ${SCRIPT_DIR}/../common.sh +. "${SCRIPT_DIR}/../globals.sh" +. "${SCRIPT_DIR}/../common.sh" echo "=== Watcher" fetch_config_repo @@ -36,7 +39,7 @@ if [[ -z $DS_LATEST ]]; then fi echo " $DS_UP_VERSION $DS_DOWN_VERSION" -if (($DS_UP_VERSION < $CLR_LATEST)); then +if (( DS_UP_VERSION < CLR_LATEST )); then echo "Upstream has a new release. It's Release Time!" exit 1 fi @@ -47,23 +50,23 @@ TMP_PREV_LIST=$(mktemp) TMP_CURR_LIST=$(mktemp) PKG_LIST_PATH=${STAGING_DIR}/releases/${DS_LATEST}/${PKG_LIST_FILE}-${DS_LATEST}.txt -if ! cat ${PKG_LIST_PATH} > ${TMP_PREV_LIST}; then +if ! cat "${PKG_LIST_PATH}" > "${TMP_PREV_LIST}"; then echo "Wrn: Failed to fetch Downstream PREVIOUS Package List. Assuming empty." fi -if result=$(koji_cmd list-tagged --latest --quiet ${KOJI_TAG}); then - echo "${result}" | awk '{print $1}' > ${TMP_CURR_LIST} +if result=$(koji_cmd list-tagged --latest --quiet "${KOJI_TAG}"); then + echo "${result}" | awk '{print $1}' > "${TMP_CURR_LIST}" else echo "Wrn: Failed to fetch Downstream Package List. Assuming empty." fi -if ! diff ${TMP_CURR_LIST} ${TMP_PREV_LIST}; then +if ! diff "${TMP_CURR_LIST}" "${TMP_PREV_LIST}"; then echo "New custom content. It's Release Time!" ret=1 else echo "Nothing to see here." fi -rm ${TMP_CURR_LIST} -rm ${TMP_PREV_LIST} +rm "${TMP_CURR_LIST}" +rm "${TMP_PREV_LIST}" exit ${ret}