OSDN Git Service

e38ef2188d761768a99ecee195b9b64ec6e62f72
[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 exitstatus
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                 chroot "$opt_basedir"/builder /usr/bin/env ${PROGRAM} -SJCGjqx $opts
266                 message_echo
267         }
268         program_exec_and_record_completion STARTER_GUEST_INIT_REINST
269 }
270
271 # ============= Enter the chroot environment =============
272 command_do_chroot_enter_if_incomplete ()
273 {
274         local PROGRAM_DEPENDS
275         command_do_chk_build_completion || program_deregister_stage_complete UPGRADE_GUEST
276         PROGRAM_DEPENDS='STARTER_GUEST_INIT_REINST'
277         _program_exec_and_record_completion__operation ()
278         {
279                 local exitstatus
280                 command_do_chroot_enter "$@"
281                 exitstatus=`command_do_get_recent_chroot_exit_status`
282                 [ "$exitstatus" -gt 0 ] && exit $exitstatus
283                 command_do_chroot_postprocess
284                 message_echo
285         }
286         program_exec_and_record_completion UPGRADE_GUEST "$@"
287 }
288
289 # ============= Pack (re)installed packages at the chroot environment =============
290 command_do_chroot_pack_update ()
291 {
292         local PROGRAM_DEPENDS
293         if [ -e "$opt_basedir"/store/complete ]
294         then
295                 if ! command_do_chk_build_completion
296                 then
297                         program_deregister_stage_complete PACK_PKGS
298                         rm -rf "$opt_basedir"/store/complete
299                 fi
300         else
301                 program_deregister_stage_complete PACK_PKGS
302         fi
303         PROGRAM_DEPENDS='UPGRADE_GUEST'
304         _program_exec_and_record_completion__operation ()
305         {
306                 message_section_title "Pack the upgrades"
307                 [ $opt_batch_mode = yes ] && opt_quiet='-a '
308                 chroot "$opt_basedir"/builder /bin/csh -c "${PROGRAM} -S $opt_quiet packupgrade create && ${PROGRAM} -S $opt_quiet packupgrade crop /.${PROGRAM}"
309         }
310         program_exec_and_record_completion PACK_PKGS
311 }
312
313 # ============= Update of the files affecting package installation of the host environment  =============
314 command_do_chroot_update_host_files ()
315 {
316         local PROGRAM_DEPENDS
317         PROGRAM_DEPENDS='PACK_PKGS'
318         _program_exec_and_record_completion__operation ()
319         {
320                 command_do_update_host_files
321         }
322         program_exec_and_record_completion UPDATE_HOST
323 }
324
325 # ============= Update of packages at the host environment =============
326 command_do_chroot_update_host_pkgs ()
327 {
328         local PROGRAM_DEPENDS
329         PROGRAM_DEPENDS='UPDATE_HOST'
330         _program_exec_and_record_completion__operation ()
331         {
332                 local storedir
333                 message_section_title "Extract the upgrade archive"
334                 storedir=$opt_basedir/store
335                 rm -rf "$storedir/work"
336                 mkdir "$storedir/work"
337                 tar xzf "$storedir/portsreinstall-upgrade.tar.gz" -C "$storedir/work"
338                 message_echo
339         }
340         program_exec_and_record_completion EXTRACT_SCRIPT_ARCHIVE
341         PROGRAM_DEPENDS='EXTRACT_SCRIPT_ARCHIVE'
342         _program_exec_and_record_completion__operation ()
343         {
344                 local opt_quiet
345                 message_section_title "Update the packages at the host environment"
346                 opt_quiet=
347                 [ $opt_batch_mode = yes ] && opt_quiet='-a '
348                 $opt_basedir/store/work/portsreinstall-upgrade -S clean
349                 $opt_basedir/store/work/portsreinstall-upgrade -S $opt_quiet -P "${PACKAGES}/${PKGREPOSITORYSUBDIR}"
350         }
351         program_exec_and_record_completion UPGRADE_HOST
352 }
353
354 # ============= Main pre-operation of do/auto =============
355 command_do_pre ()
356 {
357         # Build and mount of the chroot environment
358         fs_build_chroot
359         fs_mount
360 }
361
362 # ============= Main post-operation of do/auto =============
363 command_do_post ()
364 {
365         # Pack (re)installed packages at the guest
366         command_do_chroot_pack_update
367         
368         # Update of the files affecting package installation of the host environment 
369         command_do_chroot_update_host_files
370         
371         # Update of packages at the host environment
372         command_do_chroot_update_host_pkgs
373 }