/var/lib/sorcery/modules/build_api/common
1 #---------------------------------------------------------------------
2 ##
3 ##=head1 SYNOPSIS
4 ##
5 ## Functions for dealing with the actual compiling/installation of spells
6 ## and walking through casts 'pass 4' pipeline.
7 ##
8 ##=head1 DESCRIPTION
9 ##
10 ##
11 ##=head1 COPYRIGHT
12 ##
13 ## Copyright (C) 2002 The Source Mage Team <http://www.sourcemage.org>
14 ##
15 ##=head1 FUNCTIONS
16 #---------------------------------------------------------------------
17
18
19 #---------------------------------------------------------------------
20 ## pokes around for a configure or src/configure and if it exists
21 ## asks the user if they want to edit the custom options
22 #---------------------------------------------------------------------
23 function run_config_loc() {
24 debug "build_api/common" "Starting run_config_loc() on $SPELL"
25 pushd . > /dev/null # may have been somewhere else
26 [ -d "$SOURCE_DIRECTORY" ] &&
27 cd $SOURCE_DIRECTORY # we need to be in here for this function to work
28 if [[ $CONFIG_LOC == on ]]; then
29
30 if [ -x ./configure ] || [ -x ./src/configure ] ; then
31
32 if [ ! -d $SM_CONFIG_OPTION_CACHE ] ; then
33 mkdir --parents --mode=0755 $SM_CONFIG_OPTION_CACHE
34 fi
35
36 if [ -f $SM_CONFIG_OPTION_CACHE/$SPELL ] ; then
37 message "${MESSAGE_COLOR}These are your current -- config options for spell ${SPELL_COLOR}$SPELL"
38 message "${FILE_COLOR}($SM_CONFIG_OPTION_CACHE/$SPELL)"
39 cat $SM_CONFIG_OPTION_CACHE/$SPELL | column
40 fi
41
42 if query "Do you wish to add -- options to ./configure?" n ; then
43 F_TMP=$TMP_DIR/cast.$$.configure
44 rm -f $F_TMP
45
46 if [ -x ./configure ]; then
47 ./configure --help > $F_TMP
48 elif [ -x ./src/configure ]; then
49 ./src/configure --help > $F_TMP
50 fi
51
52 if [ -f $F_TMP ]; then
53 sedit 's/^/# /' $F_TMP
54 fi
55
56 cat $SM_CONFIG_OPTION_CACHE/$SPELL >> $F_TMP 2>/dev/null
57 edit_file $F_TMP
58 rm -f $SM_CONFIG_OPTION_CACHE/$SPELL
59 sedit '/^#.*$/d' $F_TMP
60 mv $F_TMP $SM_CONFIG_OPTION_CACHE/$SPELL
61 fi
62
63 # load custom OPTS
64 if [ -f $SM_CONFIG_OPTION_CACHE/$SPELL ]; then
65 OPTS="$OPTS $(< $SM_CONFIG_OPTION_CACHE/$SPELL)"
66 message "${MESSAGE_COLOR} OPTS= ${DEFAULT_COLOR}$OPTS"
67 fi
68
69 fi
70
71 fi
72
73 popd &>/dev/null
74
75 }
76
77 #---------------------------------------------------------------------
78 ## @Type API
79 ## Prepares to install the spell. If the spell is installed already,
80 ## the libraries are saved with save_libraries() and the spell is dispelled.
81 ## Usually called from the BUILD or PRE_INSTALL script of a spell.
82 ## Locks "libgrimoire" "install" before proceeding.
83 ## If the spell is not installed (or held) the spell is not dispelled.
84 ##
85 #---------------------------------------------------------------------
86 function real_prepare_install() { (
87
88 debug "libgrimoire" "Running prepare_install() on $SPELL"
89
90 message "${MESSAGE_COLOR}Preparing to install" \
91 "${SPELL_COLOR}${SPELL}${DEFAULT_COLOR}"
92
93 lock_resources "libgrimoire" "install"
94
95 if spell_ok $SPELL
96 then
97
98 trap "spell_recover" SIGINT
99 save_libraries
100 save_binaries
101 dispel --notriggers --nosustain --noqueue $SPELL
102
103 fi
104 ) &&
105 save_bin_lib_paths
106 }
107
108 #--------------------------------------------------------------------
109 ##
110 ## append old libraries and binaries to the appropriate environmental
111 ## variables so that they can be found by sorcery if they get
112 ## dispelled
113 ##
114 #--------------------------------------------------------------------
115 function save_bin_lib_paths()
116 {
117 # TODO this is a dirty hack we need to remove it
118 if test -d "$SOURCE_DIRECTORY/old.binaries" ; then
119 for dir in $( find "$SOURCE_DIRECTORY/old.binaries" -type d); do
120 export PATH="$dir:$PATH"
121 done
122 fi
123 if test -d "$SOURCE_DIRECTORY/old.libraries" ; then
124 for dir in $( find "$SOURCE_DIRECTORY/old.libraries" -type d); do
125 export LD_LIBRARY_PATH="$dir:$LD_LIBRARY_PATH"
126 export LD_RUN_PATH="$dir:$LD_RUN_PATH"
127 done
128 fi
129 }
130
131 #---------------------------------------------------------------------
132 ##
133 ## Gathers all documentation files from source archive and installs
134 ## them as part of the spell
135 ##
136 #---------------------------------------------------------------------
137 function real_gather_docs() { (
138
139 if [ "$GATHER_DOCS" == "on" ]; then
140
141 debug "libgrimoire" "Running gather_docs() on $SPELL DOCS=$DOCS"
142
143 DEST_DIR=$DOCUMENT_DIRECTORY/$SPELL
144 mkdir -p $DEST_DIR
145
146 cd $SOURCE_DIRECTORY
147 shopt -s nullglob
148 for i in ${DOCS}; do
149 if test -f "$i"; then
150 file -bi $i|grep -q ^application && continue
151 cp $SOURCE_DIRECTORY/${i} $DEST_DIR 2>/dev/null
152 fi
153 done
154
155 for i in ${DOC_DIRS}; do
156 if test -d "$i"; then
157 cp -r $SOURCE_DIRECTORY/${i} $DEST_DIR 2>/dev/null
158 fi
159 done
160
161 # making installed docs readable for all users.
162 chmod -fR a+r $DEST_DIR
163
164 # remove the doc dir if nothing was installed
165 rmdir $DEST_DIR 2> /dev/null
166
167 fi
168
169 ) }
170
171
172 #---------------------------------------------------------------------
173 ##
174 ## Copies pam configuration files to /etc/pam.d/
175 ##
176 #---------------------------------------------------------------------
177 function install_pam_confs() {
178
179 debug "libgrimoire" "Running install_pam_confs() on $SPELL"
180
181 if [[ -d $SCRIPT_DIRECTORY/pam.d ]]; then
182 cd "$SCRIPT_DIRECTORY/pam.d"
183
184 mkdir -p "$INSTALL_ROOT/etc/pam.d"
185 local file
186 for file in *; do
187 if ! [[ -f $INSTALL_ROOT/etc/pam.d/$file ]]; then
188 install -g root -o root "$file" "$INSTALL_ROOT/etc/pam.d"
189 fi
190 done
191
192 fi
193
194 }
195
196 #---------------------------------------------------------------------
197 ## Stuff that should be done if run_build_spell">run_build_spell succeeds
198 ## This is intended to be overridable at some point
199 #---------------------------------------------------------------------
200 function run_spell_success() {
201 debug "build_api/common" "cast of $SPELL-$VERSION was successful"
202
203 local INST_LOG="$INSTALL_LOGS/$SPELL-$VERSION"
204 local MD5_LOG="$MD5SUM_LOGS/$SPELL-$VERSION"
205 local TMP_INST_LOG="$TMP_DIR/$SPELL-$VERSION.install"
206 local TMP_MD5_LOG="$TMP_DIR/$SPELL-$VERSION.md5"
207 local C_LOG_COMP="$COMPILE_LOGS/$SPELL-$VERSION$EXTENSION"
208
209 local CACHE
210 construct_cache_name "$INSTALL_CACHE/$SPELL-$VERSION-$HOST" CACHE
211 local CACHE_COMP=$CACHE$EXTENSION
212
213 sound SUCCESS
214
215 tablet_check_version_cache "$VERSION_STATUS" &&
216 (
217 codex_set_current_spell_by_name $SPELL
218 add_version_cache "$VERSION_STATUS" "$SPELL" "$VERSION" "$PATCHLEVEL" "$SECURITY_PATCH" "$UPDATED"
219 )
220
221 # announce to everyone the spell succeeded
222 activity_log "cast" "$SPELL" "$VERSION" "success"
223 add_spell $SPELL installed $VERSION
224 echo $SPELL >> $SUCCESS_LIST
225 pop_install_queue "$SPELL"
226
227 # update depends info
228 debug "build_api/common" "Merging depends info"
229
230 # none of the old values are valid, only the new, uncommitted values are
231 remove_depends_status $DEPENDS_STATUS $SPELL
232 local spell_depends spell_sub_depends spell_rsub_depends
233 local t_DEPENDS_STATUS
234 lock_start_transaction "$DEPENDS_STATUS" t_DEPENDS_STATUS
235 get_uncommitted_depends_file $SPELL spell_depends
236 if [ -e "$spell_depends" ] ; then
237 cat $spell_depends >> $t_DEPENDS_STATUS
238 fi
239 lock_commit_transaction $DEPENDS_STATUS
240
241 # since the database is now accurate, no reason to keep old answers
242 # floating around
243 test -e "$ABANDONED_DEPENDS/$SPELL" &&
244 rm -f $ABANDONED_DEPENDS/$SPELL &>/dev/null
245
246 # none of the old values are valid, only the new, uncommitted values are
247 remove_sub_depends $SUB_DEPENDS_STATUS "" "$SPELL"
248 local spell_sub_depends
249 local t_SUB_DEPENDS_STATUS
250 lock_start_transaction "$SUB_DEPENDS_STATUS" t_SUB_DEPENDS_STATUS
251 get_uncommitted_sub_depends_file $SPELL spell_sub_depends
252 if [ -e "$spell_sub_depends" ] ; then
253 cat $spell_sub_depends >> $t_SUB_DEPENDS_STATUS
254 fi
255 lock_commit_transaction $SUB_DEPENDS_STATUS
256 get_uncommitted_rsub_depends_file $SPELL spell_rsub_depends
257
258 # compile log
259 create_compile_log
260 view_compile_log
261
262 local tablet_dir=$(tablet_get_path $SPELL)
263 if [ "$?" != 0 ] ; then
264 message "failed to make a tablet directory: $tablet_dir" \
265 "this may be a bug"
266 unset tablet_dir
267 local TABLET_IGNORE=yes
268 else
269 message "${MESSAGE_COLOR}Creating tablet in directory" \
270 "${FILE_COLOR}${tablet_dir}${DEFAULT_COLOR}"
271 tablet_install_spell_files $tablet_dir
272 local TABLET_SPELL_DIR=$tablet_dir spell_config_stage
273 spell_config_stage=$CONFIG_STAGE_DIRECTORY/$SPELL
274 lock_file "$spell_config_stage"
275 if [[ $STAGED_INSTALL != "off" && -d $spell_config_stage/current ]]
276 then
277 rmdir $spell_config_stage/current $spell_config_stage 2>/dev/null
278 if [[ -d $spell_config_stage/current ]]
279 then
280 # check if a config we staged was already staged and if so, remove it.
281 # this way users don't have to merge the same old default config again
282 # and again if they cast a spell multiple times
283 local deferred_file file quasi_basename
284 find $spell_config_stage/current -type f |
285 while read deferred_file; do
286 quasi_basename=$(sed "s,$spell_config_stage/current/,," <<< "$deferred_file")
287 find $spell_config_stage -wholename $spell_config_stage/current \
288 -prune -o -type f -wholename "*/$quasi_basename" -print |
289 while read file; do
290 if cmp -s $deferred_file $file; then
291 recursive_config_stage_cleanup $deferred_file $SPELL
292 continue 2
293 fi &>/dev/null
294 done
295 done
296
297 [[ -d $spell_config_stage/current ]] &&
298 mv $spell_config_stage/current \
299 $spell_config_stage/$(smgl_basename $tablet_dir)
300 fi
301 fi
302 unlock_file "$spell_config_stage"
303 # this data is now doubly stale, remove it
304 rm -f $ABANDONED_PERSIST/$SPELL.p
305 fi
306
307 # when delving late stages the installwatch log may not exist
308 if [[ $STAGED_INSTALL == off ]] && [[ ! -e $IW_LOG ]]; then
309 message "${PROBLEM_COLOR}The installwatch log does not exist!"
310 message "Skipping the creation of the cache archive, the install and md5 log!" \
311 "$DEFAULT_COLOR"
312
313 rm_source_dir
314 rm -f "$C_LOG"
315 return
316 fi
317
318 # install log
319 message "${MESSAGE_COLOR}Creating install log" \
320 "${FILE_COLOR}${INST_LOG}${DEFAULT_COLOR}"
321 # this will make a "root" format install log it will need to be
322 # reformatted to "log" format (see log_adjuster in libtrack for details)
323 # but basically replacing INSTALL_ROOT with TRACK_ROOT
324 create_install_log $IW_LOG $TMP_INST_LOG
325 if [[ $STAGED_INSTALL == on ]]; then
326 # save the md5sums of the files in the stage and not the target
327 # ones on the system, otherwise config merging breaks #13835
328 # for this we need an "install" log of what is in the stage
329 local STAGE_INST_LOG="$TMP_DIR/$SPELL-$VERSION.stage.install"
330 create_stage_install_log $TMP_INST_LOG $STAGE_INST_LOG
331 if [[ $tablet_dir ]] ; then
332 find $tablet_dir >> $STAGE_INST_LOG
333 fi
334 fi
335 if [[ $tablet_dir ]] ; then
336 find $tablet_dir >> $TMP_INST_LOG
337 fi
338 log_adjuster $TMP_INST_LOG $INST_LOG root log
339
340 # md5sum log
341 message "${MESSAGE_COLOR}Creating MD5 log" \
342 "${FILE_COLOR}${MD5_LOG}${DEFAULT_COLOR}"
343 if [[ $STAGED_INSTALL == on ]]; then
344 create_md5list $STAGE_INST_LOG $TMP_MD5_LOG
345 sed -i "s#${STAGE_DIRECTORY}/TRANSL##g" $TMP_MD5_LOG
346 else
347 create_md5list $TMP_INST_LOG $TMP_MD5_LOG
348 fi
349 log_adjuster $TMP_MD5_LOG $MD5_LOG root log md5_log_filter
350
351 # do this before cache archive creation (bug 8249)
352 rm_source_dir
353 if [[ $STAGED_INSTALL != off ]]
354 then
355 destroy_stage_root
356 fi
357
358 # cache archive
359
360 # Archives are stored with INSTALL_ROOT and STATE_ROOT stripped.
361 # this way they can be unpacked anywhere and sorcery will know
362 # where things will be.
363 create_cache_archive $TMP_INST_LOG $CACHE $CACHE_COMP
364
365 report_install
366 rm -f $IW_LOG $C_LOG $TMP_INST_LOG $TMP_MD5_LOG "$STAGE_INST_LOG"
367 }
368
369 #---------------------------------------------------------------------
370 ## Stuff that should be done if run_build_spell">run_build_spell fails
371 ## This is intended to be overridable at some point
372 #---------------------------------------------------------------------
373 function run_spell_failure() {
374 debug "build_api/common" "cast of $SPELL-$VERSION failed"
375 local rc=$1
376
377 sound FAILURE
378
379 local reason
380 get_failure_reason reason
381 activity_log "cast" "$SPELL" "$VERSION" "failure" "$reason"
382 echo $SPELL >> $FAILED_LIST
383
384 # if it failed after PRE_BUILD make a compile log
385 if [ "$rc" != 1 ] ; then
386 create_compile_log
387 view_compile_log
388 fi
389
390 # put the answers somewhere where they can still be used later
391 mkdir -p $ABANDONED_DEPENDS
392 local spell_depends
393 get_uncommitted_depends_file $SPELL spell_depends
394 [ -e "$spell_depends" ] && mv $spell_depends $ABANDONED_DEPENDS/$SPELL
395
396 # This may have been locked if there was a failure during the install
397 unlock_resources "libgrimoire" "install"
398
399 IW_LOG="${INSTALLWATCHFILE:-$INSTW_LOGFILE}"
400 devoke_installwatch
401
402 rm -f $IW_LOG $C_LOG
403
404 local spell_sub_depends spell_rsub_depends
405 get_uncommitted_sub_depends_file $SPELL spell_sub_depends
406 get_uncommitted_rsub_depends_file $SPELL spell_rsub_depends
407 rm -f "$spell_sub_depends" "$spell_rsub_depends"
408
409 if [[ $CLEAN_SOURCE == on ]]
410 then
411 rm_source_dir
412 if [[ $STAGED_INSTALL != off ]]
413 then
414 destroy_stage_root
415 fi
416 fi
417 CAST_EXIT_STATUS=1
418 }