public inbox for gentoo-dev@lists.gentoo.org
 help / color / mirror / Atom feed
From: William Hubbs <williamh@gentoo.org>
To: gentoo development <gentoo-dev@lists.gentoo.org>
Cc: sam@gentoo.org, soap@gentoo.org
Subject: [gentoo-dev] rfc: usrmerge script
Date: Sun, 21 Mar 2021 12:39:43 -0500	[thread overview]
Message-ID: <YFeE39Zn4WWC9Mtv@linux1.home> (raw)


[-- 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 --]

             reply	other threads:[~2021-03-21 17:39 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-21 17:39 William Hubbs [this message]
2021-03-21 18:00 ` [gentoo-dev] rfc: usrmerge script 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YFeE39Zn4WWC9Mtv@linux1.home \
    --to=williamh@gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    --cc=sam@gentoo.org \
    --cc=soap@gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox