2 # ==============================================================================
3 # portsreinstall library script
4 # - Commands of ports/packages operations -
5 # Copyright (C) 2018 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
9 # ============= Operation of reconf/rmconf command =============
10 command_pkgs_port_option_conf ()
12 local make_target origin
15 message_echo "Reconfigure the specified port options."
19 message_echo "The specified port options are reset to the default."
23 message_echo "Affected parts of the temporary database are reset automatically."
24 for origin in `pkgsys_eval_ports_glob "$@"`
26 message_echo "Re-configure $origin:"
27 database_build_make "$origin" $make_target
28 database_build_patch_reconf "$origin"
30 program_deregister_stage_complete PREPARE_FOR_INSPECT_ALL_DEPENDENCIES
31 program_deregister_stage_complete ALL_COMPLETE
34 # ============= Operation of escape command =============
35 command_pkgs_escape ()
37 local origin pkg backup_pkg
38 message_echo "Backing up and deleting the following packages for a temporary escape:"
40 for origin in `pkgsys_eval_ports_glob "$@"`
42 pkgsys_register_evaluated_globs add "${DBDIR}/taboo.list" "$origin"
43 message_echo " Registered $origin as taboo."
44 pkg=`pkgsys_get_installed_pkg_from_origin "$origin"`
45 [ -n "$pkg" ] || continue
46 if backup_pkg=`pkgsys_get_backup_pkg "$origin"`
48 message_echo "INFO: A backup package for $pkg ($origin) already exists as $backup_pkg."
49 elif backup_pkg=`pkgsys_create_backup_pkg "$pkg" "${DBDIR}/backup_packages"`
51 message_echo " Backed up $pkg ($origin) into $backup_pkg"
53 message_echo "ERROR: Failed to back up $pkg ($origin)." >&2
57 pkg_delete_f "$pkg" || \
59 message_echo "ERROR: Failed to deinstall $pkg ($origin)." >&2
62 message_echo " Deinstalled $pkg ($origin)."
65 fileedit_combine_lists "${DBDIR}/conf/TABOO:PORTS.parsed" "${DBDIR}/taboo.list" > ${DBDIR}/taboo.all.list
68 # ============= Operation of restore command =============
69 command_pkgs_restore ()
71 local tmp_done_orig origin pkg exists_old_origins origin_orig pkg_orig origin_replace pkg_replace backup_pkg
72 message_echo "Restoring the following temporary escaped packages:"
74 tmp_done_orig=${TMPDIR}/command_pkgs_restore::restore::done_orig
75 cp /dev/null "$tmp_done_orig"
76 for origin in `pkgsys_eval_ports_glob "$@"`
78 pkgsys_register_evaluated_globs remove "${DBDIR}/taboo.list" "$origin"
79 message_echo " Deregistered $origin from taboo."
80 grep -Fx -q "$origin" "$tmp_done_orig" 2> /dev/null || :
81 if pkgsys_exists_from_orig "$origin"
83 pkg=`pkgsys_get_installed_pkg_from_origin "$origin"`
84 message_echo "WARNING: $pkg ($origin) is already installed." >&2
89 for origin_orig in `database_query_initial_orgins "$origin"`
91 if [ "x$origin_orig" = "x$origin" ] && pkgsys_exists_from_orig "$origin_orig"
93 pkg_orig=`pkgsys_get_installed_pkg_from_origin "$origin_orig"`
94 message_echo "WARNING: An original version of $origin ($pkg_orig, $origin_orig) is already installed." >&2
96 exists_old_origins=yes
99 [ $exists_old_origins = yes ] && continue
100 origin_replace=`echo "$origin" \
101 | sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern"`
102 if [ "x$origin_replace" != "x$origin" ]
104 if pkgsys_exists_from_orig "$origin_replace"
106 pkg_replace=`pkgsys_get_installed_pkg_from_origin "$origin_replace"`
107 message_echo "WARNING: A replacement of $origin ($pkg_replace, $origin_replace) is already installed." >&2
111 if backup_pkg=`pkgsys_get_backup_pkg "$origin_replace" 2> /dev/null`
113 message_echo "INFO: $origin is replaced with $origin_replace ($pkg_replace)."
114 echo "$origin_replace" >> $tmp_done_orig
115 origin=$origin_replace
120 if [ -z "$backup_pkg" ] && ! backup_pkg=`pkgsys_get_backup_pkg "$origin" 2> /dev/null`
122 message_echo "ERROR: Backup for $origin is not found." >&2
126 pkg=`pkgsys_pkgarc_to_pkgname "$backup_pkg"`
127 if reinstall_chk_forbidden_conflicts "$pkg"
129 message_echo "WARNING: $pkg ($origin) is skipped because it conflicts with installed packages." >&2
133 if ! pkg_add_fF "$backup_pkg"
135 message_echo "ERROR: Failed to restore $pkg ($origin)." >&2
138 message_echo " Restored $pkg ($origin)."
141 fileedit_combine_lists "${DBDIR}/conf/TABOO:PORTS.parsed" "${DBDIR}/taboo.list" > ${DBDIR}/taboo.all.list
144 # ============= Operation of pkgsanity command =============
145 command_pkgs_pkgsanity ()
147 local tmp_list nlines iline pkg origin port_path is_reinstall_encouraged
148 tmp_list=${TMPDIR}/command_pkgs_pkgsanity:list
151 message_echo "Sanity check of the installed files for each package:"
153 pkg_info_Ea > $tmp_list.pkgs
154 pkg_info_all_flavored_origins > $tmp_list.orgs
156 message_echo "Examining the installed files for each specified package:"
158 pkgsys_eval_ports_glob "$@" > $tmp_list.orgs
161 pkgsys_get_installed_pkg_from_origin "$origin"
162 done < $tmp_list.orgs | grep -v '^[[:space:]]*$' > $tmp_list.pkgs || {
163 message_echo "WARNING: No such globs match any installed package." >&2
164 temp_terminate_process () { :; }
168 message_echo "<< Phase 1: Check and fix duplicated packages registrations for the same port origin >>"
172 [ `pkgsys_get_installed_pkg_from_origin "$origin" | wc -l` -gt 1 ] || continue
173 pkgsys_get_installed_pkg_from_origin "$origin" | while read pkg
175 echo "$((0+`pkg_check_sanity \"$pkg\" | wc -l`))" "$pkg"
176 done | sort -g > $tmp_list.pkgs_for_an_org
177 pkg_valid=`head -n 1 "$tmp_list.pkgs_for_an_org" | cut -d ' ' -f 2`
178 message_echo "Port [$origin] has multiply registered packages."
179 message_echo "The valid one will be [$pkg_valid]."
180 message_echo "Invalid one(s) will be as follows and to be deleted:"
181 sed 1d "$tmp_list.pkgs_for_an_org" | cut -d ' ' -f 2 > $tmp_list.pkgs_for_an_org_msg
182 message_cat "$tmp_list.pkgs_for_an_org_msg"
184 [ $opt_batch_mode = yes ] && errout=/dev/null
185 if backup_pkg=`pkgsys_create_backup_pkg "$pkg_valid" "${DBDIR}/backup_packages"`
188 pkg_delete_f `cat "$tmp_list.pkgs_for_an_org"` 2> $errout || {
189 message_echo "WARNING: Deletion of the broken packages may not be fully successful, but continuing anyway." >&2
192 pkg_add_fF "$backup_pkg" || {
193 message_echo "WARNING: Reinstallation of the most valid package failed, but continuing anyway." >&2
197 message_echo "WARNING: Backup of the most valid package failed, but continuing anyway." >&2
198 pkg_delete_f `cat "$tmp_list.pkgs_for_an_org"` 2> $errout || {
199 message_echo "WARNING: Deletion of the broken packages may not be fully successful, but continuing anyway." >&2
203 done < $tmp_list.orgs
205 message_echo "<< Phase 2: Check and mark broken packages for reinstallation >>"
207 nlines=`wc -l < $tmp_list.pkgs`
209 while [ $iline -le $nlines ]
211 pkg=`sed -n ${iline}p "$tmp_list.pkgs"`
212 iline=$((${iline}+1))
213 origin=`pkg_info_flavored_origin "$pkg"`
214 [ -n "$origin" ] || continue
215 grep -q -Fx "$origin" "${DBDIR}/damaged_package" 2>/dev/null && continue
216 pkgsys_sanitychk_pkgcontents "$pkg" is_reinstall_encouraged && continue
217 port_path=`pkgsys_get_portpath_from_origin "$origin"`
218 if [ ! -d "$port_path" ]
220 message_echo "WARNING: $pkg ($origin) is obsolete." >&2
224 if [ $is_reinstall_encouraged = no ]
226 if [ $opt_batch_mode = no ]
228 message_echo "Do you want to reinstall it? (y/[n])"
229 message_query_yn_default_no || continue
232 if [ $opt_batch_mode = no ]
234 message_echo "Do you want to reinstall it? ([y]/n)"
235 message_query_yn_default_yes || continue
237 database_record_reconf_recover_sanity "$origin"
242 # ============= Operation of packupgrade command =============
243 command_pkgs_packupgrade ()
245 case ${COMMAND_OPERATION} in
247 command_pkgs_packupgrade_clean
250 command_pkgs_packupgrade_create
253 command_pkgs_packupgrade_crop
258 # ============= Operation of packupgrade clean command =============
259 command_pkgs_packupgrade_clean ()
261 program_deregister_stage_complete COMMAND_PACKUPGRADE_PREPARE
262 rm -rf "${DBDIR}/command_packupgrade"
265 # ============= Stage of preparation in operation of packupgrade create command =============
266 command_pkgs_packupgrade_create__prepare ()
268 local PROGRAM_DEPENDS
270 _program_exec_and_record_completion__operation ()
273 message_section_title "Preparation"
274 mkdir -p "${PACKAGES}/${PKGREPOSITORYSUBDIR}"
275 cp "${DBDIR}/reinst_order.list" "${DBDIR}/stage.loop_list/command_packupgrade_pack"
276 cp "${DBDIR}/stage.loop_list/ports_to_delete" "${DBDIR}/stage.loop_list/command_packupgrade_delete" 2> /dev/null
277 dstdir=${DBDIR}/command_packupgrade
278 rm -rf "$dstdir" "$dstdir.tar.gz"
280 install -d "$dstdir/etc"
281 touch "$dstdir/etc/created_packages.lst"
282 pkg_get_pkgs_timestamps > $dstdir/etc/final_pkgs_snapshot.csv
285 program_exec_and_record_completion COMMAND_PACKUPGRADE_PREPARE
288 # ============= Stage of creating the manifest of deletion in operation of packupgrade create command =============
289 command_pkgs_packupgrade_create__manifest_delete ()
291 local PROGRAM_DEPENDS
292 PROGRAM_DEPENDS='COMMAND_PACKUPGRADE_PREPARE'
293 _program_exec_restartable_loop_operation__routine ()
297 printf '%s\t%s\t%s\n' delete "$origin" NA >> ${DBDIR}/command_packupgrade/etc/manifest.lst.delete
299 _program_exec_and_record_completion__operation ()
301 message_section_title "Create manifest of deletion"
302 program_exec_restartable_loop_operation command_packupgrade_delete
305 program_exec_and_record_completion COMMAND_PACKUPGRADE_MANIFEST_DELETE
308 # ============= Stage of creating the manifest of reinstallation in operation of packupgrade create command =============
309 command_pkgs_packupgrade_create__manifest_reinst ()
311 local PROGRAM_DEPENDS
312 PROGRAM_DEPENDS=COMMAND_PACKUPGRADE_PREPARE
313 _program_exec_restartable_loop_operation__routine ()
315 local origin dstdir tmp_manifest dbdir_new pkgname pkgarc timestamp_inst timestamp_arc origin_old
317 dstdir=${DBDIR}/command_packupgrade
318 tmp_manifest=${TMPDIR}/packupgrade::manifest
319 rm -rf "$tmp_manifest"
320 dbdir_new=${DBDIR}/requires/$origin
321 pkgname=`pkgsys_get_installed_pkg_from_origin "$origin"`
322 [ -n "$pkgname" ] || return 0
323 if ! grep -Fxq "$pkgname" "$dstdir/etc/created_packages.lst" 2> /dev/null
325 if pkg_info_e "$pkgname"
327 if pkgarc=`pkgsys_pkgname_to_pkgarc "${PACKAGESDIR}" "$pkgname"`
329 timestamp_inst=`pkg_get_pkg_timestamp "$pkgname" 2> /dev/null` || :
330 timestamp_arc=`ls -lD %s "$pkgarc" 2> /dev/null | sed -E 's/[[:space:]]+/ /g' | cut -w -f 6 | grep -v '^$'` || :
335 if [ -z "$timestamp_inst" -o -z "$timestamp_arc" -o "$timestamp_arc" -lt "$timestamp_inst" ]
337 if ! ( cd ${PACKAGESDIR}; pkg_create_b "$pkgname" | message_cat )
339 message_echo "ERROR: Failed to create package [$pkgname for $origin]." >&2
343 elif grep -Fxq "$origin" ${DBDIR}/success.run.full.list
345 message_echo "ERROR: Necessary package is missing [$origin]." >&2
348 fileedit_add_a_line_if_new "$pkgname" "$dstdir/etc/created_packages.lst"
350 if pkgsys_is_necessary_pkgtool "$origin"
352 pkg_patterns=`pkgsys_get_conflicting_pkgs_patterns install "$origin" | tr '\n' '|'`
353 printf '%s\t%s\t%s\n' addtool "$pkgname" "$origin|$pkg_patterns" >> $tmp_manifest
355 if [ -e "${DBDIR}/moved_from/$origin/initial_orig" ]
357 while read origin_old
359 printf '%s\t%s\t%s\n' delete "$origin_old" NA
360 done < ${DBDIR}/moved_from/$origin/initial_orig >> $tmp_manifest
362 printf '%s\t%s\t%s\n' delete "$origin" NA >> $tmp_manifest
363 pkgsys_get_conflicting_pkgs_patterns install "$origin" | while read pkg_pattern
365 printf '%s\t%s\t%s\n' delete_pattern "$pkg_pattern" NA >> $tmp_manifest
367 printf '%s\t%s\t%s\n' add "$pkgname" NA >> $tmp_manifest
369 cat "$tmp_manifest" >> $dstdir/etc/manifest.lst.update
371 _program_exec_and_record_completion__operation ()
374 message_section_title "Creating manifest of (re)installation and package archives..."
375 PACKAGESDIR=${PACKAGES}/${PKGREPOSITORYSUBDIR}
376 mkdir -p "${PACKAGESDIR}"
377 PACKAGESDIR=`realpath "${PACKAGESDIR}"`
378 program_exec_restartable_loop_operation command_packupgrade_pack
381 program_exec_and_record_completion COMMAND_PACKUPGRADE_MANIFEST_REINST
384 # ============= Stage of packing in operation of packupgrade create command =============
385 command_pkgs_packupgrade_create__pack ()
387 local PROGRAM_DEPENDS
388 PROGRAM_DEPENDS='COMMAND_PACKUPGRADE_MANIFEST_DELETE'
389 _program_exec_and_record_completion__operation ()
392 message_section_title "Packing for the upgrade at the target systems"
393 dstdir=${DBDIR}/command_packupgrade
394 cat "$dstdir/etc/manifest.lst.delete" "$dstdir/etc/manifest.lst.update" > $dstdir/etc/manifest.lst
395 install -m 444 "${DBDIR}"/WITH_PKGNG "${DBDIR}"/conf/complete_setup.sh "${DBDIR}"/conf/setenv.sh "$dstdir/etc"
396 install "${SHAREDIR}/bin/${APPNAME}-upgrade" "$dstdir"
397 install -d "$dstdir/lib/upgrade" "$dstdir/man/man8"
398 ( cd "${LIBDIR}" && find . upgrade -depth 1 -type f ) | while read filepath
400 install -m 444 "${LIBDIR}/$filepath" "$dstdir/lib/$filepath"
402 install -m 444 "${MYPREFIX}/man/man8/${PROGRAM}-upgrade.8.gz" "$dstdir/man/man8"
403 tar czf "$dstdir.tar.gz" -C "$dstdir" .
404 touch "$dstdir/complete"
406 program_exec_and_record_completion COMMAND_PACKUPGRADE_PACK
409 # ============= Operation of packupgrade create command =============
410 command_pkgs_packupgrade_create ()
412 if ! program_chk_stage_complete ALL_COMPLETE
414 message_echo "ERROR: The reinstallation of ports must be completed before using this command." >&2
418 command_pkgs_packupgrade_create__prepare
419 # Create manifest of deletion
420 command_pkgs_packupgrade_create__manifest_delete
421 # Create manifest of (re)installation and package archives
422 command_pkgs_packupgrade_create__manifest_reinst
423 # Packing for the upgrade at the target systems
424 command_pkgs_packupgrade_create__pack
427 # ============= Operation of packupgrade crop command =============
428 command_pkgs_packupgrade_crop ()
431 if ! program_chk_stage_complete ALL_COMPLETE
433 message_echo "ERROR: The reinstallation of ports must be completed before using this command." >&2
436 dstdir=${DBDIR}/command_packupgrade
437 if [ ! -e "$dstdir/complete" ]
439 message_echo "ERROR: The execution of \"packupgrade create\" command must be completed before using this command." >&2
442 cp "$dstdir.tar.gz" "${COMMAND_PACKUPGRADE_SAVEPATH}"
443 message_echo "INFO: The cropped archive is saved as [${COMMAND_PACKUPGRADE_SAVEPATH}]."
447 # ============= Operation of make command =============
448 command_pkgs_make_ports ()
452 origins=`pkgsys_eval_ports_glob "$glob"`
453 [ -n "$origins" ] || message_echo "WARNING: No matching port for the glob pattern $glob" >&2
454 echo "$origins" | while read origin
456 message_echo "========== [$origin] =========="
457 reinstall_make_individual "$origin" "$@"
460 [ $errno -eq 0 ] || exit $errno