debootstrap and InRelease modes
[shellsnippets/shellsnippets.git] / mksh / sysadmin / mvndebri.sh
1 #!/bin/mksh
2 rcsid='$MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.56 2012/08/02 21:01:39 tg Exp $'
3 rcsid='$Id: mvndebri.sh 3150 2012-08-15 11:17:10Z tglase $'
4 #-
5 # Copyright (c) 2008, 2009, 2010, 2011, 2012
6 #       Thorsten Glaser <tg@mirbsd.org>
7 # Copyright (c) 2011
8 #       Thorsten Glaser <t.glaser@tarent.de>
9 #
10 # Provided that these terms and disclaimer and all copyright notices
11 # are retained or reproduced in an accompanying document, permission
12 # is granted to deal in this work without restriction, including un-
13 # limited rights to use, publicly perform, distribute, sell, modify,
14 # merge, give away, or sublicence.
15 #
16 # This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
17 # the utmost extent permitted by applicable law, neither express nor
18 # implied; without malicious intent or gross negligence. In no event
19 # may a licensor, author or contributor be held liable for indirect,
20 # direct, other damage, loss, or other issues arising in any way out
21 # of dealing in the work, even if advised of the possibility of such
22 # damage or existence of a defect, except proven that it results out
23 # of said person's immediate fault when using the work as intended.
24
25 if [[ $1 != /* || -z $2 || ! -d $1/$2/. ]]; then
26         print -u2 Syntax error.
27         exit 1
28 fi
29 jobname=$2
30
31 hn=$(hostname)
32 case $hn {
33 (ci-evolvis?(.*))
34         hn=ci-evolvis
35         repo_keyid=0x16B5D1B2
36         ;;
37 #[…]
38 #(test-hudson?(.*))
39 #       hn=test-hudson
40 #       repo_keyid=0xDB58AF73
41 #       ;;
42 (tglase.bonn.tarent.de)
43         hn=devel-testsystem
44         repo_keyid=0x5EB8D3B3
45         ;;
46 (*)
47         print -u2 "Cannot determine hostname from '$hn'"
48         exit 1
49         ;;
50 }
51 case $hn {
52 (test-hudson|devel-testsystem)
53         print -u2 moved
54         exit 1
55         dhn=jenkins-debs.evolvis.org
56         ;;
57 (*)
58         dhn=${hn}-debs.lan.tarent.de
59         ;;
60 }
61 repo_origin='tarent solutions GmbH'
62 repo_label=tarent_auto_${hn}_$jobname
63 repo_title="tarent $hn $jobname automatic DEB Repository"
64 function repo_description {
65         typeset suite_nick=$1
66
67         print -nr -- "tarent $hn $jobname/$suite_nick autobuild repository"
68 }
69
70
71 #set -A dpkgarchs -- alpha amd64 arm armel armhf avr32 hppa hurd-i386 i386 \
72 #    ia64 kfreebsd-amd64 kfreebsd-i386 m68k mips mipsel powerpc powerpcspe \
73 #    ppc64 s390 s390x sh4 sparc sparc64
74 set -A dpkgarchs -- amd64 i386
75
76 function putfile {
77         tee $1 | gzip -n9 >$1.gz
78 }
79
80 function sortlist {
81         typeset x u=$1
82
83         if [[ $u = -u ]]; then
84                 shift
85         else
86                 u=
87         fi
88
89         for x in "$@"; do
90                 print -r -- "$x"
91         done | sort $u
92 }
93
94 set +U
95 export LC_ALL=C
96 unset LANGUAGE
97 saveIFS=$IFS
98 cd "$1/$2"
99 shift
100 shift
101 if [[ ! -d dists/. ]]; then
102         print -u2 Not an APT repository.
103         exit 1
104 fi
105
106 suites=:
107 for suite in "$@"; do
108         suites=:dists/$suite$suites
109 done
110
111 allsuites=
112 for suite in dists/*; do
113         allsuites="$allsuites${allsuites:+ }${suite##*/}"
114         [[ $suites = : || $suites = *:"$suite":* ]] || continue
115         components=Components:
116         for dist in $suite/*; do
117                 [[ -d $dist/. ]] || continue
118                 rm -rf $dist/binary-* $dist/source
119                 ovf= oef= osf=
120                 [[ -s $dist/override.file ]] && ovf=$dist/override.file
121                 [[ -s $dist/override.extra ]] && oef="-e $dist/override.extra"
122                 [[ -s $dist/override.src ]] && osf="-s $dist/override.src"
123                 components="$components ${dist##*/}"
124                 for arch in ${dpkgarchs[*]} all; do
125                                 print "\n===> Creating" \
126                                     "${dist#dists/}/$arch/Packages\n"
127                                 mkdir -p $dist/binary-$arch
128                                 dpkg-scanpackages $oef -m -a $arch \
129                                     $dist $ovf | \
130                                     putfile $dist/binary-$arch/Packages
131                 done
132                 print "\n===> Creating ${dist#dists/}/Sources"
133                 mkdir -p $dist/source
134                 dpkg-scansources $osf \
135                     $dist $ovf | \
136                     putfile $dist/source/Sources
137                 print done.
138         done
139         print "\n===> Creating ${suite#dists/}/Release"
140         rm -f $suite/Release-*
141         (cat <<-EOF
142                 Origin: ${repo_origin}
143                 Label: ${repo_label}
144                 Suite: ${suite##*/}
145                 Codename: ${suite##*/}
146                 Date: $(date -u)
147                 Architectures: all ${dpkgarchs[*]} source
148                 $components
149                 Description: $(repo_description "${suite##*/}")
150                 MD5Sum:
151         EOF
152         exec 4>$suite/Release-sha1
153         exec 5>$suite/Release-sha2
154         print -u4 SHA1:
155         print -u5 SHA256:
156         cd $suite
157         for n in Contents-* */{binary-*,source}/{Packag,Sourc}es*; do
158                 [[ -f $n ]] || continue
159                 # GNU *sum tools are horridly inefficient
160                 set -A x -- $(md5sum "$n")
161                 nm=${x[0]}
162                 set -A x -- $(sha1sum "$n")
163                 nsha1=${x[0]}
164                 set -A x -- $(sha256sum "$n")
165                 nsha2=${x[0]}
166                 ns=$(stat -c '%s' "$n")
167                 print " $nm $ns $n"
168                 print -u4 " $nsha1 $ns $n"
169                 print -u5 " $nsha2 $ns $n"
170         done) >$suite/Release-tmp
171         cat $suite/Release-sha1 $suite/Release-sha2 >>$suite/Release-tmp
172
173         gpg -u $repo_keyid --batch --passphrase-file /etc/tarent/maven.kpw \
174             -sab <$suite/Release-tmp >$suite/Release-sig
175         gpg -u $repo_keyid --batch --passphrase-file /etc/tarent/maven.kpw \
176             --clearsign <$suite/Release-tmp >$suite/Release-inl
177
178         mv -f $suite/Release-inl $suite/InRelease
179         mv -f $suite/Release-tmp $suite/Release
180         mv -f $suite/Release-sig $suite/Release.gpg
181         rm -f $suite/Release-*
182 done
183
184 print "\n===> Creating debidx.htm\n"
185
186 integer nsrc=0 nbin=0
187 br='<br />'
188
189 for suite in dists/*; do
190         for dist in $suite/*; do
191                 [[ -d $dist/. ]] || continue
192                 suitename=${suite##*/}
193                 if [[ $suitename != +([a-z0-9_]) ]]; then
194                         print -u2 "Invalid suite name '$suitename'"
195                         continue 2
196                 fi
197                 distname=${dist##*/}
198                 if [[ $distname != +([a-z0-9_-]) ]]; then
199                         print -u2 "Invalid dist name '$distname'"
200                         continue
201                 fi
202
203                 gzip -dc $dist/source/Sources.gz |&
204                 pn=; pv=; pd=; pp=; Lf=
205                 while IFS= read -pr line; do
206                         case $line {
207                         (" "*)
208                                 if [[ -n $Lf ]]; then
209                                         eval x=\$$Lf
210                                         x=$x$line
211                                         eval $Lf=\$x
212                                 fi
213                                 ;;
214                         ("Package: "*)
215                                 pn=${line##Package:*([   ])}
216                                 Lf=pn
217                                 ;;
218                         ("Version: "*)
219                                 pv=${line##Version:*([   ])}
220                                 Lf=pv
221                                 ;;
222                         ("Binary: "*)
223                                 pd=${line##Binary:*([    ])}
224                                 Lf=pd
225                                 ;;
226                         ("Directory: "*)
227                                 pp=${line##Directory:*([         ])}
228                                 Lf=pp
229                                 ;;
230                         (?*)    # anything else
231                                 Lf=
232                                 ;;
233                         (*)     # empty line
234                                 if [[ -n $pn && -n $pv && -n $pd && -n $pp ]]; then
235                                         i=0
236                                         while (( i < nsrc )); do
237                                                 [[ ${sp_name[i]} = "$pn" && \
238                                                     ${sp_dist[i]} = "$distname" ]] && break
239                                                 let i++
240                                         done
241                                         if (( i == nsrc )); then
242                                                 let nsrc++
243                                                 pvo=
244                                                 ppo=
245                                         else
246                                                 eval pvo=\$\{sp_ver_${suitename}[i]\}
247                                                 eval ppo=\$\{sp_dir_${suitename}[i]\}
248                                         fi
249                                         sp_name[i]=$pn
250                                         sp_dist[i]=$distname
251                                         #sp_suites[i]="${sp_suites[i]} $suitename"
252                                         eval sp_ver_${suitename}[i]='${pvo:+$pvo,}$pv'
253                                         eval sp_dir_${suitename}[i]='${ppo:+$ppo,}$pp/'
254                                         sp_desc[i]=${sp_desc[i]},$pd
255                                 fi
256                                 pn=; pv=; pd=; pp=; Lf=
257                                 ;;
258                         }
259                 done
260
261                 gzip -dc $(for f in $dist/binary-*/Packages.gz; do
262                         [[ -e $f ]] || continue
263                         realpath "$f"
264                 done | sort -u) |&
265                 pn=; pv=; pd=; pp=; pN=; pf=; Lf=
266                 while IFS= read -pr line; do
267                         case $line {
268                         (" "*)
269                                 if [[ -n $Lf ]]; then
270                                         eval x=\$$Lf
271                                         x=$x$line
272                                         eval $Lf=\$x
273                                 fi
274                                 ;;
275                         ("Package: "*)
276                                 pN=${line##Package:*([   ])}
277                                 Lf=pN
278                                 ;;
279                         ("Source: "*)
280                                 pn=${line##Source:*([    ])}
281                                 pn=${pn%% *}
282                                 Lf=pn
283                                 ;;
284                         ("Version: "*)
285                                 pv=${line##Version:*([   ])}
286                                 Lf=pv
287                                 ;;
288                         ("Description: "*)
289                                 pd=${line##Description:*([       ])}
290                                 ;;
291                         ("Architecture: "*)
292                                 pp=${line##Architecture:*([      ])}
293                                 Lf=pp
294                                 ;;
295                         ("Filename: "*)
296                                 pf=${line##Filename:*([  ])}
297                                 Lf=pf
298                                 ;;
299                         (?*)    # anything else
300                                 Lf=
301                                 ;;
302                         (*)     # empty line
303                                 if [[ $pf = *:* || $pf = *'%'* ]]; then
304                                         print -u2 Illegal character in $dist \
305                                             packages $pp "'Filename: $pf'"
306                                         exit 1
307                                 fi
308                                 [[ -n $pn ]] || pn=$pN
309                                 if [[ -n $pn && -n $pv && -n $pd && -n $pp ]]; then
310                                         i=0
311                                         while (( i < nbin )); do
312                                                 [[ ${bp_disp[i]} = "$pN" && ${bp_desc[i]} = "$pd" && \
313                                                     ${bp_dist[i]} = "$distname" ]] && break
314                                                 let i++
315                                         done
316                                         (( i == nbin )) && let nbin++
317                                         bp_name[i]=$pn
318                                         bp_disp[i]=$pN
319                                         bp_dist[i]=$distname
320                                         #bp_suites[i]="${bp_suites[i]} $suitename"
321                                         [[ -n $pf ]] && pv="<a href=\"$pf\">$pv</a>"
322                                         pv="$pp: $pv"
323                                         eval x=\${bp_ver_${suitename}[i]}
324                                         [[ $br$x$br = *"$br$pv$br"* ]] || x=$x${x:+$br}$pv
325                                         eval bp_ver_${suitename}[i]=\$x
326                                         bp_desc[i]=$pd
327                                 fi
328                                 pn=; pv=; pd=; pp=; pN=; pf=; Lf=
329                                 ;;
330                         }
331                 done
332         done
333 done
334
335 (cat <<'EOF'
336 <?xml version="1.0"?>\r
337 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
338  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
339 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head>
340  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
341  <meta name="MSSmartTagsPreventParsing" content="TRUE" />
342 EOF
343 print -r -- " <title>${repo_title} Index</title>"
344 cat <<'EOF'
345  <meta name="generator" content="Evolvis shellsnippets git based on $Id: mvndebri.sh 3150 2012-08-15 11:17:10Z tglase $ based on $MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.56 2012/08/02 21:01:39 tg Exp $" />
346  <style type="text/css">
347   table {
348    border: 1px solid black;
349    border-collapse: collapse;
350    text-align: left;
351    vertical-align: top;
352   }
353   tr {
354    border: 1px solid black;
355    text-align: left;
356    vertical-align: top;
357   }
358   td {
359    border: 1px solid black;
360    text-align: left;
361    vertical-align: top;
362   }
363   th {
364    background-color: #000000;
365    color: #FFFFFF;
366   }
367   .tableheadcell {
368    border: 1px solid #999999;
369    padding: 3px;
370    white-space: nowrap;
371   }
372   .srcpkgline {
373    background-color: #CCCCCC;
374   }
375   .srcpkgdist {
376    background-color: #666666;
377    color: #FFFFFF;
378    font-weight: bold;
379   }
380   .binpkgdist {
381    background-color: #999999;
382    color: #FFFFFF;
383    font-weight: bold;
384   }
385  </style>
386 </head><body>
387 EOF
388 print -r -- "<h1>${repo_title}</h1>"
389 cat <<EOF
390 <p><a href="dists/">Browse</a> the repository.
391  This repository uses <a
392   href="http://pgp.uni-mainz.de:11371/pks/lookup?search=${repo_keyid}&amp;op=vindex">${repo_keyid}</a>
393  as signing key.
394 </p>
395 <h2>Suites</h2>
396 <ul>
397 EOF
398
399 allsuites=$(for suitename in $allsuites; do
400         print $suitename
401 done | sort -u)
402
403 for suitename in $allsuites; do
404         suite=dists/$suitename
405         print -n " <li>${suite##*/}: <a href=\"$suite/\">$jobname for $suitename</a> (dists:"
406         vdists=
407         for dist in $suite/*; do
408                 [[ -d $dist/. ]] || continue
409                 distname=${dist##*/}
410                 vdists="$vdists $distname"
411                 print -n " <a href=\"$suite/$distname/\">$distname</a>"
412         done
413         print ")<br />"
414         print " <tt>deb https://${dhn}/$jobname $suitename$vdists</tt>"
415         print "</li>"
416 done
417 print "</ul>"
418 print "<h2>Packages</h2>"
419 print "<table width=\"100%\"><thead>"
420 print "<tr class=\"tablehead\">"
421 print " <th class=\"tableheadcell\">dist</th>"
422 print " <th class=\"tableheadcell\" rowspan=\"2\">Binary / Description</th>"
423 for suitename in $allsuites; do
424         print " <th class=\"tableheadcell\" rowspan=\"2\">$suitename</th>"
425 done
426 print "</tr><tr class=\"tablehead\">"
427 print " <th class=\"tableheadcell\">package name</th>"
428 print "</tr></thead><tbody>"
429
430 set -A bp_sort
431 i=0
432 while (( i < nbin )); do
433         print $i ${bp_disp[i++]} #${bp_suites[i]}
434 done | sort -k2 |&
435 while read -p num rest; do
436         bp_sort[${#bp_sort[*]}]=$num
437 done
438
439 i=0
440 while (( i < nsrc )); do
441         print $i ${sp_name[i++]}
442 done | sort -k2 |&
443 while read -p num rest; do
444         print "\n<!-- sp #$num = ${sp_name[num]} -->"
445         print "<tr class=\"srcpkgline\">"
446         print " <td class=\"srcpkgdist\">${sp_dist[num]}</td>"
447         pd=
448         for x in $(tr ', ' '\n' <<<"${sp_desc[num]}" | sort -u); do
449                 [[ -n $x ]] && pd="$pd, $x"
450         done
451         print " <td rowspan=\"2\" class=\"srcpkgdesc\">${pd#, }</td>"
452         for suitename in $allsuites; do
453                 eval pvo=\${sp_ver_${suitename}[num]}
454                 eval ppo=\${sp_dir_${suitename}[num]}
455                 IFS=,
456                 set -A pva -- $pvo
457                 set -A ppa -- $ppo
458                 IFS=$saveIFS
459                 (( ${#pva[*]} )) || pva[0]=
460                 y=
461                 i=0
462                 while (( i < ${#pva[*]} )); do
463                         pv=${pva[i]}
464                         pp=${ppa[i]}
465                         if [[ $pv = *"\1a"* ]]; then
466                                 pvdsc=${pv%%"\1a"*}
467                                 pv=${pv##*"\1a"}
468                         else
469                                 pvdsc=$pv
470                         fi
471                         if [[ -z $pv ]]; then
472                                 pv=-
473                         elif [[ $pp != ?(/) ]]; then
474                                 pv="<a href=\"$pp${sp_name[num]}_${pvdsc##+([0-9]):}.dsc\">$pv</a>"
475                         fi
476                         [[ $pp != ?(/) ]] && pv="<a href=\"$pp\">[dir]</a> $pv"
477                         y=${y:+"$y<br />"}$pv
478                         let i++
479                 done
480                 print " <td rowspan=\"2\" class=\"srcpkgitem\">$y</td>"
481         done
482         print "</tr><tr class=\"srcpkgline\">"
483         print " <td class=\"srcpkgname\">${sp_name[num]}</td>"
484         print "</tr>"
485         k=0
486         while (( k < nbin )); do
487                 (( (i = bp_sort[k++]) < 0 )) && continue
488                 [[ ${bp_name[i]} = "${sp_name[num]}" && \
489                     ${bp_dist[i]} = "${sp_dist[num]}" ]] || continue
490                 bp_sort[k - 1]=-1
491                 #print "<!-- bp #$i for${bp_suites[i]} -->"
492                 print "<!-- bp #$i -->"
493                 print "<tr class=\"binpkgline\">"
494                 print " <td class=\"binpkgname\">${bp_disp[i]}</td>"
495                 print " <td class=\"binpkgdesc\">${bp_desc[i]}</td>"
496                 for suitename in $allsuites; do
497                         eval pv=\${bp_ver_${suitename}[i]}
498                         if [[ -z $pv ]]; then
499                                 pv=-
500                         fi
501                         print " <td class=\"binpkgitem\">$pv</td>"
502                 done
503                 print "</tr>"
504         done
505 done
506
507 num=0
508 for i in ${bp_sort[*]}; do
509         (( i < 0 )) && continue
510         if (( !num )); then
511                 print "\n<!-- sp ENOENT -->"
512                 print "<tr class=\"srcpkgline\">"
513                 print " <td class=\"srcpkgname\">~ENOENT~</td>"
514                 print " <td class=\"srcpkgdesc\">binary" \
515                     "packages without a matching source package</td>"
516                 for suitename in $allsuites; do
517                         print " <td class=\"srcpkgitem\">-</td>"
518                 done
519                 print "</tr>"
520                 num=1
521         fi
522         #print "<!-- bp #$i for${bp_suites[i]} -->"
523         print "<!-- bp #$i -->"
524         print "<tr class=\"binpkgline\">"
525         print " <td class=\"binpkgdist\">${bp_dist[i]}</td>"
526         print " <td rowspan=\"2\" class=\"binpkgdesc\">${bp_desc[i]}</td>"
527         for suitename in $allsuites; do
528                 eval pv=\${bp_ver_${suitename}[i]}
529                 if [[ -z $pv ]]; then
530                         pv=-
531                 fi
532                 print " <td rowspan=\"2\" class=\"binpkgitem\">$pv</td>"
533         done
534         print "</tr><tr class=\"binpkgline\">"
535         print " <td class=\"binpkgname\">${bp_disp[i]}</td>"
536         print "</tr>"
537 done
538
539 cat <<EOF
540
541 </tbody></table>
542
543 <p>• <a href="http://validator.w3.org/check/referer">Valid XHTML/1.1!</a>
544  • <small>Generated on $(date -u +'%F %T') by <tt
545  style="white-space:pre;">$rcsid</tt></small> •</p>
546 </body></html>
547 EOF
548
549 :) >debidx.htm
550 print done.