scripts: purge use of test '-a' and '-o' ops and clean up
[girocco.git] / toolbox / reports / project-disk-use.sh
blob2265b5b3e204396633d50a70f82372c973c426fd
1 #!/bin/sh
3 # Report on project disk use.
4 # Output can be sent as email to admin with -m
5 # Automatically runs with nice and ionice (if available)
7 # Usage: project-disk-use [-m] [top-n-only]
9 # With -m mail the report to $cfg_admin instead of sending it to stdout
11 # Shows total disk usage in K bytes for $cfg_reporoot
12 # The top-n-only (all if not given) repos are then listed by
13 # decreasing order of disk space.
15 # Note that any *.git directories that are found in $cfg_reporoot that are
16 # not listed in $cfg_chroot/etc/group ARE included and have a '!' suffix added.
18 set -e
20 datefmt='%Y-%m-%d %H:%M:%S %z'
21 startdate="$(date "+$datefmt")"
23 . @basedir@/shlib.sh
25 mailresult=
26 if [ "$1" = "-m" ]; then
27 shift
28 mailresult=1
31 hasnice=
32 ! command -v nice >/dev/null || hasnice=1
33 hasionice=
34 ! command -v ionice >/dev/null || hasionice=1
36 nl='
39 fmtcomma() {
40 # remove leading 0s
41 _y="${1%%[1-9]*}"; _x="${1#$_y}"; _x="${_x:-0}"
42 # add commas after each group of 3
43 _y=
44 while [ $_x -gt 999 ]; do
45 _y="$(printf '%03d' $(($_x - $_x / 1000 * 1000)))${_y:+,$_y}"
46 _x="$(($_x/1000))"
47 done
48 [ $_x -eq 0 ] || _y="$_x${_y:+,$_y}"
49 echo "${_y:-0}"
52 fmtpct() {
53 if [ -z "$1" ] || [ "$1" = "0" ]; then return; fi
54 if [ -z "$2" ] || [ "$2" = "0" ]; then return; fi
55 _fmtpct=$(( ( $1 * 100 + $2 / 2 ) / $2 ))
56 if [ $_fmtpct -le 100 ]; then
57 _of=
58 [ -z "$4" ] || _of=" of $(fmtcomma $2)"
59 echo "${3:- }($_fmtpct%$_of)"
63 get_use_k() {
64 _targ="$1"
65 shift
66 _cmd="du $var_du_follow -k -s"
67 if [ -n "$var_du_exclude" ]; then
68 while [ -n "$1" ]; do
69 _cmd="$_cmd $var_du_exclude \"$1\""
70 shift
71 done
72 elif [ $# -ne 0 ]; then
73 echo "get_use_k: error: no du exclude option available" >&2
74 exit 1
76 _cmd="$_cmd \"$_targ\" 2>/dev/null | cut -f 1"
77 [ -z "$hasionice" ] || _cmd="ionice -c 3 $_cmd"
78 [ -z "$hasnice" ] || _cmd="nice -n 19 $_cmd"
79 eval "$_cmd"
82 is_active() (
83 cd "$cfg_reporoot/$1.git" || return 1
84 check_interval lastchange 2592000 # 30 days
87 projlist="$(cut -d : -f 1 <"$cfg_chroot/etc/group")"
89 is_listed_proj() {
90 echo "$projlist" | grep -q -e "^$1$"
93 totaluse="$(get_use_k "$cfg_reporoot")"
94 if [ -n "$var_du_exclude" ]; then
95 # Attribute all hard-linked stuff in _recyclebin to non-_recyclebin
96 inuse="$(get_use_k "$cfg_reporoot" "_recyclebin")"
97 binned="$(( $totaluse - $inuse ))"
98 else
99 # No du exclude option, if binned contains hard links into other repos
100 # its size may appear larger than it actually is and the kpct will be off
101 binned="$(get_use_k "$cfg_reporoot/_recyclebin")"
102 inuse="$(( $totaluse - $binned ))"
105 cd "$cfg_reporoot"
106 total=0
107 ktotal=0
108 howmany=0
109 orphans=0
110 mirrors=0
111 forks=0
112 mactive=0
113 pactive=0
114 results=
115 while IFS='' read -r proj; do
116 proj="${proj#./}"
117 proj="${proj%.git}"
119 is_listed_proj "$proj" || { x='!'; orphans="$(( $orphans + 1 ))"; }
120 case "$proj" in */*) forks="$(( $forks + 1 ))"; esac
121 mirror="$(get_mirror_type "$proj.git" 2>/dev/null)" || :
122 [ -z "$mirror" ] || mirrors="$(( $mirrors + 1 ))"
123 if is_active "$proj"; then
124 if [ -n "$mirror" ]; then
125 mactive="$(( $mactive + 1 ))"
126 else
127 pactive="$(( $pactive + 1 ))"
130 : ${mirror:=M}
131 usek="$(get_use_k "$proj.git")"
132 repok=
133 [ -L "$proj.git/objects" ] || ! [ -d "$proj.git/objects" ] ||
134 repok="$(git --git-dir="$cfg_reporoot/$proj.git" config --get girocco.reposizek 2>/dev/null)" || :
135 repokpct=
136 case "$repok" in
137 [0-9]*)
138 repok="${repok%%[!0-9]*}"
139 repokpct=$(( ( $repok * 100 + $usek / 2 ) / $usek ))
140 if [ $repokpct -le 100 ]; then
141 repokpct="$repokpct%"
142 else
143 repokpct="100+"
144 fi;;
146 repok=0
147 repokpct=-;;
148 esac
149 ktotal=$(( $ktotal + $repok ))
150 total="$(( $total + $usek ))"
151 howmany="$(( $howmany + 1 ))"
152 line="$usek $repokpct $mirror $proj$x$nl"
153 results="$results$line"
154 done <<EOT
155 $(find . -type d \( -path ./_recyclebin -o -name '*.git' -print \) -prune 2>/dev/null)
158 kpct=$(( ( $ktotal * 100 + $inuse / 2 ) / $inuse ))
159 enddate="$(date "+$datefmt")"
160 domail=cat
161 [ -z "$mailresult" ] || domail='mailref "diskuse@$cfg_gitweburl" -s "[$cfg_name] Project Disk Use Report" "$cfg_admin"'
163 cat <<EOT
164 Project Disk Use Report
165 =======================
167 Start Time: $startdate
168 End Time: $enddate
170 Repository Root: $cfg_reporoot
171 Unbinned Disk Use: $(fmtcomma "$inuse") (1024-byte blocks)
172 reposizek Total: $(fmtcomma "$ktotal") ($kpct%)
174 Recycle Bin Root: $cfg_reporoot/_recyclebin
175 Binned Disk Use: $(fmtcomma "$binned") (1024-byte blocks)
177 Total Disk Use: $(fmtcomma "$totaluse") (1024-byte blocks)
179 Repository Count: $(fmtcomma "$howmany")
180 Forks: $(fmtcomma "$forks")$(fmtpct "$forks" "$howmany")
181 Mirrors: $(fmtcomma "$mirrors")$(fmtpct "$mirrors" "$howmany")
182 Orphaned: $(fmtcomma "$orphans")
183 Repository Total: $(fmtcomma "$total") (1024-byte blocks)
185 30-Day Active: $(fmtcomma "$(( $pactive + $mactive ))")$(fmtpct "$(( $pactive + $mactive ))" "$howmany")
186 Push: $(fmtcomma "$pactive")$(fmtpct "$pactive" "$howmany")$(fmtpct "$pactive" "$(( $pactive + $mactive ))" "/" 1)$(fmtpct "$pactive" "$(( $howmany - $mirrors ))" "/" 1)
187 Mirror: $(fmtcomma "$mactive")$(fmtpct "$mactive" "$howmany")$(fmtpct "$mactive" "$(( $pactive + $mactive ))" "/" 1)$(fmtpct "$mactive" "$mirrors" "/" 1)
189 $(df -h "$cfg_reporoot")
192 if [ $# -lt 1 ] || [ $1 != "0" ]; then
193 topn=cat
194 message="Individual Repository Use"
195 case "${1%%[!0-9]*}" in ?*)
196 message="Individual Repository Use (Top $1)"
197 topn="head -n ${1%%[!0-9]*}"
198 esac
199 echo ""
200 echo ""
201 echo "$message"
202 echo "$message" | tr -c '\n' -
203 echo ""
204 printf '%s' "$results" | sort -k1,1nr -k4,4 |
205 while read -r a b c d; do
206 printf "%10s %4s %s %s\n" "$(fmtcomma "$a")" "$b" "$c" "$d"
207 done |
208 sed -e 's/ [M-] / /g' | $topn
210 } | eval "$domail"