205 lines
4.9 KiB
Bash
Executable file
205 lines
4.9 KiB
Bash
Executable file
#!/bin/bash
|
|
#
|
|
# Pachwrap -- chroot initialisation utility
|
|
#
|
|
# Copyright (C) 2023 Xavier R.M.
|
|
# sapphirus(at)azorium(dot)net
|
|
#
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, with only version 3 of the License.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
MACHINE_ID=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 32 | head -n 1)
|
|
EXEC_NAME="pachwrap-create"
|
|
EXEC_SCRIPT="pachwrap-exec"
|
|
|
|
main () {
|
|
|
|
parse_args "$@"
|
|
|
|
if [[ $SWITCH == *v* ]]; then
|
|
VER_DISPLAY=$EXEC_NAME chpak -v
|
|
exit
|
|
fi
|
|
|
|
if [[ ! $SANDBOX ]]; then
|
|
echo $EXEC_NAME": Sandbox not specified."
|
|
exit 1
|
|
fi
|
|
|
|
init_vars
|
|
|
|
if [[ -d $INSTANCE_ROOT ]] || [[ -d $INSTANCE_HOME ]]; then
|
|
echo $EXEC_NAME": Root or home directory for $SANDBOX exists. Aborting."
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -d $BASE_ROOT ]] && [[ ! $DEPEND ]]; then
|
|
echo $EXEC_NAME": Directory not found for $DEPEND root dependency."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Pre-initialising structures.."
|
|
|
|
init_struct
|
|
|
|
if [[ ! -d $INSTANCE_ROOT ]] || [[ ! -d $INSTANCE_HOME ]]; then
|
|
echo "Directory creation failed."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Initialising chroot.."
|
|
|
|
init_chroot
|
|
|
|
echo "Cleaning up.."
|
|
|
|
cleanup
|
|
|
|
echo "Finalising chroot.."
|
|
|
|
finalise
|
|
|
|
echo "Process complete! Use pacshrap to configure $SANDBOX."
|
|
}
|
|
|
|
parse_args () {
|
|
ArGS=()
|
|
for var in "$@"; do
|
|
case $var in
|
|
--dep=*)
|
|
DEPEND=$(echo $var | cut -c 7-)
|
|
;;
|
|
--is-dep)
|
|
SWITCH=d$SWITCH
|
|
;;
|
|
--is-root)
|
|
SWITCH=r$SWITCH
|
|
;;
|
|
-C*)
|
|
SWITCH=$(echo $var | cut -c 3-)$SWITCH
|
|
;;
|
|
-*)
|
|
SWITCH=$(echo $var | cut -c 2-)$SWITCH
|
|
;;
|
|
*)
|
|
SANDBOX=$var
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
init_vars () {
|
|
PACMAN_CONFIG=pacman.install.conf
|
|
PARAMS="$SANDBOX --root --exec"
|
|
INSTANCE_ROOT=$SANDBOX_BASE/fs/root/$SANDBOX
|
|
INSTANCE_HOME=$SANDBOX_BASE/fs/home/$SANDBOX
|
|
INSTANCE_DEP_LIST=$SANDBOX_BASE/etc/deps/$SANDBOX
|
|
|
|
if [[ $SWITCH == *d* ]]; then
|
|
ISDEP=1
|
|
fi
|
|
if [[ $SWITCH == *r* ]]; then
|
|
ISROOTDEP=1
|
|
PACMAN_CONFIG=pacman.conf
|
|
fi
|
|
|
|
BASE_ROOT=$SANDBOX_BASE/fs/root/$DEPEND
|
|
if [[ ! $DEPEND ]] && [[ ! $ISROOTDEP ]]; then
|
|
echo "Root dependency not specified."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
|
|
init_struct () {
|
|
mkdir -p $INSTANCE_ROOT $INSTANCE_HOME \
|
|
$INSTANCE_ROOT/etc \
|
|
$INSTANCE_ROOT/var/lib/pacman \
|
|
$INSTANCE_ROOT/etc/pacman.d/ \
|
|
$INSTANCE_ROOT/etc/fonts/conf.d
|
|
|
|
cp $SANDBOX_BASE/etc/pacman.conf $INSTANCE_ROOT/etc/pacman.conf
|
|
cp $SANDBOX_BASE/etc/pacman.conf $SANDBOX_BASE/etc/pacman.d/pacman.$SANDBOX.conf
|
|
cp $SANDBOX_BASE/etc/pacman.install.conf $INSTANCE_ROOT/etc/pacman.install.conf
|
|
|
|
cp /etc/pacman.d/mirrorlist $INSTANCE_ROOT/etc/pacman.d/mirrorlist
|
|
echo "en_CA.UTF-8 UTF-8" > $INSTANCE_ROOT/etc/locale.gen
|
|
echo "LANG=en_CA.UTF-8" > $INSTANCE_ROOT/etc/locale.conf
|
|
echo "user:x:1000:1000::/home/user:/bin/bash" >> $INSTANCE_ROOT/etc/passwd
|
|
echo "$MACHINE_ID" > $INSTANCE_ROOT/etc/machine-id
|
|
echo 'PS1="'$SANDBOX'> "' > $INSTANCE_HOME/.bashrc
|
|
|
|
if [[ ! $ISROOTDEP ]]; then
|
|
if [[ -f $SANDBOX_BASE/etc/deps/$DEPEND ]]; then
|
|
echo "$(cat $SANDBOX_BASE/etc/deps/$DEPEND 2>/dev/null)" > $INSTANCE_DEP_LIST
|
|
echo "$DEPEND" >> $INSTANCE_DEP_LIST
|
|
else
|
|
echo "$DEPEND" > $INSTANCE_DEP_LIST
|
|
fi
|
|
else
|
|
touch $INSTANCE_ROOT/.root
|
|
fi
|
|
|
|
if [[ $ISDEP ]]; then
|
|
cp $SANDBOX_BASE/etc/pacman.tpl.conf $SANDBOX_BASE/etc/pacman.d/tpl/pacman.$SANDBOX.conf
|
|
mkdir -p $SANDBOX_BASE/etc/db/$SANDBOX
|
|
touch $INSTANCE_ROOT/.dep
|
|
fi
|
|
|
|
}
|
|
|
|
init_chroot () {
|
|
fakechroot fakeroot pacman -Syu \
|
|
--root $INSTANCE_ROOT \
|
|
--dbpath $INSTANCE_ROOT/var/lib/pacman \
|
|
--config $INSTANCE_ROOT/etc/$PACMAN_CONFIG \
|
|
--cache /var/lib/cache/pacman/pkg \
|
|
base lib32-glibc --noconfirm 2>/dev/null
|
|
sbupdate -fbns
|
|
}
|
|
|
|
finalise () {
|
|
$EXEC_SCRIPT $PARAMS pacman-key --init
|
|
$EXEC_SCRIPT $PARAMS pacman-key --populate
|
|
$EXEC_SCRIPT $PARAMS locale-gen
|
|
$EXEC_SCRIPT $PARAMS update-ca-trust
|
|
if [[ ! $ISROOTDEP ]]; then
|
|
if [[ $DEPEND ]]; then
|
|
local deps=$(cat $INSTANCE_DEP_LIST 2>/dev/null)
|
|
local dbsyncpkgs=
|
|
|
|
for dep in $deps; do
|
|
dbsyncpkgs=$dbsyncpkgs$($EXEC_SCRIPT $dep --root --exec pacman -Qqe | sed -z -E "s/\<base\>|\<lib32-glibc\>//g")
|
|
done
|
|
if [[ $dbsyncpkgs ]]; then
|
|
$EXEC_SCRIPT $PARAMS pacman -Su --dbonly --noconfirm $dbsyncpkgs 2>/dev/null
|
|
fi
|
|
fi
|
|
sbupdate -gb $SANDBOX
|
|
fi
|
|
}
|
|
|
|
cleanup () {
|
|
rm -v -r \
|
|
$INSTANCE_ROOT/boot \
|
|
$INSTANCE_ROOT/mnt \
|
|
$INSTANCE_ROOT/root \
|
|
$INSTANCE_ROOT/srv \
|
|
$INSTANCE_ROOT/sys \
|
|
$INSTANCE_ROOT/opt \
|
|
$INSTANCE_ROOT/run \
|
|
$INSTANCE_ROOT/dev \
|
|
$INSTANCE_ROOT/etc/pacman.install.conf
|
|
}
|
|
|
|
main $@
|