public inbox for gentoo-dev@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-dev] rfc: usrmerge script
@ 2021-03-21 17:39 William Hubbs
  2021-03-21 18:00 ` Matthias Maier
  2021-03-23  9:23 ` Michał Górny
  0 siblings, 2 replies; 11+ messages in thread
From: William Hubbs @ 2021-03-21 17:39 UTC (permalink / raw
  To: gentoo development; +Cc: sam, soap


[-- Attachment #1.1: Type: text/plain, Size: 330 bytes --]

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


[-- Attachment #1.2: usrmerge --]
[-- Type: text/plain, Size: 3885 bytes --]

#!/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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-03-24 18:37 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-03-21 17:39 [gentoo-dev] rfc: usrmerge script William Hubbs
2021-03-21 18:00 ` Matthias Maier
2021-03-21 19:08   ` Luigi Mantellini
2021-03-21 19:27     ` William Hubbs
2021-03-21 19:22   ` William Hubbs
2021-03-23  9:23 ` Michał Górny
2021-03-24  5:20   ` William Hubbs
2021-03-24  7:48     ` Michał Górny
2021-03-24 15:09       ` William Hubbs
2021-03-24 17:09         ` Rich Freeman
2021-03-24 18:37           ` William Hubbs

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox