diff --git a/conty-start.sh b/conty-start.sh index 8ad1b51..523876f 100755 --- a/conty-start.sh +++ b/conty-start.sh @@ -19,8 +19,8 @@ script_version="1.23" # Important variables to manually adjust after modification! # Needed to avoid problems with mounting due to an incorrect offset. -script_size=29108 -utils_size=2520686 +script_size=33659 +utils_size=2564623 # Full path to the script script_literal="${BASH_SOURCE[0]}" @@ -114,6 +114,12 @@ Environment variables: isolates X11 server with Xephyr. The default is 1. + NVIDIA_HANDLER Fixes issues with graphical applications on Nvidia + GPUs with the proprietary driver. Enable this only + if you are using an Nvidia GPU, the proprietary + driver and encountering issues running graphical + applications. Fuse3 is required for this to work. + USE_SYS_UTILS Tells the script to use squashfuse/dwarfs and bwrap installed on the system instead of the builtin ones. @@ -166,6 +172,9 @@ fi mount_point="${working_dir}"/mnt +export overlayfs_dir="${HOME}"/.local/share/Conty/overlayfs +export nvidia_drivers_dir="${HOME}"/.local/share/Conty/nvidia + # Offset where the image is stored offset=$((script_size+utils_size)) @@ -284,6 +293,90 @@ gui () { fi } +mount_overlayfs () { + if [ "${script_md5}" != "$(cat "${overlayfs_dir}"/current-image-version 2>/dev/null)" ]; then + rm -rf "${overlayfs_dir}"/up "${overlayfs_dir}"/work \ + "${nvidia_drivers_dir}"/current-nvidia-version + fi + + mkdir -p "${overlayfs_dir}"/up + mkdir -p "${overlayfs_dir}"/work + mkdir -p "${overlayfs_dir}"/merged + + echo "${script_md5}" > "${overlayfs_dir}"/current-image-version + + if [ ! "$(ls "${overlayfs_dir}"/merged 2>/dev/null)" ]; then + if command -v "${fuse_overlayfs}" 1>/dev/null; then + if command -v fusermount3 1>/dev/null; then + "${fuse_overlayfs}" -o squash_to_uid="$(id -u)" -o squash_to_gid="$(id -g)" -o lowerdir="${mount_point}",upperdir="${overlayfs_dir}"/up,workdir="${overlayfs_dir}"/work "${overlayfs_dir}"/merged + else + echo "Fuse3 is required for fuse-overlayfs" + fi + else + echo "fuse-overlayfs not found" + fi + fi +} + +nvidia_driver_handler () { + if lsmod | grep nvidia 1>/dev/null || nvidia-smi 1>/dev/null; then + if [ "$(ls /tmp/hostlibs/x86_64-linux-gnu/libGLX_nvidia.so.* 2>/dev/null)" ]; then + nvidia_driver_version="$(basename /tmp/hostlibs/x86_64-linux-gnu/libGLX_nvidia.so.*.* | tail -c +18)" + elif [ "$(ls /tmp/hostlibs/libGLX_nvidia.so.* 2>/dev/null)" ]; then + nvidia_driver_version="$(basename /tmp/hostlibs/libGLX_nvidia.so.*.* | tail -c +18)" + elif nvidia-smi 1>/dev/null; then + nvidia_driver_version="$(nvidia-smi --query-gpu=driver_version --format=csv,noheader)" + elif modinfo nvidia &>/dev/null; then + nvidia_driver_version="$(modinfo -F version nvidia 2>/dev/null)" + fi + else + echo "Seems like your system has no Nvidia driver loaded" + exit 1 + fi + + if [ "$(cat "${nvidia_drivers_dir}"/current-nvidia-version 2>/dev/null)" = "${nvidia_driver_version}" ]; then + exit + fi + + if [ -z "${nvidia_driver_version}" ]; then + echo "Unable to determine the Nvidia driver version" + exit 1 + fi + + OLD_PWD="${PWD}" + + mkdir -p "${nvidia_drivers_dir}" + cd "${nvidia_drivers_dir}" + + echo "Found Nvidia driver ${nvidia_driver_version}" + echo "Downloading the Nvidia driver ${nvidia_driver_version}, please wait..." + + # Try to download the driver from the default Nvidia URL + driver_url="https://us.download.nvidia.com/XFree86/Linux-x86_64/${nvidia_driver_version}/NVIDIA-Linux-x86_64-${nvidia_driver_version}.run" + curl -#Lo nvidia.run "${driver_url}" + + # If the previous download failed, get the URL from FlatHub repo + if [ ! -s nvidia.run ]; then + rm -f nvidia.run + driver_url="https:$(curl -#Lo - "https://raw.githubusercontent.com/flathub/org.freedesktop.Platform.GL.nvidia/master/data/nvidia-${nvidia_driver_version}-i386.data" | cut -d ':' -f 6)" + curl -#Lo nvidia.run "${driver_url}" + fi + + if [ -s nvidia.run ]; then + echo "Installing the Nvidia driver, please wait..." + chmod +x nvidia.run + ./nvidia.run --target nvidia-driver -x &>/dev/null + cd nvidia-driver || exit 1 + fakeroot ./nvidia-installer --silent --no-x-check --no-kernel-module &>/dev/null + cd "${nvidia_drivers_dir}" + echo "${nvidia_driver_version}" > current-nvidia-version + rm -rf nvidia.run nvidia-driver + echo "The driver has been installed" + fi + + cd "${OLD_PWD}" +} + # Check if FUSE is installed if ! command -v fusermount3 1>/dev/null && ! command -v fusermount 1>/dev/null; then echo "Please install fuse2 or fuse3 and run the script again." @@ -357,6 +450,7 @@ if [ "${USE_SYS_UTILS}" != 1 ]; then fi bwrap="${working_dir}"/utils/bwrap + fuse_overlayfs="${working_dir}"/utils/fuse-overlayfs if [ ! -f "${mount_tool}" ] || [ ! -f "${bwrap}" ]; then tail -c +$((script_size+1)) "${script}" | head -c "${utils_size}" | tar -C "${working_dir}" -zxf - @@ -369,9 +463,10 @@ if [ "${USE_SYS_UTILS}" != 1 ]; then exit 1 fi - chmod +x "${mount_tool}" - chmod +x "${bwrap}" + chmod +x "${mount_tool}" 2>/dev/null + chmod +x "${bwrap}" 2>/dev/null chmod +x "${extraction_tool}" 2>/dev/null + chmod +x "${fuse_overlayfs}" 2>/dev/null fi else if ! command -v bwrap 1>/dev/null; then @@ -382,6 +477,7 @@ else fi bwrap=bwrap + fuse_overlayfs=fuse-overlayfs if [ "${dwarfs_image}" = 1 ]; then if ! command -v dwarfs 1>/dev/null && ! command -v dwarfs2 1>/dev/null; then @@ -774,10 +870,16 @@ run_bwrap () { mount_opt=(--bind-try /opt /opt) fi + if [ "${NVIDIA_HANDLER}" = 1 ] && [ "$(ls "${overlayfs_dir}"/merged 2>/dev/null)" ]; then + newroot_path="${overlayfs_dir}"/merged + else + newroot_path="${mount_point}" + fi + show_msg launch_wrapper "${bwrap}" \ - --ro-bind "${mount_point}" / \ + --bind "${newroot_path}" / \ --dev-bind /dev /dev \ --ro-bind /sys /sys \ --bind-try /tmp /tmp \ @@ -809,6 +911,11 @@ run_bwrap () { trap_exit () { rm -f "${working_dir}"/running_"${script_id}" + if [ -d "${overlayfs_dir}"/merged ]; then + fusermount"${fuse_version}" -uz "${overlayfs_dir}"/merged 2>/dev/null || \ + umount --lazy "${overlayfs_dir}"/merged 2>/dev/null + fi + if [ ! "$(ls "${working_dir}"/running_* 2>/dev/null)" ]; then fusermount"${fuse_version}" -uz "${mount_point}" 2>/dev/null || \ umount --lazy "${mount_point}" 2>/dev/null @@ -926,6 +1033,19 @@ if [ "$(ls "${mount_point}" 2>/dev/null)" ] || \ exit fi + if [ "${NVIDIA_HANDLER}" = 1 ]; then + show_msg "Nvidia driver handler is enabled" + + mount_overlayfs + mkdir -p "${nvidia_drivers_dir}" + export -f nvidia_driver_handler + run_bwrap --tmpfs /tmp --tmpfs /var --tmpfs /run \ + --bind-try /usr/lib /tmp/hostlibs \ + --bind-try /usr/lib64 /tmp/hostlibs \ + --bind-try "${nvidia_drivers_dir}" "${nvidia_drivers_dir}" \ + bash -c nvidia_driver_handler + fi + # If SANDBOX_LEVEL is 3, run Xephyr and openbox before running applications if [ "${SANDBOX}" = 1 ] && [ -n "${SANDBOX_LEVEL}" ] && [ "${SANDBOX_LEVEL}" -ge 3 ]; then if [ -f "${mount_point}"/usr/bin/Xephyr ]; then diff --git a/create-utils.sh b/create-utils.sh index a89e9e3..f29aa49 100755 --- a/create-utils.sh +++ b/create-utils.sh @@ -12,13 +12,14 @@ script_dir="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" # Set to true to compile dwarfs instead of squashfuse -build_dwarfs="true" +build_dwarfs="false" squashfuse_version="0.1.105" bwrap_version="0.8.0" lz4_version="1.9.4" zstd_version="1.5.5" squashfs_tools_version="4.6.1" +fuse_overlayfs_version="1.12" export CC=gcc export CXX=g++ @@ -33,10 +34,12 @@ cd "${script_dir}"/build-utils || exit 1 curl -#Lo lz4.tar.gz https://github.com/lz4/lz4/archive/refs/tags/v${lz4_version}.tar.gz curl -#Lo zstd.tar.gz https://github.com/facebook/zstd/archive/refs/tags/v${zstd_version}.tar.gz curl -#Lo bwrap.tar.gz https://github.com/containers/bubblewrap/archive/refs/tags/v${bwrap_version}.tar.gz +curl -#Lo fuse-overlayfs.tar.gz https://github.com/containers/fuse-overlayfs/archive/refs/tags/v${fuse_overlayfs_version}.tar.gz tar xf lz4.tar.gz tar xf zstd.tar.gz tar xf bwrap.tar.gz +tar xf fuse-overlayfs.tar.gz if [ "${build_dwarfs}" != "true" ]; then curl -#Lo squashfuse.tar.gz https://github.com/vasi/squashfuse/archive/refs/tags/${squashfuse_version}.tar.gz @@ -51,6 +54,11 @@ cd bubblewrap-"${bwrap_version}" || exit 1 ./configure --disable-selinux --disable-man make -j"$(nproc)" DESTDIR="${script_dir}"/build-utils/bin install +cd ../fuse-overlayfs-"${fuse_overlayfs_version}" || exit 1 +./autogen.sh +./configure +make -j"$(nproc)" DESTDIR="${script_dir}"/build-utils/bin install + cd ../lz4-"${lz4_version}" || exit 1 make -j"$(nproc)" DESTDIR="${script_dir}"/build-utils/bin install @@ -76,6 +84,7 @@ mv bin/usr/local/bin/squashfuse utils mv bin/usr/local/bin/squashfuse_ll utils mv bin/usr/local/bin/mksquashfs utils mv bin/usr/local/bin/unsquashfs utils +mv bin/usr/local/bin/fuse-overlayfs utils mv bin/usr/local/lib/liblz4.so."${lz4_version}" utils/liblz4.so.1 mv bin/usr/local/lib/libzstd.so."${zstd_version}" utils/libzstd.so.1 mv bin/usr/local/lib/libfuseprivate.so.0.0.0 utils/libfuseprivate.so.0 @@ -130,6 +139,7 @@ find utils -type f -exec strip --strip-unneeded {} \; 2>/dev/null cat < utils/info bubblewrap ${bwrap_version} +fuse-overlayfs ${fuse_overlayfs_version} lz4 ${lz4_version} zstd ${zstd_version} EOF diff --git a/utils.tar.gz b/utils.tar.gz index f2b018e..d268e33 100644 --- a/utils.tar.gz +++ b/utils.tar.gz @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6637ac7ef4a0e36e90349b5ce701c334abe284f4425024ea67cbf55761f617f3 -size 2520686 +oid sha256:20b855587b07fa71c8be8e73220495fcee7c9ec290914e982b76fd184fa67094 +size 2564623 diff --git a/utils_dwarfs.tar.gz b/utils_dwarfs.tar.gz index 4de9e8c..3c35cef 100644 --- a/utils_dwarfs.tar.gz +++ b/utils_dwarfs.tar.gz @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5b160ecd08ffb0b4c6340799c882fb3f017524383b323582e6e8bd7e76fbf9cc -size 9387864 +oid sha256:ef56bd72810c1c05a6f4cd77e816b2741ab014b421c00eb0337602c5a11d0959 +size 9431944