Skip to content

Commit 135850b

Browse files
authored
Fix empty gather logs due to script crash
Fix empty gather logs due to script crash
2 parents 15644e5 + 85ba013 commit 135850b

File tree

3 files changed

+92
-13
lines changed

3 files changed

+92
-13
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -184,13 +184,14 @@ Note: most of the resource outputs are given in 3 file types: `.json`, `.yaml`,
184184

185185
## Testing
186186

187-
You can run the script locally from your workstation.
188-
To do that you need an OpenShift cluster and you will have to install the Red Hat GitOps Operator.
189-
Then you can run the script like this:
187+
To do that you need an OpenShift cluster, and you will have to install the Red Hat GitOps Operator.
188+
Then you can test how your changes affects gathered data:
190189

191190
```shell
192-
chmod +x ./gather_gitops.sh
193-
./gather_gitops.sh --base-collection-path .
191+
# You may need to create the repository on quay.io manually to make sure it is public
192+
make REGISTRY_USERNAME=my-non-production-org CONTAINER_IMAGE_TAG="$(git rev-parse HEAD)" push
193+
# Note some differences are expected, like few lines in rapidly populated logs
194+
./test/compare.sh registry.redhat.io/openshift-gitops-1/must-gather-rhel8:"$SOME_OLD_VERSION" quay.io/my-non-production-org/gitops-must-gather:"$(git rev-parse HEAD)"
194195
```
195196

196197
Last but not least, please make sure you run `make lint` before pushing new changes.

gather_gitops.sh

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
11
#!/usr/bin/env bash
22

33
set -eu -o pipefail
4+
s=declare_out_of_trap_script # Workaround for https://github.com/koalaman/shellcheck/issues/3287
5+
trap 's=$?; echo >&2 "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $s' ERR
46

57
LOGS_DIR="/must-gather"
68

79
mkdir -p ${LOGS_DIR}
810

911
GITOPS_CURRENT_CSV=$(oc get subscription.operators.coreos.com --ignore-not-found -A -o json | jq '.items[] | select(.metadata.name=="openshift-gitops-operator") | .status.currentCSV' -r)
12+
if [ -z "$GITOPS_CURRENT_CSV" ]; then
13+
NON_ARGO_CRD_NAMES=()
14+
else
15+
readarray -t NON_ARGO_CRD_NAMES < <(oc get csv --ignore-not-found "$GITOPS_CURRENT_CSV" -o json | jq '.spec.customresourcedefinitions.owned[] | select(.name | contains("argoproj.io") | not) | .name' -rj)
16+
fi
1017

1118
# Gathering cluster version all the crd related to operators.coreos.com and argoproj.io
1219
echo "gather_gitops:$LINENO] inspecting crd, clusterversion .." | tee -a ${LOGS_DIR}/gather_gitops.log
20+
readarray -t UPSTREAM_CRDS < <(oc get crd -o name | grep -Ei "argoproj.io|operators.coreos.com")
1321
# Getting non.existent.crd is a hack to avoid getting all available crds in the cluster in case there are no owned resources that do not contain "argoproj.io"
14-
oc adm inspect --dest-dir=${LOGS_DIR} "$(oc get crd -o name | grep -Ei "argoproj.io|operators.coreos.com")" "$(oc get crd non.existent.crd --ignore-not-found "$(oc get csv --ignore-not-found "$GITOPS_CURRENT_CSV" -o json | jq '.spec.customresourcedefinitions.owned[] | select(.name | contains("argoproj.io") | not) | " " + .name' -rj)" -o name)" clusterversion/version > /dev/null
22+
readarray -t NON_ARGO_CRDS < <(oc get crd non.existent.crd --ignore-not-found "${NON_ARGO_CRD_NAMES[@]}" -o name)
23+
oc adm inspect --dest-dir=${LOGS_DIR} "${UPSTREAM_CRDS[@]}" "${NON_ARGO_CRDS[@]}" clusterversion/version > /dev/null
1524

1625
# Gathering all namespaced custom resources across the cluster that contains "argoproj.io" related custom resources
1726
oc get crd -o json | jq -r '.items[] | select((.spec.group | contains ("argoproj.io")) and .spec.scope=="Namespaced") | .spec.group + " " + .metadata.name + " " + .spec.names.plural' |
1827
while read -r API_GROUP APIRESOURCE API_PLURAL_NAME; do
1928
echo "gather_gitops:$LINENO] collecting ${APIRESOURCE} .." | tee -a ${LOGS_DIR}/gather_gitops.log
20-
NAMESPACES=$(oc get "${APIRESOURCE}" --all-namespaces=true --ignore-not-found -o jsonpath='{range .items[*]}{@.metadata.namespace}{"\n"}{end}' | uniq)
29+
readarray -t NAMESPACES < <(oc get "${APIRESOURCE}" --all-namespaces=true --ignore-not-found -o jsonpath='{range .items[*]}{@.metadata.namespace}{"\n"}{end}' | uniq)
2130
for NAMESPACE in "${NAMESPACES[@]}"; do
2231
mkdir -p "${LOGS_DIR}/namespaces/${NAMESPACE}/${API_GROUP}"
2332
oc get "${APIRESOURCE}" -n "${NAMESPACE}" -o=yaml >"${LOGS_DIR}/namespaces/${NAMESPACE}/${API_GROUP}/${API_PLURAL_NAME}.yaml"
@@ -26,10 +35,10 @@ done
2635

2736
# Gathering all namespaced custom resources across the cluster that are owned by gitops-operator but do not contain "argoproj.io" related customer resources
2837
# Getting "non.existent.crd" is a hack to be sure that the output is a list of items even if it only contains zero or a single item
29-
oc get crd --ignore-not-found non.existent.crd "$(oc get csv --ignore-not-found "$GITOPS_CURRENT_CSV" -o json | jq '.spec.customresourcedefinitions.owned[] | select(.name | contains("argoproj.io") | not) | " " + .name' -rj)" -o json | jq -r '.items[] | select((.spec.group | contains ("argoproj.io")) and .spec.scope=="Namespaced") | .spec.group + " " + .metadata.name + " " + .spec.names.plural' |
38+
oc get crd --ignore-not-found non.existent.crd "${NON_ARGO_CRD_NAMES[@]}" -o json | jq -r '.items[] | select((.spec.group | contains ("argoproj.io")) and .spec.scope=="Namespaced") | .spec.group + " " + .metadata.name + " " + .spec.names.plural' |
3039
while read -r API_GROUP APIRESOURCE API_PLURAL_NAME; do
3140
echo "gather_gitops:$LINENO] collecting ${APIRESOURCE} .." | tee -a ${LOGS_DIR}/gather_gitops.log
32-
NAMESPACES=$(oc get "${APIRESOURCE}" --all-namespaces=true --ignore-not-found -o jsonpath='{range .items[*]}{@.metadata.namespace}{"\n"}{end}' | uniq)
41+
readarray -t NAMESPACES < <(oc get "${APIRESOURCE}" --all-namespaces=true --ignore-not-found -o jsonpath='{range .items[*]}{@.metadata.namespace}{"\n"}{end}' | uniq)
3342
for NAMESPACE in "${NAMESPACES[@]}"; do
3443
mkdir -p "${LOGS_DIR}/namespaces/${NAMESPACE}/${API_GROUP}"
3544
oc get "${APIRESOURCE}" -n "${NAMESPACE}" -o=yaml >"${LOGS_DIR}/namespaces/${NAMESPACE}/${API_GROUP}/${API_PLURAL_NAME}.yaml"
@@ -46,7 +55,7 @@ done
4655

4756
# Gathering all cluster-scoped custom resources across the cluster that are owned by gitops-operator but do not contain "argoproj.io"
4857
# Getting "non.existent.crd" is a hack to be sure that the output is a list of items even if it only contains zero or a single item
49-
oc get crd --ignore-not-found non.existent.crd "$(oc get csv --ignore-not-found "$GITOPS_CURRENT_CSV" -o json | jq '.spec.customresourcedefinitions.owned[] | select(.name | contains("argoproj.io") | not) | " " + .name' -rj)" -o json | jq -r '.items[] | select((.spec.group | contains ("argoproj.io")) and .spec.scope=="Namespaced") | .spec.group + " " + .metadata.name + " " + .spec.names.plural' |
58+
oc get crd --ignore-not-found non.existent.crd "${NON_ARGO_CRD_NAMES[@]}" -o json | jq -r '.items[] | select((.spec.group | contains ("argoproj.io")) and .spec.scope=="Namespaced") | .spec.group + " " + .metadata.name + " " + .spec.names.plural' |
5059
while read -r API_GROUP APIRESOURCE API_PLURAL_NAME; do
5160
mkdir -p "${LOGS_DIR}/cluster-scoped-resources/${API_GROUP}"
5261
echo "gather_gitops:$LINENO] collecting ${APIRESOURCE} .." | tee -a ${LOGS_DIR}/gather_gitops.log
@@ -55,14 +64,20 @@ done
5564

5665
# Inspecting namespace reported in ARGOCD_CLUSTER_CONFIG_NAMESPACES, openshift-gitops and openshift-gitops-operator, and namespaces containing ArgoCD instances
5766
echo "gather_gitops:$LINENO] inspecting \$ARGOCD_CLUSTER_CONFIG_NAMESPACES, openshift-gitops and openshift-gitops-operator namespaces and namespaces containing ArgoCD instances .." | tee -a ${LOGS_DIR}/gather_gitops.log
58-
oc get ns --ignore-not-found "$(oc get subs -A --ignore-not-found -o json | jq '.items[] | select(.metadata.name=="openshift-gitops-operator") | .spec.config.env[]?|select(.name=="ARGOCD_CLUSTER_CONFIG_NAMESPACES")| " " + .value | sub(","; " ")' -rj)" "$(oc get ArgoCD,Rollout,RolloutManager -A -o json | jq '.items[] | " " + .metadata.namespace' -rj)" openshift-gitops openshift-gitops-operator -o json \
67+
readarray -t SUBSCRIPTIONS < <(oc get subs -A --ignore-not-found -o json | jq '.items[] | select(.metadata.name=="openshift-gitops-operator") | .spec.config.env[]?|select(.name=="ARGOCD_CLUSTER_CONFIG_NAMESPACES")| " " + .value | sub(","; " ")' -rj)
68+
readarray -t ARGO_CRDS < <(oc get ArgoCD,Rollout,RolloutManager -A -o json | jq '.items[] | " " + .metadata.namespace' -rj)
69+
oc get ns --ignore-not-found "${SUBSCRIPTIONS[@]}" "${ARGO_CRDS[@]}" openshift-gitops openshift-gitops-operator -o json \
5970
| jq '.items | unique |.[] | .metadata.name' -r |
6071
while read -r NAMESPACE; do
6172
echo "gather_gitops:$LINENO] inspecting namespace $NAMESPACE .." | tee -a ${LOGS_DIR}/gather_gitops.log
6273
oc adm inspect --dest-dir=${LOGS_DIR} "ns/$NAMESPACE" > /dev/null
6374
echo "gather_gitops:$LINENO] inspecting csv,sub,ip for namespace $NAMESPACE .." | tee -a ${LOGS_DIR}/gather_gitops.log
64-
oc adm inspect --dest-dir=${LOGS_DIR} "$(oc get --ignore-not-found clusterserviceversions.operators.coreos.com,installplans.operators.coreos.com,subscriptions.operators.coreos.com -o name -n "$NAMESPACE")" -n "$NAMESPACE" &> /dev/null \
65-
|| echo "gather_gitops:$LINENO] no csv,sub,ip found in namespace $NAMESPACE .." | tee -a ${LOGS_DIR}/gather_gitops.log
75+
readarray -t CSVS_SUBS_IPS < <(oc get --ignore-not-found clusterserviceversions.operators.coreos.com,installplans.operators.coreos.com,subscriptions.operators.coreos.com -o name -n "$NAMESPACE")
76+
if [ "${#CSVS_SUBS_IPS[@]}" -eq 0 ]; then
77+
echo "gather_gitops:$LINENO] no csv,sub,ip found in namespace $NAMESPACE .." | tee -a ${LOGS_DIR}/gather_gitops.log
78+
else
79+
oc adm inspect --dest-dir=${LOGS_DIR} "${CSVS_SUBS_IPS[@]}" -n "$NAMESPACE" &> /dev/null
80+
fi
6681
done
6782

6883
# Inspecting namespace managed by ArgoCD

test/compare.sh

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env bash
2+
# https://github.com/olivergondza/bash-strict-mode
3+
set -eEuo pipefail
4+
s=declare_out_of_trap_script # Workaround for https://github.com/koalaman/shellcheck/issues/3287
5+
trap 's=$?; echo >&2 "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $s' ERR
6+
7+
function main() {
8+
if [[ $# -ne 2 ]]; then
9+
echo >&2 "Usage: $0 [IMAGE_A] [IMAGE_B]"
10+
exit 1
11+
fi
12+
local img_a=$1
13+
local img_b=$2
14+
15+
inv_a="$(mktemp -d gitops-must-gather-A-XXXX)"
16+
inv_b="$(mktemp -d gitops-must-gather-B-XXXX)"
17+
trap 'rm -rf "${inv_a}" "${inv_b}"' EXIT
18+
19+
gather "$img_a" "$inv_a"
20+
gather "$img_b" "$inv_b"
21+
22+
diff --color=auto --recursive \
23+
--ignore-matching-lines="resourceVersion: " \
24+
"${inv_a}" "${inv_b}"
25+
}
26+
27+
function gather() {
28+
image=$1
29+
dir=$2
30+
31+
if ! oc adm must-gather --image="$image" --dest-dir="${dir}" 2>&1 | tee "${dir}/oc-adm-output.log"; then
32+
echo >&2 "Failed gathering for $image"
33+
return 1
34+
fi
35+
36+
sanitize "$image" "$dir"
37+
}
38+
39+
function sanitize() {
40+
image=$1
41+
dir=$2
42+
43+
# Unify names of the directories its name is based on image name
44+
mv "$dir"/*-sha256-* "$dir/__RESOURCES__"
45+
46+
# In log files, drop image name, generated resource names, timestamp, line numbers, and transfer metrics
47+
sed -i -r \
48+
-e "s~${image}~__IMAGE_TAG__~g" \
49+
-e "s~must-gather-[a-z0-9]{5}~must-gather-XXXXX~g" \
50+
-e 's~[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]+Z~__TIMESTAMP__~g' \
51+
-e 's~gather_gitops:[0-9]+~gather_gitops:LL~g' \
52+
-e '/total size is .* speedup is .*/d' \
53+
-e '/sent .* received .* bytes\/sec/d' \
54+
"$dir/oc-adm-output.log" "$dir/must-gather.logs" "$dir/__RESOURCES__/gather.logs" "$dir/__RESOURCES__/gather_gitops.log"
55+
56+
# Timestamps are not going to match, just test there is the same number of them
57+
ts="$(wc -l < "$dir/timestamp")"
58+
echo "$ts" > "$dir/timestamp"
59+
ts="$(wc -l < "$dir/__RESOURCES__/timestamp")"
60+
echo "$ts" > "$dir/__RESOURCES__/timestamp"
61+
}
62+
63+
main "$@"

0 commit comments

Comments
 (0)