macos: packaging support for MacOS X 10.13
[openafs.git] / src / packaging / MacOS / pkgbuild.sh.in
1 #!/bin/bash
2 # Portions Copyright (c) 2003, 2006 Apple Computer, Inc.  All rights reserved.
3 echo '**BUILDPKG**' "$@"
4
5 usage() {
6     exec >&2
7
8     echo 'Usage: pkgbuild.sh [-x] [--app-key <appkey>] [--inst-key <instkey>]'
9     echo '                   [--pass N] [--csdb <CellServDB>] <binary-dir>'
10     echo
11     echo '--app-key and --inst-key are for signing. -x prints all comamnds as '
12     echo 'they are run.'
13     echo
14     echo 'By default, all passes are run. Available passes:'
15     echo '    --pass 1: prepare pkgroot'
16     echo '    --pass 2: create packages/installer from pkgroot'
17     echo 'If you want to alter the pkgroot, run pass 1, then alter what you'
18     echo 'want, and then run pass 2 to create the resulting packages.'
19     echo 'The --pass argument may be given multiple times.'
20     exit 1
21 }
22
23 if [ x"$#" = x0 ]; then
24     usage
25 fi
26
27 anypass=0
28 PASS1=
29 PASS2=
30
31 APP_KEY=
32 INST_KEY=
33 DEST_DIR=
34 CSDB=
35
36 while [ x"$#" != x0 ] ; do
37     key="$1"
38     shift
39
40     case "$key" in
41     --app-key)
42         APP_KEY="$1"
43         shift
44         ;;
45     --inst-key)
46         INST_KEY="$1"
47         shift
48         ;;
49     --csdb)
50         CSDB="$1"
51         shift
52         ;;
53     --pass)
54         anypass=1
55         pass_arg="$1"
56         shift
57         case "$pass_arg" in
58         1)
59             PASS1=1
60             ;;
61         2)
62             PASS2=1
63             ;;
64         *)
65             echo "Unknown pass $pass_arg" >&2
66             exit 1
67             ;;
68         esac
69         ;;
70     -x)
71         DO_X=1
72         ;;
73     *)
74         if [ x"$DEST_DIR" = x ] ; then
75             DEST_DIR="$key"
76         else
77             echo "Error: Unknown arg $key" >&2
78             usage
79         fi
80         ;;
81     esac
82 done
83
84 if [ x"$anypass" = x0 ] ; then
85     PASS1=1
86     PASS2=1
87 fi
88
89 if [ x"$DEST_DIR" = x ] ; then
90     echo "Error: binary 'dest' dir not given"
91     usage
92 fi
93
94 set -e
95
96 if [ x"$DO_X" = x1 ] ; then
97     set -x
98 fi
99
100 BINDEST=`cd "$DEST_DIR" && pwd`
101 CURDIR=`pwd`
102 RESSRC=`dirname "$0"`
103 RESSRC=`cd "$RESSRC" && pwd`
104 majorvers=`uname -r | cut -d. -f1`
105
106 if [ x"$majorvers" = x10 ]; then
107     RELNAME="Snowleopard"
108     THISREL=6
109
110 elif [ x"$majorvers" = x11 ]; then
111     RELNAME="Lion"
112     THISREL=7
113
114 elif [ x"$majorvers" = x12 ]; then
115     RELNAME="MountainLion"
116     THISREL=8
117
118 elif [ x"$majorvers" = x13 ]; then
119     RELNAME="Mavericks"
120     THISREL=9
121
122 elif [ x"$majorvers" = x14 ]; then
123     RELNAME="Yosemite"
124     THISREL=10
125
126 elif [ x"$majorvers" = x15 ]; then
127     RELNAME="ElCapitan"
128     THISREL=11
129
130 elif [ x"$majorvers" = x16 ]; then
131     RELNAME="Sierra"
132     THISREL=12
133
134 elif [ x"$majorvers" = x17 ]; then
135     RELNAME="HighSierra"
136     THISREL=13
137
138 elif [ x"$majorvers" = x ] ; then
139     echo "Error running uname" >&2
140     exit 1
141
142 else
143     echo "Unknown major version $majorvers" >&2
144     exit 1
145 fi
146
147 SEP=:
148
149 PKGROOT="$CURDIR"/pkgroot
150 PKGRES="$CURDIR"/pkgres
151 DPKGROOT="$CURDIR"/dpkgroot
152 PLUGINS="$CURDIR"/plugins
153 if test -e /usr/bin/pkgbuild; then
154     :
155 else
156     echo pkgbuild not found >&2
157     exit 1
158 fi
159 if test -e /usr/bin/productbuild; then
160     :
161 else
162     echo productbuild not found >&2
163     exit 1
164 fi
165
166 if [ x"$PASS1" = x1 ]; then
167     if [ -x /usr/bin/curl ] && [ x"$CSDB" = x ]; then
168         echo "No CellServDB provided; downloading one from central.org"
169         /usr/bin/curl -f -O https://www.central.org/dl/cellservdb/CellServDB
170         if [ -f "$CURDIR"/CellServDB ] ; then
171             CSDB="$CURDIR"/CellServDB
172         fi
173     fi
174
175     if [ x"$CSDB" = x ]; then
176         echo "A CellServDB file must be provided with --csdb" >&2
177         die=1
178     else
179         # Turn CSDB into an absolute path
180         case "$CSDB" in
181         /*)
182             ;;
183         *)
184             CSDB="$CURDIR/$CSDB"
185             ;;
186         esac
187
188         if grep -q 'GCO Public CellServDB' "$CSDB" ; then
189             touch "$CSDB"
190         else
191             echo "A proper CellServDB file must be provided" >&2
192             die=1
193         fi
194     fi
195
196     for f in ReadMe.rtf."$majorvers" \
197              License.rtf \
198              CellServDB.list \
199              OpenAFS.info \
200              OpenAFS.post_install \
201              OpenAFS.pre_upgrade \
202              csrvdbmerge.pl \
203              2.0.txt
204     do
205         if [ ! -f "$RESSRC/$f" ]; then
206             echo "file missing: $RESSRC/$f" >&2
207             die=1
208         fi
209     done
210     if [ x"$die" = x1 ]; then
211         echo "Correct above errors; then retry" >&2
212         exit 1
213     fi
214
215     for f in "$BINDEST"/bin/translate_et \
216              "$BINDEST/root.client/usr/vice/etc/afs.kext/Contents/MacOS/afs"
217     do
218         if [ ! -f "$f" ] ; then
219             echo "dest file missing: $f" >&2
220             die=1
221         fi
222     done
223     if [ x"$die" = x1 ]; then
224         echo $BINDEST " is not a valid binary dir. it should be the result of" >&2
225         echo "make dest" >&2
226         exit 1
227     fi
228
229     rm -rf "$PKGROOT" "$PLUGINS"
230     mkdir "$PKGROOT"
231     mkdir "$PLUGINS"
232
233     mkdir -p "$PKGROOT"/Library
234     mkdir -p "$PKGROOT"/Library/PreferencePanes
235     mkdir -p "$PKGROOT"/Library/Security/SecurityAgentPlugins
236
237     chown -R root${SEP}admin "$PKGROOT"
238     chmod -R 755 "$PKGROOT"
239
240     (cd "$BINDEST"/tools && pax -rw OpenAFS.prefPane "$PKGROOT"/Library/PreferencePanes/)
241     (cd "$BINDEST"/tools && pax -rw aklog.bundle \
242     "$PKGROOT"/Library/Security/SecurityAgentPlugins/)
243
244     mkdir -p "$PKGROOT"/Library/OpenAFS/Tools
245     (cd "$BINDEST" && pax -rw * "$PKGROOT"/Library/OpenAFS/Tools)
246
247     cd "$RESSRC"
248     mv "$PKGROOT"/Library/OpenAFS/Tools/installer/* "$PLUGINS"/
249
250     mkdir -p "$PKGROOT"/Library/LaunchDaemons
251     chmod -R o-w "$PKGROOT"/Library
252     chmod -R g-w "$PKGROOT"/Library
253
254     cp openafs.launchd.plist "$PKGROOT"/Library/LaunchDaemons/org.openafs.filesystems.afs.plist
255     chmod 644 "$PKGROOT"/Library/LaunchDaemons/org.openafs.filesystems.afs.plist
256
257     chown root${SEP}admin "$PKGROOT"/Library
258     chown -R root${SEP}wheel "$PKGROOT"/Library/LaunchDaemons
259     chown -R root${SEP}wheel "$PKGROOT"/Library/OpenAFS/Tools
260     chmod -R og-w "$PKGROOT"/Library/OpenAFS/Tools
261
262     mkdir -p "$PKGROOT"/private/var/db/openafs/cache
263     mkdir -p "$PKGROOT"/private/var/db/openafs/etc/config
264
265     cp openafs.launchdaemon "$PKGROOT"/private/var/db/openafs/etc/launchafs.sh
266     chmod 755 "$PKGROOT"/private/var/db/openafs/etc/launchafs.sh
267
268     cp "$CSDB" "$PKGROOT"/private/var/db/openafs/etc/CellServDB.master
269     echo grand.central.org > "$PKGROOT"/private/var/db/openafs/etc/ThisCell.sample
270     echo /afs:/var/db/openafs/cache:100000 > \
271          "$PKGROOT"/private/var/db/openafs/etc/cacheinfo.sample
272
273     cp -RP "$PKGROOT"/Library/OpenAFS/Tools/etc/afssettings \
274            "$PKGROOT"/private/var/db/openafs/etc/config
275     cp settings.plist "$PKGROOT"/private/var/db/openafs/etc/config/settings.plist.orig
276     cp afs.conf "$PKGROOT"/private/var/db/openafs/etc/config/afs.conf.sample
277     cp krb5-weak.conf "$PKGROOT"/private/var/db/openafs/etc/krb5-weak.conf
278
279     cp decode-panic "$PKGROOT"/Library/OpenAFS/Tools/tools
280     chmod a+x "$PKGROOT"/Library/OpenAFS/Tools/tools/decode-panic
281
282     rm -rf "$DPKGROOT"
283     mkdir "$DPKGROOT"
284     mkdir -p "$DPKGROOT"/Library/OpenAFS/Debug
285
286     mv "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext.dSYM \
287        "$DPKGROOT"/Library/OpenAFS/Debug/
288     cp -RP "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext \
289            "$DPKGROOT"/Library/OpenAFS/Debug/
290     chown -R root${SEP}wheel "$DPKGROOT"/Library/OpenAFS/Debug
291     chmod -R og-w "$DPKGROOT"/Library/OpenAFS/Debug
292
293     strip -X -S \
294         "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext/Contents/MacOS/afs
295
296     mkdir -p "$PKGROOT"/private/var/db/openafs
297
298     cp -RP "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext \
299            "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/C \
300            "$PKGROOT"/private/var/db/openafs/etc
301
302     chown -R root${SEP}wheel "$PKGROOT"/private
303     chmod -R og-w "$PKGROOT"/private
304
305     chown -R root${SEP}wheel "$PKGROOT"/private
306     chmod -R og-w "$PKGROOT"/private
307     chmod  og-rx "$PKGROOT"/private/var/db/openafs/cache
308
309     if [ x"$APP_KEY" != x ] ; then
310         # Sign each 'thing' that we have (commands, kexts, etc)
311         for obj in "$DPKGROOT"/Library/OpenAFS/Debug/afs.kext \
312                    "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext \
313                    "$PKGROOT"/private/var/db/openafs/etc/afs.kext \
314                    "$PKGROOT"/Library/PreferencePanes/OpenAFS.prefPane/Contents/Resources/AFSBackgrounder.app \
315                    "$PKGROOT"/Library/PreferencePanes/OpenAFS.prefPane \
316                    "$PKGROOT"/Library/Security/SecurityAgentPlugins/aklog.bundle \
317                    "$PKGROOT"/Library/OpenAFS/Tools/tools/growlagent-openafs.app \
318                    "$PKGROOT"/Library/OpenAFS/Tools/tools/aklog.bundle \
319                    "$PLUGINS"/afscell.bundle
320         do
321             codesign --verbose --force --timestamp --sign "$APP_KEY" "$obj"
322         done
323
324         # Check if our signatures for our kexts are valid. 'kextutil' will exit
325         # with an error and print out a message if something is wrong with the
326         # signature. Note that a code signing cert must have the
327         # 1.2.840.113635.100.6.1.18 extension present to be used for kexts
328         # (most code signing certs cannot be used for kexts).
329         for kext in "$DPKGROOT"/Library/OpenAFS/Debug/afs.kext \
330                     "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext \
331                     "$PKGROOT"/private/var/db/openafs/etc/afs.kext
332         do
333             kextutil -no-load -print-diagnostics "$kext"
334         done
335     fi
336
337     if [ $majorvers -ge 15 ]; then
338         # El Capitan and further prevent us from touching /usr/bin directly
339         PREFIX=/opt
340         USRBIN=/opt/openafs/bin
341         USRBIN2TOOLS=../../../Library/OpenAFS/Tools
342
343         USRSBIN=/opt/openafs/sbin
344         USRSBIN2TOOLS=../../../Library/OpenAFS/Tools
345
346         MANDIR=/opt/openafs/share/man
347         MANDIR2TOOLS=../../../../Library/OpenAFS/Tools
348
349         # Add our bin, sbin, and man directories to the default search path
350         mkdir -p "$PKGROOT"/etc/paths.d "$PKGROOT"/etc/manpaths.d
351         echo "$USRBIN" > "$PKGROOT"/etc/paths.d/40-openafs
352         echo "$USRSBIN" >> "$PKGROOT"/etc/paths.d/40-openafs
353         echo "$MANDIR" > "$PKGROOT"/etc/manpaths.d/40-openafs
354     else
355         PREFIX=/usr
356         USRBIN=/usr/bin
357         USRBIN2TOOLS=../../Library/OpenAFS/Tools
358
359         USRSBIN=/usr/sbin
360         USRSBIN2TOOLS="$USRBIN2TOOLS"
361
362         MANDIR=/usr/share/man
363         MANDIR2TOOLS=../../../Library/OpenAFS/Tools
364     fi
365
366     mkdir -p "$PKGROOT$USRBIN" \
367              "$PKGROOT$USRSBIN" \
368              "$PKGROOT$MANDIR"/man1 \
369              "$PKGROOT$MANDIR"/man5 \
370              "$PKGROOT$MANDIR"/man8
371
372     BINLIST="fs klog klog.krb pagsh pagsh.krb pts sys tokens tokens.krb unlog unlog.krb aklog"
373     ETCLIST="vos"
374
375     if [ x"$DO_X" = x1 ] ; then
376         # Don't print out every single 'ln -s'... that's kinda useless
377         : 'Symlinking commands and manpages into place...'
378         set +x
379     fi
380
381     for f in $BINLIST; do
382         ln -s "$USRBIN2TOOLS"/bin/"$f" "$PKGROOT$USRBIN/$f"
383     done
384     for f in $ETCLIST; do
385         ln -s "$USRSBIN2TOOLS"/etc/"$f" "$PKGROOT$USRSBIN/$f"
386     done
387
388     for section in man1 man5 man8 ; do
389         for f in $(ls $PKGROOT/Library/OpenAFS/Tools/man/$section); do
390
391             if [ -L "$PKGROOT/Library/OpenAFS/Tools/man/$section/$f" ] ; then
392                 # If this manpage is a symlink, just change where it's pointing,
393                 # and rename the link; don't actually 'gzip' it.
394                 link=$(readlink "$PKGROOT/Library/OpenAFS/Tools/man/$section/$f")
395                 rm -f "$PKGROOT/Library/OpenAFS/Tools/man/$section/$f"
396                 ln -s "$link".gz "$PKGROOT/Library/OpenAFS/Tools/man/$section/$f".gz
397
398             else
399                 gzip -9 "$PKGROOT/Library/OpenAFS/Tools/man/$section/$f"
400             fi
401             ln -s ../"$MANDIR2TOOLS"/man/"$section/$f".gz \
402                   "$PKGROOT$MANDIR/$section/$f".gz
403         done
404     done
405
406     if [ x"$DO_X" = x1 ] ; then
407         set -x
408     fi
409
410     ln -s "$USRBIN2TOOLS"/bin/kpasswd "$PKGROOT$USRBIN"/kpasswd.afs
411
412     ln -s "$USRSBIN2TOOLS"/root.client/usr/vice/etc/afsd "$PKGROOT$USRSBIN"/afsd
413
414     chown -R root${SEP}wheel "$PKGROOT$PREFIX"
415     chmod -R og-w "$PKGROOT$PREFIX"
416 fi
417
418 if [ x"$PASS2" = x1 ]; then
419     rm -rf "$PKGRES"
420     mkdir "$PKGRES"
421     cd "$RESSRC"
422
423     rm -rf "$CURDIR"/OpenAFS-debug-extension.pkg
424     /usr/bin/pkgbuild --root "$DPKGROOT" --id org.openafs.OpenAFS-debug.pkg \
425                       --version '@VERSION@' \
426              "$CURDIR"/OpenAFS-debug-extension.pkg
427
428     cd "$RESSRC"
429     cp OpenAFS.post_install "$PKGRES"/postinstall
430     cp OpenAFS.pre_upgrade "$PKGRES"/preupgrade
431     cp OpenAFS.post_install "$PKGRES"/postupgrade
432     cp csrvdbmerge.pl "$PKGRES"
433
434     chmod a+x "$PKGRES"/csrvdbmerge.pl \
435               "$PKGRES"/postinstall \
436               "$PKGRES"/postupgrade \
437               "$PKGRES"/preupgrade
438
439     cp CellServDB.list "$PKGRES"
440     chown -R root${SEP}wheel "$PKGRES"
441
442     rm -rf "$CURDIR"/OpenAFS-dist.pkg
443     /usr/bin/pkgbuild --root "$PKGROOT" --id org.openafs.OpenAFS.pkg \
444                       --version '@VERSION@' \
445                       --scripts "$PKGRES" "$CURDIR"/OpenAFS-dist.pkg
446
447     rm -rf "$PKGRES"
448     mkdir "$PKGRES"
449     cp background.jpg "$PKGRES"/background.jpg
450     cp License.rtf "$PKGRES"
451     cp ReadMe.rtf."$majorvers" "$PKGRES"/ReadMe.rtf
452     chown -R root${SEP}wheel "$PKGRES"
453
454     if [ $majorvers -ge 15 ] ; then
455         # For El Capitan and further, we have some extra information to tell
456         # the user at the end of the installation process.
457         cp conclusion.txt "$PKGRES"/conclusion.txt
458         PRES_EXTRA="<conclusion file=\"conclusion.txt\"/>"
459     fi
460
461     # generate Distribution.xml from Distribution.xml.in -- nonstandard substs
462     sed -e "s/%%OSX_MAJOR_CUR%%/$THISREL/g" \
463         -e "s/%%OSX_MAJOR_NEXT%%/$(( $THISREL + 1 ))/g" \
464         -e "s,%%PRES_EXTRA%%,$PRES_EXTRA,g" \
465         -e "s/%%OPENAFS_VERSION%%/@VERSION@/g" \
466         < Distribution.xml.in > Distribution.xml
467
468     rm -rf "$CURDIR/prod"
469     mkdir "$CURDIR/prod"
470     mv "$CURDIR"/OpenAFS-dist.pkg "$CURDIR"/OpenAFS-debug-extension.pkg "$CURDIR"/prod
471     /usr/bin/productbuild --distribution Distribution.xml --resources "$PKGRES" \
472                           --plugins "$PLUGINS" --package-path "$CURDIR"/prod "$CURDIR"/OpenAFS.pkg
473
474     if [ x"$INST_KEY" != x ] ; then
475         mv "$CURDIR"/OpenAFS.pkg "$CURDIR"/OpenAFS-unsigned.pkg
476         productsign --timestamp --sign "$INST_KEY" "$CURDIR"/OpenAFS-unsigned.pkg \
477                     "$CURDIR"/OpenAFS.pkg
478         rm -f "$CURDIR"/OpenAFS-unsigned.pkg
479     fi
480
481     rm -rf "$CURDIR/dmg"
482     rm -f "$CURDIR/TMP.dmg"
483     rm -rf "$CURDIR/OpenAFS-@VERSION@-$RELNAME.dmg"
484
485     mkdir "$CURDIR"/dmg
486     mv "$CURDIR"/OpenAFS.pkg "$CURDIR"/dmg
487     cp "$RESSRC"/Uninstall.14.15 "$CURDIR"/dmg/Uninstall.command
488     cp "$RESSRC"/DS_Store "$CURDIR"/dmg/.DS_Store
489     mkdir "$CURDIR"/dmg/.background
490     cp "$RESSRC"/afslogo.jpg "$CURDIR"/dmg/.background
491
492     if [ x"$APP_KEY" != x ] ; then
493         codesign --verbose --force --timestamp --sign "$APP_KEY" "$CURDIR"/dmg/Uninstall.command
494     fi
495
496     hdiutil create -srcfolder "$CURDIR"/dmg -volname OpenAFS \
497             -o "$CURDIR"/TMP.dmg
498     hdiutil convert -format UDZO "$CURDIR"/TMP.dmg \
499             -o "$CURDIR/OpenAFS-@VERSION@-$RELNAME".dmg
500
501     echo
502     echo "Created $CURDIR/OpenAFS-@VERSION@-$RELNAME".dmg
503 fi