/[polypkg]/trunk/pp.back.solaris
ViewVC logotype

Contents of /trunk/pp.back.solaris

Parent Directory Parent Directory | Revision Log Revision Log


Revision 225 - (show annotations)
Wed Aug 12 19:32:35 2009 UTC (3 months, 1 week ago) by tperciva
File size: 17972 byte(s)
Don't generate a request script unless necessary

(Solaris)

Fixes bug #707.
1 #
2 # solaris backend
3 # http://docs.sun.com/app/docs/doc/802-1932
4 #
5 # the pkgmk tool input:
6 # prototype (required) -pkgproto(1M) or prototype(4)
7 # pkginfo (required) -pkginfo(4)
8 # compver (opt info)
9 # depend (opt info)
10 # space (opt info)
11 # copyright (opt info)
12 # request (optional script) (mode 0644 and no #!)
13 # checkinstall (could be used because vas dependencies broken)
14 # names must be [A-Za-z][-+A-Za-z0-9]{,8} and not (install|new|all)
15 #
16 # The component name is used for the class name
17 #
18 # pkginfo should have
19 # PKG=foobar
20 # NAME=the foo bad system
21 # CATEGORY=system
22 # ARCH=sparc
23 # VERSION=1.2[.3...][,REV=YYYY.MM.DD[.HH.MM.SS]]
24 # CLASSES=none
25 # prototype lines are
26 # [part] ftype class pathname[=srcpath] [mode owner group]
27 # directories should be 755 root sys
28 # binaries should be 555 root bin
29 # directories expected to exist should be ? ? ? (three question marks)
30 #
31 #
32 # Idea: create a "compressed" class that is installed using gzip?
33 #
34 #
35
36 pp_platforms="$pp_platforms solaris"
37
38 #@ pp_backend_solaris_detect(): return true if this platform uses solaris pkgs
39 pp_backend_solaris_detect () {
40 test x"$1" = x"SunOS"
41 }
42
43 #@ pp_backend_solaris_init(): initialise the solaris vars
44 pp_backend_solaris_init () {
45 pp_solaris_category=
46 pp_solaris_istates="s S 1 2 3" # run-states when install is ok
47 pp_solaris_rstates="s S 1 2 3" # run-states when remove is ok
48 pp_solaris_vendor="Quest Software, Inc."
49 pp_solaris_copyright=
50 pp_solaris_name=
51 pp_solaris_desc=
52 pp_solaris_package_arch=auto
53
54 pp_solaris_detect_os
55 pp_solaris_detect_arch
56
57 pp_solaris_init_svc
58
59 #-- readlink not reliably available on Solaris
60 pp_readlink_fn=pp_ls_readlink
61 }
62
63 #@ pp_solaris_detect_os(): set $pp_solaris_os to short platform ID
64 # Following the sunfreeware.com convention:
65 # SunOS 5.5 -> sol25
66 # SunOS 5.6 -> sol26
67 # SunOS 5.7 -> sol7
68 # SunOS 5.8 -> sol8
69 # SunOS 5.9 -> sol9
70 # SunOS 5.10 -> sol10
71 pp_solaris_detect_os () {
72 typeset osrel
73
74 osrel=`/usr/bin/uname -r`
75 case "$osrel" in
76 5.[0-6]) pp_solaris_os="sol2${osrel#5.}";;
77 5.*) pp_solaris_os="sol${osrel#5.}";;
78 esac
79 test -z "$pp_solaris_os" &&
80 pp_warn "can't determine OS suffix from uname -r"
81
82 }
83
84 #@ pp_solaris_detect_arch(): set $pp_solaris_arch to short platform arch
85 # NOTE: this is the architecture EXECUTION capability.
86 # The TARGET arch of the package is detected during pp_solaris_proto()
87 # i386 = 32-bit intel (i386)
88 # amd64 = 64-bit intel (x86_64)
89 # sparc = 32-bit sparc (sparc)
90 # sparcv9 = 64-bit sparc (sparc64)
91 pp_solaris_detect_arch () {
92 pp_solaris_arch=`/usr/bin/optisa amd64 sparcv9 i386 sparc`
93 [ -z "$pp_solaris_arch" ] &&
94 pp_error "can't determine processor architecture"
95 case "$pp_solaris_arch" in
96 amd64) pp_solaris_arch_std=x86_64;;
97 i386) pp_solaris_arch_std=i386;;
98 sparcv9) pp_solaris_arch_std=sparc64;;
99 sparc) pp_solaris_arch_std=sparc;;
100 *) pp_solaris_arch_std=unknown;;
101 esac
102 }
103
104 #@ pp_solaris_is_request_script_necessary():
105 # Return success if a request script should be generated; failure
106 # if it should not
107 pp_solaris_is_request_script_necessary () {
108 typeset has_optional_services
109
110 has_optional_services=no
111 for _svc in $pp_services; do
112 pp_load_service_vars $_svc
113 if test "$optional" = "yes"; then
114 has_optional_services=yes
115 fi
116 done
117
118 # If the package has no optional services and only one component, don't
119 # create a request script at all.
120 if test "$has_optional_services" = "no" &&
121 test `echo $pp_components | wc -w` -eq 1; then
122 return 1 # no
123 fi
124
125 return 0 # yes
126 }
127
128 #@ pp_solaris_request(output): Generate a request script for all components
129 pp_solaris_request () {
130 typeset _cmp _svc
131
132 #-- The common part of the request script contains the ask() function
133 # and resets the CLASSES list to empty
134 cat <<'.'
135 trap 'exit 3' 15
136 ask () {
137 ans=`ckyorn -d "$1" \
138 -p "Do you want to $2"` \
139 || exit $?
140 case "$ans" in y*|Y*) return 0;; *) return 1;; esac
141 }
142 CLASSES=
143 .
144 #-- each of our components adds itself to the CLASSES list
145 for _cmp in $pp_components; do
146 case "$_cmp" in
147 run) :;;
148 doc) echo 'ask y "install the documentation files" &&';;
149 dev) echo 'ask y "install the development files" &&';;
150 dbg) echo 'ask n "install the diagnostic files" &&';;
151 esac
152 echo ' CLASSES="$CLASSES '$_cmp'"'
153 done
154
155 #-- the request script writes the CLASSES var to its output
156 cat <<'.'
157 echo "CLASSES=$CLASSES" > $1
158 .
159
160 if test -n "$pp_services"; then
161 echo 'SERVICES='
162 for _svc in $pp_services; do
163 pp_load_service_vars $_svc
164 if test "$enable" = "yes"; then
165 _default_prompt=y
166 else
167 _default_prompt=n
168 fi
169 if test "$optional" = "yes"; then
170 echo 'ask '$_default_prompt' "install '$_svc' service" &&'
171 fi
172 echo ' SERVICES="$SERVICES '$_svc'"'
173 done
174 echo 'echo "SERVICES=$SERVICES" >> $1'
175 fi
176
177 }
178
179 #@ pp_solaris_procedure(component, post|pre): add per-component scripts
180 # The code fragments are run only if the components are active
181 pp_solaris_procedure () {
182 cat <<.
183
184 #-- $2 for $1 component of $name
185 case " \$CLASSES " in *" $1 "*)
186 .
187 cat
188 cat <<.
189 ;; esac
190 .
191 }
192
193 #@ pp_solaris_depend(): generate depend(4) output
194 pp_solaris_depend () {
195 typeset _name _vers
196 while read _name _vers; do
197 if test -n "$_name"; then
198 echo "P $_name $_name"
199 test -n "$_vers" && echo " $_vers"
200 fi
201 done
202 }
203
204 #@ pp_solaris_space(dir,blocks,inodes): accumulate space reqts for a directory
205 pp_solaris_space() {
206 echo "$2:$3:$1" >> $pp_wrkdir/space.cumulative
207 }
208
209 #@ pp_solaris_sum_space(): sum the spaces reqts
210 pp_solaris_sum_space () {
211 if test -s $pp_wrkdir/space.cumulative; then
212 sort -t: +2 < $pp_wrkdir/space.cumulative |
213 awk -F: 'NR==1{n=$3}{if($3==n){b+=$1;i+=$2}else{print n" "b" "i;b=$1;i=$2;n=$3}}END{print n" "b" "i}' > $pp_wrkdir/space
214 fi
215 }
216
217 #@ pp_solaris_proto(class) < %files: generate prototype(4) file etc.
218 pp_solaris_proto () {
219 typeset t m o g f p st
220 typeset abi
221
222 while read t m o g f p st; do
223 if test x"$o" = x"-"; then
224 o="bin"
225 fi
226 if test x"$g" = x"-"; then
227 g="bin"
228 fi
229 case "$t" in
230 f) test x"$m" = x"-" && m=444
231 case "$f" in
232 *v*) echo "v $1 $p=$pp_destdir$p $m $o $g";;
233 *) echo "f $1 $p=$pp_destdir$p $m $o $g";;
234 esac
235 if test -r "$pp_destdir$p"; then
236 #-- Use file to record ABI types seen
237 case "`file "$pp_destdir$p"`" in
238 *"ELF 32"*80386*) abi=i386;;
239 *"ELF 64"*AMD*) abi=x86_64;;
240 *"ELF 32"*SPARC*) abi=sparc;;
241 *"ELF 64"*SPARC*) abi=sparc64;;
242 *) abi=;;
243 esac
244 if test -n "$abi"; then
245 pp_add_to_list pp_solaris_abis_seen $abi
246 fi
247 fi
248 ;;
249 d) test x"$m" = x"-" && m=555
250 echo "d $1 $p $m $o $g"
251 ;;
252 s) test x"$m" = x"-" && m=777
253 test x"$m" = x"777" ||
254 pp_warn "$p: invalid mode $m for symlink, should be 777 or -"
255 echo "s $1 $p=$st $m $o $g"
256 ;;
257 esac
258 done
259 }
260
261 #-- Reads output files from the frontend and generates the single output
262 # package file under $pp_wrkdir/
263 pp_backend_solaris () {
264 typeset _cmp _svc _grp
265
266 prototype=$pp_wrkdir/prototype
267 : > $prototype
268
269 pkginfo=$pp_wrkdir/pkginfo
270 : > $pkginfo
271 echo "i pkginfo=$pkginfo" >> $prototype
272
273 case "${pp_solaris_name:-$name}" in
274 [0-9]*)
275 pp_error "Package name '${pp_solaris_name:-$name}'" \
276 "cannot start with a number"
277 ;;
278 ???????????????*)
279 pp_warn "Package name '${pp_solaris_name:-$name}'" \
280 "too long for Solaris 2.6 or 2.7 (max 9 characters)"
281 ;;
282 ??????????*)
283 pp_warn "Package name '${pp_solaris_name:-$name}'" \
284 "too long for 2.7 Solaris (max 9 characters)"
285 ;;
286 esac
287
288 #-- generate the package info file
289 echo "VERSION=$version" >> $pkginfo
290 echo "PKG=${pp_solaris_name:-$name}" >> $pkginfo
291 echo "CLASSES=$pp_components" >> $pkginfo
292 echo "BASEDIR=/" >> $pkginfo
293 echo "NAME=$name $version" >> $pkginfo
294 echo "CATEGORY=${pp_solaris_category:-application}" >> $pkginfo
295
296 desc="${pp_solaris_desc:-$description}"
297 test -n "$desc" &&
298 echo "DESC=$desc" >> $pkginfo
299
300 test -n "$pp_solaris_rstates" &&
301 echo "RSTATES=$pp_solaris_rstates" >> $pkginfo
302 test -n "$pp_solaris_istates" &&
303 echo "ISTATES=$pp_solaris_istates" >> $pkginfo
304 test -n "$pp_solaris_vendor" &&
305 echo "VENDOR=$pp_solaris_vendor" >> $pkginfo
306
307 if test -n "${pp_solaris_copyright:-$copyright}"; then
308 echo "${pp_solaris_copyright:-$copyright}" > $pp_wrkdir/copyright
309 echo "i copyright=$pp_wrkdir/copyright" >> $prototype
310 fi
311
312 #-- scripts to run before and after install
313 : > $pp_wrkdir/postinstall
314 : > $pp_wrkdir/preremove
315 for _cmp in $pp_components; do
316 #-- add the postinstall scripts in definition order
317 if test -s $pp_wrkdir/%post.$_cmp; then
318 pp_solaris_procedure $_cmp postinst < $pp_wrkdir/%post.$_cmp \
319 >> $pp_wrkdir/postinstall
320 fi
321 #-- add the preremove rules in reverse definition order
322 if test -s $pp_wrkdir/%preun.$_cmp; then
323 pp_solaris_procedure $_cmp preremove < $pp_wrkdir/%preun.$_cmp |
324 pp_prepend $pp_wrkdir/preremove
325 fi
326 #-- Add the check script in definition order
327 if test -s $pp_wrkdir/%check.$_cmp; then
328 pp_solaris_procedure $_cmp checkinstall \
329 < $pp_wrkdir/%check.$_cmp \
330 >> $pp_wrkdir/checkinstall
331 fi
332 #-- All dependencies are merged together for Solaris pkgs
333 test -s $pp_wrkdir/%depend.$_cmp &&
334 pp_solaris_depend < $pp_wrkdir/%depend.$_cmp > $pp_wrkdir/depend
335 done
336
337
338 if pp_solaris_is_request_script_necessary; then
339 pp_solaris_request > $pp_wrkdir/request
340 fi
341
342 test -n "$pp_services" &&
343 for _svc in $pp_services; do
344 pp_load_service_vars $_svc
345 pp_solaris_make_service $_svc
346 pp_solaris_install_service $_svc >> $pp_wrkdir/postinstall
347 pp_prepend $pp_wrkdir/preremove <<-.
348 /etc/init.d/$_svc stop >/dev/null 2>/dev/null
349 .
350 done
351
352 test -n "$pp_service_groups" &&
353 for _grp in $pp_service_groups; do
354 pp_solaris_make_service_group \
355 $_grp "`pp_service_get_svc_group $_grp`"
356 done
357
358 #-- if installf was used; we need to indicate a termination
359 grep installf $pp_wrkdir/postinstall >/dev/null &&
360 echo 'installf -f $PKGINST' >> $pp_wrkdir/postinstall
361
362 pp_solaris_sum_space
363
364 # NB: pkginfo and copyright are added earlier
365 for f in compver depend space checkinstall \
366 request preinstall postinstall \
367 preremove postremove; do
368 if test -s $pp_wrkdir/$f; then
369 case $f in
370 *install|*remove|request)
371 # turn scripts into a proper shell scripts
372 mv $pp_wrkdir/$f $pp_wrkdir/$f.tmp
373 { echo "#!/bin/sh";
374 echo "# $f script for ${pp_solaris_name:-$name}-$version"
375 cat $pp_wrkdir/$f.tmp
376 echo "exit 0"; } > $pp_wrkdir/$f
377 chmod +x $pp_wrkdir/$f
378 rm -f $pp_wrkdir/$f.tmp
379 ;;
380 esac
381 if $pp_opt_debug; then
382 pp_debug "contents of $f:"
383 cat $pp_wrkdir/$f >&2
384 fi
385 echo "i $f=$pp_wrkdir/$f" >> $prototype
386 fi
387 done
388
389 #-- create the prototype file which lists the files to install
390 # do this as late as possible because files could be added
391 pp_solaris_abis_seen=
392 for _cmp in $pp_components; do
393 pp_solaris_proto $_cmp < $pp_wrkdir/%files.$_cmp
394 done >> $prototype
395
396 if test x"$pp_solaris_package_arch" = x"auto"; then
397 if pp_contains "$pp_solaris_abis_seen" sparc64; then
398 pp_solaris_package_arch_std="sparc64"
399 echo "ARCH=sparcv9" >> $pkginfo
400 elif pp_contains "$pp_solaris_abis_seen" sparc; then
401 pp_solaris_package_arch_std="sparc"
402 echo "ARCH=sparc" >> $pkginfo
403 elif pp_contains "$pp_solaris_abis_seen" x86_64; then
404 pp_solaris_package_arch_std="x86_64"
405 echo "ARCH=amd64" >> $pkginfo
406 elif pp_contains "$pp_solaris_abis_seen" i386; then
407 pp_solaris_package_arch_std="i386"
408 echo "ARCH=i386" >> $pkginfo
409 else
410 pp_warn "No ELF files found: not supplying an ARCH type"
411 pp_solaris_package_arch_std="noarch"
412 fi
413 else
414 pp_solaris_package_arch_std="$pp_solaris_package_arch"
415 echo "ARCH=$pp_solaris_package_arch" >> $pkginfo
416 fi
417
418 mkdir $pp_wrkdir/pkg
419
420 . $pp_wrkdir/%fixup
421
422 if $pp_opt_debug; then
423 echo "$pkginfo::"; cat $pkginfo
424 echo "$prototype::"; cat $prototype
425 fi >&2
426
427 pkgmk -a $pp_solaris_arch -d $pp_wrkdir/pkg \
428 -f $prototype || { error "pkgmk failed"; return; }
429 pkgtrans -s $pp_wrkdir/pkg \
430 $pp_wrkdir/`pp_backend_solaris_names` \
431 ${pp_solaris_name:-$name} \
432 || { error "pkgtrans failed"; return; }
433 }
434
435 #@ pp_backend_solaris_cleanup(): cleanup
436 pp_backend_solaris_cleanup () {
437 :
438 }
439
440 #@ pp_backend_solaris_names(): print the name of the package files created
441 pp_backend_solaris_names () {
442 echo ${pp_solaris_name:-$name}-$version-${pp_solaris_package_arch_std:-$pp_solaris_arch}.pkg
443 }
444
445 #@ pp_backend_solaris_install_script(): generates a helper install script
446 pp_backend_solaris_install_script () {
447 typeset pkgname platform
448
449 platform="${pp_solaris_os:-solaris}-${pp_solaris_package_arch_std:-$pp_solaris_arch}"
450
451 echo "#! /sbin/sh"
452 pp_install_script_common
453 pkgname=`pp_backend_solaris_names`
454
455 cat <<.
456 tmpnocheck=/tmp/nocheck\$\$
457 tmpresponse=/tmp/response\$\$
458 trap 'rm -f \$tmpnocheck \$tmpresponse' 0
459
460 make_tmpfiles () {
461 cat <<-.. > \$tmpresponse
462 CLASSES=\$*
463 SERVICES=$pp_services
464 ..
465 cat <<-.. > \$tmpnocheck
466 mail=
467 instance=overwrite
468 partial=nocheck
469 runlevel=nocheck
470 idepend=nocheck
471 rdepend=nocheck
472 space=nocheck
473 setuid=nocheck
474 conflict=nocheck
475 action=nocheck
476 basedir=default
477 ..
478 }
479
480 test \$# -eq 0 && usage
481 op="\$1"; shift
482
483 case "\$op" in
484 list-components)
485 test \$# -eq 0 || usage \$op
486 echo "$pp_components"
487 ;;
488 list-services)
489 test \$# -eq 0 || usage \$op
490 echo "$pp_services"
491 ;;
492 list-files)
493 test \$# -ge 1 || usage \$op
494 echo \${PP_PKGDESTDIR:-.}/$pkgname
495 ;;
496 install)
497 test \$# -ge 1 || usage \$op
498 make_tmpfiles "\$@"
499 verbose /usr/sbin/pkgadd -n -d \${PP_PKGDESTDIR:-.}/$pkgname \
500 -r \$tmpresponse \
501 -a \$tmpnocheck \
502 ${pp_solaris_name:-$name}
503 ;;
504 uninstall)
505 test \$# -ge 1 || usage \$op
506 make_tmpfiles "\$@"
507 verbose /usr/sbin/pkgrm -n \
508 -a \$tmpnocheck \
509 ${pp_solaris_name:-$name}
510 ;;
511 start|stop)
512 test \$# -ge 1 || usage \$op
513 ec=0
514 for svc
515 do
516 verbose /etc/init.d/\$svc \$op || ec=1
517 done
518 exit \$ec
519 ;;
520 print-platform)
521 echo "$platform"
522 ;;
523 *)
524 usage
525 ;;
526 esac
527 .
528 }
529
530 #@ pp_solaris_dynlib_depend(): emits dependency from shared library info
531 # a list of files should be supplied on stdin. non-executable files
532 # are ignored. output is a set of dependency lines that should
533 # be added to %depend.$cpt
534 pp_solaris_dynlib_depend () {
535 xargs ldd 2>/dev/null |
536 sed -e '/^[^ ]*:$/d' -e 's,.*=>[ ]*,,' -e 's,^[ ]*,,' |
537 sort -u |
538 grep -v '^/usr/platform/' | (
539 set -- ""; shift
540 while read p; do
541 set -- "$@" -p "$p"
542 if [ $# -gt 32 ]; then
543 echo "$# is $#" >&2
544 pkgchk -l "$@"
545 set -- ""; shift
546 fi
547 done
548 [ $# -gt 0 ] && pkgchk -l "$@"
549 )|
550 awk '/^Current status:/{p=0} p==1 {print $1} /^Referenced by/ {p=1}' |
551 sort -u |
552 xargs -l32 pkginfo -x |
553 awk 'NR % 2 == 1 { name=$1; } NR%2 == 0 { print name, $2 }'
554 }
555
556 #@ pp_solaris_add_dynlib_depends(): creates dependencies for each component
557 pp_solaris_add_dynlib_depends () {
558 typeset tmp
559 tmp=$pp_wrkdir/tmp.dynlib
560
561 for _cmp in $pp_components; do
562 awk '{print destdir $6}' destdir="$pp_destdir" \
563 < $pp_wrkdir/%files.$_cmp |
564 pp_solaris_dynlib_depend > $tmp
565 if test -s $tmp; then
566 cat $tmp >> $pp_wrkdir/%depend.$_cmp
567 fi
568 rm -f $tmp
569 done
570 }
571
572 #@ pp_backend_solaris_probe(): probe local host type
573 pp_backend_solaris_probe () {
574 echo "${pp_solaris_os}-${pp_solaris_arch_std}"
575 }
576
577 #@ pp_backend_solaris_vas_platforms(): print the VAS platform identifiers
578 pp_backend_solaris_vas_platforms () {
579 case `pp_backend_solaris_probe` in
580 sol10-sparc* | sol9-sparc* | sol8-sparc*)
581 echo solaris8-sparc solaris7-sparc solaris26-sparc;;
582 sol7-sparc*) echo solaris7-sparc solaris26-sparc;;
583 sol26-sparc*) echo solaris26-sparc;;
584 sol8-*86) echo solaris8-x86;;
585 sol10-*86 | sol10-x86_64)
586 echo solaris10-x64 solaris8-x86;;
587 *) pp_die "unknown system `pp_backend_solaris_probe`";;
588 esac
589 }

Ted.Percival@quest.com
ViewVC Help
Powered by ViewVC 1.1.2