scripts: purge use of test '-a' and '-o' ops and clean up
[girocco.git] / toolbox / reports / project-fsck-status.sh
blob9d5193909695f28c9ee8af2fb2649f9e869203a2
1 #!/bin/sh
3 # Report on project fsck status.
4 # Output can be sent as email to admin with -m
5 # Automatically runs with nice and ionice (if available)
7 # Usage: project-fsck-status [-m]
9 # With -m mail the report to $cfg_admin instead of sending it to stdout
11 # Shows fsck status for all projects with details for any issues
13 # Note that only projects listed in $cfg_chroot/etc/group are checked
15 set -e
17 datefmt='%Y-%m-%d %H:%M:%S %z'
18 startdate="$(date "+$datefmt")"
20 . @basedir@/shlib.sh
22 mailresult=
23 if [ "$1" = "-m" ]; then
24 shift
25 mailresult=1
28 hasnice=
29 ! command -v nice >/dev/null || hasnice=1
30 hasionice=
31 ! command -v ionice >/dev/null || hasionice=1
33 nl='
36 projlist="$(cut -d : -f 1 <"$cfg_chroot/etc/group")"
38 is_listed_proj() {
39 echo "$projlist" | grep -q -e "^$1$"
42 is_empty_proj() {
43 # if packed-refs is empty and no files in refs then empty
44 # we do NOT want to run any git command in case the repo is bad
45 _pd="$cfg_reporoot/$1.git"
46 if [ -f "$_pd/packed-refs" ] && [ -s "$_pd/packed-refs" ]; then
47 if [ $(LC_ALL=C sed -n '/^#/!p' <"$_pd/packed-refs" | LC_ALL=C wc -l) -gt 0 ]; then
48 return 1
51 test $(find "$_pd/refs" -type f -print 2>/dev/null | head -n 1 | LC_ALL=C wc -l) -eq 0
54 get_fsck_proj() (
55 cd "$cfg_reporoot/$1.git" || {
56 echo "no such directory: $cfg_reporoot/$1.git"
57 return 1
59 # using --strict changes "zero-padded file modes" from a warning into an error
60 # which we do NOT want so we do NOT use --strict
61 cmd="git fsck"
62 [ -z "$var_have_git_1710" ] || cmd="$cmd --no-dangling"
63 # no need for --no-progress (v1.7.9+) since stderr will not be a tty
64 cmd="$cmd 2>&1"
65 [ -z "$hasionice" ] || cmd="ionice -c 3 $cmd"
66 [ -z "$hasnice" ] || cmd="nice -n 19 $cmd"
67 fsckresult=0
68 fsckoutput="$(eval "$cmd")" || fsckresult=$?
69 if [ -z "$var_have_git_1710" ]; then
70 # strip lines starting with "dangling" since --no-dangling is not supported
71 # note that "dangling" is NOT translated
72 fsckoutput="$(printf '%s\n' "$fsckoutput" | LC_ALL=C sed -n '/^dangling/!p')"
74 [ -z "$fsckoutput" ] || printf '%s\n' "$fsckoutput"
75 return $fsckresult
78 cd "$cfg_reporoot"
79 # howmany is how many fsck was run on plus how many were empty
80 howmany=0
81 # mtcount is how many were empty
82 mtcount=0
83 # okcount is how many fsck returned 0 status for
84 okcount=0
85 # warncount is how many fsck returned 0 status but non-empty output
86 warncount=0
87 # errresults are results from fsck non-0 status fsck runs
88 errresults=
89 # warnresults are non-empty results from 0 status fsck runs
90 warnresults=
91 while IFS='' read -r proj; do
92 proj="${proj#./}"
93 proj="${proj%.git}"
94 is_listed_proj "$proj" && is_git_dir "$cfg_reporoot/$proj.git" || continue
95 [ -d "$proj.git/objects" ] || continue
96 howmany="$(( $howmany + 1 ))"
97 if is_empty_proj "$proj"; then
98 mtcount="$(( $mtcount + 1 ))"
99 continue
101 ok=1
102 output="$(get_fsck_proj "$proj")" || ok=
103 [ -z "$ok" ] || okcount="$(( $okcount + 1 ))"
104 [ -n "$ok" ] || [ -n "$output" ] || output="git fsck failed with no output"
105 if [ -n "$output" ]; then
106 output="$(printf '%s\n' "$output" | LC_ALL=C sed 's/^/ /')$nl"
107 if [ -n "$ok" ]; then
108 # warning
109 warncount="$(( $warncount + 1 ))"
110 [ -z "$warnresults" ] || warnresults="$warnresults$nl"
111 warnresults="$warnresults$proj: (warnings only)$nl$output"
112 else
113 [ -z "$errresults" ] || errresults="$errresults$nl"
114 errresults="$errresults$proj: (errors found)$nl$output"
117 done <<EOT
118 $(find . -type d \( -path ./_recyclebin -o -name '*.git' -print \) -prune 2>/dev/null)
121 enddate="$(date "+$datefmt")"
122 domail=cat
123 [ -z "$mailresult" ] || domail='mailref "fsck@$cfg_gitweburl" -s "[$cfg_name] Project Fsck Status Report" "$cfg_admin"'
125 cat <<EOT
126 Project Fsck Status Report
127 ==========================
129 Start Time: $startdate
130 End Time: $enddate
132 Projects Checked: $howmany
133 Projects Okay: $(( $okcount + $mtcount )) (passed + warned + empty)
135 Projects Passed: $(( $okcount - $warncount ))
136 Projects Warned: $warncount
137 Projects Empty: $mtcount
138 Projects Failed: $(( $howmany - $mtcount - $okcount ))
142 if [ -n "$errresults" ] || [ -n "$warnresults" ]; then
143 echo ""
144 echo "Fsck Output"
145 echo "-----------"
146 echo ""
147 printf '%s' "$errresults"
148 [ -z "$errresults" ] || [ -z "$warnresults" ] || echo ""
149 printf '%s' "$warnresults"
150 echo ""
152 } | eval "$domail"