From 6f4a23694d26608ef360da3fb0a6cbb3a575cd07 Mon Sep 17 00:00:00 2001 From: Blaine Gardner Date: Wed, 12 Jan 2022 18:22:03 -0700 Subject: [PATCH] build: make crd/rbac generation order deterministic Linux doesn't guarantee file ordering, so when dealing with files in order, we can use 'sort' to make sure the order is deterministic. For yq's usage of files, we need to keep file names in an intermediate variable, and this should be an array to support file paths with spaces. 'readarray' is not available on MacOS's built-in bash, so a longer 'while read' loop is needed for the array creation. Signed-off-by: Blaine Gardner --- build/crds/build-crds.sh | 14 +++++++++++++- build/rbac/keep-rbac-yaml.sh | 24 ++++++++++++++++-------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/build/crds/build-crds.sh b/build/crds/build-crds.sh index 58a064254..1f40effe2 100755 --- a/build/crds/build-crds.sh +++ b/build/crds/build-crds.sh @@ -97,7 +97,19 @@ fi generating_main_crd +# Linux doesn't guarantee file ordering, so we must sort the output to make sure it's deterministic. +# In order to handle file paths with spaces in the yq command below, it's easiest to read the +# file names into an array. +# Set locale `LC_ALL=C` because different OSes have different sort behavior; +# `C` sorting order is based on the byte values, +# Reference: https://blog.zhimingwang.org/macos-lc_collate-hunt +LC_ALL=C +CRD_FILES=() +while read -r line; do + CRD_FILES+=("$line") +done < <(find "$OLM_CATALOG_DIR" -type f -name '*.yaml' | sort) + echo "---" >> "$CEPH_CRDS_FILE_PATH" # yq doesn't output the first doc separator -$YQ_BIN_PATH eval-all '.' "$OLM_CATALOG_DIR/"*.yaml >> "$CEPH_CRDS_FILE_PATH" +$YQ_BIN_PATH eval-all '.' "${CRD_FILES[@]}" >> "$CEPH_CRDS_FILE_PATH" build_helm_resources diff --git a/build/rbac/keep-rbac-yaml.sh b/build/rbac/keep-rbac-yaml.sh index be6420a43..b235846c3 100755 --- a/build/rbac/keep-rbac-yaml.sh +++ b/build/rbac/keep-rbac-yaml.sh @@ -1,9 +1,5 @@ #!/usr/bin/env bash set -eEuo pipefail -# setting locate `LC_ALL=C` because different OS do files sorting differently, -# so setting a common behaviour, `C` sorting order is based on the byte values, -# Reference: https://blog.zhimingwang.org/macos-lc_collate-hunt -LC_ALL=C # READS FROM STDIN # WRITES TO STDOUT @@ -39,14 +35,26 @@ sed '/^# Source: /d' | # helm adds '# Source: ' comments atop of each yaml $YQ eval --split-exp '.kind + " " + .metadata.name + " "' - # split into files by .yaml # outputting the filenames with spaces after kind and name keeps the same sorting from before +# Linux doesn't guarantee file ordering, so sort the files to make sure order is deterministic. +# And in order to handle file paths with spaces, it's easiest to read the file names into an array. +# Set locale `LC_ALL=C` because different OSes have different sort behavior; +# `C` sorting order is based on the byte values, +# Reference: https://blog.zhimingwang.org/macos-lc_collate-hunt +LC_ALL=C +RBAC_FILES=() +while read -r line; do + RBAC_FILES+=("$line") +done < <(find . -type f -name '*.yml' | sort) + # For debugging, output the resource kinds and names we processed and the number we are keeping -for file in *.yml; do - echo "${file%.yml}" >/dev/stderr +for file in "${RBAC_FILES[@]}"; do + # basename to get rid of the leading './' which find adds; %.yml to remove the .yml suffix + basename "${file%.yml}" >/dev/stderr done # shellcheck disable=SC2012 # we know filenames are alphanumeric from being k8s resources -echo "Number of RBAC resources: $(ls "${temp_dir}" | wc -l)" >/dev/stderr +echo "Number of RBAC resources: ${#RBAC_FILES[@]}" >/dev/stderr -$YQ eval-all '.' ./*.yml | # output all files, now sorted by Kind and Name by the fs +$YQ eval-all '.' "${RBAC_FILES[@]}" | # output all files, now sorted by Kind and Name by the fs sed '/^$/d' # remove empty lines caused by yq's display of header/footer comments rm -rf "${temp_dir}"