OSDN Git Service

7022f7005294914f60d5dfadfd4d97c30fc6235a
[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         [ "x$opt_share_port_pkgs_dirs" = xyes ] && return
122         message_section_title "Update the files affecting package installation of the host environment"
123         message_echo "INFO: targets are packages, distfiles, port options and ports/packages management tools configurations"
124         for dirpath in "${DISTDIR}" "${PACKAGES}" "${PORT_DBDIR}"
125         do
126                 (
127                         mkdir -p "$dirpath"
128                         cd $dirpath && find . -type f
129                 ) | while read file
130                 do
131                         [ -e "$opt_basedir/builder$dirpath/$file" ] || rm "$dirpath/$file"
132                 done
133                 (
134                         cd "$opt_basedir"/builder$dirpath && find . -type f
135                 ) | while read file
136                 do
137                         [ ! -e "$dirpath/$file" -o "$opt_basedir/builder$dirpath/$file" -nt "$dirpath/$file" ] || continue
138                         nodedir=`dirname "$dirpath/$file"`
139                         mkdir -p "$nodedir"
140                         cp -p "$opt_basedir/builder$dirpath/$file" "$dirpath/$file"
141                 done
142                 find -d $dirpath -mindepth 1 -type d -empty -delete
143         done
144         for filepath in "${LOCALBASE}"/etc/portsreinstall.conf "${LOCALBASE}"/etc/pkgtools.conf "${LOCALBASE}"/etc/pkg.conf /etc/make.conf "${DBDIR}"
145         do
146                 if [ -e "$opt_basedir"/builder$filepath ]
147                 then
148                         [ ! -e $filepath -o "$opt_basedir"/builder$filepath -nt $filepath ] && cp -p "$opt_basedir"/builder$filepath $filepath
149                 else
150                         rm -f $filepath
151                 fi
152         done
153         message_echo
154 }
155
156 # ============= Ending process =============
157 command_do_ending_process ()
158 {
159         temp_terminate_process () { :; }
160         if [ $opt_no_opening_message = yes ]
161         then
162                 message_echo "Done as ${APPNAME}"
163                 return
164         fi
165         message_section_title "COMPLETELY DONE"
166         message_echo "- E N D -"
167 }
168
169 # ============= Initial clean up =============
170 command_do_chroot_cleanup  ()
171 {
172         local PROGRAM_DEPENDS
173         PROGRAM_DEPENDS=
174         _program_exec_and_record_completion__operation ()
175         {
176                 fs_destroy
177                 message_echo
178         }
179         program_exec_and_record_completion CLEANUP_GUEST
180 }
181
182 # ============= Common process after exiting from the chroot environment =============
183 command_do_chroot_postprocess ()
184 {
185                 if ! command_do_chk_build_completion
186                 then
187                         message_echo "INFO: Exited from the builder chroot environment without completing the build." >&2
188                         exit 130
189                 fi
190                 message_echo "INFO: The package build completed."
191                 message_echo "Is it OK to apply the upgrade to the host environment? ([y]/n)"
192                 if ! message_query_yn_default_yes
193                 then
194                         message_echo "INFO: Terminated because the continuation is stopped by the user."
195                         exit 130
196                 fi
197 }
198
199 # ============= Starter process in the chroot environment: Update the ports tree =============
200 command_do_starter_portsnap ()
201 {
202         local PROGRAM_DEPENDS
203         PROGRAM_DEPENDS='CLEANUP_GUEST'
204         _program_exec_and_record_completion__operation ()
205         {
206                 local mode stdout
207                 [ $opt_fullcourse = no ] && return
208                 message_section_title "Full course starter: Update the ports tree"
209                 pkgsys_update_portstree
210                 message_echo
211         }
212         program_exec_and_record_completion STARTER_GUEST_PORTS_TREE
213 }
214
215 # ============= Starter process of the full course: Update the package repository =============
216 command_do_starter_pkg ()
217 {
218         local PROGRAM_DEPENDS
219         PROGRAM_DEPENDS='STARTER_GUEST_PORTS_TREE'
220         _program_exec_and_record_completion__operation ()
221         {
222                 local opts
223                 [ $opt_fullcourse = no ] && return
224                 message_section_title "Full course starter: Update the package repository"
225                 pkg_update_pkgrepository
226                 message_echo
227         }
228         program_exec_and_record_completion STARTER_GUEST_PKG_REPO
229 }
230
231 # ============= Starter process of the full course: Clean the temporary database =============
232 command_do_starter_clean ()
233 {
234         local PROGRAM_DEPENDS
235         PROGRAM_DEPENDS='STARTER_GUEST_PKG_REPO'
236         _program_exec_and_record_completion__operation ()
237         {
238                 local opts
239                 [ $opt_fullcourse = no ] && return
240                 message_section_title "Full course starter: Clean the temporary database"
241                 if [ $opt_batch_mode = no ]
242                 then
243                         opts=
244                 else
245                         opts='-q'
246                 fi
247                 chroot "$opt_basedir"/builder /usr/bin/env ${PROGRAM} $opts clean force
248                 message_echo
249         }
250         program_exec_and_record_completion STARTER_GUEST_CLEAN
251 }
252
253 # ============= Main process in the chroot environment: Initiate the reinstallation process =============
254 command_do_main_init_resinst ()
255 {
256         local PROGRAM_DEPENDS
257         PROGRAM_DEPENDS='STARTER_GUEST_CLEAN'
258         _program_exec_and_record_completion__operation ()
259         {
260                 local opts opt_smart
261                 [ $opt_fullcourse = no ] && return
262                 message_section_title "Full course main: Initiate the reinstallation process"
263                 opts=
264                 [ $opt_batch_mode = yes ] && opts='-Ya'
265                 opt_smart=
266                 [ $opt_upgraded_system = no ]  && opt_smart='-q'
267                 chroot "$opt_basedir"/builder /usr/bin/env ${PROGRAM} -SJCGjx $opts $opt_smart
268                 message_echo
269         }
270         program_exec_and_record_completion STARTER_GUEST_INIT_REINST
271 }
272
273 # ============= Enter the chroot environment =============
274 command_do_chroot_enter_if_incomplete ()
275 {
276         local PROGRAM_DEPENDS
277         command_do_chk_build_completion || program_deregister_stage_complete UPGRADE_GUEST
278         PROGRAM_DEPENDS='STARTER_GUEST_INIT_REINST'
279         _program_exec_and_record_completion__operation ()
280         {
281                 local exitstatus
282                 command_do_chroot_enter "$@"
283                 exitstatus=`command_do_get_recent_chroot_exit_status`
284                 [ "$exitstatus" -gt 0 ] && exit $exitstatus
285                 command_do_chroot_postprocess
286                 message_echo
287         }
288         program_exec_and_record_completion UPGRADE_GUEST "$@"
289 }
290
291 # ============= Pack (re)installed packages at the chroot environment =============
292 command_do_chroot_pack_update ()
293 {
294         local PROGRAM_DEPENDS
295         if [ -e "$opt_basedir"/store/complete ]
296         then
297                 if ! command_do_chk_build_completion
298                 then
299                         program_deregister_stage_complete PACK_PKGS
300                         rm -rf "$opt_basedir"/store/complete
301                 fi
302         else
303                 program_deregister_stage_complete PACK_PKGS
304         fi
305         PROGRAM_DEPENDS='UPGRADE_GUEST'
306         _program_exec_and_record_completion__operation ()
307         {
308                 message_section_title "Pack the upgrades"
309                 [ $opt_batch_mode = yes ] && opt_quiet='-a '
310                 chroot "$opt_basedir"/builder /bin/csh -c "${PROGRAM} -S $opt_quiet packupgrade create && ${PROGRAM} -S $opt_quiet packupgrade crop /.${PROGRAM}"
311         }
312         program_exec_and_record_completion PACK_PKGS
313 }
314
315 # ============= Update of the files affecting package installation of the host environment  =============
316 command_do_chroot_update_host_files ()
317 {
318         local PROGRAM_DEPENDS
319         PROGRAM_DEPENDS='PACK_PKGS'
320         _program_exec_and_record_completion__operation ()
321         {
322                 command_do_update_host_files
323         }
324         program_exec_and_record_completion UPDATE_HOST
325 }
326
327 # ============= Update of packages at the host environment =============
328 command_do_chroot_update_host_pkgs ()
329 {
330         local PROGRAM_DEPENDS
331         PROGRAM_DEPENDS='UPDATE_HOST'
332         _program_exec_and_record_completion__operation ()
333         {
334                 local storedir
335                 message_section_title "Extract the upgrade archive"
336                 storedir=$opt_basedir/store
337                 rm -rf "$storedir/work"
338                 mkdir "$storedir/work"
339                 tar xzf "$storedir/portsreinstall-upgrade.tar.gz" -C "$storedir/work"
340                 message_echo
341         }
342         program_exec_and_record_completion EXTRACT_SCRIPT_ARCHIVE
343         PROGRAM_DEPENDS='EXTRACT_SCRIPT_ARCHIVE'
344         _program_exec_and_record_completion__operation ()
345         {
346                 local opt_quiet
347                 message_section_title "Update the packages at the host environment"
348                 opt_quiet=
349                 [ $opt_batch_mode = yes ] && opt_quiet='-a '
350                 $opt_basedir/store/work/portsreinstall-upgrade -S clean
351                 $opt_basedir/store/work/portsreinstall-upgrade -S $opt_quiet -P "${PACKAGES}/${PKGREPOSITORYSUBDIR}"
352         }
353         program_exec_and_record_completion UPGRADE_HOST
354 }
355
356 # ============= Main pre-operation of do/auto =============
357 command_do_pre ()
358 {
359         # Build and mount of the chroot environment
360         fs_build_chroot
361         fs_mount
362 }
363
364 # ============= Main post-operation of do/auto =============
365 command_do_post ()
366 {
367         # Pack (re)installed packages at the guest
368         command_do_chroot_pack_update
369         
370         # Update of the files affecting package installation of the host environment 
371         command_do_chroot_update_host_files
372         
373         # Update of packages at the host environment
374         command_do_chroot_update_host_pkgs
375 }