Last active
July 9, 2022 21:33
-
-
Save nocnokneo/6ff81783985e28cdbd45 to your computer and use it in GitHub Desktop.
yum-chroot.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
this_script=$(basename $0) | |
print_usage() | |
{ | |
echo <<EOF | |
Usage: ${this_script} create CHROOT_DIR [CENTOS_RELEASE_RPM_URL] | |
${this_script} run CHROOT_DIR [COMMAND ...] | |
${this_script} --help | |
The first form of the command is used if CHROOT_DIR does not already exist or | |
is an empty directory. A new chroot will be created at CHROOT_DIR based upon | |
the centos-release RPM file pointed to by CENTOS_RELEASE_RPM_URL. After the | |
chroot is created, it will be entered using a bash login shell. | |
The second form of the command is used if CHROOT_DIR already exists and is not | |
empty. It will execute COMMAND inside the chroot. The default command is | |
'/bin/bash -l' | |
EOF | |
} | |
die() | |
{ | |
echo "$1" 2>&1 | |
exit 1 | |
} | |
unmount_chroot() | |
{ | |
chroot=$(readlink -e $1) || return 1 | |
[[ ${chroot} == / ]] && return 1 | |
chroot_mounted_dirs=$(awk -v chroot="${chroot}" '$2 ~ chroot {print $2}' /proc/mounts) || return 1 | |
for mount_point in ${chroot_mounted_dirs}; do | |
echo "Unmounting ${mount_point} ..." | |
umount ${mount_point} | |
done | |
} | |
dir_is_empty() | |
{ | |
[[ ! "$(find $1 -maxdepth 0 -empty)" == "" ]] | |
} | |
create_chroot() | |
{ | |
( set -e | |
chroot_dir=$(readlink -m $1) | |
centos_release_rpm=${2} | |
if [[ ${centos_release_rpm} = *.x86_64.rpm ]]; then | |
basearch=x86_64 | |
arch=x86_64 | |
else | |
basearch=i386 | |
arch=i686 | |
fi | |
case "$centos_release_rpm" in | |
*/6*/os/i386/*) | |
basearch=i386 | |
arch=i686 | |
releasever=6 | |
;; | |
*/6*/os/x86_64/*) | |
basearch=x86_64 | |
arch=x86_64 | |
releasever=6 | |
;; | |
*/7*/os/x86_64/*) | |
basearch=x86_64 | |
arch=x86_64 | |
releasever=7 | |
;; | |
*) | |
cat 1>&2 <<EOF | |
Unsupported RHEL release. Supported versions are: | |
* 6/i386 | |
* 6/x86_64 | |
* 7/x86_64 | |
EOF | |
return 1 | |
;; | |
esac | |
mkdir -p ${chroot_dir} | |
if ! dir_is_empty ${chroot_dir}; then | |
echo "${chroot_dir} is not empty." | |
read -p "Proceed anyway? [yN] " proceed | |
[[ $proceed = [yY] ]] || return 1 | |
fi | |
rpm --root=${chroot_dir} --install --nodeps ${centos_release_rpm} | |
mkdir -p ${chroot_dir}/etc/yum/vars | |
echo ${releasever} > ${chroot_dir}/etc/yum/vars/releasever | |
echo ${arch} > ${chroot_dir}/etc/yum/vars/arch | |
echo ${basearch} > ${chroot_dir}/etc/yum/vars/basearch | |
yum --installroot=${chroot_dir} --assumeyes --nogpgcheck install yum | |
chroot ${chroot_dir} rpm --rebuilddb | |
) | |
} | |
run_chroot() | |
{ | |
( set -e | |
chroot_dir=$(readlink -e $1) | |
shift | |
chroot_command="$@" | |
if [ -z ${chroot_command} ]; then | |
chroot_command="/bin/bash -l" | |
fi | |
echo "Setting up chroot and launching: ${chroot_command}" | |
trap "unmount_chroot \"${chroot_dir}\"" EXIT | |
# List of required bind mounts in order of dependency. | |
bind_mount_points="/proc /dev" | |
for mount_point in ${bind_mount_points}; do | |
if [ -d ${mount_point} ] && ! mount | grep -q " on ${chroot_dir}${mount_point} "; then | |
echo "Mounting ${chroot_dir}${mount_point} ..." | |
mkdir -p ${chroot_dir}${mount_point} | |
mount --bind ${mount_point} ${chroot_dir}${mount_point} | |
fi | |
done | |
cp -p /etc/resolv.conf ${chroot_dir}/etc/ | |
touch ${chroot_dir}/root/.Xauthority | |
# TODO: The following is used in lieu of bind-mounting /tmp /run and /dev/pts | |
xauth extract - $DISPLAY | xauth -f ${chroot_dir}/root/.Xauthority merge - | |
chroot ${chroot_dir} env XAUTHORITY=/root/.Xauthority ${chroot_command} | |
echo "Exited chroot." | |
) | |
} | |
case "$1" in | |
create) | |
echo "Installing new chroot ..." | |
release_url="$3" | |
# Allow interactive selection if no URL provided | |
if [ -z "${release_url}" ]; then | |
url_choices='http://mirror.centos.org/centos/6/os/i386/Packages/centos-release-6-5.el6.centos.11.1.i686.rpm | |
http://mirror.centos.org/centos/6/os/x86_64/Packages/centos-release-6-5.el6.centos.11.1.x86_64.rpm | |
http://mirror.centos.org/centos/7/os/x86_64/Packages/centos-release-7-0.1406.el7.centos.2.3.x86_64.rpm' | |
echo -e "Select RPM URL to initialize chroot:\n" | |
echo "$url_choices" | awk '{ print " [", NR, "]", $0 }' | |
read -p "Selection: " choice | |
release_url=$(echo "${url_choices}" | sed -n "${choice} p") | |
fi | |
create_chroot ${2} ${release_url} || die "Failed to create chroot" | |
cat <<EOF | |
============================================================================== | |
New chroot created successfully. You can launch a bash session inside the | |
chroot with: | |
sudo ${this_script} run | |
You may wish to install the util-linux package in order to have a more | |
complete environment for interactive use. | |
============================================================================== | |
EOF | |
;; | |
run) | |
shift | |
run_chroot "$@" || dia "Failed to launch chroot" | |
;; | |
-h|--help) | |
print_usage | |
exit 0 | |
;; | |
'') | |
print_usage | |
exit 1 | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment