All, the following is a script which will migrate a Gentoo system to the usr merge layout. This is similar to the unsymlink-lib tool used to migrate a system from the 17.0 to the 17.1 profiles.
I'm attaching it here to get some comments before I package it, so please let me know if I have missed something. Thanks, William
#!/bin/bb
# shellcheck disable=SC2039 shell=sh
rollback_path=/var/usrmerge-rollback
check_internal_commands() {
for cmd in cp ln; do
[ "$(command -v "${cmd}")" = ${cmd} ] && continue
printf 'busybox does not include the %s command internally\n'
"${cmd}"
return 1
done
return 0
}
check_root() {
[ "$(id -u)" = 0 ] && return 0
printf 'This script must be run by root\n'
return 1
}
run_command() {
local cmd
[ -n "${dryrun}" ] && cmd="echo"
${cmd} "$@" || exit
return 0
}
setup_rollback() {
if [ -e "${rollback_path}" ]; then
printf '%s already exists\n' "${rollback_path}"
printf 'please remove it before continuing\n'
return 1
fi
printf 'Creating %s to allow rollbacks\n' "${rollback_path}"
run_command mkdir "${rollback_path}"
run_command mkdir "${rollback_path}/usr"
local dir
for dir in /bin /lib* /sbin; do
run_command cp -a "${dir}" "${rollback_path}"
done
for dir in /usr/bin /usr/lib* /usr/sbin; do
[ "${dir}" = /usr/libexec ] && continue
run_command cp -a "${dir}" "${rollback_path}/usr"
done
return 0
}
action_finish() {
run_command rm -fr "${rollback_path}"
return 0
}
action_help() {
local cmd
cmd="$(basename "${0}")"
printf 'usage: %s -h\n' "${cmd}"
printf ' %s [-d] -f|-m|-r\n' "${cmd}"
printf '\n'
printf '-h | --help - displays this message\n'
printf '-d | --dry-run - show what would be done\n'
printf '-f | --finish - remove the rollback data\n'
printf '-m | --merge - perform the usr merge\n'
printf '-r | --roll-back - attempt to undo the usr merge\n'
return 0
}
action_merge() {
if [ -L /bin ] || [ -L /sbin ]; then
printf 'The /usr merge has been completed on this system\n'
return 0
fi
local dir
for dir in /lib*; do
[ -L "${dir}" ] || continue
printf '%s is a symbolic link.\n' "${dir}"
printf 'This means you have not migrated to the 17.1 profiles
yet\n'
printf 'please do so before running this script\n'
return 1
done
setup_rollback || return
# copy root directories to /usr counterparts and create
# the /usr merge compatibility symlinks
for dir in /bin /lib* /sbin; do
run_command cp -a -i "${dir}"/* /usr/"${dir}"
run_command rm -rf "${dir}"
run_command ln -snf usr/"${dir}" "${dir}"
done
# merge /usr/sbin into /usr/bin
run_cmd cp -a -i /usr/sbin/* /usr/bin
run_cmd rm -fr /usr/sbin
run_cmd ln -snf bin /usr/sbin
return 0
}
action_rollback() {
if [ ! -d "${rollback_path}" ]; then
printf '%s does not exist, unable to roll back\n'
"${rollback_path}"
return 1
fi
local dir rollback_dir
for dir in /bin /lib* /sbin /usr/bin /usr/lib* /usr/sbin; do
[ "${dir}" = /usr/libexec ] && continue
rollback_dir="${rollback_path}/${dir}"
[ -d "${rollback_dir}" ] && continue
printf 'Unable to perform rollback, %s is missing\n'
"${rollback_dir}"
return 1
done
for dir in /bin /lib* /sbin ; do
rollback_dir="${rollback_path}/${dir}"
run_cmd rm -fr "${dir}"
run_cmd cp -a "${rollback_dir}" /
done
for dir in /usr/bin /usr/lib* /usr/sbin; do
[ "${dir}" = /usr/libexec ] && continue
rollback_dir="${rollback_path}/${dir}"
run_cmd rm -f "${dir}"
run_cmd cp -a "${rollback_dir}" /usr
done
return 0
}
main() {
local dryrun finish merge rollback
while [ $# -gt 0 ]; do
case $1 in
-d|--dry-run)
dryrun=1
;;
-h|--help)
action_help
return 0
;;
-f|--finish)
finish=1
;;
-m|--merge)
merge=1
;;
-r|--roll-back)
rollback=1
;;
esac
shift
done
check_internal_commands || return
check_root || return
if [ "${finish}" = "${merge}" ] && [ "${merge}" = "${rollback}" ]; then
printf 'You must select -f, -m or -r\n'
action_help
return 1
elif [ -n "${finish}" ]; then
action_finish || return
elif [ -n "${merge}" ]; then
action_merge || return
elif [ -n "${rollback}" ]; then
action_rollback || return
fi
return 0
}
main "$@" || exit
exit 0
signature.asc
Description: PGP signature
