├── .gitignore ├── LICENSE ├── README ├── TODO ├── dfly-update └── dfly-update.conf /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.swp 3 | *.orig 4 | *.bak 5 | *_bak 6 | .#* 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-2020 Aaron LI 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | =========== 2 | dfly-update 3 | =========== 4 | 5 | A simple tool to update a DragonFly BSD system using a binary release or 6 | snapshot image file. 7 | 8 | Introduction 9 | ------------ 10 | The officially supported method to update a DragonFly BSD system is 11 | building and installing from the source. However, on a low-end machine 12 | (e.g., a small VPS), it's time-consuming and hard to build the source. On 13 | the other hand, it's not easy to transfer the built "/usr/obj" (quite big) 14 | to a remote VPS for an update. Therefore, a simple tool to update a the 15 | system directly using a binary release or snapshot image is very useful and 16 | necessary. 17 | 18 | This tool refers to the installation procedures and the official source 19 | upgrade processes to implement the update task, which mainly includes 20 | the following steps: 21 | 22 | 1. mount the system image file (*.img); 23 | 2. backup the current kernel and world (including "/etc"); 24 | 3. install the kernel and world using cpdup (similar to the installer); 25 | 4. create new users and groups; 26 | 5. identify the new/changed "/etc" files, rename the conflicting ones 27 | with suffix ".__new__" and then copy over; 28 | 6. remove obsolete files according to "Makefile_upgrade.inc"; 29 | 7. umount, show the "*.__new__" files that need manual merge. 30 | 31 | Usage 32 | ----- 33 | dfly# git clone https://github.com/liweitianux/dfly-update 34 | dfly# cd dfly-update 35 | dfly# ./dfly-update fly 36 | 37 | NOTE: 38 | After this, you still need to merge the listed config files with suffix 39 | ".__new__", and also upgrade the packages. 40 | 41 | Versions 42 | -------- 43 | * 0.2.0 (2019-01-09) 44 | - New command line syntax 45 | - Remove the "status" and "download" commands to be a lot simpler 46 | - Use "cpdup -X" to ignore the files that should not be overwritten 47 | - Create new users/groups according to the new master.passwd/group 48 | - Multiple other small improvements and cleanups 49 | * 0.1.5 (2018-12-28) 50 | - Rebuild multiple databases after upgrade 51 | - Various minor cleanups 52 | * 0.1.4 (2018-12-20) 53 | - Install "/rescue" directory 54 | - Improve mtree(8) usage 55 | * 0.1.3 (2018-04-16) 56 | - Fix the issue that the old "Makefile_upgrade" was used 57 | - Make the upgrade messages more concise 58 | * 0.1.2 (2018-03-11) 59 | - First usable version for broader testing 60 | 61 | License 62 | ------- 63 | MIT License 64 | Copyright (c) 2017-2020 Aaron LI 65 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | * PATH: use tools from the new system 2 | * Merge new users/groups 3 | * Interactively merge updated /etc files 4 | (borrow OpenBSD's sysmerge(8) or improve/simplify mergemaster(8)) 5 | * rcs(1) controlled /etc upgrade 6 | 7 | [rcs-etc] 8 | * rcs + vendor branch: to manage /etc and support 3-way merge to update 9 | the files 10 | * etc-upgrade can be interrupted/paused and then resumed 11 | * generate a detailed report for the upgrade, something like a git commit 12 | * display the report and let user to make sure the upgrade is correct 13 | * send the report as an email to root 14 | 15 | * trap signal; clean up on error 16 | * lock/status file to be safe ... 17 | -------------------------------------------------------------------------------- /dfly-update: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2017-2020 Aaron LI 4 | # MIT License 5 | # 6 | # Tool to update a DragonFly BSD system using binary releases or 7 | # snapshot builds. 8 | # 9 | 10 | # Exit immediately if any untested command fails in non-interactive mode 11 | set -e 12 | # Exit with an error when an undefined variable is referenced 13 | set -u 14 | 15 | DEBUG=${DEBUG:-""} 16 | 17 | VERSION="0.2.0" 18 | NAME="dfly-update" 19 | AUTHOR="Aaron LI " 20 | URL="https://github.com/liweitianux/dfly-update" 21 | 22 | # 23 | # Error Codes 24 | # 25 | 26 | EC_USAGE=1 27 | EC_ARGS=2 28 | EC_CONFIG=11 29 | EC_TMPFILE=12 30 | EC_MD5=13 31 | EC_FETCH=14 32 | EC_MOUNT=15 33 | EC_UMOUNT=16 34 | EC_VN=17 35 | EC_TAR=18 36 | EC_MTREE=19 37 | EC_CPDUP=20 38 | EC_NOFILE=21 39 | EC_PW=22 40 | 41 | 42 | # 43 | # Default Configurations 44 | # 45 | 46 | # Path to the cpdup(1) executable 47 | CPDUP="/bin/cpdup" 48 | # Temporary directory to cache the image, etc, ... 49 | CACHE_DIR="/var/tmp/${NAME}" 50 | # Directory to mount the system image 51 | MNT_DIR="/mnt/${NAME}" 52 | # Backup directory 53 | BACK_DIR="/var/backups/${NAME}" 54 | 55 | # List of files/directories to be installed 56 | # NOTE: Do NOT include 'etc' below! 57 | INSTALL_LIST=' 58 | /COPYRIGHT 59 | /bin 60 | /boot 61 | /compat 62 | /lib 63 | /libexec 64 | /rescue 65 | /sbin 66 | /usr/Makefile 67 | /usr/bin 68 | /usr/games 69 | /usr/include 70 | /usr/lib 71 | /usr/libdata 72 | /usr/libexec 73 | /usr/sbin 74 | /usr/share 75 | /var/msgs 76 | /var/yp 77 | ' 78 | 79 | # Ignored files to be kept from overriding by the upgrade. 80 | FILES_IGNORE=' 81 | /boot/loader.conf 82 | /etc/crypttab 83 | /etc/fstab 84 | /etc/group 85 | /etc/localtime 86 | /etc/login.conf.db 87 | /etc/master.passwd 88 | /etc/motd 89 | /etc/passwd 90 | /etc/pwd.db 91 | /etc/rc.conf 92 | /etc/spwd.db 93 | /var/db/locate.database 94 | /var/mail/root 95 | ' 96 | # Filename suffix for newly installed files that need (manual) merge. 97 | NEW_SUF="__new__" 98 | 99 | 100 | # 101 | # Helper Functions 102 | # 103 | 104 | debug() { 105 | # Add "|| true" to work with "set -e" 106 | [ -n "${DEBUG}" ] && echo "DEBUG: $@" >&2 || true 107 | } 108 | 109 | log() { 110 | echo "$@" >&2 111 | } 112 | 113 | warn() { 114 | echo "WARNING: $@" >&2 115 | } 116 | 117 | error() { 118 | local ec="$1" 119 | shift 120 | echo "ERROR: $@" >&2 121 | exit ${ec} 122 | } 123 | 124 | # Get the device mounted at the given directory 125 | get_mount_dev() { 126 | local mntpnt="$1" 127 | local dev=$(df | awk '$NF == "'${mntpnt}'" { print $1 }') 128 | echo "${dev}" 129 | } 130 | 131 | # Mount the specified system image file 132 | # 133 | # mount_image(imgfile, mntpnt) 134 | # 135 | mount_image() { 136 | local imgfile="$1" 137 | local mntpnt="$2" 138 | local dev vn 139 | 140 | dev=$(get_mount_dev ${mntpnt}) 141 | [ -z "${dev}" ] || 142 | error ${EC_MOUNT} "${dev} already mounted at ${mntpnt}" 143 | 144 | [ -d "${mntpnt}" ] || mkdir "${mntpnt}" 145 | vn=$(vnconfig -c vn ${imgfile}) || exit ${EC_VN} 146 | mount -r /dev/${vn}s2a ${mntpnt} || exit ${EC_MOUNT} 147 | } 148 | 149 | # Umount the image and unconfigure the underlying VN device 150 | # 151 | # umount_image(mntpnt) 152 | # 153 | umount_image() { 154 | local mntpnt="$1" 155 | local dev vn 156 | dev=$(get_mount_dev ${mntpnt}) 157 | vn=${dev#/dev/} 158 | umount ${mntpnt} || exit ${EC_UMOUNT} 159 | echo "Unconfigure ${vn} ..." 160 | vnconfig -u "${vn%s??}" || exit ${EC_VN} 161 | } 162 | 163 | # Backup the old kernel 164 | backup_kernel() { 165 | local kerndir="/boot/kernel" 166 | local oldkerndir="${kerndir}.old" 167 | [ -d "${oldkerndir}" ] && { 168 | rm -r ${oldkerndir} 169 | warn "Removed previously backed kernel: ${oldkerndir}" 170 | } 171 | 172 | echo "Backing up current kernel to ${oldkerndir} ..." 173 | mkdir -p ${oldkerndir} 174 | chflags noschg ${kerndir}/kernel 175 | objcopy --strip-debug ${kerndir}/kernel ${oldkerndir}/kernel 176 | for f in ${kerndir}/*.ko; do 177 | objcopy --strip-debug ${f} ${oldkerndir}/${f##*/} 178 | done 179 | 180 | [ -f "${kerndir}/initrd.img" ] && 181 | cp -p ${kerndir}/initrd.img ${oldkerndir} 182 | [ -f "${kerndir}/initrd.img.gz" ] && 183 | cp -p ${kerndir}/initrd.img.gz ${oldkerndir} 184 | echo "DONE" 185 | } 186 | 187 | # Backup the old world 188 | # 189 | # backup_world(backfile) 190 | # 191 | backup_world() { 192 | local backfile="$1" 193 | local backdir=$(dirname "${backfile}") 194 | [ -d "${backdir}" ] || mkdir ${backdir} 195 | [ -f "${backfile}" ] && { 196 | rm -f "${backfile}" 197 | warn "Removed previously backed world: ${backfile}" 198 | } 199 | 200 | echo "Backing up current world to ${backfile} ..." 201 | tar -czf "${backfile}" \ 202 | --options gzip:compression-level=1 \ 203 | -C / \ 204 | etc bin sbin lib libexec \ 205 | usr/bin usr/sbin usr/lib usr/libexec && 206 | echo "DONE" || 207 | exit ${EC_TAR} 208 | } 209 | 210 | # Make the ignore file for cpdup(1) 211 | make_cpignore() { 212 | local cpignore=$(mktemp -t ${NAME}) || exit ${EC_TMPFILE} 213 | local f f2 214 | for f in ${FILES_IGNORE}; do 215 | f2=$(echo "${f}" | sed 's|^/etc/|/etc.hdd/|') 216 | # NOTE: 'cpdup -X' doesn't normalize multiple '/' to be one. 217 | echo "${MNT_DIR%/}/${f2#/}" >> ${cpignore} 218 | done 219 | echo ${cpignore} 220 | } 221 | 222 | # Install the new system (kernel and world, excluding /etc) 223 | install_system() { 224 | local file item path cpignore 225 | 226 | echo " => Creating distribution directories ..." 227 | for item in \ 228 | root:/ \ 229 | var:/var \ 230 | usr:/usr \ 231 | include:/usr/include; do 232 | file=BSD.${item%:*}.dist 233 | path=${item#*:} 234 | echo " * mtree: ${path} ..." 235 | mtree -deiqU -f ${MNT_DIR}/etc.hdd/mtree/${file} -p ${path} || 236 | exit ${EC_MTREE} 237 | done 238 | 239 | echo " => Collecting ignored files for cpdup ..." 240 | cpignore=$(make_cpignore) || exit ${EC_TMPFILE} 241 | 242 | echo " => Installing kernel and world ..." 243 | for item in ${INSTALL_LIST}; do 244 | [ "${item%/}" = "/etc" ] && { 245 | warn "'/etc' is in 'INSTALL_LIST'; force ignored" 246 | continue 247 | } 248 | echo -n " * Installing: ${item} ... " 249 | # NOTE: 'cpdup -X' doesn't normalize multiple '/' to be one. 250 | ${CPDUP} -o -X ${cpignore} ${MNT_DIR%/}/${item#/} /${item} || 251 | exit ${EC_CPDUP} 252 | echo "ok" 253 | done 254 | 255 | rm -f ${cpignore} 256 | echo " => DONE!" 257 | } 258 | 259 | # Add new users and groups 260 | add_users() { 261 | local fpasswd="${MNT_DIR}/etc.hdd/master.passwd" 262 | local fgroup="${MNT_DIR}/etc.hdd/group" 263 | local _name _pw _uid _gid _gids item 264 | local _class _change _expire _gecos _home _shell _members 265 | 266 | echo " => Adding new users ..." 267 | _gids="" 268 | while IFS=':' read -r _name _pw _uid _gid _class \ 269 | _change _expire _gecos _home _shell; do 270 | case ${_name} in 271 | '' | \#*) continue ;; 272 | esac 273 | pw usershow ${_name} -q >/dev/null && continue 274 | 275 | # NOTE: There is circular dependence: 'groupadd' requires the members 276 | # already exist, while 'useradd' requires the group exists. 277 | # So first assign new users to the 'nogroup' group, and make 278 | # adjustments after group creation. 279 | echo " * ${_name}: ${_uid}, ${_gid}, ${_gecos}, ${_home}, ${_shell}" 280 | pw useradd ${_name} \ 281 | -u ${_uid} -g nogroup -d ${_home} -s ${_shell} \ 282 | -L "${_class}" -c "${_gecos}" || exit ${EC_PW} 283 | _gids="${_gids} ${_name}:${_gid}" 284 | done < ${fpasswd} 285 | 286 | echo " => Adding new groups ..." 287 | while IFS=':' read -r _name _pw _gid _members; do 288 | case ${_name} in 289 | '' | \#*) continue ;; 290 | esac 291 | pw groupshow ${_name} -q >/dev/null && continue 292 | 293 | echo " * ${_name}: ${_gid}, ${_members}" 294 | pw groupadd ${_name} -g ${_gid} -M "${_members}" || exit ${EC_PW} 295 | done < ${fgroup} 296 | 297 | echo " => Adjusting the group of new users ..." 298 | for item in ${_gids}; do 299 | _name=${item%:*} 300 | _gid=${item#*:} 301 | echo " * ${_name}: ${_gid}" 302 | pw usermod ${_name} -g ${_gid} || exit ${EC_PW} 303 | done 304 | } 305 | 306 | # Upgrade the system with new configuration files 307 | upgrade_system() { 308 | local etcdir file file_etc file_new cpignore 309 | 310 | [ -d "${CACHE_DIR}" ] || mkdir "${CACHE_DIR}" 311 | etcdir="${CACHE_DIR}/etc.new" 312 | rm -rf "${etcdir}" 313 | 314 | echo " => Collecting ignored files for cpdup ..." 315 | cpignore=$(make_cpignore) || exit ${EC_TMPFILE} 316 | echo " => Coping new /etc to: ${etcdir}" 317 | ${CPDUP} -o -X ${cpignore} ${MNT_DIR%/}/etc.hdd ${etcdir} || 318 | exit ${EC_CPDUP} 319 | rm -f ${cpignore} 320 | 321 | echo " => Identifying new/updated config files ..." 322 | (cd "${etcdir}" && find -s . -type f) | while read -r file; do 323 | file_etc="/etc/${file#./}" 324 | file_new="${etcdir}/${file#./}" 325 | if [ -f "${file_etc}" ]; then 326 | if cmp -s "${file_etc}" "${file_new}"; then 327 | rm -f "${file_new}" 328 | else 329 | mv "${file_new}" "${file_new}.${NEW_SUF}" 330 | echo " * ${file_new} [UPDATED]" 331 | fi 332 | else 333 | echo " * ${file_new} [NEW]" 334 | fi 335 | done 336 | 337 | echo " => Installing new configurations ..." 338 | ${CPDUP} -o ${etcdir} /etc || exit ${EC_CPDUP} 339 | echo " => DONE!" 340 | rm -rf "${etcdir}" 341 | echo "+---------+" 342 | echo "| WARNING | Files with '${NEW_SUF}' suffix need manual merge!" 343 | echo "+---------+" 344 | } 345 | 346 | # Clean up obsolete and deprecated files 347 | cleanup() { 348 | local mk_upgrade tmpfile item itemcat 349 | 350 | mk_upgrade=/etc/upgrade/Makefile_upgrade.inc 351 | [ -e "${mk_upgrade}.${NEW_SUF}" ] && mk_upgrade=${mk_upgrade}.${NEW_SUF} 352 | echo "Removing obsolete and deprecated files ..." 353 | echo "(according to ${mk_upgrade})" 354 | tmpfile=$(mktemp -t ${NAME}) || exit ${EC_TMPFILE} 355 | make -f ${mk_upgrade} -V TO_REMOVE | tr ' ' '\n' > ${tmpfile} 356 | make -f ${mk_upgrade} -V TO_REMOVE_LATE | tr ' ' '\n' >> ${tmpfile} 357 | 358 | # Credit: https://stackoverflow.com/a/10929511 359 | # [ -n "${item}" ]: do not ignore the last line if not end with a '\n' 360 | while IFS='' read -r item || [ -n "${item}" ]; do 361 | if [ -n "${item}" ] && [ -e ${item} -o -L ${item} ]; then 362 | echo " * ${item}" 363 | chflags -Rf noschg ${item} 364 | rm -rf ${item} 365 | fi 366 | if echo "${item}" | grep -q '/man/man[1-9]/'; then 367 | itemcat=$(echo "${item}" | sed 's|/man/man|/man/cat|') 368 | if [ -e "${itemcat}" ]; then 369 | echo " * ${itemcat}" 370 | chflags -Rf noschg ${itemcat} 371 | rm -rf ${itemcat} 372 | fi 373 | fi 374 | done < ${tmpfile} 375 | rm -f ${tmpfile} 376 | echo "DONE" 377 | } 378 | 379 | # Misc operations after upgrade 380 | postupgrade() { 381 | echo "Rebuild capability database ..." 382 | cap_mkdb /etc/login.conf 383 | echo "Rebuild password database ..." 384 | pwd_mkdb -p /etc/master.passwd 385 | echo "Rebuild mail aliases db ..." 386 | newaliases 387 | echo "Rebuild whatis database ..." 388 | makewhatis 389 | echo "Rebuild shared library cache ..." 390 | ldconfig -R 391 | 392 | echo "+=========================================================+" 393 | echo "The following config files need manual merge:" 394 | echo "+---------------------------------------------------------+" 395 | find -s /etc -name "*.${NEW_SUF}" | sort 396 | 397 | cat << _EOF_ 398 | +---------------------------------------------------------+ 399 | After manually merge the above files, reboot into the new 400 | system, and upgrade the packages with: 401 | # pkg update 402 | # pkg upgrade [-f] 403 | +=========================================================+ 404 | _EOF_ 405 | } 406 | 407 | 408 | # 409 | # Main 410 | # 411 | 412 | usage() { 413 | cat <<_EOF_ 414 | Upgrade a DragonFly BSD system using a binary release/snapshot 415 | 416 | Usage: 417 | ${0##*/} [-h] [-c ] [-d] 418 | [-s ] [-S is 0 (the default), 440 | otherwise it is assumed that the image file is already mounted 441 | at \${MNT_DIR} (default to be '${MNT_DIR}'). 442 | 443 | v${VERSION} 444 | ${AUTHOR} 445 | ${URL} 446 | 447 | _EOF_ 448 | } 449 | 450 | 451 | ISTART=0 452 | ISTOP=99 453 | 454 | while getopts :c:dhs:S: opt; do 455 | case ${opt} in 456 | c) 457 | CONFIGFILE="${OPTARG}" 458 | if [ -r "${CONFIGFILE}" ]; then 459 | . ${CONFIGFILE} 460 | else 461 | error ${EC_CONFIG} "cannot read config file: ${CONFIGFILE}" 462 | fi 463 | ;; 464 | d) 465 | DEBUG=yes 466 | ;; 467 | h) 468 | usage 469 | exit ${EC_USAGE} 470 | ;; 471 | s) 472 | ISTART="${OPTARG}" 473 | ;; 474 | S) 475 | ISTOP="${OPTARG}" 476 | ;; 477 | \?) 478 | log "Invalid option -${OPTARG}" 479 | usage 480 | exit ${EC_ARGS} 481 | ;; 482 | :) 483 | log "Option -${OPTARG} requires an argument" 484 | usage 485 | exit ${EC_ARGS} 486 | ;; 487 | esac 488 | done 489 | 490 | shift $((OPTIND - 1)) 491 | 492 | if [ ${ISTART} -eq 0 ]; then 493 | [ $# -eq 1 ] || error ${EC_ARGS} "no image file provided" 494 | IMG="$1" 495 | [ -f "${IMG}" ] || error ${EC_NOFILE} "image file not exists: ${IMG}" 496 | else 497 | DEV=$(get_mount_dev ${MNT_DIR}) 498 | [ -n "${DEV}" ] || error ${EC_MOUNT} "nothing mounted at: ${MNT_DIR}" 499 | fi 500 | 501 | istep=0 502 | echo "[${istep}] Mounting image to ${MNT_DIR} ..." 503 | [ ${istep} -ge ${ISTART} -a ${istep} -le ${ISTOP} ] && 504 | mount_image "${IMG}" "${MNT_DIR}" || 505 | echo "(skipped)" 506 | 507 | istep=$((${istep} + 1)) 508 | echo "[${istep}] Backing up current kernel ..." 509 | [ ${istep} -ge ${ISTART} -a ${istep} -le ${ISTOP} ] && 510 | backup_kernel || 511 | echo "(skipped)" 512 | 513 | istep=$((${istep} + 1)) 514 | echo "[${istep}] Backing up current world ..." 515 | [ ${istep} -ge ${ISTART} -a ${istep} -le ${ISTOP} ] && 516 | backup_world "${BACK_DIR}/world.tar.gz" || 517 | echo "(skipped)" 518 | 519 | istep=$((${istep} + 1)) 520 | echo "[${istep}] Installing new kernel and world ..." 521 | [ ${istep} -ge ${ISTART} -a ${istep} -le ${ISTOP} ] && 522 | install_system || 523 | echo "(skipped)" 524 | 525 | istep=$((${istep} + 1)) 526 | echo "[${istep}] Adding new users and groups ..." 527 | [ ${istep} -ge ${ISTART} -a ${istep} -le ${ISTOP} ] && 528 | add_users || 529 | echo "(skipped)" 530 | 531 | istep=$((${istep} + 1)) 532 | echo "[${istep}] Upgrade system files ..." 533 | [ ${istep} -ge ${ISTART} -a ${istep} -le ${ISTOP} ] && 534 | upgrade_system || 535 | echo "(skipped)" 536 | 537 | istep=$((${istep} + 1)) 538 | echo "[${istep}] Clean up obsolete files ..." 539 | [ ${istep} -ge ${ISTART} -a ${istep} -le ${ISTOP} ] && 540 | cleanup || 541 | echo "(skipped)" 542 | 543 | istep=$((${istep} + 1)) 544 | echo "[${istep}] Umounting image from ${MNT_DIR} ..." 545 | [ ${istep} -ge ${ISTART} -a ${istep} -le ${ISTOP} ] && 546 | umount_image "${MNT_DIR}" || 547 | echo "(skipped)" 548 | 549 | istep=$((${istep} + 1)) 550 | echo "[${istep}] Misc operations after upgrade ..." 551 | [ ${istep} -ge ${ISTART} -a ${istep} -le ${ISTOP} ] && 552 | postupgrade || 553 | echo "(skipped)" 554 | 555 | exit 0 556 | -------------------------------------------------------------------------------- /dfly-update.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Configurations for 'dfly-update' 3 | # 4 | 5 | # Tool name 6 | #NAME=dfly-update 7 | 8 | # Path to the cpdup(1) executable 9 | #CPDUP="/bin/cpdup" 10 | 11 | # Temporary directory to cache the image, etc, ... 12 | #CACHE_DIR="/var/tmp/${NAME}" 13 | 14 | # Directory to mount the system image 15 | #MNT_DIR="/mnt/${NAME}" 16 | 17 | # Backup directory 18 | #BACK_DIR="/var/backups/${NAME}" 19 | 20 | # Ignored files to be kept from overriding by the upgrade. 21 | #FILES_IGNORE=' 22 | # /boot/loader.conf 23 | # /etc/crypttab 24 | # /etc/fstab 25 | # /etc/group 26 | # /etc/localtime 27 | # /etc/login.conf.db 28 | # /etc/master.passwd 29 | # /etc/motd 30 | # /etc/passwd 31 | # /etc/pwd.db 32 | # /etc/rc.conf 33 | # /etc/spwd.db 34 | # /var/db/locate.database 35 | # /var/mail/root 36 | #' 37 | 38 | # Filename suffix for newly installed config files that need (manual) 39 | # merge. 40 | #NEW_SUF="__new__" 41 | --------------------------------------------------------------------------------