OSDN Git Service

Fixed a bug that portsreinstall-chroot auto had lost its functionality.
[portsreinstall/current.git] / lib / chroot / libcommand_do.sh
1 #!/bin/sh -e
2 # ==============================================================================
3 # portsreinstall library script
4 # Overlay onto lib/libcommand_do.sh for portsreinstall-chroot
5 # - "do" command operation -
6 # Copyright (C) 2018 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
7 # This software is distributed under the 2-Clause BSD License.
8 # ==============================================================================
9
10 # ============= Check the completion of build at the chroot environment =============
11 command_do_chk_build_completion ()
12 {
13         [ -e "$opt_basedir/builder/${DBDIR_PROG}"/stage.complete/ALL_COMPLETE ]
14 }
15
16 # ============= Check whether the termination of portsreinstall at the chroot environment was a unionfs error =============
17 command_do_chk_unionfs_error_at_chroot ()
18 {
19         [ -e "$opt_basedir/builder/${DBDIR_PROG}"/execflag/unionfs_error ]
20 }
21
22 # ============= Get the recent chroot exit status of the builder chroot environment =============
23 command_do_get_recent_chroot_exit_status ()
24 {
25         cat "${DBDIR}/recent_exit_status"
26 }
27
28 # ============= Enter the shell of the guest =============
29 command_do_chroot_enter_shell ()
30 {
31         local shellcmd exitstatus
32         message_cat <<eof
33 =========================================================
34 You entered the builder chroot environment.
35 Complete the update of packages by portsreinstall(8),
36 Then exit to the target environment.
37 =========================================================
38
39 eof
40         shellcmd=`id -P | sed -E 's|.*:([^:]*)$|\1|'`
41         case `basename "$shellcmd"` in
42         sh | ksh | zsh | '' )
43                 shellcmd="env PS1='\\\$@[builder]\h\\$ ' ${shellcmd:-/bin/sh}"
44                 ;;
45         bash )
46                 shellcmd="env PS1='\u@[builder]\h\\$ ' $shellcmd"
47                 ;;
48         esac
49         chroot "$opt_basedir"/builder "$shellcmd"
50         exitstatus=$?
51         echo "$exitstatus" > ${DBDIR}/recent_exit_status
52         return $exitstatus
53 }
54
55 # ============= Execute in the chroot environment automatically repeating by fixing the file systems =============
56 _command_do_auto_repeat_by_fixing_fs ()
57 {
58         until "$@" || ! command_do_chk_unionfs_error_at_chroot
59         do
60                 message_echo "INFO: Retrying by re-mounting the file systems for the builder chroot environment." >&2
61                 fs_unmount
62                 fs_mount
63         done
64 }
65
66 # ============= Continue reinstallation in the guest =============
67 command_do_chroot_enter_fullcourse ()
68 {
69         local exitstatus opt_quiet
70         message_section_title "Full course main: Reinstallation process"
71         [ $opt_batch_mode = yes ] && opt_quiet='-a '
72         chroot "$opt_basedir"/builder /usr/bin/env ${PROGRAM} -S $opt_quiet
73         exitstatus=$?
74         echo "$exitstatus" > ${DBDIR}/recent_exit_status
75         return $exitstatus
76 }
77
78 # ============= Enter the guest and execute portsreinstall(8) automatically =============
79 command_do_chroot_auto ()
80 {
81         local exitstatus opt_quiet
82         [ $opt_batch_mode = yes ] && opt_quiet='-a '
83         message_cat <<eof
84 =========================================================
85 Automatic execution inside the builder chroot environment:
86 portsreinstall -S $@
87 =========================================================
88
89 eof
90         chroot "$opt_basedir"/builder /usr/bin/env ${PROGRAM} -S $opt_quiet "$@"
91         exitstatus=$?
92         echo "$exitstatus" > ${DBDIR}/recent_exit_status
93         return $exitstatus
94 }
95
96 # ============= Enter the guest =============
97 command_do_chroot_enter ()
98 {
99         if [ $COMMAND_MODE = auto ]
100         then
101                 [ $opt_fullcourse = yes ] && message_section_title "Full course main"
102                 _command_do_auto_repeat_by_fixing_fs command_do_chroot_auto "$@"
103         elif [ $opt_fullcourse = no ]
104         then
105                 if ! command_do_chroot_enter_shell
106                 then
107                         message_echo "INFO: The last exit status in the builder chroot environment was non-zero." >&2
108                         command_do_chk_unionfs_error_at_chroot && \
109                                 message_echo "INFO: Executing ${APPNAME} again may be sufficient for the troubleshooting." >&2
110                 fi
111         else
112                 _command_do_auto_repeat_by_fixing_fs command_do_chroot_enter_fullcourse
113         fi
114         return `command_do_get_recent_chroot_exit_status`
115 }
116
117 # ============= Update of the files affecting package installation of the host environment  =============
118 command_do_update_host_files ()
119 {
120         local dirpath filepath
121         message_section_title "Update the files affecting package installation of the host environment"
122         message_echo "INFO: targets are packages, distfiles, port options and ports/packages management tools configurations"
123         for dirpath in "${DISTDIR}" "${PACKAGES}" "${PORT_DBDIR}"
124         do
125                 (
126                         mkdir -p "$dirpath"
127                         cd $dirpath && find . -type f
128                 ) | while read file
129                 do
130                         [ -e "$opt_basedir/builder$dirpath/$file" ] || rm "$dirpath/$file"
131                 done
132                 (
133                         cd "$opt_basedir"/builder$dirpath && find . -type f
134                 ) | while read file
135                 do
136                         [ ! -e "$dirpath/$file" -o "$opt_basedir/builder$dirpath/$file" -nt "$dirpath/$file" ] || continue
137                         nodedir=`dirname "$dirpath/$file"`
138                         mkdir -p "$nodedir"
139                         cp -p "$opt_basedir/builder$dirpath/$file" "$dirpath/$file"
140                 done
141                 find -d $dirpath -type d -empty -delete
142         done
143         for filepath in "${LOCALBASE}"/etc/portsreinstall.conf "${LOCALBASE}"/etc/pkgtools.conf "${LOCALBASE}"/etc/pkg.conf /etc/make.conf "${DBDIR}"
144         do
145                 if [ -e "$opt_basedir"/builder$filepath ]
146                 then
147                         [ ! -e $filepath -o "$opt_basedir"/builder$filepath -nt $filepath ] && cp -p "$opt_basedir"/builder$filepath $filepath
148                 else
149                         rm -f $filepath
150                 fi
151         done
152         message_echo
153 }
154
155 # ============= Ending process =============
156 command_do_ending_process ()
157 {
158         temp_terminate_process () { :; }
159         if [ $opt_no_opening_message = yes ]
160         then
161                 message_echo "Done as ${APPNAME}"
162                 return
163         fi
164         message_section_title "COMPLETELY DONE"
165         message_echo "- E N D -"
166 }
167
168 # ============= Initial clean up =============
169 command_do_chroot_cleanup  ()
170 {
171         local PROGRAM_DEPENDS
172         PROGRAM_DEPENDS=
173         _program_exec_and_record_completion__operation ()
174         {
175                 fs_destroy
176                 message_echo
177         }
178         program_exec_and_record_completion CLEANUP_GUEST
179 }
180
181 # ============= Common process after exiting from the chroot environment =============
182 command_do_chroot_postprocess ()
183 {
184                 if ! command_do_chk_build_completion
185                 then
186                         message_echo "INFO: Exited from the builder chroot environment without completing the build." >&2
187                         exit 130
188                 fi
189                 message_echo "INFO: The package build completed."
190                 message_echo "Is it OK to apply the upgrade to the host environment? ([y]/n)"
191                 if ! message_query_yn_default_yes
192                 then
193                         message_echo "INFO: Terminated because the continuation is stopped by the user."
194                         exit 130
195                 fi
196 }
197
198 # ============= Starter process in the chroot environment: Update the ports tree =============
199 command_do_starter_portsnap ()
200 {
201         local PROGRAM_DEPENDS
202         PROGRAM_DEPENDS='CLEANUP_GUEST'
203         _program_exec_and_record_completion__operation ()
204         {
205                 local mode stdout
206                 [ $opt_fullcourse = no ] && return
207                 message_section_title "Full course starter: Update the ports tree"
208                 if [ -e "$opt_basedir/builder$PORTSNAP_WORKDIR/INDEX" ]
209                 then
210                         mode=update
211                 else
212                         mode=extract
213                 fi
214                 if [ $opt_batch_mode = no ]
215                 then
216                         stdout=/dev/stdout
217                 else
218                         stdout=/dev/null
219                 fi
220                 chroot "$opt_basedir"/builder /usr/bin/env portsnap fetch $mode > $stdout
221                 message_echo
222         }
223         program_exec_and_record_completion STARTER_GUEST_PORTS_TREE
224 }
225
226 # ============= Starter process in the chroot environment: Update the package repository =============
227 command_do_starter_pkg ()
228 {
229         local PROGRAM_DEPENDS
230         PROGRAM_DEPENDS='STARTER_GUEST_PORTS_TREE'
231         _program_exec_and_record_completion__operation ()
232         {
233                 local opts
234                 [ $opt_fullcourse = no ] && return
235                 message_section_title "Full course starter: Update the package repository"
236                 if [ $opt_batch_mode = no ]
237                 then
238                         opts=
239                 else
240                         opts='-q'
241                 fi
242                 chroot "$opt_basedir"/builder /usr/bin/env pkg update $opts
243                 message_echo
244         }
245         program_exec_and_record_completion STARTER_GUEST_PKG_REPO
246 }
247
248 # ============= Starter process in the chroot environment: Clean the temporary database =============
249 command_do_starter_clean ()
250 {
251         local PROGRAM_DEPENDS
252         PROGRAM_DEPENDS='STARTER_GUEST_PKG_REPO'
253         _program_exec_and_record_completion__operation ()
254         {
255                 local opts
256                 [ $opt_fullcourse = no ] && return
257                 message_section_title "Full course starter: Clean the temporary database"
258                 if [ $opt_batch_mode = no ]
259                 then
260                         opts=
261                 else
262                         opts='-q'
263                 fi
264                 chroot "$opt_basedir"/builder /usr/bin/env ${PROGRAM} $opts clean force
265                 message_echo
266         }
267         program_exec_and_record_completion STARTER_GUEST_CLEAN
268 }
269
270 # ============= Main process in the chroot environment: Initiate the reinstallation process =============
271 command_do_main_init_resinst ()
272 {
273         local PROGRAM_DEPENDS
274         PROGRAM_DEPENDS='STARTER_GUEST_CLEAN'
275         _program_exec_and_record_completion__operation ()
276         {
277                 local exitstatus
278                 [ $opt_fullcourse = no ] && return
279                 message_section_title "Full course main: Initiate the reinstallation process"
280                 opts=
281                 [ $opt_batch_mode = yes ] && opts='-Ya'
282                 chroot "$opt_basedir"/builder /usr/bin/env ${PROGRAM} -SJCGjqx $opts
283                 message_echo
284         }
285         program_exec_and_record_completion STARTER_GUEST_INIT_REINST
286 }
287
288 # ============= Enter the chroot environment =============
289 command_do_chroot_enter_if_incomplete ()
290 {
291         local PROGRAM_DEPENDS
292         command_do_chk_build_completion || program_deregister_stage_complete UPGRADE_GUEST
293         PROGRAM_DEPENDS='STARTER_GUEST_INIT_REINST'
294         _program_exec_and_record_completion__operation ()
295         {
296                 local exitstatus
297                 command_do_chroot_enter "$@"
298                 exitstatus=`command_do_get_recent_chroot_exit_status`
299                 [ "$exitstatus" -gt 0 ] && exit $exitstatus
300                 command_do_chroot_postprocess
301                 message_echo
302         }
303         program_exec_and_record_completion UPGRADE_GUEST "$@"
304 }
305
306 # ============= Pack (re)installed packages at the chroot environment =============
307 command_do_chroot_pack_update ()
308 {
309         local PROGRAM_DEPENDS
310         if [ -e "$opt_basedir"/store/complete ]
311         then
312                 if ! command_do_chk_build_completion
313                 then
314                         program_deregister_stage_complete PACK_PKGS
315                         rm -rf "$opt_basedir"/store/complete
316                 fi
317         else
318                 program_deregister_stage_complete PACK_PKGS
319         fi
320         PROGRAM_DEPENDS='UPGRADE_GUEST'
321         _program_exec_and_record_completion__operation ()
322         {
323                 message_section_title "Pack the upgrades"
324                 [ $opt_batch_mode = yes ] && opt_quiet='-a '
325                 chroot "$opt_basedir"/builder /bin/csh -c "${PROGRAM} -S $opt_quiet packupgrade create && ${PROGRAM} -S $opt_quiet packupgrade crop /.${PROGRAM}"
326         }
327         program_exec_and_record_completion PACK_PKGS
328 }
329
330 # ============= Update of the files affecting package installation of the host environment  =============
331 command_do_chroot_update_host_files ()
332 {
333         local PROGRAM_DEPENDS
334         PROGRAM_DEPENDS='PACK_PKGS'
335         _program_exec_and_record_completion__operation ()
336         {
337                 command_do_update_host_files
338         }
339         program_exec_and_record_completion UPDATE_HOST
340 }
341
342 # ============= Update of packages at the host environment =============
343 command_do_chroot_update_host_pkgs ()
344 {
345         local PROGRAM_DEPENDS
346         PROGRAM_DEPENDS='UPDATE_HOST'
347         _program_exec_and_record_completion__operation ()
348         {
349                 message_section_title "Extract the upgrade archive"
350                 (
351                         cd "$opt_basedir"/store
352                         rm -rf work
353                         mkdir work
354                         tar xzf portsreinstall-upgrade.tar.gz -C work
355                 )
356         }
357         program_exec_and_record_completion EXTRACT_SCRIPT_ARCHIVE
358         PROGRAM_DEPENDS='EXTRACT_SCRIPT_ARCHIVE'
359         _program_exec_and_record_completion__operation ()
360         {
361                 message_section_title "Update the packages at the host environment"
362                 (
363                         cd "$opt_basedir"/store
364                         opt_quiet=
365                         [ $opt_batch_mode = yes ] && opt_quiet='-a '
366                         work/portsreinstall-upgrade -S clean
367                         work/portsreinstall-upgrade -S $opt_quiet -P "${PACKAGES}/${PKGREPOSITORYSUBDIR}"
368                 )
369         }
370         program_exec_and_record_completion UPGRADE_HOST
371 }
372
373 # ============= Main pre-operation of do/auto =============
374 command_do_pre ()
375 {
376         # Initial clean up
377         command_do_chroot_cleanup
378         
379         # Build and mount of the chroot environment
380         fs_build_chroot
381         fs_mount
382 }
383
384 # ============= Main post-operation of do/auto =============
385 command_do_post ()
386 {
387         # Pack (re)installed packages at the guest
388         command_do_chroot_pack_update
389         
390         # Update of the files affecting package installation of the host environment 
391         command_do_chroot_update_host_files
392         
393         # Update of packages at the host environment
394         command_do_chroot_update_host_pkgs
395 }