Util.pm: avoid unintended @ interpolation
[girocco.git] / toolbox / reports / project-disk-use.sh
blobce6b2c5e3e8aa8e5d46648c756df697ac1359a8b
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="$(printf '\n*')"
37 nl="${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 get_use_k() {
53 _targ="$1"
54 shift
55 _cmd="du $var_du_follow -k -s"
56 if [ -n "$var_du_exclude" ]; then
57 while [ -n "$1" ]; do
58 _cmd="$_cmd $var_du_exclude \"$1\""
59 shift
60 done
61 elif [ $# -ne 0 ]; then
62 echo "get_use_k: error: no du exclude option available" >&2
63 exit 1
65 _cmd="$_cmd \"$_targ\" 2>/dev/null | cut -f 1"
66 [ -n "$hasionice" ] && _cmd="ionice -c 3 $_cmd"
67 [ -n "$hasnice" ] && _cmd="nice -n 19 $_cmd"
68 eval "$_cmd"
71 projlist="$(cut -d : -f 1 < "$cfg_chroot/etc/group")"
73 is_listed_proj() {
74 echo "$projlist" | grep -q -e "^$1$"
77 totaluse="$(get_use_k "$cfg_reporoot")"
78 if [ -n "$var_du_exclude" ]; then
79 # Attribute all hard-linked stuff in _recyclebin to non-_recyclebin
80 inuse="$(get_use_k "$cfg_reporoot" "_recyclebin")"
81 binned="$(( $totaluse - $inuse ))"
82 else
83 # No du exclude option, if binned contains hard links into other repos
84 # its size may appear larger than it actually is and the kpct will be off
85 binned="$(get_use_k "$cfg_reporoot/_recyclebin")"
86 inuse="$(( $totaluse - $binned ))"
89 cd "$cfg_reporoot"
90 total=0
91 ktotal=0
92 howmany=0
93 orphans=0
94 results=
95 while IFS='' read -r proj; do
96 proj="${proj#./}"
97 proj="${proj%.git}"
99 is_listed_proj "$proj" || { x='!'; orphans="$(( $orphans + 1 ))"; }
100 mirror="$(get_mirror_type "$proj.git" 2>/dev/null || :)"
101 : ${mirror:=M}
102 usek="$(get_use_k "$proj.git")"
103 repok=
104 [ -L "$proj.git/objects" -o ! -d "$proj.git/objects" ] || \
105 repok="$(git --git-dir="$cfg_reporoot/$proj.git" config --get girocco.reposizek 2>/dev/null || :)"
106 repokpct=
107 case "$repok" in
108 [0-9]*)
109 repok="${repok%%[!0-9]*}"
110 repokpct=$(( ( $repok * 100 + $usek / 2 ) / $usek ))
111 if [ $repokpct -le 100 ]; then
112 repokpct="$repokpct%"
113 else
114 repokpct="100+"
115 fi;;
117 repok=0
118 repokpct=-;;
119 esac
120 ktotal=$(( $ktotal + $repok ))
121 total="$(( $total + $usek ))"
122 howmany="$(( $howmany + 1 ))"
123 line="$usek $repokpct $mirror $proj$x$nl"
124 results="$results$line"
125 done <<EOT
126 $(find . -type d \( -path ./_recyclebin -o -name '*.git' -print \) -prune 2>/dev/null)
129 kpct=$(( ( $ktotal * 100 + $inuse / 2 ) / $inuse ))
130 enddate="$(date "+$datefmt")"
131 domail=cat
132 [ -n "$mailresult" ] && domail='mail -s "[$cfg_name] Project Disk Use Report" "$cfg_admin"'
134 cat <<EOT
135 Project Disk Use Report
136 =======================
138 Start Time: $startdate
139 End Time: $enddate
141 Repository Root: $cfg_reporoot
142 Unbinned Disk Use: $(fmtcomma "$inuse") (1024-byte blocks)
143 reposizek Total: $(fmtcomma "$ktotal") ($kpct%)
145 Recycle Bin Root: $cfg_reporoot/_recyclebin
146 Binned Disk Use: $(fmtcomma "$binned") (1024-byte blocks)
148 Total Disk Use: $(fmtcomma "$totaluse") (1024-byte blocks)
150 Repository Count: $(fmtcomma "$howmany")
151 Orphaned: $(fmtcomma "$orphans")
152 Repository Total: $(fmtcomma "$total") (1024-byte blocks)
154 $(df -h "$cfg_reporoot")
157 if [ $# -lt 1 ] || [ $1 != "0" ]; then
158 topn=cat
159 message="Individual Repository Use"
160 case "${1%%[!0-9]*}" in ?*)
161 message="Individual Repository Use (Top $1)"
162 topn="head -n ${1%%[!0-9]*}"
163 esac
164 echo ""
165 echo ""
166 echo "$message"
167 echo "$message" | tr -c '\n' -
168 echo ""
169 printf '%s' "$results" | sort -k1,1nr -k4,4 | \
170 while read -r a b c d; do
171 printf "%10s %4s %s %s\n" "$(fmtcomma "$a")" "$b" "$c" "$d"
172 done | \
173 sed -e 's/ [M-] / /g' | $topn
175 } | eval "$domail"