/[polypkg]/trunk/pp.model
ViewVC logotype

Contents of /trunk/pp.model

Parent Directory Parent Directory | Revision Log Revision Log


Revision 222 - (show annotations)
Thu Jun 18 00:13:04 2009 UTC (5 months ago) by tperciva
File size: 11382 byte(s)
Allow packager to make service installation optional

This changes the default, where on platforms that support it
(Solaris, others?) the user would be prompted whether to install
each service. Services are now installed automatically without
asking unless the packager specifies optional=yes in the spec file.

Inspired by part of QAS r892.
1
2 #@ $pp_shlib_suffix: used to replace .%so at end of %files paths
3 # -- platform initialisation functions may (should) change this
4 pp_shlib_suffix='.so*'
5
6 #@ pp_model_init(): initialise model variables and files
7 pp_model_init () {
8 #@ $pp_components: whitespace-delimited list of components seen in %files
9 pp_components=
10 #@ $pp_services: whitespace-delimited list of %service seen
11 pp_services=
12
13 rm -f $pp_wrkdir/%files.* \
14 $pp_wrkdir/%post.* \
15 $pp_wrkdir/%preun.* \
16 $pp_wrkdir/%service.* \
17 $pp_wrkdir/%set \
18 $pp_wrkdir/%fixup
19 }
20
21
22 #@ pp_have_component(component): return true if component was defined
23 pp_have_component () {
24 pp_contains "$pp_components" "$1"
25 }
26
27 #@ pp_have_all_components(component...): return true if all components defined
28 pp_have_all_components () {
29 pp_contains_all "$pp_components" "$@"
30 }
31
32 #@ pp_add_component(component): adds component to $pp_components
33 pp_add_component () {
34 pp_add_to_list 'pp_components' "$1"
35 }
36
37 #@ pp_add_service(service): adds service to $pp_services
38 pp_add_service () {
39 pp_add_to_list 'pp_services' "$1"
40 }
41
42 #@ pp_service_init_vars(): initialises user service variables
43 pp_service_init_vars () {
44 cmd=
45 pidfile=
46 stop_signal=15 # SIGTERM
47 user=root
48 group=
49 enable=yes # make it so the service starts on boot
50 optional=no # Whether installing this service is optional
51 pp_backend_init_svc_vars
52 }
53
54 #@ pp_service_check_vars(service): error if required user variables are unset
55 pp_service_check_vars () {
56 test -n "$cmd" ||
57 pp_error "%service $1: cmd not defined"
58 case "$enable" in
59 yes|no) : ;;
60 *) pp_error "%service $1: \$enable must be set to yes or no";;
61 esac
62 }
63
64 #@ pp_load_service_vars(svc): source a file for service definitions
65 pp_load_service_vars () {
66 pp_service_init_vars
67 . "$pp_wrkdir/%service.$1"
68 pp_service_check_vars "$1"
69 }
70
71 #@ pp_files_expand(path [m] [[u]:[g]] [f] [t]): expand to a file path
72 # writes multiple lines of the form
73 # type path mode owner group flags [target]
74 # flags contains the letter v if the file is volatile
75 pp_files_expand () {
76 typeset _p _mode _group _owner _flags _path _optional _has_target _tree
77 typeset _path _file _tgt _m _o _g _f _type _lm _ll _lo _lg _ls _lx
78 typeset _ignore _a
79
80 test $# -eq 0 && return
81
82 pp_debug "pp_files_expand: path is: $1"
83
84 case "$1" in "#"*) return;; esac
85 _p="$1"; shift
86
87 pp_debug "pp_files_expand: other arguments: $*"
88
89 #-- the mode must be an octal number of at least three digits
90 _mode="="
91 _a=`eval echo \"$1\"`
92 case "$_a" in
93 *:*) :;;
94 -|=|[01234567][01234567][01234567]*) _mode="$_a"; shift;;
95 esac
96
97 #-- the owner:group field may have optional parts
98 _a=`eval echo \"$1\"`
99 case "$_a" in
100 *:*) _group=${_a#*:}; _owner=${_a%:*}; shift;;
101 =|-) _group=$_a; _owner=$_a; shift;;
102 *) _group=; _owner=;;
103 esac
104
105 #-- process the flags argument
106 _flags=
107 _optional=false
108 _has_target=false
109 _ignore=false
110 if test $# -gt 0; then
111 _a=`eval echo \"$1\"`
112 case ",$_a," in *,volatile,*) _flags="${_flags}v";; esac
113 case ",$_a," in *,optional,*) _optional=true;; esac
114 case ",$_a," in *,symlink,*) _has_target=true;; esac
115 case ",$_a," in *,ignore-others,*) _flags="${_flags}i";; esac
116 case ",$_a," in *,ignore,*) _ignore=true;; esac
117 shift
118 fi
119
120 #-- process the target argument
121 if $_has_target; then
122 test $# -ne 0 || pp_error "$_p: missing target"
123 _a=`eval echo \"$1\"`
124 _target="$_a"
125 shift
126 fi
127
128 pp_debug "pp_files_expand: $_mode|$_owner:$_group|$_flags|$_target|$*"
129
130 test $# -eq 0 || pp_error "$_p: too many arguments"
131
132 #-- process speciall suffixes
133 tree=
134 case "$_p" in
135 *"/**") _p="${_p%"/**"}"; tree="**";;
136 *".%so") _p="${_p%".%so"}$pp_shlib_suffix";;
137 esac
138
139 #-- expand the path using the shell glob
140 pp_debug "expanding .$_p ... with $pp_expand_path"
141 (cd ${pp_destdir} && $pp_expand_path ".$_p") > $pp_wrkdir/tmp.files.exp
142
143 #-- expand path/** by rewriting the glob output file
144 case "$tree" in
145 "") : ;;
146 "**")
147 pp_debug "expanding /** tree ..."
148 while read _path; do
149 _path="${_path#.}"
150 pp_find_recurse "$pp_destdir${_path%/}"
151 done < $pp_wrkdir/tmp.files.exp |
152 sort -u > $pp_wrkdir/tmp.files.exp2
153 mv $pp_wrkdir/tmp.files.exp2 $pp_wrkdir/tmp.files.exp
154 ;;
155 esac
156
157 while read _path; do
158 _path="${_path#.}"
159 _file="${pp_destdir}${_path}"
160 _tgt=
161 _m="$_mode"
162 _o="${_owner:--}"
163 _g="${_group:--}"
164 _f="$_flags"
165
166 case "$_path" in
167 /*) :;;
168 *) pp_warn "$_path: inserting leading /"
169 _path="/$_path";; # ensure leading /
170 esac
171
172 #-- sanity checks
173 case "$_path" in
174 */../*|*/..) pp_error "$_path: invalid .. in path";;
175 */./*|*/.) pp_warn "$_path: invalid component . in path";;
176 *//*) pp_warn "$_path: redundant / in path";;
177 esac
178
179 #-- set the type based on the real file's type
180 if $_ignore; then
181 _type=f _m=_ _o=_ _g=_
182 elif test -h "$_file"; then
183 case "$_path" in
184 */) pp_warn "$_path (symlink $_file): removing trailing /"
185 _path="${_path%/}"
186 ;;
187 esac
188 _type=s
189 if test x"$_target" != x"=" -a -n "$_target"; then
190 _tgt="$_target"
191 pp_debug "symlink target is $_tgt"
192 else
193 _tgt=`pp_readlink "$_file"`;
194 test -z "$_tgt" && pp_error "can't readlink $_file"
195 case "$_tgt" in
196 ${pp_destdir}/*)
197 pp_warn "stripped \$destdir from symlink ($_path)"
198 _tgt="${_tgt#$pp_destdir}";;
199 esac
200 fi
201 _m=777
202 elif test -d "$_file"; then
203 #-- display a warning if the user forgot the trailing /
204 case "$_path" in
205 */) :;;
206 *) pp_warn "$_path (matching $_file): adding trailing /"
207 _path="$_path/";;
208 esac
209 _type=d
210 $_has_target && pp_error "$_file: not a symlink"
211 elif test -f "$_file"; then
212 case "$_path" in
213 */) pp_warn "$_path (matching $_file): removing trailing /"
214 _path="${_path%/}"
215 ;;
216 esac
217 _type=f
218 $_has_target && pp_error "$_file: not a symlink"
219 else
220 $_optional && continue
221 pp_error "$_file: missing"
222 _type=f
223 fi
224
225 #-- convert '=' shortcuts into mode/owner/group from ls
226 case ":$_m:$_o:$_g:" in *:=:*)
227 if LS_OPTIONS=--color=never /bin/ls -ld "$_file" \
228 > $pp_wrkdir/ls.tmp
229 then
230 read _lm _ll _lo _lg _ls _lx < $pp_wrkdir/ls.tmp
231 test x"$_m" = x"=" && _m=`pp_mode_from_ls "$_lm"`
232 test x"$_o" = x"=" && _o="$_lo"
233 test x"$_g" = x"=" && _g="$_lg"
234 else
235 pp_error "cannot read $_file"
236 test x"$_m" = x"=" && _m=-
237 test x"$_o" = x"=" && _o=-
238 test x"$_g" = x"=" && _g=-
239 fi
240 ;;
241 esac
242
243 test -n "$_f" || _f=-
244
245 #-- sanity checks
246 test -n "$_type" || pp_die "_type empty"
247 test -n "$_path" || pp_die "_path empty"
248 test -n "$_m" || pp_die "_m empty"
249 test -n "$_o" || pp_die "_o empty"
250 test -n "$_g" || pp_die "_g empty"
251
252 #-- setuid/gid files must be given an explicit owner/group (or =)
253 case "$_o:$_g:$_m" in
254 -:*:[4657][1357]??|-:*:[4657]?[1357]?|-:*:[4657]??[1357])
255 pp_error "$_path: setuid file ($_m) missing explicit owner";;
256 *:-:[2367][1357]??|*:-:[2367]?[1357]?|*:-:[2367]??[1357])
257 pp_error "$_path: setgid file ($_m) missing explicit group";;
258 esac
259
260 # convert numeric uids into usernames; only works for /etc/passwd
261 case "$_o" in [0-9]*) _o=`pp_getpwuid $_o`;; esac
262 case "$_g" in [0-9]*) _g=`pp_getgrgid $_g`;; esac
263
264 pp_debug "$_type $_m $_o $_g $_f $_path" $_tgt
265 $_ignore || echo "$_type $_m $_o $_g $_f $_path" $_tgt
266 pp_note_file_used "$_path"
267 case "$_f" in *i*) echo "$_path" >> $pp_wrkdir/ign.files;; esac
268 done < $pp_wrkdir/tmp.files.exp
269 }
270
271 #@ pp_files_check_duplicates(): raise an error on duplicate files
272 pp_files_check_duplicates () {
273 typeset _path
274 if test -s $pp_wrkdir/all.files; then
275 sort < $pp_wrkdir/all.files | uniq -d > $pp_wrkdir/duplicate.files
276 if test -f $pp_wrkdir/ign.awk; then
277 # Remove ignored files
278 mv $pp_wrkdir/duplicate.files $pp_wrkdir/duplicate.files.ign
279 sed -e 's/^/_ _ _ _ _ /' < $pp_wrkdir/duplicate.files.ign |
280 awk -f $pp_wrkdir/ign.awk |
281 sed -e 's/^_ _ _ _ _ //' > $pp_wrkdir/duplicate.files
282 fi
283 while read _path; do
284 pp_warn "$_path: file declared more than once"
285 done <$pp_wrkdir/duplicate.files
286 fi
287 }
288
289 #@ pp_files_check_coverage(): raise an error if files aren't listed
290 # compares the list of files under pp_destdir with the list of
291 # all files inside %files sections. Only generates warnings (for now.)
292 pp_files_check_coverage () {
293 pp_find_recurse "$pp_destdir" | sort > $pp_wrkdir/coverage.avail
294 if test -s $pp_wrkdir/all.files; then
295 sort -u < $pp_wrkdir/all.files
296 else
297 :
298 fi > $pp_wrkdir/coverage.used
299 join -v1 $pp_wrkdir/coverage.avail $pp_wrkdir/coverage.used \
300 > $pp_wrkdir/coverage.not-packaged
301 if test -s $pp_wrkdir/coverage.not-packaged; then
302 pp_warn "The following files/directories were found but not packaged:"
303 sed -e 's,^, ,' < $pp_wrkdir/coverage.not-packaged >&2
304 fi
305 join -v2 $pp_wrkdir/coverage.avail $pp_wrkdir/coverage.used \
306 > $pp_wrkdir/coverage.not-avail
307 if test -s $pp_wrkdir/coverage.not-avail; then
308 pp_warn "The following files/directories were named but not found:"
309 sed -e 's,^, ,' < $pp_wrkdir/coverage.not-avail >&2
310 fi
311 }
312
313 #@ pp_files_ignore_others(): remove ignored files
314 pp_files_ignore_others () {
315 typeset p f
316
317 test -s $pp_wrkdir/ign.files || return
318
319 #-- for each file in ign.files, we remove it from all the
320 # other %files.* lists, except where it has an i flag.
321 # rather than scan each list multiple times, we build
322 # an awk script
323
324 pp_debug "stripping ignore files"
325
326 while read p; do
327 echo '$6 == "'"$p"'" && $5 !~ /i/ { next }'
328 done < $pp_wrkdir/ign.files > $pp_wrkdir/ign.awk
329 echo '{ print }' >> $pp_wrkdir/ign.awk
330
331 $pp_opt_debug && cat $pp_wrkdir/ign.awk
332
333 for f in $pp_wrkdir/%files.*; do
334 mv $f $f.ign
335 awk -f $pp_wrkdir/ign.awk < $f.ign > $f || pp_error "awk"
336 done
337 }
338
339 #@ pp_service_scan_groups(): scan services for groups
340 # Populates the list $pp_service_groups with all defined groups,
341 # and creates the files %svcgrp.$group each containing the
342 # names of services inside each that group, one per line.
343 pp_service_scan_groups () {
344 typeset svc
345
346 #-- scan for "group" commands, and build a list of groups
347 pp_service_groups=
348 if test -n "$pp_services"; then
349 for svc in $pp_services; do
350 group=
351 . $pp_wrkdir/%service.$svc
352 if test -n "$group"; then
353 pp_contains "$pp_services" "$group" && pp_error \
354 "%service $svc: group name $group in use by a service"
355 pp_add_to_list 'pp_service_groups' "$group"
356 echo "$svc" >> $pp_wrkdir/%svcgrp.$group
357 fi
358 done
359 fi
360 }
361
362 #@ pp_service_get_svc_group: prints the services with a group on one line
363 pp_service_get_svc_group () {
364 (tr '\012' ' ' < $pp_wrkdir/%svcgrp.$1 ; echo) | sed -e 's/ $//'
365 }

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