macos: packaging support for MacOS X 10.15
[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" = x18 ]; then
139     RELNAME="Mojave"
140     THISREL=14
141
142 elif [ x"$majorvers" = x19 ]; then
143     RELNAME="Catalina"
144     THISREL=15
145
146 elif [ x"$majorvers" = x ] ; then
147     echo "Error running uname" >&2
148     exit 1
149
150 else
151     echo "Unknown major version $majorvers" >&2
152     exit 1
153 fi
154
155 SEP=:
156
157 PKGROOT="$CURDIR"/pkgroot
158 PKGRES="$CURDIR"/pkgres
159 DPKGROOT="$CURDIR"/dpkgroot
160 PLUGINS="$CURDIR"/plugins
161 if test -e /usr/bin/pkgbuild; then
162     :
163 else
164     echo pkgbuild not found >&2
165     exit 1
166 fi
167 if test -e /usr/bin/productbuild; then
168     :
169 else
170     echo productbuild not found >&2
171     exit 1
172 fi
173
174 if [ x"$PASS1" = x1 ]; then
175     if [ -x /usr/bin/curl ] && [ x"$CSDB" = x ]; then
176         echo "No CellServDB provided; downloading one from central.org"
177         /usr/bin/curl -f -O https://www.central.org/dl/cellservdb/CellServDB
178         if [ -f "$CURDIR"/CellServDB ] ; then
179             CSDB="$CURDIR"/CellServDB
180         fi
181     fi
182
183     if [ x"$CSDB" = x ]; then
184         echo "A CellServDB file must be provided with --csdb" >&2
185         die=1
186     else
187         # Turn CSDB into an absolute path
188         case "$CSDB" in
189         /*)
190             ;;
191         *)
192             CSDB="$CURDIR/$CSDB"
193             ;;
194         esac
195
196         if grep -q 'GCO Public CellServDB' "$CSDB" ; then
197             touch "$CSDB"
198         else
199             echo "A proper CellServDB file must be provided" >&2
200             die=1
201         fi
202     fi
203
204     for f in ReadMe.rtf."$majorvers" \
205              License.rtf \
206              CellServDB.list \
207              OpenAFS.info \
208              OpenAFS.post_install \
209              OpenAFS.pre_upgrade \
210              csrvdbmerge.pl \
211              2.0.txt
212     do
213         if [ ! -f "$RESSRC/$f" ]; then
214             echo "file missing: $RESSRC/$f" >&2
215             die=1
216         fi
217     done
218     if [ x"$die" = x1 ]; then
219         echo "Correct above errors; then retry" >&2
220         exit 1
221     fi
222
223     for f in "$BINDEST"/bin/translate_et \
224              "$BINDEST/root.client/usr/vice/etc/afs.kext/Contents/MacOS/afs"
225     do
226         if [ ! -f "$f" ] ; then
227             echo "dest file missing: $f" >&2
228             die=1
229         fi
230     done
231     if [ x"$die" = x1 ]; then
232         echo $BINDEST " is not a valid binary dir. it should be the result of" >&2
233         echo "make dest" >&2
234         exit 1
235     fi
236
237     rm -rf "$PKGROOT" "$PLUGINS"
238     mkdir "$PKGROOT"
239     mkdir "$PLUGINS"
240
241     mkdir -p "$PKGROOT"/Library
242     mkdir -p "$PKGROOT"/Library/PreferencePanes
243     mkdir -p "$PKGROOT"/Library/Security/SecurityAgentPlugins
244
245     chown -R root${SEP}admin "$PKGROOT"
246     chmod -R 755 "$PKGROOT"
247
248     (cd "$BINDEST"/tools && pax -rw OpenAFS.prefPane "$PKGROOT"/Library/PreferencePanes/)
249     (cd "$BINDEST"/tools && pax -rw aklog.bundle \
250     "$PKGROOT"/Library/Security/SecurityAgentPlugins/)
251
252     mkdir -p "$PKGROOT"/Library/OpenAFS/Tools
253     (cd "$BINDEST" && pax -rw * "$PKGROOT"/Library/OpenAFS/Tools)
254
255     cd "$RESSRC"
256     mv "$PKGROOT"/Library/OpenAFS/Tools/installer/* "$PLUGINS"/
257
258     mkdir -p "$PKGROOT"/Library/LaunchDaemons
259     chmod -R o-w "$PKGROOT"/Library
260     chmod -R g-w "$PKGROOT"/Library
261
262     cp openafs.launchd.plist "$PKGROOT"/Library/LaunchDaemons/org.openafs.filesystems.afs.plist
263     chmod 644 "$PKGROOT"/Library/LaunchDaemons/org.openafs.filesystems.afs.plist
264
265     chown root${SEP}admin "$PKGROOT"/Library
266     chown -R root${SEP}wheel "$PKGROOT"/Library/LaunchDaemons
267     chown -R root${SEP}wheel "$PKGROOT"/Library/OpenAFS/Tools
268     chmod -R og-w "$PKGROOT"/Library/OpenAFS/Tools
269
270     mkdir -p "$PKGROOT"/private/var/db/openafs/cache
271     mkdir -p "$PKGROOT"/private/var/db/openafs/etc/config
272
273     cp openafs.launchdaemon "$PKGROOT"/private/var/db/openafs/etc/launchafs.sh
274     chmod 755 "$PKGROOT"/private/var/db/openafs/etc/launchafs.sh
275
276     cp "$CSDB" "$PKGROOT"/private/var/db/openafs/etc/CellServDB.master
277     echo grand.central.org > "$PKGROOT"/private/var/db/openafs/etc/ThisCell.sample
278     echo /afs:/var/db/openafs/cache:100000 > \
279          "$PKGROOT"/private/var/db/openafs/etc/cacheinfo.sample
280
281     cp -RP "$PKGROOT"/Library/OpenAFS/Tools/etc/afssettings \
282            "$PKGROOT"/private/var/db/openafs/etc/config
283     cp settings.plist "$PKGROOT"/private/var/db/openafs/etc/config/settings.plist.orig
284     cp afs.conf "$PKGROOT"/private/var/db/openafs/etc/config/afs.conf.sample
285     cp krb5-weak.conf "$PKGROOT"/private/var/db/openafs/etc/krb5-weak.conf
286
287     cp decode-panic "$PKGROOT"/Library/OpenAFS/Tools/tools
288     chmod a+x "$PKGROOT"/Library/OpenAFS/Tools/tools/decode-panic
289
290     rm -rf "$DPKGROOT"
291     mkdir "$DPKGROOT"
292     mkdir -p "$DPKGROOT"/Library/OpenAFS/Debug
293
294     mv "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext.dSYM \
295        "$DPKGROOT"/Library/OpenAFS/Debug/
296     cp -RP "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext \
297            "$DPKGROOT"/Library/OpenAFS/Debug/
298     chown -R root${SEP}wheel "$DPKGROOT"/Library/OpenAFS/Debug
299     chmod -R og-w "$DPKGROOT"/Library/OpenAFS/Debug
300
301     strip -X -S \
302         "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext/Contents/MacOS/afs
303
304     mkdir -p "$PKGROOT"/private/var/db/openafs
305
306     cp -RP "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext \
307            "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/C \
308            "$PKGROOT"/private/var/db/openafs/etc
309
310     chown -R root${SEP}wheel "$PKGROOT"/private
311     chmod -R og-w "$PKGROOT"/private
312
313     chown -R root${SEP}wheel "$PKGROOT"/private
314     chmod -R og-w "$PKGROOT"/private
315     chmod  og-rx "$PKGROOT"/private/var/db/openafs/cache
316
317     if [ x"$APP_KEY" != x ] ; then
318         # Sign each 'thing' that we have (commands, kexts, etc)
319         for obj in "$DPKGROOT"/Library/OpenAFS/Debug/afs.kext \
320                    "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext \
321                    "$PKGROOT"/private/var/db/openafs/etc/afs.kext \
322                    "$PKGROOT"/Library/PreferencePanes/OpenAFS.prefPane/Contents/Resources/AFSBackgrounder.app \
323                    "$PKGROOT"/Library/PreferencePanes/OpenAFS.prefPane \
324                    "$PKGROOT"/Library/Security/SecurityAgentPlugins/aklog.bundle \
325                    "$PKGROOT"/Library/OpenAFS/Tools/tools/growlagent-openafs.app \
326                    "$PKGROOT"/Library/OpenAFS/Tools/tools/aklog.bundle \
327                    "$PLUGINS"/afscell.bundle
328         do
329             codesign --verbose --force --timestamp --sign "$APP_KEY" "$obj"
330         done
331
332         # Check if our signatures for our kexts are valid. 'kextutil' will exit
333         # with an error and print out a message if something is wrong with the
334         # signature. Note that a code signing cert must have the
335         # 1.2.840.113635.100.6.1.18 extension present to be used for kexts
336         # (most code signing certs cannot be used for kexts).
337         for kext in "$DPKGROOT"/Library/OpenAFS/Debug/afs.kext \
338                     "$PKGROOT"/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.kext \
339                     "$PKGROOT"/private/var/db/openafs/etc/afs.kext
340         do
341             kextutil -no-load -print-diagnostics "$kext"
342         done
343     fi
344
345     if [ $majorvers -ge 15 ]; then
346         # El Capitan and further prevent us from touching /usr/bin directly
347         PREFIX=/opt
348         USRBIN=/opt/openafs/bin
349         USRBIN2TOOLS=../../../Library/OpenAFS/Tools
350
351         USRSBIN=/opt/openafs/sbin
352         USRSBIN2TOOLS=../../../Library/OpenAFS/Tools
353
354         MANDIR=/opt/openafs/share/man
355         MANDIR2TOOLS=../../../../Library/OpenAFS/Tools
356
357         # Add our bin, sbin, and man directories to the default search path
358         mkdir -p "$PKGROOT"/etc/paths.d "$PKGROOT"/etc/manpaths.d
359         echo "$USRBIN" > "$PKGROOT"/etc/paths.d/40-openafs
360         echo "$USRSBIN" >> "$PKGROOT"/etc/paths.d/40-openafs
361         echo "$MANDIR" > "$PKGROOT"/etc/manpaths.d/40-openafs
362     else
363         PREFIX=/usr
364         USRBIN=/usr/bin
365         USRBIN2TOOLS=../../Library/OpenAFS/Tools
366
367         USRSBIN=/usr/sbin
368         USRSBIN2TOOLS="$USRBIN2TOOLS"
369
370         MANDIR=/usr/share/man
371         MANDIR2TOOLS=../../../Library/OpenAFS/Tools
372     fi
373
374     mkdir -p "$PKGROOT$USRBIN" \
375              "$PKGROOT$USRSBIN" \
376              "$PKGROOT$MANDIR"/man1 \
377              "$PKGROOT$MANDIR"/man5 \
378              "$PKGROOT$MANDIR"/man8
379
380     BINLIST="fs klog klog.krb pagsh pagsh.krb pts sys tokens tokens.krb unlog unlog.krb aklog"
381     ETCLIST="vos"
382
383     if [ x"$DO_X" = x1 ] ; then
384         # Don't print out every single 'ln -s'... that's kinda useless
385         : 'Symlinking commands and manpages into place...'
386         set +x
387     fi
388
389     for f in $BINLIST; do
390         ln -s "$USRBIN2TOOLS"/bin/"$f" "$PKGROOT$USRBIN/$f"
391     done
392     for f in $ETCLIST; do
393         ln -s "$USRSBIN2TOOLS"/etc/"$f" "$PKGROOT$USRSBIN/$f"
394     done
395
396     for section in man1 man5 man8 ; do
397         for f in $(ls $PKGROOT/Library/OpenAFS/Tools/man/$section); do
398
399             if [ -L "$PKGROOT/Library/OpenAFS/Tools/man/$section/$f" ] ; then
400                 # If this manpage is a symlink, just change where it's pointing,
401                 # and rename the link; don't actually 'gzip' it.
402                 link=$(readlink "$PKGROOT/Library/OpenAFS/Tools/man/$section/$f")
403                 rm -f "$PKGROOT/Library/OpenAFS/Tools/man/$section/$f"
404                 ln -s "$link".gz "$PKGROOT/Library/OpenAFS/Tools/man/$section/$f".gz
405
406             else
407                 gzip -9 "$PKGROOT/Library/OpenAFS/Tools/man/$section/$f"
408             fi
409             ln -s ../"$MANDIR2TOOLS"/man/"$section/$f".gz \
410                   "$PKGROOT$MANDIR/$section/$f".gz
411         done
412     done
413
414     if [ x"$DO_X" = x1 ] ; then
415         set -x
416     fi
417
418     ln -s "$USRBIN2TOOLS"/bin/kpasswd "$PKGROOT$USRBIN"/kpasswd.afs
419
420     ln -s "$USRSBIN2TOOLS"/root.client/usr/vice/etc/afsd "$PKGROOT$USRSBIN"/afsd
421
422     chown -R root${SEP}wheel "$PKGROOT$PREFIX"
423     chmod -R og-w "$PKGROOT$PREFIX"
424 fi
425
426 if [ x"$PASS2" = x1 ]; then
427     rm -rf "$PKGRES"
428     mkdir "$PKGRES"
429     cd "$RESSRC"
430
431     rm -rf "$CURDIR"/OpenAFS-debug-extension.pkg
432     /usr/bin/pkgbuild --root "$DPKGROOT" --id org.openafs.OpenAFS-debug.pkg \
433                       --version '@PACKAGE_VERSION@' \
434              "$CURDIR"/OpenAFS-debug-extension.pkg
435
436     cd "$RESSRC"
437     cp OpenAFS.post_install "$PKGRES"/postinstall
438     cp OpenAFS.pre_upgrade "$PKGRES"/preupgrade
439     cp OpenAFS.post_install "$PKGRES"/postupgrade
440     cp csrvdbmerge.pl "$PKGRES"
441
442     chmod a+x "$PKGRES"/csrvdbmerge.pl \
443               "$PKGRES"/postinstall \
444               "$PKGRES"/postupgrade \
445               "$PKGRES"/preupgrade
446
447     cp CellServDB.list "$PKGRES"
448     chown -R root${SEP}wheel "$PKGRES"
449
450     rm -rf "$CURDIR"/OpenAFS-dist.pkg
451     /usr/bin/pkgbuild --root "$PKGROOT" --id org.openafs.OpenAFS.pkg \
452                       --version '@PACKAGE_VERSION@' \
453                       --scripts "$PKGRES" "$CURDIR"/OpenAFS-dist.pkg
454
455     rm -rf "$PKGRES"
456     mkdir "$PKGRES"
457     cp background.jpg "$PKGRES"/background.jpg
458     cp License.rtf "$PKGRES"
459     cp ReadMe.rtf."$majorvers" "$PKGRES"/ReadMe.rtf
460     chown -R root${SEP}wheel "$PKGRES"
461
462     if [ $majorvers -ge 15 ] ; then
463         # For El Capitan and further, we have some extra information to tell
464         # the user at the end of the installation process.
465         cp conclusion.txt "$PKGRES"/conclusion.txt
466         PRES_EXTRA="<conclusion file=\"conclusion.txt\"/>"
467     fi
468
469     # generate Distribution.xml from Distribution.xml.in -- nonstandard substs
470     sed -e "s/%%OSX_MAJOR_CUR%%/$THISREL/g" \
471         -e "s/%%OSX_MAJOR_NEXT%%/$(( $THISREL + 1 ))/g" \
472         -e "s,%%PRES_EXTRA%%,$PRES_EXTRA,g" \
473         -e "s/%%OPENAFS_VERSION%%/@PACKAGE_VERSION@/g" \
474         < Distribution.xml.in > Distribution.xml
475
476     rm -rf "$CURDIR/prod"
477     mkdir "$CURDIR/prod"
478     mv "$CURDIR"/OpenAFS-dist.pkg "$CURDIR"/OpenAFS-debug-extension.pkg "$CURDIR"/prod
479     /usr/bin/productbuild --distribution Distribution.xml --resources "$PKGRES" \
480                           --plugins "$PLUGINS" --package-path "$CURDIR"/prod "$CURDIR"/OpenAFS.pkg
481
482     if [ x"$INST_KEY" != x ] ; then
483         mv "$CURDIR"/OpenAFS.pkg "$CURDIR"/OpenAFS-unsigned.pkg
484         productsign --timestamp --sign "$INST_KEY" "$CURDIR"/OpenAFS-unsigned.pkg \
485                     "$CURDIR"/OpenAFS.pkg
486         rm -f "$CURDIR"/OpenAFS-unsigned.pkg
487     fi
488
489     rm -rf "$CURDIR/dmg"
490     rm -f "$CURDIR/TMP.dmg"
491     rm -rf "$CURDIR/OpenAFS-@PACKAGE_VERSION@-$RELNAME.dmg"
492
493     mkdir "$CURDIR"/dmg
494     mv "$CURDIR"/OpenAFS.pkg "$CURDIR"/dmg
495     cp "$RESSRC"/Uninstall.14.15 "$CURDIR"/dmg/Uninstall.command
496     cp "$RESSRC"/DS_Store "$CURDIR"/dmg/.DS_Store
497     mkdir "$CURDIR"/dmg/.background
498     cp "$RESSRC"/afslogo.jpg "$CURDIR"/dmg/.background
499
500     if [ x"$APP_KEY" != x ] ; then
501         codesign --verbose --force --timestamp --sign "$APP_KEY" "$CURDIR"/dmg/Uninstall.command
502     fi
503
504     hdiutil create -srcfolder "$CURDIR"/dmg -volname OpenAFS \
505             -o "$CURDIR"/TMP.dmg
506     hdiutil convert -format UDZO "$CURDIR"/TMP.dmg \
507             -o "$CURDIR/OpenAFS-@PACKAGE_VERSION@-$RELNAME".dmg
508
509     echo
510     echo "Created $CURDIR/OpenAFS-@PACKAGE_VERSION@-$RELNAME".dmg
511 fi