From 27f92d0b3f781ae63e21843104abd9ac2ff0ffec Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Fri, 25 Oct 2019 20:46:27 +0200 Subject: [PATCH 001/116] Add rw permission to files in image --- lib/core/build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/core/build.sh b/lib/core/build.sh index 40c2181..1406ed7 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -80,6 +80,9 @@ function build_image_env(){ "pacman-key --init; pacman-key --populate archlinux; [ -e /etc/pacman.d/gnupg/S.gpg-agent ] && gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye" sudo rm ${maindir}/root/var/cache/pacman/pkg/* + # This is needed on system with busybox tar command. + # If the file does not have write permission, the tar command to extract files fails. + sudo chmod -R u+rw ${maindir}/root/etc/ca-certificates/extracted/cadir mkdir -p ${maindir}/output builtin cd ${maindir}/output From c5847b85836c30a5c3414af4767c4106ff737d85 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Fri, 25 Oct 2019 20:46:38 +0200 Subject: [PATCH 002/116] 7.0.1 --- VERSION | 2 +- lib/core/build.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 66ce77b..9fe9ff9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.0 +7.0.1 diff --git a/lib/core/build.sh b/lib/core/build.sh index 1406ed7..faf7f08 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -82,7 +82,7 @@ function build_image_env(){ sudo rm ${maindir}/root/var/cache/pacman/pkg/* # This is needed on system with busybox tar command. # If the file does not have write permission, the tar command to extract files fails. - sudo chmod -R u+rw ${maindir}/root/etc/ca-certificates/extracted/cadir + sudo chmod -R u+rw ${maindir}/root/ mkdir -p ${maindir}/output builtin cd ${maindir}/output From e0dd3257a8b2c5cbc719b074efbcdf482de64b43 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 15 Dec 2019 11:55:27 +0000 Subject: [PATCH 003/116] Add support for ARM arch during build and check --- .travis.yml | 8 +++++--- lib/checks/check.sh | 5 +++-- lib/core/build.sh | 17 ++++++++++++++--- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index dceb835..13c3d4a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,8 @@ script: - sudo -E ${PWD}/bin/junest groot -- ${PWD}/lib/checks/check.sh --run-root-tests - yes | junest setup --delete - # Disable arm because it fails when exiting from check.sh for apparent no reason - #- JUNEST_HOME=~/.junest-arm junest proot -f -- ./lib/checks/check.sh --skip-aur-tests - #- yes | JUNEST_HOME=~/.junest-arm junest setup --delete + - JUNEST_HOME=~/.junest-arm junest proot --fakeroot -- ${PWD}/lib/checks/check.sh + - JUNEST_HOME=~/.junest-arm junest ns -- ${PWD}/lib/checks/check.sh + # Do not run root test because iftop does not work well in arm + - JUNEST_HOME=~/.junest-arm sudo -E ${PWD}/bin/junest groot -- ${PWD}/lib/checks/check.sh + - yes | JUNEST_HOME=~/.junest-arm junest setup --delete diff --git a/lib/checks/check.sh b/lib/checks/check.sh index 9ee7505..55acd1b 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -64,7 +64,7 @@ pacman --noconfirm -Rsn ${repo_package1} repo_package2=iftop info "Checking ${repo_package2} package from official repo..." pacman --noconfirm -S ${repo_package2} -$RUN_ROOT_TESTS && iftop -t -s 5 +$RUN_ROOT_TESTS && iftop -t -s 5 -i lo pacman --noconfirm -Rsn ${repo_package2} if ! $SKIP_AUR_TESTS @@ -74,7 +74,8 @@ then maindir=$(mktemp -d -t ${CMD}.XXXXXXXXXX) builtin cd ${maindir} curl -L -J -O -k "https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=${aur_package}" - /opt/makepkg/bin/makepkg -sfc --noconfirm + # -A allows to ignore arch for ARM + /opt/makepkg/bin/makepkg -Asfc --noconfirm pacman --noconfirm -U ${aur_package}*.pkg.tar.xz pacman --noconfirm -Rsn ${aur_package} diff --git a/lib/core/build.sh b/lib/core/build.sh index faf7f08..898551a 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -55,7 +55,9 @@ function build_image_env(){ # The archlinux-keyring and libunistring are due to missing dependencies declaration in ARM archlinux # All the essential executables (ln, mkdir, chown, etc) are in coreutils # unshare command belongs to util-linux - sudo pacstrap -G -M -d ${maindir}/root pacman coreutils libunistring archlinux-keyring util-linux + local arm_keyring="" + [[ $(uname -m) == *"arm"* ]] && arm_keyring="archlinuxarm-keyring" + sudo pacstrap -G -M -d ${maindir}/root pacman coreutils libunistring archlinux-keyring $arm_keyring util-linux sudo bash -c "echo 'Server = $DEFAULT_MIRROR' >> ${maindir}/root/etc/pacman.d/mirrorlist" sudo mkdir -p ${maindir}/root/run/lock @@ -76,8 +78,17 @@ function build_image_env(){ sudo pacman --noconfirm --root ${maindir}/root -Rsn sed gzip info "Setting up the pacman keyring (this might take a while!)..." - sudo ${maindir}/root/opt/junest/bin/groot -b /dev ${maindir}/root bash -c \ - "pacman-key --init; pacman-key --populate archlinux; [ -e /etc/pacman.d/gnupg/S.gpg-agent ] && gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye" + # gawk command is required for pacman-key + sudo pacman --noconfirm --root ${maindir}/root -S gawk + sudo ${maindir}/root/opt/junest/bin/groot -b /dev ${maindir}/root bash -c ' + pacman-key --init; + for keyring_file in /usr/share/pacman/keyrings/*.gpg; + do + keyring=$(basename $keyring_file | cut -f 1 -d "."); + pacman-key --populate $keyring; + done; + [ -e /etc/pacman.d/gnupg/S.gpg-agent ] && gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye' + sudo pacman --noconfirm --root ${maindir}/root -Rsn gawk sudo rm ${maindir}/root/var/cache/pacman/pkg/* # This is needed on system with busybox tar command. From 11a439499bfacc85e5b006f41d37237d29be06bc Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 15 Dec 2019 13:05:14 +0000 Subject: [PATCH 004/116] Remove interface lo when checking iftop --- .travis.yml | 3 --- lib/checks/check.sh | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 13c3d4a..38470dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,4 @@ script: - yes | junest setup --delete - JUNEST_HOME=~/.junest-arm junest proot --fakeroot -- ${PWD}/lib/checks/check.sh - - JUNEST_HOME=~/.junest-arm junest ns -- ${PWD}/lib/checks/check.sh - # Do not run root test because iftop does not work well in arm - - JUNEST_HOME=~/.junest-arm sudo -E ${PWD}/bin/junest groot -- ${PWD}/lib/checks/check.sh - yes | JUNEST_HOME=~/.junest-arm junest setup --delete diff --git a/lib/checks/check.sh b/lib/checks/check.sh index 55acd1b..fb60ff0 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -64,7 +64,7 @@ pacman --noconfirm -Rsn ${repo_package1} repo_package2=iftop info "Checking ${repo_package2} package from official repo..." pacman --noconfirm -S ${repo_package2} -$RUN_ROOT_TESTS && iftop -t -s 5 -i lo +$RUN_ROOT_TESTS && iftop -t -s 5 pacman --noconfirm -Rsn ${repo_package2} if ! $SKIP_AUR_TESTS From 538e87f036e56d46f5ccda756071aa3c3d090ea9 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Fri, 21 Feb 2020 23:05:46 +0100 Subject: [PATCH 005/116] Add FUNDING file --- .github/FUNDING.yml | 2 ++ README.md | 8 +++++++- VERSION | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..8efae1f --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: fsquillace +custom: https://github.com/fsquillace/junest/blob/master/README.md#donating diff --git a/README.md b/README.md index 856a9a8..3f96180 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ The lightweight Arch Linux based distro that runs upon any Linux distros without |Project Status|Donation|Communication| |:------------:|:------:|:-----------:| -| [![Build status](https://api.travis-ci.org/fsquillace/junest.png?branch=master)](https://travis-ci.org/fsquillace/junest) [![OpenHub](https://www.openhub.net/p/junest/widgets/project_thin_badge.gif)](https://www.openhub.net/p/junest) | [![PayPal](https://img.shields.io/badge/PayPal-Donate%20a%20beer-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8LEHQKBCYTACY) | [![Join the gitter chat at https://gitter.im/fsquillace/junest](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/fsquillace/junest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![RSS](https://img.shields.io/badge/RSS-News-orange.svg)](http://fsquillace.github.io/junest-site/feed.xml) | +| [![Build status](https://api.travis-ci.org/fsquillace/junest.png?branch=master)](https://travis-ci.org/fsquillace/junest) [![OpenHub](https://www.openhub.net/p/junest/widgets/project_thin_badge.gif)](https://www.openhub.net/p/junest) | [![Github Sponsors](https://img.shields.io/badge/GitHub-Sponsors-orange.svg)](https://github.com/sponsors/fsquillace) [![PayPal](https://img.shields.io/badge/PayPal-Donation-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8LEHQKBCYTACY) | [![Join the gitter chat at https://gitter.im/fsquillace/junest](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/fsquillace/junest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![RSS](https://img.shields.io/badge/RSS-News-orange.svg)](http://fsquillace.github.io/junest-site/feed.xml) | **Table of Contents** - [Description](#description) @@ -23,6 +23,7 @@ The lightweight Arch Linux based distro that runs upon any Linux distros without - [Troubleshooting](#troubleshooting) - [More documentation](#more-documentation) - [Contributing](#contributing) +- [Donating](#donating) - [Authors](#authors) Description @@ -518,6 +519,11 @@ Contributions are welcome! You could help improving JuNest in the following ways - [Suggesting Enhancements](CONTRIBUTING.md#suggesting-enhancements) - [Writing Code](CONTRIBUTING.md#your-first-code-contribution) +Donating +======== +To sustain the project please consider funding by donations through +the [GitHub Sponsors page](https://github.com/sponsors/fsquillace/). + Authors ======= JuNest was originally created in late 2014 by [Filippo Squillace (feel.sqoox@gmail.com)](https://github.com/fsquillace). diff --git a/VERSION b/VERSION index a8907c0..a50da18 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.2 +7.0.3 From 9bfd7e047d97fea93d9fbde90705df76e21c8550 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 14 Mar 2020 17:05:40 +0100 Subject: [PATCH 006/116] Add bwrap as backend for ns --- .travis.yml | 10 +-- README.md | 62 ++++++++++------ bin/junest | 16 +++-- lib/checks/check.sh | 64 +++++++++-------- lib/core/build.sh | 78 ++++++++++++++------ lib/core/common.sh | 13 +++- lib/core/namespace.sh | 70 +++++++++++++----- lib/core/proot.sh | 4 +- pkgs/sudo-fake/PKGBUILD | 4 +- tests/unit-tests/test-junest.sh | 111 ++++++++++++++++++++--------- tests/unit-tests/test-namespace.sh | 98 ++++++++++++++++++++----- tests/unit-tests/test-proot.sh | 26 +++---- 12 files changed, 387 insertions(+), 169 deletions(-) diff --git a/.travis.yml b/.travis.yml index 38470dc..b3a3bea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,10 +21,12 @@ script: - bash ./tests/unit-tests/unit-tests.sh # Multiple tests against different execution modes: - - junest proot --fakeroot -- ${PWD}/lib/checks/check.sh - - junest ns -- ${PWD}/lib/checks/check.sh - - sudo -E ${PWD}/bin/junest groot -- ${PWD}/lib/checks/check.sh --run-root-tests + - junest proot --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests + - junest proot -- ${PWD}/lib/checks/check.sh --skip-aur-tests --use-sudo + - junest ns --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests + - junest ns -- ${PWD}/lib/checks/check.sh --use-sudo + - sudo -E ${PWD}/bin/junest groot -- ${PWD}/lib/checks/check.sh --run-root-tests --skip-aur-tests - yes | junest setup --delete - - JUNEST_HOME=~/.junest-arm junest proot --fakeroot -- ${PWD}/lib/checks/check.sh + - JUNEST_HOME=~/.junest-arm junest proot --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests - yes | JUNEST_HOME=~/.junest-arm junest setup --delete diff --git a/README.md b/README.md index 3f96180..fc9f320 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,9 @@ The lightweight Arch Linux based distro that runs upon any Linux distros without Description =========== -**JuNest** (Jailed User NEST) is a lightweight Arch Linux based distribution that allows to have -an isolated GNU/Linux environment inside any generic host GNU/Linux OS +**JuNest** (Jailed User NEST) is a lightweight Arch Linux based distribution +that allows to have disposable and isolated GNU/Linux environments +within any generic GNU/Linux host OS and without the need to have root privileges for installing packages. JuNest contains mainly the package managers (called [pacman](https://wiki.archlinux.org/index.php/Pacman) @@ -86,14 +87,22 @@ By default, JuNest run via the Linux namespaces (aka `ns`) as the backend progra junest ``` +You can use the command `sudo` to acquire fakeroot privileges and +install/remove packages. + +Alternatively, you can access root privileges without using `sudo` with the +`-f` option: + +```sh +junest -f +``` + Another execution mode is via [Proot](https://wiki.archlinux.org/index.php/Proot): ```sh junest proot [-f] ``` -Where `-f` allow fakeroot access to install/remove packages. - There are multiple backend programs, each with its own pros/cons. To know more about the JuNest execution modes depending on the backend program used, see the [Usage](#usage) section below. @@ -105,15 +114,20 @@ Have fun! If you are new on Arch Linux and you are not familiar with `pacman` package manager visit the [pacman rosetta page](https://wiki.archlinux.org/index.php/Pacman_Rosetta). -JuNest provides a modified version of `makepkg` in `/opt/makepkg/bin` that -allows you to build packages from [AUR](https://aur.archlinux.org/) repository. -Remember that in order to build packages, `base-devel` package group is required +In `ns` mode, you can easily install package from [AUR](https://aur.archlinux.org/) repository +using the already available [`yay`](https://aur.archlinux.org/packages/yay/) +command. In `proot` mode, JuNest does no longer support the building of AUR packages. + +**Remember** that in order to build packages from source, `base-devel` package group is required first: ```sh pacman -Sy --ignore sudo base-devel ``` +JuNest uses a modified version of `sudo`. That's why the original `sudo` +package has to be ignored in the previous command. + Installation ============ @@ -125,14 +139,14 @@ Before installing JuNest be sure that all dependencies are properly installed in - [bash (>=4.0)](https://www.gnu.org/software/bash/) - [GNU coreutils](https://www.gnu.org/software/coreutils/) -The minimum recommended Linux kernel of the host OS is 2.6.32 on x86 (64 bit) +In `proot` mode, the minimum recommended Linux kernel for the host OS is 2.6.32 on x86 (64 bit) and ARM architectures. It is still possible to run JuNest on lower 2.6.x host OS kernels but errors may appear, and some applications may crash. For further information, read the [Troubleshooting](#troubleshooting) section below. -## Method one (Recommended) ## +## Installation from git repository ## Just clone the JuNest repo somewhere (for example in ~/.local/share/junest): git clone git://github.com/fsquillace/junest ~/.local/share/junest @@ -142,14 +156,6 @@ Just clone the JuNest repo somewhere (for example in ~/.local/share/junest): If you are using an Arch Linux system you can, alternatively, install JuNest from the [AUR repository](https://aur.archlinux.org/packages/junest-git/). After installing junest will be located in `/opt/junest/` -## Method two ## -Alternatively, another installation method would be to directly download the JuNest image and place it to the default directory `~/.junest`: - - ARCH= - mkdir ~/.junest - curl https://s3-eu-west-1.amazonaws.com/junest-repo/junest/junest-${ARCH}.tar.gz | tar -xz -C ~/.junest - export PATH=~/.junest/opt/junest/bin:$PATH - Usage ===== There are three different ways you can run JuNest depending on the backend program you decide to use. @@ -173,7 +179,12 @@ provides the state of the user namespace on several GNU/Linux distros. In order to run JuNest via Linux namespaces: -- As fakeroot - Allow to install/remove packages: `junest ns` or `junest` +- As normal user - Allow to make basic operations or install/remove packages +with `sudo` command: `junest ns` or `junest` +- As fakeroot - Allow to install/remove packages: `junest ns -f` or `junest -f` + +This mode is based on the fantastic +[`bubblewrap`](https://github.com/containers/bubblewrap) command. PRoot based ----------- @@ -211,8 +222,8 @@ The following table shows the capabilities that each backend program is able to | | QEMU | Root privileges required | Manage Official Packages | Manage AUR Packages | Portability | Support | User modes | | --- | ---- | ------------------------ | ------------------------ | ------------------- | ----------- | ------- | ---------- | -| **Linux Namespaces** | NO | NO | YES | YES | Poor | YES | `fakeroot` only | -| **Proot** | YES | NO | YES | YES | YES | Poor | Normal user and `fakeroot` | +| **Linux Namespaces** | NO | NO | YES | YES | Poor | YES | Normal user and `fakeroot` | +| **Proot** | YES | NO | YES | NO | YES | Poor | Normal user and `fakeroot` | | **Chroot** | NO | YES | YES | YES | YES | YES | `root` only | Advanced usage @@ -343,6 +354,17 @@ For Arch Linux related FAQs take a look at the [General troubleshooting page](ht > Remember to ignore `sudo` as it conflicts with `sudo-fake` package. +## Can't set user and group as root + +> **Q**: In ns mode when installing package I get the following error: + + warning: warning given when extracting /usr/file... (Can't set user=0/group=0 for + /usr/file...) + +> **A**: This is because as fakeroot is not possible to set the owner/group of +> files as root. The package will still be installed correctly even though this +> message is showed. + ## No servers configured for repository ## > **Q**: Why I cannot install packages? diff --git a/bin/junest b/bin/junest index 8ea3b19..442b31e 100755 --- a/bin/junest +++ b/bin/junest @@ -38,9 +38,9 @@ usage() { echo -e " Defaults to the host architecture ($ARCH)" echo -e " -d, --delete Delete $NAME from ${JUNEST_HOME}" echo - echo -e " n[s] Access via Linux Namespaces using GRoot (Default action)" + echo -e " n[s] Access via Linux Namespaces using BubbleWrap (Default action)" echo -e " -b, --backend-args Arguments for GRoot backend program" - echo -e " ($CMD groot -b \"--help\" to check out the GRoot options)" + echo -e " ($CMD groot -b \"--help\" to check out the bwrap options)" echo -e " -n, --no-copy-files Do not copy common etc files into $NAME environment" echo echo -e " p[root] Access via PRoot" @@ -138,6 +138,7 @@ function _parse_root_opts() { function _parse_ns_opts() { # Options: + OPT_FAKEROOT=false OPT_BACKEND_ARGS=false BACKEND_ARGS="" OPT_NO_COPY_FILES=false @@ -145,6 +146,7 @@ function _parse_ns_opts() { while [[ -n "$1" ]] do case "$1" in + -f|--fakeroot) OPT_FAKEROOT=true ; shift ;; -b|--backend-args) OPT_BACKEND_ARGS=true ; shift ; BACKEND_ARGS=$1; shift ;; -n|--no-copy-files) OPT_NO_COPY_FILES=true ; shift ;; --) shift ; break ;; @@ -250,12 +252,16 @@ function execute_operation() { local run_env if $ACT_NAMESPACE; then - run_env=run_env_with_namespace + if $OPT_FAKEROOT; then + run_env=run_env_as_bwrap_fakeroot + else + run_env=run_env_as_bwrap_user + fi elif $ACT_PROOT; then if $OPT_FAKEROOT; then - run_env=run_env_as_fakeroot + run_env=run_env_as_proot_fakeroot else - run_env=run_env_as_user + run_env=run_env_as_proot_user fi elif $ACT_GROOT; then run_env=run_env_as_groot diff --git a/lib/checks/check.sh b/lib/checks/check.sh index fb60ff0..5214595 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -9,15 +9,26 @@ # # vim: ft=sh -set -eu +set -e + -OPT_RUN_ROOT_TESTS=${1:-false} RUN_ROOT_TESTS=false -[[ ${OPT_RUN_ROOT_TESTS} == "--run-root-tests" ]] && RUN_ROOT_TESTS=true - -OPT_SKIP_AUR_TESTS=${1:-false} SKIP_AUR_TESTS=false -[[ ${OPT_SKIP_AUR_TESTS} == "--skip-aur-tests" ]] && SKIP_AUR_TESTS=true +USE_SUDO=false +while [[ -n "$1" ]] +do + case "$1" in + --run-root-tests) RUN_ROOT_TESTS=true ; shift ;; + --skip-aur-tests) SKIP_AUR_TESTS=true ; shift ;; + --use-sudo) USE_SUDO=true ; shift ;; + *) die "Invalid option $1" ;; + esac +done + +set -u + +SUDO="" +[[ -n $USE_SUDO ]] && SUDO="sudo" JUNEST_HOME=${JUNEST_HOME:-$HOME/.junest} @@ -36,49 +47,42 @@ info "Initial JuNest setup..." trap "[[ -e /etc/pacman.d/gnupg/S.gpg-agent ]] && gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye" QUIT EXIT ABRT KILL TERM INT echo "Server = ${DEFAULT_MIRROR}" >> /etc/pacman.d/mirrorlist -pacman --noconfirm -Syy +$SUDO pacman --noconfirm -Syy -pacman-key --init +$SUDO pacman-key --init -pacman --noconfirm -S archlinux-keyring -pacman-key --populate archlinux +$SUDO pacman --noconfirm -S archlinux-keyring +$SUDO pacman-key --populate archlinux -pacman --noconfirm -S archlinuxarm-keyring || echo "No ARM keyring detected" -pacman-key --populate archlinuxarm || echo "No ARM keyring detected" +$SUDO pacman --noconfirm -S archlinuxarm-keyring || echo "No ARM keyring detected" +$SUDO pacman-key --populate archlinuxarm || echo "No ARM keyring detected" -pacman --noconfirm -Su -pacman --noconfirm -S grep coreutils -pacman --noconfirm -S $(pacman -Sg base-devel | cut -d ' ' -f 2 | grep -v sudo) +$SUDO pacman --noconfirm -Su +$SUDO pacman --noconfirm -S grep coreutils +$SUDO pacman --noconfirm -S $(pacman -Sg base-devel | cut -d ' ' -f 2 | grep -v sudo) info "Checking basic executables work..." -pacman -Qi pacman 1> /dev/null -/opt/makepkg/bin/makepkg --help 1> /dev/null +$SUDO pacman -Qi pacman 1> /dev/null /opt/proot/proot-$ARCH --help 1> /dev/null repo_package1=tree echo "Checking ${repo_package1} package from official repo..." -pacman --noconfirm -S ${repo_package1} +$SUDO pacman --noconfirm -S ${repo_package1} tree -L 1 -pacman --noconfirm -Rsn ${repo_package1} +$SUDO pacman --noconfirm -Rsn ${repo_package1} repo_package2=iftop info "Checking ${repo_package2} package from official repo..." -pacman --noconfirm -S ${repo_package2} -$RUN_ROOT_TESTS && iftop -t -s 5 -pacman --noconfirm -Rsn ${repo_package2} +$SUDO pacman --noconfirm -S ${repo_package2} +$RUN_ROOT_TESTS && $SUDO iftop -t -s 5 +$SUDO pacman --noconfirm -Rsn ${repo_package2} if ! $SKIP_AUR_TESTS then aur_package=tcptraceroute info "Checking ${aur_package} package from AUR repo..." - maindir=$(mktemp -d -t ${CMD}.XXXXXXXXXX) - builtin cd ${maindir} - curl -L -J -O -k "https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=${aur_package}" - # -A allows to ignore arch for ARM - /opt/makepkg/bin/makepkg -Asfc --noconfirm - - pacman --noconfirm -U ${aur_package}*.pkg.tar.xz - pacman --noconfirm -Rsn ${aur_package} + yay --noconfirm -S ${aur_package} + $SUDO pacman --noconfirm -Rsn ${aur_package} fi # The following ensures that the gpg agent gets killed (if exists) diff --git a/lib/core/build.sh b/lib/core/build.sh index 898551a..d4215eb 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -8,13 +8,6 @@ # # vim: ft=sh -function _check_package(){ - if ! pacman -Qq $1 > /dev/null - then - die "Package $1 must be installed" - fi -} - function _install_pkg_from_aur(){ local maindir=$1 local pkgname=$2 @@ -35,15 +28,50 @@ function _install_pkg(){ sudo pacman --noconfirm --root ${maindir}/root -U *.pkg.tar.xz } +function _prepare() { + # ArchLinux System initialization + sudo pacman --noconfirm -Syu + sudo pacman -S --noconfirm base-devel + sudo pacman -S --noconfirm git arch-install-scripts +} + +function _install_proot_and_qemu(){ + local maindir="$1" + local main_repo=https://s3-eu-west-1.amazonaws.com/${CMD}-repo + proot_link=${main_repo}/proot + qemu_link=${main_repo}/qemu + + info "Installing proot static binaries" + sudo bash -c " + mkdir -p '${maindir}/root/opt/proot/' + curl '$proot_link/proot-x86_64' > '${maindir}/root/opt/proot/proot-x86_64' + curl '$proot_link/proot-arm' > '${maindir}/root/opt/proot/proot-arm' + chmod -R 755 '${maindir}/root/opt/proot/' + " + + info "Installing qemu static binaries" + sudo bash -c " + mkdir -p '${maindir}/root/opt/qemu/' + if [[ $ARCH == 'arm' ]] + then + curl '${qemu_link}/arm/qemu-arm-static-x86_64' > '${maindir}/root/opt/qemu/qemu-arm-static-x86_64' + elif [[ $ARCH == 'x86_64' ]] + then + curl '${qemu_link}/x86_64/qemu-x86_64-static-arm' > '${maindir}/root/opt/qemu/qemu-x86_64-static-arm' + fi + chmod -R 755 '${maindir}/root/opt/qemu/' + " +} + function build_image_env(){ umask 022 # The function must runs on ArchLinux with non-root privileges. + # This is because installing AUR packages can be done by normal users only. (( EUID == 0 )) && \ die "You cannot build with root privileges." - _check_package arch-install-scripts - _check_package gcc + _prepare local disable_validation=$1 @@ -54,33 +82,41 @@ function build_image_env(){ info "Installing pacman and its dependencies..." # The archlinux-keyring and libunistring are due to missing dependencies declaration in ARM archlinux # All the essential executables (ln, mkdir, chown, etc) are in coreutils - # unshare command belongs to util-linux + # bwrap command belongs to bubblewrap local arm_keyring="" [[ $(uname -m) == *"arm"* ]] && arm_keyring="archlinuxarm-keyring" - sudo pacstrap -G -M -d ${maindir}/root pacman coreutils libunistring archlinux-keyring $arm_keyring util-linux + sudo pacstrap -G -M -d ${maindir}/root pacman coreutils libunistring archlinux-keyring $arm_keyring bubblewrap sudo bash -c "echo 'Server = $DEFAULT_MIRROR' >> ${maindir}/root/etc/pacman.d/mirrorlist" sudo mkdir -p ${maindir}/root/run/lock # AUR packages requires non-root user to be compiled. proot fakes the user to 10 _install_pkg ${maindir} "$JUNEST_BASE/pkgs/sudo-fake" - info "Install ${NAME} script..." - _install_pkg_from_aur ${maindir} "${CMD}-git" "${CMD}.install" + info "Install yay..." + sudo pacman --noconfirm -S go + _install_pkg_from_aur ${maindir} "yay" + + _install_proot_and_qemu "${maindir}" + + echo "Generating the metadata info" + sudo install -d -m 755 "${maindir}/root/etc/${CMD}" + sudo bash -c "echo 'JUNEST_ARCH=$ARCH' > ${maindir}/root/etc/${CMD}/info" info "Generating the locales..." - # sed command is required for locale-gen + # sed command is required for locale-gen but it is required by fakeroot + # and cannot be removed # localedef (called by locale-gen) requires gzip sudo pacman --noconfirm --root ${maindir}/root -S sed gzip sudo ln -sf /usr/share/zoneinfo/posix/UTC ${maindir}/root/etc/localtime sudo bash -c "echo 'en_US.UTF-8 UTF-8' >> ${maindir}/root/etc/locale.gen" - sudo ${maindir}/root/opt/junest/bin/groot ${maindir}/root locale-gen + sudo ${JUNEST_BASE}/bin/groot ${maindir}/root locale-gen sudo bash -c "echo LANG=\"en_US.UTF-8\" >> ${maindir}/root/etc/locale.conf" - sudo pacman --noconfirm --root ${maindir}/root -Rsn sed gzip + sudo pacman --noconfirm --root ${maindir}/root -Rsn gzip info "Setting up the pacman keyring (this might take a while!)..." # gawk command is required for pacman-key sudo pacman --noconfirm --root ${maindir}/root -S gawk - sudo ${maindir}/root/opt/junest/bin/groot -b /dev ${maindir}/root bash -c ' + sudo ${JUNEST_BASE}/bin/groot -b /dev ${maindir}/root bash -c ' pacman-key --init; for keyring_file in /usr/share/pacman/keyrings/*.gpg; do @@ -105,9 +141,11 @@ function build_image_env(){ then mkdir -p ${maindir}/root_test $TAR -zxpf ${imagefile} -C "${maindir}/root_test" - JUNEST_HOME="${maindir}/root_test" ${JUNEST_BASE}/bin/${CMD} proot -f ${JUNEST_BASE}/lib/checks/check.sh - JUNEST_HOME="${maindir}/root_test" ${JUNEST_BASE}/bin/${CMD} ns ${JUNEST_BASE}/lib/checks/check.sh - JUNEST_HOME="${maindir}/root_test" sudo -E ${JUNEST_BASE}/bin/${CMD} groot ${JUNEST_BASE}/lib/checks/check.sh --run-root-tests + JUNEST_HOME="${maindir}/root_test" ${JUNEST_BASE}/bin/${CMD} proot --fakeroot ${JUNEST_BASE}/lib/checks/check.sh --skip-aur-tests + JUNEST_HOME="${maindir}/root_test" ${JUNEST_BASE}/bin/${CMD} proot ${JUNEST_BASE}/lib/checks/check.sh --skip-aur-tests --use-sudo + JUNEST_HOME="${maindir}/root_test" ${JUNEST_BASE}/bin/${CMD} ns --fakeroot ${JUNEST_BASE}/lib/checks/check.sh --skip-aur-tests + JUNEST_HOME="${maindir}/root_test" ${JUNEST_BASE}/bin/${CMD} ns ${JUNEST_BASE}/lib/checks/check.sh --use-sudo + JUNEST_HOME="${maindir}/root_test" sudo -E ${JUNEST_BASE}/bin/${CMD} groot ${JUNEST_BASE}/lib/checks/check.sh --run-root-tests --skip-aur-tests fi sudo cp ${maindir}/output/${imagefile} ${ORIGIN_WD} diff --git a/lib/core/common.sh b/lib/core/common.sh index 601e46c..219622a 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -81,6 +81,7 @@ CP=cp # Used for checking user namespace in config.gz file ZGREP=zgrep UNSHARE=unshare +BWRAP=bwrap LD_EXEC="$LD_LIB --library-path ${JUNEST_HOME}/usr/lib:${JUNEST_HOME}/lib" @@ -139,7 +140,17 @@ function unshare_cmd(){ then $UNSHARE "$@" else - die "Error: Something went wrong with unshare command. Exiting" + die "Error: Something went wrong while executing unshare command. Exiting" + fi +} + +function bwrap_cmd(){ + # TODO re-evaluate this strategy: + if $LD_EXEC ${JUNEST_HOME}/usr/bin/$BWRAP --dev-bind / / "${SH[0]}" "-c" ":" + then + $LD_EXEC ${JUNEST_HOME}/usr/bin/$BWRAP "${@}" + else + die "Error: Something went wrong while executing bwrap command. Exiting" fi } diff --git a/lib/core/namespace.sh b/lib/core/namespace.sh index 7943faa..39080e0 100644 --- a/lib/core/namespace.sh +++ b/lib/core/namespace.sh @@ -1,9 +1,8 @@ #!/usr/bin/env bash # -# This module contains all namespace functionalities for JuNest. +# This module contains functionalities for accessing to JuNest via bubblewrap. # -# http://man7.org/linux/man-pages/man7/namespaces.7.html -# http://man7.org/linux/man-pages/man2/unshare.2.html +# https://github.com/containers/bubblewrap # # Dependencies: # - lib/utils/utils.sh @@ -56,46 +55,75 @@ function _check_user_namespace() { set -e } -function _run_env_with_namespace(){ +function _run_env_with_bwrap(){ local backend_args="$1" shift - provide_common_bindings - local bindings=${RESULT} - unset RESULT - - # Use option -n in groot because umount do not work sometimes. - # As soon as the process terminates, the namespace - # will terminate too with its own mounted directories. if [[ "$1" != "" ]] then - JUNEST_ENV=1 unshare_cmd --mount --user --map-root-user $GROOT --no-umount --recursive $bindings $backend_args "$JUNEST_HOME" "${SH[@]}" "-c" "$(insert_quotes_on_spaces "${@}")" + JUNEST_ENV=1 bwrap_cmd --bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try ${backend_args} "${SH[@]}" "-c" "$(insert_quotes_on_spaces "${@}")" else - JUNEST_ENV=1 unshare_cmd --mount --user --map-root-user $GROOT --no-umount --recursive $bindings $backend_args "$JUNEST_HOME" "${SH[@]}" + JUNEST_ENV=1 bwrap_cmd --bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try ${backend_args} "${SH[@]}" fi + +} + +####################################### +# Run JuNest as fakeroot via bwrap +# +# Globals: +# JUNEST_HOME (RO) : The JuNest home directory. +# SH (RO) : Contains the default command to run in JuNest. +# Arguments: +# backend_args ($1) : The arguments to pass to bwrap +# no_copy_files ($2?) : If false it will copy some files in /etc +# from host to JuNest environment. +# cmd ($3-?) : The command to run inside JuNest environment. +# Default command is defined by SH variable. +# Returns: +# $ARCHITECTURE_MISMATCH : If host and JuNest architecture are different. +# $ROOT_ACCESS_ERROR : If the user is the real root. +# Output: +# - : The command output. +####################################### +function run_env_as_bwrap_fakeroot(){ + check_nested_env + + local backend_args="$1" + local no_copy_files="$2" + shift 2 + + _check_user_namespace + + check_same_arch + + if ! $no_copy_files + then + copy_common_files + fi + + _run_env_with_bwrap "--uid 0 $backend_args" "$@" } ####################################### -# Run JuNest as fakeroot user via user namespace. +# Run JuNest as normal user via bwrap. # # Globals: # JUNEST_HOME (RO) : The JuNest home directory. -# GROOT (RO) : The groot program. # SH (RO) : Contains the default command to run in JuNest. # Arguments: -# backend_args ($1) : The arguments to pass to groot +# backend_args ($1) : The arguments to pass to bwrap # no_copy_files ($2?) : If false it will copy some files in /etc # from host to JuNest environment. # cmd ($3-?) : The command to run inside JuNest environment. # Default command is defined by SH variable. # Returns: # $ARCHITECTURE_MISMATCH : If host and JuNest architecture are different. -# Depends on the unshare command outcome. # Output: # - : The command output. ####################################### -function run_env_with_namespace() { +function run_env_as_bwrap_user() { check_nested_env local backend_args="$1" @@ -117,5 +145,9 @@ function run_env_with_namespace() { copy_passwd_and_group fi - _run_env_with_namespace "$backend_args" "$@" + _run_env_with_bwrap "$backend_args" "$@" } + + + + diff --git a/lib/core/proot.sh b/lib/core/proot.sh index 69502eb..abf91df 100644 --- a/lib/core/proot.sh +++ b/lib/core/proot.sh @@ -58,7 +58,7 @@ function _run_env_with_qemu(){ # Output: # - : The command output. ####################################### -function run_env_as_fakeroot(){ +function run_env_as_proot_fakeroot(){ (( EUID == 0 )) && \ die_on_status $ROOT_ACCESS_ERROR "You cannot access with root privileges. Use --groot option instead." check_nested_env @@ -99,7 +99,7 @@ function run_env_as_fakeroot(){ # Output: # - : The command output. ####################################### -function run_env_as_user(){ +function run_env_as_proot_user(){ (( EUID == 0 )) && \ die_on_status $ROOT_ACCESS_ERROR "You cannot access with root privileges. Use --groot option instead." check_nested_env diff --git a/pkgs/sudo-fake/PKGBUILD b/pkgs/sudo-fake/PKGBUILD index 99fa18b..3587807 100644 --- a/pkgs/sudo-fake/PKGBUILD +++ b/pkgs/sudo-fake/PKGBUILD @@ -12,7 +12,7 @@ arch=('any') url="" license=('GPL') groups=() -depends=() +depends=('fakeroot' 'fakechroot') makedepends=() provides=('sudo') conflicts=('sudo') @@ -36,7 +36,7 @@ do esac done -[[ -z "\${@}" ]] || "\${@}" +[[ -z "\${@}" ]] || fakechroot fakeroot "\${@}" EOF chmod 755 "${pkgdir}/usr/bin/sudo" diff --git a/tests/unit-tests/test-junest.sh b/tests/unit-tests/test-junest.sh index 98c6cb2..db7d184 100755 --- a/tests/unit-tests/test-junest.sh +++ b/tests/unit-tests/test-junest.sh @@ -37,11 +37,11 @@ function setup_env_from_file(){ function setup_env(){ echo "setup_env($1)" } -function run_env_as_fakeroot(){ +function run_env_as_proot_fakeroot(){ local backend_args="$1" local no_copy_files="$2" shift 2 - echo "run_env_as_fakeroot($backend_args,$no_copy_files,$@)" + echo "run_env_as_proot_fakeroot($backend_args,$no_copy_files,$@)" } function run_env_as_groot(){ local backend_args="$1" @@ -55,17 +55,23 @@ function run_env_as_chroot(){ shift 2 echo "run_env_as_chroot($backend_args,$no_copy_files,$@)" } -function run_env_as_user(){ +function run_env_as_proot_user(){ local backend_args="$1" local no_copy_files="$2" shift 2 - echo "run_env_as_user($backend_args,$no_copy_files,$@)" + echo "run_env_as_proot_user($backend_args,$no_copy_files,$@)" } -function run_env_with_namespace(){ +function run_env_as_bwrap_fakeroot(){ local backend_args="$1" local no_copy_files="$2" shift 2 - echo "run_env_with_namespace($backend_args,$no_copy_files,$@)" + echo "run_env_as_bwrap_fakeroot($backend_args,$no_copy_files,$@)" +} +function run_env_as_bwrap_user(){ + local backend_args="$1" + local no_copy_files="$2" + shift 2 + echo "run_env_as_bwrap_user($backend_args,$no_copy_files,$@)" } function test_help(){ @@ -131,22 +137,22 @@ function test_setup_env(){ assertCommandFail main setup -a arm } -function test_run_env_as_fakeroot(){ +function test_run_env_as_proot_fakeroot(){ assertCommandSuccess main p -f - assertEquals "run_env_as_fakeroot(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,false,)" "$(cat $STDOUTF)" assertCommandSuccess main proot --fakeroot - assertEquals "run_env_as_fakeroot(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,false,)" "$(cat $STDOUTF)" assertCommandSuccess main p -f -n - assertEquals "run_env_as_fakeroot(,true,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,true,)" "$(cat $STDOUTF)" assertCommandSuccess main proot -f -b "-b arg" - assertEquals "run_env_as_fakeroot(-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(-b arg,false,)" "$(cat $STDOUTF)" assertCommandSuccess main proot -f -b "-b arg" -- command -kv - assertEquals "run_env_as_fakeroot(-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(-b arg,false,command -kv)" "$(cat $STDOUTF)" assertCommandSuccess main proot -f command --as - assertEquals "run_env_as_fakeroot(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,false,command --as)" "$(cat $STDOUTF)" assertCommandSuccess main proot -f -- command --as - assertEquals "run_env_as_fakeroot(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,false,command --as)" "$(cat $STDOUTF)" is_env_installed(){ return 1 @@ -156,18 +162,18 @@ function test_run_env_as_fakeroot(){ function test_run_env_as_user(){ assertCommandSuccess main proot - assertEquals "run_env_as_user(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,false,)" "$(cat $STDOUTF)" assertCommandSuccess main p -n - assertEquals "run_env_as_user(,true,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,true,)" "$(cat $STDOUTF)" assertCommandSuccess main proot -b "-b arg" - assertEquals "run_env_as_user(-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(-b arg,false,)" "$(cat $STDOUTF)" assertCommandSuccess main proot -b "-b arg" -- command -ll - assertEquals "run_env_as_user(-b arg,false,command -ll)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(-b arg,false,command -ll)" "$(cat $STDOUTF)" assertCommandSuccess main proot command -ls - assertEquals "run_env_as_user(,false,command -ls)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,false,command -ls)" "$(cat $STDOUTF)" assertCommandSuccess main proot -- command -ls - assertEquals "run_env_as_user(,false,command -ls)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,false,command -ls)" "$(cat $STDOUTF)" is_env_installed(){ return 1 @@ -209,36 +215,73 @@ function test_run_env_as_chroot(){ assertCommandFail main root -f } -function test_run_env_with_namespace(){ +function test_run_env_as_bwrap_fakeroot(){ + assertCommandSuccess main n -f + assertEquals "run_env_as_bwrap_fakeroot(,false,)" "$(cat $STDOUTF)" + assertCommandSuccess main ns -f + assertEquals "run_env_as_bwrap_fakeroot(,false,)" "$(cat $STDOUTF)" + assertCommandSuccess main ns -n -f + assertEquals "run_env_as_bwrap_fakeroot(,true,)" "$(cat $STDOUTF)" + + assertCommandSuccess main ns -f -b "-b arg" + assertEquals "run_env_as_bwrap_fakeroot(-b arg,false,)" "$(cat $STDOUTF)" + assertCommandSuccess main ns -f -b "-b arg" -- command -kv + assertEquals "run_env_as_bwrap_fakeroot(-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertCommandSuccess main ns -f command --as + assertEquals "run_env_as_bwrap_fakeroot(,false,command --as)" "$(cat $STDOUTF)" + assertCommandSuccess main ns -f -- command --as + assertEquals "run_env_as_bwrap_fakeroot(,false,command --as)" "$(cat $STDOUTF)" + + assertCommandSuccess main -f + assertEquals "run_env_as_bwrap_fakeroot(,false,)" "$(cat $STDOUTF)" + assertCommandSuccess main -f + assertEquals "run_env_as_bwrap_fakeroot(,false,)" "$(cat $STDOUTF)" + + assertCommandSuccess main -f -b "-b arg" + assertEquals "run_env_as_bwrap_fakeroot(-b arg,false,)" "$(cat $STDOUTF)" + assertCommandSuccess main -f -b "-b arg" -- command -kv + assertEquals "run_env_as_bwrap_fakeroot(-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertCommandSuccess main -f command --as + assertEquals "run_env_as_bwrap_fakeroot(,false,command --as)" "$(cat $STDOUTF)" + assertCommandSuccess main -f -- command --as + assertEquals "run_env_as_bwrap_fakeroot(,false,command --as)" "$(cat $STDOUTF)" + + is_env_installed(){ + return 1 + } + assertCommandFail main ns -f +} + +function test_run_env_as_bwrap_user(){ assertCommandSuccess main n - assertEquals "run_env_with_namespace(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,false,)" "$(cat $STDOUTF)" assertCommandSuccess main ns - assertEquals "run_env_with_namespace(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,false,)" "$(cat $STDOUTF)" assertCommandSuccess main ns -n - assertEquals "run_env_with_namespace(,true,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,true,)" "$(cat $STDOUTF)" assertCommandSuccess main ns -b "-b arg" - assertEquals "run_env_with_namespace(-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(-b arg,false,)" "$(cat $STDOUTF)" assertCommandSuccess main ns -b "-b arg" -- command -kv - assertEquals "run_env_with_namespace(-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(-b arg,false,command -kv)" "$(cat $STDOUTF)" assertCommandSuccess main ns command --as - assertEquals "run_env_with_namespace(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,false,command --as)" "$(cat $STDOUTF)" assertCommandSuccess main ns -- command --as - assertEquals "run_env_with_namespace(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,false,command --as)" "$(cat $STDOUTF)" assertCommandSuccess main - assertEquals "run_env_with_namespace(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,false,)" "$(cat $STDOUTF)" assertCommandSuccess main - assertEquals "run_env_with_namespace(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,false,)" "$(cat $STDOUTF)" assertCommandSuccess main -b "-b arg" - assertEquals "run_env_with_namespace(-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(-b arg,false,)" "$(cat $STDOUTF)" assertCommandSuccess main -b "-b arg" -- command -kv - assertEquals "run_env_with_namespace(-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(-b arg,false,command -kv)" "$(cat $STDOUTF)" assertCommandSuccess main command --as - assertEquals "run_env_with_namespace(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,false,command --as)" "$(cat $STDOUTF)" assertCommandSuccess main -- command --as - assertEquals "run_env_with_namespace(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,false,command --as)" "$(cat $STDOUTF)" is_env_installed(){ return 1 diff --git a/tests/unit-tests/test-namespace.sh b/tests/unit-tests/test-namespace.sh index 4ecc794..03eb1cd 100755 --- a/tests/unit-tests/test-namespace.sh +++ b/tests/unit-tests/test-namespace.sh @@ -15,8 +15,8 @@ function oneTimeSetUp(){ ## Mock functions ## function init_mocks() { - function unshare_cmd(){ - echo "unshare $@" + function bwrap_cmd(){ + echo "bwrap $@" } } @@ -99,17 +99,24 @@ function test_is_user_namespace_enabled_with_userns_clone_file_enabled(){ assertCommandSuccess _is_user_namespace_enabled } -function test_run_env_with_namespace() { - assertCommandSuccess run_env_with_namespace "" "false" "" - assertEquals "unshare --mount --user --map-root-user $GROOT --no-umount --recursive -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login" "$(cat $STDOUTF)" +function test_run_env_as_bwrap_fakeroot() { + assertCommandSuccess run_env_as_bwrap_fakeroot "" "false" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 /bin/sh --login" "$(cat $STDOUTF)" + + _test_copy_common_files +} + +function test_run_env_as_bwrap_user() { + assertCommandSuccess run_env_as_bwrap_user "" "false" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files } -function test_run_env_with_namespace_no_copy() { - assertCommandSuccess run_env_with_namespace "" "true" "" - assertEquals "unshare --mount --user --map-root-user $GROOT --no-umount --recursive -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login" "$(cat $STDOUTF)" +function test_run_env_as_bwrap_fakeroot_no_copy() { + assertCommandSuccess run_env_as_bwrap_fakeroot "" "true" "" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 /bin/sh --login" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -133,33 +140,86 @@ function test_run_env_with_namespace_no_copy() { assertEquals 0 $? } -function test_run_env_with_namespace_with_bindings() { - assertCommandSuccess run_env_with_namespace "-b /usr -b /lib:/tmp/lib" "false" "" - assertEquals "unshare --mount --user --map-root-user $GROOT --no-umount --recursive -b $HOME -b /tmp -b /proc -b /sys -b /dev -b /usr -b /lib:/tmp/lib $JUNEST_HOME /bin/sh --login" "$(cat $STDOUTF)" +function test_run_env_as_bwrap_user_no_copy() { + assertCommandSuccess run_env_as_bwrap_user "" "true" "" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try /bin/sh --login" "$(cat $STDOUTF)" + + [[ ! -e ${JUNEST_HOME}/etc/hosts ]] + assertEquals 0 $? + [[ ! -e ${JUNEST_HOME}/etc/host.conf ]] + assertEquals 0 $? + [[ ! -e ${JUNEST_HOME}/etc/nsswitch.conf ]] + assertEquals 0 $? + [[ ! -e ${JUNEST_HOME}/etc/resolv.conf ]] + assertEquals 0 $? + + [[ ! -e ${JUNEST_HOME}/etc/hosts.equiv ]] + assertEquals 0 $? + [[ ! -e ${JUNEST_HOME}/etc/netgroup ]] + assertEquals 0 $? + [[ ! -e ${JUNEST_HOME}/etc/networks ]] + assertEquals 0 $? + + [[ ! -e ${JUNEST_HOME}/etc/passwd ]] + assertEquals 0 $? + [[ ! -e ${JUNEST_HOME}/etc/group ]] + assertEquals 0 $? +} + +function test_run_env_as_bwrap_fakeroot_with_backend_args() { + assertCommandSuccess run_env_as_bwrap_fakeroot "--bind /usr /usr" "false" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --bind /usr /usr /bin/sh --login" "$(cat $STDOUTF)" + + _test_copy_common_files +} + +function test_run_env_as_bwrap_user_with_backend_args() { + assertCommandSuccess run_env_as_bwrap_user "--bind /usr /usr" "false" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --bind /usr /usr /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files } -function test_run_env_with_namespace_with_command() { - assertCommandSuccess run_env_with_namespace "" "false" "ls -la" - assertEquals "unshare --mount --user --map-root-user $GROOT --no-umount --recursive -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" +function test_run_env_as_bwrap_fakeroot_with_command() { + assertCommandSuccess run_env_as_bwrap_fakeroot "" "false" "ls -la" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + + _test_copy_common_files +} + +function test_run_env_as_bwrap_user_with_command() { + assertCommandSuccess run_env_as_bwrap_user "" "false" "ls -la" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files } -function test_run_env_with_namespace_with_bindings_and_command() { - assertCommandSuccess run_env_with_namespace "-b /usr -b /lib:/tmp/lib" "false" "ls -la" - assertEquals "unshare --mount --user --map-root-user $GROOT --no-umount --recursive -b $HOME -b /tmp -b /proc -b /sys -b /dev -b /usr -b /lib:/tmp/lib $JUNEST_HOME /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" +function test_run_env_as_bwrap_fakeroot_with_backend_args_and_command() { + assertCommandSuccess run_env_as_bwrap_fakeroot "--bind /usr /usr" "false" "ls -la" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --bind /usr /usr /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + + _test_copy_common_files +} + +function test_run_env_as_bwrap_user_with_backend_args_and_command() { + assertCommandSuccess run_env_as_bwrap_user "--bind /usr /usr" "false" "ls -la" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --bind /usr /usr /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files } -function test_run_env_with_namespace_nested_env(){ +function test_run_env_as_bwrap_fakeroot_nested_env(){ JUNEST_ENV=1 - assertCommandFailOnStatus 106 run_env_with_namespace "" "false" "" + assertCommandFailOnStatus 106 run_env_as_bwrap_fakeroot "" "false" "" + unset JUNEST_ENV +} + +function test_run_env_as_bwrap_user_nested_env(){ + JUNEST_ENV=1 + assertCommandFailOnStatus 106 run_env_as_bwrap_user "" "false" "" unset JUNEST_ENV } diff --git a/tests/unit-tests/test-proot.sh b/tests/unit-tests/test-proot.sh index a951cd6..4463df7 100755 --- a/tests/unit-tests/test-proot.sh +++ b/tests/unit-tests/test-proot.sh @@ -47,26 +47,26 @@ function _test_copy_remaining_files() { assertEquals 0 $? } -function test_run_env_as_user(){ +function test_run_env_as_proot_user(){ _run_env_with_qemu() { echo $@ } - assertCommandSuccess run_env_as_user "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" + assertCommandSuccess run_env_as_proot_user "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" SH=("/usr/bin/echo") - assertCommandSuccess run_env_as_user "-k 3.10" "false" + assertCommandSuccess run_env_as_proot_user "-k 3.10" "false" assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files } -function test_run_env_as_user_no_copy(){ +function test_run_env_as_proot_user_no_copy(){ _run_env_with_qemu() { echo $@ } - assertCommandSuccess run_env_as_user "-k 3.10" "true" "/usr/bin/mkdir" "-v" "/newdir2" + assertCommandSuccess run_env_as_proot_user "-k 3.10" "true" "/usr/bin/mkdir" "-v" "/newdir2" assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] @@ -91,29 +91,29 @@ function test_run_env_as_user_no_copy(){ assertEquals 0 $? } -function test_run_env_as_user_nested_env(){ +function test_run_env_as_proot_user_nested_env(){ JUNEST_ENV=1 - assertCommandFailOnStatus 106 run_env_as_user "" "false" + assertCommandFailOnStatus 106 run_env_as_proot_user "" "false" unset JUNEST_ENV } -function test_run_env_as_fakeroot(){ +function test_run_env_as_proot_fakeroot(){ _run_env_with_qemu() { echo $@ } - assertCommandSuccess run_env_as_fakeroot "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" + assertCommandSuccess run_env_as_proot_fakeroot "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" assertEquals "-0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" SH=("/usr/bin/echo") - assertCommandSuccess run_env_as_fakeroot "-k 3.10" "false" + assertCommandSuccess run_env_as_proot_fakeroot "-k 3.10" "false" assertEquals "-0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat $STDOUTF)" _test_copy_common_files } -function test_run_env_as_fakeroot_nested_env(){ +function test_run_env_as_proot_fakeroot_nested_env(){ JUNEST_ENV=1 - assertCommandFailOnStatus 106 run_env_as_fakeroot "" "false" "" + assertCommandFailOnStatus 106 run_env_as_proot_fakeroot "" "false" "" unset JUNEST_ENV } @@ -121,7 +121,7 @@ function test_run_env_with_quotes(){ _run_env_with_qemu() { echo $@ } - assertCommandSuccess run_env_as_user "-k 3.10" "false" "bash" "-c" "/usr/bin/mkdir -v /newdir2" + assertCommandSuccess run_env_as_proot_user "-k 3.10" "false" "bash" "-c" "/usr/bin/mkdir -v /newdir2" assertEquals "-b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 bash -c /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" } From 121f2c74f60a0e78e3164631dd1a4cbe3a2d63c8 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 15 Mar 2020 17:10:49 +0100 Subject: [PATCH 007/116] Improve build for ARM arch --- lib/checks/check.sh | 16 ++++++++++------ lib/core/build.sh | 7 +------ lib/core/common.sh | 1 - lib/core/setup.sh | 3 --- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/lib/checks/check.sh b/lib/checks/check.sh index 5214595..e7f924a 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -46,16 +46,20 @@ info "Initial JuNest setup..." # otherwise it is not possible to exit from the session trap "[[ -e /etc/pacman.d/gnupg/S.gpg-agent ]] && gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye" QUIT EXIT ABRT KILL TERM INT -echo "Server = ${DEFAULT_MIRROR}" >> /etc/pacman.d/mirrorlist $SUDO pacman --noconfirm -Syy +# Awk is required for pacman-key +$SUDO pacman --noconfirm -S gawk $SUDO pacman-key --init -$SUDO pacman --noconfirm -S archlinux-keyring -$SUDO pacman-key --populate archlinux - -$SUDO pacman --noconfirm -S archlinuxarm-keyring || echo "No ARM keyring detected" -$SUDO pacman-key --populate archlinuxarm || echo "No ARM keyring detected" +if [[ $(uname -m) == *"arm"* ]] +then + $SUDO pacman --noconfirm -S archlinuxarm-keyring + $SUDO pacman-key --populate archlinuxarm +else + $SUDO pacman --noconfirm -S archlinux-keyring + $SUDO pacman-key --populate archlinux +fi $SUDO pacman --noconfirm -Su $SUDO pacman --noconfirm -S grep coreutils diff --git a/lib/core/build.sh b/lib/core/build.sh index d4215eb..4cad766 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -80,16 +80,11 @@ function build_image_env(){ trap - QUIT EXIT ABRT KILL TERM INT trap "sudo rm -rf ${maindir}; die \"Error occurred when installing ${NAME}\"" EXIT QUIT ABRT KILL TERM INT info "Installing pacman and its dependencies..." - # The archlinux-keyring and libunistring are due to missing dependencies declaration in ARM archlinux # All the essential executables (ln, mkdir, chown, etc) are in coreutils # bwrap command belongs to bubblewrap - local arm_keyring="" - [[ $(uname -m) == *"arm"* ]] && arm_keyring="archlinuxarm-keyring" - sudo pacstrap -G -M -d ${maindir}/root pacman coreutils libunistring archlinux-keyring $arm_keyring bubblewrap - sudo bash -c "echo 'Server = $DEFAULT_MIRROR' >> ${maindir}/root/etc/pacman.d/mirrorlist" + sudo pacstrap -G -M -d ${maindir}/root pacman coreutils bubblewrap sudo mkdir -p ${maindir}/root/run/lock - # AUR packages requires non-root user to be compiled. proot fakes the user to 10 _install_pkg ${maindir} "$JUNEST_BASE/pkgs/sudo-fake" info "Install yay..." diff --git a/lib/core/common.sh b/lib/core/common.sh index 219622a..4622232 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -52,7 +52,6 @@ fi MAIN_REPO=https://s3-eu-west-1.amazonaws.com/${CMD}-repo ENV_REPO=${MAIN_REPO}/${CMD} -DEFAULT_MIRROR='https://mirrors.kernel.org/archlinux/$repo/os/$arch' ORIGIN_WD=$(pwd) diff --git a/lib/core/setup.sh b/lib/core/setup.sh index 2cbfdf1..d061281 100644 --- a/lib/core/setup.sh +++ b/lib/core/setup.sh @@ -52,7 +52,6 @@ function _setup_env(){ mkdir_cmd -p "${JUNEST_HOME}" $TAR -zxpf ${imagepath} -C ${JUNEST_HOME} - info "The default mirror URL is ${DEFAULT_MIRROR}." info "Remember to refresh the package databases from the server:" info " pacman -Syy" info "${NAME} installed successfully" @@ -70,7 +69,6 @@ function _setup_env(){ # the JuNest system from the image. # ENV_REPO (RO) : URL of the site containing JuNest images. # NAME (RO) : The JuNest name. -# DEFAULT_MIRROR (RO) : Arch Linux URL mirror. # Arguments: # arch ($1?) : The JuNest architecture image to download. # Defaults to the host architecture @@ -105,7 +103,6 @@ function setup_env(){ # JUNEST_HOME (RO) : The JuNest home directory in which JuNest needs # to be installed. # NAME (RO) : The JuNest name. -# DEFAULT_MIRROR (RO) : Arch Linux URL mirror. # Arguments: # imagefile ($1) : The JuNest image file. # Returns: From 6e55e0c6487a9f435d9926f45fb946993c89b53b Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 15 Mar 2020 23:26:25 +0100 Subject: [PATCH 008/116] See mirror URL only for non arm arch --- lib/core/build.sh | 8 +++++++- lib/core/common.sh | 1 + lib/core/setup.sh | 4 +++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/core/build.sh b/lib/core/build.sh index 4cad766..3260795 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -83,11 +83,17 @@ function build_image_env(){ # All the essential executables (ln, mkdir, chown, etc) are in coreutils # bwrap command belongs to bubblewrap sudo pacstrap -G -M -d ${maindir}/root pacman coreutils bubblewrap + + if [[ $(uname -m) != *"arm"* ]] + then + # x86_64 does not have any mirror set by default... + sudo bash -c "echo 'Server = $DEFAULT_MIRROR' >> ${maindir}/root/etc/pacman.d/mirrorlist" + fi sudo mkdir -p ${maindir}/root/run/lock _install_pkg ${maindir} "$JUNEST_BASE/pkgs/sudo-fake" - info "Install yay..." + info "Installing yay..." sudo pacman --noconfirm -S go _install_pkg_from_aur ${maindir} "yay" diff --git a/lib/core/common.sh b/lib/core/common.sh index 4622232..219622a 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -52,6 +52,7 @@ fi MAIN_REPO=https://s3-eu-west-1.amazonaws.com/${CMD}-repo ENV_REPO=${MAIN_REPO}/${CMD} +DEFAULT_MIRROR='https://mirrors.kernel.org/archlinux/$repo/os/$arch' ORIGIN_WD=$(pwd) diff --git a/lib/core/setup.sh b/lib/core/setup.sh index d061281..532f2a2 100644 --- a/lib/core/setup.sh +++ b/lib/core/setup.sh @@ -52,9 +52,11 @@ function _setup_env(){ mkdir_cmd -p "${JUNEST_HOME}" $TAR -zxpf ${imagepath} -C ${JUNEST_HOME} + info "${NAME} installed successfully!" + echo + info "Please change the pacman mirror URL in /etc/pacman.d/mirrorlist according to your location." info "Remember to refresh the package databases from the server:" info " pacman -Syy" - info "${NAME} installed successfully" } From 385dd8c68c7f6e05194606f007dec2e75c16800c Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 15 Mar 2020 23:49:45 +0100 Subject: [PATCH 009/116] Add script to check all tests --- .travis.yml | 13 +++++-------- lib/checks/check.sh | 26 ++++++++++++++------------ lib/checks/check_all.sh | 17 +++++++++++++++++ 3 files changed, 36 insertions(+), 20 deletions(-) create mode 100755 lib/checks/check_all.sh diff --git a/.travis.yml b/.travis.yml index b3a3bea..a0feac4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,13 +20,10 @@ script: - bash ./tests/checkstyle/checkstyle.sh - bash ./tests/unit-tests/unit-tests.sh - # Multiple tests against different execution modes: - - junest proot --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests - - junest proot -- ${PWD}/lib/checks/check.sh --skip-aur-tests --use-sudo - - junest ns --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests - - junest ns -- ${PWD}/lib/checks/check.sh --use-sudo - - sudo -E ${PWD}/bin/junest groot -- ${PWD}/lib/checks/check.sh --run-root-tests --skip-aur-tests + - export JUNEST_HOME=~/.junest + - ${PWD}/lib/checks/check_all.sh - yes | junest setup --delete - - JUNEST_HOME=~/.junest-arm junest proot --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests - - yes | JUNEST_HOME=~/.junest-arm junest setup --delete + - export JUNEST_HOME=~/.junest-arm + - ${PWD}/lib/checks/check_all.sh + - yes | junest setup --delete diff --git a/lib/checks/check.sh b/lib/checks/check.sh index e7f924a..e8bfc95 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -46,24 +46,26 @@ info "Initial JuNest setup..." # otherwise it is not possible to exit from the session trap "[[ -e /etc/pacman.d/gnupg/S.gpg-agent ]] && gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye" QUIT EXIT ABRT KILL TERM INT -$SUDO pacman --noconfirm -Syy +PACMAN_OPTIONS="--noconfirm --disable-download-timeout" + +$SUDO pacman $PACMAN_OPTIONS -Syy # Awk is required for pacman-key -$SUDO pacman --noconfirm -S gawk +$SUDO pacman $PACMAN_OPTIONS -S gawk $SUDO pacman-key --init if [[ $(uname -m) == *"arm"* ]] then - $SUDO pacman --noconfirm -S archlinuxarm-keyring + $SUDO pacman $PACMAN_OPTIONS -S archlinuxarm-keyring $SUDO pacman-key --populate archlinuxarm else - $SUDO pacman --noconfirm -S archlinux-keyring + $SUDO pacman $PACMAN_OPTIONS -S archlinux-keyring $SUDO pacman-key --populate archlinux fi -$SUDO pacman --noconfirm -Su -$SUDO pacman --noconfirm -S grep coreutils -$SUDO pacman --noconfirm -S $(pacman -Sg base-devel | cut -d ' ' -f 2 | grep -v sudo) +$SUDO pacman $PACMAN_OPTIONS -Su +$SUDO pacman $PACMAN_OPTIONS -S grep coreutils +$SUDO pacman $PACMAN_OPTIONS -S $(pacman -Sg base-devel | cut -d ' ' -f 2 | grep -v sudo) info "Checking basic executables work..." $SUDO pacman -Qi pacman 1> /dev/null @@ -71,22 +73,22 @@ $SUDO pacman -Qi pacman 1> /dev/null repo_package1=tree echo "Checking ${repo_package1} package from official repo..." -$SUDO pacman --noconfirm -S ${repo_package1} +$SUDO pacman $PACMAN_OPTIONS -S ${repo_package1} tree -L 1 -$SUDO pacman --noconfirm -Rsn ${repo_package1} +$SUDO pacman $PACMAN_OPTIONS -Rsn ${repo_package1} repo_package2=iftop info "Checking ${repo_package2} package from official repo..." -$SUDO pacman --noconfirm -S ${repo_package2} +$SUDO pacman $PACMAN_OPTIONS -S ${repo_package2} $RUN_ROOT_TESTS && $SUDO iftop -t -s 5 -$SUDO pacman --noconfirm -Rsn ${repo_package2} +$SUDO pacman $PACMAN_OPTIONS -Rsn ${repo_package2} if ! $SKIP_AUR_TESTS then aur_package=tcptraceroute info "Checking ${aur_package} package from AUR repo..." yay --noconfirm -S ${aur_package} - $SUDO pacman --noconfirm -Rsn ${aur_package} + $SUDO pacman $PACMAN_OPTIONS -Rsn ${aur_package} fi # The following ensures that the gpg agent gets killed (if exists) diff --git a/lib/checks/check_all.sh b/lib/checks/check_all.sh new file mode 100755 index 0000000..6e28ee5 --- /dev/null +++ b/lib/checks/check_all.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# Multiple tests against different execution modes + +set -ex + +# JUNEST_BASE can be overridden for testing purposes. +# There is no need for doing it for normal usage. +JUNEST_BASE="${JUNEST_BASE:-$(readlink -f $(dirname $(readlink -f "$0"))/../..)}" + +JUNEST_SCRIPT=${JUNEST_SCRIPT:-${JUNEST_BASE}/bin/junest} +CHECK_SCRIPT=${JUNEST_BASE}/lib/checks/check.sh + +$JUNEST_SCRIPT proot --fakeroot -- "$CHECK_SCRIPT" --skip-aur-tests +$JUNEST_SCRIPT proot -- "$CHECK_SCRIPT" --skip-aur-tests --use-sudo +$JUNEST_SCRIPT ns --fakeroot -- "$CHECK_SCRIPT" --skip-aur-tests +$JUNEST_SCRIPT ns -- "$CHECK_SCRIPT" --use-sudo +sudo -E $JUNEST_SCRIPT groot -- "$CHECK_SCRIPT" --run-root-tests --skip-aur-tests From 4b5b7b300b4d40a76a09df3f1c83236326313d57 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Mon, 16 Mar 2020 18:59:01 +0100 Subject: [PATCH 010/116] Add test for bwrap command --- lib/core/build.sh | 6 +----- lib/core/common.sh | 3 +-- tests/unit-tests/test-common.sh | 12 ++++++++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/core/build.sh b/lib/core/build.sh index 3260795..bd07c5b 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -142,11 +142,7 @@ function build_image_env(){ then mkdir -p ${maindir}/root_test $TAR -zxpf ${imagefile} -C "${maindir}/root_test" - JUNEST_HOME="${maindir}/root_test" ${JUNEST_BASE}/bin/${CMD} proot --fakeroot ${JUNEST_BASE}/lib/checks/check.sh --skip-aur-tests - JUNEST_HOME="${maindir}/root_test" ${JUNEST_BASE}/bin/${CMD} proot ${JUNEST_BASE}/lib/checks/check.sh --skip-aur-tests --use-sudo - JUNEST_HOME="${maindir}/root_test" ${JUNEST_BASE}/bin/${CMD} ns --fakeroot ${JUNEST_BASE}/lib/checks/check.sh --skip-aur-tests - JUNEST_HOME="${maindir}/root_test" ${JUNEST_BASE}/bin/${CMD} ns ${JUNEST_BASE}/lib/checks/check.sh --use-sudo - JUNEST_HOME="${maindir}/root_test" sudo -E ${JUNEST_BASE}/bin/${CMD} groot ${JUNEST_BASE}/lib/checks/check.sh --run-root-tests --skip-aur-tests + JUNEST_HOME="${maindir}/root_test" ${JUNEST_BASE}/lib/checks/check_all.sh fi sudo cp ${maindir}/output/${imagefile} ${ORIGIN_WD} diff --git a/lib/core/common.sh b/lib/core/common.sh index 219622a..fe43dde 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -145,8 +145,7 @@ function unshare_cmd(){ } function bwrap_cmd(){ - # TODO re-evaluate this strategy: - if $LD_EXEC ${JUNEST_HOME}/usr/bin/$BWRAP --dev-bind / / "${SH[0]}" "-c" ":" + if $LD_EXEC ${JUNEST_HOME}/usr/bin/$BWRAP --dev-bind / / "${SH[0]}" "-c" ":" then $LD_EXEC ${JUNEST_HOME}/usr/bin/$BWRAP "${@}" else diff --git a/tests/unit-tests/test-common.sh b/tests/unit-tests/test-common.sh index dfff6f4..dd77077 100755 --- a/tests/unit-tests/test-common.sh +++ b/tests/unit-tests/test-common.sh @@ -34,6 +34,11 @@ function setUp(){ } UNSHARE=unshare_mock + bwrap_mock() { + echo "bwrap $@" + } + BWRAP=bwrap_mock + } function test_ln(){ @@ -136,6 +141,13 @@ function test_unshare(){ UNSHARE=false LD_EXEC=false assertCommandFail unshare_cmd new_program } +function test_bwrap(){ + assertCommandSuccess bwrap_cmd new_program + assertEquals "$(echo -e "ld_exec ${JUNEST_HOME}/usr/bin/$BWRAP --dev-bind / / /bin/sh -c :\nld_exec ${JUNEST_HOME}/usr/bin/$BWRAP new_program")" "$(cat $STDOUTF)" + + BWRAP=false LD_EXEC=false assertCommandFail bwrap_cmd new_program +} + function test_chroot(){ CLASSIC_CHROOT=echo assertCommandSuccess chroot_cmd root assertEquals "root" "$(cat $STDOUTF)" From 628ac3c65516c70117b5bc6916dbc54aadd1177b Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Mon, 16 Mar 2020 20:12:27 +0100 Subject: [PATCH 011/116] 7.1.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a50da18..a3fcc71 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3 +7.1.0 From 1580ba9c8e86eff8c955da8fe499f1ad07c8a7b5 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Mon, 16 Mar 2020 20:52:01 +0100 Subject: [PATCH 012/116] Fix travis for ARM tests --- .travis.yml | 3 ++- VERSION | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a0feac4..025ddc7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,5 +25,6 @@ script: - yes | junest setup --delete - export JUNEST_HOME=~/.junest-arm - - ${PWD}/lib/checks/check_all.sh + - junest proot --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests + - junest proot -- ${PWD}/lib/checks/check.sh --skip-aur-tests --use-sudo - yes | junest setup --delete diff --git a/VERSION b/VERSION index a3fcc71..21c8c7b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.1.0 +7.1.1 From 6592bc9bd22a6b389e1705e0732f5ca3469d7927 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 22 Mar 2020 17:33:59 +0100 Subject: [PATCH 013/116] Separate proot, qemu, groot into packages --- bin/junest | 4 +-- lib/checks/check.sh | 3 +- lib/core/build.sh | 41 ++++++------------------ lib/core/common.sh | 13 ++++---- lib/core/proot.sh | 2 +- pkgs/groot-git/PKGBUILD | 58 ++++++++++++++++++++++++++++++++++ pkgs/proot-static/PKGBUILD | 43 +++++++++++++++++++++++++ pkgs/qemu-static/PKGBUILD | 50 +++++++++++++++++++++++++++++ tests/unit-tests/test-proot.sh | 2 +- 9 files changed, 173 insertions(+), 43 deletions(-) create mode 100644 pkgs/groot-git/PKGBUILD create mode 100644 pkgs/proot-static/PKGBUILD create mode 100644 pkgs/qemu-static/PKGBUILD diff --git a/bin/junest b/bin/junest index 442b31e..3b7eb87 100755 --- a/bin/junest +++ b/bin/junest @@ -39,8 +39,8 @@ usage() { echo -e " -d, --delete Delete $NAME from ${JUNEST_HOME}" echo echo -e " n[s] Access via Linux Namespaces using BubbleWrap (Default action)" - echo -e " -b, --backend-args Arguments for GRoot backend program" - echo -e " ($CMD groot -b \"--help\" to check out the bwrap options)" + echo -e " -b, --backend-args Arguments for bwrap backend program" + echo -e " ($CMD ns -b \"--help\" to check out the bwrap options)" echo -e " -n, --no-copy-files Do not copy common etc files into $NAME environment" echo echo -e " p[root] Access via PRoot" diff --git a/lib/checks/check.sh b/lib/checks/check.sh index e8bfc95..634044c 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -69,7 +69,8 @@ $SUDO pacman $PACMAN_OPTIONS -S $(pacman -Sg base-devel | cut -d ' ' -f 2 | grep info "Checking basic executables work..." $SUDO pacman -Qi pacman 1> /dev/null -/opt/proot/proot-$ARCH --help 1> /dev/null +/usr/bin/proot --help 1> /dev/null +/usr/bin/groot --help 1> /dev/null repo_package1=tree echo "Checking ${repo_package1} package from official repo..." diff --git a/lib/core/build.sh b/lib/core/build.sh index bd07c5b..a25cef6 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -23,8 +23,12 @@ function _install_pkg_from_aur(){ function _install_pkg(){ local maindir=$1 local pkgbuilddir=$2 - builtin cd ${pkgbuilddir} + # Generate a working directory because sources will be downloaded to there + working_dir=$(TMPDIR=/tmp mktemp -d -t junest-wd.XXXXXXXXXX) + cp -R "$pkgbuilddir"/* "$working_dir" + builtin cd ${working_dir} makepkg -sfcd + makepkg --printsrcinfo > ${pkgbuilddir}/.SRCINFO sudo pacman --noconfirm --root ${maindir}/root -U *.pkg.tar.xz } @@ -35,34 +39,6 @@ function _prepare() { sudo pacman -S --noconfirm git arch-install-scripts } -function _install_proot_and_qemu(){ - local maindir="$1" - local main_repo=https://s3-eu-west-1.amazonaws.com/${CMD}-repo - proot_link=${main_repo}/proot - qemu_link=${main_repo}/qemu - - info "Installing proot static binaries" - sudo bash -c " - mkdir -p '${maindir}/root/opt/proot/' - curl '$proot_link/proot-x86_64' > '${maindir}/root/opt/proot/proot-x86_64' - curl '$proot_link/proot-arm' > '${maindir}/root/opt/proot/proot-arm' - chmod -R 755 '${maindir}/root/opt/proot/' - " - - info "Installing qemu static binaries" - sudo bash -c " - mkdir -p '${maindir}/root/opt/qemu/' - if [[ $ARCH == 'arm' ]] - then - curl '${qemu_link}/arm/qemu-arm-static-x86_64' > '${maindir}/root/opt/qemu/qemu-arm-static-x86_64' - elif [[ $ARCH == 'x86_64' ]] - then - curl '${qemu_link}/x86_64/qemu-x86_64-static-arm' > '${maindir}/root/opt/qemu/qemu-x86_64-static-arm' - fi - chmod -R 755 '${maindir}/root/opt/qemu/' - " -} - function build_image_env(){ umask 022 @@ -84,7 +60,7 @@ function build_image_env(){ # bwrap command belongs to bubblewrap sudo pacstrap -G -M -d ${maindir}/root pacman coreutils bubblewrap - if [[ $(uname -m) != *"arm"* ]] + if [[ ${ARCH} != "arm" ]] then # x86_64 does not have any mirror set by default... sudo bash -c "echo 'Server = $DEFAULT_MIRROR' >> ${maindir}/root/etc/pacman.d/mirrorlist" @@ -92,13 +68,14 @@ function build_image_env(){ sudo mkdir -p ${maindir}/root/run/lock _install_pkg ${maindir} "$JUNEST_BASE/pkgs/sudo-fake" + _install_pkg ${maindir} "$JUNEST_BASE/pkgs/proot-static" + _install_pkg ${maindir} "$JUNEST_BASE/pkgs/qemu-static" + _install_pkg ${maindir} "$JUNEST_BASE/pkgs/groot-git" info "Installing yay..." sudo pacman --noconfirm -S go _install_pkg_from_aur ${maindir} "yay" - _install_proot_and_qemu "${maindir}" - echo "Generating the metadata info" sudo install -d -m 755 "${maindir}/root/etc/${CMD}" sudo bash -c "echo 'JUNEST_ARCH=$ARCH' > ${maindir}/root/etc/${CMD}/info" diff --git a/lib/core/common.sh b/lib/core/common.sh index fe43dde..eb728e9 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -21,7 +21,6 @@ NO_CONFIG_FOUND=108 UNPRIVILEGED_USERNS_DISABLED=109 JUNEST_HOME=${JUNEST_HOME:-~/.${CMD}} -JUNEST_BASE=${JUNEST_BASE:-${JUNEST_HOME}/opt/junest} JUNEST_TEMPDIR=${JUNEST_TEMPDIR:-/tmp} # The update of the variable PATH ensures that the executables are @@ -34,15 +33,17 @@ UNAME=uname ARCH_LIST=('x86_64' 'x86' 'arm') HOST_ARCH=$($UNAME -m) -if [ $HOST_ARCH == "i686" ] || [ $HOST_ARCH == "i386" ] +# To check all available architectures look here: +# https://wiki.archlinux.org/index.php/PKGBUILD#arch +if [[ $HOST_ARCH == "i686" ]] || [[ $HOST_ARCH == "i386" ]] then ARCH="x86" LD_LIB="${JUNEST_HOME}/lib/ld-linux.so.2" -elif [ $HOST_ARCH == "x86_64" ] +elif [[ $HOST_ARCH == "x86_64" ]] then ARCH="x86_64" LD_LIB="${JUNEST_HOME}/lib64/ld-linux-x86-64.so.2" -elif [[ $HOST_ARCH =~ .*(arm).* ]] +elif [[ $HOST_ARCH =~ .*(arm).* ]] || [[ $HOST_ARCH == "aarch64" ]] then ARCH="arm" LD_LIB="${JUNEST_HOME}/lib/ld-linux-armhf.so.3" @@ -66,8 +67,8 @@ ORIGIN_WD=$(pwd) SH=("/bin/sh" "--login") # List of executables that are run in the host OS: -PROOT="${JUNEST_HOME}/opt/proot/proot-${ARCH}" -GROOT=${JUNEST_BASE}/bin/groot +PROOT="${JUNEST_HOME}/usr/bin/proot" +GROOT="${JUNEST_HOME}/usr/bin/groot" CLASSIC_CHROOT=chroot WGET="wget --no-check-certificate" CURL="curl -L -J -O -k" diff --git a/lib/core/proot.sh b/lib/core/proot.sh index abf91df..d2bfd5f 100644 --- a/lib/core/proot.sh +++ b/lib/core/proot.sh @@ -33,7 +33,7 @@ function _run_env_with_qemu(){ warn "Emulating $NAME via QEMU..." [ -e ${qemu_symlink} ] || \ - ln_cmd -s ${JUNEST_HOME}/opt/qemu/${qemu_bin} ${qemu_symlink} + ln_cmd -s ${JUNEST_HOME}/bin/${qemu_bin} ${qemu_symlink} proot_args="-q ${qemu_symlink} $proot_args" fi shift diff --git a/pkgs/groot-git/PKGBUILD b/pkgs/groot-git/PKGBUILD new file mode 100644 index 0000000..015f9a2 --- /dev/null +++ b/pkgs/groot-git/PKGBUILD @@ -0,0 +1,58 @@ +# Maintainer: Filippo Squillace +# More details on how to change this file: +# https://wiki.archlinux.org/index.php/PKGBUILD +# https://wiki.archlinux.org/index.php/Creating_packages +# https://wiki.archlinux.org/index.php/Arch_User_Repository#Submitting_packages + +pkgname=groot-git +pkgver=1.0.1 +pkgrel=1 +pkgdesc="" +arch=('any') +url="https://github.com/fsquillace/groot" +license=('GPL') +groups=() +depends=('coreutils') +makedepends=() +provides=('groot') +conflicts=() +replaces=() +backup=() +options=() +#install= +noextract=() + + +source=('groot::git+https://github.com/fsquillace/groot.git#branch=master') +md5sums=('SKIP') + + +pkgver() { + cd "$srcdir/${pkgname%-git}" + +# The examples below are not absolute and need to be adapted to each repo. The +# primary goal is to generate version numbers that will increase according to +# pacman's version comparisons with later commits to the repo. The format +# VERSION='VER_NUM.rREV_NUM.HASH', or a relevant subset in case VER_NUM or HASH +# are not available, is recommended. + +# Git, tags available + printf "%s" "$(git describe --tags | sed 's/\([^-]*-\)g/r\1/;s/-/./g')" + +# Git, no tags available +# printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" + +} + +build() { + : +} + +package() { + cd "$srcdir/${pkgname%-git}" + + install -d -m 755 "${pkgdir}/usr/bin" + install -m 755 "${srcdir}/${pkgname%-git}/bin/groot" ${pkgdir}/usr/bin/groot +} + +# vim:set ts=2 sw=2 et: diff --git a/pkgs/proot-static/PKGBUILD b/pkgs/proot-static/PKGBUILD new file mode 100644 index 0000000..fad9291 --- /dev/null +++ b/pkgs/proot-static/PKGBUILD @@ -0,0 +1,43 @@ +# Maintainer: Filippo Squillace +# More details on how to change this file: +# https://wiki.archlinux.org/index.php/PKGBUILD +# https://wiki.archlinux.org/index.php/Creating_packages +# https://wiki.archlinux.org/index.php/Arch_User_Repository#Submitting_packages + +pkgname=proot-static +_pkgname=proot +pkgver=5.1.0 +pkgrel=1 +pkgdesc="chroot, mount --bind, and binfmt_misc without privilege/setup. Static binary only" +arch=('any') +url="https://proot-me.github.io/" +license=('GPL') +groups=() +depends=() +makedepends=() +provides=('proot') +conflicts=('proot' 'proot-bin') +backup=() +options=() +#install= +source=() +md5sums=() +noextract=() + +MAIN_REPO=https://s3-eu-west-1.amazonaws.com/junest-repo +PROOT_LINK=${MAIN_REPO}/proot + +source_x86_64=("${_pkgname}"::"$PROOT_LINK/proot-x86_64") +source_i686=("${_pkgname}"::"$PROOT_LINK/proot-x86") +source_arm=("${_pkgname}"::"$PROOT_LINK/proot-arm") +md5sums_x86_64=('14080705dd45a6bafa20e909a68072cb') +md5sums_i686=('b1c08236b56d121e04e9e29b197d0eeb') +md5sums_arm=('8218c5f00e77e2e6e04c372ced27c7e7') + +package() { + echo "Installing proot static binaries" + install -d -m 755 "${pkgdir}/usr/bin/" + install -m 755 "${srcdir}/${_pkgname}" ${pkgdir}/usr/bin/proot +} + +# vim:set ts=2 sw=2 et: diff --git a/pkgs/qemu-static/PKGBUILD b/pkgs/qemu-static/PKGBUILD new file mode 100644 index 0000000..3b7fc65 --- /dev/null +++ b/pkgs/qemu-static/PKGBUILD @@ -0,0 +1,50 @@ +# Maintainer: Filippo Squillace +# More details on how to change this file: +# https://wiki.archlinux.org/index.php/PKGBUILD +# https://wiki.archlinux.org/index.php/Creating_packages +# https://wiki.archlinux.org/index.php/Arch_User_Repository#Submitting_packages + +pkgname=qemu-static +pkgver=2.3.0 +pkgrel=1 +pkgdesc="Statically linked binaries of Qemu with user emulation. Useful for containers/chroot environment with binfmt." +arch=('any') +url="http://wiki.qemu.org" +license=('GPL2') +groups=() +depends=() +makedepends=() +provides=() +conflicts=() +backup=() +options=() +#install= +source=() +md5sums=() +noextract=() + +MAIN_REPO=https://s3-eu-west-1.amazonaws.com/junest-repo +QEMU_LINK=$MAIN_REPO/qemu + +source_x86_64=("${QEMU_LINK}/x86_64/qemu-x86_64-static-x86" "${QEMU_LINK}/x86_64/qemu-x86_64-static-arm") +source_i686=("${QEMU_LINK}/x86/qemu-x86-static-x86_64" "${QEMU_LINK}/x86/qemu-x86_64-static-arm") +md5sums_x86_64=('8a706d734f8c790743a8114dda4c344a' '3ced729c95d2514f35d4899e944a4582') +md5sums_x86=('c28d5049193dbce75efa0c8655d71427' 'f75fd15722fcc2914e3de0b0a46eb982') + +source_arm=("${QEMU_LINK}/arm/qemu-arm-static-x86_64" "${QEMU_LINK}/arm/qemu-arm-static-x86") +md5sums_arm=('bd9de1927aae4eb26dc0e5615159a616' 'a7c2b6ca53fa166f0c06ec76cc5edd7d') +source_armv6h=("${QEMU_LINK}/arm/qemu-arm-static-x86_64" "${QEMU_LINK}/arm/qemu-arm-static-x86") +md5sums_armv6h=('bd9de1927aae4eb26dc0e5615159a616' 'a7c2b6ca53fa166f0c06ec76cc5edd7d') +source_armv7h=("${QEMU_LINK}/arm/qemu-arm-static-x86_64" "${QEMU_LINK}/arm/qemu-arm-static-x86") +md5sums_armv7h=('bd9de1927aae4eb26dc0e5615159a616' 'a7c2b6ca53fa166f0c06ec76cc5edd7d') +source_aarch64=("${QEMU_LINK}/arm/qemu-arm-static-x86_64" "${QEMU_LINK}/arm/qemu-arm-static-x86") +md5sums_aarch64=('bd9de1927aae4eb26dc0e5615159a616' 'a7c2b6ca53fa166f0c06ec76cc5edd7d') + + +package() { + echo "Installing qemu static binaries" + install -d -m 755 "${pkgdir}/usr/bin" + install -m 755 "${srcdir}"/qemu-* ${pkgdir}/usr/bin +} + +# vim:set ts=2 sw=2 et: diff --git a/tests/unit-tests/test-proot.sh b/tests/unit-tests/test-proot.sh index 4463df7..8fa636f 100755 --- a/tests/unit-tests/test-proot.sh +++ b/tests/unit-tests/test-proot.sh @@ -153,7 +153,7 @@ function test_qemu() { } RANDOM=100 ARCH=x86_64 assertCommandSuccess _run_env_with_qemu "" - assertEquals "$(echo -e "-s $JUNEST_HOME/opt/qemu/qemu-arm-static-x86_64 /tmp/qemu-arm-static-x86_64-100\n-q /tmp/qemu-arm-static-x86_64-100")" "$(cat $STDOUTF)" + assertEquals "$(echo -e "-s $JUNEST_HOME/bin/qemu-arm-static-x86_64 /tmp/qemu-arm-static-x86_64-100\n-q /tmp/qemu-arm-static-x86_64-100")" "$(cat $STDOUTF)" } source $JUNEST_ROOT/tests/utils/shunit2 From 348b73ce732215a5c6f7e44a4540fdb8beeb48d7 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 24 Mar 2020 21:18:25 +0100 Subject: [PATCH 014/116] Remove groot content --- bin/groot | 242 -------------------------------- tests/unit-tests/test-groot.sh | 248 --------------------------------- 2 files changed, 490 deletions(-) delete mode 100755 bin/groot delete mode 100755 tests/unit-tests/test-groot.sh diff --git a/bin/groot b/bin/groot deleted file mode 100755 index cb4952f..0000000 --- a/bin/groot +++ /dev/null @@ -1,242 +0,0 @@ -#!/bin/bash -# -# This script is the simplified and portable version of arch-chroot -# (https://wiki.archlinux.org/index.php/Change_root#Using_arch-chroot) -# - -set -e - -# JUNEST_BASE can be overridden for testing purposes. -# There is no need for doing it for normal usage. -JUNEST_BASE="${JUNEST_BASE:-$(readlink -f $(dirname $(readlink -f "$0"))/..)}" -NAME='GRoot' -CMD='groot' -DESCRIPTION="I am $NAME!" -CHROOTCMD=${CHROOTCMD:-chroot} -SHELL="/bin/sh" -MOUNT=mount -UMOUNT=umount -MKDIR=mkdir -TOUCH=touch -CUT=cut -SORT=sort -UNIQ=uniq -CAT=cat -READLINK=readlink -MOUNTS_FILE=/proc/self/mounts - -NOT_EXISTING_FILE=103 -NOT_ABSOLUTE_PATH=111 -NO_ROOT_PRIVILEGES=110 - -source "${JUNEST_BASE}/lib/utils/utils.sh" - - -################################ MAIN FUNCTIONS ########################### - -function is_mountpoint() { - local mountpoint="$1" - for mp in $($CAT $MOUNTS_FILE | $CUT -f2 -d' ' | $SORT -r | $UNIQ) - do - [[ $mp == $mountpoint ]] && return 0 - done - return 1 -} - -function chroot_teardown() { - # Remove all mounts starting from the most nested ones. - # Suffix the CHROOTDIR with / to avoid umounting directories not belonging - # to CHROOTDIR. - local normalized_chrootdir="$($READLINK -f ${CHROOTDIR})/" - local final_res=0 - for mp in $($CAT $MOUNTS_FILE | $CUT -f2 -d' ' | $SORT -r | $UNIQ) - do - if [[ $mp =~ ^${normalized_chrootdir}.* ]] && is_mountpoint "$mp" - then - $UMOUNT $mp || final_res=$? - fi - done - $UMOUNT ${CHROOTDIR%/} - - return $final_res -} - -function chroot_maybe_add_mount() { - local cond=$1 - shift - if eval "$cond"; then - $MOUNT "$@" - return - fi - return 1 -} - -function chroot_setup() { - $OPT_NO_UMOUNT || check_and_trap 'chroot_teardown' QUIT EXIT ABRT KILL TERM INT - - if ! chroot_maybe_add_mount "! is_mountpoint '$CHROOTDIR'" --bind "$CHROOTDIR" "$CHROOTDIR" - then - warn "Failed mount of directories. $CHROOTDIR is already a mountpoint. Skipping it..." - return 0 - fi - - local re='(.*):(.*)' - for binds in ${BINDINGS[@]} - do - local host_path="" - local guest_path="" - if [[ $binds =~ $re ]] - then - local host_path="${BASH_REMATCH[1]}" - local guest_path="${BASH_REMATCH[2]}" - else - local host_path="$binds" - local guest_path="$binds" - fi - - create_node "${host_path}" "${CHROOTDIR}${guest_path}" - mount_directory "${host_path}" "${guest_path}" - done -} - -function mount_directory() { - local host_path=$($READLINK -f "$1") - local guest_path="$2" - - if ! $OPT_AVOID_BIND - then - $MOUNT $OPT_BIND "${host_path}" "${CHROOTDIR}${guest_path}" - return 0 - fi - - case "$host_path" in - /proc) $MOUNT proc "${CHROOTDIR}${guest_path}" -t proc ;; - /sys) $MOUNT sys "${CHROOTDIR}${guest_path}" -t sysfs ;; - /dev) $MOUNT udev "${CHROOTDIR}${guest_path}" -t devtmpfs; $MOUNT devpts "${guest_path}/pts" -t devpts; $MOUNT shm "${guest_path}/shm" -t tmpfs ;; - /run) $MOUNT run "${CHROOTDIR}${guest_path}" -t tmpfs ;; - /tmp) $MOUNT tmp "${CHROOTDIR}${guest_path}" -t tmpfs ;; - *) $MOUNT $OPT_BIND "${host_path}" "${CHROOTDIR}${guest_path}" ;; - esac - - return 0 -} - -function create_node() { - local src="$1" - local dst="$2" - if [[ ! -e $src ]] - then - die_on_status $NOT_EXISTING_FILE "${src} does not exist." - elif [[ $src != /* ]] - then - die_on_status $NOT_ABSOLUTE_PATH "${src} is not an absolute path." - elif [[ -f $src ]] - then - $TOUCH "$dst" - elif [[ -d $src ]] - then - $MKDIR -p "$dst" - fi -} - -function usage() { - cat < [command]] - -Options: - -b, --bind - Make the content of accessible in the guest rootfs. - - This option makes any file or directory of the host rootfs - accessible in the confined environment just as if it were part of - the guest rootfs. By default the host path is bound to the same - path in the guest rootfs but users can specify any other location - with the syntax: -b :. This option can - be invoked multiple times and the paths specified must be absolutes. - - -n, --no-umount - Do not umount after chroot session finished. - - -r, --recursive - Use rbind instead of bind. - - -i, --avoid-bind - Attempt to avoid mount --bind for common directories and use - proper mount fstype instead. Detected directories with - corresponding fstype are: /proc (proc), /sys (sysfs), - /dev (devtmpfs), /tmp (tmpfs), /run (tmpfs). - - -h, --help Print this help message - - -V, --version Show the $NAME version - -If 'command' is unspecified, $CMD will launch $SHELL. - -EOF -} - -version() { - echo -e "$NAME $(cat $JUNEST_BASE/VERSION)" -} - -function parse_arguments() { - BINDINGS=() - OPT_NO_UMOUNT=false - OPT_RECURSIVE=false - OPT_BIND="--bind" - OPT_AVOID_BIND=false - OPT_HELP=false - OPT_VERSION=false - for opt in "$@" - do - case "$1" in - -b|--bind) shift ; BINDINGS+=("$1") ; shift ;; - -n|--no-umount) OPT_NO_UMOUNT=true ; shift ;; - -r|--recursive) OPT_BIND="--rbind" ; shift ;; - -i|--avoid-bind) OPT_AVOID_BIND=true ; shift ;; - -h|--help) OPT_HELP=true ; shift ;; - -V|--version) OPT_VERSION=true ; shift ;; - -*) die "Invalid option $1" ;; - *) break ;; - esac - done - - if [[ ! -z $1 ]] - then - CHROOTDIR="$1" - shift - fi - ARGS=() - for arg in "$@" - do - ARGS+=("$arg") - done -} - -function is_user_root() { - (( EUID == 0 )) -} - -function execute_operation() { - $OPT_HELP && usage && return - $OPT_VERSION && version && return - - is_user_root || die_on_status $NO_ROOT_PRIVILEGES 'This script must be run with root privileges' - - [[ -d $CHROOTDIR ]] || die_on_status $NOT_EXISTING_FILE "Can't create chroot on non-directory $CHROOTDIR" - - chroot_setup "$CHROOTDIR" || die "Failed to setup chroot $CHROOTDIR" - - $CHROOTCMD "$CHROOTDIR" "${ARGS[@]}" -} - - -function main() { - parse_arguments "$@" - execute_operation -} - -main "$@" diff --git a/tests/unit-tests/test-groot.sh b/tests/unit-tests/test-groot.sh deleted file mode 100755 index 5fb2580..0000000 --- a/tests/unit-tests/test-groot.sh +++ /dev/null @@ -1,248 +0,0 @@ -#!/bin/bash -source "$(dirname $0)/../utils/utils.sh" - -JUNEST_BASE="$(readlink -f $(dirname $(readlink -f "$0"))/../..)" - -# Disable the exiterr -set +e - -function oneTimeSetUp(){ - setUpUnitTests -} - -function setUp(){ - # Attempt to source the files under test to revert variable overrides - source $JUNEST_BASE/bin/groot -h &> /dev/null - set +e - - cwdSetUp - mkdir -p chrootdir - - init_mocks -} - -function tearDown(){ - cwdTearDown -} - -## Mock functions ## -function init_mocks() { - function usage(){ - echo "usage" - } - function is_user_root() { - return 0 - } - function chroot() { - echo "chroot($@)" - } - function mountpoint() { - echo "mountpoint($@)" - # As default suppose the mountpoint does not exist - return 1 - } - function mountpoint_mock() { - echo "mountpoint($@)" - } - function mount() { - echo "mount($@)" - } - function umount() { - echo "umount($@)" - } - function check_and_trap() { - echo "check_and_trap($@)" - } - - # As default suppose the mountpoint "chrootdir" does not exist - echo -e "1 /home/mychroot/dev\n" > ./mounts - MOUNTS_FILE=./mounts -} - -function test_help(){ - assertCommandSuccess main -h - assertEquals "usage" "$(cat $STDOUTF)" - assertCommandSuccess main --help - assertEquals "usage" "$(cat $STDOUTF)" -} -function test_version(){ - assertCommandSuccess main -V - assertEquals "$NAME $(cat $JUNEST_BASE/VERSION)" "$(cat $STDOUTF)" - assertCommandSuccess main --version - assertEquals "$NAME $(cat $JUNEST_BASE/VERSION)" "$(cat $STDOUTF)" -} -function test_groot_no_root(){ - is_user_root() { - return 1 - } - assertCommandFailOnStatus $NO_ROOT_PRIVILEGES main -} -function test_groot_no_directory(){ - assertCommandFailOnStatus $NOT_EXISTING_FILE main no-directory -} -function test_groot_mountpoint_exist(){ - echo -e "1 /home/mychroot/dev\n1 chrootdir\n" > ./mounts - MOUNTS_FILE=./mounts - assertCommandSuccess main chrootdir - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} -function test_groot_mountpoint_does_not_exist(){ - assertCommandSuccess main chrootdir - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} -function test_groot_with_bind(){ - assertCommandSuccess main -b /tmp chrootdir - [[ -d chrootdir/tmp ]] - assertEquals 0 $? - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nmount(--bind /tmp chrootdir/tmp)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} -function test_groot_with_bind_file(){ - touch file_src - assertCommandSuccess main -b ${PWD}/file_src:/file_src chrootdir - [[ -f chrootdir/file_src ]] - assertEquals 0 $? - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nmount(--bind ${PWD}/file_src chrootdir/file_src)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} -function test_groot_with_bind_not_existing_node(){ - assertCommandFailOnStatus $NOT_EXISTING_FILE main -b ${PWD}/file_src:/file_src chrootdir - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)")" "$(cat $STDOUTF)" -} -function test_groot_with_bind_not_absolute_path_node(){ - touch file_src - assertCommandFailOnStatus $NOT_ABSOLUTE_PATH main -b file_src:/file_src chrootdir - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)")" "$(cat $STDOUTF)" -} -function test_groot_with_bind_guest_host(){ - assertCommandSuccess main -b /tmp:/home/tmp chrootdir - [[ -d chrootdir/home/tmp ]] - assertEquals 0 $? - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nmount(--bind /tmp chrootdir/home/tmp)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} -function test_groot_with_multiple_bind(){ - assertCommandSuccess main -b /tmp:/home/tmp -b /dev chrootdir - [[ -d chrootdir/home/tmp ]] - assertEquals 0 $? - [[ -d chrootdir/dev ]] - assertEquals 0 $? - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nmount(--bind /tmp chrootdir/home/tmp)\nmount(--bind /dev chrootdir/dev)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} -function test_groot_with_command(){ - assertCommandSuccess main chrootdir ls -la -h - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nchroot(chrootdir ls -la -h)")" "$(cat $STDOUTF)" -} -function test_groot_with_bind_and_command(){ - assertCommandSuccess main -b /tmp:/home/tmp -b /dev chrootdir ls -la -h - [[ -d chrootdir/home/tmp ]] - assertEquals 0 $? - [[ -d chrootdir/dev ]] - assertEquals 0 $? - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nmount(--bind /tmp chrootdir/home/tmp)\nmount(--bind /dev chrootdir/dev)\nchroot(chrootdir ls -la -h)")" "$(cat $STDOUTF)" -} -function test_groot_with_bind_no_umount(){ - assertCommandSuccess main -n chrootdir - assertEquals "$(echo -e "mount(--bind chrootdir chrootdir)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} -function test_groot_with_chroot_teardown(){ - echo -e "1 /home/mychroot/dev\n1 /home/mychroot/proc/fs1\n1 /home/mychroot\n1 /home/mychroot-no/dev\n1 /home/mychroot/dev/shm\n1 /home/mychroot/proc\n" > ./mounts - MOUNTS_FILE=./mounts - CHROOTDIR=/home/mychroot assertCommandSuccess chroot_teardown - assertEquals "$(echo -e "umount(/home/mychroot/proc/fs1) -umount(/home/mychroot/proc) -umount(/home/mychroot/dev/shm) -umount(/home/mychroot/dev) -umount(/home/mychroot)")" "$(cat $STDOUTF)" -} - -function test_groot_with_chroot_teardown_umount_failure(){ - function umount() { - echo "umount($@)" - [[ "$1" == "/home/mychroot/dev/shm" ]] && return 128 - return 0 - } - UMOUNT=umount - echo -e "1 /home/mychroot/dev\n1 /home/mychroot/proc/fs1\n1 /home/mychroot\n1 /home/mychroot-no/dev\n1 /home/mychroot/dev/shm\n1 /home/mychroot/proc\n" > ./mounts - MOUNTS_FILE=./mounts - CHROOTDIR=/home/mychroot assertCommandFailOnStatus 128 chroot_teardown - assertEquals "$(echo -e "umount(/home/mychroot/proc/fs1) -umount(/home/mychroot/proc) -umount(/home/mychroot/dev/shm) -umount(/home/mychroot/dev) -umount(/home/mychroot)")" "$(cat $STDOUTF)" -} -function test_groot_with_chroot_teardown_with_trailing_slash(){ - echo -e "1 /home/mychroot/dev\n1 /home/mychroot/proc/fs1\n1 /home/mychroot\n1 /home/mychroot-no/dev\n1 /home/mychroot/dev/shm\n1 /home/mychroot/proc\n" > ./mounts - MOUNTS_FILE=./mounts - CHROOTDIR=/home/mychroot assertCommandSuccess chroot_teardown - assertEquals "$(echo -e "umount(/home/mychroot/proc/fs1) -umount(/home/mychroot/proc) -umount(/home/mychroot/dev/shm) -umount(/home/mychroot/dev) -umount(/home/mychroot)")" "$(cat $STDOUTF)" -} -function test_groot_with_chroot_teardown_mountpoint_failure(){ - is_mountpoint() { - [[ $1 == "/home/mychroot/dev/shm" ]] && return 128 - return 0 - } - echo -e "1 /home/mychroot/dev\n1 /home/mychroot/proc/fs1\n1 /home/mychroot\n1 /home/mychroot-no/dev\n1 /home/mychroot/dev/shm\n1 /home/mychroot/proc\n" > ./mounts - MOUNTS_FILE=./mounts - CHROOTDIR=/home/mychroot assertCommandSuccess chroot_teardown - assertEquals "$(echo -e "umount(/home/mychroot/proc/fs1) -umount(/home/mychroot/proc) -umount(/home/mychroot/dev) -umount(/home/mychroot)")" "$(cat $STDOUTF)" -} - -function test_groot_with_rbind(){ - assertCommandSuccess main -r -b /tmp chrootdir - [[ -d chrootdir/tmp ]] - assertEquals 0 $? - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nmount(--rbind /tmp chrootdir/tmp)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} - -function test_groot_with_avoid_bind_proc(){ - assertCommandSuccess main -i -b /proc chrootdir - [[ -d chrootdir/proc ]] - assertEquals 0 $? - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nmount(proc chrootdir/proc -t proc)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} - -function test_groot_with_avoid_bind_dev(){ - assertCommandSuccess main -i -b /dev chrootdir - [[ -d chrootdir/dev ]] - assertEquals 0 $? - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nmount(udev chrootdir/dev -t devtmpfs)\nmount(devpts /dev/pts -t devpts)\nmount(shm /dev/shm -t tmpfs)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} - -function test_groot_with_avoid_bind_sys(){ - assertCommandSuccess main -i -b /sys chrootdir - [[ -d chrootdir/sys ]] - assertEquals 0 $? - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nmount(sys chrootdir/sys -t sysfs)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} - -function test_groot_with_avoid_bind_run(){ - assertCommandSuccess main -i -b /run chrootdir - [[ -d chrootdir/run ]] - assertEquals 0 $? - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nmount(run chrootdir/run -t tmpfs)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} - -function test_groot_with_avoid_bind_tmp(){ - assertCommandSuccess main -i -b /tmp chrootdir - [[ -d chrootdir/tmp ]] - assertEquals 0 $? - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nmount(tmp chrootdir/tmp -t tmpfs)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} - -function test_groot_with_avoid_bind_combined(){ - assertCommandSuccess main -i -b /tmp -b /usr chrootdir - cat $STDERRF - [[ -d chrootdir/tmp ]] - assertEquals 0 $? - [[ -d chrootdir/usr ]] - assertEquals 0 $? - assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmount(--bind chrootdir chrootdir)\nmount(tmp chrootdir/tmp -t tmpfs)\nmount(--bind /usr chrootdir/usr)\nchroot(chrootdir)")" "$(cat $STDOUTF)" -} - -source $(dirname $0)/../utils/shunit2 From 09b9c644d97589738aae4e69865a8db8082c2f51 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Fri, 27 Mar 2020 18:39:58 +0100 Subject: [PATCH 015/116] Add option to specify location of backend command --- bin/junest | 22 ++-- lib/core/chroot.sh | 22 ++-- lib/core/namespace.sh | 29 +++-- lib/core/proot.sh | 40 ++++--- tests/unit-tests/test-chroot.sh | 33 ++++-- tests/unit-tests/test-junest.sh | 182 +++++++++++++++++------------ tests/unit-tests/test-namespace.sh | 42 +++++-- tests/unit-tests/test-proot.sh | 51 ++++++-- 8 files changed, 273 insertions(+), 148 deletions(-) diff --git a/bin/junest b/bin/junest index 3b7eb87..17d32bc 100755 --- a/bin/junest +++ b/bin/junest @@ -39,22 +39,27 @@ usage() { echo -e " -d, --delete Delete $NAME from ${JUNEST_HOME}" echo echo -e " n[s] Access via Linux Namespaces using BubbleWrap (Default action)" + echo -e " -f, --fakeroot Run $NAME with fakeroot privileges" + echo -e " --backend-command Bwrap command to use" echo -e " -b, --backend-args Arguments for bwrap backend program" echo -e " ($CMD ns -b \"--help\" to check out the bwrap options)" echo -e " -n, --no-copy-files Do not copy common etc files into $NAME environment" echo echo -e " p[root] Access via PRoot" echo -e " -f, --fakeroot Run $NAME with fakeroot privileges" + echo -e " --backend-command PRoot command to use" echo -e " -b, --backend-args Arguments for PRoot backend program" echo -e " ($CMD proot -b \"--help\" to check out the PRoot options)" echo -e " -n, --no-copy-files Do not copy common etc files into $NAME environment" echo echo -e " g[root] Access with root privileges via GRoot" + echo -e " --backend-command GRoot command to use" echo -e " -b, --backend-args Arguments for GRoot backend program" echo -e " ($CMD groot -b \"--help\" to check out the GRoot options)" echo -e " -n, --no-copy-files Do not copy common etc files into $NAME environment" echo echo -e " r[oot] Access with root privileges via classic chroot" + echo -e " --backend-command Chroot command to use" echo -e " -b, --backend-args Arguments for chroot backend program" echo -e " ($CMD root -b \"--help\" to check out the chroot options)" echo -e " -n, --no-copy-files Do not copy common etc files into $NAME environment" @@ -114,15 +119,16 @@ function parse_arguments(){ function _parse_root_opts() { # Options: - OPT_BACKEND_ARGS=false BACKEND_ARGS="" OPT_NO_COPY_FILES=false + BACKEND_COMMAND="" while [[ -n "$1" ]] do case "$1" in - -b|--backend-args) OPT_BACKEND_ARGS=true ; shift ; BACKEND_ARGS=$1; shift ;; + -b|--backend-args) shift ; BACKEND_ARGS=$1; shift ;; -n|--no-copy-files) OPT_NO_COPY_FILES=true ; shift ;; + --backend-command) shift; BACKEND_COMMAND="$1"; shift ;; --) shift ; break ;; -*) die "Invalid option $1" ;; *) break ;; @@ -139,16 +145,17 @@ function _parse_root_opts() { function _parse_ns_opts() { # Options: OPT_FAKEROOT=false - OPT_BACKEND_ARGS=false BACKEND_ARGS="" OPT_NO_COPY_FILES=false + BACKEND_COMMAND="" while [[ -n "$1" ]] do case "$1" in -f|--fakeroot) OPT_FAKEROOT=true ; shift ;; - -b|--backend-args) OPT_BACKEND_ARGS=true ; shift ; BACKEND_ARGS=$1; shift ;; + -b|--backend-args) shift ; BACKEND_ARGS=$1; shift ;; -n|--no-copy-files) OPT_NO_COPY_FILES=true ; shift ;; + --backend-command) shift; BACKEND_COMMAND="$1"; shift ;; --) shift ; break ;; -*) die "Invalid option $1" ;; *) break ;; @@ -165,16 +172,17 @@ function _parse_ns_opts() { function _parse_proot_opts() { # Options: OPT_FAKEROOT=false - OPT_BACKEND_ARGS=false BACKEND_ARGS="" OPT_NO_COPY_FILES=false + BACKEND_COMMAND="" while [[ -n "$1" ]] do case "$1" in -f|--fakeroot) OPT_FAKEROOT=true ; shift ;; - -b|--backend-args) OPT_BACKEND_ARGS=true ; shift ; BACKEND_ARGS=$1; shift ;; + -b|--backend-args) shift ; BACKEND_ARGS=$1; shift ;; -n|--no-copy-files) OPT_NO_COPY_FILES=true ; shift ;; + --backend-command) shift; BACKEND_COMMAND="$1"; shift ;; --) shift ; break ;; -*) die "Invalid option $1" ;; *) break ;; @@ -269,7 +277,7 @@ function execute_operation() { run_env=run_env_as_chroot fi - $run_env "${BACKEND_ARGS}" $OPT_NO_COPY_FILES "${ARGS[@]}" + $run_env "$BACKEND_COMMAND" "${BACKEND_ARGS}" $OPT_NO_COPY_FILES "${ARGS[@]}" } diff --git a/lib/core/chroot.sh b/lib/core/chroot.sh index eb584f0..635137b 100644 --- a/lib/core/chroot.sh +++ b/lib/core/chroot.sh @@ -58,15 +58,18 @@ function _run_env_as_xroot(){ function run_env_as_groot(){ check_nested_env - local backend_args="$1" - local no_copy_files="$2" - shift 2 + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 + + [[ -z "$backend_command" ]] && backend_command="$GROOT" provide_common_bindings local bindings=${RESULT} unset RESULT - _run_env_as_xroot "$GROOT $bindings" "$backend_args" "$no_copy_files" "$@" + _run_env_as_xroot "$backend_command $bindings" "$backend_args" "$no_copy_files" "$@" } ####################################### @@ -92,9 +95,12 @@ function run_env_as_groot(){ function run_env_as_chroot(){ check_nested_env - local backend_args="$1" - local no_copy_files="$2" - shift 2 + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 - _run_env_as_xroot chroot_cmd "$backend_args" "$no_copy_files" "$@" + [[ -z "$backend_command" ]] && backend_command=chroot_cmd + + _run_env_as_xroot "$backend_command" "$backend_args" "$no_copy_files" "$@" } diff --git a/lib/core/namespace.sh b/lib/core/namespace.sh index 39080e0..1307de0 100644 --- a/lib/core/namespace.sh +++ b/lib/core/namespace.sh @@ -56,14 +56,17 @@ function _check_user_namespace() { } function _run_env_with_bwrap(){ - local backend_args="$1" - shift + local backend_command="$1" + local backend_args="$2" + shift 2 + + [[ -z "$backend_command" ]] && backend_command=bwrap_cmd if [[ "$1" != "" ]] then - JUNEST_ENV=1 bwrap_cmd --bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try ${backend_args} "${SH[@]}" "-c" "$(insert_quotes_on_spaces "${@}")" + JUNEST_ENV=1 "$backend_command" --bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try ${backend_args} "${SH[@]}" "-c" "$(insert_quotes_on_spaces "${@}")" else - JUNEST_ENV=1 bwrap_cmd --bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try ${backend_args} "${SH[@]}" + JUNEST_ENV=1 "$backend_command" --bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try ${backend_args} "${SH[@]}" fi } @@ -89,9 +92,10 @@ function _run_env_with_bwrap(){ function run_env_as_bwrap_fakeroot(){ check_nested_env - local backend_args="$1" - local no_copy_files="$2" - shift 2 + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 _check_user_namespace @@ -102,7 +106,7 @@ function run_env_as_bwrap_fakeroot(){ copy_common_files fi - _run_env_with_bwrap "--uid 0 $backend_args" "$@" + _run_env_with_bwrap "$backend_command" "--uid 0 $backend_args" "$@" } @@ -126,9 +130,10 @@ function run_env_as_bwrap_fakeroot(){ function run_env_as_bwrap_user() { check_nested_env - local backend_args="$1" - local no_copy_files="$2" - shift 2 + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 _check_user_namespace @@ -145,7 +150,7 @@ function run_env_as_bwrap_user() { copy_passwd_and_group fi - _run_env_with_bwrap "$backend_args" "$@" + _run_env_with_bwrap "$backend_command" "$backend_args" "$@" } diff --git a/lib/core/proot.sh b/lib/core/proot.sh index d2bfd5f..a1eee73 100644 --- a/lib/core/proot.sh +++ b/lib/core/proot.sh @@ -9,19 +9,25 @@ # vim: ft=sh function _run_env_with_proot(){ - local proot_args="$1" - shift + local backend_command="$1" + local backend_args="$2" + shift 2 + + [[ -z "$backend_command" ]] && backend_command=proot_cmd if [ "$1" != "" ] then - JUNEST_ENV=1 proot_cmd "${proot_args}" "${SH[@]}" "-c" "$(insert_quotes_on_spaces "${@}")" + JUNEST_ENV=1 "${backend_command}" "${backend_args}" "${SH[@]}" "-c" "$(insert_quotes_on_spaces "${@}")" else - JUNEST_ENV=1 proot_cmd "${proot_args}" "${SH[@]}" + JUNEST_ENV=1 "${backend_command}" "${backend_args}" "${SH[@]}" fi } function _run_env_with_qemu(){ - local proot_args="$1" + local backend_command="$1" + local backend_args="$2" + shift 2 + source ${JUNEST_HOME}/etc/junest/info if [ "$JUNEST_ARCH" != "$ARCH" ] @@ -34,10 +40,10 @@ function _run_env_with_qemu(){ warn "Emulating $NAME via QEMU..." [ -e ${qemu_symlink} ] || \ ln_cmd -s ${JUNEST_HOME}/bin/${qemu_bin} ${qemu_symlink} - proot_args="-q ${qemu_symlink} $proot_args" + backend_args="-q ${qemu_symlink} $backend_args" fi - shift - _run_env_with_proot "$proot_args" "${@}" + + _run_env_with_proot "$backend_args" "${@}" } ####################################### @@ -63,9 +69,10 @@ function run_env_as_proot_fakeroot(){ die_on_status $ROOT_ACCESS_ERROR "You cannot access with root privileges. Use --groot option instead." check_nested_env - local backend_args="$1" - local no_copy_files="$2" - shift 2 + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 if ! $no_copy_files then @@ -78,7 +85,7 @@ function run_env_as_proot_fakeroot(){ # An alternative is via -S option: #_run_env_with_qemu "-S ${JUNEST_HOME} $1" "${@:2}" - _run_env_with_qemu "-0 ${bindings} -r ${JUNEST_HOME} $backend_args" "$@" + _run_env_with_qemu "$backend_command" "-0 ${bindings} -r ${JUNEST_HOME} $backend_args" "$@" } ####################################### @@ -104,9 +111,10 @@ function run_env_as_proot_user(){ die_on_status $ROOT_ACCESS_ERROR "You cannot access with root privileges. Use --groot option instead." check_nested_env - local backend_args="$1" - local no_copy_files="$2" - shift 2 + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 if ! $no_copy_files then @@ -127,5 +135,5 @@ function run_env_as_proot_user(){ local bindings=${RESULT} unset RESULT - _run_env_with_qemu "${bindings} -r ${JUNEST_HOME} $backend_args" "$@" + _run_env_with_qemu "$backend_command" "${bindings} -r ${JUNEST_HOME} $backend_args" "$@" } diff --git a/tests/unit-tests/test-chroot.sh b/tests/unit-tests/test-chroot.sh index b2e5e70..4556671 100755 --- a/tests/unit-tests/test-chroot.sh +++ b/tests/unit-tests/test-chroot.sh @@ -32,20 +32,28 @@ function init_mocks() { echo "chroot_cmd $@" } GROOT=chroot_cmd + mychroot() { + echo mychroot $@ + } } function test_run_env_as_groot_cmd(){ - assertCommandSuccess run_env_as_groot "" "false" pwd + assertCommandSuccess run_env_as_groot "" "" "false" pwd assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)" } function test_run_env_as_groot_no_cmd(){ - assertCommandSuccess run_env_as_groot "" "false" "" + assertCommandSuccess run_env_as_groot "" "" "false" "" assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c /bin/sh --login" "$(cat $STDOUTF)" } +function test_run_env_as_groot_with_backend_command(){ + assertCommandSuccess run_env_as_groot "mychroot" "" "false" "" + assertEquals "mychroot -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c /bin/sh --login" "$(cat $STDOUTF)" +} + function test_run_env_as_groot_no_copy(){ - assertCommandSuccess run_env_as_groot "" "true" pwd + assertCommandSuccess run_env_as_groot "" "" "true" pwd assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] @@ -60,27 +68,32 @@ function test_run_env_as_groot_no_copy(){ function test_run_env_as_groot_nested_env(){ JUNEST_ENV=1 - assertCommandFailOnStatus 106 run_env_as_groot "" "false" "" + assertCommandFailOnStatus 106 run_env_as_groot "" "" "false" "" unset JUNEST_ENV } function test_run_env_as_groot_cmd_with_backend_args(){ - assertCommandSuccess run_env_as_groot "-n -b /home/blah" "false" pwd + assertCommandSuccess run_env_as_groot "" "-n -b /home/blah" "false" pwd assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev -n -b /home/blah $JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)" } function test_run_env_as_chroot_cmd(){ - assertCommandSuccess run_env_as_chroot "" "false" pwd + assertCommandSuccess run_env_as_chroot "" "" "false" pwd assertEquals "chroot_cmd $JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)" } function test_run_env_as_chroot_no_cmd(){ - assertCommandSuccess run_env_as_chroot "" "false" "" + assertCommandSuccess run_env_as_chroot "" "" "false" "" assertEquals "chroot_cmd $JUNEST_HOME /bin/sh --login -c /bin/sh --login" "$(cat $STDOUTF)" } +function test_run_env_as_chroot_with_backend_command(){ + assertCommandSuccess run_env_as_chroot "mychroot" "" "false" "" + assertEquals "mychroot $JUNEST_HOME /bin/sh --login -c /bin/sh --login" "$(cat $STDOUTF)" +} + function test_run_env_as_chroot_no_copy(){ - assertCommandSuccess run_env_as_chroot "" "true" pwd + assertCommandSuccess run_env_as_chroot "" "" "true" pwd assertEquals "chroot_cmd $JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] @@ -95,12 +108,12 @@ function test_run_env_as_chroot_no_copy(){ function test_run_env_as_choot_nested_env(){ JUNEST_ENV=1 - assertCommandFailOnStatus 106 run_env_as_chroot "" "false" "" + assertCommandFailOnStatus 106 run_env_as_chroot "" "" "false" "" unset JUNEST_ENV } function test_run_env_as_chroot_cmd_with_backend_args(){ - assertCommandSuccess run_env_as_chroot "-n -b /home/blah" "false" pwd + assertCommandSuccess run_env_as_chroot "" "-n -b /home/blah" "false" pwd assertEquals "chroot_cmd -n -b /home/blah $JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)" } diff --git a/tests/unit-tests/test-junest.sh b/tests/unit-tests/test-junest.sh index db7d184..e3c7ee1 100755 --- a/tests/unit-tests/test-junest.sh +++ b/tests/unit-tests/test-junest.sh @@ -38,40 +38,46 @@ function setup_env(){ echo "setup_env($1)" } function run_env_as_proot_fakeroot(){ - local backend_args="$1" - local no_copy_files="$2" - shift 2 - echo "run_env_as_proot_fakeroot($backend_args,$no_copy_files,$@)" + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 + echo "run_env_as_proot_fakeroot($backend_command,$backend_args,$no_copy_files,$@)" } function run_env_as_groot(){ - local backend_args="$1" - local no_copy_files="$2" - shift 2 - echo "run_env_as_groot($backend_args,$no_copy_files,$@)" + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 + echo "run_env_as_groot($backend_command,$backend_args,$no_copy_files,$@)" } function run_env_as_chroot(){ - local backend_args="$1" - local no_copy_files="$2" - shift 2 - echo "run_env_as_chroot($backend_args,$no_copy_files,$@)" + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 + echo "run_env_as_chroot($backend_command,$backend_args,$no_copy_files,$@)" } function run_env_as_proot_user(){ - local backend_args="$1" - local no_copy_files="$2" - shift 2 - echo "run_env_as_proot_user($backend_args,$no_copy_files,$@)" + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 + echo "run_env_as_proot_user($backend_command,$backend_args,$no_copy_files,$@)" } function run_env_as_bwrap_fakeroot(){ - local backend_args="$1" - local no_copy_files="$2" - shift 2 - echo "run_env_as_bwrap_fakeroot($backend_args,$no_copy_files,$@)" + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 + echo "run_env_as_bwrap_fakeroot($backend_command,$backend_args,$no_copy_files,$@)" } function run_env_as_bwrap_user(){ - local backend_args="$1" - local no_copy_files="$2" - shift 2 - echo "run_env_as_bwrap_user($backend_args,$no_copy_files,$@)" + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 + echo "run_env_as_bwrap_user($backend_command,$backend_args,$no_copy_files,$@)" } function test_help(){ @@ -139,20 +145,25 @@ function test_setup_env(){ function test_run_env_as_proot_fakeroot(){ assertCommandSuccess main p -f - assertEquals "run_env_as_proot_fakeroot(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main proot --fakeroot - assertEquals "run_env_as_proot_fakeroot(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main p -f -n - assertEquals "run_env_as_proot_fakeroot(,true,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,,true,)" "$(cat $STDOUTF)" + + assertCommandSuccess main p -f --backend-command blah + assertEquals "run_env_as_proot_fakeroot(blah,,false,)" "$(cat $STDOUTF)" + assertCommandSuccess main proot -f --backend-command blah + assertEquals "run_env_as_proot_fakeroot(blah,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main proot -f -b "-b arg" - assertEquals "run_env_as_proot_fakeroot(-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,-b arg,false,)" "$(cat $STDOUTF)" assertCommandSuccess main proot -f -b "-b arg" -- command -kv - assertEquals "run_env_as_proot_fakeroot(-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,-b arg,false,command -kv)" "$(cat $STDOUTF)" assertCommandSuccess main proot -f command --as - assertEquals "run_env_as_proot_fakeroot(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,,false,command --as)" "$(cat $STDOUTF)" assertCommandSuccess main proot -f -- command --as - assertEquals "run_env_as_proot_fakeroot(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,,false,command --as)" "$(cat $STDOUTF)" is_env_installed(){ return 1 @@ -162,18 +173,23 @@ function test_run_env_as_proot_fakeroot(){ function test_run_env_as_user(){ assertCommandSuccess main proot - assertEquals "run_env_as_proot_user(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main p -n - assertEquals "run_env_as_proot_user(,true,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,,true,)" "$(cat $STDOUTF)" + + assertCommandSuccess main p --backend-command blah + assertEquals "run_env_as_proot_user(blah,,false,)" "$(cat $STDOUTF)" + assertCommandSuccess main proot --backend-command blah + assertEquals "run_env_as_proot_user(blah,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main proot -b "-b arg" - assertEquals "run_env_as_proot_user(-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,-b arg,false,)" "$(cat $STDOUTF)" assertCommandSuccess main proot -b "-b arg" -- command -ll - assertEquals "run_env_as_proot_user(-b arg,false,command -ll)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,-b arg,false,command -ll)" "$(cat $STDOUTF)" assertCommandSuccess main proot command -ls - assertEquals "run_env_as_proot_user(,false,command -ls)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,,false,command -ls)" "$(cat $STDOUTF)" assertCommandSuccess main proot -- command -ls - assertEquals "run_env_as_proot_user(,false,command -ls)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,,false,command -ls)" "$(cat $STDOUTF)" is_env_installed(){ return 1 @@ -183,15 +199,21 @@ function test_run_env_as_user(){ function test_run_env_as_groot(){ assertCommandSuccess main g - assertEquals "run_env_as_groot(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_groot(,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main g -n - assertEquals "run_env_as_groot(,true,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_groot(,,true,)" "$(cat $STDOUTF)" assertCommandSuccess main g -b "-b arg" - assertEquals "run_env_as_groot(-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_groot(,-b arg,false,)" "$(cat $STDOUTF)" + + assertCommandSuccess main g --backend-command blah + assertEquals "run_env_as_groot(blah,,false,)" "$(cat $STDOUTF)" + assertCommandSuccess main groot --backend-command blah + assertEquals "run_env_as_groot(blah,,false,)" "$(cat $STDOUTF)" + assertCommandSuccess main groot command - assertEquals "run_env_as_groot(,false,command)" "$(cat $STDOUTF)" + assertEquals "run_env_as_groot(,,false,command)" "$(cat $STDOUTF)" assertCommandSuccess main groot -- command - assertEquals "run_env_as_groot(,false,command)" "$(cat $STDOUTF)" + assertEquals "run_env_as_groot(,,false,command)" "$(cat $STDOUTF)" is_env_installed(){ return 1 @@ -201,13 +223,19 @@ function test_run_env_as_groot(){ function test_run_env_as_chroot(){ assertCommandSuccess main r - assertEquals "run_env_as_chroot(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_chroot(,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main r -b "-b arg" - assertEquals "run_env_as_chroot(-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_chroot(,-b arg,false,)" "$(cat $STDOUTF)" + + assertCommandSuccess main r --backend-command blah + assertEquals "run_env_as_chroot(blah,,false,)" "$(cat $STDOUTF)" + assertCommandSuccess main root --backend-command blah + assertEquals "run_env_as_chroot(blah,,false,)" "$(cat $STDOUTF)" + assertCommandSuccess main root command - assertEquals "run_env_as_chroot(,false,command)" "$(cat $STDOUTF)" + assertEquals "run_env_as_chroot(,,false,command)" "$(cat $STDOUTF)" assertCommandSuccess main root -- command - assertEquals "run_env_as_chroot(,false,command)" "$(cat $STDOUTF)" + assertEquals "run_env_as_chroot(,,false,command)" "$(cat $STDOUTF)" is_env_installed(){ return 1 @@ -217,34 +245,39 @@ function test_run_env_as_chroot(){ function test_run_env_as_bwrap_fakeroot(){ assertCommandSuccess main n -f - assertEquals "run_env_as_bwrap_fakeroot(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main ns -f - assertEquals "run_env_as_bwrap_fakeroot(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main ns -n -f - assertEquals "run_env_as_bwrap_fakeroot(,true,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,true,)" "$(cat $STDOUTF)" assertCommandSuccess main ns -f -b "-b arg" - assertEquals "run_env_as_bwrap_fakeroot(-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,-b arg,false,)" "$(cat $STDOUTF)" assertCommandSuccess main ns -f -b "-b arg" -- command -kv - assertEquals "run_env_as_bwrap_fakeroot(-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,-b arg,false,command -kv)" "$(cat $STDOUTF)" assertCommandSuccess main ns -f command --as - assertEquals "run_env_as_bwrap_fakeroot(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,command --as)" "$(cat $STDOUTF)" assertCommandSuccess main ns -f -- command --as - assertEquals "run_env_as_bwrap_fakeroot(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,command --as)" "$(cat $STDOUTF)" + + assertCommandSuccess main ns -f --backend-command blah + assertEquals "run_env_as_bwrap_fakeroot(blah,,false,)" "$(cat $STDOUTF)" + assertCommandSuccess main -f --backend-command blah + assertEquals "run_env_as_bwrap_fakeroot(blah,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main -f - assertEquals "run_env_as_bwrap_fakeroot(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main -f - assertEquals "run_env_as_bwrap_fakeroot(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main -f -b "-b arg" - assertEquals "run_env_as_bwrap_fakeroot(-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,-b arg,false,)" "$(cat $STDOUTF)" assertCommandSuccess main -f -b "-b arg" -- command -kv - assertEquals "run_env_as_bwrap_fakeroot(-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,-b arg,false,command -kv)" "$(cat $STDOUTF)" assertCommandSuccess main -f command --as - assertEquals "run_env_as_bwrap_fakeroot(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,command --as)" "$(cat $STDOUTF)" assertCommandSuccess main -f -- command --as - assertEquals "run_env_as_bwrap_fakeroot(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,command --as)" "$(cat $STDOUTF)" is_env_installed(){ return 1 @@ -254,34 +287,39 @@ function test_run_env_as_bwrap_fakeroot(){ function test_run_env_as_bwrap_user(){ assertCommandSuccess main n - assertEquals "run_env_as_bwrap_user(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main ns - assertEquals "run_env_as_bwrap_user(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main ns -n - assertEquals "run_env_as_bwrap_user(,true,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,true,)" "$(cat $STDOUTF)" assertCommandSuccess main ns -b "-b arg" - assertEquals "run_env_as_bwrap_user(-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,-b arg,false,)" "$(cat $STDOUTF)" assertCommandSuccess main ns -b "-b arg" -- command -kv - assertEquals "run_env_as_bwrap_user(-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,-b arg,false,command -kv)" "$(cat $STDOUTF)" assertCommandSuccess main ns command --as - assertEquals "run_env_as_bwrap_user(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,command --as)" "$(cat $STDOUTF)" assertCommandSuccess main ns -- command --as - assertEquals "run_env_as_bwrap_user(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,command --as)" "$(cat $STDOUTF)" + + assertCommandSuccess main ns --backend-command blah + assertEquals "run_env_as_bwrap_user(blah,,false,)" "$(cat $STDOUTF)" + assertCommandSuccess main --backend-command blah + assertEquals "run_env_as_bwrap_user(blah,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main - assertEquals "run_env_as_bwrap_user(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main - assertEquals "run_env_as_bwrap_user(,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,)" "$(cat $STDOUTF)" assertCommandSuccess main -b "-b arg" - assertEquals "run_env_as_bwrap_user(-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,-b arg,false,)" "$(cat $STDOUTF)" assertCommandSuccess main -b "-b arg" -- command -kv - assertEquals "run_env_as_bwrap_user(-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,-b arg,false,command -kv)" "$(cat $STDOUTF)" assertCommandSuccess main command --as - assertEquals "run_env_as_bwrap_user(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,command --as)" "$(cat $STDOUTF)" assertCommandSuccess main -- command --as - assertEquals "run_env_as_bwrap_user(,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,command --as)" "$(cat $STDOUTF)" is_env_installed(){ return 1 diff --git a/tests/unit-tests/test-namespace.sh b/tests/unit-tests/test-namespace.sh index 03eb1cd..9efbad3 100755 --- a/tests/unit-tests/test-namespace.sh +++ b/tests/unit-tests/test-namespace.sh @@ -18,6 +18,9 @@ function init_mocks() { function bwrap_cmd(){ echo "bwrap $@" } + function mybwrap(){ + echo "mybwrap $@" + } } function setUp(){ @@ -100,22 +103,37 @@ function test_is_user_namespace_enabled_with_userns_clone_file_enabled(){ } function test_run_env_as_bwrap_fakeroot() { - assertCommandSuccess run_env_as_bwrap_fakeroot "" "false" + assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } +function test_run_env_as_bwrap_fakeroot_with_backend_command() { + assertCommandSuccess run_env_as_bwrap_fakeroot "mybwrap" "" "false" + assertEquals "mybwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 /bin/sh --login" "$(cat $STDOUTF)" + + _test_copy_common_files +} + function test_run_env_as_bwrap_user() { - assertCommandSuccess run_env_as_bwrap_user "" "false" + assertCommandSuccess run_env_as_bwrap_user "" "" "false" assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files } +function test_run_env_as_bwrap_user_with_backend_command() { + assertCommandSuccess run_env_as_bwrap_user "mybwrap" "" "false" + assertEquals "mybwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try /bin/sh --login" "$(cat $STDOUTF)" + + _test_copy_common_files + _test_copy_remaining_files +} + function test_run_env_as_bwrap_fakeroot_no_copy() { - assertCommandSuccess run_env_as_bwrap_fakeroot "" "true" "" + assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "true" "" assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 /bin/sh --login" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] @@ -141,7 +159,7 @@ function test_run_env_as_bwrap_fakeroot_no_copy() { } function test_run_env_as_bwrap_user_no_copy() { - assertCommandSuccess run_env_as_bwrap_user "" "true" "" + assertCommandSuccess run_env_as_bwrap_user "" "" "true" "" assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try /bin/sh --login" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] @@ -167,14 +185,14 @@ function test_run_env_as_bwrap_user_no_copy() { } function test_run_env_as_bwrap_fakeroot_with_backend_args() { - assertCommandSuccess run_env_as_bwrap_fakeroot "--bind /usr /usr" "false" + assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --bind /usr /usr /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_user_with_backend_args() { - assertCommandSuccess run_env_as_bwrap_user "--bind /usr /usr" "false" + assertCommandSuccess run_env_as_bwrap_user "" "--bind /usr /usr" "false" assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --bind /usr /usr /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files @@ -182,14 +200,14 @@ function test_run_env_as_bwrap_user_with_backend_args() { } function test_run_env_as_bwrap_fakeroot_with_command() { - assertCommandSuccess run_env_as_bwrap_fakeroot "" "false" "ls -la" + assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" "ls -la" assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_user_with_command() { - assertCommandSuccess run_env_as_bwrap_user "" "false" "ls -la" + assertCommandSuccess run_env_as_bwrap_user "" "" "false" "ls -la" assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files @@ -197,14 +215,14 @@ function test_run_env_as_bwrap_user_with_command() { } function test_run_env_as_bwrap_fakeroot_with_backend_args_and_command() { - assertCommandSuccess run_env_as_bwrap_fakeroot "--bind /usr /usr" "false" "ls -la" + assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" "ls -la" assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --bind /usr /usr /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_user_with_backend_args_and_command() { - assertCommandSuccess run_env_as_bwrap_user "--bind /usr /usr" "false" "ls -la" + assertCommandSuccess run_env_as_bwrap_user "" "--bind /usr /usr" "false" "ls -la" assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --bind /usr /usr /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files @@ -213,13 +231,13 @@ function test_run_env_as_bwrap_user_with_backend_args_and_command() { function test_run_env_as_bwrap_fakeroot_nested_env(){ JUNEST_ENV=1 - assertCommandFailOnStatus 106 run_env_as_bwrap_fakeroot "" "false" "" + assertCommandFailOnStatus 106 run_env_as_bwrap_fakeroot "" "" "false" "" unset JUNEST_ENV } function test_run_env_as_bwrap_user_nested_env(){ JUNEST_ENV=1 - assertCommandFailOnStatus 106 run_env_as_bwrap_user "" "false" "" + assertCommandFailOnStatus 106 run_env_as_bwrap_user "" "" "false" "" unset JUNEST_ENV } diff --git a/tests/unit-tests/test-proot.sh b/tests/unit-tests/test-proot.sh index 8fa636f..9e152f9 100755 --- a/tests/unit-tests/test-proot.sh +++ b/tests/unit-tests/test-proot.sh @@ -51,22 +51,37 @@ function test_run_env_as_proot_user(){ _run_env_with_qemu() { echo $@ } - assertCommandSuccess run_env_as_proot_user "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" + assertCommandSuccess run_env_as_proot_user "" "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" SH=("/usr/bin/echo") - assertCommandSuccess run_env_as_proot_user "-k 3.10" "false" + assertCommandSuccess run_env_as_proot_user "" "-k 3.10" "false" assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files } +function test_run_env_as_proot_user_with_backend_command(){ + _run_env_with_qemu() { + echo $@ + } + assertCommandSuccess run_env_as_proot_user "myproot" "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" + assertEquals "myproot -b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" + + SH=("/usr/bin/echo") + assertCommandSuccess run_env_as_proot_user "myproot" "-k 3.10" "false" + assertEquals "myproot -b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat $STDOUTF)" + + _test_copy_common_files + _test_copy_remaining_files +} + function test_run_env_as_proot_user_no_copy(){ _run_env_with_qemu() { echo $@ } - assertCommandSuccess run_env_as_proot_user "-k 3.10" "true" "/usr/bin/mkdir" "-v" "/newdir2" + assertCommandSuccess run_env_as_proot_user "" "-k 3.10" "true" "/usr/bin/mkdir" "-v" "/newdir2" assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] @@ -93,7 +108,7 @@ function test_run_env_as_proot_user_no_copy(){ function test_run_env_as_proot_user_nested_env(){ JUNEST_ENV=1 - assertCommandFailOnStatus 106 run_env_as_proot_user "" "false" + assertCommandFailOnStatus 106 run_env_as_proot_user "" "" "false" unset JUNEST_ENV } @@ -101,19 +116,33 @@ function test_run_env_as_proot_fakeroot(){ _run_env_with_qemu() { echo $@ } - assertCommandSuccess run_env_as_proot_fakeroot "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" + assertCommandSuccess run_env_as_proot_fakeroot "" "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" assertEquals "-0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" SH=("/usr/bin/echo") - assertCommandSuccess run_env_as_proot_fakeroot "-k 3.10" "false" + assertCommandSuccess run_env_as_proot_fakeroot "" "-k 3.10" "false" assertEquals "-0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat $STDOUTF)" _test_copy_common_files } +function test_run_env_as_proot_fakeroot_with_backend_command(){ + _run_env_with_qemu() { + echo $@ + } + assertCommandSuccess run_env_as_proot_fakeroot "myproot" "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" + assertEquals "myproot -0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" + + SH=("/usr/bin/echo") + assertCommandSuccess run_env_as_proot_fakeroot "myproot" "-k 3.10" "false" + assertEquals "myproot -0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat $STDOUTF)" + + _test_copy_common_files +} + function test_run_env_as_proot_fakeroot_nested_env(){ JUNEST_ENV=1 - assertCommandFailOnStatus 106 run_env_as_proot_fakeroot "" "false" "" + assertCommandFailOnStatus 106 run_env_as_proot_fakeroot "" "" "false" "" unset JUNEST_ENV } @@ -121,7 +150,7 @@ function test_run_env_with_quotes(){ _run_env_with_qemu() { echo $@ } - assertCommandSuccess run_env_as_proot_user "-k 3.10" "false" "bash" "-c" "/usr/bin/mkdir -v /newdir2" + assertCommandSuccess run_env_as_proot_user "" "-k 3.10" "false" "bash" "-c" "/usr/bin/mkdir -v /newdir2" assertEquals "-b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 bash -c /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" } @@ -131,10 +160,10 @@ function test_run_env_with_proot_args(){ echo $@ } - assertCommandSuccess _run_env_with_proot --help + assertCommandSuccess _run_env_with_proot "" "--help" assertEquals "--help /bin/sh --login" "$(cat $STDOUTF)" - assertCommandSuccess _run_env_with_proot --help mycommand + assertCommandSuccess _run_env_with_proot "" "--help" mycommand assertEquals "--help /bin/sh --login -c mycommand" "$(cat $STDOUTF)" assertCommandFail _run_env_with_proot @@ -152,7 +181,7 @@ function test_qemu() { echo $@ } - RANDOM=100 ARCH=x86_64 assertCommandSuccess _run_env_with_qemu "" + RANDOM=100 ARCH=x86_64 assertCommandSuccess _run_env_with_qemu "" "" assertEquals "$(echo -e "-s $JUNEST_HOME/bin/qemu-arm-static-x86_64 /tmp/qemu-arm-static-x86_64-100\n-q /tmp/qemu-arm-static-x86_64-100")" "$(cat $STDOUTF)" } From 500546a0e25c2ae5fea6cd4971e1b6c7a65af217 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 28 Mar 2020 12:57:03 +0100 Subject: [PATCH 016/116] Fix build and proot --- lib/core/build.sh | 4 ++-- lib/core/proot.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/core/build.sh b/lib/core/build.sh index a25cef6..9a224f0 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -87,14 +87,14 @@ function build_image_env(){ sudo pacman --noconfirm --root ${maindir}/root -S sed gzip sudo ln -sf /usr/share/zoneinfo/posix/UTC ${maindir}/root/etc/localtime sudo bash -c "echo 'en_US.UTF-8 UTF-8' >> ${maindir}/root/etc/locale.gen" - sudo ${JUNEST_BASE}/bin/groot ${maindir}/root locale-gen + sudo ${maindir}/root/bin/groot ${maindir}/root locale-gen sudo bash -c "echo LANG=\"en_US.UTF-8\" >> ${maindir}/root/etc/locale.conf" sudo pacman --noconfirm --root ${maindir}/root -Rsn gzip info "Setting up the pacman keyring (this might take a while!)..." # gawk command is required for pacman-key sudo pacman --noconfirm --root ${maindir}/root -S gawk - sudo ${JUNEST_BASE}/bin/groot -b /dev ${maindir}/root bash -c ' + sudo ${maindir}/root/bin/groot -b /dev ${maindir}/root bash -c ' pacman-key --init; for keyring_file in /usr/share/pacman/keyrings/*.gpg; do diff --git a/lib/core/proot.sh b/lib/core/proot.sh index a1eee73..bce8295 100644 --- a/lib/core/proot.sh +++ b/lib/core/proot.sh @@ -43,7 +43,7 @@ function _run_env_with_qemu(){ backend_args="-q ${qemu_symlink} $backend_args" fi - _run_env_with_proot "$backend_args" "${@}" + _run_env_with_proot "${backend_command}" "$backend_args" "${@}" } ####################################### From 12e6f6214e588ce6fff36d5944be4cbe5a43854b Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 28 Mar 2020 13:16:40 +0100 Subject: [PATCH 017/116] Add arm arch to proot --- pkgs/proot-static/PKGBUILD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pkgs/proot-static/PKGBUILD b/pkgs/proot-static/PKGBUILD index fad9291..95d34de 100644 --- a/pkgs/proot-static/PKGBUILD +++ b/pkgs/proot-static/PKGBUILD @@ -29,10 +29,19 @@ PROOT_LINK=${MAIN_REPO}/proot source_x86_64=("${_pkgname}"::"$PROOT_LINK/proot-x86_64") source_i686=("${_pkgname}"::"$PROOT_LINK/proot-x86") + source_arm=("${_pkgname}"::"$PROOT_LINK/proot-arm") +source_armv6h=("${_pkgname}"::"$PROOT_LINK/proot-arm") +source_armv7h=("${_pkgname}"::"$PROOT_LINK/proot-arm") +source_aarch64=("${_pkgname}"::"$PROOT_LINK/proot-arm") + md5sums_x86_64=('14080705dd45a6bafa20e909a68072cb') md5sums_i686=('b1c08236b56d121e04e9e29b197d0eeb') + md5sums_arm=('8218c5f00e77e2e6e04c372ced27c7e7') +md5sums_armv6h=('8218c5f00e77e2e6e04c372ced27c7e7') +md5sums_armv7h=('8218c5f00e77e2e6e04c372ced27c7e7') +md5sums_aarch64=('8218c5f00e77e2e6e04c372ced27c7e7') package() { echo "Installing proot static binaries" From b0169a8e5fdb8f938e4bea54d6fd20120976c7c2 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 28 Mar 2020 15:55:08 +0100 Subject: [PATCH 018/116] 7.2.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 21c8c7b..0ee843c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.1.1 +7.2.0 From 6d7bc4efa442f9177f79ef500e313ff2c3bc1b92 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 28 Mar 2020 16:38:53 +0100 Subject: [PATCH 019/116] Add all arch in proot-static package --- lib/checks/check.sh | 1 - lib/core/common.sh | 2 +- pkgs/proot-static/PKGBUILD | 19 +++---------------- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/lib/checks/check.sh b/lib/checks/check.sh index 634044c..57dea5f 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -69,7 +69,6 @@ $SUDO pacman $PACMAN_OPTIONS -S $(pacman -Sg base-devel | cut -d ' ' -f 2 | grep info "Checking basic executables work..." $SUDO pacman -Qi pacman 1> /dev/null -/usr/bin/proot --help 1> /dev/null /usr/bin/groot --help 1> /dev/null repo_package1=tree diff --git a/lib/core/common.sh b/lib/core/common.sh index eb728e9..624a33c 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -67,7 +67,7 @@ ORIGIN_WD=$(pwd) SH=("/bin/sh" "--login") # List of executables that are run in the host OS: -PROOT="${JUNEST_HOME}/usr/bin/proot" +PROOT="${JUNEST_HOME}/usr/bin/proot-${ARCH}" GROOT="${JUNEST_HOME}/usr/bin/groot" CLASSIC_CHROOT=chroot WGET="wget --no-check-certificate" diff --git a/pkgs/proot-static/PKGBUILD b/pkgs/proot-static/PKGBUILD index 95d34de..f73c126 100644 --- a/pkgs/proot-static/PKGBUILD +++ b/pkgs/proot-static/PKGBUILD @@ -27,26 +27,13 @@ noextract=() MAIN_REPO=https://s3-eu-west-1.amazonaws.com/junest-repo PROOT_LINK=${MAIN_REPO}/proot -source_x86_64=("${_pkgname}"::"$PROOT_LINK/proot-x86_64") -source_i686=("${_pkgname}"::"$PROOT_LINK/proot-x86") - -source_arm=("${_pkgname}"::"$PROOT_LINK/proot-arm") -source_armv6h=("${_pkgname}"::"$PROOT_LINK/proot-arm") -source_armv7h=("${_pkgname}"::"$PROOT_LINK/proot-arm") -source_aarch64=("${_pkgname}"::"$PROOT_LINK/proot-arm") - -md5sums_x86_64=('14080705dd45a6bafa20e909a68072cb') -md5sums_i686=('b1c08236b56d121e04e9e29b197d0eeb') - -md5sums_arm=('8218c5f00e77e2e6e04c372ced27c7e7') -md5sums_armv6h=('8218c5f00e77e2e6e04c372ced27c7e7') -md5sums_armv7h=('8218c5f00e77e2e6e04c372ced27c7e7') -md5sums_aarch64=('8218c5f00e77e2e6e04c372ced27c7e7') +source=("proot-x86_64"::"$PROOT_LINK/proot-x86_64" "proot-arm"::"$PROOT_LINK/proot-arm") +md5sums=('14080705dd45a6bafa20e909a68072cb' '8218c5f00e77e2e6e04c372ced27c7e7') package() { echo "Installing proot static binaries" install -d -m 755 "${pkgdir}/usr/bin/" - install -m 755 "${srcdir}/${_pkgname}" ${pkgdir}/usr/bin/proot + install -m 755 "${srcdir}/"${_pkgname}-* ${pkgdir}/usr/bin/ } # vim:set ts=2 sw=2 et: From 7b3685941dfc112bfeccf8de83822397d153b3ac Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 28 Mar 2020 18:48:51 +0100 Subject: [PATCH 020/116] 7.2.1 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0ee843c..b26a34e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.2.0 +7.2.1 From 98107ac07f394fb625bf2260c29f86b115036f48 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 15 Sep 2020 14:06:03 +0200 Subject: [PATCH 021/116] Change format package from xz --- .gitignore | 2 +- lib/core/build.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 2d39c41..b47a408 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ *.swp -*pkg.tar.xz +*pkg.tar.* *.tar.gz *.SRCINFO diff --git a/lib/core/build.sh b/lib/core/build.sh index 9a224f0..af0c5bb 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -17,7 +17,7 @@ function _install_pkg_from_aur(){ $CURL "https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=${pkgname}" [ -z "${installname}" ] || $CURL "https://aur.archlinux.org/cgit/aur.git/plain/${installname}?h=${pkgname}" makepkg -sfcd - sudo pacman --noconfirm --root ${maindir}/root -U ${pkgname}*.pkg.tar.xz + sudo pacman --noconfirm --root ${maindir}/root -U ${pkgname}*.pkg.tar.* } function _install_pkg(){ @@ -29,7 +29,7 @@ function _install_pkg(){ builtin cd ${working_dir} makepkg -sfcd makepkg --printsrcinfo > ${pkgbuilddir}/.SRCINFO - sudo pacman --noconfirm --root ${maindir}/root -U *.pkg.tar.xz + sudo pacman --noconfirm --root ${maindir}/root -U *.pkg.tar.* } function _prepare() { From 84f4d2037022227d741c37b9fdc1992d93daadcf Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 15 Sep 2020 19:31:24 +0200 Subject: [PATCH 022/116] Disable integ test for ARM --- .travis.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 025ddc7..b4126d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,8 @@ script: - ${PWD}/lib/checks/check_all.sh - yes | junest setup --delete - - export JUNEST_HOME=~/.junest-arm - - junest proot --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests - - junest proot -- ${PWD}/lib/checks/check.sh --skip-aur-tests --use-sudo - - yes | junest setup --delete + # ARM with qemu does seem to work properly. Disabling integ tests for ARM for now. + #- export JUNEST_HOME=~/.junest-arm + #- junest proot --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests + #- junest proot -- ${PWD}/lib/checks/check.sh --skip-aur-tests --use-sudo + #- yes | junest setup --delete From 440dde65643fd401eae30afd29fb14cca609000e Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 15 Sep 2020 19:40:16 +0200 Subject: [PATCH 023/116] 7.2.2 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index b26a34e..77f5bec 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.2.1 +7.2.2 From 26e58aaeec477aac25bd7f1d38d3870745376ff4 Mon Sep 17 00:00:00 2001 From: hodapp512 Date: Thu, 10 Dec 2020 11:27:15 -0600 Subject: [PATCH 024/116] Update README.md for updated bind usage --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fc9f320..ce38b1c 100644 --- a/README.md +++ b/README.md @@ -269,7 +269,13 @@ armv7l ``` ## Bind directories ## -To bind a host directory to a guest location, you can use proot arguments: +To bind a host directory to a guest location: + +```sh +junest -b "--bind /home/user/mydata /mnt/mydata" +``` + +Or using proot arguments: ```sh junest proot -b "-b /mnt/mydata:/home/user/mydata" From 95479ba41fd38330f66b16f406869a2c6a9cc722 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Mon, 21 Dec 2020 08:58:23 +0100 Subject: [PATCH 025/116] Use arch-travis in CI --- .travis.yml | 91 +++++++++++++++++++++++++++++++++++------------ lib/core/build.sh | 10 ++++-- 2 files changed, 77 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml index b4126d8..e09143c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,31 +1,78 @@ -language: bash - sudo: required +os: linux -env: - - TRAVIS_BASH_VERSION="4.0" +cache: + directories: + - ~/.ccache + - ~/.pkg-cache -before_install: - - ./tests/integ-tests/install-bash.sh "$TRAVIS_BASH_VERSION" +services: +- docker -install: - - PATH=$PWD/bin:$PATH - - junest setup - - junest -- echo "Installing JuNest (\$(uname -m))" - - JUNEST_HOME=~/.junest-arm junest setup --arch arm - - JUNEST_HOME=~/.junest-arm junest proot --fakeroot -- echo "Installing JuNest (\$(uname -m))" +archlinux: + mount: + - ~/.ccache:~/.ccache + - ~/.pkg-cache:/var/cache/pacman/pkg + repos: + - bartus=https://github.com/bartoszek/AUR-repo/raw/master + packages: + # pacman packages + - git + - ccache + - haveged + - aws-cli + + before_install: +# 1.Override `package-cleanup.hook` to preserve cache for travis. +# 2.Enable ccache +# 3.Multithreaded build and compress +# 4.Suppress all gcc warnings + - | + sudo mkdir /etc/pacman.d/hooks/ + sudo ln -s /dev/null /etc/pacman.d/hooks/package-cleanup.hook + sudo sed -i '/^BUILDENV/s/\!ccache/ccache/' /etc/makepkg.conf + sudo sed -i '/#MAKEFLAGS=/c MAKEFLAGS="-j2"' /etc/makepkg.conf + sudo sed -i '/^COMPRESSXZ/s/\xz/xz -T 2/' /etc/makepkg.conf + sudo sed -i '$a CFLAGS="$CFLAGS -w"' /etc/makepkg.conf + sudo sed -i '$a CXXFLAGS="$CXXFLAGS -w"' /etc/makepkg.conf + # TODO this is not used + script: + - "./bin/junest build -n" script: - - bash --version - - bash ./tests/checkstyle/checkstyle.sh - - bash ./tests/unit-tests/unit-tests.sh +- "curl -s https://raw.githubusercontent.com/bartoszek/arch-travis/master/arch-travis.sh | bash" +- "echo pacman pkg cache size: $(du -h ~/.pkg-cache|cut -f1) in $(ls ~/.pkg-cache|wc -l) files" - - export JUNEST_HOME=~/.junest - - ${PWD}/lib/checks/check_all.sh - - yes | junest setup --delete - # ARM with qemu does seem to work properly. Disabling integ tests for ARM for now. - #- export JUNEST_HOME=~/.junest-arm - #- junest proot --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests - #- junest proot -- ${PWD}/lib/checks/check.sh --skip-aur-tests --use-sudo + +#language: bash + +#sudo: required + +#env: + #- TRAVIS_BASH_VERSION="4.0" + +#before_install: + #- ./tests/integ-tests/install-bash.sh "$TRAVIS_BASH_VERSION" + +#install: + #- PATH=$PWD/bin:$PATH + #- junest setup + #- junest -- echo "Installing JuNest (\$(uname -m))" + #- JUNEST_HOME=~/.junest-arm junest setup --arch arm + #- JUNEST_HOME=~/.junest-arm junest proot --fakeroot -- echo "Installing JuNest (\$(uname -m))" + +#script: + #- bash --version + #- bash ./tests/checkstyle/checkstyle.sh + #- bash ./tests/unit-tests/unit-tests.sh + + #- export JUNEST_HOME=~/.junest + #- ${PWD}/lib/checks/check_all.sh #- yes | junest setup --delete + + ## ARM with qemu does seem to work properly. Disabling integ tests for ARM for now. + ##- export JUNEST_HOME=~/.junest-arm + ##- junest proot --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests + ##- junest proot -- ${PWD}/lib/checks/check.sh --skip-aur-tests --use-sudo + ##- yes | junest setup --delete diff --git a/lib/core/build.sh b/lib/core/build.sh index af0c5bb..a3ed8bd 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -80,6 +80,7 @@ function build_image_env(){ sudo install -d -m 755 "${maindir}/root/etc/${CMD}" sudo bash -c "echo 'JUNEST_ARCH=$ARCH' > ${maindir}/root/etc/${CMD}/info" + set -x info "Generating the locales..." # sed command is required for locale-gen but it is required by fakeroot # and cannot be removed @@ -87,14 +88,18 @@ function build_image_env(){ sudo pacman --noconfirm --root ${maindir}/root -S sed gzip sudo ln -sf /usr/share/zoneinfo/posix/UTC ${maindir}/root/etc/localtime sudo bash -c "echo 'en_US.UTF-8 UTF-8' >> ${maindir}/root/etc/locale.gen" - sudo ${maindir}/root/bin/groot ${maindir}/root locale-gen + sudo ${maindir}/root/bin/groot --no-umount ${maindir}/root locale-gen + #sudo mount --bind ${maindir}/root ${maindir}/root + #sudo arch-chroot ${maindir}/root locale-gen sudo bash -c "echo LANG=\"en_US.UTF-8\" >> ${maindir}/root/etc/locale.conf" sudo pacman --noconfirm --root ${maindir}/root -Rsn gzip info "Setting up the pacman keyring (this might take a while!)..." # gawk command is required for pacman-key sudo pacman --noconfirm --root ${maindir}/root -S gawk - sudo ${maindir}/root/bin/groot -b /dev ${maindir}/root bash -c ' + #TODO sudo mount --bind /dev ${maindir}/root/dev + #sudo ${maindir}/root/bin/groot --no-umount -b /dev ${maindir}/root bash -c ' + sudo ${maindir}/root/bin/groot --no-umount ${maindir}/root bash -c ' pacman-key --init; for keyring_file in /usr/share/pacman/keyrings/*.gpg; do @@ -102,6 +107,7 @@ function build_image_env(){ pacman-key --populate $keyring; done; [ -e /etc/pacman.d/gnupg/S.gpg-agent ] && gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye' + sudo umount ${maindir}/root sudo pacman --noconfirm --root ${maindir}/root -Rsn gawk sudo rm ${maindir}/root/var/cache/pacman/pkg/* From b75faac48fccba542b82f7cfd786d2f0984853bd Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 26 Dec 2020 12:33:48 +0100 Subject: [PATCH 026/116] Add remaining junest tests in travis --- .travis.yml | 81 ++++++++++++++++++++++------------------- lib/checks/check.sh | 6 ++- lib/checks/check_all.sh | 11 +++--- lib/core/build.sh | 11 ++---- 4 files changed, 58 insertions(+), 51 deletions(-) diff --git a/.travis.yml b/.travis.yml index e09143c..cfd7148 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,20 +13,18 @@ archlinux: mount: - ~/.ccache:~/.ccache - ~/.pkg-cache:/var/cache/pacman/pkg - repos: - - bartus=https://github.com/bartoszek/AUR-repo/raw/master packages: - # pacman packages - - git - - ccache - - haveged + # Pacman packages - aws-cli + - ccache + - git + - haveged before_install: -# 1.Override `package-cleanup.hook` to preserve cache for travis. -# 2.Enable ccache -# 3.Multithreaded build and compress -# 4.Suppress all gcc warnings + # 1.Override `package-cleanup.hook` to preserve cache for travis. + # 2.Enable ccache + # 3.Multithreaded build and compress + # 4.Suppress all gcc warnings - | sudo mkdir /etc/pacman.d/hooks/ sudo ln -s /dev/null /etc/pacman.d/hooks/package-cleanup.hook @@ -35,44 +33,51 @@ archlinux: sudo sed -i '/^COMPRESSXZ/s/\xz/xz -T 2/' /etc/makepkg.conf sudo sed -i '$a CFLAGS="$CFLAGS -w"' /etc/makepkg.conf sudo sed -i '$a CXXFLAGS="$CXXFLAGS -w"' /etc/makepkg.conf - # TODO this is not used script: - - "./bin/junest build -n" + - ./bin/junest build -n + + +env: + - TRAVIS_BASH_VERSION="4.0" + +before_install: + - ./tests/integ-tests/install-bash.sh "$TRAVIS_BASH_VERSION" + +install: + - PATH=$PWD/bin:$PATH script: -- "curl -s https://raw.githubusercontent.com/bartoszek/arch-travis/master/arch-travis.sh | bash" -- "echo pacman pkg cache size: $(du -h ~/.pkg-cache|cut -f1) in $(ls ~/.pkg-cache|wc -l) files" + ####################### + # Unit Tests + ####################### + - bash --version + - bash ./tests/checkstyle/checkstyle.sh + - bash ./tests/unit-tests/unit-tests.sh + # ARM with qemu does seem to work properly. Disabling integ tests for ARM for now. + #- export JUNEST_HOME=~/.junest-arm + #- junest proot --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests + #- junest proot -- ${PWD}/lib/checks/check.sh --skip-aur-tests --use-sudo + #- yes | junest setup --delete + ####################### + # Build and validation tests + ####################### + - "curl -s https://raw.githubusercontent.com/bartoszek/arch-travis/master/arch-travis.sh | bash" + - "echo pacman pkg cache size: $(du -h ~/.pkg-cache|cut -f1) in $(ls ~/.pkg-cache|wc -l) files" + - ls -l + - pwd -#language: bash - -#sudo: required - -#env: - #- TRAVIS_BASH_VERSION="4.0" - -#before_install: - #- ./tests/integ-tests/install-bash.sh "$TRAVIS_BASH_VERSION" - -#install: - #- PATH=$PWD/bin:$PATH + # TODO Test the new created JuNest image against Ubuntu host #- junest setup #- junest -- echo "Installing JuNest (\$(uname -m))" #- JUNEST_HOME=~/.junest-arm junest setup --arch arm #- JUNEST_HOME=~/.junest-arm junest proot --fakeroot -- echo "Installing JuNest (\$(uname -m))" + - export JUNEST_HOME=~/.junest + - junest setup -i junest-x86_64.tar.gz + - ${PWD}/lib/checks/check_all.sh + - yes | junest setup --delete -#script: - #- bash --version - #- bash ./tests/checkstyle/checkstyle.sh - #- bash ./tests/unit-tests/unit-tests.sh + # TODO test deployed image can be downloaded correctly - #- export JUNEST_HOME=~/.junest - #- ${PWD}/lib/checks/check_all.sh - #- yes | junest setup --delete - ## ARM with qemu does seem to work properly. Disabling integ tests for ARM for now. - ##- export JUNEST_HOME=~/.junest-arm - ##- junest proot --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests - ##- junest proot -- ${PWD}/lib/checks/check.sh --skip-aur-tests --use-sudo - ##- yes | junest setup --delete diff --git a/lib/checks/check.sh b/lib/checks/check.sh index 57dea5f..6ae3e6a 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -80,7 +80,11 @@ $SUDO pacman $PACMAN_OPTIONS -Rsn ${repo_package1} repo_package2=iftop info "Checking ${repo_package2} package from official repo..." $SUDO pacman $PACMAN_OPTIONS -S ${repo_package2} -$RUN_ROOT_TESTS && $SUDO iftop -t -s 5 +if $RUN_ROOT_TESTS +then + # Time it out given that sometimes it gets stuck after few seconds. + $SUDO timeout 10 iftop -t -s 5 || true +fi $SUDO pacman $PACMAN_OPTIONS -Rsn ${repo_package2} if ! $SKIP_AUR_TESTS diff --git a/lib/checks/check_all.sh b/lib/checks/check_all.sh index 6e28ee5..91bc058 100755 --- a/lib/checks/check_all.sh +++ b/lib/checks/check_all.sh @@ -8,10 +8,11 @@ set -ex JUNEST_BASE="${JUNEST_BASE:-$(readlink -f $(dirname $(readlink -f "$0"))/../..)}" JUNEST_SCRIPT=${JUNEST_SCRIPT:-${JUNEST_BASE}/bin/junest} + CHECK_SCRIPT=${JUNEST_BASE}/lib/checks/check.sh -$JUNEST_SCRIPT proot --fakeroot -- "$CHECK_SCRIPT" --skip-aur-tests -$JUNEST_SCRIPT proot -- "$CHECK_SCRIPT" --skip-aur-tests --use-sudo -$JUNEST_SCRIPT ns --fakeroot -- "$CHECK_SCRIPT" --skip-aur-tests -$JUNEST_SCRIPT ns -- "$CHECK_SCRIPT" --use-sudo -sudo -E $JUNEST_SCRIPT groot -- "$CHECK_SCRIPT" --run-root-tests --skip-aur-tests +$JUNEST_SCRIPT proot --fakeroot --backend-args "-b ${JUNEST_BASE}" -- "$CHECK_SCRIPT" --skip-aur-tests +$JUNEST_SCRIPT proot --backend-args "-b ${JUNEST_BASE}" -- "$CHECK_SCRIPT" --skip-aur-tests --use-sudo +$JUNEST_SCRIPT ns --backend-args "--bind ${JUNEST_BASE} ${JUNEST_BASE}" --fakeroot -- "$CHECK_SCRIPT" --skip-aur-tests +$JUNEST_SCRIPT ns --backend-args "--bind ${JUNEST_BASE} ${JUNEST_BASE}" -- "$CHECK_SCRIPT" --use-sudo +sudo -E $JUNEST_SCRIPT groot --backend-args "--bind ${JUNEST_BASE}" -- "$CHECK_SCRIPT" --run-root-tests --skip-aur-tests diff --git a/lib/core/build.sh b/lib/core/build.sh index a3ed8bd..fb41ede 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -88,18 +88,14 @@ function build_image_env(){ sudo pacman --noconfirm --root ${maindir}/root -S sed gzip sudo ln -sf /usr/share/zoneinfo/posix/UTC ${maindir}/root/etc/localtime sudo bash -c "echo 'en_US.UTF-8 UTF-8' >> ${maindir}/root/etc/locale.gen" - sudo ${maindir}/root/bin/groot --no-umount ${maindir}/root locale-gen - #sudo mount --bind ${maindir}/root ${maindir}/root - #sudo arch-chroot ${maindir}/root locale-gen + sudo ${maindir}/root/bin/groot ${maindir}/root locale-gen sudo bash -c "echo LANG=\"en_US.UTF-8\" >> ${maindir}/root/etc/locale.conf" sudo pacman --noconfirm --root ${maindir}/root -Rsn gzip info "Setting up the pacman keyring (this might take a while!)..." # gawk command is required for pacman-key sudo pacman --noconfirm --root ${maindir}/root -S gawk - #TODO sudo mount --bind /dev ${maindir}/root/dev - #sudo ${maindir}/root/bin/groot --no-umount -b /dev ${maindir}/root bash -c ' - sudo ${maindir}/root/bin/groot --no-umount ${maindir}/root bash -c ' + sudo ${maindir}/root/bin/groot --no-umount --avoid-bind -b /dev ${maindir}/root bash -c ' pacman-key --init; for keyring_file in /usr/share/pacman/keyrings/*.gpg; do @@ -107,7 +103,8 @@ function build_image_env(){ pacman-key --populate $keyring; done; [ -e /etc/pacman.d/gnupg/S.gpg-agent ] && gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye' - sudo umount ${maindir}/root + sudo umount --force --recursive --lazy ${maindir}/root/dev + sudo umount --force --recursive ${maindir}/root sudo pacman --noconfirm --root ${maindir}/root -Rsn gawk sudo rm ${maindir}/root/var/cache/pacman/pkg/* From 9d2e6e4bbf09b0630b7a4f388dab2abfe6bb18df Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Mon, 28 Dec 2020 10:22:13 +0100 Subject: [PATCH 027/116] Add deploy feature --- .travis.yml | 31 ++++++++------ ci/deploy.sh | 50 +++++++++++++++++++++++ {tests/integ-tests => ci}/install-bash.sh | 0 lib/checks/check.sh | 2 +- lib/checks/check_all.sh | 10 ++--- 5 files changed, 75 insertions(+), 18 deletions(-) create mode 100755 ci/deploy.sh rename {tests/integ-tests => ci}/install-bash.sh (100%) diff --git a/.travis.yml b/.travis.yml index cfd7148..648a0cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,6 @@ archlinux: - ~/.pkg-cache:/var/cache/pacman/pkg packages: # Pacman packages - - aws-cli - ccache - git - haveged @@ -34,14 +33,23 @@ archlinux: sudo sed -i '$a CFLAGS="$CFLAGS -w"' /etc/makepkg.conf sudo sed -i '$a CXXFLAGS="$CXXFLAGS -w"' /etc/makepkg.conf script: + # Here do not make any validation (-n) because it will be done later on in the Ubuntu host directly - ./bin/junest build -n env: + matrix: - TRAVIS_BASH_VERSION="4.0" + global: + # AWS_ACCESS_KEY_ID + - secure: "ZotyKKWH5ZrBXDdEnVmV22gbn86BBSiqDZn2d2jVAApgUQdDc3wa7/uYAZP1bts6oQ897nnkUSFHk3M3QAcIoPJerUITTU5D7yjKcFDejgHdpJ4t9XSajmpY9CgKftWapwliWG4wolAKwyAp5GnYqz4GGltHyGxbF/VzUNRF3lw=" + # AWS_SECRET_ACCESS_KEY + - secure: "AWixvJmhr6+rfF4cspMWMjkvLuOsdfNanLK5wrqkgx/0ezDGBBThH0qVhn5Mp1QFM6wVF+LRA6UESNnj0wNwByZHdM6LddkJWlWHb/qkVK+AO4RKUsXJWNyPyOkCNj/WEFpZHQKKUAlEtC8m8AmAcuoi90cr6ih0PXIePRyPFrM=" before_install: - - ./tests/integ-tests/install-bash.sh "$TRAVIS_BASH_VERSION" + - ./ci/install-bash.sh "$TRAVIS_BASH_VERSION" + - sudo apt-get update + - sudo apt-get -y install awscli install: - PATH=$PWD/bin:$PATH @@ -56,28 +64,27 @@ script: # ARM with qemu does seem to work properly. Disabling integ tests for ARM for now. #- export JUNEST_HOME=~/.junest-arm + #- junest setup --arch arm + #- junest proot --fakeroot -- echo "Installing JuNest (\$(uname -m))" #- junest proot --fakeroot -- ${PWD}/lib/checks/check.sh --skip-aur-tests #- junest proot -- ${PWD}/lib/checks/check.sh --skip-aur-tests --use-sudo #- yes | junest setup --delete ####################### - # Build and validation tests + # Build and validation ####################### - "curl -s https://raw.githubusercontent.com/bartoszek/arch-travis/master/arch-travis.sh | bash" - "echo pacman pkg cache size: $(du -h ~/.pkg-cache|cut -f1) in $(ls ~/.pkg-cache|wc -l) files" - ls -l - - pwd - - # TODO Test the new created JuNest image against Ubuntu host - #- junest setup - #- junest -- echo "Installing JuNest (\$(uname -m))" - #- JUNEST_HOME=~/.junest-arm junest setup --arch arm - #- JUNEST_HOME=~/.junest-arm junest proot --fakeroot -- echo "Installing JuNest (\$(uname -m))" + # Test the newly created JuNest image against Ubuntu host - export JUNEST_HOME=~/.junest - junest setup -i junest-x86_64.tar.gz - ${PWD}/lib/checks/check_all.sh - yes | junest setup --delete - # TODO test deployed image can be downloaded correctly - +after_success: + ####################### + # Deploy and validation + ####################### + - ./ci/deploy.sh ${PWD}/junest-x86_64.tar.gz diff --git a/ci/deploy.sh b/ci/deploy.sh new file mode 100755 index 0000000..fa2ff75 --- /dev/null +++ b/ci/deploy.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +set -e + +IMG_PATH=$1 + +set -u + +MAX_OLD_IMAGES=30 + +# ARCH can be one of: x86, x86_64, arm +HOST_ARCH=$(uname -m) +if [ $HOST_ARCH == "i686" ] || [ $HOST_ARCH == "i386" ] +then + ARCH="x86" +elif [ $HOST_ARCH == "x86_64" ] +then + ARCH="x86_64" +elif [[ $HOST_ARCH =~ .*(arm).* ]] +then + ARCH="arm" +else + echo "Unknown architecture ${HOST_ARCH}" >&2 + exit 11 +fi + +if [[ "$TRAVIS_BRANCH" == "master" ]] +then + + export AWS_DEFAULT_REGION=eu-west-1 + # Upload image + # The put is done via a temporary filename in order to prevent outage on the + # production file for a longer period of time. + cp ${IMG_PATH} ${IMG_PATH}.temp + aws s3 cp ${IMG_PATH}.temp s3://junest-repo/junest/ + aws s3 mv s3://junest-repo/junest/${IMG_PATH}.temp s3://junest-repo/junest/${IMG_PATH} + aws s3api put-object-acl --acl public-read --bucket junest-repo --key junest/${IMG_PATH} + + DATE=$(date +'%Y-%m-%d-%H-%M-%S') + + aws s3 cp ${IMG_PATH} s3://junest-repo/junest/${IMG_PATH}.${DATE} + + # Cleanup old images + aws s3 ls s3://junest-repo/junest/junest-${ARCH}.tar.gz. | awk '{print $4}' | head -n -${MAX_OLD_IMAGES} | xargs -I {} s3 rm "s3://junest-repo/junest/{}" + + # Test the newly deployed image can be downloaded correctly + junest setup + junest -- echo "Installed JuNest (\$(uname -m))" + yes | junest setup --delete +fi diff --git a/tests/integ-tests/install-bash.sh b/ci/install-bash.sh similarity index 100% rename from tests/integ-tests/install-bash.sh rename to ci/install-bash.sh diff --git a/lib/checks/check.sh b/lib/checks/check.sh index 6ae3e6a..957156b 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -9,7 +9,7 @@ # # vim: ft=sh -set -e +set -ex RUN_ROOT_TESTS=false diff --git a/lib/checks/check_all.sh b/lib/checks/check_all.sh index 91bc058..cc1c4df 100755 --- a/lib/checks/check_all.sh +++ b/lib/checks/check_all.sh @@ -11,8 +11,8 @@ JUNEST_SCRIPT=${JUNEST_SCRIPT:-${JUNEST_BASE}/bin/junest} CHECK_SCRIPT=${JUNEST_BASE}/lib/checks/check.sh -$JUNEST_SCRIPT proot --fakeroot --backend-args "-b ${JUNEST_BASE}" -- "$CHECK_SCRIPT" --skip-aur-tests -$JUNEST_SCRIPT proot --backend-args "-b ${JUNEST_BASE}" -- "$CHECK_SCRIPT" --skip-aur-tests --use-sudo -$JUNEST_SCRIPT ns --backend-args "--bind ${JUNEST_BASE} ${JUNEST_BASE}" --fakeroot -- "$CHECK_SCRIPT" --skip-aur-tests -$JUNEST_SCRIPT ns --backend-args "--bind ${JUNEST_BASE} ${JUNEST_BASE}" -- "$CHECK_SCRIPT" --use-sudo -sudo -E $JUNEST_SCRIPT groot --backend-args "--bind ${JUNEST_BASE}" -- "$CHECK_SCRIPT" --run-root-tests --skip-aur-tests +$JUNEST_SCRIPT proot --fakeroot -- "$CHECK_SCRIPT" --skip-aur-tests +$JUNEST_SCRIPT proot -- "$CHECK_SCRIPT" --skip-aur-tests --use-sudo +$JUNEST_SCRIPT ns --fakeroot -- "$CHECK_SCRIPT" --skip-aur-tests +$JUNEST_SCRIPT ns -- "$CHECK_SCRIPT" --use-sudo +sudo -E $JUNEST_SCRIPT groot -- "$CHECK_SCRIPT" --run-root-tests --skip-aur-tests From 3d16ee2583de6fc071e787422d9d990238053acb Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 29 Dec 2020 10:46:49 +0100 Subject: [PATCH 028/116] First commit for wrappers --- bin/junest | 43 +++++++++++++++++++++++++++++++++++++++++++ lib/core/wrappers.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 lib/core/wrappers.sh diff --git a/bin/junest b/bin/junest index 17d32bc..a19e550 100755 --- a/bin/junest +++ b/bin/junest @@ -17,6 +17,7 @@ source "${JUNEST_BASE}/lib/core/setup.sh" source "${JUNEST_BASE}/lib/core/chroot.sh" source "${JUNEST_BASE}/lib/core/namespace.sh" source "${JUNEST_BASE}/lib/core/proot.sh" +source "${JUNEST_BASE}/lib/core/wrappers.sh" ################################### @@ -67,6 +68,12 @@ usage() { echo -e " b[uild] Build a $NAME image (must run in ArchLinux)" echo -e " -n, --disable-check Disable the $NAME image check" echo + echo -e " c[reate-wrappers] Create wrappers in ${JUNEST_HOME}/usr/bin_wrappers of the executables under" + echo -e " ${JUNEST_HOME}/usr/bin to be run directly from the host." + echo -e " Use the variable JUNEST_ARGS to define how the wrapper will call $NAME (default "ns --fakeroot")." + echo -e " Use PATH variable to point directly to the bin_wrappers directory from the host." + echo -e " -r, --recreate-existing Instead of skipping existing wrappers recreate them" + echo } version() { @@ -80,6 +87,7 @@ function parse_arguments(){ ACT_NAMESPACE=false ACT_PROOT=false ACT_GROOT=false + ACT_WRAPPERS=false ACT_ROOT=false ACT_HELP=false ACT_VERSION=false @@ -91,6 +99,7 @@ function parse_arguments(){ p|proot) ACT_PROOT=true ; shift ;; g|groot) ACT_GROOT=true ; shift ;; r|root) ACT_ROOT=true ; shift ;; + c|create-wrappers) ACT_WRAPPERS=true ; shift ;; -h|--help) ACT_HELP=true ; shift ;; -V|--version) ACT_VERSION=true ; shift ;; *) ACT_NAMESPACE=true ;; @@ -114,9 +123,33 @@ function parse_arguments(){ elif $ACT_ROOT then _parse_root_opts "$@" + elif $ACT_WRAPPERS + then + _parse_wrappers_opts "$@" fi } +function _parse_wrappers_opts() { + # Options: + OPT_RECREATE_EXISTING=false + + while [[ -n "$1" ]] + do + case "$1" in + -r|--recreate-existing) OPT_RECREATE_EXISTING=true ; shift ;; + --) shift ; break ;; + -*) die "Invalid option $1" ;; + *) break ;; + esac + done + + ARGS=() + for arg in "$@" + do + ARGS+=("$arg") + done +} + function _parse_root_opts() { # Options: BACKEND_ARGS="" @@ -247,6 +280,7 @@ function execute_operation() { else setup_env $ARCH_ARG fi + create_wrappers false fi return @@ -258,6 +292,11 @@ function execute_operation() { die "Error: The image is still not installed in $JUNEST_HOME. Run this first: $CMD setup" fi + if $ACT_WRAPPERS; then + create_wrappers $OPT_RECREATE_EXISTING + return + fi + local run_env if $ACT_NAMESPACE; then if $OPT_FAKEROOT; then @@ -279,6 +318,10 @@ function execute_operation() { $run_env "$BACKEND_COMMAND" "${BACKEND_ARGS}" $OPT_NO_COPY_FILES "${ARGS[@]}" + # TODO use the run_env exit status + + # Call create_wrappers in case new bin files have been created + create_wrappers false } function main() { diff --git a/lib/core/wrappers.sh b/lib/core/wrappers.sh new file mode 100644 index 0000000..184fca5 --- /dev/null +++ b/lib/core/wrappers.sh @@ -0,0 +1,31 @@ + + +function create_wrappers() { + mkdir -p ${JUNEST_HOME}/usr/bin_wrappers + + cd ${JUNEST_HOME}/usr/bin + for file in * + do + [[ -x $file ]] || continue + if [[ -e ${JUNEST_HOME}/usr/bin_wrappers/$file ]] + then + continue + fi + cat < ${JUNEST_HOME}/usr/bin_wrappers/${file} +#!/usr/bin/env bash + +JUNEST_ARGS=\${JUNEST_ARGS:-ns --fakeroot} + +junest \${JUNEST_ARGS} -- ${file} "\$@" +EOF + chmod +x ${JUNEST_HOME}/usr/bin_wrappers/${file} + done + + # Remove wrappers no longer needed + cd ${JUNEST_HOME}/usr/bin_wrappers + for file in * + do + [[ -e ${JUNEST_HOME}/usr/bin/$file ]] || rm -f $file + done + +} From 2aeb23b88283cd710855c6919203b4fa8ef71aa3 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 29 Dec 2020 13:09:35 +0100 Subject: [PATCH 029/116] Add tests for wrappers --- bin/junest | 46 ++------------------- lib/checks/check_all.sh | 3 ++ tests/unit-tests/test-wrappers.sh | 67 +++++++++++++++++++++++++++++++ tests/utils/utils.sh | 1 + 4 files changed, 74 insertions(+), 43 deletions(-) create mode 100755 tests/unit-tests/test-wrappers.sh diff --git a/bin/junest b/bin/junest index a19e550..2671e86 100755 --- a/bin/junest +++ b/bin/junest @@ -68,12 +68,6 @@ usage() { echo -e " b[uild] Build a $NAME image (must run in ArchLinux)" echo -e " -n, --disable-check Disable the $NAME image check" echo - echo -e " c[reate-wrappers] Create wrappers in ${JUNEST_HOME}/usr/bin_wrappers of the executables under" - echo -e " ${JUNEST_HOME}/usr/bin to be run directly from the host." - echo -e " Use the variable JUNEST_ARGS to define how the wrapper will call $NAME (default "ns --fakeroot")." - echo -e " Use PATH variable to point directly to the bin_wrappers directory from the host." - echo -e " -r, --recreate-existing Instead of skipping existing wrappers recreate them" - echo } version() { @@ -87,7 +81,6 @@ function parse_arguments(){ ACT_NAMESPACE=false ACT_PROOT=false ACT_GROOT=false - ACT_WRAPPERS=false ACT_ROOT=false ACT_HELP=false ACT_VERSION=false @@ -99,7 +92,6 @@ function parse_arguments(){ p|proot) ACT_PROOT=true ; shift ;; g|groot) ACT_GROOT=true ; shift ;; r|root) ACT_ROOT=true ; shift ;; - c|create-wrappers) ACT_WRAPPERS=true ; shift ;; -h|--help) ACT_HELP=true ; shift ;; -V|--version) ACT_VERSION=true ; shift ;; *) ACT_NAMESPACE=true ;; @@ -123,33 +115,9 @@ function parse_arguments(){ elif $ACT_ROOT then _parse_root_opts "$@" - elif $ACT_WRAPPERS - then - _parse_wrappers_opts "$@" fi } -function _parse_wrappers_opts() { - # Options: - OPT_RECREATE_EXISTING=false - - while [[ -n "$1" ]] - do - case "$1" in - -r|--recreate-existing) OPT_RECREATE_EXISTING=true ; shift ;; - --) shift ; break ;; - -*) die "Invalid option $1" ;; - *) break ;; - esac - done - - ARGS=() - for arg in "$@" - do - ARGS+=("$arg") - done -} - function _parse_root_opts() { # Options: BACKEND_ARGS="" @@ -280,7 +248,7 @@ function execute_operation() { else setup_env $ARCH_ARG fi - create_wrappers false + create_wrappers fi return @@ -292,11 +260,6 @@ function execute_operation() { die "Error: The image is still not installed in $JUNEST_HOME. Run this first: $CMD setup" fi - if $ACT_WRAPPERS; then - create_wrappers $OPT_RECREATE_EXISTING - return - fi - local run_env if $ACT_NAMESPACE; then if $OPT_FAKEROOT; then @@ -316,12 +279,9 @@ function execute_operation() { run_env=run_env_as_chroot fi - $run_env "$BACKEND_COMMAND" "${BACKEND_ARGS}" $OPT_NO_COPY_FILES "${ARGS[@]}" - - # TODO use the run_env exit status - # Call create_wrappers in case new bin files have been created - create_wrappers false + trap "create_wrappers" EXIT QUIT TERM KILL + $run_env "$BACKEND_COMMAND" "${BACKEND_ARGS}" $OPT_NO_COPY_FILES "${ARGS[@]}" } function main() { diff --git a/lib/checks/check_all.sh b/lib/checks/check_all.sh index cc1c4df..9e5f0a6 100755 --- a/lib/checks/check_all.sh +++ b/lib/checks/check_all.sh @@ -16,3 +16,6 @@ $JUNEST_SCRIPT proot -- "$CHECK_SCRIPT" --skip-aur-tests --use-sudo $JUNEST_SCRIPT ns --fakeroot -- "$CHECK_SCRIPT" --skip-aur-tests $JUNEST_SCRIPT ns -- "$CHECK_SCRIPT" --use-sudo sudo -E $JUNEST_SCRIPT groot -- "$CHECK_SCRIPT" --run-root-tests --skip-aur-tests + +# Test the wrappers work +$JUNEST_HOME/usr/bin_wrappers/pacman --help diff --git a/tests/unit-tests/test-wrappers.sh b/tests/unit-tests/test-wrappers.sh new file mode 100755 index 0000000..a78c81f --- /dev/null +++ b/tests/unit-tests/test-wrappers.sh @@ -0,0 +1,67 @@ +#!/bin/bash +source "$(dirname $0)/../utils/utils.sh" + +source "$(dirname $0)/../../lib/core/wrappers.sh" + +# Disable the exiterr +set +e + +function oneTimeSetUp(){ + setUpUnitTests +} + +function setUp(){ + junestSetUp +} + +function tearDown(){ + junestTearDown +} + +function test_create_wrappers_empty_bin(){ + assertCommandSuccess create_wrappers + assertEquals "" "$(cat $STDOUTF)" + assertTrue "bin_wrappers does not exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" +} + +function test_create_wrappers_not_executable_file(){ + touch $JUNEST_HOME/usr/bin/myfile + assertCommandSuccess create_wrappers + assertEquals "" "$(cat $STDOUTF)" + assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" + assertTrue "myfile wrapper should not exist" "[ ! -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" +} + +function test_create_wrappers_executable_file(){ + touch $JUNEST_HOME/usr/bin/myfile + chmod +x $JUNEST_HOME/usr/bin/myfile + assertCommandSuccess create_wrappers + assertEquals "" "$(cat $STDOUTF)" + assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" + assertTrue "myfile wrapper should exist" "[ -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" +} + +function test_create_wrappers_already_exist(){ + touch $JUNEST_HOME/usr/bin/myfile + chmod +x $JUNEST_HOME/usr/bin/myfile + mkdir -p $JUNEST_HOME/usr/bin_wrappers + touch $JUNEST_HOME/usr/bin_wrappers/myfile + chmod +x $JUNEST_HOME/usr/bin_wrappers/myfile + assertCommandSuccess create_wrappers + assertEquals "" "$(cat $STDOUTF)" + assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" + assertTrue "myfile wrapper should exist" "[ -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" + assertEquals "" "$(touch $JUNEST_HOME/usr/bin_wrappers/myfile)" +} + +function test_create_wrappers_executable_no_longer_exist(){ + mkdir -p $JUNEST_HOME/usr/bin_wrappers + touch $JUNEST_HOME/usr/bin_wrappers/myfile + chmod +x $JUNEST_HOME/usr/bin_wrappers/myfile + assertCommandSuccess create_wrappers + assertEquals "" "$(cat $STDOUTF)" + assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" + assertTrue "myfile wrapper should not exist" "[ ! -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" +} + +source $(dirname $0)/../utils/shunit2 diff --git a/tests/utils/utils.sh b/tests/utils/utils.sh index ed7cb8c..542af68 100644 --- a/tests/utils/utils.sh +++ b/tests/utils/utils.sh @@ -11,6 +11,7 @@ function cwdTearDown(){ function junestSetUp(){ JUNEST_HOME=$(TMPDIR=/tmp mktemp -d -t junest-home.XXXXXXXXXX) + mkdir -p ${JUNEST_HOME}/usr/bin mkdir -p ${JUNEST_HOME}/etc/junest echo "JUNEST_ARCH=x86_64" > ${JUNEST_HOME}/etc/junest/info mkdir -p ${JUNEST_HOME}/etc/ca-certificates From d25ae301588a9cdad51f4cd571032c3da17952ac Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 29 Dec 2020 14:42:41 +0100 Subject: [PATCH 030/116] Update README --- README.md | 75 +++++++++++++++++++++------------ VERSION | 2 +- lib/checks/check.sh | 8 ---- tests/unit-tests/test-junest.sh | 3 ++ 4 files changed, 51 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index fc9f320..4779250 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ The lightweight Arch Linux based distro that runs upon any Linux distros without Description =========== **JuNest** (Jailed User NEST) is a lightweight Arch Linux based distribution -that allows to have disposable and isolated GNU/Linux environments +that allows to have disposable and partial isolated GNU/Linux environments within any generic GNU/Linux host OS and without the need to have root privileges for installing packages. @@ -41,7 +41,7 @@ The main advantages on using JuNest are: - Install packages without root privileges. - Partial isolated environment which you can install packages without affecting a production system. -- Access to a wide range of packages in particular on GNU/Linux distros that may contain limited repositories (such as CentOS and RedHat). +- Access to a wide range of packages, in particular on GNU/Linux distros that may contain limited repositories (such as CentOS and RedHat). - Available for `x86_64` and `arm` architectures but you can build your own image from scratch too! - Run on a different architecture from the host OS via QEMU - All Arch Linux lovers can have their favourite distro everywhere! @@ -57,7 +57,7 @@ build a complete isolated environment but, conversely, is the ability to run programs as they were running natively from the host OS. Almost everything is shared between host OS and the JuNest sandbox (kernel, process subtree, network, mounting, etc) and only the root filesystem gets isolated -(as the programs installed in JuNest need to reside elsewhere). +(since the programs installed in JuNest need to reside elsewhere). This allows interaction between processes belonging to both host OS and JuNest. For instance, you can install `top` command in JuNest in order to monitor @@ -107,6 +107,27 @@ There are multiple backend programs, each with its own pros/cons. To know more about the JuNest execution modes depending on the backend program used, see the [Usage](#usage) section below. +Run commands installed in JuNest directly from host +--------------------------------------- + +Installed programs can be accessible directly from host. +For instance, supposing the host OS is an Ubuntu distro you can directly +run `pacman` by simply updating the `PATH` variable: + +```sh +export PATH="$PATH:~/.junest/usr/bin_wrappers" +pacman -S htop +htop +``` + +By default the wrappers use `"ns --fakeroot"` but you can change it via `JUNEST_ARGS`. +For instance, if you want to run `iftop` with real root privileges: + +``` +pacman -S iftop +sudo JUNEST_ARGS="groot" iftop +``` + Have fun! --------- @@ -149,12 +170,22 @@ section below. ## Installation from git repository ## Just clone the JuNest repo somewhere (for example in ~/.local/share/junest): - git clone git://github.com/fsquillace/junest ~/.local/share/junest - export PATH=~/.local/share/junest/bin:$PATH +```sh +git clone git://github.com/fsquillace/junest ~/.local/share/junest +export PATH=~/.local/share/junest/bin:$PATH +``` + +Optionally you want to use the wrappers to run commands +installed in JuNest directly from host: + +```sh +export PATH="$PATH:~/.junest/usr/bin_wrappers" +``` +Update your `~/.bashrc` or `~/.zshrc` to get always the wrappers available. ### Installation using AUR (Arch Linux only) ### If you are using an Arch Linux system you can, alternatively, install JuNest from the [AUR repository](https://aur.archlinux.org/packages/junest-git/). -After installing junest will be located in `/opt/junest/` +JuNest will be located in `/opt/junest/` Usage ===== @@ -189,7 +220,8 @@ This mode is based on the fantastic PRoot based ----------- [Proot](https://wiki.archlinux.org/index.php/Proot) represents a portable -solution that works well in most of GNU/Linux distros available. +solution which allows unprivileged users to execute programs inside a sandbox +and works well in most of GNU/Linux distros available. One of the major drawbacks is the fact that Proot is not officially supported anymore, therefore, Proot bugs may no longer be fixed. @@ -203,7 +235,9 @@ Chroot based ------------ This solution suits only for privileged users. JuNest provides the possibility to run the environment via `chroot` program. -In particular, it uses a special program called `GRoot`, an enhanced `chroot` +In particular, it uses a special program called `GRoot`, a small and portable +version of +[arch-chroot](https://wiki.archlinux.org/index.php/Chroot) wrapper, that allows to bind mount directories specified by the user, such as `/proc`, `/sys`, `/dev`, `/tmp` and `$HOME`, before executing any programs inside the JuNest sandbox. In case the mounting will not @@ -275,7 +309,7 @@ To bind a host directory to a guest location, you can use proot arguments: junest proot -b "-b /mnt/mydata:/home/user/mydata" ``` -The option `-b` to provide options to the backeng program will work with PRoot, Namespace and GRoot backend programs. +The option `-b` to provide options to the backend program will work with PRoot, Namespace and GRoot backend programs. Check out the backend program options by passing `--help` option: ```sh @@ -303,21 +337,6 @@ Related wiki page: Internals ========= - -There are two main chroot jail used in JuNest. -The main one is [proot](https://wiki.archlinux.org/index.php/Proot) which -allows unprivileged users to execute programs inside a sandbox and -GRoot, a small and portable version of -[arch-chroot](https://wiki.archlinux.org/index.php/Chroot) which is an -enhanced chroot for privileged users that mounts the primary directories -(i.e. `/proc`, `/sys`, `/dev` and `/run`) before executing any programs inside -the sandbox. - -## Automatic fallback to classic chroot ## -If GRoot fails for some reasons in the host system (i.e. it is not able to -mount one of the directories), -JuNest automatically tries to fallback to the classic chroot. - ## Automatic fallback for all the dependent host OS executables ## JuNest attempts first to run the executables in the host OS located in different positions (`/usr/bin`, `/bin`, `/usr/sbin` and `/sbin`). @@ -325,10 +344,10 @@ As a fallback it tries to run the same executable if it is available in the JuNe environment. ## Automatic building of the JuNest images ## -There is not periodic automation build of the JuNest images yet. -This was due to the difficulty to automate builds for arm architecture. -The JuNest image for the `x86_64` is built periodically every once every three -months. +There is a periodic automation build of the JuNest images for `x86_64` arch +only. +The JuNest image for `arm` architecture may not be always up to date because +the build is performed manually. ## Static QEMU binaries ## There are static QEMU binaries included in JuNest image that allows to run JuNest diff --git a/VERSION b/VERSION index 77f5bec..1502020 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.2.2 +7.3.0 diff --git a/lib/checks/check.sh b/lib/checks/check.sh index 957156b..7af5832 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -95,12 +95,4 @@ then $SUDO pacman $PACMAN_OPTIONS -Rsn ${aur_package} fi -# The following ensures that the gpg agent gets killed (if exists) -# otherwise it is not possible to exit from the session -if [[ -e /etc/pacman.d/gnupg/S.gpg-agent ]] -then - gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye || echo "GPG agent did not close properly" - echo "GPG agent closed" -fi - exit 0 diff --git a/tests/unit-tests/test-junest.sh b/tests/unit-tests/test-junest.sh index e3c7ee1..0ba7cf5 100755 --- a/tests/unit-tests/test-junest.sh +++ b/tests/unit-tests/test-junest.sh @@ -31,6 +31,9 @@ function build_image_env(){ function delete_env(){ echo "delete_env" } +function create_wrappers(){ + : +} function setup_env_from_file(){ echo "setup_env_from_file($1)" } From d3f9f13ccd3c5a9798bb61c12686260c4bd9b973 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Wed, 30 Dec 2020 00:13:58 +0100 Subject: [PATCH 031/116] Fix deploy --- .travis.yml | 2 +- ci/deploy.sh | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 648a0cb..1122ce2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -87,4 +87,4 @@ after_success: ####################### # Deploy and validation ####################### - - ./ci/deploy.sh ${PWD}/junest-x86_64.tar.gz + - ./ci/deploy.sh ./junest-x86_64.tar.gz diff --git a/ci/deploy.sh b/ci/deploy.sh index fa2ff75..6053424 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -4,7 +4,7 @@ set -e IMG_PATH=$1 -set -u +set -ux MAX_OLD_IMAGES=30 @@ -31,14 +31,15 @@ then # Upload image # The put is done via a temporary filename in order to prevent outage on the # production file for a longer period of time. + img_name=$(basename ${IMG_PATH}) cp ${IMG_PATH} ${IMG_PATH}.temp aws s3 cp ${IMG_PATH}.temp s3://junest-repo/junest/ - aws s3 mv s3://junest-repo/junest/${IMG_PATH}.temp s3://junest-repo/junest/${IMG_PATH} - aws s3api put-object-acl --acl public-read --bucket junest-repo --key junest/${IMG_PATH} + aws s3 mv s3://junest-repo/junest/$img_name.temp s3://junest-repo/junest/$img_name + aws s3api put-object-acl --acl public-read --bucket junest-repo --key junest/$img_name DATE=$(date +'%Y-%m-%d-%H-%M-%S') - aws s3 cp ${IMG_PATH} s3://junest-repo/junest/${IMG_PATH}.${DATE} + aws s3 cp s3://junest-repo/junest/$img_name s3://junest-repo/junest/${img_name}.${DATE} # Cleanup old images aws s3 ls s3://junest-repo/junest/junest-${ARCH}.tar.gz. | awk '{print $4}' | head -n -${MAX_OLD_IMAGES} | xargs -I {} s3 rm "s3://junest-repo/junest/{}" From f98fa897bf7809a4642d9a377563a33b42c40fb2 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Wed, 30 Dec 2020 00:59:00 +0100 Subject: [PATCH 032/116] 7.3.1 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1502020..643916c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.0 +7.3.1 From 6291e5cc83cbe03f90671129fdc75bed122652d5 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Wed, 30 Dec 2020 13:08:01 +0100 Subject: [PATCH 033/116] Use the Junest repo to install package deps --- VERSION | 2 +- lib/core/build.sh | 17 +++++++---- pkgs/groot-git/PKGBUILD | 58 -------------------------------------- pkgs/proot-static/PKGBUILD | 39 ------------------------- pkgs/qemu-static/PKGBUILD | 50 -------------------------------- pkgs/sudo-fake/PKGBUILD | 45 ----------------------------- 6 files changed, 13 insertions(+), 198 deletions(-) delete mode 100644 pkgs/groot-git/PKGBUILD delete mode 100644 pkgs/proot-static/PKGBUILD delete mode 100644 pkgs/qemu-static/PKGBUILD delete mode 100644 pkgs/sudo-fake/PKGBUILD diff --git a/VERSION b/VERSION index 643916c..eab246c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.1 +7.3.2 diff --git a/lib/core/build.sh b/lib/core/build.sh index fb41ede..b387582 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -21,6 +21,8 @@ function _install_pkg_from_aur(){ } function _install_pkg(){ + # This function allows to install packages from AUR. + # At the moment is not used. local maindir=$1 local pkgbuilddir=$2 # Generate a working directory because sources will be downloaded to there @@ -40,6 +42,7 @@ function _prepare() { } function build_image_env(){ + set -x umask 022 # The function must runs on ArchLinux with non-root privileges. @@ -67,10 +70,13 @@ function build_image_env(){ fi sudo mkdir -p ${maindir}/root/run/lock - _install_pkg ${maindir} "$JUNEST_BASE/pkgs/sudo-fake" - _install_pkg ${maindir} "$JUNEST_BASE/pkgs/proot-static" - _install_pkg ${maindir} "$JUNEST_BASE/pkgs/qemu-static" - _install_pkg ${maindir} "$JUNEST_BASE/pkgs/groot-git" + sudo tee -a ${maindir}/root/etc/pacman.conf > /dev/null < ${maindir}/root/etc/${CMD}/info" - set -x info "Generating the locales..." # sed command is required for locale-gen but it is required by fakeroot # and cannot be removed @@ -130,4 +135,6 @@ function build_image_env(){ builtin cd ${ORIGIN_WD} trap - QUIT EXIT ABRT KILL TERM INT sudo rm -fr "$maindir" + + set +x } diff --git a/pkgs/groot-git/PKGBUILD b/pkgs/groot-git/PKGBUILD deleted file mode 100644 index 015f9a2..0000000 --- a/pkgs/groot-git/PKGBUILD +++ /dev/null @@ -1,58 +0,0 @@ -# Maintainer: Filippo Squillace -# More details on how to change this file: -# https://wiki.archlinux.org/index.php/PKGBUILD -# https://wiki.archlinux.org/index.php/Creating_packages -# https://wiki.archlinux.org/index.php/Arch_User_Repository#Submitting_packages - -pkgname=groot-git -pkgver=1.0.1 -pkgrel=1 -pkgdesc="" -arch=('any') -url="https://github.com/fsquillace/groot" -license=('GPL') -groups=() -depends=('coreutils') -makedepends=() -provides=('groot') -conflicts=() -replaces=() -backup=() -options=() -#install= -noextract=() - - -source=('groot::git+https://github.com/fsquillace/groot.git#branch=master') -md5sums=('SKIP') - - -pkgver() { - cd "$srcdir/${pkgname%-git}" - -# The examples below are not absolute and need to be adapted to each repo. The -# primary goal is to generate version numbers that will increase according to -# pacman's version comparisons with later commits to the repo. The format -# VERSION='VER_NUM.rREV_NUM.HASH', or a relevant subset in case VER_NUM or HASH -# are not available, is recommended. - -# Git, tags available - printf "%s" "$(git describe --tags | sed 's/\([^-]*-\)g/r\1/;s/-/./g')" - -# Git, no tags available -# printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" - -} - -build() { - : -} - -package() { - cd "$srcdir/${pkgname%-git}" - - install -d -m 755 "${pkgdir}/usr/bin" - install -m 755 "${srcdir}/${pkgname%-git}/bin/groot" ${pkgdir}/usr/bin/groot -} - -# vim:set ts=2 sw=2 et: diff --git a/pkgs/proot-static/PKGBUILD b/pkgs/proot-static/PKGBUILD deleted file mode 100644 index f73c126..0000000 --- a/pkgs/proot-static/PKGBUILD +++ /dev/null @@ -1,39 +0,0 @@ -# Maintainer: Filippo Squillace -# More details on how to change this file: -# https://wiki.archlinux.org/index.php/PKGBUILD -# https://wiki.archlinux.org/index.php/Creating_packages -# https://wiki.archlinux.org/index.php/Arch_User_Repository#Submitting_packages - -pkgname=proot-static -_pkgname=proot -pkgver=5.1.0 -pkgrel=1 -pkgdesc="chroot, mount --bind, and binfmt_misc without privilege/setup. Static binary only" -arch=('any') -url="https://proot-me.github.io/" -license=('GPL') -groups=() -depends=() -makedepends=() -provides=('proot') -conflicts=('proot' 'proot-bin') -backup=() -options=() -#install= -source=() -md5sums=() -noextract=() - -MAIN_REPO=https://s3-eu-west-1.amazonaws.com/junest-repo -PROOT_LINK=${MAIN_REPO}/proot - -source=("proot-x86_64"::"$PROOT_LINK/proot-x86_64" "proot-arm"::"$PROOT_LINK/proot-arm") -md5sums=('14080705dd45a6bafa20e909a68072cb' '8218c5f00e77e2e6e04c372ced27c7e7') - -package() { - echo "Installing proot static binaries" - install -d -m 755 "${pkgdir}/usr/bin/" - install -m 755 "${srcdir}/"${_pkgname}-* ${pkgdir}/usr/bin/ -} - -# vim:set ts=2 sw=2 et: diff --git a/pkgs/qemu-static/PKGBUILD b/pkgs/qemu-static/PKGBUILD deleted file mode 100644 index 3b7fc65..0000000 --- a/pkgs/qemu-static/PKGBUILD +++ /dev/null @@ -1,50 +0,0 @@ -# Maintainer: Filippo Squillace -# More details on how to change this file: -# https://wiki.archlinux.org/index.php/PKGBUILD -# https://wiki.archlinux.org/index.php/Creating_packages -# https://wiki.archlinux.org/index.php/Arch_User_Repository#Submitting_packages - -pkgname=qemu-static -pkgver=2.3.0 -pkgrel=1 -pkgdesc="Statically linked binaries of Qemu with user emulation. Useful for containers/chroot environment with binfmt." -arch=('any') -url="http://wiki.qemu.org" -license=('GPL2') -groups=() -depends=() -makedepends=() -provides=() -conflicts=() -backup=() -options=() -#install= -source=() -md5sums=() -noextract=() - -MAIN_REPO=https://s3-eu-west-1.amazonaws.com/junest-repo -QEMU_LINK=$MAIN_REPO/qemu - -source_x86_64=("${QEMU_LINK}/x86_64/qemu-x86_64-static-x86" "${QEMU_LINK}/x86_64/qemu-x86_64-static-arm") -source_i686=("${QEMU_LINK}/x86/qemu-x86-static-x86_64" "${QEMU_LINK}/x86/qemu-x86_64-static-arm") -md5sums_x86_64=('8a706d734f8c790743a8114dda4c344a' '3ced729c95d2514f35d4899e944a4582') -md5sums_x86=('c28d5049193dbce75efa0c8655d71427' 'f75fd15722fcc2914e3de0b0a46eb982') - -source_arm=("${QEMU_LINK}/arm/qemu-arm-static-x86_64" "${QEMU_LINK}/arm/qemu-arm-static-x86") -md5sums_arm=('bd9de1927aae4eb26dc0e5615159a616' 'a7c2b6ca53fa166f0c06ec76cc5edd7d') -source_armv6h=("${QEMU_LINK}/arm/qemu-arm-static-x86_64" "${QEMU_LINK}/arm/qemu-arm-static-x86") -md5sums_armv6h=('bd9de1927aae4eb26dc0e5615159a616' 'a7c2b6ca53fa166f0c06ec76cc5edd7d') -source_armv7h=("${QEMU_LINK}/arm/qemu-arm-static-x86_64" "${QEMU_LINK}/arm/qemu-arm-static-x86") -md5sums_armv7h=('bd9de1927aae4eb26dc0e5615159a616' 'a7c2b6ca53fa166f0c06ec76cc5edd7d') -source_aarch64=("${QEMU_LINK}/arm/qemu-arm-static-x86_64" "${QEMU_LINK}/arm/qemu-arm-static-x86") -md5sums_aarch64=('bd9de1927aae4eb26dc0e5615159a616' 'a7c2b6ca53fa166f0c06ec76cc5edd7d') - - -package() { - echo "Installing qemu static binaries" - install -d -m 755 "${pkgdir}/usr/bin" - install -m 755 "${srcdir}"/qemu-* ${pkgdir}/usr/bin -} - -# vim:set ts=2 sw=2 et: diff --git a/pkgs/sudo-fake/PKGBUILD b/pkgs/sudo-fake/PKGBUILD deleted file mode 100644 index 3587807..0000000 --- a/pkgs/sudo-fake/PKGBUILD +++ /dev/null @@ -1,45 +0,0 @@ -# Maintainer: Filippo Squillace -# More details on how to change this file: -# https://wiki.archlinux.org/index.php/PKGBUILD -# https://wiki.archlinux.org/index.php/Creating_packages -# https://wiki.archlinux.org/index.php/Arch_User_Repository#Submitting_packages - -pkgname=sudo-fake -pkgver=0.1.0 -pkgrel=1 -pkgdesc="Simple script that bypasses sudo and execute the actual command. Useful for fakeroot environments." -arch=('any') -url="" -license=('GPL') -groups=() -depends=('fakeroot' 'fakechroot') -makedepends=() -provides=('sudo') -conflicts=('sudo') -backup=() -options=() -#install= -source=() -md5sums=() -noextract=() - -package() { - install -d -m 755 "${pkgdir}/usr/bin/" - cat < "${pkgdir}/usr/bin/sudo" -#!/bin/bash -for opt in "\$@" -do - case "\$1" in - --) shift ; break ;; - -*) shift ;; - *) break ;; - esac -done - -[[ -z "\${@}" ]] || fakechroot fakeroot "\${@}" -EOF - - chmod 755 "${pkgdir}/usr/bin/sudo" -} - -# vim:set ts=2 sw=2 et: From 4527297be101e048c39a408965fd9ce75478b891 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Thu, 31 Dec 2020 12:05:23 +0100 Subject: [PATCH 034/116] Remove warnings when using pacman --- README.md | 14 ++++++++++++++ VERSION | 2 +- lib/core/namespace.sh | 2 +- tests/unit-tests/test-namespace.sh | 12 ++++++------ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 285d160..1d950d5 100644 --- a/README.md +++ b/README.md @@ -390,6 +390,20 @@ For Arch Linux related FAQs take a look at the [General troubleshooting page](ht > files as root. The package will still be installed correctly even though this > message is showed. +## Could not change the root directory in pacman + +> **Q**: In ns fakeroot mode when installing package I get the following error: + + could not change the root directory (Operation not permitted) + error: command failed to execute correctly + +> **A**: This is one of the last step executed in `pacman`. +> In any case, the package will still be installed correctly even though this +> message is showed. +> If you use `sudo` +> instead, the error should not appear given that the fake sudo script uses +> `fakechroot` internally. + ## No servers configured for repository ## > **Q**: Why I cannot install packages? diff --git a/VERSION b/VERSION index eab246c..44e98ad 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.2 +7.3.3 diff --git a/lib/core/namespace.sh b/lib/core/namespace.sh index 1307de0..6be2c5f 100644 --- a/lib/core/namespace.sh +++ b/lib/core/namespace.sh @@ -106,7 +106,7 @@ function run_env_as_bwrap_fakeroot(){ copy_common_files fi - _run_env_with_bwrap "$backend_command" "--uid 0 $backend_args" "$@" + _run_env_with_bwrap "$backend_command" "--uid 0 --gid 0 $backend_args" "$@" } diff --git a/tests/unit-tests/test-namespace.sh b/tests/unit-tests/test-namespace.sh index 9efbad3..02149b4 100755 --- a/tests/unit-tests/test-namespace.sh +++ b/tests/unit-tests/test-namespace.sh @@ -104,14 +104,14 @@ function test_is_user_namespace_enabled_with_userns_clone_file_enabled(){ function test_run_env_as_bwrap_fakeroot() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_fakeroot_with_backend_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "mybwrap" "" "false" - assertEquals "mybwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "mybwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } @@ -134,7 +134,7 @@ function test_run_env_as_bwrap_user_with_backend_command() { function test_run_env_as_bwrap_fakeroot_no_copy() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "true" "" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 /bin/sh --login" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -186,7 +186,7 @@ function test_run_env_as_bwrap_user_no_copy() { function test_run_env_as_bwrap_fakeroot_with_backend_args() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --bind /usr /usr /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 --bind /usr /usr /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } @@ -201,7 +201,7 @@ function test_run_env_as_bwrap_user_with_backend_args() { function test_run_env_as_bwrap_fakeroot_with_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" "ls -la" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files } @@ -216,7 +216,7 @@ function test_run_env_as_bwrap_user_with_command() { function test_run_env_as_bwrap_fakeroot_with_backend_args_and_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" "ls -la" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --bind /usr /usr /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 --bind /usr /usr /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files } From f0b6f0962e453a2dc3ea3da9b2f334a03c568dfb Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Mon, 4 Jan 2021 15:34:52 +0100 Subject: [PATCH 035/116] Use true fakechroot/fakeroot in ns fakeroot mode --- README.md | 12 ---------- bin/junest | 6 +---- lib/core/chroot.sh | 22 ++++++++---------- lib/core/common.sh | 14 +++++------ lib/core/namespace.sh | 37 +++++++++++------------------- lib/core/proot.sh | 20 +++++++--------- tests/unit-tests/test-chroot.sh | 8 +++---- tests/unit-tests/test-namespace.sh | 12 +++++----- 8 files changed, 49 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index 1d950d5..48337a6 100644 --- a/README.md +++ b/README.md @@ -392,18 +392,6 @@ For Arch Linux related FAQs take a look at the [General troubleshooting page](ht ## Could not change the root directory in pacman -> **Q**: In ns fakeroot mode when installing package I get the following error: - - could not change the root directory (Operation not permitted) - error: command failed to execute correctly - -> **A**: This is one of the last step executed in `pacman`. -> In any case, the package will still be installed correctly even though this -> message is showed. -> If you use `sudo` -> instead, the error should not appear given that the fake sudo script uses -> `fakechroot` internally. - ## No servers configured for repository ## > **Q**: Why I cannot install packages? diff --git a/bin/junest b/bin/junest index 2671e86..7040197 100755 --- a/bin/junest +++ b/bin/junest @@ -190,11 +190,7 @@ function _parse_proot_opts() { esac done - ARGS=() - for arg in "$@" - do - ARGS+=("$arg") - done + ARGS=("$@") } function _parse_build_opts() { diff --git a/lib/core/chroot.sh b/lib/core/chroot.sh index 635137b..afabc71 100644 --- a/lib/core/chroot.sh +++ b/lib/core/chroot.sh @@ -20,8 +20,8 @@ function _run_env_as_xroot(){ # SUDO_USER is more reliable compared to SUDO_UID [ -z $SUDO_USER ] || uid=$SUDO_USER:$SUDO_GID - local main_cmd="${SH[@]}" - [ "$1" != "" ] && main_cmd="$(insert_quotes_on_spaces "$@")" + local args=() + [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") # With chown the ownership of the files is assigned to the real user trap - QUIT EXIT ABRT KILL TERM INT @@ -32,7 +32,7 @@ function _run_env_as_xroot(){ copy_common_files fi - JUNEST_ENV=1 $cmd $backend_args "$JUNEST_HOME" "${SH[@]}" "-c" "${main_cmd}" + JUNEST_ENV=1 $cmd $backend_args "$JUNEST_HOME" "${DEFAULT_SH[@]}" "${args[@]}" } ####################################### @@ -43,13 +43,13 @@ function _run_env_as_xroot(){ # UID (RO) : The user ID. # SUDO_USER (RO) : The sudo user ID. # SUDO_GID (RO) : The sudo group ID. -# SH (RO) : Contains the default command to run in JuNest. +# DEFAULT_SH (RO) : Contains the default command to run in JuNest. # Arguments: # backend_args ($1) : The arguments to pass to backend program # no_copy_files ($2?) : If false it will copy some files in /etc # from host to JuNest environment. # cmd ($3-?) : The command to run inside JuNest environment. -# Default command is defined by SH variable. +# Default command is defined by DEFAULT_SH variable. # Returns: # $ARCHITECTURE_MISMATCH : If host and JuNest architecture are different. # Output: @@ -58,13 +58,11 @@ function _run_env_as_xroot(){ function run_env_as_groot(){ check_nested_env - local backend_command="$1" + local backend_command="${1:-$GROOT}" local backend_args="$2" local no_copy_files="$3" shift 3 - [[ -z "$backend_command" ]] && backend_command="$GROOT" - provide_common_bindings local bindings=${RESULT} unset RESULT @@ -80,13 +78,13 @@ function run_env_as_groot(){ # UID (RO) : The user ID. # SUDO_USER (RO) : The sudo user ID. # SUDO_GID (RO) : The sudo group ID. -# SH (RO) : Contains the default command to run in JuNest. +# DEFAULT_SH (RO) : Contains the default command to run in JuNest. # Arguments: # backend_args ($1) : The arguments to pass to backend program # no_copy_files ($2?) : If false it will copy some files in /etc # from host to JuNest environment. # cmd ($3-?) : The command to run inside JuNest environment. -# Default command is defined by SH variable. +# Default command is defined by DEFAULT_SH variable. # Returns: # $ARCHITECTURE_MISMATCH : If host and JuNest architecture are different. # Output: @@ -95,12 +93,10 @@ function run_env_as_groot(){ function run_env_as_chroot(){ check_nested_env - local backend_command="$1" + local backend_command="${1:-chroot_cmd}" local backend_args="$2" local no_copy_files="$3" shift 3 - [[ -z "$backend_command" ]] && backend_command=chroot_cmd - _run_env_as_xroot "$backend_command" "$backend_args" "$no_copy_files" "$@" } diff --git a/lib/core/common.sh b/lib/core/common.sh index 624a33c..a496522 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -64,7 +64,7 @@ ORIGIN_WD=$(pwd) # different locations in the host OS. # List of executables that are run inside JuNest: -SH=("/bin/sh" "--login") +DEFAULT_SH=("/bin/sh" "--login") # List of executables that are run in the host OS: PROOT="${JUNEST_HOME}/usr/bin/proot-${ARCH}" @@ -132,12 +132,12 @@ function unshare_cmd(){ # with --user option available. # Hence, give priority to the `unshare` executable in JuNest image. # Also, unshare provides an environment in which /bin/sh maps to dash shell, - # therefore it ignores all the remaining SH arguments (i.e. --login) as + # therefore it ignores all the remaining DEFAULT_SH arguments (i.e. --login) as # they are not supported by dash. - if $LD_EXEC ${JUNEST_HOME}/usr/bin/$UNSHARE --user "${SH[0]}" "-c" ":" + if $LD_EXEC ${JUNEST_HOME}/usr/bin/$UNSHARE --user "${DEFAULT_SH[0]}" "-c" ":" then $LD_EXEC ${JUNEST_HOME}/usr/bin/$UNSHARE "${@}" - elif $UNSHARE --user "${SH[0]}" "-c" ":" + elif $UNSHARE --user "${DEFAULT_SH[0]}" "-c" ":" then $UNSHARE "$@" else @@ -146,7 +146,7 @@ function unshare_cmd(){ } function bwrap_cmd(){ - if $LD_EXEC ${JUNEST_HOME}/usr/bin/$BWRAP --dev-bind / / "${SH[0]}" "-c" ":" + if $LD_EXEC ${JUNEST_HOME}/usr/bin/$BWRAP --dev-bind / / "${DEFAULT_SH[0]}" "-c" ":" then $LD_EXEC ${JUNEST_HOME}/usr/bin/$BWRAP "${@}" else @@ -157,10 +157,10 @@ function bwrap_cmd(){ function proot_cmd(){ local proot_args="$1" shift - if ${PROOT} ${proot_args} "${SH[@]}" "-c" ":" + if ${PROOT} ${proot_args} "${DEFAULT_SH[@]}" "-c" ":" then ${PROOT} ${proot_args} "${@}" - elif PROOT_NO_SECCOMP=1 ${PROOT} ${proot_args} "${SH[@]}" "-c" ":" + elif PROOT_NO_SECCOMP=1 ${PROOT} ${proot_args} "${DEFAULT_SH[@]}" "-c" ":" then warn "Warn: Proot is not properly working. Disabling SECCOMP and expect the application to run slowly in particular when it uses syscalls intensively." warn "Try to use Linux namespace instead as it is more reliable: junest ns" diff --git a/lib/core/namespace.sh b/lib/core/namespace.sh index 6be2c5f..45c7c09 100644 --- a/lib/core/namespace.sh +++ b/lib/core/namespace.sh @@ -55,34 +55,19 @@ function _check_user_namespace() { set -e } -function _run_env_with_bwrap(){ - local backend_command="$1" - local backend_args="$2" - shift 2 - - [[ -z "$backend_command" ]] && backend_command=bwrap_cmd - - if [[ "$1" != "" ]] - then - JUNEST_ENV=1 "$backend_command" --bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try ${backend_args} "${SH[@]}" "-c" "$(insert_quotes_on_spaces "${@}")" - else - JUNEST_ENV=1 "$backend_command" --bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try ${backend_args} "${SH[@]}" - fi - -} ####################################### # Run JuNest as fakeroot via bwrap # # Globals: # JUNEST_HOME (RO) : The JuNest home directory. -# SH (RO) : Contains the default command to run in JuNest. +# DEFAULT_SH (RO) : Contains the default command to run in JuNest. # Arguments: # backend_args ($1) : The arguments to pass to bwrap # no_copy_files ($2?) : If false it will copy some files in /etc # from host to JuNest environment. # cmd ($3-?) : The command to run inside JuNest environment. -# Default command is defined by SH variable. +# Default command is defined by DEFAULT_SH variable. # Returns: # $ARCHITECTURE_MISMATCH : If host and JuNest architecture are different. # $ROOT_ACCESS_ERROR : If the user is the real root. @@ -92,7 +77,7 @@ function _run_env_with_bwrap(){ function run_env_as_bwrap_fakeroot(){ check_nested_env - local backend_command="$1" + local backend_command="${1:-bwrap_cmd}" local backend_args="$2" local no_copy_files="$3" shift 3 @@ -106,7 +91,10 @@ function run_env_as_bwrap_fakeroot(){ copy_common_files fi - _run_env_with_bwrap "$backend_command" "--uid 0 --gid 0 $backend_args" "$@" + local args=() + [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") + + JUNEST_ENV=1 "$backend_command" --bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 $backend_args sudo "${DEFAULT_SH[@]}" "${args[@]}" } @@ -115,13 +103,13 @@ function run_env_as_bwrap_fakeroot(){ # # Globals: # JUNEST_HOME (RO) : The JuNest home directory. -# SH (RO) : Contains the default command to run in JuNest. +# DEFAULT_SH (RO) : Contains the default command to run in JuNest. # Arguments: # backend_args ($1) : The arguments to pass to bwrap # no_copy_files ($2?) : If false it will copy some files in /etc # from host to JuNest environment. # cmd ($3-?) : The command to run inside JuNest environment. -# Default command is defined by SH variable. +# Default command is defined by DEFAULT_SH variable. # Returns: # $ARCHITECTURE_MISMATCH : If host and JuNest architecture are different. # Output: @@ -130,7 +118,7 @@ function run_env_as_bwrap_fakeroot(){ function run_env_as_bwrap_user() { check_nested_env - local backend_command="$1" + local backend_command="${1:-bwrap_cmd}" local backend_args="$2" local no_copy_files="$3" shift 3 @@ -150,7 +138,10 @@ function run_env_as_bwrap_user() { copy_passwd_and_group fi - _run_env_with_bwrap "$backend_command" "$backend_args" "$@" + local args=() + [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") + + JUNEST_ENV=1 "$backend_command" --bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try $backend_args "${DEFAULT_SH[@]}" "${args[@]}" } diff --git a/lib/core/proot.sh b/lib/core/proot.sh index bce8295..1e258f2 100644 --- a/lib/core/proot.sh +++ b/lib/core/proot.sh @@ -9,18 +9,14 @@ # vim: ft=sh function _run_env_with_proot(){ - local backend_command="$1" + local backend_command="${1:-proot_cmd}" local backend_args="$2" shift 2 - [[ -z "$backend_command" ]] && backend_command=proot_cmd + local args=() + [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") - if [ "$1" != "" ] - then - JUNEST_ENV=1 "${backend_command}" "${backend_args}" "${SH[@]}" "-c" "$(insert_quotes_on_spaces "${@}")" - else - JUNEST_ENV=1 "${backend_command}" "${backend_args}" "${SH[@]}" - fi + JUNEST_ENV=1 "${backend_command}" "${backend_args}" "${DEFAULT_SH[@]}" "${args[@]}" } function _run_env_with_qemu(){ @@ -52,13 +48,13 @@ function _run_env_with_qemu(){ # Globals: # JUNEST_HOME (RO) : The JuNest home directory. # EUID (RO) : The user ID. -# SH (RO) : Contains the default command to run in JuNest. +# DEFAULT_SH (RO) : Contains the default command to run in JuNest. # Arguments: # backend_args ($1) : The arguments to pass to proot # no_copy_files ($2?) : If false it will copy some files in /etc # from host to JuNest environment. # cmd ($3-?) : The command to run inside JuNest environment. -# Default command is defined by SH variable. +# Default command is defined by DEFAULT_SH variable. # Returns: # $ROOT_ACCESS_ERROR : If the user is the real root. # Output: @@ -94,13 +90,13 @@ function run_env_as_proot_fakeroot(){ # Globals: # JUNEST_HOME (RO) : The JuNest home directory. # EUID (RO) : The user ID. -# SH (RO) : Contains the default command to run in JuNest. +# DEFAULT_SH (RO) : Contains the default command to run in JuNest. # Arguments: # backend_args ($1) : The arguments to pass to proot # no_copy_files ($2?) : If false it will copy some files in /etc # from host to JuNest environment. # cmd ($3-?) : The command to run inside JuNest environment. -# Default command is defined by SH variable. +# Default command is defined by DEFAULT_SH variable. # Returns: # $ROOT_ACCESS_ERROR : If the user is the real root. # Output: diff --git a/tests/unit-tests/test-chroot.sh b/tests/unit-tests/test-chroot.sh index 4556671..44999f7 100755 --- a/tests/unit-tests/test-chroot.sh +++ b/tests/unit-tests/test-chroot.sh @@ -44,12 +44,12 @@ function test_run_env_as_groot_cmd(){ function test_run_env_as_groot_no_cmd(){ assertCommandSuccess run_env_as_groot "" "" "false" "" - assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login" "$(cat $STDOUTF)" } function test_run_env_as_groot_with_backend_command(){ assertCommandSuccess run_env_as_groot "mychroot" "" "false" "" - assertEquals "mychroot -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "mychroot -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login" "$(cat $STDOUTF)" } function test_run_env_as_groot_no_copy(){ @@ -84,12 +84,12 @@ function test_run_env_as_chroot_cmd(){ function test_run_env_as_chroot_no_cmd(){ assertCommandSuccess run_env_as_chroot "" "" "false" "" - assertEquals "chroot_cmd $JUNEST_HOME /bin/sh --login -c /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "chroot_cmd $JUNEST_HOME /bin/sh --login" "$(cat $STDOUTF)" } function test_run_env_as_chroot_with_backend_command(){ assertCommandSuccess run_env_as_chroot "mychroot" "" "false" "" - assertEquals "mychroot $JUNEST_HOME /bin/sh --login -c /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "mychroot $JUNEST_HOME /bin/sh --login" "$(cat $STDOUTF)" } function test_run_env_as_chroot_no_copy(){ diff --git a/tests/unit-tests/test-namespace.sh b/tests/unit-tests/test-namespace.sh index 02149b4..e24311f 100755 --- a/tests/unit-tests/test-namespace.sh +++ b/tests/unit-tests/test-namespace.sh @@ -104,14 +104,14 @@ function test_is_user_namespace_enabled_with_userns_clone_file_enabled(){ function test_run_env_as_bwrap_fakeroot() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_fakeroot_with_backend_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "mybwrap" "" "false" - assertEquals "mybwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "mybwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } @@ -134,7 +134,7 @@ function test_run_env_as_bwrap_user_with_backend_command() { function test_run_env_as_bwrap_fakeroot_no_copy() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "true" "" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -186,7 +186,7 @@ function test_run_env_as_bwrap_user_no_copy() { function test_run_env_as_bwrap_fakeroot_with_backend_args() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 --bind /usr /usr /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } @@ -201,7 +201,7 @@ function test_run_env_as_bwrap_user_with_backend_args() { function test_run_env_as_bwrap_fakeroot_with_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" "ls -la" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files } @@ -216,7 +216,7 @@ function test_run_env_as_bwrap_user_with_command() { function test_run_env_as_bwrap_fakeroot_with_backend_args_and_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" "ls -la" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 --bind /usr /usr /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files } From 8d4217492ac4a95ca98065f727469884ce89d1cb Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Mon, 4 Jan 2021 21:09:50 +0100 Subject: [PATCH 036/116] 7.3.4 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 44e98ad..c968a57 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.3 +7.3.4 From 6548e19eb58d2a5753b7b2754e629bb3d56b3584 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 10 Jan 2021 13:12:11 +0100 Subject: [PATCH 037/116] Use proper proc,dev,sys binds for ns mode --- README.md | 3 +++ lib/core/namespace.sh | 5 +++-- tests/unit-tests/test-namespace.sh | 24 ++++++++++++------------ 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 48337a6..29d9df5 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,9 @@ first: ```sh pacman -Sy --ignore sudo base-devel +:: sudo is in IgnorePkg/IgnoreGroup. Install anyway? [Y/n] n +... +... ``` JuNest uses a modified version of `sudo`. That's why the original `sudo` diff --git a/lib/core/namespace.sh b/lib/core/namespace.sh index 45c7c09..c80b80d 100644 --- a/lib/core/namespace.sh +++ b/lib/core/namespace.sh @@ -10,6 +10,7 @@ # # vim: ft=sh +COMMON_BWRAP_OPTION="--bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --bind /sys /sys --bind /proc /proc --dev-bind-try /dev /dev --unshare-user-try" CONFIG_PROC_FILE="/proc/config.gz" CONFIG_BOOT_FILE="/boot/config-$($UNAME -r)" PROC_USERNS_CLONE_FILE="/proc/sys/kernel/unprivileged_userns_clone" @@ -94,7 +95,7 @@ function run_env_as_bwrap_fakeroot(){ local args=() [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") - JUNEST_ENV=1 "$backend_command" --bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 $backend_args sudo "${DEFAULT_SH[@]}" "${args[@]}" + JUNEST_ENV=1 "$backend_command" $COMMON_BWRAP_OPTION --uid 0 --gid 0 $backend_args sudo "${DEFAULT_SH[@]}" "${args[@]}" } @@ -141,7 +142,7 @@ function run_env_as_bwrap_user() { local args=() [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") - JUNEST_ENV=1 "$backend_command" --bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try $backend_args "${DEFAULT_SH[@]}" "${args[@]}" + JUNEST_ENV=1 "$backend_command" $COMMON_BWRAP_OPTION $backend_args "${DEFAULT_SH[@]}" "${args[@]}" } diff --git a/tests/unit-tests/test-namespace.sh b/tests/unit-tests/test-namespace.sh index e24311f..d2cafd9 100755 --- a/tests/unit-tests/test-namespace.sh +++ b/tests/unit-tests/test-namespace.sh @@ -104,21 +104,21 @@ function test_is_user_namespace_enabled_with_userns_clone_file_enabled(){ function test_run_env_as_bwrap_fakeroot() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_fakeroot_with_backend_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "mybwrap" "" "false" - assertEquals "mybwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "mybwrap $COMMON_BWRAP_OPTION --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_user() { assertCommandSuccess run_env_as_bwrap_user "" "" "false" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files @@ -126,7 +126,7 @@ function test_run_env_as_bwrap_user() { function test_run_env_as_bwrap_user_with_backend_command() { assertCommandSuccess run_env_as_bwrap_user "mybwrap" "" "false" - assertEquals "mybwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "mybwrap $COMMON_BWRAP_OPTION /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files @@ -134,7 +134,7 @@ function test_run_env_as_bwrap_user_with_backend_command() { function test_run_env_as_bwrap_fakeroot_no_copy() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "true" "" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -160,7 +160,7 @@ function test_run_env_as_bwrap_fakeroot_no_copy() { function test_run_env_as_bwrap_user_no_copy() { assertCommandSuccess run_env_as_bwrap_user "" "" "true" "" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION /bin/sh --login" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -186,14 +186,14 @@ function test_run_env_as_bwrap_user_no_copy() { function test_run_env_as_bwrap_fakeroot_with_backend_args() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_user_with_backend_args() { assertCommandSuccess run_env_as_bwrap_user "" "--bind /usr /usr" "false" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --bind /usr /usr /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION --bind /usr /usr /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files @@ -201,14 +201,14 @@ function test_run_env_as_bwrap_user_with_backend_args() { function test_run_env_as_bwrap_fakeroot_with_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" "ls -la" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION --uid 0 --gid 0 sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_user_with_command() { assertCommandSuccess run_env_as_bwrap_user "" "" "false" "ls -la" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files @@ -216,14 +216,14 @@ function test_run_env_as_bwrap_user_with_command() { function test_run_env_as_bwrap_fakeroot_with_backend_args_and_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" "ls -la" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_user_with_backend_args_and_command() { assertCommandSuccess run_env_as_bwrap_user "" "--bind /usr /usr" "false" "ls -la" - assertEquals "bwrap --bind $JUNEST_HOME / --bind $HOME $HOME --bind /tmp /tmp --proc /proc --dev /dev --unshare-user-try --bind /usr /usr /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION --bind /usr /usr /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files From b8ad2182be7e281f1637ebc75734eee5e7fd0bc4 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 10 Jan 2021 13:25:49 +0100 Subject: [PATCH 038/116] Update README --- README.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 29d9df5..fc0f5ba 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ The script will download the image from the repository and will place it to the Access to environment --------------------- -By default, JuNest run via the Linux namespaces (aka `ns`) as the backend program. To access via `ns` just type: +JuNest uses the Linux namespaces (aka `ns`) as the default backend program. To access via `ns` just type: ```sh junest @@ -90,8 +90,8 @@ junest You can use the command `sudo` to acquire fakeroot privileges and install/remove packages. -Alternatively, you can access root privileges without using `sudo` with the -`-f` option: +Alternatively, you can access fakeroot privileges without using `sudo` all the +time with the `-f` (or `--fakeroot`) option: ```sh junest -f @@ -107,7 +107,7 @@ There are multiple backend programs, each with its own pros/cons. To know more about the JuNest execution modes depending on the backend program used, see the [Usage](#usage) section below. -Run commands installed in JuNest directly from host +Run JuNest installed programs directly from host OS --------------------------------------- Installed programs can be accessible directly from host. @@ -120,7 +120,7 @@ pacman -S htop htop ``` -By default the wrappers use `"ns --fakeroot"` but you can change it via `JUNEST_ARGS`. +By default the wrappers use `"ns --fakeroot"` but you can change it via `JUNEST_ARGS` environment variable. For instance, if you want to run `iftop` with real root privileges: ``` @@ -128,18 +128,14 @@ pacman -S iftop sudo JUNEST_ARGS="groot" iftop ``` - -Have fun! ---------- - -If you are new on Arch Linux and you are not familiar with `pacman` package manager -visit the [pacman rosetta page](https://wiki.archlinux.org/index.php/Pacman_Rosetta). +Install packages from AUR +------------------------- In `ns` mode, you can easily install package from [AUR](https://aur.archlinux.org/) repository using the already available [`yay`](https://aur.archlinux.org/packages/yay/) command. In `proot` mode, JuNest does no longer support the building of AUR packages. -**Remember** that in order to build packages from source, `base-devel` package group is required +**Remember** that in order to build packages from AUR, `base-devel` package group is required first: ```sh @@ -150,7 +146,13 @@ pacman -Sy --ignore sudo base-devel ``` JuNest uses a modified version of `sudo`. That's why the original `sudo` -package has to be ignored in the previous command. +package must be ignored in the previous command. + +Have fun! +--------- + +If you are new on Arch Linux and you are not familiar with `pacman` package manager +visit the [pacman rosetta page](https://wiki.archlinux.org/index.php/Pacman_Rosetta). Installation ============ From 79e4107196a7019877c994f8e31ad6ce112e9b4d Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 10 Jan 2021 13:26:07 +0100 Subject: [PATCH 039/116] Update VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c968a57..d9edd15 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.4 +7.3.5 From 8e560b4a8af6dc50ea0d62872ee56d7bab65771e Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 16 Feb 2021 18:13:27 +0100 Subject: [PATCH 040/116] Make namespace check more robust and update README --- README.md | 4 ++-- lib/core/namespace.sh | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fc0f5ba..ee832f1 100644 --- a/README.md +++ b/README.md @@ -139,14 +139,14 @@ command. In `proot` mode, JuNest does no longer support the building of AUR pack first: ```sh -pacman -Sy --ignore sudo base-devel +pacman -Syu --ignore sudo base-devel :: sudo is in IgnorePkg/IgnoreGroup. Install anyway? [Y/n] n ... ... ``` JuNest uses a modified version of `sudo`. That's why the original `sudo` -package must be ignored in the previous command. +package **must be ignored** in the previous command. Have fun! --------- diff --git a/lib/core/namespace.sh b/lib/core/namespace.sh index c80b80d..e9d3a53 100644 --- a/lib/core/namespace.sh +++ b/lib/core/namespace.sh @@ -27,7 +27,9 @@ function _is_user_namespace_enabled() { return $NOT_EXISTING_FILE fi - if ! zgrep_cmd -q "CONFIG_USER_NS=y" $config_file + # `-q` option in zgrep may cause a gzip: stdout: Broken pipe + # Use redirect to /dev/null instead + if ! zgrep_cmd "CONFIG_USER_NS=y" $config_file > /dev/null then return $NO_CONFIG_FOUND fi @@ -37,7 +39,9 @@ function _is_user_namespace_enabled() { return 0 fi - if ! zgrep_cmd -q "1" $PROC_USERNS_CLONE_FILE + # `-q` option in zgrep may cause a gzip: stdout: Broken pipe + # Use redirect to /dev/null instead + if ! zgrep_cmd "1" $PROC_USERNS_CLONE_FILE > /dev/null then return $UNPRIVILEGED_USERNS_DISABLED fi From 700b809fbedacb26cc82b7d360950ac90365e5a3 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 16 Feb 2021 18:18:24 +0100 Subject: [PATCH 041/116] 7.3.6 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index d9edd15..ee11304 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.5 +7.3.6 From 6af7bae41836a4a866950a660537ab3d3cab3aad Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Wed, 24 Mar 2021 11:49:28 +0100 Subject: [PATCH 042/116] Fix wrappers using eval #262 --- README.md | 7 ++++--- VERSION | 2 +- lib/core/wrappers.sh | 5 ++++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ee832f1..eb5927b 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ to a wide range of packages from the Arch Linux repositories. The main advantages on using JuNest are: - Install packages without root privileges. -- Partial isolated environment which you can install packages without affecting a production system. +- Partial isolated environment in which you can install packages without affecting a production system. - Access to a wide range of packages, in particular on GNU/Linux distros that may contain limited repositories (such as CentOS and RedHat). - Available for `x86_64` and `arm` architectures but you can build your own image from scratch too! - Run on a different architecture from the host OS via QEMU @@ -51,7 +51,7 @@ JuNest follows the [Arch Linux philosophy](https://wiki.archlinux.org/index.php/ How different is JuNest from Docker and Vagrant? ------------------------------------------------ Although JuNest sounds similar to a virtualisation/Linux container -like system, -JuNest differentiate a lot between Docker and Vagrant. +JuNest is quite different from solutions like Docker or Vagrant. In fact, the purpose of JuNest is **not** to build a complete isolated environment but, conversely, is the ability to run programs as they were running natively from the host OS. Almost everything is shared @@ -110,7 +110,8 @@ used, see the [Usage](#usage) section below. Run JuNest installed programs directly from host OS --------------------------------------- -Installed programs can be accessible directly from host. +Installed programs can be accessible directly from host without +calling `junest` command. For instance, supposing the host OS is an Ubuntu distro you can directly run `pacman` by simply updating the `PATH` variable: diff --git a/VERSION b/VERSION index ee11304..704726e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.6 +7.3.7 diff --git a/lib/core/wrappers.sh b/lib/core/wrappers.sh index 184fca5..b3c63f3 100644 --- a/lib/core/wrappers.sh +++ b/lib/core/wrappers.sh @@ -11,12 +11,15 @@ function create_wrappers() { then continue fi + # Arguments inside a variable (i.e. `JUNEST_ARGS`) separated by quotes + # are not recognized normally unless using `eval`. More info here: + # https://github.com/fsquillace/junest/issues/262 cat < ${JUNEST_HOME}/usr/bin_wrappers/${file} #!/usr/bin/env bash JUNEST_ARGS=\${JUNEST_ARGS:-ns --fakeroot} -junest \${JUNEST_ARGS} -- ${file} "\$@" +eval junest \${JUNEST_ARGS[@]} -- ${file} "\$@" EOF chmod +x ${JUNEST_HOME}/usr/bin_wrappers/${file} done From 08553a447eba53a2ebab083e4a6a30269a92bf91 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Wed, 24 Mar 2021 11:54:17 +0100 Subject: [PATCH 043/116] Remove @ from wrapper --- lib/core/wrappers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/wrappers.sh b/lib/core/wrappers.sh index b3c63f3..1fd8696 100644 --- a/lib/core/wrappers.sh +++ b/lib/core/wrappers.sh @@ -19,7 +19,7 @@ function create_wrappers() { JUNEST_ARGS=\${JUNEST_ARGS:-ns --fakeroot} -eval junest \${JUNEST_ARGS[@]} -- ${file} "\$@" +eval junest \${JUNEST_ARGS} -- ${file} "\$@" EOF chmod +x ${JUNEST_HOME}/usr/bin_wrappers/${file} done From e9406123b9da8c5c8f67370a3c2e364c7ac9863f Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Fri, 18 Jun 2021 18:47:14 +0200 Subject: [PATCH 044/116] Test travis --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1122ce2..de3ab23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,6 +45,8 @@ env: - secure: "ZotyKKWH5ZrBXDdEnVmV22gbn86BBSiqDZn2d2jVAApgUQdDc3wa7/uYAZP1bts6oQ897nnkUSFHk3M3QAcIoPJerUITTU5D7yjKcFDejgHdpJ4t9XSajmpY9CgKftWapwliWG4wolAKwyAp5GnYqz4GGltHyGxbF/VzUNRF3lw=" # AWS_SECRET_ACCESS_KEY - secure: "AWixvJmhr6+rfF4cspMWMjkvLuOsdfNanLK5wrqkgx/0ezDGBBThH0qVhn5Mp1QFM6wVF+LRA6UESNnj0wNwByZHdM6LddkJWlWHb/qkVK+AO4RKUsXJWNyPyOkCNj/WEFpZHQKKUAlEtC8m8AmAcuoi90cr6ih0PXIePRyPFrM=" + # DOCKER_USERNAME + # DOCKER_PASSWORD before_install: - ./ci/install-bash.sh "$TRAVIS_BASH_VERSION" @@ -73,7 +75,8 @@ script: ####################### # Build and validation ####################### - - "curl -s https://raw.githubusercontent.com/bartoszek/arch-travis/master/arch-travis.sh | bash" + #- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + - "curl -s https://raw.githubusercontent.com/fsquillace/arch-travis/master/arch-travis.sh | bash" - "echo pacman pkg cache size: $(du -h ~/.pkg-cache|cut -f1) in $(ls ~/.pkg-cache|wc -l) files" - ls -l # Test the newly created JuNest image against Ubuntu host From fc3b54e97f652353ee403134d326d1a21288874e Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 19 Jun 2021 16:26:07 +0200 Subject: [PATCH 045/116] Authenticate to Docker hub --- .travis.yml | 4 +--- VERSION | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index de3ab23..786b363 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,8 +45,6 @@ env: - secure: "ZotyKKWH5ZrBXDdEnVmV22gbn86BBSiqDZn2d2jVAApgUQdDc3wa7/uYAZP1bts6oQ897nnkUSFHk3M3QAcIoPJerUITTU5D7yjKcFDejgHdpJ4t9XSajmpY9CgKftWapwliWG4wolAKwyAp5GnYqz4GGltHyGxbF/VzUNRF3lw=" # AWS_SECRET_ACCESS_KEY - secure: "AWixvJmhr6+rfF4cspMWMjkvLuOsdfNanLK5wrqkgx/0ezDGBBThH0qVhn5Mp1QFM6wVF+LRA6UESNnj0wNwByZHdM6LddkJWlWHb/qkVK+AO4RKUsXJWNyPyOkCNj/WEFpZHQKKUAlEtC8m8AmAcuoi90cr6ih0PXIePRyPFrM=" - # DOCKER_USERNAME - # DOCKER_PASSWORD before_install: - ./ci/install-bash.sh "$TRAVIS_BASH_VERSION" @@ -75,7 +73,7 @@ script: ####################### # Build and validation ####################### - #- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + - echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin - "curl -s https://raw.githubusercontent.com/fsquillace/arch-travis/master/arch-travis.sh | bash" - "echo pacman pkg cache size: $(du -h ~/.pkg-cache|cut -f1) in $(ls ~/.pkg-cache|wc -l) files" - ls -l diff --git a/VERSION b/VERSION index 704726e..8837f2c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.7 +7.3.8 From e45d76651ef0d4cf8c2b17c03673896520df6c03 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Thu, 9 Sep 2021 20:54:52 +0200 Subject: [PATCH 046/116] First commit --- lib/core/build.sh | 4 +++- lib/core/common.sh | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/core/build.sh b/lib/core/build.sh index b387582..b57cce2 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -76,7 +76,7 @@ function build_image_env(){ SigLevel = Optional TrustedOnly Server = https://raw.githubusercontent.com/fsquillace/junest-repo/master/any EOT - sudo pacman --noconfirm --config ${maindir}/root/etc/pacman.conf --root ${maindir}/root -Sy sudo-fake groot-git proot-static qemu-static + sudo pacman --noconfirm --config ${maindir}/root/etc/pacman.conf --root ${maindir}/root -Sy sudo-fake groot-git proot-static qemu-user-static-bin-alt info "Installing yay..." sudo pacman --noconfirm -S go @@ -100,7 +100,9 @@ EOT info "Setting up the pacman keyring (this might take a while!)..." # gawk command is required for pacman-key sudo pacman --noconfirm --root ${maindir}/root -S gawk + # TODO check why the following did not fail! sudo ${maindir}/root/bin/groot --no-umount --avoid-bind -b /dev ${maindir}/root bash -c ' + set -e pacman-key --init; for keyring_file in /usr/share/pacman/keyrings/*.gpg; do diff --git a/lib/core/common.sh b/lib/core/common.sh index a496522..f7c52ec 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -53,7 +53,7 @@ fi MAIN_REPO=https://s3-eu-west-1.amazonaws.com/${CMD}-repo ENV_REPO=${MAIN_REPO}/${CMD} -DEFAULT_MIRROR='https://mirrors.kernel.org/archlinux/$repo/os/$arch' +DEFAULT_MIRROR='https://mirror.rackspace.com/archlinux/$repo/os/$arch' ORIGIN_WD=$(pwd) From 86277fd58919af710f35c7b2a2613e4045fee0f8 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Thu, 9 Sep 2021 22:54:00 +0200 Subject: [PATCH 047/116] Put the original mirror back --- lib/core/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/common.sh b/lib/core/common.sh index f7c52ec..c8cc8a1 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -53,7 +53,7 @@ fi MAIN_REPO=https://s3-eu-west-1.amazonaws.com/${CMD}-repo ENV_REPO=${MAIN_REPO}/${CMD} -DEFAULT_MIRROR='https://mirror.rackspace.com/archlinux/$repo/os/$arch' +DEFAULT_MIRROR='https://mirrors.kernel.com/archlinux/$repo/os/$arch' ORIGIN_WD=$(pwd) From 9ecabcd5249577d2969e025ef4a9c5cb4b92f1bc Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 11 Sep 2021 14:15:48 +0200 Subject: [PATCH 048/116] Change mirrorlist, update the initial message, do not inherit PATH variable and use precompiled yay during build phase --- lib/core/build.sh | 18 +----------------- lib/core/common.sh | 4 ++-- lib/core/setup.sh | 5 ++++- 3 files changed, 7 insertions(+), 20 deletions(-) diff --git a/lib/core/build.sh b/lib/core/build.sh index b57cce2..e17650a 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -8,18 +8,6 @@ # # vim: ft=sh -function _install_pkg_from_aur(){ - local maindir=$1 - local pkgname=$2 - local installname=$3 - mkdir -p ${maindir}/packages/${pkgname} - builtin cd ${maindir}/packages/${pkgname} - $CURL "https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=${pkgname}" - [ -z "${installname}" ] || $CURL "https://aur.archlinux.org/cgit/aur.git/plain/${installname}?h=${pkgname}" - makepkg -sfcd - sudo pacman --noconfirm --root ${maindir}/root -U ${pkgname}*.pkg.tar.* -} - function _install_pkg(){ # This function allows to install packages from AUR. # At the moment is not used. @@ -76,11 +64,7 @@ function build_image_env(){ SigLevel = Optional TrustedOnly Server = https://raw.githubusercontent.com/fsquillace/junest-repo/master/any EOT - sudo pacman --noconfirm --config ${maindir}/root/etc/pacman.conf --root ${maindir}/root -Sy sudo-fake groot-git proot-static qemu-user-static-bin-alt - - info "Installing yay..." - sudo pacman --noconfirm -S go - _install_pkg_from_aur ${maindir} "yay" + sudo pacman --noconfirm --config ${maindir}/root/etc/pacman.conf --root ${maindir}/root -Sy sudo-fake groot-git proot-static qemu-user-static-bin-alt yay echo "Generating the metadata info" sudo install -d -m 755 "${maindir}/root/etc/${CMD}" diff --git a/lib/core/common.sh b/lib/core/common.sh index c8cc8a1..113fb14 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -25,7 +25,7 @@ JUNEST_TEMPDIR=${JUNEST_TEMPDIR:-/tmp} # The update of the variable PATH ensures that the executables are # found on different locations -PATH=$PATH:/usr/bin:/bin:/usr/sbin:/sbin +PATH=/usr/bin:/bin:/usr/local/bin:/usr/sbin:/sbin:${HOME}/.local/bin # The executable uname is essential in order to get the architecture # of the host system, so a fallback mechanism cannot be used for it. @@ -53,7 +53,7 @@ fi MAIN_REPO=https://s3-eu-west-1.amazonaws.com/${CMD}-repo ENV_REPO=${MAIN_REPO}/${CMD} -DEFAULT_MIRROR='https://mirrors.kernel.com/archlinux/$repo/os/$arch' +DEFAULT_MIRROR='https://mirror.rackspace.com/archlinux/$repo/os/$arch' ORIGIN_WD=$(pwd) diff --git a/lib/core/setup.sh b/lib/core/setup.sh index 532f2a2..28b04d3 100644 --- a/lib/core/setup.sh +++ b/lib/core/setup.sh @@ -54,7 +54,10 @@ function _setup_env(){ $TAR -zxpf ${imagepath} -C ${JUNEST_HOME} info "${NAME} installed successfully!" echo - info "Please change the pacman mirror URL in /etc/pacman.d/mirrorlist according to your location." + info "Default mirror URL set to: ${DEFAULT_MIRROR}" + info "You can change the pacman mirror URL in /etc/pacman.d/mirrorlist according to your location:" + info " \$EDITOR ${JUNEST_HOME}/etc/pacman.d/mirrorlist" + echo info "Remember to refresh the package databases from the server:" info " pacman -Syy" } From 38ab252f98f222acb6545e60832a57c992a1a280 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 21 Sep 2021 14:20:16 +0200 Subject: [PATCH 049/116] Enable all capabilities in ns fakeroot mode --- lib/core/namespace.sh | 2 +- tests/unit-tests/test-namespace.sh | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/core/namespace.sh b/lib/core/namespace.sh index e9d3a53..f15bbb4 100644 --- a/lib/core/namespace.sh +++ b/lib/core/namespace.sh @@ -99,7 +99,7 @@ function run_env_as_bwrap_fakeroot(){ local args=() [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") - JUNEST_ENV=1 "$backend_command" $COMMON_BWRAP_OPTION --uid 0 --gid 0 $backend_args sudo "${DEFAULT_SH[@]}" "${args[@]}" + JUNEST_ENV=1 "$backend_command" $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 $backend_args sudo "${DEFAULT_SH[@]}" "${args[@]}" } diff --git a/tests/unit-tests/test-namespace.sh b/tests/unit-tests/test-namespace.sh index d2cafd9..6b53e9c 100755 --- a/tests/unit-tests/test-namespace.sh +++ b/tests/unit-tests/test-namespace.sh @@ -104,14 +104,14 @@ function test_is_user_namespace_enabled_with_userns_clone_file_enabled(){ function test_run_env_as_bwrap_fakeroot() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" - assertEquals "bwrap $COMMON_BWRAP_OPTION --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_fakeroot_with_backend_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "mybwrap" "" "false" - assertEquals "mybwrap $COMMON_BWRAP_OPTION --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "mybwrap $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } @@ -134,7 +134,7 @@ function test_run_env_as_bwrap_user_with_backend_command() { function test_run_env_as_bwrap_fakeroot_no_copy() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "true" "" - assertEquals "bwrap $COMMON_BWRAP_OPTION --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -186,7 +186,7 @@ function test_run_env_as_bwrap_user_no_copy() { function test_run_env_as_bwrap_fakeroot_with_backend_args() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" - assertEquals "bwrap $COMMON_BWRAP_OPTION --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } @@ -201,7 +201,7 @@ function test_run_env_as_bwrap_user_with_backend_args() { function test_run_env_as_bwrap_fakeroot_with_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" "ls -la" - assertEquals "bwrap $COMMON_BWRAP_OPTION --uid 0 --gid 0 sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files } @@ -216,7 +216,7 @@ function test_run_env_as_bwrap_user_with_command() { function test_run_env_as_bwrap_fakeroot_with_backend_args_and_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" "ls -la" - assertEquals "bwrap $COMMON_BWRAP_OPTION --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "bwrap $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files } From 7fe9c0e9ec6a50e50050b601076edec9bbf1e675 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Wed, 13 Oct 2021 12:23:41 +0200 Subject: [PATCH 050/116] Fix the --backend-command option --- lib/checks/check_all.sh | 4 ++++ lib/core/common.sh | 6 +++--- lib/core/namespace.sh | 10 ++++++---- lib/core/proot.sh | 4 ++-- tests/unit-tests/test-common.sh | 2 +- tests/unit-tests/test-namespace.sh | 25 +++++++++++-------------- 6 files changed, 27 insertions(+), 24 deletions(-) diff --git a/lib/checks/check_all.sh b/lib/checks/check_all.sh index 9e5f0a6..c975542 100755 --- a/lib/checks/check_all.sh +++ b/lib/checks/check_all.sh @@ -13,8 +13,12 @@ CHECK_SCRIPT=${JUNEST_BASE}/lib/checks/check.sh $JUNEST_SCRIPT proot --fakeroot -- "$CHECK_SCRIPT" --skip-aur-tests $JUNEST_SCRIPT proot -- "$CHECK_SCRIPT" --skip-aur-tests --use-sudo +# Test the backend command option +$JUNEST_SCRIPT proot --backend-command "$JUNEST_HOME/usr/bin/proot-x86_64" -- exit $JUNEST_SCRIPT ns --fakeroot -- "$CHECK_SCRIPT" --skip-aur-tests $JUNEST_SCRIPT ns -- "$CHECK_SCRIPT" --use-sudo +# Test the backend command option +$JUNEST_SCRIPT ns --backend-command "$JUNEST_HOME/usr/bin/bwrap" -- exit sudo -E $JUNEST_SCRIPT groot -- "$CHECK_SCRIPT" --run-root-tests --skip-aur-tests # Test the wrappers work diff --git a/lib/core/common.sh b/lib/core/common.sh index 113fb14..ad2b0f7 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -67,6 +67,7 @@ ORIGIN_WD=$(pwd) DEFAULT_SH=("/bin/sh" "--login") # List of executables that are run in the host OS: +BWRAP="${JUNEST_HOME}/usr/bin/bwrap" PROOT="${JUNEST_HOME}/usr/bin/proot-${ARCH}" GROOT="${JUNEST_HOME}/usr/bin/groot" CLASSIC_CHROOT=chroot @@ -82,7 +83,6 @@ CP=cp # Used for checking user namespace in config.gz file ZGREP=zgrep UNSHARE=unshare -BWRAP=bwrap LD_EXEC="$LD_LIB --library-path ${JUNEST_HOME}/usr/lib:${JUNEST_HOME}/lib" @@ -146,9 +146,9 @@ function unshare_cmd(){ } function bwrap_cmd(){ - if $LD_EXEC ${JUNEST_HOME}/usr/bin/$BWRAP --dev-bind / / "${DEFAULT_SH[0]}" "-c" ":" + if $LD_EXEC $BWRAP --dev-bind / / "${DEFAULT_SH[0]}" "-c" ":" then - $LD_EXEC ${JUNEST_HOME}/usr/bin/$BWRAP "${@}" + $LD_EXEC $BWRAP "${@}" else die "Error: Something went wrong while executing bwrap command. Exiting" fi diff --git a/lib/core/namespace.sh b/lib/core/namespace.sh index f15bbb4..0567989 100644 --- a/lib/core/namespace.sh +++ b/lib/core/namespace.sh @@ -67,6 +67,7 @@ function _check_user_namespace() { # Globals: # JUNEST_HOME (RO) : The JuNest home directory. # DEFAULT_SH (RO) : Contains the default command to run in JuNest. +# BWRAP (RO): : The location of the bwrap binary. # Arguments: # backend_args ($1) : The arguments to pass to bwrap # no_copy_files ($2?) : If false it will copy some files in /etc @@ -82,7 +83,7 @@ function _check_user_namespace() { function run_env_as_bwrap_fakeroot(){ check_nested_env - local backend_command="${1:-bwrap_cmd}" + local backend_command="${1:-$BWRAP}" local backend_args="$2" local no_copy_files="$3" shift 3 @@ -99,7 +100,7 @@ function run_env_as_bwrap_fakeroot(){ local args=() [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") - JUNEST_ENV=1 "$backend_command" $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 $backend_args sudo "${DEFAULT_SH[@]}" "${args[@]}" + BWRAP="${backend_command}" JUNEST_ENV=1 bwrap_cmd $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 $backend_args sudo "${DEFAULT_SH[@]}" "${args[@]}" } @@ -109,6 +110,7 @@ function run_env_as_bwrap_fakeroot(){ # Globals: # JUNEST_HOME (RO) : The JuNest home directory. # DEFAULT_SH (RO) : Contains the default command to run in JuNest. +# BWRAP (RO): : The location of the bwrap binary. # Arguments: # backend_args ($1) : The arguments to pass to bwrap # no_copy_files ($2?) : If false it will copy some files in /etc @@ -123,7 +125,7 @@ function run_env_as_bwrap_fakeroot(){ function run_env_as_bwrap_user() { check_nested_env - local backend_command="${1:-bwrap_cmd}" + local backend_command="${1:-$BWRAP}" local backend_args="$2" local no_copy_files="$3" shift 3 @@ -146,7 +148,7 @@ function run_env_as_bwrap_user() { local args=() [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") - JUNEST_ENV=1 "$backend_command" $COMMON_BWRAP_OPTION $backend_args "${DEFAULT_SH[@]}" "${args[@]}" + BWRAP="${backend_command}" JUNEST_ENV=1 bwrap_cmd $COMMON_BWRAP_OPTION $backend_args "${DEFAULT_SH[@]}" "${args[@]}" } diff --git a/lib/core/proot.sh b/lib/core/proot.sh index 1e258f2..f074b47 100644 --- a/lib/core/proot.sh +++ b/lib/core/proot.sh @@ -9,14 +9,14 @@ # vim: ft=sh function _run_env_with_proot(){ - local backend_command="${1:-proot_cmd}" + local backend_command="${1:-$PROOT}" local backend_args="$2" shift 2 local args=() [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") - JUNEST_ENV=1 "${backend_command}" "${backend_args}" "${DEFAULT_SH[@]}" "${args[@]}" + PROOT="${backend_command}" JUNEST_ENV=1 proot_cmd "${backend_args}" "${DEFAULT_SH[@]}" "${args[@]}" } function _run_env_with_qemu(){ diff --git a/tests/unit-tests/test-common.sh b/tests/unit-tests/test-common.sh index dd77077..0aba4b7 100755 --- a/tests/unit-tests/test-common.sh +++ b/tests/unit-tests/test-common.sh @@ -143,7 +143,7 @@ function test_unshare(){ function test_bwrap(){ assertCommandSuccess bwrap_cmd new_program - assertEquals "$(echo -e "ld_exec ${JUNEST_HOME}/usr/bin/$BWRAP --dev-bind / / /bin/sh -c :\nld_exec ${JUNEST_HOME}/usr/bin/$BWRAP new_program")" "$(cat $STDOUTF)" + assertEquals "$(echo -e "ld_exec $BWRAP --dev-bind / / /bin/sh -c :\nld_exec $BWRAP new_program")" "$(cat $STDOUTF)" BWRAP=false LD_EXEC=false assertCommandFail bwrap_cmd new_program } diff --git a/tests/unit-tests/test-namespace.sh b/tests/unit-tests/test-namespace.sh index 6b53e9c..72b9035 100755 --- a/tests/unit-tests/test-namespace.sh +++ b/tests/unit-tests/test-namespace.sh @@ -16,10 +16,7 @@ function oneTimeSetUp(){ ## Mock functions ## function init_mocks() { function bwrap_cmd(){ - echo "bwrap $@" - } - function mybwrap(){ - echo "mybwrap $@" + echo "$BWRAP $@" } } @@ -104,7 +101,7 @@ function test_is_user_namespace_enabled_with_userns_clone_file_enabled(){ function test_run_env_as_bwrap_fakeroot() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" - assertEquals "bwrap $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } @@ -118,7 +115,7 @@ function test_run_env_as_bwrap_fakeroot_with_backend_command() { function test_run_env_as_bwrap_user() { assertCommandSuccess run_env_as_bwrap_user "" "" "false" - assertEquals "bwrap $COMMON_BWRAP_OPTION /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files @@ -134,7 +131,7 @@ function test_run_env_as_bwrap_user_with_backend_command() { function test_run_env_as_bwrap_fakeroot_no_copy() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "true" "" - assertEquals "bwrap $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -160,7 +157,7 @@ function test_run_env_as_bwrap_fakeroot_no_copy() { function test_run_env_as_bwrap_user_no_copy() { assertCommandSuccess run_env_as_bwrap_user "" "" "true" "" - assertEquals "bwrap $COMMON_BWRAP_OPTION /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION /bin/sh --login" "$(cat $STDOUTF)" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -186,14 +183,14 @@ function test_run_env_as_bwrap_user_no_copy() { function test_run_env_as_bwrap_fakeroot_with_backend_args() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" - assertEquals "bwrap $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_user_with_backend_args() { assertCommandSuccess run_env_as_bwrap_user "" "--bind /usr /usr" "false" - assertEquals "bwrap $COMMON_BWRAP_OPTION --bind /usr /usr /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --bind /usr /usr /bin/sh --login" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files @@ -201,14 +198,14 @@ function test_run_env_as_bwrap_user_with_backend_args() { function test_run_env_as_bwrap_fakeroot_with_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" "ls -la" - assertEquals "bwrap $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_user_with_command() { assertCommandSuccess run_env_as_bwrap_user "" "" "false" "ls -la" - assertEquals "bwrap $COMMON_BWRAP_OPTION /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files @@ -216,14 +213,14 @@ function test_run_env_as_bwrap_user_with_command() { function test_run_env_as_bwrap_fakeroot_with_backend_args_and_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" "ls -la" - assertEquals "bwrap $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files } function test_run_env_as_bwrap_user_with_backend_args_and_command() { assertCommandSuccess run_env_as_bwrap_user "" "--bind /usr /usr" "false" "ls -la" - assertEquals "bwrap $COMMON_BWRAP_OPTION --bind /usr /usr /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --bind /usr /usr /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" _test_copy_common_files _test_copy_remaining_files From 6e872c5f2657f17651c52933e74f8a963e99a08e Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Wed, 13 Oct 2021 22:33:09 +0200 Subject: [PATCH 051/116] Update version and README --- README.md | 2 +- VERSION | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index eb5927b..3f25266 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ The lightweight Arch Linux based distro that runs upon any Linux distros without |Project Status|Donation|Communication| |:------------:|:------:|:-----------:| -| [![Build status](https://api.travis-ci.org/fsquillace/junest.png?branch=master)](https://travis-ci.org/fsquillace/junest) [![OpenHub](https://www.openhub.net/p/junest/widgets/project_thin_badge.gif)](https://www.openhub.net/p/junest) | [![Github Sponsors](https://img.shields.io/badge/GitHub-Sponsors-orange.svg)](https://github.com/sponsors/fsquillace) [![PayPal](https://img.shields.io/badge/PayPal-Donation-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8LEHQKBCYTACY) | [![Join the gitter chat at https://gitter.im/fsquillace/junest](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/fsquillace/junest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![RSS](https://img.shields.io/badge/RSS-News-orange.svg)](http://fsquillace.github.io/junest-site/feed.xml) | +| [![Build status](https://api.travis-ci.com/fsquillace/junest.png?branch=master)](https://app.travis-ci.com/github/fsquillace/junest) [![OpenHub](https://www.openhub.net/p/junest/widgets/project_thin_badge.gif)](https://www.openhub.net/p/junest) | [![Github Sponsors](https://img.shields.io/badge/GitHub-Sponsors-orange.svg)](https://github.com/sponsors/fsquillace) [![PayPal](https://img.shields.io/badge/PayPal-Donation-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8LEHQKBCYTACY) | [![Join the gitter chat at https://gitter.im/fsquillace/junest](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/fsquillace/junest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![RSS](https://img.shields.io/badge/RSS-News-orange.svg)](http://fsquillace.github.io/junest-site/feed.xml) | **Table of Contents** - [Description](#description) diff --git a/VERSION b/VERSION index 8837f2c..7dc1035 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.8 +7.3.9 From 4036a7737be9bcfba87a953141e2c6509717dae5 Mon Sep 17 00:00:00 2001 From: Ayaka Mikazuki Date: Wed, 3 Nov 2021 11:18:42 +0800 Subject: [PATCH 052/116] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce38b1c..61cddb1 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ section below. ## Installation from git repository ## Just clone the JuNest repo somewhere (for example in ~/.local/share/junest): - git clone git://github.com/fsquillace/junest ~/.local/share/junest + git clone https://github.com/fsquillace/junest.git ~/.local/share/junest export PATH=~/.local/share/junest/bin:$PATH ### Installation using AUR (Arch Linux only) ### From 5e975243381d036dc95d92424d2152a365d81a3b Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Mon, 20 Dec 2021 18:45:43 +0000 Subject: [PATCH 053/116] Update README with proot updates --- README.md | 21 +++++++++------------ VERSION | 2 +- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 3f25266..564f013 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ JuNest ====== -The lightweight Arch Linux based distro that runs upon any Linux distros without root access. +The lightweight Arch Linux based distro that runs, without root privileges, upon any Linux distro.

=4.0)](https://www.gnu.org/software/bash/) - [GNU coreutils](https://www.gnu.org/software/coreutils/) -In `proot` mode, the minimum recommended Linux kernel for the host OS is 2.6.32 on x86 (64 bit) -and ARM architectures. It is still possible to run JuNest on lower -2.6.x host OS kernels but errors may appear, and some applications may -crash. For further information, read the [Troubleshooting](#troubleshooting) -section below. - - ## Installation from git repository ## Just clone the JuNest repo somewhere (for example in ~/.local/share/junest): ```sh -git clone git://github.com/fsquillace/junest ~/.local/share/junest +git clone https://github.com/fsquillace/junest.git ~/.local/share/junest export PATH=~/.local/share/junest/bin:$PATH ``` @@ -228,8 +221,6 @@ PRoot based [Proot](https://wiki.archlinux.org/index.php/Proot) represents a portable solution which allows unprivileged users to execute programs inside a sandbox and works well in most of GNU/Linux distros available. -One of the major drawbacks is the fact that Proot is not officially -supported anymore, therefore, Proot bugs may no longer be fixed. In order to run JuNest via Proot: @@ -237,6 +228,12 @@ In order to run JuNest via Proot: - As fakeroot - Allow to install/remove packages: `junest proot -f` +In `proot` mode, the minimum recommended Linux kernel for the host OS is 2.6.32 on x86 (64 bit) +and ARM architectures. It is still possible to run JuNest on lower +2.6.x host OS kernels but errors may appear, and some applications may +crash. For further information, read the [Troubleshooting](#troubleshooting) +section below. + Chroot based ------------ This solution suits only for privileged users. JuNest provides the possibility @@ -263,7 +260,7 @@ The following table shows the capabilities that each backend program is able to | | QEMU | Root privileges required | Manage Official Packages | Manage AUR Packages | Portability | Support | User modes | | --- | ---- | ------------------------ | ------------------------ | ------------------- | ----------- | ------- | ---------- | | **Linux Namespaces** | NO | NO | YES | YES | Poor | YES | Normal user and `fakeroot` | -| **Proot** | YES | NO | YES | NO | YES | Poor | Normal user and `fakeroot` | +| **Proot** | YES | NO | YES | NO | YES | YES | Normal user and `fakeroot` | | **Chroot** | NO | YES | YES | YES | YES | YES | `root` only | Advanced usage diff --git a/VERSION b/VERSION index 7dc1035..6fddc82 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.9 +7.3.10 From 4a1c11d4edf4207b27db2bfc63d861e1e5fc5019 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Mon, 20 Dec 2021 21:19:47 +0000 Subject: [PATCH 054/116] Fix deploy script --- ci/deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/deploy.sh b/ci/deploy.sh index 6053424..617755b 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -42,7 +42,7 @@ then aws s3 cp s3://junest-repo/junest/$img_name s3://junest-repo/junest/${img_name}.${DATE} # Cleanup old images - aws s3 ls s3://junest-repo/junest/junest-${ARCH}.tar.gz. | awk '{print $4}' | head -n -${MAX_OLD_IMAGES} | xargs -I {} s3 rm "s3://junest-repo/junest/{}" + aws s3 ls s3://junest-repo/junest/junest-${ARCH}.tar.gz. | awk '{print $4}' | head -n -${MAX_OLD_IMAGES} | xargs -I {} aws s3 rm "s3://junest-repo/junest/{}" # Test the newly deployed image can be downloaded correctly junest setup From de63bdf96a980b1edb57f603458d360f102334b9 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Fri, 31 Dec 2021 18:09:10 +0100 Subject: [PATCH 055/116] Change url main repo --- ci/deploy.sh | 1 - lib/core/common.sh | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ci/deploy.sh b/ci/deploy.sh index 617755b..d953f04 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -35,7 +35,6 @@ then cp ${IMG_PATH} ${IMG_PATH}.temp aws s3 cp ${IMG_PATH}.temp s3://junest-repo/junest/ aws s3 mv s3://junest-repo/junest/$img_name.temp s3://junest-repo/junest/$img_name - aws s3api put-object-acl --acl public-read --bucket junest-repo --key junest/$img_name DATE=$(date +'%Y-%m-%d-%H-%M-%S') diff --git a/lib/core/common.sh b/lib/core/common.sh index ad2b0f7..7618af5 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -51,7 +51,7 @@ else die "Unknown architecture ${HOST_ARCH}" fi -MAIN_REPO=https://s3-eu-west-1.amazonaws.com/${CMD}-repo +MAIN_REPO=https://dwa8bhj1f036z.cloudfront.net ENV_REPO=${MAIN_REPO}/${CMD} DEFAULT_MIRROR='https://mirror.rackspace.com/archlinux/$repo/os/$arch' From 6efc4d0f528cdbbf52cac44e1e9e45f6bf310d5d Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Fri, 31 Dec 2021 18:20:27 +0100 Subject: [PATCH 056/116] Update VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6fddc82..de0fc6a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.10 +7.3.11 From 7d8c619ee06127f8dd28d2238d881a3cfbfdb321 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Wed, 5 Jan 2022 23:47:55 +0100 Subject: [PATCH 057/116] #284 Fix copy command --- lib/core/common.sh | 8 +++++--- tests/unit-tests/test-common.sh | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/core/common.sh b/lib/core/common.sh index 7618af5..7d23d07 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -276,20 +276,22 @@ function copy_passwd_and_group(){ ! getent_cmd passwd ${USER} >> ${JUNEST_HOME}/etc/passwd then warn "getent command failed or does not exist. Binding directly from /etc/passwd." - copy_file /etc/passwd ${JUNEST_HOME}/etc/passwd + copy_file /etc/passwd fi if ! getent_cmd group > ${JUNEST_HOME}/etc/group then warn "getent command failed or does not exist. Binding directly from /etc/group." - copy_file /etc/group ${JUNEST_HOME}/etc/group + copy_file /etc/group fi return 0 } function copy_file() { local file="${1}" - [[ -r "$file" ]] && cp_cmd "$file" "${JUNEST_HOME}/$file" + # -f option ensure to remove destination file if it cannot be opened + # https://github.com/fsquillace/junest/issues/284 + [[ -r "$file" ]] && cp_cmd -f "$file" "${JUNEST_HOME}/$file" return 0 } diff --git a/tests/unit-tests/test-common.sh b/tests/unit-tests/test-common.sh index 0aba4b7..7037f98 100755 --- a/tests/unit-tests/test-common.sh +++ b/tests/unit-tests/test-common.sh @@ -197,7 +197,7 @@ function test_copy_passwd_and_group_fallback(){ echo $@ } CP=cp_cmd_mock GETENT=false LD_EXEC=false assertCommandSuccess copy_passwd_and_group - assertEquals "$(echo -e "/etc/passwd $JUNEST_HOME//etc/passwd\n/etc/group $JUNEST_HOME//etc/group")" "$(cat $STDOUTF)" + assertEquals "$(echo -e "-f /etc/passwd $JUNEST_HOME//etc/passwd\n-f /etc/group $JUNEST_HOME//etc/group")" "$(cat $STDOUTF)" } function test_copy_passwd_and_group_failure(){ From 5f7eaff50eec7c9beb4b4deb1f2ebbd56aa96810 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 8 Jan 2022 11:57:53 +0100 Subject: [PATCH 058/116] 7.3.12 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index de0fc6a..1cef271 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.11 +7.3.12 From bc543a928566f8457b07755726e1a1a183ced0bf Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Fri, 11 Feb 2022 12:12:42 +0100 Subject: [PATCH 059/116] Fix quoting in wrapper script The 'eval' introduced in #262 unfortunately breaks command invocations were a parameter contains spaces, such as rg "my pattern with spaces" as it would be called as `rg my pattern with spaces`. This can be fixed using printf. Using parameter extension quoting with ${@@Q} only works with bash >4.4 (but only >4.0 is required). At least the above invocation then works correctly! --- lib/core/wrappers.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/core/wrappers.sh b/lib/core/wrappers.sh index 1fd8696..45206bb 100644 --- a/lib/core/wrappers.sh +++ b/lib/core/wrappers.sh @@ -1,9 +1,9 @@ function create_wrappers() { - mkdir -p ${JUNEST_HOME}/usr/bin_wrappers + mkdir -p "${JUNEST_HOME}/usr/bin_wrappers" - cd ${JUNEST_HOME}/usr/bin + cd "${JUNEST_HOME}/usr/bin" || return 1 for file in * do [[ -x $file ]] || continue @@ -14,21 +14,21 @@ function create_wrappers() { # Arguments inside a variable (i.e. `JUNEST_ARGS`) separated by quotes # are not recognized normally unless using `eval`. More info here: # https://github.com/fsquillace/junest/issues/262 - cat < ${JUNEST_HOME}/usr/bin_wrappers/${file} + cat < "${JUNEST_HOME}/usr/bin_wrappers/${file}" #!/usr/bin/env bash JUNEST_ARGS=\${JUNEST_ARGS:-ns --fakeroot} -eval junest \${JUNEST_ARGS} -- ${file} "\$@" +eval junest "\${JUNEST_ARGS}" -- ${file} "\$(printf "%q" "\$@")" EOF - chmod +x ${JUNEST_HOME}/usr/bin_wrappers/${file} + chmod +x "${JUNEST_HOME}/usr/bin_wrappers/${file}" done # Remove wrappers no longer needed - cd ${JUNEST_HOME}/usr/bin_wrappers + cd "${JUNEST_HOME}/usr/bin_wrappers" || return 1 for file in * do - [[ -e ${JUNEST_HOME}/usr/bin/$file ]] || rm -f $file + [[ -e ${JUNEST_HOME}/usr/bin/$file ]] || rm -f "$file" done } From 2b9f1839f117dcd04fb575c5bada5155ac441d0d Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 13 Feb 2022 20:02:08 +0100 Subject: [PATCH 060/116] Add create-bin-wrappers command --- README.md | 2 +- bin/junest | 24 ++++++++++++++++++++++++ lib/core/wrappers.sh | 23 +++++++++++++++++++++-- tests/unit-tests/test-wrappers.sh | 19 ++++++++++++++++--- 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 564f013..458c1ac 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ Run JuNest installed programs directly from host OS --------------------------------------- Installed programs can be accessible directly from host without -calling `junest` command. +entering directly into a JuNest session (no need to call `junest` command). For instance, supposing the host OS is an Ubuntu distro you can directly run `pacman` by simply updating the `PATH` variable: diff --git a/bin/junest b/bin/junest index 7040197..22540fb 100755 --- a/bin/junest +++ b/bin/junest @@ -68,6 +68,9 @@ usage() { echo -e " b[uild] Build a $NAME image (must run in ArchLinux)" echo -e " -n, --disable-check Disable the $NAME image check" echo + echo -e " create-bin-wrappers Create bin wrappers in $JUNEST_HOME/usr/bin_wrappers" + echo -e " -f, --force Replace the wrapper files even if they already exist" + echo } version() { @@ -78,6 +81,7 @@ function parse_arguments(){ # Actions ACT_SETUP=false ACT_BUILD=false + ACT_CREATE_WRAPPERS=false ACT_NAMESPACE=false ACT_PROOT=false ACT_GROOT=false @@ -88,6 +92,7 @@ function parse_arguments(){ case "$1" in s|setup) ACT_SETUP=true ; shift ;; b|build) ACT_BUILD=true ; shift ;; + create-bin-wrappers) ACT_CREATE_WRAPPERS=true ; shift ;; n|ns) ACT_NAMESPACE=true ; shift ;; p|proot) ACT_PROOT=true ; shift ;; g|groot) ACT_GROOT=true ; shift ;; @@ -103,6 +108,9 @@ function parse_arguments(){ elif $ACT_BUILD then _parse_build_opts "$@" + elif $ACT_CREATE_WRAPPERS + then + _parse_create_wrappers_opts "$@" elif $ACT_NAMESPACE then _parse_ns_opts "$@" @@ -204,6 +212,17 @@ function _parse_build_opts() { done } +function _parse_create_wrappers_opts() { + OPT_FORCE=false + while [[ -n "$1" ]] + do + case "$1" in + -f|--force) OPT_FORCE=true ; shift ;; + *) die "Invalid option $1" ;; + esac + done +} + function _parse_setup_opts() { OPT_FROM_FILE=false IMAGE_FILE="" @@ -256,6 +275,11 @@ function execute_operation() { die "Error: The image is still not installed in $JUNEST_HOME. Run this first: $CMD setup" fi + if $ACT_CREATE_WRAPPERS; then + create_wrappers $OPT_FORCE + exit + fi + local run_env if $ACT_NAMESPACE; then if $OPT_FAKEROOT; then diff --git a/lib/core/wrappers.sh b/lib/core/wrappers.sh index 45206bb..da5517f 100644 --- a/lib/core/wrappers.sh +++ b/lib/core/wrappers.sh @@ -1,13 +1,32 @@ +#!/usr/bin/env bash +# +# Dependencies: +# None +# +# vim: ft=sh - +####################################### +# Create bin wrappers +# +# Globals: +# JUNEST_HOME (RO) : The JuNest home directory. +# Arguments: +# force ($1?) : Create bin wrappers even if the bin file exists. +# Defaults to false. +# Returns: +# None +# Output: +# None +####################################### function create_wrappers() { + local force=${1:-false} mkdir -p "${JUNEST_HOME}/usr/bin_wrappers" cd "${JUNEST_HOME}/usr/bin" || return 1 for file in * do [[ -x $file ]] || continue - if [[ -e ${JUNEST_HOME}/usr/bin_wrappers/$file ]] + if [[ -e ${JUNEST_HOME}/usr/bin_wrappers/$file ]] && ! $force then continue fi diff --git a/tests/unit-tests/test-wrappers.sh b/tests/unit-tests/test-wrappers.sh index a78c81f..9daf0f9 100755 --- a/tests/unit-tests/test-wrappers.sh +++ b/tests/unit-tests/test-wrappers.sh @@ -45,13 +45,26 @@ function test_create_wrappers_already_exist(){ touch $JUNEST_HOME/usr/bin/myfile chmod +x $JUNEST_HOME/usr/bin/myfile mkdir -p $JUNEST_HOME/usr/bin_wrappers - touch $JUNEST_HOME/usr/bin_wrappers/myfile + echo "original" > $JUNEST_HOME/usr/bin_wrappers/myfile chmod +x $JUNEST_HOME/usr/bin_wrappers/myfile - assertCommandSuccess create_wrappers + assertCommandSuccess create_wrappers false assertEquals "" "$(cat $STDOUTF)" assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" assertTrue "myfile wrapper should exist" "[ -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" - assertEquals "" "$(touch $JUNEST_HOME/usr/bin_wrappers/myfile)" + assertEquals "original" "$(cat $JUNEST_HOME/usr/bin_wrappers/myfile)" +} + +function test_create_wrappers_forced_already_exist(){ + echo "new" > $JUNEST_HOME/usr/bin/myfile + chmod +x $JUNEST_HOME/usr/bin/myfile + mkdir -p $JUNEST_HOME/usr/bin_wrappers + echo "original" > $JUNEST_HOME/usr/bin_wrappers/myfile + chmod +x $JUNEST_HOME/usr/bin_wrappers/myfile + assertCommandSuccess create_wrappers true + assertEquals "" "$(cat $STDOUTF)" + assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" + assertTrue "myfile wrapper should exist" "[ -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" + assertNotEquals "original" "$(cat $JUNEST_HOME/usr/bin_wrappers/myfile)" } function test_create_wrappers_executable_no_longer_exist(){ From e794a6150cdb3d6298685dcd3c8cb12ffe06aa24 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Wed, 16 Feb 2022 22:55:40 +0100 Subject: [PATCH 061/116] Add more unit tests --- bin/junest | 2 +- lib/checks/check_all.sh | 1 + tests/unit-tests/test-junest.sh | 143 +++++++++++++++++--------------- 3 files changed, 79 insertions(+), 67 deletions(-) diff --git a/bin/junest b/bin/junest index 22540fb..c09f339 100755 --- a/bin/junest +++ b/bin/junest @@ -69,7 +69,7 @@ usage() { echo -e " -n, --disable-check Disable the $NAME image check" echo echo -e " create-bin-wrappers Create bin wrappers in $JUNEST_HOME/usr/bin_wrappers" - echo -e " -f, --force Replace the wrapper files even if they already exist" + echo -e " -f, --force Create the wrapper files even if they already exist" echo } diff --git a/lib/checks/check_all.sh b/lib/checks/check_all.sh index c975542..210ebfb 100755 --- a/lib/checks/check_all.sh +++ b/lib/checks/check_all.sh @@ -22,4 +22,5 @@ $JUNEST_SCRIPT ns --backend-command "$JUNEST_HOME/usr/bin/bwrap" -- exit sudo -E $JUNEST_SCRIPT groot -- "$CHECK_SCRIPT" --run-root-tests --skip-aur-tests # Test the wrappers work +$JUNEST_SCRIPT create-bin-wrappers --force $JUNEST_HOME/usr/bin_wrappers/pacman --help diff --git a/tests/unit-tests/test-junest.sh b/tests/unit-tests/test-junest.sh index 0ba7cf5..123b4bd 100755 --- a/tests/unit-tests/test-junest.sh +++ b/tests/unit-tests/test-junest.sh @@ -12,75 +12,74 @@ function oneTimeSetUp(){ } function setUp(){ + ## Mock functions ## + function usage(){ + echo "usage" + } + function version(){ + echo "version" + } + function build_image_env(){ + local disable_check=$1 + echo "build_image_env($disable_check)" + } + function delete_env(){ + echo "delete_env" + } + function setup_env_from_file(){ + echo "setup_env_from_file($1)" + } + function setup_env(){ + echo "setup_env($1)" + } + function run_env_as_proot_fakeroot(){ + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 + echo "run_env_as_proot_fakeroot($backend_command,$backend_args,$no_copy_files,$@)" + } + function run_env_as_groot(){ + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 + echo "run_env_as_groot($backend_command,$backend_args,$no_copy_files,$@)" + } + function run_env_as_chroot(){ + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 + echo "run_env_as_chroot($backend_command,$backend_args,$no_copy_files,$@)" + } + function run_env_as_proot_user(){ + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 + echo "run_env_as_proot_user($backend_command,$backend_args,$no_copy_files,$@)" + } + function run_env_as_bwrap_fakeroot(){ + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 + echo "run_env_as_bwrap_fakeroot($backend_command,$backend_args,$no_copy_files,$@)" + } + function run_env_as_bwrap_user(){ + local backend_command="$1" + local backend_args="$2" + local no_copy_files="$3" + shift 3 + echo "run_env_as_bwrap_user($backend_command,$backend_args,$no_copy_files,$@)" + } function is_env_installed(){ return 0 } -} - -## Mock functions ## -function usage(){ - echo "usage" -} -function version(){ - echo "version" -} -function build_image_env(){ - local disable_check=$1 - echo "build_image_env($disable_check)" -} -function delete_env(){ - echo "delete_env" -} -function create_wrappers(){ - : -} -function setup_env_from_file(){ - echo "setup_env_from_file($1)" -} -function setup_env(){ - echo "setup_env($1)" -} -function run_env_as_proot_fakeroot(){ - local backend_command="$1" - local backend_args="$2" - local no_copy_files="$3" - shift 3 - echo "run_env_as_proot_fakeroot($backend_command,$backend_args,$no_copy_files,$@)" -} -function run_env_as_groot(){ - local backend_command="$1" - local backend_args="$2" - local no_copy_files="$3" - shift 3 - echo "run_env_as_groot($backend_command,$backend_args,$no_copy_files,$@)" -} -function run_env_as_chroot(){ - local backend_command="$1" - local backend_args="$2" - local no_copy_files="$3" - shift 3 - echo "run_env_as_chroot($backend_command,$backend_args,$no_copy_files,$@)" -} -function run_env_as_proot_user(){ - local backend_command="$1" - local backend_args="$2" - local no_copy_files="$3" - shift 3 - echo "run_env_as_proot_user($backend_command,$backend_args,$no_copy_files,$@)" -} -function run_env_as_bwrap_fakeroot(){ - local backend_command="$1" - local backend_args="$2" - local no_copy_files="$3" - shift 3 - echo "run_env_as_bwrap_fakeroot($backend_command,$backend_args,$no_copy_files,$@)" -} -function run_env_as_bwrap_user(){ - local backend_command="$1" - local backend_args="$2" - local no_copy_files="$3" - shift 3 - echo "run_env_as_bwrap_user($backend_command,$backend_args,$no_copy_files,$@)" + function create_wrappers(){ + : + } } function test_help(){ @@ -106,6 +105,18 @@ function test_build_image_env(){ assertEquals "build_image_env(true)" "$(cat $STDOUTF)" } +function test_create_wrappers(){ + function create_wrappers(){ + local force=$1 + echo "create_wrappers($force)" + } + assertCommandSuccess main create-bin-wrappers + assertEquals "create_wrappers(false)" "$(cat $STDOUTF)" + + assertCommandSuccess main create-bin-wrappers --force + assertEquals "create_wrappers(true)" "$(cat $STDOUTF)" +} + function test_delete_env(){ assertCommandSuccess main s -d assertEquals "delete_env" "$(cat $STDOUTF)" From 0295f37758c0fdeb9b45f05f7ed10941a9e52bd3 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 27 Feb 2022 22:43:12 +0100 Subject: [PATCH 062/116] Add shellcheck --- .travis.yml | 1 + bin/junest | 16 +-- ci/deploy.sh | 14 +-- ci/install-bash.sh | 6 +- lib/checks/check.sh | 18 ++- lib/checks/check_all.sh | 8 +- lib/core/build.sh | 62 +++++----- lib/core/chroot.sh | 6 +- lib/core/common.sh | 57 ++++----- lib/core/namespace.sh | 17 +-- lib/core/proot.sh | 14 ++- lib/core/setup.sh | 38 +++--- lib/utils/utils.sh | 54 ++++----- tests/checkstyle/checkstyle.sh | 17 +-- tests/unit-tests/test-chroot.sh | 30 ++--- tests/unit-tests/test-common.sh | 112 +++++++++--------- tests/unit-tests/test-junest.sh | 178 +++++++++++++++-------------- tests/unit-tests/test-namespace.sh | 54 +++++---- tests/unit-tests/test-proot.sh | 88 ++++++++------ tests/unit-tests/test-setup.sh | 31 ++--- tests/unit-tests/test-utils.sh | 64 ++++------- tests/unit-tests/test-wrappers.sh | 56 ++++----- tests/unit-tests/unit-tests.sh | 3 +- tests/utils/utils.sh | 31 ++--- 24 files changed, 519 insertions(+), 456 deletions(-) diff --git a/.travis.yml b/.travis.yml index 786b363..2ad29e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -61,6 +61,7 @@ script: - bash --version - bash ./tests/checkstyle/checkstyle.sh - bash ./tests/unit-tests/unit-tests.sh + - shellcheck bin/junest lib/**/*.sh ci/*.sh tests/**/*.sh # ARM with qemu does seem to work properly. Disabling integ tests for ARM for now. #- export JUNEST_HOME=~/.junest-arm diff --git a/bin/junest b/bin/junest index c09f339..d3435fe 100755 --- a/bin/junest +++ b/bin/junest @@ -1,4 +1,5 @@ #!/usr/bin/env bash +# shellcheck disable=SC1091 # # This file is part of JuNest (https://github.com/fsquillace/junest). # @@ -7,7 +8,7 @@ set -e # JUNEST_BASE can be overridden for testing purposes. # There is no need for doing it for normal usage. -JUNEST_BASE="${JUNEST_BASE:-$(readlink -f $(dirname $(readlink -f "$0"))/..)}" +JUNEST_BASE="${JUNEST_BASE:-$(readlink -f "$(dirname "$(readlink -f "$0")")"/..)}" source "${JUNEST_BASE}/lib/utils/utils.sh" source "${JUNEST_BASE}/lib/core/common.sh" @@ -24,7 +25,7 @@ source "${JUNEST_BASE}/lib/core/wrappers.sh" ### General functions ### ################################### usage() { - echo -e "$NAME (v$(cat $JUNEST_BASE/VERSION)): $DESCRIPTION" + echo -e "$NAME (v$(cat "$JUNEST_BASE"/VERSION)): $DESCRIPTION" echo echo -e "Usage: $CMD [action] [options] [--] [command]" echo @@ -74,7 +75,7 @@ usage() { } version() { - echo -e "$NAME $(cat $JUNEST_BASE/VERSION)" + echo -e "$NAME $(cat "$JUNEST_BASE"/VERSION)" } function parse_arguments(){ @@ -226,14 +227,13 @@ function _parse_create_wrappers_opts() { function _parse_setup_opts() { OPT_FROM_FILE=false IMAGE_FILE="" - OPT_ARCH=false ARCH_ARG="" OPT_DELETE=false while [[ -n "$1" ]] do case "$1" in -i|--from-file) OPT_FROM_FILE=true ; shift ; IMAGE_FILE=$1 ; shift ;; - -a|--arch) OPT_ARCH=true ; shift ; ARCH_ARG=$1; shift ;; + -a|--arch) shift ; ARCH_ARG=$1; shift ;; -d|--delete) OPT_DELETE=true ; shift ;; *) die "Invalid option $1" ;; esac @@ -259,9 +259,9 @@ function execute_operation() { fi if $OPT_FROM_FILE; then - setup_env_from_file $IMAGE_FILE + setup_env_from_file "$IMAGE_FILE" else - setup_env $ARCH_ARG + setup_env "$ARCH_ARG" fi create_wrappers fi @@ -300,7 +300,7 @@ function execute_operation() { fi # Call create_wrappers in case new bin files have been created - trap "create_wrappers" EXIT QUIT TERM KILL + trap "create_wrappers" EXIT QUIT TERM $run_env "$BACKEND_COMMAND" "${BACKEND_ARGS}" $OPT_NO_COPY_FILES "${ARGS[@]}" } diff --git a/ci/deploy.sh b/ci/deploy.sh index d953f04..b3ba92c 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -10,10 +10,10 @@ MAX_OLD_IMAGES=30 # ARCH can be one of: x86, x86_64, arm HOST_ARCH=$(uname -m) -if [ $HOST_ARCH == "i686" ] || [ $HOST_ARCH == "i386" ] +if [ "$HOST_ARCH" == "i686" ] || [ "$HOST_ARCH" == "i386" ] then ARCH="x86" -elif [ $HOST_ARCH == "x86_64" ] +elif [ "$HOST_ARCH" == "x86_64" ] then ARCH="x86_64" elif [[ $HOST_ARCH =~ .*(arm).* ]] @@ -31,14 +31,14 @@ then # Upload image # The put is done via a temporary filename in order to prevent outage on the # production file for a longer period of time. - img_name=$(basename ${IMG_PATH}) - cp ${IMG_PATH} ${IMG_PATH}.temp - aws s3 cp ${IMG_PATH}.temp s3://junest-repo/junest/ - aws s3 mv s3://junest-repo/junest/$img_name.temp s3://junest-repo/junest/$img_name + img_name=$(basename "${IMG_PATH}") + cp "${IMG_PATH}" "${IMG_PATH}".temp + aws s3 cp "${IMG_PATH}".temp s3://junest-repo/junest/ + aws s3 mv s3://junest-repo/junest/"$img_name".temp s3://junest-repo/junest/"$img_name" DATE=$(date +'%Y-%m-%d-%H-%M-%S') - aws s3 cp s3://junest-repo/junest/$img_name s3://junest-repo/junest/${img_name}.${DATE} + aws s3 cp "s3://junest-repo/junest/$img_name" "s3://junest-repo/junest/${img_name}.${DATE}" # Cleanup old images aws s3 ls s3://junest-repo/junest/junest-${ARCH}.tar.gz. | awk '{print $4}' | head -n -${MAX_OLD_IMAGES} | xargs -I {} aws s3 rm "s3://junest-repo/junest/{}" diff --git a/ci/install-bash.sh b/ci/install-bash.sh index 575c9c5..b766123 100755 --- a/ci/install-bash.sh +++ b/ci/install-bash.sh @@ -4,10 +4,10 @@ set -ex VERSION=$1 cd /tmp -wget http://ftp.gnu.org/gnu/bash/bash-$VERSION.tar.gz +wget "http://ftp.gnu.org/gnu/bash/bash-$VERSION.tar.gz" -tar -zxf bash-$VERSION.tar.gz -cd /tmp/bash-$VERSION* +tar -zxf "bash-$VERSION.tar.gz" +cd /tmp/bash-"$VERSION"* ./configure make sudo make install diff --git a/lib/checks/check.sh b/lib/checks/check.sh index 7af5832..f984d96 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +# shellcheck disable=SC1091 # # This modules is used for: # - Running checks against the building JuNest image @@ -34,7 +35,7 @@ JUNEST_HOME=${JUNEST_HOME:-$HOME/.junest} # JUNEST_BASE can be overridden for testing purposes. # There is no need for doing it for normal usage. -JUNEST_BASE="${JUNEST_BASE:-$(readlink -f $(dirname $(readlink -f "$0"))/../..)}" +JUNEST_BASE="${JUNEST_BASE:-$(readlink -f "$(dirname "$(readlink -f "$0")")"/../..)}" source "${JUNEST_BASE}/lib/utils/utils.sh" source "${JUNEST_BASE}/lib/core/common.sh" @@ -44,27 +45,35 @@ info "Validating JuNest located in ${JUNEST_HOME}..." info "Initial JuNest setup..." # The following ensures that the gpg agent gets killed (if exists) # otherwise it is not possible to exit from the session -trap "[[ -e /etc/pacman.d/gnupg/S.gpg-agent ]] && gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye" QUIT EXIT ABRT KILL TERM INT +trap "[[ -e /etc/pacman.d/gnupg/S.gpg-agent ]] && gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye" QUIT EXIT ABRT TERM INT PACMAN_OPTIONS="--noconfirm --disable-download-timeout" +# shellcheck disable=SC2086 $SUDO pacman $PACMAN_OPTIONS -Syy # Awk is required for pacman-key +# shellcheck disable=SC2086 $SUDO pacman $PACMAN_OPTIONS -S gawk $SUDO pacman-key --init if [[ $(uname -m) == *"arm"* ]] then + # shellcheck disable=SC2086 $SUDO pacman $PACMAN_OPTIONS -S archlinuxarm-keyring $SUDO pacman-key --populate archlinuxarm else + # shellcheck disable=SC2086 $SUDO pacman $PACMAN_OPTIONS -S archlinux-keyring $SUDO pacman-key --populate archlinux fi +# shellcheck disable=SC2086 $SUDO pacman $PACMAN_OPTIONS -Su +# shellcheck disable=SC2086 $SUDO pacman $PACMAN_OPTIONS -S grep coreutils +# shellcheck disable=SC2086 +# shellcheck disable=SC2046 $SUDO pacman $PACMAN_OPTIONS -S $(pacman -Sg base-devel | cut -d ' ' -f 2 | grep -v sudo) info "Checking basic executables work..." @@ -73,18 +82,22 @@ $SUDO pacman -Qi pacman 1> /dev/null repo_package1=tree echo "Checking ${repo_package1} package from official repo..." +# shellcheck disable=SC2086 $SUDO pacman $PACMAN_OPTIONS -S ${repo_package1} tree -L 1 +# shellcheck disable=SC2086 $SUDO pacman $PACMAN_OPTIONS -Rsn ${repo_package1} repo_package2=iftop info "Checking ${repo_package2} package from official repo..." +# shellcheck disable=SC2086 $SUDO pacman $PACMAN_OPTIONS -S ${repo_package2} if $RUN_ROOT_TESTS then # Time it out given that sometimes it gets stuck after few seconds. $SUDO timeout 10 iftop -t -s 5 || true fi +# shellcheck disable=SC2086 $SUDO pacman $PACMAN_OPTIONS -Rsn ${repo_package2} if ! $SKIP_AUR_TESTS @@ -92,6 +105,7 @@ then aur_package=tcptraceroute info "Checking ${aur_package} package from AUR repo..." yay --noconfirm -S ${aur_package} + # shellcheck disable=SC2086 $SUDO pacman $PACMAN_OPTIONS -Rsn ${aur_package} fi diff --git a/lib/checks/check_all.sh b/lib/checks/check_all.sh index 210ebfb..394309c 100755 --- a/lib/checks/check_all.sh +++ b/lib/checks/check_all.sh @@ -5,7 +5,7 @@ set -ex # JUNEST_BASE can be overridden for testing purposes. # There is no need for doing it for normal usage. -JUNEST_BASE="${JUNEST_BASE:-$(readlink -f $(dirname $(readlink -f "$0"))/../..)}" +JUNEST_BASE="${JUNEST_BASE:-$(readlink -f "$(dirname "$(readlink -f "$0")")"/../..)}" JUNEST_SCRIPT=${JUNEST_SCRIPT:-${JUNEST_BASE}/bin/junest} @@ -19,8 +19,8 @@ $JUNEST_SCRIPT ns --fakeroot -- "$CHECK_SCRIPT" --skip-aur-tests $JUNEST_SCRIPT ns -- "$CHECK_SCRIPT" --use-sudo # Test the backend command option $JUNEST_SCRIPT ns --backend-command "$JUNEST_HOME/usr/bin/bwrap" -- exit -sudo -E $JUNEST_SCRIPT groot -- "$CHECK_SCRIPT" --run-root-tests --skip-aur-tests +sudo -E "$JUNEST_SCRIPT" groot -- "$CHECK_SCRIPT" --run-root-tests --skip-aur-tests # Test the wrappers work -$JUNEST_SCRIPT create-bin-wrappers --force -$JUNEST_HOME/usr/bin_wrappers/pacman --help +"$JUNEST_SCRIPT" create-bin-wrappers --force +"$JUNEST_HOME"/usr/bin_wrappers/pacman --help diff --git a/lib/core/build.sh b/lib/core/build.sh index e17650a..48996f9 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -16,10 +16,10 @@ function _install_pkg(){ # Generate a working directory because sources will be downloaded to there working_dir=$(TMPDIR=/tmp mktemp -d -t junest-wd.XXXXXXXXXX) cp -R "$pkgbuilddir"/* "$working_dir" - builtin cd ${working_dir} + builtin cd "${working_dir}" || return 1 makepkg -sfcd - makepkg --printsrcinfo > ${pkgbuilddir}/.SRCINFO - sudo pacman --noconfirm --root ${maindir}/root -U *.pkg.tar.* + makepkg --printsrcinfo > "${pkgbuilddir}"/.SRCINFO + sudo pacman --noconfirm --root "${maindir}"/root -U ./*.pkg.tar.* } function _prepare() { @@ -42,29 +42,31 @@ function build_image_env(){ local disable_validation=$1 - local maindir=$(TMPDIR=$JUNEST_TEMPDIR mktemp -d -t ${CMD}.XXXXXXXXXX) - sudo mkdir -p ${maindir}/root - trap - QUIT EXIT ABRT KILL TERM INT - trap "sudo rm -rf ${maindir}; die \"Error occurred when installing ${NAME}\"" EXIT QUIT ABRT KILL TERM INT + local maindir + maindir=$(TMPDIR=$JUNEST_TEMPDIR mktemp -d -t "${CMD}".XXXXXXXXXX) + sudo mkdir -p "${maindir}"/root + trap - QUIT EXIT ABRT TERM INT + # shellcheck disable=SC2064 + trap "sudo rm -rf ${maindir}; die \"Error occurred when installing ${NAME}\"" EXIT QUIT ABRT TERM INT info "Installing pacman and its dependencies..." # All the essential executables (ln, mkdir, chown, etc) are in coreutils # bwrap command belongs to bubblewrap - sudo pacstrap -G -M -d ${maindir}/root pacman coreutils bubblewrap + sudo pacstrap -G -M -d "${maindir}"/root pacman coreutils bubblewrap if [[ ${ARCH} != "arm" ]] then # x86_64 does not have any mirror set by default... sudo bash -c "echo 'Server = $DEFAULT_MIRROR' >> ${maindir}/root/etc/pacman.d/mirrorlist" fi - sudo mkdir -p ${maindir}/root/run/lock + sudo mkdir -p "${maindir}"/root/run/lock - sudo tee -a ${maindir}/root/etc/pacman.conf > /dev/null < /dev/null <> ${maindir}/root/etc/locale.gen" - sudo ${maindir}/root/bin/groot ${maindir}/root locale-gen + sudo "${maindir}"/root/bin/groot "${maindir}"/root locale-gen sudo bash -c "echo LANG=\"en_US.UTF-8\" >> ${maindir}/root/etc/locale.conf" - sudo pacman --noconfirm --root ${maindir}/root -Rsn gzip + sudo pacman --noconfirm --root "${maindir}"/root -Rsn gzip info "Setting up the pacman keyring (this might take a while!)..." # gawk command is required for pacman-key - sudo pacman --noconfirm --root ${maindir}/root -S gawk + sudo pacman --noconfirm --root "${maindir}"/root -S gawk # TODO check why the following did not fail! - sudo ${maindir}/root/bin/groot --no-umount --avoid-bind -b /dev ${maindir}/root bash -c ' + sudo "${maindir}"/root/bin/groot --no-umount --avoid-bind -b /dev "${maindir}"/root bash -c ' set -e pacman-key --init; for keyring_file in /usr/share/pacman/keyrings/*.gpg; @@ -94,31 +96,31 @@ EOT pacman-key --populate $keyring; done; [ -e /etc/pacman.d/gnupg/S.gpg-agent ] && gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye' - sudo umount --force --recursive --lazy ${maindir}/root/dev - sudo umount --force --recursive ${maindir}/root - sudo pacman --noconfirm --root ${maindir}/root -Rsn gawk + sudo umount --force --recursive --lazy "${maindir}"/root/dev + sudo umount --force --recursive "${maindir}"/root + sudo pacman --noconfirm --root "${maindir}"/root -Rsn gawk - sudo rm ${maindir}/root/var/cache/pacman/pkg/* + sudo rm "${maindir}"/root/var/cache/pacman/pkg/* # This is needed on system with busybox tar command. # If the file does not have write permission, the tar command to extract files fails. - sudo chmod -R u+rw ${maindir}/root/ + sudo chmod -R u+rw "${maindir}"/root/ - mkdir -p ${maindir}/output - builtin cd ${maindir}/output + mkdir -p "${maindir}"/output + builtin cd "${maindir}"/output || return 1 local imagefile="${CMD}-${ARCH}.tar.gz" info "Compressing image to ${imagefile}..." - sudo $TAR -zcpf ${imagefile} -C ${maindir}/root . + sudo "$TAR" -zcpf "${imagefile}" -C "${maindir}"/root . if ! $disable_validation then - mkdir -p ${maindir}/root_test - $TAR -zxpf ${imagefile} -C "${maindir}/root_test" - JUNEST_HOME="${maindir}/root_test" ${JUNEST_BASE}/lib/checks/check_all.sh + mkdir -p "${maindir}"/root_test + $TAR -zxpf "${imagefile}" -C "${maindir}/root_test" + JUNEST_HOME="${maindir}/root_test" "${JUNEST_BASE}"/lib/checks/check_all.sh fi - sudo cp ${maindir}/output/${imagefile} ${ORIGIN_WD} + sudo cp "${maindir}"/output/"${imagefile}" "${ORIGIN_WD}" - builtin cd ${ORIGIN_WD} + builtin cd "${ORIGIN_WD}" || return 1 trap - QUIT EXIT ABRT KILL TERM INT sudo rm -fr "$maindir" diff --git a/lib/core/chroot.sh b/lib/core/chroot.sh index afabc71..c2237a9 100644 --- a/lib/core/chroot.sh +++ b/lib/core/chroot.sh @@ -18,20 +18,22 @@ function _run_env_as_xroot(){ local uid=$UID # SUDO_USER is more reliable compared to SUDO_UID - [ -z $SUDO_USER ] || uid=$SUDO_USER:$SUDO_GID + [[ -z $SUDO_USER ]] || uid=$SUDO_USER:$SUDO_GID local args=() [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") # With chown the ownership of the files is assigned to the real user trap - QUIT EXIT ABRT KILL TERM INT - trap "[ -z $uid ] || chown_cmd -R ${uid} ${JUNEST_HOME};" EXIT QUIT ABRT KILL TERM INT + # shellcheck disable=SC2064 + trap "[ -z $uid ] || chown_cmd -R ${uid} ${JUNEST_HOME};" EXIT QUIT ABRT TERM INT if ! $no_copy_files then copy_common_files fi + # shellcheck disable=SC2086 JUNEST_ENV=1 $cmd $backend_args "$JUNEST_HOME" "${DEFAULT_SH[@]}" "${args[@]}" } diff --git a/lib/core/common.sh b/lib/core/common.sh index 7d23d07..a75aff9 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# shellcheck disable=SC2034 +# shellcheck disable=SC1091 # # This module contains all common functionalities for JuNest. # @@ -29,7 +31,7 @@ PATH=/usr/bin:/bin:/usr/local/bin:/usr/sbin:/sbin:${HOME}/.local/bin # The executable uname is essential in order to get the architecture # of the host system, so a fallback mechanism cannot be used for it. -UNAME=uname +UNAME="uname" ARCH_LIST=('x86_64' 'x86' 'arm') HOST_ARCH=$($UNAME -m) @@ -53,6 +55,7 @@ fi MAIN_REPO=https://dwa8bhj1f036z.cloudfront.net ENV_REPO=${MAIN_REPO}/${CMD} +# shellcheck disable=SC2016 DEFAULT_MIRROR='https://mirror.rackspace.com/archlinux/$repo/os/$arch' ORIGIN_WD=$(pwd) @@ -73,16 +76,16 @@ GROOT="${JUNEST_HOME}/usr/bin/groot" CLASSIC_CHROOT=chroot WGET="wget --no-check-certificate" CURL="curl -L -J -O -k" -TAR=tar +TAR="tar" CHOWN="chown" -LN=ln -RM=rm -MKDIR=mkdir -GETENT=getent -CP=cp +LN="ln" +RM="rm" +MKDIR="mkdir" +GETENT="getent" +CP="cp" # Used for checking user namespace in config.gz file -ZGREP=zgrep -UNSHARE=unshare +ZGREP="zgrep" +UNSHARE="unshare" LD_EXEC="$LD_LIB --library-path ${JUNEST_HOME}/usr/lib:${JUNEST_HOME}/lib" @@ -91,32 +94,32 @@ LD_EXEC="$LD_LIB --library-path ${JUNEST_HOME}/usr/lib:${JUNEST_HOME}/lib" # image. function ln_cmd(){ - $LN "$@" || $LD_EXEC ${JUNEST_HOME}/usr/bin/$LN "$@" + $LN "$@" || $LD_EXEC "${JUNEST_HOME}"/usr/bin/$LN "$@" } function getent_cmd(){ - $GETENT "$@" || $LD_EXEC ${JUNEST_HOME}/usr/bin/$GETENT "$@" + $GETENT "$@" || $LD_EXEC "${JUNEST_HOME}"/usr/bin/$GETENT "$@" } function cp_cmd(){ - $CP "$@" || $LD_EXEC ${JUNEST_HOME}/usr/bin/$CP "$@" + $CP "$@" || $LD_EXEC "${JUNEST_HOME}"/usr/bin/$CP "$@" } function rm_cmd(){ - $RM "$@" || $LD_EXEC ${JUNEST_HOME}/usr/bin/$RM "$@" + $RM "$@" || $LD_EXEC "${JUNEST_HOME}"/usr/bin/$RM "$@" } function chown_cmd(){ - $CHOWN "$@" || $LD_EXEC ${JUNEST_HOME}/usr/bin/$CHOWN "$@" + $CHOWN "$@" || $LD_EXEC "${JUNEST_HOME}"/usr/bin/$CHOWN "$@" } function mkdir_cmd(){ - $MKDIR "$@" || $LD_EXEC ${JUNEST_HOME}/usr/bin/$MKDIR "$@" + $MKDIR "$@" || $LD_EXEC "${JUNEST_HOME}"/usr/bin/$MKDIR "$@" } function zgrep_cmd(){ # No need for LD_EXEC as zgrep is a POSIX shell script - $ZGREP "$@" || ${JUNEST_HOME}/usr/bin/$ZGREP "$@" + $ZGREP "$@" || "${JUNEST_HOME}"/usr/bin/$ZGREP "$@" } function download_cmd(){ @@ -124,7 +127,7 @@ function download_cmd(){ } function chroot_cmd(){ - $CLASSIC_CHROOT "$@" || $LD_EXEC ${JUNEST_HOME}/usr/bin/$CLASSIC_CHROOT "$@" + $CLASSIC_CHROOT "$@" || $LD_EXEC "${JUNEST_HOME}"/usr/bin/$CLASSIC_CHROOT "$@" } function unshare_cmd(){ @@ -134,9 +137,9 @@ function unshare_cmd(){ # Also, unshare provides an environment in which /bin/sh maps to dash shell, # therefore it ignores all the remaining DEFAULT_SH arguments (i.e. --login) as # they are not supported by dash. - if $LD_EXEC ${JUNEST_HOME}/usr/bin/$UNSHARE --user "${DEFAULT_SH[0]}" "-c" ":" + if $LD_EXEC "${JUNEST_HOME}"/usr/bin/$UNSHARE --user "${DEFAULT_SH[0]}" "-c" ":" then - $LD_EXEC ${JUNEST_HOME}/usr/bin/$UNSHARE "${@}" + $LD_EXEC "${JUNEST_HOME}"/usr/bin/$UNSHARE "${@}" elif $UNSHARE --user "${DEFAULT_SH[0]}" "-c" ":" then $UNSHARE "$@" @@ -146,9 +149,9 @@ function unshare_cmd(){ } function bwrap_cmd(){ - if $LD_EXEC $BWRAP --dev-bind / / "${DEFAULT_SH[0]}" "-c" ":" + if $LD_EXEC "$BWRAP" --dev-bind / / "${DEFAULT_SH[0]}" "-c" ":" then - $LD_EXEC $BWRAP "${@}" + $LD_EXEC "$BWRAP" "${@}" else die "Error: Something went wrong while executing bwrap command. Exiting" fi @@ -157,8 +160,10 @@ function bwrap_cmd(){ function proot_cmd(){ local proot_args="$1" shift + # shellcheck disable=SC2086 if ${PROOT} ${proot_args} "${DEFAULT_SH[@]}" "-c" ":" then + # shellcheck disable=SC2086 ${PROOT} ${proot_args} "${@}" elif PROOT_NO_SECCOMP=1 ${PROOT} ${proot_args} "${DEFAULT_SH[@]}" "-c" ":" then @@ -192,7 +197,7 @@ function check_nested_env() { if [[ $JUNEST_ENV == "1" ]] then die_on_status $NESTED_ENVIRONMENT "Error: Nested ${NAME} environments are not allowed" - elif [[ ! -z $JUNEST_ENV ]] && [[ $JUNEST_ENV != "0" ]] + elif [[ -n $JUNEST_ENV ]] && [[ $JUNEST_ENV != "0" ]] then die_on_status $VARIABLE_NOT_SET "The variable JUNEST_ENV is not properly set" fi @@ -214,7 +219,7 @@ function check_nested_env() { # None ####################################### function check_same_arch() { - source ${JUNEST_HOME}/etc/junest/info + source "${JUNEST_HOME}"/etc/junest/info [ "$JUNEST_ARCH" != "$ARCH" ] && \ die_on_status $ARCHITECTURE_MISMATCH "The host system architecture is not correct: $ARCH != $JUNEST_ARCH" return 0 @@ -272,14 +277,14 @@ function copy_passwd_and_group(){ # is configured. # Try to at least get the current user via `getent passwd $USER` since it uses # a more reliable and faster system call (getpwnam(3)). - if ! getent_cmd passwd > ${JUNEST_HOME}/etc/passwd || \ - ! getent_cmd passwd ${USER} >> ${JUNEST_HOME}/etc/passwd + if ! getent_cmd passwd > "${JUNEST_HOME}"/etc/passwd || \ + ! getent_cmd passwd "${USER}" >> "${JUNEST_HOME}"/etc/passwd then warn "getent command failed or does not exist. Binding directly from /etc/passwd." copy_file /etc/passwd fi - if ! getent_cmd group > ${JUNEST_HOME}/etc/group + if ! getent_cmd group > "${JUNEST_HOME}"/etc/group then warn "getent command failed or does not exist. Binding directly from /etc/group." copy_file /etc/group diff --git a/lib/core/namespace.sh b/lib/core/namespace.sh index 0567989..2754dab 100644 --- a/lib/core/namespace.sh +++ b/lib/core/namespace.sh @@ -10,6 +10,7 @@ # # vim: ft=sh +# shellcheck disable=SC2027 COMMON_BWRAP_OPTION="--bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --bind /sys /sys --bind /proc /proc --dev-bind-try /dev /dev --unshare-user-try" CONFIG_PROC_FILE="/proc/config.gz" CONFIG_BOOT_FILE="/boot/config-$($UNAME -r)" @@ -24,14 +25,14 @@ function _is_user_namespace_enabled() { then config_file=$CONFIG_BOOT_FILE else - return $NOT_EXISTING_FILE + return "$NOT_EXISTING_FILE" fi # `-q` option in zgrep may cause a gzip: stdout: Broken pipe # Use redirect to /dev/null instead - if ! zgrep_cmd "CONFIG_USER_NS=y" $config_file > /dev/null + if ! zgrep_cmd "CONFIG_USER_NS=y" "$config_file" > /dev/null then - return $NO_CONFIG_FOUND + return "$NO_CONFIG_FOUND" fi if [[ ! -e $PROC_USERNS_CLONE_FILE ]] @@ -43,7 +44,7 @@ function _is_user_namespace_enabled() { # Use redirect to /dev/null instead if ! zgrep_cmd "1" $PROC_USERNS_CLONE_FILE > /dev/null then - return $UNPRIVILEGED_USERNS_DISABLED + return "$UNPRIVILEGED_USERNS_DISABLED" fi return 0 @@ -53,9 +54,9 @@ function _check_user_namespace() { set +e _is_user_namespace_enabled case $? in - $NOT_EXISTING_FILE) warn "Could not understand if user namespace is enabled. No config.gz file found. Proceeding anyway..." ;; - $NO_CONFIG_FOUND) warn "Unprivileged user namespace is disabled at kernel compile time or kernel too old (<3.8). Proceeding anyway..." ;; - $UNPRIVILEGED_USERNS_DISABLED) warn "Unprivileged user namespace disabled. Root permissions are required to enable it: sudo sysctl kernel.unprivileged_userns_clone=1" ;; + "$NOT_EXISTING_FILE") warn "Could not understand if user namespace is enabled. No config.gz file found. Proceeding anyway..." ;; + "$NO_CONFIG_FOUND") warn "Unprivileged user namespace is disabled at kernel compile time or kernel too old (<3.8). Proceeding anyway..." ;; + "$UNPRIVILEGED_USERNS_DISABLED") warn "Unprivileged user namespace disabled. Root permissions are required to enable it: sudo sysctl kernel.unprivileged_userns_clone=1" ;; esac set -e } @@ -100,6 +101,7 @@ function run_env_as_bwrap_fakeroot(){ local args=() [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") + # shellcheck disable=SC2086 BWRAP="${backend_command}" JUNEST_ENV=1 bwrap_cmd $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 $backend_args sudo "${DEFAULT_SH[@]}" "${args[@]}" } @@ -148,6 +150,7 @@ function run_env_as_bwrap_user() { local args=() [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") + # shellcheck disable=SC2086 BWRAP="${backend_command}" JUNEST_ENV=1 bwrap_cmd $COMMON_BWRAP_OPTION $backend_args "${DEFAULT_SH[@]}" "${args[@]}" } diff --git a/lib/core/proot.sh b/lib/core/proot.sh index f074b47..259c8b7 100644 --- a/lib/core/proot.sh +++ b/lib/core/proot.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +# shellcheck disable=SC1091 # # This module contains all proot functionalities for JuNest. # @@ -24,18 +25,19 @@ function _run_env_with_qemu(){ local backend_args="$2" shift 2 - source ${JUNEST_HOME}/etc/junest/info + source "${JUNEST_HOME}"/etc/junest/info if [ "$JUNEST_ARCH" != "$ARCH" ] then local qemu_bin="qemu-$JUNEST_ARCH-static-$ARCH" local qemu_symlink="/tmp/${qemu_bin}-$RANDOM" trap - QUIT EXIT ABRT KILL TERM INT - trap "[ -e ${qemu_symlink} ] && rm_cmd -f ${qemu_symlink}" EXIT QUIT ABRT KILL TERM INT + # shellcheck disable=SC2064 + trap "[ -e ${qemu_symlink} ] && rm_cmd -f ${qemu_symlink}" EXIT QUIT ABRT TERM INT warn "Emulating $NAME via QEMU..." - [ -e ${qemu_symlink} ] || \ - ln_cmd -s ${JUNEST_HOME}/bin/${qemu_bin} ${qemu_symlink} + [[ -e ${qemu_symlink} ]] || \ + ln_cmd -s "${JUNEST_HOME}/bin/${qemu_bin}" "${qemu_symlink}" backend_args="-q ${qemu_symlink} $backend_args" fi @@ -62,7 +64,7 @@ function _run_env_with_qemu(){ ####################################### function run_env_as_proot_fakeroot(){ (( EUID == 0 )) && \ - die_on_status $ROOT_ACCESS_ERROR "You cannot access with root privileges. Use --groot option instead." + die_on_status "$ROOT_ACCESS_ERROR" "You cannot access with root privileges. Use --groot option instead." check_nested_env local backend_command="$1" @@ -104,7 +106,7 @@ function run_env_as_proot_fakeroot(){ ####################################### function run_env_as_proot_user(){ (( EUID == 0 )) && \ - die_on_status $ROOT_ACCESS_ERROR "You cannot access with root privileges. Use --groot option instead." + die_on_status "$ROOT_ACCESS_ERROR" "You cannot access with root privileges. Use --groot option instead." check_nested_env local backend_command="$1" diff --git a/lib/core/setup.sh b/lib/core/setup.sh index 28b04d3..749fd66 100644 --- a/lib/core/setup.sh +++ b/lib/core/setup.sh @@ -22,7 +22,7 @@ # None ####################################### function is_env_installed(){ - [ -d "$JUNEST_HOME" ] && [ "$(ls -A $JUNEST_HOME)" ] && return 0 + [[ -d "$JUNEST_HOME" ]] && [[ "$(ls -A "$JUNEST_HOME")" ]] && return 0 return 1 } @@ -30,7 +30,7 @@ function is_env_installed(){ function _cleanup_build_directory(){ local maindir=$1 check_not_null "$maindir" - builtin cd $ORIGIN_WD + builtin cd "$ORIGIN_WD" || return 1 trap - QUIT EXIT ABRT KILL TERM INT rm_cmd -fr "$maindir" } @@ -40,7 +40,8 @@ function _prepare_build_directory(){ local maindir=$1 check_not_null "$maindir" trap - QUIT EXIT ABRT KILL TERM INT - trap "rm_cmd -rf ${maindir}; die \"Error occurred when installing ${NAME}\"" EXIT QUIT ABRT KILL TERM INT + # shellcheck disable=SC2064 + trap "rm_cmd -rf ${maindir}; die \"Error occurred when installing ${NAME}\"" EXIT QUIT ABRT TERM INT } @@ -51,7 +52,7 @@ function _setup_env(){ is_env_installed && die "Error: ${NAME} has been already installed in $JUNEST_HOME" mkdir_cmd -p "${JUNEST_HOME}" - $TAR -zxpf ${imagepath} -C ${JUNEST_HOME} + $TAR -zxpf "${imagepath}" -C "${JUNEST_HOME}" info "${NAME} installed successfully!" echo info "Default mirror URL set to: ${DEFAULT_MIRROR}" @@ -84,21 +85,22 @@ function _setup_env(){ ####################################### function setup_env(){ local arch=${1:-$ARCH} - contains_element $arch "${ARCH_LIST[@]}" || \ - die_on_status $NOT_AVAILABLE_ARCH "The architecture is not one of: ${ARCH_LIST[@]}" + contains_element "$arch" "${ARCH_LIST[@]}" || \ + die_on_status "$NOT_AVAILABLE_ARCH" "The architecture is not one of: ${ARCH_LIST[*]}" - local maindir=$(TMPDIR=$JUNEST_TEMPDIR mktemp -d -t ${CMD}.XXXXXXXXXX) - _prepare_build_directory $maindir + local maindir + maindir=$(TMPDIR=$JUNEST_TEMPDIR mktemp -d -t "${CMD}".XXXXXXXXXX) + _prepare_build_directory "$maindir" info "Downloading ${NAME}..." - builtin cd ${maindir} + builtin cd "${maindir}" || return 1 local imagefile=${CMD}-${arch}.tar.gz - download_cmd ${ENV_REPO}/${imagefile} + download_cmd "${ENV_REPO}/${imagefile}" info "Installing ${NAME}..." - _setup_env ${maindir}/${imagefile} + _setup_env "${maindir}/${imagefile}" - _cleanup_build_directory ${maindir} + _cleanup_build_directory "${maindir}" } ####################################### @@ -118,10 +120,10 @@ function setup_env(){ function setup_env_from_file(){ local imagefile=$1 check_not_null "$imagefile" - [ ! -e ${imagefile} ] && die_on_status $NOT_EXISTING_FILE "Error: The ${NAME} image file ${imagefile} does not exist" + [[ ! -e ${imagefile} ]] && die_on_status "$NOT_EXISTING_FILE" "Error: The ${NAME} image file ${imagefile} does not exist" info "Installing ${NAME} from ${imagefile}..." - _setup_env ${imagefile} + _setup_env "${imagefile}" } ####################################### @@ -138,18 +140,18 @@ function setup_env_from_file(){ ####################################### function delete_env(){ ! ask "Are you sure to delete ${NAME} located in ${JUNEST_HOME}" "N" && return - if mountpoint -q ${JUNEST_HOME} + if mountpoint -q "${JUNEST_HOME}" then info "There are mounted directories inside ${JUNEST_HOME}" - if ! umount --force ${JUNEST_HOME} + if ! umount --force "${JUNEST_HOME}" then error "Cannot umount directories in ${JUNEST_HOME}" die "Try to delete ${NAME} using root permissions" fi fi # the CA directories are read only and can be deleted only by changing the mod - chmod -R +w ${JUNEST_HOME}/etc/ca-certificates - if rm_cmd -rf ${JUNEST_HOME} + chmod -R +w "${JUNEST_HOME}"/etc/ca-certificates + if rm_cmd -rf "${JUNEST_HOME}" then info "${NAME} deleted in ${JUNEST_HOME}" else diff --git a/lib/utils/utils.sh b/lib/utils/utils.sh index 00e2cb6..5659568 100644 --- a/lib/utils/utils.sh +++ b/lib/utils/utils.sh @@ -50,7 +50,7 @@ function echoerr() { # Message printed to stderr. ####################################### function die() { - error $@ + error "$@" exit 1 } @@ -70,8 +70,8 @@ function die() { function die_on_status() { status=$1 shift - error $@ - exit $status + error "$@" + exit "$status" } ####################################### @@ -87,7 +87,7 @@ function die_on_status() { # Message printed to stderr. ####################################### function error() { - echoerr -e "\033[1;31m$@\033[0m" + echoerr -e "\033[1;31m$*\033[0m" } ####################################### @@ -104,7 +104,7 @@ function error() { ####################################### function warn() { # $@: msg (mandatory) - str: Message to print - echoerr -e "\033[1;33m$@\033[0m" + echoerr -e "\033[1;33m$*\033[0m" } ####################################### @@ -120,7 +120,7 @@ function warn() { # Message printed to stdout. ####################################### function info(){ - echo -e "\033[1;36m$@\033[0m" + echo -e "\033[1;36m$*\033[0m" } ####################################### @@ -142,12 +142,12 @@ function info(){ function ask(){ local question=$1 local default_answer=$2 - check_not_null $question + check_not_null "$question" - if [ ! -z "$default_answer" ] + if [ -n "$default_answer" ] then local answers="Y y N n" - [[ "$answers" =~ "$default_answer" ]] || { error "The default answer: $default_answer is wrong."; return $WRONG_ANSWER; } + [[ "$answers" =~ $default_answer ]] || { error "The default answer: $default_answer is wrong."; return $WRONG_ANSWER; } fi local default="Y" @@ -156,12 +156,13 @@ function ask(){ local other="n" [ "$default" == "N" ] && other="y" - local prompt=$(info "$question (${default}/${other})> ") + local prompt + prompt=$(info "$question (${default}/${other})> ") local res="none" while [ "$res" != "Y" ] && [ "$res" != "N" ] && [ "$res" != "" ]; do - read -p "$prompt" res + read -r -p "$prompt" res res=$(echo "$res" | tr '[:lower:]' '[:upper:]') done @@ -170,36 +171,31 @@ function ask(){ [ "$res" == "Y" ] } -function check_and_trap() { - local sigs="${@:2:${#@}}" - local traps="$(trap -p $sigs)" - [[ $traps ]] && die "Attempting to overwrite existing $sigs trap: $traps" - trap $@ -} - -function check_and_force_trap() { - local sigs="${@:2:${#@}}" - local traps="$(trap -p $sigs)" - [[ $traps ]] && warn "Attempting to overwrite existing $sigs trap: $traps" - trap $@ -} - function insert_quotes_on_spaces(){ # It inserts quotes between arguments. # Useful to preserve quotes on command # to be used inside sh -c/bash -c - C='' + local C="" whitespace="[[:space:]]" for i in "$@" do if [[ $i =~ $whitespace ]] then - C="$C \"$i\"" + temp_C="\"$i\"" else - C="$C $i" + temp_C="$i" fi + + # Handle edge case when C is empty to avoid adding an extra space + if [[ -z $C ]] + then + C="$temp_C" + else + C="$C $temp_C" + fi + done - echo $C + echo "$C" } contains_element () { diff --git a/tests/checkstyle/checkstyle.sh b/tests/checkstyle/checkstyle.sh index 27cb82a..4f71965 100755 --- a/tests/checkstyle/checkstyle.sh +++ b/tests/checkstyle/checkstyle.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash +# shellcheck disable=SC1091 -source "$(dirname $0)/../utils/utils.sh" +source "$(dirname "$0")/../utils/utils.sh" # Disable the exiterr set +e @@ -10,12 +11,12 @@ function oneTimeSetUp(){ } function test_check_no_tabs(){ - assertCommandFailOnStatus 1 grep -R "$(printf '\t')" $(dirname $0)/../../bin/* - assertEquals "" "$(cat $STDOUTF)" - assertEquals "" "$(cat $STDERRF)" - assertCommandFailOnStatus 1 grep -R "$(printf '\t')" $(dirname $0)/../../lib/* - assertEquals "" "$(cat $STDOUTF)" - assertEquals "" "$(cat $STDERRF)" + assertCommandFailOnStatus 1 grep -R "$(printf '\t')" "$(dirname "$0")"/../../bin/* + assertEquals "" "$(cat "$STDOUTF")" + assertEquals "" "$(cat "$STDERRF")" + assertCommandFailOnStatus 1 grep -R "$(printf '\t')" "$(dirname "$0")"/../../lib/* + assertEquals "" "$(cat "$STDOUTF")" + assertEquals "" "$(cat "$STDERRF")" } -source $(dirname $0)/../utils/shunit2 +source "$(dirname "$0")"/../utils/shunit2 diff --git a/tests/unit-tests/test-chroot.sh b/tests/unit-tests/test-chroot.sh index 44999f7..f634b5b 100755 --- a/tests/unit-tests/test-chroot.sh +++ b/tests/unit-tests/test-chroot.sh @@ -1,6 +1,7 @@ #!/bin/bash +# shellcheck disable=SC1091 -JUNEST_ROOT=$(readlink -f $(dirname $0)/../..) +JUNEST_ROOT=$(readlink -f "$(dirname "$0")"/../..) source "$JUNEST_ROOT/tests/utils/utils.sh" @@ -29,32 +30,33 @@ function tearDown(){ function init_mocks() { chroot_cmd() { [ "$JUNEST_ENV" != "1" ] && return 1 - echo "chroot_cmd $@" + echo "chroot_cmd $*" } + # shellcheck disable=SC2034 GROOT=chroot_cmd mychroot() { - echo mychroot $@ + echo mychroot "$*" } } function test_run_env_as_groot_cmd(){ assertCommandSuccess run_env_as_groot "" "" "false" pwd - assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)" + assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c pwd" "$(cat "$STDOUTF")" } function test_run_env_as_groot_no_cmd(){ assertCommandSuccess run_env_as_groot "" "" "false" "" - assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login" "$(cat "$STDOUTF")" } function test_run_env_as_groot_with_backend_command(){ assertCommandSuccess run_env_as_groot "mychroot" "" "false" "" - assertEquals "mychroot -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "mychroot -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login" "$(cat "$STDOUTF")" } function test_run_env_as_groot_no_copy(){ assertCommandSuccess run_env_as_groot "" "" "true" pwd - assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)" + assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c pwd" "$(cat "$STDOUTF")" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -74,27 +76,27 @@ function test_run_env_as_groot_nested_env(){ function test_run_env_as_groot_cmd_with_backend_args(){ assertCommandSuccess run_env_as_groot "" "-n -b /home/blah" "false" pwd - assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev -n -b /home/blah $JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)" + assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev -n -b /home/blah $JUNEST_HOME /bin/sh --login -c pwd" "$(cat "$STDOUTF")" } function test_run_env_as_chroot_cmd(){ assertCommandSuccess run_env_as_chroot "" "" "false" pwd - assertEquals "chroot_cmd $JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)" + assertEquals "chroot_cmd $JUNEST_HOME /bin/sh --login -c pwd" "$(cat "$STDOUTF")" } function test_run_env_as_chroot_no_cmd(){ assertCommandSuccess run_env_as_chroot "" "" "false" "" - assertEquals "chroot_cmd $JUNEST_HOME /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "chroot_cmd $JUNEST_HOME /bin/sh --login" "$(cat "$STDOUTF")" } function test_run_env_as_chroot_with_backend_command(){ assertCommandSuccess run_env_as_chroot "mychroot" "" "false" "" - assertEquals "mychroot $JUNEST_HOME /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "mychroot $JUNEST_HOME /bin/sh --login" "$(cat "$STDOUTF")" } function test_run_env_as_chroot_no_copy(){ assertCommandSuccess run_env_as_chroot "" "" "true" pwd - assertEquals "chroot_cmd $JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)" + assertEquals "chroot_cmd $JUNEST_HOME /bin/sh --login -c pwd" "$(cat "$STDOUTF")" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -114,7 +116,7 @@ function test_run_env_as_choot_nested_env(){ function test_run_env_as_chroot_cmd_with_backend_args(){ assertCommandSuccess run_env_as_chroot "" "-n -b /home/blah" "false" pwd - assertEquals "chroot_cmd -n -b /home/blah $JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)" + assertEquals "chroot_cmd -n -b /home/blah $JUNEST_HOME /bin/sh --login -c pwd" "$(cat "$STDOUTF")" } -source $JUNEST_ROOT/tests/utils/shunit2 +source "$JUNEST_ROOT"/tests/utils/shunit2 diff --git a/tests/unit-tests/test-common.sh b/tests/unit-tests/test-common.sh index 7037f98..d0a6c0b 100755 --- a/tests/unit-tests/test-common.sh +++ b/tests/unit-tests/test-common.sh @@ -1,6 +1,7 @@ #!/bin/bash +# shellcheck disable=SC1091 -JUNEST_ROOT=$(readlink -f $(dirname $0)/../..) +JUNEST_ROOT=$(readlink -f "$(dirname "$0")"/../..) source "$JUNEST_ROOT/tests/utils/utils.sh" @@ -21,52 +22,55 @@ function oneTimeTearDown(){ function setUp(){ ld_exec_mock() { - echo "ld_exec $@" + echo "ld_exec $*" } ld_exec_mock_false() { - echo "ld_exec $@" + echo "ld_exec $*" return 1 } + # shellcheck disable=SC2034 LD_EXEC=ld_exec_mock unshare_mock() { - echo "unshare $@" + echo "unshare $*" } + # shellcheck disable=SC2034 UNSHARE=unshare_mock bwrap_mock() { - echo "bwrap $@" + echo "bwrap $*" } + # shellcheck disable=SC2034 BWRAP=bwrap_mock } function test_ln(){ - LN=echo assertCommandSuccess ln_cmd -s ln_file new_file - assertEquals "-s ln_file new_file" "$(cat $STDOUTF)" + LN="echo" assertCommandSuccess ln_cmd -s ln_file new_file + assertEquals "-s ln_file new_file" "$(cat "$STDOUTF")" LN=false assertCommandSuccess ln_cmd -s ln_file new_file - assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false -s ln_file new_file" "$(cat $STDOUTF)" + assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false -s ln_file new_file" "$(cat "$STDOUTF")" LN=false LD_EXEC=false assertCommandFail ln_cmd } function test_getent(){ - GETENT=echo assertCommandSuccess getent_cmd passwd - assertEquals "passwd" "$(cat $STDOUTF)" + GETENT="echo" assertCommandSuccess getent_cmd passwd + assertEquals "passwd" "$(cat "$STDOUTF")" - GETENT=false assertCommandSuccess getent_cmd passwd - assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false passwd" "$(cat $STDOUTF)" + GETENT="false" assertCommandSuccess getent_cmd passwd + assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false passwd" "$(cat "$STDOUTF")" GETENT=false LD_EXEC=false assertCommandFail getent_cmd } function test_cp(){ - CP=echo assertCommandSuccess cp_cmd passwd - assertEquals "passwd" "$(cat $STDOUTF)" + CP="echo" assertCommandSuccess cp_cmd passwd + assertEquals "passwd" "$(cat "$STDOUTF")" CP=false assertCommandSuccess cp_cmd passwd - assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false passwd" "$(cat $STDOUTF)" + assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false passwd" "$(cat "$STDOUTF")" CP=false LD_EXEC=false assertCommandFail cp_cmd } @@ -76,7 +80,9 @@ function test_download(){ CURL=/bin/false assertCommandSuccess download_cmd + # shellcheck disable=SC2034 WGET=/bin/false + # shellcheck disable=SC2034 CURL=/bin/true assertCommandSuccess download_cmd @@ -84,76 +90,77 @@ function test_download(){ } function test_rm(){ - RM=echo assertCommandSuccess rm_cmd rm_file - assertEquals "rm_file" "$(cat $STDOUTF)" + RM="echo" assertCommandSuccess rm_cmd rm_file + assertEquals "rm_file" "$(cat "$STDOUTF")" - RM=false assertCommandSuccess rm_cmd rm_file - assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false rm_file" "$(cat $STDOUTF)" + RM="false" assertCommandSuccess rm_cmd rm_file + assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false rm_file" "$(cat "$STDOUTF")" RM=false LD_EXEC=false assertCommandFail rm_cmd rm_file } function test_chown(){ - local id=$(id -u) + local id + id=$(id -u) - CHOWN=echo assertCommandSuccess chown_cmd $id chown_file - assertEquals "$id chown_file" "$(cat $STDOUTF)" + CHOWN="echo" assertCommandSuccess chown_cmd "$id" chown_file + assertEquals "$id chown_file" "$(cat "$STDOUTF")" - CHOWN=false assertCommandSuccess chown_cmd $id chown_file - assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false $id chown_file" "$(cat $STDOUTF)" + CHOWN="false" assertCommandSuccess chown_cmd "$id" chown_file + assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false $id chown_file" "$(cat "$STDOUTF")" - CHOWN=false LD_EXEC=false assertCommandFail chown_cmd $id chown_file + CHOWN=false LD_EXEC=false assertCommandFail chown_cmd "$id" chown_file } function test_mkdir(){ - MKDIR=echo assertCommandSuccess mkdir_cmd -p new_dir/new_dir - assertEquals "-p new_dir/new_dir" "$(cat $STDOUTF)" + MKDIR="echo" assertCommandSuccess mkdir_cmd -p new_dir/new_dir + assertEquals "-p new_dir/new_dir" "$(cat "$STDOUTF")" MKDIR=false assertCommandSuccess mkdir_cmd -p new_dir/new_dir - assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false -p new_dir/new_dir" "$(cat $STDOUTF)" + assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false -p new_dir/new_dir" "$(cat "$STDOUTF")" MKDIR=false LD_EXEC=false assertCommandFail mkdir_cmd -p new_dir/new_dir } function test_zgrep(){ - ZGREP=echo assertCommandSuccess zgrep_cmd new_file - assertEquals "new_file" "$(cat $STDOUTF)" + ZGREP="echo" assertCommandSuccess zgrep_cmd new_file + assertEquals "new_file" "$(cat "$STDOUTF")" - mkdir -p ${JUNEST_HOME}/usr/bin - touch ${JUNEST_HOME}/usr/bin/false - chmod +x ${JUNEST_HOME}/usr/bin/false + mkdir -p "${JUNEST_HOME}"/usr/bin + touch "${JUNEST_HOME}"/usr/bin/false + chmod +x "${JUNEST_HOME}"/usr/bin/false - echo -e "#!/bin/bash\necho zgrep" > ${JUNEST_HOME}/usr/bin/false + echo -e "#!/bin/bash\necho zgrep" > "${JUNEST_HOME}"/usr/bin/false ZGREP=false assertCommandSuccess zgrep_cmd new_file - assertEquals "zgrep" "$(cat $STDOUTF)" + assertEquals "zgrep" "$(cat "$STDOUTF")" - echo -e "#!/bin/bash\nexit 1" > ${JUNEST_HOME}/usr/bin/false + echo -e "#!/bin/bash\nexit 1" > "${JUNEST_HOME}"/usr/bin/false ZGREP=false assertCommandFail zgrep_cmd new_file } function test_unshare(){ assertCommandSuccess unshare_cmd new_program - assertEquals "$(echo -e "ld_exec ${JUNEST_HOME}/usr/bin/$UNSHARE --user /bin/sh -c :\nld_exec ${JUNEST_HOME}/usr/bin/$UNSHARE new_program")" "$(cat $STDOUTF)" + assertEquals "$(echo -e "ld_exec ${JUNEST_HOME}/usr/bin/$UNSHARE --user /bin/sh -c :\nld_exec ${JUNEST_HOME}/usr/bin/$UNSHARE new_program")" "$(cat "$STDOUTF")" LD_EXEC=ld_exec_mock_false assertCommandSuccess unshare_cmd new_program - assertEquals "$(echo -e "ld_exec ${JUNEST_HOME}/usr/bin/unshare_mock --user /bin/sh -c :\nunshare --user /bin/sh -c :\nunshare new_program")" "$(cat $STDOUTF)" + assertEquals "$(echo -e "ld_exec ${JUNEST_HOME}/usr/bin/unshare_mock --user /bin/sh -c :\nunshare --user /bin/sh -c :\nunshare new_program")" "$(cat "$STDOUTF")" UNSHARE=false LD_EXEC=false assertCommandFail unshare_cmd new_program } function test_bwrap(){ assertCommandSuccess bwrap_cmd new_program - assertEquals "$(echo -e "ld_exec $BWRAP --dev-bind / / /bin/sh -c :\nld_exec $BWRAP new_program")" "$(cat $STDOUTF)" + assertEquals "$(echo -e "ld_exec $BWRAP --dev-bind / / /bin/sh -c :\nld_exec $BWRAP new_program")" "$(cat "$STDOUTF")" BWRAP=false LD_EXEC=false assertCommandFail bwrap_cmd new_program } function test_chroot(){ - CLASSIC_CHROOT=echo assertCommandSuccess chroot_cmd root - assertEquals "root" "$(cat $STDOUTF)" + CLASSIC_CHROOT="echo" assertCommandSuccess chroot_cmd root + assertEquals "root" "$(cat "$STDOUTF")" CLASSIC_CHROOT=false assertCommandSuccess chroot_cmd root - assertEquals "ld_exec $JUNEST_HOME/usr/bin/false root" "$(cat $STDOUTF)" + assertEquals "ld_exec $JUNEST_HOME/usr/bin/false root" "$(cat "$STDOUTF")" CLASSIC_CHROOT=false LD_EXEC=false assertCommandFail chroot_cmd root } @@ -170,34 +177,35 @@ function test_proot_cmd_seccomp(){ } PROOT=envv assertCommandSuccess proot_cmd cmd - assertEquals "" "$(cat $STDOUTF | grep "^PROOT_NO_SECCOMP")" + assertEquals "" "$(grep "^PROOT_NO_SECCOMP" "$STDOUTF")" envv(){ env | grep "^PROOT_NO_SECCOMP" } + # shellcheck disable=SC2034 PROOT=envv assertCommandSuccess proot_cmd cmd # The variable PROOT_NO_SECCOMP will be produced # twice due to the fallback mechanism assertEquals "PROOT_NO_SECCOMP=1 -PROOT_NO_SECCOMP=1" "$(cat $STDOUTF | grep "^PROOT_NO_SECCOMP")" +PROOT_NO_SECCOMP=1" "$(grep "^PROOT_NO_SECCOMP" "$STDOUTF")" } function test_copy_passwd_and_group(){ getent_cmd_mock() { - echo $@ + echo "$*" } GETENT=getent_cmd_mock assertCommandSuccess copy_passwd_and_group - assertEquals "$(echo -e "passwd\npasswd $USER")" "$(cat $JUNEST_HOME/etc/passwd)" - assertEquals "group" "$(cat $JUNEST_HOME/etc/group)" + assertEquals "$(echo -e "passwd\npasswd $USER")" "$(cat "$JUNEST_HOME"/etc/passwd)" + assertEquals "group" "$(cat "$JUNEST_HOME"/etc/group)" } function test_copy_passwd_and_group_fallback(){ cp_cmd_mock() { - echo $@ + echo "$*" } CP=cp_cmd_mock GETENT=false LD_EXEC=false assertCommandSuccess copy_passwd_and_group - assertEquals "$(echo -e "-f /etc/passwd $JUNEST_HOME//etc/passwd\n-f /etc/group $JUNEST_HOME//etc/group")" "$(cat $STDOUTF)" + assertEquals "$(echo -e "-f /etc/passwd $JUNEST_HOME//etc/passwd\n-f /etc/group $JUNEST_HOME//etc/group")" "$(cat "$STDOUTF")" } function test_copy_passwd_and_group_failure(){ @@ -213,14 +221,14 @@ function test_nested_env_not_set_variable(){ } function test_check_same_arch_not_same(){ - echo "JUNEST_ARCH=XXX" > ${JUNEST_HOME}/etc/junest/info + echo "JUNEST_ARCH=XXX" > "${JUNEST_HOME}"/etc/junest/info assertCommandFailOnStatus 104 check_same_arch } function test_check_same_arch(){ - echo "JUNEST_ARCH=$ARCH" > ${JUNEST_HOME}/etc/junest/info + echo "JUNEST_ARCH=$ARCH" > "${JUNEST_HOME}"/etc/junest/info assertCommandSuccess check_same_arch } -source $JUNEST_ROOT/tests/utils/shunit2 +source "$JUNEST_ROOT"/tests/utils/shunit2 diff --git a/tests/unit-tests/test-junest.sh b/tests/unit-tests/test-junest.sh index 123b4bd..086062f 100755 --- a/tests/unit-tests/test-junest.sh +++ b/tests/unit-tests/test-junest.sh @@ -1,8 +1,10 @@ #!/bin/bash -source "$(dirname $0)/../utils/utils.sh" +# shellcheck disable=SC1091 -JUNEST_BASE="$(dirname $0)/../.." -source $JUNEST_BASE/bin/junest -h &> /dev/null +source "$(dirname "$0")/../utils/utils.sh" + +JUNEST_BASE="$(dirname "$0")/../.." +source "$JUNEST_BASE"/bin/junest -h &> /dev/null # Disable the exiterr set +e @@ -37,42 +39,42 @@ function setUp(){ local backend_args="$2" local no_copy_files="$3" shift 3 - echo "run_env_as_proot_fakeroot($backend_command,$backend_args,$no_copy_files,$@)" + echo "run_env_as_proot_fakeroot($backend_command,$backend_args,$no_copy_files,$*)" } function run_env_as_groot(){ local backend_command="$1" local backend_args="$2" local no_copy_files="$3" shift 3 - echo "run_env_as_groot($backend_command,$backend_args,$no_copy_files,$@)" + echo "run_env_as_groot($backend_command,$backend_args,$no_copy_files,$*)" } function run_env_as_chroot(){ local backend_command="$1" local backend_args="$2" local no_copy_files="$3" shift 3 - echo "run_env_as_chroot($backend_command,$backend_args,$no_copy_files,$@)" + echo "run_env_as_chroot($backend_command,$backend_args,$no_copy_files,$*)" } function run_env_as_proot_user(){ local backend_command="$1" local backend_args="$2" local no_copy_files="$3" shift 3 - echo "run_env_as_proot_user($backend_command,$backend_args,$no_copy_files,$@)" + echo "run_env_as_proot_user($backend_command,$backend_args,$no_copy_files,$*)" } function run_env_as_bwrap_fakeroot(){ local backend_command="$1" local backend_args="$2" local no_copy_files="$3" shift 3 - echo "run_env_as_bwrap_fakeroot($backend_command,$backend_args,$no_copy_files,$@)" + echo "run_env_as_bwrap_fakeroot($backend_command,$backend_args,$no_copy_files,$*)" } function run_env_as_bwrap_user(){ local backend_command="$1" local backend_args="$2" local no_copy_files="$3" shift 3 - echo "run_env_as_bwrap_user($backend_command,$backend_args,$no_copy_files,$@)" + echo "run_env_as_bwrap_user($backend_command,$backend_args,$no_copy_files,$*)" } function is_env_installed(){ return 0 @@ -84,25 +86,25 @@ function setUp(){ function test_help(){ assertCommandSuccess main -h - assertEquals "usage" "$(cat $STDOUTF)" + assertEquals "usage" "$(cat "$STDOUTF")" assertCommandSuccess main --help - assertEquals "usage" "$(cat $STDOUTF)" + assertEquals "usage" "$(cat "$STDOUTF")" } function test_version(){ assertCommandSuccess main -V - assertEquals "version" "$(cat $STDOUTF)" + assertEquals "version" "$(cat "$STDOUTF")" assertCommandSuccess main --version - assertEquals "version" "$(cat $STDOUTF)" + assertEquals "version" "$(cat "$STDOUTF")" } function test_build_image_env(){ assertCommandSuccess main b - assertEquals "build_image_env(false)" "$(cat $STDOUTF)" + assertEquals "build_image_env(false)" "$(cat "$STDOUTF")" assertCommandSuccess main build - assertEquals "build_image_env(false)" "$(cat $STDOUTF)" + assertEquals "build_image_env(false)" "$(cat "$STDOUTF")" assertCommandSuccess main b -n - assertEquals "build_image_env(true)" "$(cat $STDOUTF)" + assertEquals "build_image_env(true)" "$(cat "$STDOUTF")" assertCommandSuccess main build --disable-check - assertEquals "build_image_env(true)" "$(cat $STDOUTF)" + assertEquals "build_image_env(true)" "$(cat "$STDOUTF")" } function test_create_wrappers(){ @@ -111,26 +113,26 @@ function test_create_wrappers(){ echo "create_wrappers($force)" } assertCommandSuccess main create-bin-wrappers - assertEquals "create_wrappers(false)" "$(cat $STDOUTF)" + assertEquals "create_wrappers(false)" "$(cat "$STDOUTF")" assertCommandSuccess main create-bin-wrappers --force - assertEquals "create_wrappers(true)" "$(cat $STDOUTF)" + assertEquals "create_wrappers(true)" "$(cat "$STDOUTF")" } function test_delete_env(){ assertCommandSuccess main s -d - assertEquals "delete_env" "$(cat $STDOUTF)" + assertEquals "delete_env" "$(cat "$STDOUTF")" assertCommandSuccess main setup --delete - assertEquals "delete_env" "$(cat $STDOUTF)" + assertEquals "delete_env" "$(cat "$STDOUTF")" } function test_setup_env_from_file(){ is_env_installed(){ return 1 } assertCommandSuccess main s -i myimage - assertEquals "setup_env_from_file(myimage)" "$(cat $STDOUTF)" + assertEquals "setup_env_from_file(myimage)" "$(cat "$STDOUTF")" assertCommandSuccess main setup --from-file myimage - assertEquals "setup_env_from_file(myimage)" "$(cat $STDOUTF)" + assertEquals "setup_env_from_file(myimage)" "$(cat "$STDOUTF")" is_env_installed(){ return 0 @@ -143,13 +145,13 @@ function test_setup_env(){ return 1 } assertCommandSuccess main s - assertEquals "setup_env()" "$(cat $STDOUTF)" + assertEquals "setup_env()" "$(cat "$STDOUTF")" assertCommandSuccess main setup - assertEquals "setup_env()" "$(cat $STDOUTF)" + assertEquals "setup_env()" "$(cat "$STDOUTF")" assertCommandSuccess main s -a arm - assertEquals "setup_env(arm)" "$(cat $STDOUTF)" + assertEquals "setup_env(arm)" "$(cat "$STDOUTF")" assertCommandSuccess main setup --arch arm - assertEquals "setup_env(arm)" "$(cat $STDOUTF)" + assertEquals "setup_env(arm)" "$(cat "$STDOUTF")" is_env_installed(){ return 0 @@ -159,25 +161,25 @@ function test_setup_env(){ function test_run_env_as_proot_fakeroot(){ assertCommandSuccess main p -f - assertEquals "run_env_as_proot_fakeroot(,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main proot --fakeroot - assertEquals "run_env_as_proot_fakeroot(,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main p -f -n - assertEquals "run_env_as_proot_fakeroot(,,true,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,,true,)" "$(cat "$STDOUTF")" assertCommandSuccess main p -f --backend-command blah - assertEquals "run_env_as_proot_fakeroot(blah,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(blah,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main proot -f --backend-command blah - assertEquals "run_env_as_proot_fakeroot(blah,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(blah,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main proot -f -b "-b arg" - assertEquals "run_env_as_proot_fakeroot(,-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,-b arg,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main proot -f -b "-b arg" -- command -kv - assertEquals "run_env_as_proot_fakeroot(,-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,-b arg,false,command -kv)" "$(cat "$STDOUTF")" assertCommandSuccess main proot -f command --as - assertEquals "run_env_as_proot_fakeroot(,,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,,false,command --as)" "$(cat "$STDOUTF")" assertCommandSuccess main proot -f -- command --as - assertEquals "run_env_as_proot_fakeroot(,,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_fakeroot(,,false,command --as)" "$(cat "$STDOUTF")" is_env_installed(){ return 1 @@ -187,23 +189,23 @@ function test_run_env_as_proot_fakeroot(){ function test_run_env_as_user(){ assertCommandSuccess main proot - assertEquals "run_env_as_proot_user(,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main p -n - assertEquals "run_env_as_proot_user(,,true,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,,true,)" "$(cat "$STDOUTF")" assertCommandSuccess main p --backend-command blah - assertEquals "run_env_as_proot_user(blah,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(blah,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main proot --backend-command blah - assertEquals "run_env_as_proot_user(blah,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(blah,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main proot -b "-b arg" - assertEquals "run_env_as_proot_user(,-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,-b arg,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main proot -b "-b arg" -- command -ll - assertEquals "run_env_as_proot_user(,-b arg,false,command -ll)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,-b arg,false,command -ll)" "$(cat "$STDOUTF")" assertCommandSuccess main proot command -ls - assertEquals "run_env_as_proot_user(,,false,command -ls)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,,false,command -ls)" "$(cat "$STDOUTF")" assertCommandSuccess main proot -- command -ls - assertEquals "run_env_as_proot_user(,,false,command -ls)" "$(cat $STDOUTF)" + assertEquals "run_env_as_proot_user(,,false,command -ls)" "$(cat "$STDOUTF")" is_env_installed(){ return 1 @@ -213,21 +215,21 @@ function test_run_env_as_user(){ function test_run_env_as_groot(){ assertCommandSuccess main g - assertEquals "run_env_as_groot(,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_groot(,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main g -n - assertEquals "run_env_as_groot(,,true,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_groot(,,true,)" "$(cat "$STDOUTF")" assertCommandSuccess main g -b "-b arg" - assertEquals "run_env_as_groot(,-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_groot(,-b arg,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main g --backend-command blah - assertEquals "run_env_as_groot(blah,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_groot(blah,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main groot --backend-command blah - assertEquals "run_env_as_groot(blah,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_groot(blah,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main groot command - assertEquals "run_env_as_groot(,,false,command)" "$(cat $STDOUTF)" + assertEquals "run_env_as_groot(,,false,command)" "$(cat "$STDOUTF")" assertCommandSuccess main groot -- command - assertEquals "run_env_as_groot(,,false,command)" "$(cat $STDOUTF)" + assertEquals "run_env_as_groot(,,false,command)" "$(cat "$STDOUTF")" is_env_installed(){ return 1 @@ -237,19 +239,19 @@ function test_run_env_as_groot(){ function test_run_env_as_chroot(){ assertCommandSuccess main r - assertEquals "run_env_as_chroot(,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_chroot(,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main r -b "-b arg" - assertEquals "run_env_as_chroot(,-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_chroot(,-b arg,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main r --backend-command blah - assertEquals "run_env_as_chroot(blah,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_chroot(blah,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main root --backend-command blah - assertEquals "run_env_as_chroot(blah,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_chroot(blah,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main root command - assertEquals "run_env_as_chroot(,,false,command)" "$(cat $STDOUTF)" + assertEquals "run_env_as_chroot(,,false,command)" "$(cat "$STDOUTF")" assertCommandSuccess main root -- command - assertEquals "run_env_as_chroot(,,false,command)" "$(cat $STDOUTF)" + assertEquals "run_env_as_chroot(,,false,command)" "$(cat "$STDOUTF")" is_env_installed(){ return 1 @@ -259,39 +261,39 @@ function test_run_env_as_chroot(){ function test_run_env_as_bwrap_fakeroot(){ assertCommandSuccess main n -f - assertEquals "run_env_as_bwrap_fakeroot(,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main ns -f - assertEquals "run_env_as_bwrap_fakeroot(,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main ns -n -f - assertEquals "run_env_as_bwrap_fakeroot(,,true,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,true,)" "$(cat "$STDOUTF")" assertCommandSuccess main ns -f -b "-b arg" - assertEquals "run_env_as_bwrap_fakeroot(,-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,-b arg,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main ns -f -b "-b arg" -- command -kv - assertEquals "run_env_as_bwrap_fakeroot(,-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,-b arg,false,command -kv)" "$(cat "$STDOUTF")" assertCommandSuccess main ns -f command --as - assertEquals "run_env_as_bwrap_fakeroot(,,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,command --as)" "$(cat "$STDOUTF")" assertCommandSuccess main ns -f -- command --as - assertEquals "run_env_as_bwrap_fakeroot(,,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,command --as)" "$(cat "$STDOUTF")" assertCommandSuccess main ns -f --backend-command blah - assertEquals "run_env_as_bwrap_fakeroot(blah,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(blah,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main -f --backend-command blah - assertEquals "run_env_as_bwrap_fakeroot(blah,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(blah,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main -f - assertEquals "run_env_as_bwrap_fakeroot(,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main -f - assertEquals "run_env_as_bwrap_fakeroot(,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main -f -b "-b arg" - assertEquals "run_env_as_bwrap_fakeroot(,-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,-b arg,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main -f -b "-b arg" -- command -kv - assertEquals "run_env_as_bwrap_fakeroot(,-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,-b arg,false,command -kv)" "$(cat "$STDOUTF")" assertCommandSuccess main -f command --as - assertEquals "run_env_as_bwrap_fakeroot(,,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,command --as)" "$(cat "$STDOUTF")" assertCommandSuccess main -f -- command --as - assertEquals "run_env_as_bwrap_fakeroot(,,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_fakeroot(,,false,command --as)" "$(cat "$STDOUTF")" is_env_installed(){ return 1 @@ -301,39 +303,39 @@ function test_run_env_as_bwrap_fakeroot(){ function test_run_env_as_bwrap_user(){ assertCommandSuccess main n - assertEquals "run_env_as_bwrap_user(,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main ns - assertEquals "run_env_as_bwrap_user(,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main ns -n - assertEquals "run_env_as_bwrap_user(,,true,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,true,)" "$(cat "$STDOUTF")" assertCommandSuccess main ns -b "-b arg" - assertEquals "run_env_as_bwrap_user(,-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,-b arg,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main ns -b "-b arg" -- command -kv - assertEquals "run_env_as_bwrap_user(,-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,-b arg,false,command -kv)" "$(cat "$STDOUTF")" assertCommandSuccess main ns command --as - assertEquals "run_env_as_bwrap_user(,,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,command --as)" "$(cat "$STDOUTF")" assertCommandSuccess main ns -- command --as - assertEquals "run_env_as_bwrap_user(,,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,command --as)" "$(cat "$STDOUTF")" assertCommandSuccess main ns --backend-command blah - assertEquals "run_env_as_bwrap_user(blah,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(blah,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main --backend-command blah - assertEquals "run_env_as_bwrap_user(blah,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(blah,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main - assertEquals "run_env_as_bwrap_user(,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main - assertEquals "run_env_as_bwrap_user(,,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main -b "-b arg" - assertEquals "run_env_as_bwrap_user(,-b arg,false,)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,-b arg,false,)" "$(cat "$STDOUTF")" assertCommandSuccess main -b "-b arg" -- command -kv - assertEquals "run_env_as_bwrap_user(,-b arg,false,command -kv)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,-b arg,false,command -kv)" "$(cat "$STDOUTF")" assertCommandSuccess main command --as - assertEquals "run_env_as_bwrap_user(,,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,command --as)" "$(cat "$STDOUTF")" assertCommandSuccess main -- command --as - assertEquals "run_env_as_bwrap_user(,,false,command --as)" "$(cat $STDOUTF)" + assertEquals "run_env_as_bwrap_user(,,false,command --as)" "$(cat "$STDOUTF")" is_env_installed(){ return 1 @@ -353,4 +355,4 @@ function test_invalid_option(){ assertCommandFail main s --no-option } -source $(dirname $0)/../utils/shunit2 +source "$(dirname "$0")"/../utils/shunit2 diff --git a/tests/unit-tests/test-namespace.sh b/tests/unit-tests/test-namespace.sh index 72b9035..373c1be 100755 --- a/tests/unit-tests/test-namespace.sh +++ b/tests/unit-tests/test-namespace.sh @@ -1,6 +1,7 @@ #!/bin/bash +# shellcheck disable=SC1091 -JUNEST_ROOT=$(readlink -f $(dirname $0)/../..) +JUNEST_ROOT=$(readlink -f "$(dirname "$0")"/../..) source "$JUNEST_ROOT/tests/utils/utils.sh" @@ -16,7 +17,7 @@ function oneTimeSetUp(){ ## Mock functions ## function init_mocks() { function bwrap_cmd(){ - echo "$BWRAP $@" + echo "$BWRAP $*" } } @@ -39,16 +40,16 @@ function tearDown(){ } function _test_copy_common_files() { - [[ -e /etc/hosts ]] && assertEquals "$(cat /etc/hosts)" "$(cat ${JUNEST_HOME}/etc/hosts)" - [[ -e /etc/host.conf ]] && assertEquals "$(cat /etc/host.conf)" "$(cat ${JUNEST_HOME}/etc/host.conf)" - [[ -e /etc/nsswitch.conf ]] && assertEquals "$(cat /etc/nsswitch.conf)" "$(cat ${JUNEST_HOME}/etc/nsswitch.conf)" - [[ -e /etc/resolv.conf ]] && assertEquals "$(cat /etc/resolv.conf)" "$(cat ${JUNEST_HOME}/etc/resolv.conf)" + [[ -e /etc/hosts ]] && assertEquals "$(cat /etc/hosts)" "$(cat "${JUNEST_HOME}"/etc/hosts)" + [[ -e /etc/host.conf ]] && assertEquals "$(cat /etc/host.conf)" "$(cat "${JUNEST_HOME}"/etc/host.conf)" + [[ -e /etc/nsswitch.conf ]] && assertEquals "$(cat /etc/nsswitch.conf)" "$(cat "${JUNEST_HOME}"/etc/nsswitch.conf)" + [[ -e /etc/resolv.conf ]] && assertEquals "$(cat /etc/resolv.conf)" "$(cat "${JUNEST_HOME}"/etc/resolv.conf)" } function _test_copy_remaining_files() { - [[ -e /etc/hosts.equiv ]] && assertEquals "$(cat /etc/hosts.equiv)" "$(cat ${JUNEST_HOME}/etc/hosts.equiv)" - [[ -e /etc/netgroup ]] && assertEquals "$(cat /etc/netgroup)" "$(cat ${JUNEST_HOME}/etc/netgroup)" - [[ -e /etc/networks ]] && assertEquals "$(cat /etc/networks)" "$(cat ${JUNEST_HOME}/etc/networks)" + [[ -e /etc/hosts.equiv ]] && assertEquals "$(cat /etc/hosts.equiv)" "$(cat "${JUNEST_HOME}"/etc/hosts.equiv)" + [[ -e /etc/netgroup ]] && assertEquals "$(cat /etc/netgroup)" "$(cat "${JUNEST_HOME}"/etc/netgroup)" + [[ -e /etc/networks ]] && assertEquals "$(cat /etc/networks)" "$(cat "${JUNEST_HOME}"/etc/networks)" [[ -e ${JUNEST_HOME}/etc/passwd ]] assertEquals 0 $? @@ -59,7 +60,7 @@ function _test_copy_remaining_files() { function test_is_user_namespace_enabled_no_config_file(){ CONFIG_PROC_FILE="blah" CONFIG_BOOT_FILE="blah" - assertCommandFailOnStatus $NOT_EXISTING_FILE _is_user_namespace_enabled + assertCommandFailOnStatus "$NOT_EXISTING_FILE" _is_user_namespace_enabled } function test_is_user_namespace_enabled_no_config(){ @@ -67,7 +68,7 @@ function test_is_user_namespace_enabled_no_config(){ gzip config CONFIG_PROC_FILE="config.gz" CONFIG_BOOT_FILE="blah" - assertCommandFailOnStatus $NO_CONFIG_FOUND _is_user_namespace_enabled + assertCommandFailOnStatus "$NO_CONFIG_FOUND" _is_user_namespace_enabled } function test_is_user_namespace_enabled_with_config(){ @@ -86,13 +87,15 @@ function test_is_user_namespace_enabled_with_userns_clone_file_disabled(){ CONFIG_BOOT_FILE="blah" PROC_USERNS_CLONE_FILE="unprivileged_userns_clone" echo "0" > $PROC_USERNS_CLONE_FILE - assertCommandFailOnStatus $UNPRIVILEGED_USERNS_DISABLED _is_user_namespace_enabled + assertCommandFailOnStatus "$UNPRIVILEGED_USERNS_DISABLED" _is_user_namespace_enabled } function test_is_user_namespace_enabled_with_userns_clone_file_enabled(){ echo "CONFIG_USER_NS=y" > config gzip config + # shellcheck disable=SC2034 CONFIG_PROC_FILE="config.gz" + # shellcheck disable=SC2034 CONFIG_BOOT_FILE="blah" PROC_USERNS_CLONE_FILE="unprivileged_userns_clone" echo "1" > $PROC_USERNS_CLONE_FILE @@ -101,21 +104,21 @@ function test_is_user_namespace_enabled_with_userns_clone_file_enabled(){ function test_run_env_as_bwrap_fakeroot() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" - assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat "$STDOUTF")" _test_copy_common_files } function test_run_env_as_bwrap_fakeroot_with_backend_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "mybwrap" "" "false" - assertEquals "mybwrap $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "mybwrap $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat "$STDOUTF")" _test_copy_common_files } function test_run_env_as_bwrap_user() { assertCommandSuccess run_env_as_bwrap_user "" "" "false" - assertEquals "$BWRAP $COMMON_BWRAP_OPTION /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION /bin/sh --login" "$(cat "$STDOUTF")" _test_copy_common_files _test_copy_remaining_files @@ -123,7 +126,7 @@ function test_run_env_as_bwrap_user() { function test_run_env_as_bwrap_user_with_backend_command() { assertCommandSuccess run_env_as_bwrap_user "mybwrap" "" "false" - assertEquals "mybwrap $COMMON_BWRAP_OPTION /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "mybwrap $COMMON_BWRAP_OPTION /bin/sh --login" "$(cat "$STDOUTF")" _test_copy_common_files _test_copy_remaining_files @@ -131,7 +134,7 @@ function test_run_env_as_bwrap_user_with_backend_command() { function test_run_env_as_bwrap_fakeroot_no_copy() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "true" "" - assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat "$STDOUTF")" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -157,7 +160,7 @@ function test_run_env_as_bwrap_fakeroot_no_copy() { function test_run_env_as_bwrap_user_no_copy() { assertCommandSuccess run_env_as_bwrap_user "" "" "true" "" - assertEquals "$BWRAP $COMMON_BWRAP_OPTION /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION /bin/sh --login" "$(cat "$STDOUTF")" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -183,14 +186,14 @@ function test_run_env_as_bwrap_user_no_copy() { function test_run_env_as_bwrap_fakeroot_with_backend_args() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" - assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login" "$(cat "$STDOUTF")" _test_copy_common_files } function test_run_env_as_bwrap_user_with_backend_args() { assertCommandSuccess run_env_as_bwrap_user "" "--bind /usr /usr" "false" - assertEquals "$BWRAP $COMMON_BWRAP_OPTION --bind /usr /usr /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --bind /usr /usr /bin/sh --login" "$(cat "$STDOUTF")" _test_copy_common_files _test_copy_remaining_files @@ -198,14 +201,14 @@ function test_run_env_as_bwrap_user_with_backend_args() { function test_run_env_as_bwrap_fakeroot_with_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" "ls -la" - assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login -c \"ls -la\"" "$(cat "$STDOUTF")" _test_copy_common_files } function test_run_env_as_bwrap_user_with_command() { assertCommandSuccess run_env_as_bwrap_user "" "" "false" "ls -la" - assertEquals "$BWRAP $COMMON_BWRAP_OPTION /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION /bin/sh --login -c \"ls -la\"" "$(cat "$STDOUTF")" _test_copy_common_files _test_copy_remaining_files @@ -213,14 +216,14 @@ function test_run_env_as_bwrap_user_with_command() { function test_run_env_as_bwrap_fakeroot_with_backend_args_and_command() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "--bind /usr /usr" "false" "ls -la" - assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 --bind /usr /usr sudo /bin/sh --login -c \"ls -la\"" "$(cat "$STDOUTF")" _test_copy_common_files } function test_run_env_as_bwrap_user_with_backend_args_and_command() { assertCommandSuccess run_env_as_bwrap_user "" "--bind /usr /usr" "false" "ls -la" - assertEquals "$BWRAP $COMMON_BWRAP_OPTION --bind /usr /usr /bin/sh --login -c \"ls -la\"" "$(cat $STDOUTF)" + assertEquals "$BWRAP $COMMON_BWRAP_OPTION --bind /usr /usr /bin/sh --login -c \"ls -la\"" "$(cat "$STDOUTF")" _test_copy_common_files _test_copy_remaining_files @@ -233,9 +236,10 @@ function test_run_env_as_bwrap_fakeroot_nested_env(){ } function test_run_env_as_bwrap_user_nested_env(){ + # shellcheck disable=SC2034 JUNEST_ENV=1 assertCommandFailOnStatus 106 run_env_as_bwrap_user "" "" "false" "" unset JUNEST_ENV } -source $JUNEST_ROOT/tests/utils/shunit2 +source "$JUNEST_ROOT"/tests/utils/shunit2 diff --git a/tests/unit-tests/test-proot.sh b/tests/unit-tests/test-proot.sh index 9e152f9..2217150 100755 --- a/tests/unit-tests/test-proot.sh +++ b/tests/unit-tests/test-proot.sh @@ -1,6 +1,7 @@ #!/bin/bash +# shellcheck disable=SC1091 -JUNEST_ROOT=$(readlink -f $(dirname $0)/../..) +JUNEST_ROOT=$(readlink -f "$(dirname "$0")"/../..) source "$JUNEST_ROOT/tests/utils/utils.sh" @@ -30,16 +31,16 @@ function tearDown(){ } function _test_copy_common_files() { - [[ -e /etc/hosts ]] && assertEquals "$(cat /etc/hosts)" "$(cat ${JUNEST_HOME}/etc/hosts)" - [[ -e /etc/host.conf ]] && assertEquals "$(cat /etc/host.conf)" "$(cat ${JUNEST_HOME}/etc/host.conf)" - [[ -e /etc/nsswitch.conf ]] && assertEquals "$(cat /etc/nsswitch.conf)" "$(cat ${JUNEST_HOME}/etc/nsswitch.conf)" - [[ -e /etc/resolv.conf ]] && assertEquals "$(cat /etc/resolv.conf)" "$(cat ${JUNEST_HOME}/etc/resolv.conf)" + [[ -e /etc/hosts ]] && assertEquals "$(cat /etc/hosts)" "$(cat "${JUNEST_HOME}"/etc/hosts)" + [[ -e /etc/host.conf ]] && assertEquals "$(cat /etc/host.conf)" "$(cat "${JUNEST_HOME}"/etc/host.conf)" + [[ -e /etc/nsswitch.conf ]] && assertEquals "$(cat /etc/nsswitch.conf)" "$(cat "${JUNEST_HOME}"/etc/nsswitch.conf)" + [[ -e /etc/resolv.conf ]] && assertEquals "$(cat /etc/resolv.conf)" "$(cat "${JUNEST_HOME}"/etc/resolv.conf)" } function _test_copy_remaining_files() { - [[ -e /etc/hosts.equiv ]] && assertEquals "$(cat /etc/hosts.equiv)" "$(cat ${JUNEST_HOME}/etc/hosts.equiv)" - [[ -e /etc/netgroup ]] && assertEquals "$(cat /etc/netgroup)" "$(cat ${JUNEST_HOME}/etc/netgroup)" - [[ -e /etc/networks ]] && assertEquals "$(cat /etc/networks)" "$(cat ${JUNEST_HOME}/etc/networks)" + [[ -e /etc/hosts.equiv ]] && assertEquals "$(cat /etc/hosts.equiv)" "$(cat "${JUNEST_HOME}"/etc/hosts.equiv)" + [[ -e /etc/netgroup ]] && assertEquals "$(cat /etc/netgroup)" "$(cat "${JUNEST_HOME}"/etc/netgroup)" + [[ -e /etc/networks ]] && assertEquals "$(cat /etc/networks)" "$(cat "${JUNEST_HOME}"/etc/networks)" [[ -e ${JUNEST_HOME}/etc/passwd ]] assertEquals 0 $? @@ -49,14 +50,16 @@ function _test_copy_remaining_files() { function test_run_env_as_proot_user(){ _run_env_with_qemu() { - echo $@ + # shellcheck disable=SC2086 + # shellcheck disable=SC2048 + echo $* } assertCommandSuccess run_env_as_proot_user "" "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" - assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" + assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" SH=("/usr/bin/echo") assertCommandSuccess run_env_as_proot_user "" "-k 3.10" "false" - assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat $STDOUTF)" + assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat "$STDOUTF")" _test_copy_common_files _test_copy_remaining_files @@ -64,14 +67,16 @@ function test_run_env_as_proot_user(){ function test_run_env_as_proot_user_with_backend_command(){ _run_env_with_qemu() { - echo $@ + # shellcheck disable=SC2086 + # shellcheck disable=SC2048 + echo $* } assertCommandSuccess run_env_as_proot_user "myproot" "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" - assertEquals "myproot -b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" + assertEquals "myproot -b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" SH=("/usr/bin/echo") assertCommandSuccess run_env_as_proot_user "myproot" "-k 3.10" "false" - assertEquals "myproot -b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat $STDOUTF)" + assertEquals "myproot -b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat "$STDOUTF")" _test_copy_common_files _test_copy_remaining_files @@ -79,10 +84,12 @@ function test_run_env_as_proot_user_with_backend_command(){ function test_run_env_as_proot_user_no_copy(){ _run_env_with_qemu() { - echo $@ + # shellcheck disable=SC2086 + # shellcheck disable=SC2048 + echo $* } assertCommandSuccess run_env_as_proot_user "" "-k 3.10" "true" "/usr/bin/mkdir" "-v" "/newdir2" - assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" + assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -114,28 +121,33 @@ function test_run_env_as_proot_user_nested_env(){ function test_run_env_as_proot_fakeroot(){ _run_env_with_qemu() { - echo $@ + # shellcheck disable=SC2086 + # shellcheck disable=SC2048 + echo $* } assertCommandSuccess run_env_as_proot_fakeroot "" "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" - assertEquals "-0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" + assertEquals "-0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" SH=("/usr/bin/echo") assertCommandSuccess run_env_as_proot_fakeroot "" "-k 3.10" "false" - assertEquals "-0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat $STDOUTF)" + assertEquals "-0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat "$STDOUTF")" _test_copy_common_files } function test_run_env_as_proot_fakeroot_with_backend_command(){ _run_env_with_qemu() { - echo $@ + # shellcheck disable=SC2086 + # shellcheck disable=SC2048 + echo $* } assertCommandSuccess run_env_as_proot_fakeroot "myproot" "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" - assertEquals "myproot -0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" + assertEquals "myproot -0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" + # shellcheck disable=SC2034 SH=("/usr/bin/echo") assertCommandSuccess run_env_as_proot_fakeroot "myproot" "-k 3.10" "false" - assertEquals "myproot -0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat $STDOUTF)" + assertEquals "myproot -0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat "$STDOUTF")" _test_copy_common_files } @@ -148,41 +160,51 @@ function test_run_env_as_proot_fakeroot_nested_env(){ function test_run_env_with_quotes(){ _run_env_with_qemu() { - echo $@ + # shellcheck disable=SC2086 + # shellcheck disable=SC2048 + echo $* } assertCommandSuccess run_env_as_proot_user "" "-k 3.10" "false" "bash" "-c" "/usr/bin/mkdir -v /newdir2" - assertEquals "-b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 bash -c /usr/bin/mkdir -v /newdir2" "$(cat $STDOUTF)" + assertEquals "-b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 bash -c /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" } function test_run_env_with_proot_args(){ proot_cmd() { [ "$JUNEST_ENV" != "1" ] && return 1 - echo $@ + # shellcheck disable=SC2086 + # shellcheck disable=SC2048 + echo $* } assertCommandSuccess _run_env_with_proot "" "--help" - assertEquals "--help /bin/sh --login" "$(cat $STDOUTF)" + assertEquals "--help /bin/sh --login" "$(cat "$STDOUTF")" assertCommandSuccess _run_env_with_proot "" "--help" mycommand - assertEquals "--help /bin/sh --login -c mycommand" "$(cat $STDOUTF)" + assertEquals "--help /bin/sh --login -c mycommand" "$(cat "$STDOUTF")" assertCommandFail _run_env_with_proot } function test_qemu() { - echo "JUNEST_ARCH=arm" > ${JUNEST_HOME}/etc/junest/info + echo "JUNEST_ARCH=arm" > "${JUNEST_HOME}"/etc/junest/info rm_cmd() { - echo $@ + # shellcheck disable=SC2086 + # shellcheck disable=SC2048 + echo $* } ln_cmd() { - echo $@ + # shellcheck disable=SC2086 + # shellcheck disable=SC2048 + echo $* } _run_env_with_proot() { - echo $@ + # shellcheck disable=SC2086 + # shellcheck disable=SC2048 + echo $* } RANDOM=100 ARCH=x86_64 assertCommandSuccess _run_env_with_qemu "" "" - assertEquals "$(echo -e "-s $JUNEST_HOME/bin/qemu-arm-static-x86_64 /tmp/qemu-arm-static-x86_64-100\n-q /tmp/qemu-arm-static-x86_64-100")" "$(cat $STDOUTF)" + assertEquals "$(echo -e "-s $JUNEST_HOME/bin/qemu-arm-static-x86_64 /tmp/qemu-arm-static-x86_64-100\n-q /tmp/qemu-arm-static-x86_64-100")" "$(cat "$STDOUTF")" } -source $JUNEST_ROOT/tests/utils/shunit2 +source "$JUNEST_ROOT"/tests/utils/shunit2 diff --git a/tests/unit-tests/test-setup.sh b/tests/unit-tests/test-setup.sh index a15dbca..d8c2456 100755 --- a/tests/unit-tests/test-setup.sh +++ b/tests/unit-tests/test-setup.sh @@ -1,6 +1,7 @@ #!/bin/bash +# shellcheck disable=SC1091 -JUNEST_ROOT=$(readlink -f $(dirname $0)/../..) +JUNEST_ROOT=$(readlink -f "$(dirname "$0")"/../..) source "$JUNEST_ROOT/tests/utils/utils.sh" @@ -26,24 +27,26 @@ function tearDown(){ } function test_is_env_installed(){ - rm -rf $JUNEST_HOME/* + rm -rf "${JUNEST_HOME:?}"/* assertCommandFail is_env_installed - touch $JUNEST_HOME/just_file + touch "$JUNEST_HOME"/just_file assertCommandSuccess is_env_installed } function test_setup_env(){ - rm -rf $JUNEST_HOME/* + rm -rf "${JUNEST_HOME:?}"/* wget_mock(){ # Proof that the setup is happening # inside $JUNEST_TEMPDIR - local cwd=${PWD#${JUNEST_TEMPDIR}} - local parent_dir=${PWD%${cwd}} + local cwd=${PWD#"${JUNEST_TEMPDIR}"} + local parent_dir=${PWD%"${cwd}"} assertEquals "$JUNEST_TEMPDIR" "${parent_dir}" touch file - tar -czvf ${CMD}-${ARCH}.tar.gz file + tar -czvf "${CMD}-${ARCH}".tar.gz file } + # shellcheck disable=SC2034 WGET=wget_mock + # shellcheck disable=SC2119 setup_env 1> /dev/null assertTrue "[ -e $JUNEST_HOME/file ]" @@ -52,10 +55,10 @@ function test_setup_env(){ function test_setup_env_from_file(){ - rm -rf $JUNEST_HOME/* + rm -rf "${JUNEST_HOME:?}"/* touch file - tar -czvf ${CMD}-${ARCH}.tar.gz file 1> /dev/null - assertCommandSuccess setup_env_from_file ${CMD}-${ARCH}.tar.gz + tar -czvf "${CMD}-${ARCH}".tar.gz file 1> /dev/null + assertCommandSuccess setup_env_from_file "${CMD}-${ARCH}.tar.gz" assertTrue "[ -e $JUNEST_HOME/file ]" } @@ -64,10 +67,10 @@ function test_setup_env_from_file_not_existing_file(){ } function test_setup_env_from_file_with_absolute_path(){ - rm -rf $JUNEST_HOME/* + rm -rf "${JUNEST_HOME:?}"/* touch file - tar -czf ${CMD}-${ARCH}.tar.gz file - assertCommandSuccess setup_env_from_file ${CMD}-${ARCH}.tar.gz + tar -czf "${CMD}-${ARCH}".tar.gz file + assertCommandSuccess setup_env_from_file "${CMD}-${ARCH}.tar.gz" assertTrue "[ -e $JUNEST_HOME/file ]" } @@ -78,4 +81,4 @@ function test_delete_env(){ assertCommandFail is_env_installed } -source $JUNEST_ROOT/tests/utils/shunit2 +source "$JUNEST_ROOT"/tests/utils/shunit2 diff --git a/tests/unit-tests/test-utils.sh b/tests/unit-tests/test-utils.sh index c0b1ebf..03e602a 100755 --- a/tests/unit-tests/test-utils.sh +++ b/tests/unit-tests/test-utils.sh @@ -1,10 +1,13 @@ #!/bin/bash -source "$(dirname $0)/../utils/utils.sh" +# shellcheck disable=SC1091 + +source "$(dirname "$0")/../utils/utils.sh" unset HOME -export HOME=$(TMPDIR=/tmp mktemp -d -t pearl-user-home.XXXXXXX) +export HOME +HOME=$(TMPDIR=/tmp mktemp -d -t pearl-user-home.XXXXXXX) -source "$(dirname $0)/../../lib/utils/utils.sh" +source "$(dirname "$0")/../../lib/utils/utils.sh" # Disable the exiterr set +e @@ -20,37 +23,42 @@ function test_check_not_null(){ function test_echoerr(){ assertCommandSuccess echoerr "Test" - assertEquals "Test" "$(cat $STDERRF)" + assertEquals "Test" "$(cat "$STDERRF")" } function test_error(){ assertCommandSuccess error "Test" - local expected=$(echo -e "\033[1;31mTest\033[0m") - assertEquals "$expected" "$(cat $STDERRF)" + local expected + expected=$(echo -e "\033[1;31mTest\033[0m") + assertEquals "$expected" "$(cat "$STDERRF")" } function test_warn(){ assertCommandSuccess warn "Test" - local expected=$(echo -e "\033[1;33mTest\033[0m") - assertEquals "$expected" "$(cat $STDERRF)" + local expected + expected=$(echo -e "\033[1;33mTest\033[0m") + assertEquals "$expected" "$(cat "$STDERRF")" } function test_info(){ assertCommandSuccess info "Test" - local expected=$(echo -e "\033[1;36mTest\033[0m") - assertEquals "$expected" "$(cat $STDOUTF)" + local expected + expected=$(echo -e "\033[1;36mTest\033[0m") + assertEquals "$expected" "$(cat "$STDOUTF")" } function test_die(){ assertCommandFail die "Test" - local expected=$(echo -e "\033[1;31mTest\033[0m") - assertEquals "$expected" "$(cat $STDERRF)" + local expected + expected=$(echo -e "\033[1;31mTest\033[0m") + assertEquals "$expected" "$(cat "$STDERRF")" } function test_die_on_status(){ assertCommandFailOnStatus 222 die_on_status 222 "Test" - local expected=$(echo -e "\033[1;31mTest\033[0m") - assertEquals "$expected" "$(cat $STDERRF)" + local expected + expected=$(echo -e "\033[1;31mTest\033[0m") + assertEquals "$expected" "$(cat "$STDERRF")" } function test_ask_null_question(){ @@ -79,34 +87,12 @@ function test_ask_wrong_default_answer() { assertEquals 33 $? } -function test_check_and_trap_fail() { - trap echo EXIT - trap ls QUIT - assertCommandFailOnStatus 1 check_and_trap 'pwd' EXIT QUIT -} - -function test_check_and_trap() { - trap - EXIT QUIT - assertCommandSuccess check_and_trap 'echo' EXIT QUIT -} - -function test_check_and_force_trap_fail() { - trap echo EXIT - trap ls QUIT - assertCommandSuccess check_and_force_trap 'echo' EXIT QUIT -} - -function test_check_and_force_trap() { - trap - EXIT QUIT - assertCommandSuccess check_and_force_trap 'echo' EXIT QUIT -} - function test_insert_quotes_on_spaces(){ assertCommandSuccess insert_quotes_on_spaces this is "a test" - assertEquals "this is \"a test\"" "$(cat $STDOUTF)" + assertEquals "this is \"a test\"" "$(cat "$STDOUTF")" assertCommandSuccess insert_quotes_on_spaces this is 'a test' - assertEquals "this is \"a test\"" "$(cat $STDOUTF)" + assertEquals "this is \"a test\"" "$(cat "$STDOUTF")" } function test_contains_element(){ @@ -116,4 +102,4 @@ function test_contains_element(){ assertCommandFailOnStatus 1 contains_element "blabla" "${array[@]}" } -source $(dirname $0)/../utils/shunit2 +source "$(dirname "$0")"/../utils/shunit2 diff --git a/tests/unit-tests/test-wrappers.sh b/tests/unit-tests/test-wrappers.sh index 9daf0f9..af7aae2 100755 --- a/tests/unit-tests/test-wrappers.sh +++ b/tests/unit-tests/test-wrappers.sh @@ -1,7 +1,9 @@ #!/bin/bash -source "$(dirname $0)/../utils/utils.sh" +# shellcheck disable=SC1091 -source "$(dirname $0)/../../lib/core/wrappers.sh" +source "$(dirname "$0")/../utils/utils.sh" + +source "$(dirname "$0")/../../lib/core/wrappers.sh" # Disable the exiterr set +e @@ -20,61 +22,61 @@ function tearDown(){ function test_create_wrappers_empty_bin(){ assertCommandSuccess create_wrappers - assertEquals "" "$(cat $STDOUTF)" + assertEquals "" "$(cat "$STDOUTF")" assertTrue "bin_wrappers does not exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" } function test_create_wrappers_not_executable_file(){ - touch $JUNEST_HOME/usr/bin/myfile + touch "$JUNEST_HOME"/usr/bin/myfile assertCommandSuccess create_wrappers - assertEquals "" "$(cat $STDOUTF)" + assertEquals "" "$(cat "$STDOUTF")" assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" assertTrue "myfile wrapper should not exist" "[ ! -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" } function test_create_wrappers_executable_file(){ - touch $JUNEST_HOME/usr/bin/myfile - chmod +x $JUNEST_HOME/usr/bin/myfile + touch "$JUNEST_HOME"/usr/bin/myfile + chmod +x "$JUNEST_HOME"/usr/bin/myfile assertCommandSuccess create_wrappers - assertEquals "" "$(cat $STDOUTF)" + assertEquals "" "$(cat "$STDOUTF")" assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" assertTrue "myfile wrapper should exist" "[ -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" } function test_create_wrappers_already_exist(){ - touch $JUNEST_HOME/usr/bin/myfile - chmod +x $JUNEST_HOME/usr/bin/myfile - mkdir -p $JUNEST_HOME/usr/bin_wrappers - echo "original" > $JUNEST_HOME/usr/bin_wrappers/myfile - chmod +x $JUNEST_HOME/usr/bin_wrappers/myfile + touch "$JUNEST_HOME"/usr/bin/myfile + chmod +x "$JUNEST_HOME"/usr/bin/myfile + mkdir -p "$JUNEST_HOME"/usr/bin_wrappers + echo "original" > "$JUNEST_HOME"/usr/bin_wrappers/myfile + chmod +x "$JUNEST_HOME"/usr/bin_wrappers/myfile assertCommandSuccess create_wrappers false - assertEquals "" "$(cat $STDOUTF)" + assertEquals "" "$(cat "$STDOUTF")" assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" assertTrue "myfile wrapper should exist" "[ -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" - assertEquals "original" "$(cat $JUNEST_HOME/usr/bin_wrappers/myfile)" + assertEquals "original" "$(cat "$JUNEST_HOME"/usr/bin_wrappers/myfile)" } function test_create_wrappers_forced_already_exist(){ - echo "new" > $JUNEST_HOME/usr/bin/myfile - chmod +x $JUNEST_HOME/usr/bin/myfile - mkdir -p $JUNEST_HOME/usr/bin_wrappers - echo "original" > $JUNEST_HOME/usr/bin_wrappers/myfile - chmod +x $JUNEST_HOME/usr/bin_wrappers/myfile + echo "new" > "$JUNEST_HOME"/usr/bin/myfile + chmod +x "$JUNEST_HOME"/usr/bin/myfile + mkdir -p "$JUNEST_HOME"/usr/bin_wrappers + echo "original" > "$JUNEST_HOME"/usr/bin_wrappers/myfile + chmod +x "$JUNEST_HOME"/usr/bin_wrappers/myfile assertCommandSuccess create_wrappers true - assertEquals "" "$(cat $STDOUTF)" + assertEquals "" "$(cat "$STDOUTF")" assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" assertTrue "myfile wrapper should exist" "[ -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" - assertNotEquals "original" "$(cat $JUNEST_HOME/usr/bin_wrappers/myfile)" + assertNotEquals "original" "$(cat "$JUNEST_HOME"/usr/bin_wrappers/myfile)" } function test_create_wrappers_executable_no_longer_exist(){ - mkdir -p $JUNEST_HOME/usr/bin_wrappers - touch $JUNEST_HOME/usr/bin_wrappers/myfile - chmod +x $JUNEST_HOME/usr/bin_wrappers/myfile + mkdir -p "$JUNEST_HOME"/usr/bin_wrappers + touch "$JUNEST_HOME"/usr/bin_wrappers/myfile + chmod +x "$JUNEST_HOME"/usr/bin_wrappers/myfile assertCommandSuccess create_wrappers - assertEquals "" "$(cat $STDOUTF)" + assertEquals "" "$(cat "$STDOUTF")" assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" assertTrue "myfile wrapper should not exist" "[ ! -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" } -source $(dirname $0)/../utils/shunit2 +source "$(dirname "$0")"/../utils/shunit2 diff --git a/tests/unit-tests/unit-tests.sh b/tests/unit-tests/unit-tests.sh index acf1bba..e90ed22 100755 --- a/tests/unit-tests/unit-tests.sh +++ b/tests/unit-tests/unit-tests.sh @@ -1,6 +1,7 @@ #!/bin/bash tests_succeded=true -for tst in $(ls $(dirname $0)/test* | grep -v $(basename $0)) +# shellcheck disable=SC2010 +for tst in $(ls "$(dirname "$0")"/test* | grep -v "$(basename "$0")") do $tst || tests_succeded=false done diff --git a/tests/utils/utils.sh b/tests/utils/utils.sh index 542af68..ab37bd9 100644 --- a/tests/utils/utils.sh +++ b/tests/utils/utils.sh @@ -1,26 +1,28 @@ +#!/usr/bin/env bash + OLD_CWD=${PWD} function cwdSetUp(){ ORIGIN_CWD=$(TMPDIR=/tmp mktemp -d -t junest-cwd.XXXXXXXXXX) - cd $ORIGIN_CWD + cd "$ORIGIN_CWD" || return 1 } function cwdTearDown(){ - rm -rf $ORIGIN_CWD - cd $OLD_CWD + rm -rf "$ORIGIN_CWD" + cd "$OLD_CWD" || return 1 } function junestSetUp(){ JUNEST_HOME=$(TMPDIR=/tmp mktemp -d -t junest-home.XXXXXXXXXX) - mkdir -p ${JUNEST_HOME}/usr/bin - mkdir -p ${JUNEST_HOME}/etc/junest - echo "JUNEST_ARCH=x86_64" > ${JUNEST_HOME}/etc/junest/info - mkdir -p ${JUNEST_HOME}/etc/ca-certificates + mkdir -p "${JUNEST_HOME}/usr/bin" + mkdir -p "${JUNEST_HOME}/etc/junest" + echo "JUNEST_ARCH=x86_64" > "${JUNEST_HOME}/etc/junest/info" + mkdir -p "${JUNEST_HOME}/etc/ca-certificates" } function junestTearDown(){ # the CA directories are read only and can be deleted only by changing the mod - [ -d ${JUNEST_HOME}/etc/ca-certificates ] && chmod -R +w ${JUNEST_HOME}/etc/ca-certificates - rm -rf $JUNEST_HOME + [ -d "${JUNEST_HOME}/etc/ca-certificates" ] && chmod -R +w "${JUNEST_HOME}/etc/ca-certificates" + rm -rf "$JUNEST_HOME" unset JUNEST_HOME } @@ -32,15 +34,17 @@ function setUpUnitTests(){ } function assertCommandSuccess(){ + # shellcheck disable=SC2091 $(set -e - "$@" > $STDOUTF 2> $STDERRF + "$@" > "$STDOUTF" 2> "$STDERRF" ) assertTrue "The command $1 did not return 0 exit status" $? } function assertCommandFail(){ + # shellcheck disable=SC2091 $(set -e - "$@" > $STDOUTF 2> $STDERRF + "$@" > "$STDOUTF" 2> "$STDERRF" ) assertFalse "The command $1 returned 0 exit status" $? } @@ -50,8 +54,9 @@ function assertCommandFail(){ function assertCommandFailOnStatus(){ local status=$1 shift + # shellcheck disable=SC2091 $(set -e - "$@" > $STDOUTF 2> $STDERRF + "$@" > "$STDOUTF" 2> "$STDERRF" ) - assertEquals $status $? + assertEquals "$status" $? } From 21b5e3fabb4d5d28e82d1225f7eb415f026bc226 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 1 Mar 2022 00:43:02 +0100 Subject: [PATCH 063/116] 7.3.13 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1cef271..e459e6b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.12 +7.3.13 From 0e6aa260ad59312ced486a5c76185765405deb70 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 23 Apr 2022 16:43:22 +0000 Subject: [PATCH 064/116] Default to ns mode (not fakeroot) for bin wrappers and add sudoj command This is related to #292 --- README.md | 19 ++++++++++++++----- bin/sudoj | 8 ++++++++ lib/checks/check_all.sh | 1 + lib/core/wrappers.sh | 2 +- 4 files changed, 24 insertions(+), 6 deletions(-) create mode 100755 bin/sudoj diff --git a/README.md b/README.md index 458c1ac..da7248e 100644 --- a/README.md +++ b/README.md @@ -110,25 +110,34 @@ used, see the [Usage](#usage) section below. Run JuNest installed programs directly from host OS --------------------------------------- -Installed programs can be accessible directly from host without -entering directly into a JuNest session (no need to call `junest` command). +Program installed within JuNest can be accessible directly from host machine +without entering directly into a JuNest session +(no need to call `junest` command first). For instance, supposing the host OS is an Ubuntu distro you can directly run `pacman` by simply updating the `PATH` variable: ```sh export PATH="$PATH:~/.junest/usr/bin_wrappers" -pacman -S htop +sudoj pacman -S htop htop ``` -By default the wrappers use `"ns --fakeroot"` but you can change it via `JUNEST_ARGS` environment variable. +By default the wrappers use `ns` mode. To use the `ns --fakeroot` you can use the convenient command helper `sudoj`. +For more control on backend mode you can use the `JUNEST_ARGS` environment variable. For instance, if you want to run `iftop` with real root privileges: ``` -pacman -S iftop +sudoj pacman -S iftop sudo JUNEST_ARGS="groot" iftop ``` +Bin wrappers can be always recreated (e.g. in case for some reasons they get +corrupted) with: + +``` +junest create-bin-wrappers -f +``` + Install packages from AUR ------------------------- diff --git a/bin/sudoj b/bin/sudoj new file mode 100755 index 0000000..aa43e15 --- /dev/null +++ b/bin/sudoj @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# +# This file is part of JuNest (https://github.com/fsquillace/junest). +# + +export PATH="${PATH}:${JUNEST_HOME}/usr/bin_wrappers" + +JUNEST_ARGS="ns --fakeroot" "$@" diff --git a/lib/checks/check_all.sh b/lib/checks/check_all.sh index 394309c..2b39f9a 100755 --- a/lib/checks/check_all.sh +++ b/lib/checks/check_all.sh @@ -24,3 +24,4 @@ sudo -E "$JUNEST_SCRIPT" groot -- "$CHECK_SCRIPT" --run-root-tests --skip-aur-te # Test the wrappers work "$JUNEST_SCRIPT" create-bin-wrappers --force "$JUNEST_HOME"/usr/bin_wrappers/pacman --help +"${JUNEST_BASE}/bin/sudoj" pacman -Syu diff --git a/lib/core/wrappers.sh b/lib/core/wrappers.sh index da5517f..13b206a 100644 --- a/lib/core/wrappers.sh +++ b/lib/core/wrappers.sh @@ -36,7 +36,7 @@ function create_wrappers() { cat < "${JUNEST_HOME}/usr/bin_wrappers/${file}" #!/usr/bin/env bash -JUNEST_ARGS=\${JUNEST_ARGS:-ns --fakeroot} +JUNEST_ARGS=\${JUNEST_ARGS:-ns} eval junest "\${JUNEST_ARGS}" -- ${file} "\$(printf "%q" "\$@")" EOF From 73b8bec8db34d1cfb51bf97934ac31a3909f0eaf Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 24 Apr 2022 19:42:10 +0000 Subject: [PATCH 065/116] Fix wrapper when passing multiple arguments and add unit tests This change come from the PR #289 --- lib/core/wrappers.sh | 6 +++--- tests/unit-tests/test-wrappers.sh | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/lib/core/wrappers.sh b/lib/core/wrappers.sh index 13b206a..d6c2f52 100644 --- a/lib/core/wrappers.sh +++ b/lib/core/wrappers.sh @@ -33,12 +33,12 @@ function create_wrappers() { # Arguments inside a variable (i.e. `JUNEST_ARGS`) separated by quotes # are not recognized normally unless using `eval`. More info here: # https://github.com/fsquillace/junest/issues/262 + # https://github.com/fsquillace/junest/pull/287 cat < "${JUNEST_HOME}/usr/bin_wrappers/${file}" #!/usr/bin/env bash -JUNEST_ARGS=\${JUNEST_ARGS:-ns} - -eval junest "\${JUNEST_ARGS}" -- ${file} "\$(printf "%q" "\$@")" +eval "junest_args_array=(\${JUNEST_ARGS:-ns})" +junest "\${junest_args_array[@]}" -- ${file} "\$@" EOF chmod +x "${JUNEST_HOME}/usr/bin_wrappers/${file}" done diff --git a/tests/unit-tests/test-wrappers.sh b/tests/unit-tests/test-wrappers.sh index af7aae2..ebd1eff 100755 --- a/tests/unit-tests/test-wrappers.sh +++ b/tests/unit-tests/test-wrappers.sh @@ -43,6 +43,35 @@ function test_create_wrappers_executable_file(){ assertTrue "myfile wrapper should exist" "[ -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" } +function test_create_wrappers_verify_content(){ + # Test for: + # https://github.com/fsquillace/junest/issues/262 + # https://github.com/fsquillace/junest/issues/292 + touch "$JUNEST_HOME"/usr/bin/myfile + chmod +x "$JUNEST_HOME"/usr/bin/myfile + export JUNEST_ARGS="ns --fakeroot -b '--bind /run /run2'" + assertCommandSuccess create_wrappers + assertEquals "" "$(cat "$STDOUTF")" + + # Mock junest command to capture the actual output generated from myfile script + junest(){ + for arg in "$@" + do + echo "$arg" + done + } + assertEquals "ns +--fakeroot +-b +--bind /run /run2 +-- +myfile +pacman +-Rsn +neovim +new package" "$(source "$JUNEST_HOME"/usr/bin_wrappers/myfile pacman -Rsn neovim 'new package')" +} + function test_create_wrappers_already_exist(){ touch "$JUNEST_HOME"/usr/bin/myfile chmod +x "$JUNEST_HOME"/usr/bin/myfile From df2fec0a363433bd939b7c7f3f7a18e488fc9e17 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 24 Apr 2022 20:14:12 +0000 Subject: [PATCH 066/116] 7.3.14 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index e459e6b..af97984 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.13 +7.3.14 From a9f53042790b832dbb7a8b8d6930cc623dcba882 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Thu, 28 Jul 2022 00:07:15 +0200 Subject: [PATCH 067/116] #297 Create bin wrapper for symlinks --- lib/core/wrappers.sh | 7 +++++-- tests/unit-tests/test-wrappers.sh | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/core/wrappers.sh b/lib/core/wrappers.sh index d6c2f52..7e8b3a8 100644 --- a/lib/core/wrappers.sh +++ b/lib/core/wrappers.sh @@ -25,7 +25,10 @@ function create_wrappers() { cd "${JUNEST_HOME}/usr/bin" || return 1 for file in * do - [[ -x $file ]] || continue + [[ -d $file ]] && continue + # Symlinks outside junest appear as broken even though the are correct + # within a junest session. The following do not skip broken symlinks: + [[ -x $file || -L $file ]] || continue if [[ -e ${JUNEST_HOME}/usr/bin_wrappers/$file ]] && ! $force then continue @@ -47,7 +50,7 @@ EOF cd "${JUNEST_HOME}/usr/bin_wrappers" || return 1 for file in * do - [[ -e ${JUNEST_HOME}/usr/bin/$file ]] || rm -f "$file" + [[ -e ${JUNEST_HOME}/usr/bin/$file || -L ${JUNEST_HOME}/usr/bin/$file ]] || rm -f "$file" done } diff --git a/tests/unit-tests/test-wrappers.sh b/tests/unit-tests/test-wrappers.sh index ebd1eff..8944ee5 100755 --- a/tests/unit-tests/test-wrappers.sh +++ b/tests/unit-tests/test-wrappers.sh @@ -34,6 +34,22 @@ function test_create_wrappers_not_executable_file(){ assertTrue "myfile wrapper should not exist" "[ ! -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" } +function test_create_wrappers_directory(){ + mkdir -p "$JUNEST_HOME"/usr/bin/mydir + assertCommandSuccess create_wrappers + assertEquals "" "$(cat "$STDOUTF")" + assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" + assertTrue "mydir wrapper should not exist" "[ ! -e $JUNEST_HOME/usr/bin_wrappers/mydir ]" +} + +function test_create_wrappers_broken_link(){ + ln -s /opt/myapp/bin/cmd "$JUNEST_HOME"/usr/bin/cmd + assertCommandSuccess create_wrappers + assertEquals "" "$(cat "$STDOUTF")" + assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/bin_wrappers ]" + assertTrue "cmd wrapper should exist" "[ -x $JUNEST_HOME/usr/bin_wrappers/cmd ]" +} + function test_create_wrappers_executable_file(){ touch "$JUNEST_HOME"/usr/bin/myfile chmod +x "$JUNEST_HOME"/usr/bin/myfile From 799d3bdd426a42aaf024948c02f69287cbf71835 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Thu, 28 Jul 2022 00:23:48 +0200 Subject: [PATCH 068/116] Install keyring first during the build preparation --- lib/checks/check.sh | 3 --- lib/core/build.sh | 32 ++++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/lib/checks/check.sh b/lib/checks/check.sh index f984d96..720e9e0 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -52,9 +52,6 @@ PACMAN_OPTIONS="--noconfirm --disable-download-timeout" # shellcheck disable=SC2086 $SUDO pacman $PACMAN_OPTIONS -Syy -# Awk is required for pacman-key -# shellcheck disable=SC2086 -$SUDO pacman $PACMAN_OPTIONS -S gawk $SUDO pacman-key --init if [[ $(uname -m) == *"arm"* ]] diff --git a/lib/core/build.sh b/lib/core/build.sh index 48996f9..8406c97 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -24,7 +24,18 @@ function _install_pkg(){ function _prepare() { # ArchLinux System initialization - sudo pacman --noconfirm -Syu + sudo pacman --noconfirm -Syy + sudo pacman-key --init + if [[ $(uname -m) == *"arm"* ]] + then + sudo pacman -S --noconfirm archlinuxarm-keyring + sudo pacman-key --populate archlinuxarm + else + sudo pacman -S --noconfirm archlinux-keyring + sudo pacman-key --populate archlinux + fi + + sudo pacman --noconfirm -Su sudo pacman -S --noconfirm base-devel sudo pacman -S --noconfirm git arch-install-scripts } @@ -84,21 +95,22 @@ EOT sudo pacman --noconfirm --root "${maindir}"/root -Rsn gzip info "Setting up the pacman keyring (this might take a while!)..." - # gawk command is required for pacman-key - sudo pacman --noconfirm --root "${maindir}"/root -S gawk - # TODO check why the following did not fail! - sudo "${maindir}"/root/bin/groot --no-umount --avoid-bind -b /dev "${maindir}"/root bash -c ' + if [[ $(uname -m) == *"arm"* ]] + then + sudo pacman -S --noconfirm --root "${maindir}"/root archlinuxarm-keyring + else + sudo pacman -S --noconfirm --root "${maindir}"/root archlinux-keyring + fi + sudo mount --bind "${maindir}"/root "${maindir}"/root + sudo arch-chroot "${maindir}"/root bash -c ' set -e pacman-key --init; for keyring_file in /usr/share/pacman/keyrings/*.gpg; do keyring=$(basename $keyring_file | cut -f 1 -d "."); pacman-key --populate $keyring; - done; - [ -e /etc/pacman.d/gnupg/S.gpg-agent ] && gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye' - sudo umount --force --recursive --lazy "${maindir}"/root/dev - sudo umount --force --recursive "${maindir}"/root - sudo pacman --noconfirm --root "${maindir}"/root -Rsn gawk + done;' + sudo umount "${maindir}"/root sudo rm "${maindir}"/root/var/cache/pacman/pkg/* # This is needed on system with busybox tar command. From 77acbf5214ee84841bf7daedcf3dad5d88ce7798 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Fri, 5 Aug 2022 18:02:38 +0200 Subject: [PATCH 069/116] 7.3.15 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index af97984..31938fa 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.14 +7.3.15 From 56761f6e630f0dd81eaf516a8b698bac11156c1a Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 15 Oct 2022 12:20:44 +0200 Subject: [PATCH 070/116] Change url --- .travis.yml | 5 ----- ci/deploy.sh | 12 +++++------- lib/core/common.sh | 4 ++-- lib/core/setup.sh | 2 +- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2ad29e8..b819cbf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,11 +40,6 @@ archlinux: env: matrix: - TRAVIS_BASH_VERSION="4.0" - global: - # AWS_ACCESS_KEY_ID - - secure: "ZotyKKWH5ZrBXDdEnVmV22gbn86BBSiqDZn2d2jVAApgUQdDc3wa7/uYAZP1bts6oQ897nnkUSFHk3M3QAcIoPJerUITTU5D7yjKcFDejgHdpJ4t9XSajmpY9CgKftWapwliWG4wolAKwyAp5GnYqz4GGltHyGxbF/VzUNRF3lw=" - # AWS_SECRET_ACCESS_KEY - - secure: "AWixvJmhr6+rfF4cspMWMjkvLuOsdfNanLK5wrqkgx/0ezDGBBThH0qVhn5Mp1QFM6wVF+LRA6UESNnj0wNwByZHdM6LddkJWlWHb/qkVK+AO4RKUsXJWNyPyOkCNj/WEFpZHQKKUAlEtC8m8AmAcuoi90cr6ih0PXIePRyPFrM=" before_install: - ./ci/install-bash.sh "$TRAVIS_BASH_VERSION" diff --git a/ci/deploy.sh b/ci/deploy.sh index b3ba92c..0d95fa6 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -6,7 +6,8 @@ IMG_PATH=$1 set -ux -MAX_OLD_IMAGES=30 +MAX_OLD_IMAGES=5 +ENDPOINT="https://gateway.storjshare.io" # ARCH can be one of: x86, x86_64, arm HOST_ARCH=$(uname -m) @@ -32,16 +33,13 @@ then # The put is done via a temporary filename in order to prevent outage on the # production file for a longer period of time. img_name=$(basename "${IMG_PATH}") - cp "${IMG_PATH}" "${IMG_PATH}".temp - aws s3 cp "${IMG_PATH}".temp s3://junest-repo/junest/ - aws s3 mv s3://junest-repo/junest/"$img_name".temp s3://junest-repo/junest/"$img_name" + aws s3 --endpoint-url="$ENDPOINT" cp "${IMG_PATH}" s3://junest-repo/junest/ DATE=$(date +'%Y-%m-%d-%H-%M-%S') - - aws s3 cp "s3://junest-repo/junest/$img_name" "s3://junest-repo/junest/${img_name}.${DATE}" + aws s3 --endpoint-url="$ENDPOINT" cp "${IMG_PATH}" "s3://junest-repo/junest/${img_name}.${DATE}" # Cleanup old images - aws s3 ls s3://junest-repo/junest/junest-${ARCH}.tar.gz. | awk '{print $4}' | head -n -${MAX_OLD_IMAGES} | xargs -I {} aws s3 rm "s3://junest-repo/junest/{}" + aws s3 --endpoint-url="$ENDPOINT" ls s3://junest-repo/junest/junest-${ARCH}.tar.gz. | awk '{print $4}' | head -n -${MAX_OLD_IMAGES} | xargs -I {} aws s3 --endpoint-url="$ENDPOINT" rm "s3://junest-repo/junest/{}" # Test the newly deployed image can be downloaded correctly junest setup diff --git a/lib/core/common.sh b/lib/core/common.sh index a75aff9..0362d69 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -53,7 +53,7 @@ else die "Unknown architecture ${HOST_ARCH}" fi -MAIN_REPO=https://dwa8bhj1f036z.cloudfront.net +MAIN_REPO=https://link.storjshare.io/s/jvb5tgarnjtt565fffa44spvyuga/junest-repo ENV_REPO=${MAIN_REPO}/${CMD} # shellcheck disable=SC2016 DEFAULT_MIRROR='https://mirror.rackspace.com/archlinux/$repo/os/$arch' @@ -74,7 +74,7 @@ BWRAP="${JUNEST_HOME}/usr/bin/bwrap" PROOT="${JUNEST_HOME}/usr/bin/proot-${ARCH}" GROOT="${JUNEST_HOME}/usr/bin/groot" CLASSIC_CHROOT=chroot -WGET="wget --no-check-certificate" +WGET="wget --content-disposition --no-check-certificate" CURL="curl -L -J -O -k" TAR="tar" CHOWN="chown" diff --git a/lib/core/setup.sh b/lib/core/setup.sh index 749fd66..7138fc4 100644 --- a/lib/core/setup.sh +++ b/lib/core/setup.sh @@ -95,7 +95,7 @@ function setup_env(){ info "Downloading ${NAME}..." builtin cd "${maindir}" || return 1 local imagefile=${CMD}-${arch}.tar.gz - download_cmd "${ENV_REPO}/${imagefile}" + download_cmd "${ENV_REPO}/${imagefile}?download=1" info "Installing ${NAME}..." _setup_env "${maindir}/${imagefile}" From f0e82bf8bffc5c03e201879e373e80edf78a0db8 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 15 Oct 2022 12:50:44 +0200 Subject: [PATCH 071/116] 7.3.16 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 31938fa..e32eb5c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.15 +7.3.16 From e5f14c373562519923ea571d21b60e686535d24d Mon Sep 17 00:00:00 2001 From: Spencer Skylar Chan <54919210+schance995@users.noreply.github.com> Date: Sun, 30 Oct 2022 04:14:51 +0000 Subject: [PATCH 072/116] Extend $PATH in common.sh with system $PATH. This lets junest work on non-FHS systems such as GNU Guix. --- lib/core/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/common.sh b/lib/core/common.sh index 0362d69..4b2e7ff 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -27,7 +27,7 @@ JUNEST_TEMPDIR=${JUNEST_TEMPDIR:-/tmp} # The update of the variable PATH ensures that the executables are # found on different locations -PATH=/usr/bin:/bin:/usr/local/bin:/usr/sbin:/sbin:${HOME}/.local/bin +PATH=/usr/bin:/bin:/usr/local/bin:/usr/sbin:/sbin:${HOME}/.local/bin:"$PATH" # The executable uname is essential in order to get the architecture # of the host system, so a fallback mechanism cannot be used for it. From 2f6e137e7eaab2052a8421cba0e5640d4f28a523 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 5 Nov 2022 13:02:35 +0100 Subject: [PATCH 073/116] 7.3.17 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index e32eb5c..9a62cf1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.16 +7.3.17 From 91f95ae4b593e70c06db644e5d54f3b1a0bb21f0 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 18 Dec 2022 10:50:22 +0000 Subject: [PATCH 074/116] Change URL to CloudFlare provider --- ci/deploy.sh | 2 +- lib/core/common.sh | 1 + lib/core/setup.sh | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ci/deploy.sh b/ci/deploy.sh index 0d95fa6..78fbd93 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -7,7 +7,7 @@ IMG_PATH=$1 set -ux MAX_OLD_IMAGES=5 -ENDPOINT="https://gateway.storjshare.io" +ENDPOINT="https://8da1bcd84e423c9b013b69fe1e8b4675.r2.cloudflarestorage.com" # ARCH can be one of: x86, x86_64, arm HOST_ARCH=$(uname -m) diff --git a/lib/core/common.sh b/lib/core/common.sh index 4b2e7ff..7062ecd 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -54,6 +54,7 @@ else fi MAIN_REPO=https://link.storjshare.io/s/jvb5tgarnjtt565fffa44spvyuga/junest-repo +MAIN_REPO=https://pub-a2af2344e8554f6c807bc3db355ae622.r2.dev ENV_REPO=${MAIN_REPO}/${CMD} # shellcheck disable=SC2016 DEFAULT_MIRROR='https://mirror.rackspace.com/archlinux/$repo/os/$arch' diff --git a/lib/core/setup.sh b/lib/core/setup.sh index 7138fc4..749fd66 100644 --- a/lib/core/setup.sh +++ b/lib/core/setup.sh @@ -95,7 +95,7 @@ function setup_env(){ info "Downloading ${NAME}..." builtin cd "${maindir}" || return 1 local imagefile=${CMD}-${arch}.tar.gz - download_cmd "${ENV_REPO}/${imagefile}?download=1" + download_cmd "${ENV_REPO}/${imagefile}" info "Installing ${NAME}..." _setup_env "${maindir}/${imagefile}" From 60c7d1c5d0c352c74b3339c867714766a1798294 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 18 Dec 2022 12:37:44 +0000 Subject: [PATCH 075/116] Update keyring --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index b819cbf..e024bbd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,6 +32,11 @@ archlinux: sudo sed -i '/^COMPRESSXZ/s/\xz/xz -T 2/' /etc/makepkg.conf sudo sed -i '$a CFLAGS="$CFLAGS -w"' /etc/makepkg.conf sudo sed -i '$a CXXFLAGS="$CXXFLAGS -w"' /etc/makepkg.conf + sudo pacman -Syy --noconfirm --disable-download-timeout + sudo pacman-key --init + sudo pacman -S --noconfirm --disable-download-timeout archlinux-keyring + sudo pacman-key --populate archlinux + sudo pacman -Su --noconfirm --disable-download-timeout script: # Here do not make any validation (-n) because it will be done later on in the Ubuntu host directly - ./bin/junest build -n From 30967bc15f53e9c3408b0712497628f9aa762010 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 18 Dec 2022 12:49:40 +0000 Subject: [PATCH 076/116] Remove -d option in pacstrap --- ci/deploy.sh | 2 +- lib/core/build.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/deploy.sh b/ci/deploy.sh index 78fbd93..a45d0a1 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -28,7 +28,7 @@ fi if [[ "$TRAVIS_BRANCH" == "master" ]] then - export AWS_DEFAULT_REGION=eu-west-1 + export AWS_DEFAULT_REGION=auto # Upload image # The put is done via a temporary filename in order to prevent outage on the # production file for a longer period of time. diff --git a/lib/core/build.sh b/lib/core/build.sh index 8406c97..45f3631 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -62,7 +62,7 @@ function build_image_env(){ info "Installing pacman and its dependencies..." # All the essential executables (ln, mkdir, chown, etc) are in coreutils # bwrap command belongs to bubblewrap - sudo pacstrap -G -M -d "${maindir}"/root pacman coreutils bubblewrap + sudo pacstrap -G -M "${maindir}"/root pacman coreutils bubblewrap if [[ ${ARCH} != "arm" ]] then From c052e660eeb5d5002100617a210eb22f4da4b547 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 18 Dec 2022 13:43:00 +0000 Subject: [PATCH 077/116] 7.3.18 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 9a62cf1..166696f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.17 +7.3.18 From fab5b0df2eead06cffad041cc6ac2c17a540b916 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 18 Dec 2022 20:40:41 +0000 Subject: [PATCH 078/116] Remove arch-travis and directly use docker --- .travis.yml | 36 ++---------------------------------- ci/build_image.sh | 15 +++++++++++++++ lib/checks/check.sh | 21 ++------------------- lib/core/build.sh | 16 ++-------------- lib/core/common.sh | 24 ++++++++++++++++++++++++ 5 files changed, 45 insertions(+), 67 deletions(-) create mode 100755 ci/build_image.sh diff --git a/.travis.yml b/.travis.yml index e024bbd..153b779 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,39 +9,6 @@ cache: services: - docker -archlinux: - mount: - - ~/.ccache:~/.ccache - - ~/.pkg-cache:/var/cache/pacman/pkg - packages: - # Pacman packages - - ccache - - git - - haveged - - before_install: - # 1.Override `package-cleanup.hook` to preserve cache for travis. - # 2.Enable ccache - # 3.Multithreaded build and compress - # 4.Suppress all gcc warnings - - | - sudo mkdir /etc/pacman.d/hooks/ - sudo ln -s /dev/null /etc/pacman.d/hooks/package-cleanup.hook - sudo sed -i '/^BUILDENV/s/\!ccache/ccache/' /etc/makepkg.conf - sudo sed -i '/#MAKEFLAGS=/c MAKEFLAGS="-j2"' /etc/makepkg.conf - sudo sed -i '/^COMPRESSXZ/s/\xz/xz -T 2/' /etc/makepkg.conf - sudo sed -i '$a CFLAGS="$CFLAGS -w"' /etc/makepkg.conf - sudo sed -i '$a CXXFLAGS="$CXXFLAGS -w"' /etc/makepkg.conf - sudo pacman -Syy --noconfirm --disable-download-timeout - sudo pacman-key --init - sudo pacman -S --noconfirm --disable-download-timeout archlinux-keyring - sudo pacman-key --populate archlinux - sudo pacman -Su --noconfirm --disable-download-timeout - script: - # Here do not make any validation (-n) because it will be done later on in the Ubuntu host directly - - ./bin/junest build -n - - env: matrix: - TRAVIS_BASH_VERSION="4.0" @@ -75,7 +42,8 @@ script: # Build and validation ####################### - echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin - - "curl -s https://raw.githubusercontent.com/fsquillace/arch-travis/master/arch-travis.sh | bash" + - docker run --rm -v "$(pwd):/build" -v ~/.ccache:/home/travis/.ccache -v ~/.pkg-cache:/var/cache/pacman/pkg --privileged archlinux:latest bash /build/ci/build_image.sh + - "echo pacman pkg cache size: $(du -h ~/.pkg-cache|cut -f1) in $(ls ~/.pkg-cache|wc -l) files" - ls -l # Test the newly created JuNest image against Ubuntu host diff --git a/ci/build_image.sh b/ci/build_image.sh new file mode 100755 index 0000000..f9cda95 --- /dev/null +++ b/ci/build_image.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -ex + +pacman -Sy --noconfirm sudo + +# Create a travis user +echo "travis ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/travis +chmod 'u=r,g=r,o=' /etc/sudoers.d/travis +groupadd --gid "2000" "travis" +useradd --create-home --uid "2000" --gid "2000" --shell /usr/bin/false "travis" + +# Here do not make any validation (-n) because it will be done later on in the Ubuntu host directly +cd /build +runuser -u travis -- /build/bin/junest build -n diff --git a/lib/checks/check.sh b/lib/checks/check.sh index 720e9e0..e811f8a 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -47,26 +47,9 @@ info "Initial JuNest setup..." # otherwise it is not possible to exit from the session trap "[[ -e /etc/pacman.d/gnupg/S.gpg-agent ]] && gpg-connect-agent -S /etc/pacman.d/gnupg/S.gpg-agent killagent /bye" QUIT EXIT ABRT TERM INT +prepare_archlinux "$SUDO" + PACMAN_OPTIONS="--noconfirm --disable-download-timeout" - -# shellcheck disable=SC2086 -$SUDO pacman $PACMAN_OPTIONS -Syy - -$SUDO pacman-key --init - -if [[ $(uname -m) == *"arm"* ]] -then - # shellcheck disable=SC2086 - $SUDO pacman $PACMAN_OPTIONS -S archlinuxarm-keyring - $SUDO pacman-key --populate archlinuxarm -else - # shellcheck disable=SC2086 - $SUDO pacman $PACMAN_OPTIONS -S archlinux-keyring - $SUDO pacman-key --populate archlinux -fi - -# shellcheck disable=SC2086 -$SUDO pacman $PACMAN_OPTIONS -Su # shellcheck disable=SC2086 $SUDO pacman $PACMAN_OPTIONS -S grep coreutils # shellcheck disable=SC2086 diff --git a/lib/core/build.sh b/lib/core/build.sh index 45f3631..09939d1 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -24,20 +24,8 @@ function _install_pkg(){ function _prepare() { # ArchLinux System initialization - sudo pacman --noconfirm -Syy - sudo pacman-key --init - if [[ $(uname -m) == *"arm"* ]] - then - sudo pacman -S --noconfirm archlinuxarm-keyring - sudo pacman-key --populate archlinuxarm - else - sudo pacman -S --noconfirm archlinux-keyring - sudo pacman-key --populate archlinux - fi - - sudo pacman --noconfirm -Su - sudo pacman -S --noconfirm base-devel - sudo pacman -S --noconfirm git arch-install-scripts + prepare_archlinux + sudo pacman -S --noconfirm git arch-install-scripts haveged } function build_image_env(){ diff --git a/lib/core/common.sh b/lib/core/common.sh index 7062ecd..d44303f 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -308,3 +308,27 @@ function copy_common_files() { copy_file /etc/resolv.conf return 0 } + +function prepare_archlinux() { + local sudo=${1:-sudo} + local pacman_options="--noconfirm --disable-download-timeout" + + # shellcheck disable=SC2086 + $sudo pacman $pacman_options -Syy + + $sudo pacman-key --init + + if [[ $(uname -m) == *"arm"* ]] + then + # shellcheck disable=SC2086 + $sudo pacman $pacman_options -S archlinuxarm-keyring + $sudo pacman-key --populate archlinuxarm + else + # shellcheck disable=SC2086 + $sudo pacman $pacman_options -S archlinux-keyring + $sudo pacman-key --populate archlinux + fi + + # shellcheck disable=SC2086 + $sudo pacman $pacman_options -Su +} From 1c16425b8854c8d3e56eb6153fbb62b06e99f905 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Mon, 19 Dec 2022 23:15:38 +0000 Subject: [PATCH 079/116] 7.3.19 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 166696f..c082dc6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.18 +7.3.19 From 76c1644c6334db6755d825714202e3364b6e4e4d Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 31 Dec 2022 11:05:36 +0000 Subject: [PATCH 080/116] Add discord server link --- README.md | 2 +- lib/core/setup.sh | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index da7248e..acea67f 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ The lightweight Arch Linux based distro that runs, without root privileges, upon |Project Status|Donation|Communication| |:------------:|:------:|:-----------:| -| [![Build status](https://api.travis-ci.com/fsquillace/junest.png?branch=master)](https://app.travis-ci.com/github/fsquillace/junest) [![OpenHub](https://www.openhub.net/p/junest/widgets/project_thin_badge.gif)](https://www.openhub.net/p/junest) | [![Github Sponsors](https://img.shields.io/badge/GitHub-Sponsors-orange.svg)](https://github.com/sponsors/fsquillace) [![PayPal](https://img.shields.io/badge/PayPal-Donation-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8LEHQKBCYTACY) | [![Join the gitter chat at https://gitter.im/fsquillace/junest](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/fsquillace/junest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![RSS](https://img.shields.io/badge/RSS-News-orange.svg)](http://fsquillace.github.io/junest-site/feed.xml) | +| [![Build status](https://api.travis-ci.com/fsquillace/junest.png?branch=master)](https://app.travis-ci.com/github/fsquillace/junest) [![OpenHub](https://www.openhub.net/p/junest/widgets/project_thin_badge.gif)](https://www.openhub.net/p/junest) | [![Github Sponsors](https://img.shields.io/badge/GitHub-Sponsors-orange.svg)](https://github.com/sponsors/fsquillace) [![PayPal](https://img.shields.io/badge/PayPal-Donation-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8LEHQKBCYTACY) | [![Join the Discord server at https://discord.gg/ttfBT7MKve](https://img.shields.io/badge/Discord-Server-blueviolet.svg)](https://discord.gg/ttfBT7MKve) | **Table of Contents** - [Description](#description) diff --git a/lib/core/setup.sh b/lib/core/setup.sh index 749fd66..58c6122 100644 --- a/lib/core/setup.sh +++ b/lib/core/setup.sh @@ -61,6 +61,9 @@ function _setup_env(){ echo info "Remember to refresh the package databases from the server:" info " pacman -Syy" + echo + info "To install packages from AUR follow the wiki here:" + info "https://github.com/fsquillace/junest#install-packages-from-aur" } From 20f42f6cb7e5e65bbdab791c24c7d9f6eb3c3003 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 31 Dec 2022 11:17:45 +0000 Subject: [PATCH 081/116] 7.3.20 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c082dc6..185f9e4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.19 +7.3.20 From 65c45517e15f4e0f3efa8245e8fec20c53c51b3e Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 15 Jan 2023 22:03:27 +0100 Subject: [PATCH 082/116] Bind /run/user directory --- lib/core/common.sh | 3 ++- lib/core/namespace.sh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/core/common.sh b/lib/core/common.sh index d44303f..df79bec 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -84,6 +84,7 @@ RM="rm" MKDIR="mkdir" GETENT="getent" CP="cp" +ID="id" # Used for checking user namespace in config.gz file ZGREP="zgrep" UNSHARE="unshare" @@ -245,7 +246,7 @@ function check_same_arch() { function provide_common_bindings(){ RESULT="" local re='(.*):.*' - for bind in "/dev" "/sys" "/proc" "/tmp" "$HOME" + for bind in "/dev" "/sys" "/proc" "/tmp" "$HOME" "/run/user/$($ID -u)" do if [[ $bind =~ $re ]] then diff --git a/lib/core/namespace.sh b/lib/core/namespace.sh index 2754dab..9471f31 100644 --- a/lib/core/namespace.sh +++ b/lib/core/namespace.sh @@ -11,7 +11,7 @@ # vim: ft=sh # shellcheck disable=SC2027 -COMMON_BWRAP_OPTION="--bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --bind /sys /sys --bind /proc /proc --dev-bind-try /dev /dev --unshare-user-try" +COMMON_BWRAP_OPTION="--bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp /tmp --bind /sys /sys --bind /proc /proc --dev-bind-try /dev /dev --bind-try "/run/user/$($ID -u)" "/run/user/$($ID -u)" --unshare-user-try" CONFIG_PROC_FILE="/proc/config.gz" CONFIG_BOOT_FILE="/boot/config-$($UNAME -r)" PROC_USERNS_CLONE_FILE="/proc/sys/kernel/unprivileged_userns_clone" From a9174267b39b1737ca17e7d8b91fe17ba7812b42 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 15 Jan 2023 22:28:08 +0100 Subject: [PATCH 083/116] Add unit tests --- README.md | 2 +- tests/unit-tests/test-chroot.sh | 10 +++++----- tests/unit-tests/test-proot.sh | 20 ++++++++++---------- tests/utils/shunit2 | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index acea67f..ed326c0 100644 --- a/README.md +++ b/README.md @@ -251,7 +251,7 @@ In particular, it uses a special program called `GRoot`, a small and portable version of [arch-chroot](https://wiki.archlinux.org/index.php/Chroot) wrapper, that allows to bind mount directories specified by the user, such as -`/proc`, `/sys`, `/dev`, `/tmp` and `$HOME`, before +`/proc`, `/sys`, `/dev`, `/tmp`, `/run/user/` and `$HOME`, before executing any programs inside the JuNest sandbox. In case the mounting will not work, JuNest is even providing the possibility to run the environment directly via the pure `chroot` command. diff --git a/tests/unit-tests/test-chroot.sh b/tests/unit-tests/test-chroot.sh index f634b5b..703004d 100755 --- a/tests/unit-tests/test-chroot.sh +++ b/tests/unit-tests/test-chroot.sh @@ -41,22 +41,22 @@ function init_mocks() { function test_run_env_as_groot_cmd(){ assertCommandSuccess run_env_as_groot "" "" "false" pwd - assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c pwd" "$(cat "$STDOUTF")" + assertEquals "chroot_cmd -b /run/user/$(id -u) -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c pwd" "$(cat "$STDOUTF")" } function test_run_env_as_groot_no_cmd(){ assertCommandSuccess run_env_as_groot "" "" "false" "" - assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login" "$(cat "$STDOUTF")" + assertEquals "chroot_cmd -b /run/user/$(id -u) -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login" "$(cat "$STDOUTF")" } function test_run_env_as_groot_with_backend_command(){ assertCommandSuccess run_env_as_groot "mychroot" "" "false" "" - assertEquals "mychroot -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login" "$(cat "$STDOUTF")" + assertEquals "mychroot -b /run/user/$(id -u) -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login" "$(cat "$STDOUTF")" } function test_run_env_as_groot_no_copy(){ assertCommandSuccess run_env_as_groot "" "" "true" pwd - assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c pwd" "$(cat "$STDOUTF")" + assertEquals "chroot_cmd -b /run/user/$(id -u) -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login -c pwd" "$(cat "$STDOUTF")" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -76,7 +76,7 @@ function test_run_env_as_groot_nested_env(){ function test_run_env_as_groot_cmd_with_backend_args(){ assertCommandSuccess run_env_as_groot "" "-n -b /home/blah" "false" pwd - assertEquals "chroot_cmd -b $HOME -b /tmp -b /proc -b /sys -b /dev -n -b /home/blah $JUNEST_HOME /bin/sh --login -c pwd" "$(cat "$STDOUTF")" + assertEquals "chroot_cmd -b /run/user/$(id -u) -b $HOME -b /tmp -b /proc -b /sys -b /dev -n -b /home/blah $JUNEST_HOME /bin/sh --login -c pwd" "$(cat "$STDOUTF")" } function test_run_env_as_chroot_cmd(){ diff --git a/tests/unit-tests/test-proot.sh b/tests/unit-tests/test-proot.sh index 2217150..dfc7498 100755 --- a/tests/unit-tests/test-proot.sh +++ b/tests/unit-tests/test-proot.sh @@ -55,11 +55,11 @@ function test_run_env_as_proot_user(){ echo $* } assertCommandSuccess run_env_as_proot_user "" "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" - assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" + assertEquals "-b /run/user/$(id -u) -b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" SH=("/usr/bin/echo") assertCommandSuccess run_env_as_proot_user "" "-k 3.10" "false" - assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat "$STDOUTF")" + assertEquals "-b /run/user/$(id -u) -b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat "$STDOUTF")" _test_copy_common_files _test_copy_remaining_files @@ -72,11 +72,11 @@ function test_run_env_as_proot_user_with_backend_command(){ echo $* } assertCommandSuccess run_env_as_proot_user "myproot" "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" - assertEquals "myproot -b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" + assertEquals "myproot -b /run/user/$(id -u) -b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" SH=("/usr/bin/echo") assertCommandSuccess run_env_as_proot_user "myproot" "-k 3.10" "false" - assertEquals "myproot -b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat "$STDOUTF")" + assertEquals "myproot -b /run/user/$(id -u) -b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat "$STDOUTF")" _test_copy_common_files _test_copy_remaining_files @@ -89,7 +89,7 @@ function test_run_env_as_proot_user_no_copy(){ echo $* } assertCommandSuccess run_env_as_proot_user "" "-k 3.10" "true" "/usr/bin/mkdir" "-v" "/newdir2" - assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" + assertEquals "-b /run/user/$(id -u) -b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" [[ ! -e ${JUNEST_HOME}/etc/hosts ]] assertEquals 0 $? @@ -126,11 +126,11 @@ function test_run_env_as_proot_fakeroot(){ echo $* } assertCommandSuccess run_env_as_proot_fakeroot "" "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" - assertEquals "-0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" + assertEquals "-0 -b /run/user/$(id -u) -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" SH=("/usr/bin/echo") assertCommandSuccess run_env_as_proot_fakeroot "" "-k 3.10" "false" - assertEquals "-0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat "$STDOUTF")" + assertEquals "-0 -b /run/user/$(id -u) -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat "$STDOUTF")" _test_copy_common_files } @@ -142,12 +142,12 @@ function test_run_env_as_proot_fakeroot_with_backend_command(){ echo $* } assertCommandSuccess run_env_as_proot_fakeroot "myproot" "-k 3.10" "false" "/usr/bin/mkdir" "-v" "/newdir2" - assertEquals "myproot -0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" + assertEquals "myproot -0 -b /run/user/$(id -u) -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" # shellcheck disable=SC2034 SH=("/usr/bin/echo") assertCommandSuccess run_env_as_proot_fakeroot "myproot" "-k 3.10" "false" - assertEquals "myproot -0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat "$STDOUTF")" + assertEquals "myproot -0 -b /run/user/$(id -u) -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat "$STDOUTF")" _test_copy_common_files } @@ -165,7 +165,7 @@ function test_run_env_with_quotes(){ echo $* } assertCommandSuccess run_env_as_proot_user "" "-k 3.10" "false" "bash" "-c" "/usr/bin/mkdir -v /newdir2" - assertEquals "-b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 bash -c /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" + assertEquals "-b /run/user/$(id -u) -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10 bash -c /usr/bin/mkdir -v /newdir2" "$(cat "$STDOUTF")" } function test_run_env_with_proot_args(){ diff --git a/tests/utils/shunit2 b/tests/utils/shunit2 index d6e7503..e4c719c 100644 --- a/tests/utils/shunit2 +++ b/tests/utils/shunit2 @@ -987,7 +987,7 @@ _shunit_extractTestFunctions() # extract the lines with test function names, strip of anything besides the # function name, and output everything on a single line. _shunit_regex_='^[ ]*(function )*test[A-Za-z0-9_]* *\(\)' - egrep "${_shunit_regex_}" "${_shunit_script_}" \ + grep -E "${_shunit_regex_}" "${_shunit_script_}" \ |sed 's/^[^A-Za-z0-9_]*//;s/^function //;s/\([A-Za-z0-9_]*\).*/\1/g' \ |xargs From 24925838778593e44f4aa27daa194f6c2fa532fa Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 15 Jan 2023 22:28:41 +0100 Subject: [PATCH 084/116] 7.4.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 185f9e4..ba7f754 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.3.20 +7.4.0 From 0b34458fb516bf3e53571708a30a85fc54049b3a Mon Sep 17 00:00:00 2001 From: Cosmo Date: Mon, 30 Jan 2023 23:51:50 -0500 Subject: [PATCH 085/116] Fix deprecated find -perm syntax --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ed326c0..d53a353 100644 --- a/README.md +++ b/README.md @@ -512,7 +512,7 @@ For Arch Linux related FAQs take a look at the [General troubleshooting page](ht > have *suid* permission, you can list the commands from your JuNest environment > with the following command: - $> find /usr/bin -perm +4000 + $> find /usr/bin -perm /4000 ## No characters are visible on a graphic application ## From 632b416955b93eff2ba6275e582ec689b2b1d93d Mon Sep 17 00:00:00 2001 From: Cosmo Date: Tue, 31 Jan 2023 00:30:41 -0500 Subject: [PATCH 086/116] Fix grammar and improve style --- README.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index ed326c0..9b75181 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ JuNest ====== -The lightweight Arch Linux based distro that runs, without root privileges, upon any Linux distro. +The lightweight Arch Linux based distro that runs, without root privileges, on top of any other Linux distro.

Date: Tue, 31 Jan 2023 22:09:43 +0100 Subject: [PATCH 087/116] 7.4.1 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index ba7f754..815da58 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.4.0 +7.4.1 From 95f97a62b74d1dc42e7747c7fb6453f8f59a3ccf Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Fri, 17 Feb 2023 18:26:13 +0100 Subject: [PATCH 088/116] #305: Add fakeroot variable to bypass chown commands --- lib/core/build.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/core/build.sh b/lib/core/build.sh index 09939d1..0f3d8b0 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -70,6 +70,8 @@ EOT echo "Generating the metadata info" sudo install -d -m 755 "${maindir}/root/etc/${CMD}" sudo bash -c "echo 'JUNEST_ARCH=$ARCH' > ${maindir}/root/etc/${CMD}/info" + # Related to: https://github.com/fsquillace/junest/issues/305 + sudo bash -c "echo 'export FAKEROOTDONTTRYCHOWN=true' > ${maindir}/root/etc/profile.d/junest.sh" info "Generating the locales..." # sed command is required for locale-gen but it is required by fakeroot From b976f767d5960df9ab39127a2482a5a9d96eb123 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Fri, 17 Feb 2023 18:40:19 +0100 Subject: [PATCH 089/116] Add checks for fakeroot chown --- lib/checks/check.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/checks/check.sh b/lib/checks/check.sh index e811f8a..789206e 100755 --- a/lib/checks/check.sh +++ b/lib/checks/check.sh @@ -54,12 +54,22 @@ PACMAN_OPTIONS="--noconfirm --disable-download-timeout" $SUDO pacman $PACMAN_OPTIONS -S grep coreutils # shellcheck disable=SC2086 # shellcheck disable=SC2046 -$SUDO pacman $PACMAN_OPTIONS -S $(pacman -Sg base-devel | cut -d ' ' -f 2 | grep -v sudo) +$SUDO pacman $PACMAN_OPTIONS -Syu --ignore sudo base-devel info "Checking basic executables work..." $SUDO pacman -Qi pacman 1> /dev/null /usr/bin/groot --help 1> /dev/null +# Test FAKEROOTDONTTRYCHOWN is set to true by default +set +u +if [[ -z $FAKEROOTKEY ]] +then + fakeroot chown root /tmp +else + chown root /tmp +fi +set -u + repo_package1=tree echo "Checking ${repo_package1} package from official repo..." # shellcheck disable=SC2086 From 369cda8dc648b431234c8d6030ab2cac5246ea1d Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 18 Feb 2023 00:03:19 +0100 Subject: [PATCH 090/116] 7.4.2 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 815da58..f8cb1fa 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.4.1 +7.4.2 From 4db85bcf1f247f316ed5f849d37908db5fcfd314 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 18 Feb 2023 00:49:54 +0100 Subject: [PATCH 091/116] #318: Use multi-call wrapper --- lib/core/wrappers.sh | 24 +++++++++++++----------- tests/unit-tests/test-wrappers.sh | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/core/wrappers.sh b/lib/core/wrappers.sh index 7e8b3a8..1afbb2b 100644 --- a/lib/core/wrappers.sh +++ b/lib/core/wrappers.sh @@ -21,6 +21,17 @@ function create_wrappers() { local force=${1:-false} mkdir -p "${JUNEST_HOME}/usr/bin_wrappers" + # Arguments inside a variable (i.e. `JUNEST_ARGS`) separated by quotes + # are not recognized normally unless using `eval`. More info here: + # https://github.com/fsquillace/junest/issues/262 + # https://github.com/fsquillace/junest/pull/287 + cat < "${JUNEST_HOME}/usr/bin/junest_wrapper" +#!/usr/bin/env bash + +eval "junest_args_array=(\${JUNEST_ARGS:-ns})" +junest "\${junest_args_array[@]}" -- \$(basename \${0}) "\$@" +EOF + chmod +x "${JUNEST_HOME}/usr/bin/junest_wrapper" cd "${JUNEST_HOME}/usr/bin" || return 1 for file in * @@ -33,17 +44,8 @@ function create_wrappers() { then continue fi - # Arguments inside a variable (i.e. `JUNEST_ARGS`) separated by quotes - # are not recognized normally unless using `eval`. More info here: - # https://github.com/fsquillace/junest/issues/262 - # https://github.com/fsquillace/junest/pull/287 - cat < "${JUNEST_HOME}/usr/bin_wrappers/${file}" -#!/usr/bin/env bash - -eval "junest_args_array=(\${JUNEST_ARGS:-ns})" -junest "\${junest_args_array[@]}" -- ${file} "\$@" -EOF - chmod +x "${JUNEST_HOME}/usr/bin_wrappers/${file}" + rm -f "${JUNEST_HOME}/usr/bin_wrappers/$file" + ln -s "../bin/junest_wrapper" "${JUNEST_HOME}/usr/bin_wrappers/$file" done # Remove wrappers no longer needed diff --git a/tests/unit-tests/test-wrappers.sh b/tests/unit-tests/test-wrappers.sh index 8944ee5..c5a5857 100755 --- a/tests/unit-tests/test-wrappers.sh +++ b/tests/unit-tests/test-wrappers.sh @@ -81,7 +81,7 @@ function test_create_wrappers_verify_content(){ -b --bind /run /run2 -- -myfile +test-wrappers.sh pacman -Rsn neovim From ba0ddcc524b3a94e34dd8b2b747c882a8c16dd4e Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 18 Feb 2023 23:47:20 +0100 Subject: [PATCH 092/116] 7.4.3 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index f8cb1fa..0f4a1d6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.4.2 +7.4.3 From 9b00c5c4c51c513b09ae32b97a0fbd8ca8590d45 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 30 Apr 2023 13:20:54 +0200 Subject: [PATCH 093/116] Reduce PATH when accessing to Junest session --- lib/core/chroot.sh | 3 ++- lib/core/namespace.sh | 6 ++++-- lib/core/proot.sh | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/core/chroot.sh b/lib/core/chroot.sh index c2237a9..c7f8abc 100644 --- a/lib/core/chroot.sh +++ b/lib/core/chroot.sh @@ -33,8 +33,9 @@ function _run_env_as_xroot(){ copy_common_files fi + # Resets PATH to avoid polluting with host related bin paths # shellcheck disable=SC2086 - JUNEST_ENV=1 $cmd $backend_args "$JUNEST_HOME" "${DEFAULT_SH[@]}" "${args[@]}" + PATH='' JUNEST_ENV=1 $cmd $backend_args "$JUNEST_HOME" "${DEFAULT_SH[@]}" "${args[@]}" } ####################################### diff --git a/lib/core/namespace.sh b/lib/core/namespace.sh index 9471f31..bbda112 100644 --- a/lib/core/namespace.sh +++ b/lib/core/namespace.sh @@ -101,8 +101,9 @@ function run_env_as_bwrap_fakeroot(){ local args=() [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") + # Fix PATH to /usr/bin to make sudo working and avoid polluting with host related bin paths # shellcheck disable=SC2086 - BWRAP="${backend_command}" JUNEST_ENV=1 bwrap_cmd $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 $backend_args sudo "${DEFAULT_SH[@]}" "${args[@]}" + PATH="/usr/bin" BWRAP="${backend_command}" JUNEST_ENV=1 bwrap_cmd $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 $backend_args sudo "${DEFAULT_SH[@]}" "${args[@]}" } @@ -150,8 +151,9 @@ function run_env_as_bwrap_user() { local args=() [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") + # Resets PATH to avoid polluting with host related bin paths # shellcheck disable=SC2086 - BWRAP="${backend_command}" JUNEST_ENV=1 bwrap_cmd $COMMON_BWRAP_OPTION $backend_args "${DEFAULT_SH[@]}" "${args[@]}" + PATH='' BWRAP="${backend_command}" JUNEST_ENV=1 bwrap_cmd $COMMON_BWRAP_OPTION $backend_args "${DEFAULT_SH[@]}" "${args[@]}" } diff --git a/lib/core/proot.sh b/lib/core/proot.sh index 259c8b7..b6c1c8f 100644 --- a/lib/core/proot.sh +++ b/lib/core/proot.sh @@ -17,7 +17,8 @@ function _run_env_with_proot(){ local args=() [[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")") - PROOT="${backend_command}" JUNEST_ENV=1 proot_cmd "${backend_args}" "${DEFAULT_SH[@]}" "${args[@]}" + # Resets PATH to avoid polluting with host related bin paths + PATH='' PROOT="${backend_command}" JUNEST_ENV=1 proot_cmd "${backend_args}" "${DEFAULT_SH[@]}" "${args[@]}" } function _run_env_with_qemu(){ From 296c9e47b4b98a8bdac048b5611b43f5ee4009c4 Mon Sep 17 00:00:00 2001 From: Escape0707 Date: Sat, 6 May 2023 00:55:50 +0900 Subject: [PATCH 094/116] Update README.md to accommodate that sudo-fake provides sudo Since junest/sudo-fake now provides sudo, users don't need to ignore core/sudo during the installation of base-devel. They only need to make sure not to install core/sudo manually. --- README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 321feae..a6485d2 100644 --- a/README.md +++ b/README.md @@ -149,14 +149,11 @@ command. In `proot` mode, JuNest does no longer support the building of AUR pack first: ```sh -pacman -Syu --ignore sudo base-devel -:: sudo is in IgnorePkg/IgnoreGroup. Install anyway? [Y/n] n -... -... +pacman -S base-devel ``` -JuNest uses a modified version of `sudo`. That's why the original `sudo` -package **must be ignored** in the previous command. +JuNest uses a modified version of `sudo` provided by `junest/sudo-fake`. And the original `core/sudo` +package will be ignored **(and must not be installed)** during the installation of `base-devel`. Have fun! --------- @@ -387,9 +384,9 @@ For Arch Linux related FAQs take a look at the [General troubleshooting page](ht > In order to install AUR packages you need to install the package group `base-devel` first > that contains all the essential packages for compiling from source code (such as gcc, make, patch, etc): - #> pacman -S --ignore sudo base-devel + #> pacman -S base-devel -> Remember to ignore `sudo` as it conflicts with `sudo-fake` package. +> Remember to not install `core/sudo` as it conflicts with `junest/sudo-fake` package. ## Can't set user and group as root From 874f52f0f8b61f47c7a7e10cbbeebb382f4f9b3b Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 6 May 2023 00:46:09 +0200 Subject: [PATCH 095/116] Remove PATH setting for chroot mode --- lib/core/chroot.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/core/chroot.sh b/lib/core/chroot.sh index c7f8abc..c2237a9 100644 --- a/lib/core/chroot.sh +++ b/lib/core/chroot.sh @@ -33,9 +33,8 @@ function _run_env_as_xroot(){ copy_common_files fi - # Resets PATH to avoid polluting with host related bin paths # shellcheck disable=SC2086 - PATH='' JUNEST_ENV=1 $cmd $backend_args "$JUNEST_HOME" "${DEFAULT_SH[@]}" "${args[@]}" + JUNEST_ENV=1 $cmd $backend_args "$JUNEST_HOME" "${DEFAULT_SH[@]}" "${args[@]}" } ####################################### From ae365215fbaf2650429203d5a5ffa063369cfb5d Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 6 May 2023 01:38:52 +0200 Subject: [PATCH 096/116] 7.4.4 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0f4a1d6..4e61aee 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.4.3 +7.4.4 From 39508ca8a9ddabfa2ebe1311831ec641a30bb121 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 7 May 2023 13:59:00 +0200 Subject: [PATCH 097/116] First commit --- bin/junest | 9 +++++++-- lib/core/wrappers.sh | 18 ++++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/bin/junest b/bin/junest index d3435fe..7288e59 100755 --- a/bin/junest +++ b/bin/junest @@ -69,8 +69,11 @@ usage() { echo -e " b[uild] Build a $NAME image (must run in ArchLinux)" echo -e " -n, --disable-check Disable the $NAME image check" echo - echo -e " create-bin-wrappers Create bin wrappers in $JUNEST_HOME/usr/bin_wrappers" + echo -e " create-bin-wrappers Create a bin wrappers directory according to --bin-path option" + echo -e " Default path is $JUNEST_HOME/usr/bin_wrappers" echo -e " -f, --force Create the wrapper files even if they already exist" + echo -e " -p, --bin-path The source directory where executable are located in JuNest" + echo -e " Default value is: /usr/bin" echo } @@ -215,10 +218,12 @@ function _parse_build_opts() { function _parse_create_wrappers_opts() { OPT_FORCE=false + OPT_BIN_PATH="" while [[ -n "$1" ]] do case "$1" in -f|--force) OPT_FORCE=true ; shift ;; + -p|--bin-path) shift ; OPT_BIN_PATH="$1" ; shift ;; *) die "Invalid option $1" ;; esac done @@ -276,7 +281,7 @@ function execute_operation() { fi if $ACT_CREATE_WRAPPERS; then - create_wrappers $OPT_FORCE + create_wrappers $OPT_FORCE "$OPT_BIN_PATH" exit fi diff --git a/lib/core/wrappers.sh b/lib/core/wrappers.sh index 1afbb2b..1fe955c 100644 --- a/lib/core/wrappers.sh +++ b/lib/core/wrappers.sh @@ -20,7 +20,9 @@ ####################################### function create_wrappers() { local force=${1:-false} - mkdir -p "${JUNEST_HOME}/usr/bin_wrappers" + local bin_path=${2:-/usr/bin} + bin_path=${bin_path%/} + mkdir -p "${JUNEST_HOME}${bin_path}_wrappers" # Arguments inside a variable (i.e. `JUNEST_ARGS`) separated by quotes # are not recognized normally unless using `eval`. More info here: # https://github.com/fsquillace/junest/issues/262 @@ -33,26 +35,26 @@ junest "\${junest_args_array[@]}" -- \$(basename \${0}) "\$@" EOF chmod +x "${JUNEST_HOME}/usr/bin/junest_wrapper" - cd "${JUNEST_HOME}/usr/bin" || return 1 + cd "${JUNEST_HOME}${bin_path}" || return 1 for file in * do [[ -d $file ]] && continue - # Symlinks outside junest appear as broken even though the are correct + # Symlinks outside junest appear as broken even though they are correct # within a junest session. The following do not skip broken symlinks: [[ -x $file || -L $file ]] || continue - if [[ -e ${JUNEST_HOME}/usr/bin_wrappers/$file ]] && ! $force + if [[ -e ${JUNEST_HOME}${bin_path}_wrappers/$file ]] && ! $force then continue fi - rm -f "${JUNEST_HOME}/usr/bin_wrappers/$file" - ln -s "../bin/junest_wrapper" "${JUNEST_HOME}/usr/bin_wrappers/$file" + rm -f "${JUNEST_HOME}${bin_path}_wrappers/$file" + ln -s "${JUNEST_HOME}/usr/bin/junest_wrapper" "${JUNEST_HOME}${bin_path}_wrappers/$file" done # Remove wrappers no longer needed - cd "${JUNEST_HOME}/usr/bin_wrappers" || return 1 + cd "${JUNEST_HOME}${bin_path}_wrappers" || return 1 for file in * do - [[ -e ${JUNEST_HOME}/usr/bin/$file || -L ${JUNEST_HOME}/usr/bin/$file ]] || rm -f "$file" + [[ -e ${JUNEST_HOME}${bin_path}/$file || -L ${JUNEST_HOME}${bin_path}/$file ]] || rm -f "$file" done } From c2dae9021d7bd4936d622a2984a8310984d2263d Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 7 May 2023 14:15:55 +0200 Subject: [PATCH 098/116] Add integ test --- lib/checks/check_all.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/checks/check_all.sh b/lib/checks/check_all.sh index 2b39f9a..13e9237 100755 --- a/lib/checks/check_all.sh +++ b/lib/checks/check_all.sh @@ -24,4 +24,8 @@ sudo -E "$JUNEST_SCRIPT" groot -- "$CHECK_SCRIPT" --run-root-tests --skip-aur-te # Test the wrappers work "$JUNEST_SCRIPT" create-bin-wrappers --force "$JUNEST_HOME"/usr/bin_wrappers/pacman --help + +"$JUNEST_SCRIPT" create-bin-wrappers --force --bin-path /usr/bin/core_perl/ +"$JUNEST_HOME"/usr/bin/core_perl_wrappers/shasum --help + "${JUNEST_BASE}/bin/sudoj" pacman -Syu From 3742c16ce06bc8fbf6758a6f4ee796c3b2988084 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 7 May 2023 16:13:10 +0200 Subject: [PATCH 099/116] Add documentation and unit test --- README.md | 24 ++++++++++++++++++++---- tests/unit-tests/test-wrappers.sh | 11 +++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a6485d2..72ae100 100644 --- a/README.md +++ b/README.md @@ -110,9 +110,9 @@ used, see the [Usage](#usage) section below. Run JuNest installed programs directly from host OS --------------------------------------- -Program installed within JuNest can be accessible directly from host machine -without entering directly into a JuNest session -(no need to call `junest` command first). +Programs installed within JuNest can be accessible directly from host machine +without entering into a JuNest session +(namely, no need to call `junest` command first). For instance, supposing the host OS is an Ubuntu distro you can directly run `pacman` by simply updating the `PATH` variable: @@ -123,7 +123,7 @@ htop ``` By default the wrappers use `ns` mode. To use the `ns --fakeroot` you can use the convenient command helper `sudoj`. -For more control on backend mode you can use the `JUNEST_ARGS` environment variable. +For more control on backend modes you can use the `JUNEST_ARGS` environment variable too. For instance, if you want to run `iftop` with real root privileges: ``` @@ -138,6 +138,22 @@ corrupted) with: junest create-bin-wrappers -f ``` +Bin wrappers are automatically generated each time they get installed inside JuNest. +This only works for executables located in `/usr/bin` path. +For executables in other locations (say `/usr/mybinpath`) you can only create +wrappers manually by executing the command: + +``` +junest create-bin-wrappers --bin-path /usr/mybinpath +``` + +Obviously, to get access to the corresponding bin wrappers you will need to +update your `PATH` variable accordingly: + +``` +export PATH="$PATH:~/.junest/usr/mybinpath_wrappers" +``` + Install packages from AUR ------------------------- diff --git a/tests/unit-tests/test-wrappers.sh b/tests/unit-tests/test-wrappers.sh index c5a5857..eef1f38 100755 --- a/tests/unit-tests/test-wrappers.sh +++ b/tests/unit-tests/test-wrappers.sh @@ -124,4 +124,15 @@ function test_create_wrappers_executable_no_longer_exist(){ assertTrue "myfile wrapper should not exist" "[ ! -x $JUNEST_HOME/usr/bin_wrappers/myfile ]" } +function test_create_wrappers_custom_bin_path(){ + mkdir -p "$JUNEST_HOME"/usr/mybindir + touch "$JUNEST_HOME"/usr/mybindir/myfile + chmod +x "$JUNEST_HOME"/usr/mybindir/myfile + assertCommandSuccess create_wrappers false /usr/mybindir/ + assertEquals "" "$(cat "$STDOUTF")" + assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/mybindir_wrappers ]" + assertTrue "myfile wrapper should exist" "[ -x $JUNEST_HOME/usr/mybindir_wrappers/myfile ]" +} + + source "$(dirname "$0")"/../utils/shunit2 From 507502dc1a5bbcdfa836a6d984cd4524958879cd Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 7 May 2023 16:27:17 +0200 Subject: [PATCH 100/116] 7.4.5 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 4e61aee..e91f104 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.4.4 +7.4.5 From daa60b05e3cd4ebf75970ca19bb1a012339dfc8d Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Mon, 29 May 2023 11:47:18 +0200 Subject: [PATCH 101/116] Fix PATH when running trap --- VERSION | 2 +- bin/junest | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index e91f104..bd8293a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.4.5 +7.4.6 diff --git a/bin/junest b/bin/junest index 7288e59..356482d 100755 --- a/bin/junest +++ b/bin/junest @@ -305,7 +305,7 @@ function execute_operation() { fi # Call create_wrappers in case new bin files have been created - trap "create_wrappers" EXIT QUIT TERM + trap "PATH=$PATH create_wrappers" EXIT QUIT TERM $run_env "$BACKEND_COMMAND" "${BACKEND_ARGS}" $OPT_NO_COPY_FILES "${ARGS[@]}" } From 9a06d47f76bbe18cd0817ba6ddb5a780713a6d73 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Mon, 29 May 2023 12:00:15 +0200 Subject: [PATCH 102/116] Add shellcheck disable --- bin/junest | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/junest b/bin/junest index 356482d..f0d6abe 100755 --- a/bin/junest +++ b/bin/junest @@ -305,6 +305,7 @@ function execute_operation() { fi # Call create_wrappers in case new bin files have been created + # shellcheck disable=SC2064 trap "PATH=$PATH create_wrappers" EXIT QUIT TERM $run_env "$BACKEND_COMMAND" "${BACKEND_ARGS}" $OPT_NO_COPY_FILES "${ARGS[@]}" } From b3565e093d848eeb6c4f72ca97df25d200f0e0ad Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Wed, 31 May 2023 14:57:57 +0200 Subject: [PATCH 103/116] #328 Check if `user` file exist in `ns` directory --- lib/core/namespace.sh | 30 +++++++++++++++------------ tests/unit-tests/test-namespace.sh | 33 +++++++++++++----------------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/lib/core/namespace.sh b/lib/core/namespace.sh index bbda112..70763bd 100644 --- a/lib/core/namespace.sh +++ b/lib/core/namespace.sh @@ -15,8 +15,24 @@ COMMON_BWRAP_OPTION="--bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp CONFIG_PROC_FILE="/proc/config.gz" CONFIG_BOOT_FILE="/boot/config-$($UNAME -r)" PROC_USERNS_CLONE_FILE="/proc/sys/kernel/unprivileged_userns_clone" +PROC_USERNS_FILE="/proc/$$/ns/user" function _is_user_namespace_enabled() { + if [[ -L $PROC_USERNS_FILE ]] + then + return 0 + fi + + if [[ -e $PROC_USERNS_CLONE_FILE ]] + then + # `-q` option in zgrep may cause a gzip: stdout: Broken pipe + # Use redirect to /dev/null instead + if zgrep_cmd "1" "$PROC_USERNS_CLONE_FILE" > /dev/null + then + return 0 + fi + fi + local config_file="" if [[ -e $CONFIG_PROC_FILE ]] then @@ -35,19 +51,7 @@ function _is_user_namespace_enabled() { return "$NO_CONFIG_FOUND" fi - if [[ ! -e $PROC_USERNS_CLONE_FILE ]] - then - return 0 - fi - - # `-q` option in zgrep may cause a gzip: stdout: Broken pipe - # Use redirect to /dev/null instead - if ! zgrep_cmd "1" $PROC_USERNS_CLONE_FILE > /dev/null - then - return "$UNPRIVILEGED_USERNS_DISABLED" - fi - - return 0 + return "$UNPRIVILEGED_USERNS_DISABLED" } function _check_user_namespace() { diff --git a/tests/unit-tests/test-namespace.sh b/tests/unit-tests/test-namespace.sh index 373c1be..781ca92 100755 --- a/tests/unit-tests/test-namespace.sh +++ b/tests/unit-tests/test-namespace.sh @@ -58,50 +58,45 @@ function _test_copy_remaining_files() { } function test_is_user_namespace_enabled_no_config_file(){ + PROC_USERNS_FILE="blah" + PROC_USERNS_CLONE_FILE="blah" CONFIG_PROC_FILE="blah" CONFIG_BOOT_FILE="blah" assertCommandFailOnStatus "$NOT_EXISTING_FILE" _is_user_namespace_enabled } function test_is_user_namespace_enabled_no_config(){ + PROC_USERNS_FILE="blah" + PROC_USERNS_CLONE_FILE="blah" touch config gzip config + # shellcheck disable=SC2034 CONFIG_PROC_FILE="config.gz" + # shellcheck disable=SC2034 CONFIG_BOOT_FILE="blah" assertCommandFailOnStatus "$NO_CONFIG_FOUND" _is_user_namespace_enabled } -function test_is_user_namespace_enabled_with_config(){ - echo "CONFIG_USER_NS=y" > config - gzip config - CONFIG_PROC_FILE="config.gz" - CONFIG_BOOT_FILE="blah" - PROC_USERNS_CLONE_FILE="not-existing-file" - assertCommandSuccess _is_user_namespace_enabled -} - function test_is_user_namespace_enabled_with_userns_clone_file_disabled(){ - echo "CONFIG_USER_NS=y" > config - gzip config - CONFIG_PROC_FILE="config.gz" - CONFIG_BOOT_FILE="blah" + PROC_USERNS_FILE="blah" PROC_USERNS_CLONE_FILE="unprivileged_userns_clone" echo "0" > $PROC_USERNS_CLONE_FILE assertCommandFailOnStatus "$UNPRIVILEGED_USERNS_DISABLED" _is_user_namespace_enabled } function test_is_user_namespace_enabled_with_userns_clone_file_enabled(){ - echo "CONFIG_USER_NS=y" > config - gzip config - # shellcheck disable=SC2034 - CONFIG_PROC_FILE="config.gz" - # shellcheck disable=SC2034 - CONFIG_BOOT_FILE="blah" PROC_USERNS_CLONE_FILE="unprivileged_userns_clone" echo "1" > $PROC_USERNS_CLONE_FILE assertCommandSuccess _is_user_namespace_enabled } +function test_is_user_namespace_enabled_with_proc_userns_file_existing(){ + PROC_USERNS_FILE="user" + ln -s . $PROC_USERNS_FILE + PROC_USERNS_CLONE_FILE="blah" + assertCommandSuccess _is_user_namespace_enabled +} + function test_run_env_as_bwrap_fakeroot() { assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false" assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat "$STDOUTF")" From 2dd84efecbb6bda68b12cd567c41d01d3176f9d2 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Wed, 31 May 2023 15:07:39 +0200 Subject: [PATCH 104/116] 7.4.7 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index bd8293a..25627bc 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.4.6 +7.4.7 From d19d2f07b68e596706c7c576ca941e63809483c0 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 22 Jul 2023 16:26:21 +0200 Subject: [PATCH 105/116] Add buymeacoffee badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 72ae100..e51e5be 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ The lightweight Arch Linux based distro that runs, without root privileges, on t |Project Status|Donation|Communication| |:------------:|:------:|:-----------:| -| [![Build status](https://api.travis-ci.com/fsquillace/junest.png?branch=master)](https://app.travis-ci.com/github/fsquillace/junest) [![OpenHub](https://www.openhub.net/p/junest/widgets/project_thin_badge.gif)](https://www.openhub.net/p/junest) | [![Github Sponsors](https://img.shields.io/badge/GitHub-Sponsors-orange.svg)](https://github.com/sponsors/fsquillace) [![PayPal](https://img.shields.io/badge/PayPal-Donation-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8LEHQKBCYTACY) | [![Join the Discord server at https://discord.gg/ttfBT7MKve](https://img.shields.io/badge/Discord-Server-blueviolet.svg)](https://discord.gg/ttfBT7MKve) | +| [![Build status](https://api.travis-ci.com/fsquillace/junest.png?branch=master)](https://app.travis-ci.com/github/fsquillace/junest) [![OpenHub](https://www.openhub.net/p/junest/widgets/project_thin_badge.gif)](https://www.openhub.net/p/junest) | [![Github Sponsors](https://img.shields.io/badge/GitHub-Sponsors-orange.svg)](https://github.com/sponsors/fsquillace) [![PayPal](https://img.shields.io/badge/PayPal-Donation-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8LEHQKBCYTACY) [![Buy me a coffee](https://www.buymeacoffee.com/assets/img/custom_images/yellow_img.png)](https://www.buymeacoffee.com/fsquillace) | [![Join the Discord server at https://discord.gg/ttfBT7MKve](https://img.shields.io/badge/Discord-Server-blueviolet.svg)](https://discord.gg/ttfBT7MKve) | **Table of Contents** - [Description](#description) From 6ae9f72dd5bd423bf5e6db8e62cf0e343a8a2bee Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 22 Jul 2023 16:34:44 +0200 Subject: [PATCH 106/116] Add Readme update --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e51e5be..7be58b1 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,9 @@ Setup environment ----------------- The first operation required is to install the JuNest environment in the -location of your choice (by default `~/.junest`, configurable via the environment variable `JUNEST_HOME`): +location of your choice via `JUNEST_HOME` environment variable +(it must contain an absolute path) which by +default is `~/.junest`: ```sh junest setup From e680325f5a815f58c8ef7e57a319c6cd64a497a2 Mon Sep 17 00:00:00 2001 From: Cosmo Date: Mon, 13 Nov 2023 15:29:05 -0500 Subject: [PATCH 107/116] Explain installation before quickstart/setup This should clear up some of the confusion that new users experience when discovering JuNest for the first time --- README.md | 62 +++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 72ae100..49f3786 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,37 @@ This allows interaction between processes belonging to both host OS and JuNest. For example, you can install the `top` command in JuNest and use it to monitor processes belonging to the host OS. +Installation +============ + +## Dependencies ## +JuNest comes with a very short list of dependencies in order to be installed in most +of GNU/Linux distributions. +Before installing JuNest be sure that all dependencies are properly installed in your system: + +- [bash (>=4.0)](https://www.gnu.org/software/bash/) +- [GNU coreutils](https://www.gnu.org/software/coreutils/) + +## Installation from git repository ## +Just clone the JuNest repo somewhere (for example in ~/.local/share/junest): + +```sh +git clone https://github.com/fsquillace/junest.git ~/.local/share/junest +export PATH=~/.local/share/junest/bin:$PATH +``` + +Optionally you want to use the wrappers to run commands +installed in JuNest directly from host: + +```sh +export PATH="$PATH:~/.junest/usr/bin_wrappers" +``` +Update your `~/.bashrc` or `~/.zshrc` to get always the wrappers available. + +### Installation using AUR (Arch Linux only) ### +If you are using an Arch Linux system you can, alternatively, install JuNest from the [AUR repository](https://aur.archlinux.org/packages/junest-git/). +JuNest will be located in `/opt/junest/` + Quickstart ========== @@ -177,37 +208,6 @@ Have fun! If you are new on Arch Linux and you are not familiar with `pacman` package manager visit the [pacman rosetta page](https://wiki.archlinux.org/index.php/Pacman_Rosetta). -Installation -============ - -## Dependencies ## -JuNest comes with a very short list of dependencies in order to be installed in most -of GNU/Linux distributions. -Before installing JuNest be sure that all dependencies are properly installed in your system: - -- [bash (>=4.0)](https://www.gnu.org/software/bash/) -- [GNU coreutils](https://www.gnu.org/software/coreutils/) - -## Installation from git repository ## -Just clone the JuNest repo somewhere (for example in ~/.local/share/junest): - -```sh -git clone https://github.com/fsquillace/junest.git ~/.local/share/junest -export PATH=~/.local/share/junest/bin:$PATH -``` - -Optionally you want to use the wrappers to run commands -installed in JuNest directly from host: - -```sh -export PATH="$PATH:~/.junest/usr/bin_wrappers" -``` -Update your `~/.bashrc` or `~/.zshrc` to get always the wrappers available. - -### Installation using AUR (Arch Linux only) ### -If you are using an Arch Linux system you can, alternatively, install JuNest from the [AUR repository](https://aur.archlinux.org/packages/junest-git/). -JuNest will be located in `/opt/junest/` - Usage ===== There are three different ways you can run JuNest depending on the backend program you decide to use. From c91e013cd4c473df120697e8130700d4d95c83ed Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 9 Jan 2024 15:51:33 +0100 Subject: [PATCH 108/116] Copy pacman.conf file if does not exist --- lib/core/build.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/core/build.sh b/lib/core/build.sh index 0f3d8b0..7a2ef9d 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -25,7 +25,8 @@ function _install_pkg(){ function _prepare() { # ArchLinux System initialization prepare_archlinux - sudo pacman -S --noconfirm git arch-install-scripts haveged + # curl is used to download pacman.conf file + sudo pacman -S --noconfirm git arch-install-scripts haveged curl } function build_image_env(){ @@ -59,12 +60,19 @@ function build_image_env(){ fi sudo mkdir -p "${maindir}"/root/run/lock - sudo tee -a "${maindir}"/root/etc/pacman.conf > /dev/null < Date: Tue, 9 Jan 2024 16:41:45 +0100 Subject: [PATCH 109/116] 7.4.8 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 25627bc..da8d653 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.4.7 +7.4.8 From fd449721375124ab9870970fb1e649b9d36da1dc Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Thu, 1 Aug 2024 19:51:21 +0200 Subject: [PATCH 110/116] Disable the checks and fix shellcheck --- .travis.yml | 4 +++- bin/junest | 3 +++ tests/unit-tests/test-chroot.sh | 3 +++ tests/unit-tests/test-common.sh | 8 ++++++++ tests/unit-tests/test-junest.sh | 25 +++++++++++++++++++++++++ tests/unit-tests/test-namespace.sh | 1 + tests/unit-tests/test-proot.sh | 10 ++++++++++ tests/unit-tests/test-setup.sh | 1 + tests/unit-tests/test-wrappers.sh | 1 + 9 files changed, 55 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 153b779..8efa537 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,7 +49,9 @@ script: # Test the newly created JuNest image against Ubuntu host - export JUNEST_HOME=~/.junest - junest setup -i junest-x86_64.tar.gz - - ${PWD}/lib/checks/check_all.sh + # TODO The check does not work at the moment: https://app.travis-ci.com/github/fsquillace/junest/builds/271706037 + # Disabling it in order to avoid having stale version of junest images. + # - ${PWD}/lib/checks/check_all.sh - yes | junest setup --delete diff --git a/bin/junest b/bin/junest index f0d6abe..4084fe0 100755 --- a/bin/junest +++ b/bin/junest @@ -250,6 +250,7 @@ function execute_operation() { $ACT_VERSION && version && return if $ACT_BUILD; then + # shellcheck disable=SC2086 build_image_env $OPT_DISABLE_CHECK return fi @@ -281,6 +282,7 @@ function execute_operation() { fi if $ACT_CREATE_WRAPPERS; then + # shellcheck disable=SC2086 create_wrappers $OPT_FORCE "$OPT_BIN_PATH" exit fi @@ -307,6 +309,7 @@ function execute_operation() { # Call create_wrappers in case new bin files have been created # shellcheck disable=SC2064 trap "PATH=$PATH create_wrappers" EXIT QUIT TERM + # shellcheck disable=SC2086 $run_env "$BACKEND_COMMAND" "${BACKEND_ARGS}" $OPT_NO_COPY_FILES "${ARGS[@]}" } diff --git a/tests/unit-tests/test-chroot.sh b/tests/unit-tests/test-chroot.sh index 703004d..3739c58 100755 --- a/tests/unit-tests/test-chroot.sh +++ b/tests/unit-tests/test-chroot.sh @@ -29,12 +29,15 @@ function tearDown(){ function init_mocks() { chroot_cmd() { + # shellcheck disable=SC2317 [ "$JUNEST_ENV" != "1" ] && return 1 + # shellcheck disable=SC2317 echo "chroot_cmd $*" } # shellcheck disable=SC2034 GROOT=chroot_cmd mychroot() { + # shellcheck disable=SC2317 echo mychroot "$*" } } diff --git a/tests/unit-tests/test-common.sh b/tests/unit-tests/test-common.sh index d0a6c0b..89c1a1e 100755 --- a/tests/unit-tests/test-common.sh +++ b/tests/unit-tests/test-common.sh @@ -22,8 +22,10 @@ function oneTimeTearDown(){ function setUp(){ ld_exec_mock() { + # shellcheck disable=SC2317 echo "ld_exec $*" } + # shellcheck disable=SC2317 ld_exec_mock_false() { echo "ld_exec $*" return 1 @@ -32,11 +34,13 @@ function setUp(){ LD_EXEC=ld_exec_mock unshare_mock() { + # shellcheck disable=SC2317 echo "unshare $*" } # shellcheck disable=SC2034 UNSHARE=unshare_mock + # shellcheck disable=SC2317 bwrap_mock() { echo "bwrap $*" } @@ -173,6 +177,7 @@ function test_proot_cmd_compat(){ function test_proot_cmd_seccomp(){ envv(){ + # shellcheck disable=SC2317 env } PROOT=envv @@ -180,6 +185,7 @@ function test_proot_cmd_seccomp(){ assertEquals "" "$(grep "^PROOT_NO_SECCOMP" "$STDOUTF")" envv(){ + # shellcheck disable=SC2317 env | grep "^PROOT_NO_SECCOMP" } # shellcheck disable=SC2034 @@ -193,6 +199,7 @@ PROOT_NO_SECCOMP=1" "$(grep "^PROOT_NO_SECCOMP" "$STDOUTF")" function test_copy_passwd_and_group(){ getent_cmd_mock() { + # shellcheck disable=SC2317 echo "$*" } GETENT=getent_cmd_mock assertCommandSuccess copy_passwd_and_group @@ -202,6 +209,7 @@ function test_copy_passwd_and_group(){ function test_copy_passwd_and_group_fallback(){ cp_cmd_mock() { + # shellcheck disable=SC2317 echo "$*" } CP=cp_cmd_mock GETENT=false LD_EXEC=false assertCommandSuccess copy_passwd_and_group diff --git a/tests/unit-tests/test-junest.sh b/tests/unit-tests/test-junest.sh index 086062f..07a92b1 100755 --- a/tests/unit-tests/test-junest.sh +++ b/tests/unit-tests/test-junest.sh @@ -15,25 +15,32 @@ function oneTimeSetUp(){ function setUp(){ ## Mock functions ## + # shellcheck disable=SC2317 function usage(){ echo "usage" } + # shellcheck disable=SC2317 function version(){ echo "version" } + # shellcheck disable=SC2317 function build_image_env(){ local disable_check=$1 echo "build_image_env($disable_check)" } + # shellcheck disable=SC2317 function delete_env(){ echo "delete_env" } + # shellcheck disable=SC2317 function setup_env_from_file(){ echo "setup_env_from_file($1)" } + # shellcheck disable=SC2317 function setup_env(){ echo "setup_env($1)" } + # shellcheck disable=SC2317 function run_env_as_proot_fakeroot(){ local backend_command="$1" local backend_args="$2" @@ -41,6 +48,7 @@ function setUp(){ shift 3 echo "run_env_as_proot_fakeroot($backend_command,$backend_args,$no_copy_files,$*)" } + # shellcheck disable=SC2317 function run_env_as_groot(){ local backend_command="$1" local backend_args="$2" @@ -48,6 +56,7 @@ function setUp(){ shift 3 echo "run_env_as_groot($backend_command,$backend_args,$no_copy_files,$*)" } + # shellcheck disable=SC2317 function run_env_as_chroot(){ local backend_command="$1" local backend_args="$2" @@ -55,6 +64,7 @@ function setUp(){ shift 3 echo "run_env_as_chroot($backend_command,$backend_args,$no_copy_files,$*)" } + # shellcheck disable=SC2317 function run_env_as_proot_user(){ local backend_command="$1" local backend_args="$2" @@ -62,6 +72,7 @@ function setUp(){ shift 3 echo "run_env_as_proot_user($backend_command,$backend_args,$no_copy_files,$*)" } + # shellcheck disable=SC2317 function run_env_as_bwrap_fakeroot(){ local backend_command="$1" local backend_args="$2" @@ -69,6 +80,7 @@ function setUp(){ shift 3 echo "run_env_as_bwrap_fakeroot($backend_command,$backend_args,$no_copy_files,$*)" } + # shellcheck disable=SC2317 function run_env_as_bwrap_user(){ local backend_command="$1" local backend_args="$2" @@ -76,9 +88,11 @@ function setUp(){ shift 3 echo "run_env_as_bwrap_user($backend_command,$backend_args,$no_copy_files,$*)" } + # shellcheck disable=SC2317 function is_env_installed(){ return 0 } + # shellcheck disable=SC2317 function create_wrappers(){ : } @@ -108,6 +122,7 @@ function test_build_image_env(){ } function test_create_wrappers(){ + # shellcheck disable=SC2317 function create_wrappers(){ local force=$1 echo "create_wrappers($force)" @@ -126,6 +141,7 @@ function test_delete_env(){ assertEquals "delete_env" "$(cat "$STDOUTF")" } function test_setup_env_from_file(){ + # shellcheck disable=SC2317 is_env_installed(){ return 1 } @@ -134,6 +150,7 @@ function test_setup_env_from_file(){ assertCommandSuccess main setup --from-file myimage assertEquals "setup_env_from_file(myimage)" "$(cat "$STDOUTF")" + # shellcheck disable=SC2317 is_env_installed(){ return 0 } @@ -141,6 +158,7 @@ function test_setup_env_from_file(){ } function test_setup_env(){ + # shellcheck disable=SC2317 is_env_installed(){ return 1 } @@ -153,6 +171,7 @@ function test_setup_env(){ assertCommandSuccess main setup --arch arm assertEquals "setup_env(arm)" "$(cat "$STDOUTF")" + # shellcheck disable=SC2317 is_env_installed(){ return 0 } @@ -181,6 +200,7 @@ function test_run_env_as_proot_fakeroot(){ assertCommandSuccess main proot -f -- command --as assertEquals "run_env_as_proot_fakeroot(,,false,command --as)" "$(cat "$STDOUTF")" + # shellcheck disable=SC2317 is_env_installed(){ return 1 } @@ -207,6 +227,7 @@ function test_run_env_as_user(){ assertCommandSuccess main proot -- command -ls assertEquals "run_env_as_proot_user(,,false,command -ls)" "$(cat "$STDOUTF")" + # shellcheck disable=SC2317 is_env_installed(){ return 1 } @@ -231,6 +252,7 @@ function test_run_env_as_groot(){ assertCommandSuccess main groot -- command assertEquals "run_env_as_groot(,,false,command)" "$(cat "$STDOUTF")" + # shellcheck disable=SC2317 is_env_installed(){ return 1 } @@ -253,6 +275,7 @@ function test_run_env_as_chroot(){ assertCommandSuccess main root -- command assertEquals "run_env_as_chroot(,,false,command)" "$(cat "$STDOUTF")" + # shellcheck disable=SC2317 is_env_installed(){ return 1 } @@ -295,6 +318,7 @@ function test_run_env_as_bwrap_fakeroot(){ assertCommandSuccess main -f -- command --as assertEquals "run_env_as_bwrap_fakeroot(,,false,command --as)" "$(cat "$STDOUTF")" + # shellcheck disable=SC2317 is_env_installed(){ return 1 } @@ -337,6 +361,7 @@ function test_run_env_as_bwrap_user(){ assertCommandSuccess main -- command --as assertEquals "run_env_as_bwrap_user(,,false,command --as)" "$(cat "$STDOUTF")" + # shellcheck disable=SC2317 is_env_installed(){ return 1 } diff --git a/tests/unit-tests/test-namespace.sh b/tests/unit-tests/test-namespace.sh index 781ca92..7a845aa 100755 --- a/tests/unit-tests/test-namespace.sh +++ b/tests/unit-tests/test-namespace.sh @@ -16,6 +16,7 @@ function oneTimeSetUp(){ ## Mock functions ## function init_mocks() { + # shellcheck disable=SC2317 function bwrap_cmd(){ echo "$BWRAP $*" } diff --git a/tests/unit-tests/test-proot.sh b/tests/unit-tests/test-proot.sh index dfc7498..0f4f11a 100755 --- a/tests/unit-tests/test-proot.sh +++ b/tests/unit-tests/test-proot.sh @@ -49,6 +49,7 @@ function _test_copy_remaining_files() { } function test_run_env_as_proot_user(){ + # shellcheck disable=SC2317 _run_env_with_qemu() { # shellcheck disable=SC2086 # shellcheck disable=SC2048 @@ -66,6 +67,7 @@ function test_run_env_as_proot_user(){ } function test_run_env_as_proot_user_with_backend_command(){ + # shellcheck disable=SC2317 _run_env_with_qemu() { # shellcheck disable=SC2086 # shellcheck disable=SC2048 @@ -83,6 +85,7 @@ function test_run_env_as_proot_user_with_backend_command(){ } function test_run_env_as_proot_user_no_copy(){ + # shellcheck disable=SC2317 _run_env_with_qemu() { # shellcheck disable=SC2086 # shellcheck disable=SC2048 @@ -120,6 +123,7 @@ function test_run_env_as_proot_user_nested_env(){ } function test_run_env_as_proot_fakeroot(){ + # shellcheck disable=SC2317 _run_env_with_qemu() { # shellcheck disable=SC2086 # shellcheck disable=SC2048 @@ -136,6 +140,7 @@ function test_run_env_as_proot_fakeroot(){ } function test_run_env_as_proot_fakeroot_with_backend_command(){ + # shellcheck disable=SC2317 _run_env_with_qemu() { # shellcheck disable=SC2086 # shellcheck disable=SC2048 @@ -159,6 +164,7 @@ function test_run_env_as_proot_fakeroot_nested_env(){ } function test_run_env_with_quotes(){ + # shellcheck disable=SC2317 _run_env_with_qemu() { # shellcheck disable=SC2086 # shellcheck disable=SC2048 @@ -169,6 +175,7 @@ function test_run_env_with_quotes(){ } function test_run_env_with_proot_args(){ + # shellcheck disable=SC2317 proot_cmd() { [ "$JUNEST_ENV" != "1" ] && return 1 # shellcheck disable=SC2086 @@ -187,16 +194,19 @@ function test_run_env_with_proot_args(){ function test_qemu() { echo "JUNEST_ARCH=arm" > "${JUNEST_HOME}"/etc/junest/info + # shellcheck disable=SC2317 rm_cmd() { # shellcheck disable=SC2086 # shellcheck disable=SC2048 echo $* } + # shellcheck disable=SC2317 ln_cmd() { # shellcheck disable=SC2086 # shellcheck disable=SC2048 echo $* } + # shellcheck disable=SC2317 _run_env_with_proot() { # shellcheck disable=SC2086 # shellcheck disable=SC2048 diff --git a/tests/unit-tests/test-setup.sh b/tests/unit-tests/test-setup.sh index d8c2456..de2df75 100755 --- a/tests/unit-tests/test-setup.sh +++ b/tests/unit-tests/test-setup.sh @@ -35,6 +35,7 @@ function test_is_env_installed(){ function test_setup_env(){ rm -rf "${JUNEST_HOME:?}"/* + # shellcheck disable=SC2317 wget_mock(){ # Proof that the setup is happening # inside $JUNEST_TEMPDIR diff --git a/tests/unit-tests/test-wrappers.sh b/tests/unit-tests/test-wrappers.sh index eef1f38..ee9776f 100755 --- a/tests/unit-tests/test-wrappers.sh +++ b/tests/unit-tests/test-wrappers.sh @@ -70,6 +70,7 @@ function test_create_wrappers_verify_content(){ assertEquals "" "$(cat "$STDOUTF")" # Mock junest command to capture the actual output generated from myfile script + # shellcheck disable=SC2317 junest(){ for arg in "$@" do From e68c24dec630412b01f378ffe242f79a5586a38b Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Thu, 1 Aug 2024 20:29:07 +0200 Subject: [PATCH 111/116] 7.4.9 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index da8d653..14ebea1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.4.8 +7.4.9 From 7af01ba4811b03c4764727803a4c4c3d30e23c6c Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 8 Oct 2024 01:04:11 +0200 Subject: [PATCH 112/116] Fix pacman 7 usage during build --- lib/core/build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/core/build.sh b/lib/core/build.sh index 7a2ef9d..cf23f67 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -65,6 +65,9 @@ function build_image_env(){ # https://app.travis-ci.com/github/fsquillace/junest/builds/268216346 [[ -e "${maindir}"/root/etc/pacman.conf ]] || sudo curl "https://gitlab.archlinux.org/archlinux/packaging/packages/pacman/-/raw/main/pacman.conf" -o "${maindir}/root/etc/pacman.conf" + # Pacman/pacstrap bug: https://gitlab.archlinux.org/archlinux/packaging/packages/arch-install-scripts/-/issues/3 + sudo sed -i '/^DownloadUser = alpm$/d' "${maindir}"/root/etc/pacman.conf + sudo tee -a "${maindir}"/root/etc/pacman.conf < Date: Tue, 8 Oct 2024 01:10:24 +0200 Subject: [PATCH 113/116] Do not remove gzip during build --- lib/core/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/build.sh b/lib/core/build.sh index cf23f67..9d985ea 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -87,13 +87,13 @@ EOT info "Generating the locales..." # sed command is required for locale-gen but it is required by fakeroot # and cannot be removed - # localedef (called by locale-gen) requires gzip + # localedef (called by locale-gen) requires gzip but it is supposed to be + # already installed as systemd already depends on it sudo pacman --noconfirm --root "${maindir}"/root -S sed gzip sudo ln -sf /usr/share/zoneinfo/posix/UTC "${maindir}"/root/etc/localtime sudo bash -c "echo 'en_US.UTF-8 UTF-8' >> ${maindir}/root/etc/locale.gen" sudo "${maindir}"/root/bin/groot "${maindir}"/root locale-gen sudo bash -c "echo LANG=\"en_US.UTF-8\" >> ${maindir}/root/etc/locale.conf" - sudo pacman --noconfirm --root "${maindir}"/root -Rsn gzip info "Setting up the pacman keyring (this might take a while!)..." if [[ $(uname -m) == *"arm"* ]] From e2d9517a92093b6e5caddc5ab8c2254e76819134 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Tue, 8 Oct 2024 19:47:29 +0200 Subject: [PATCH 114/116] Test enabling back the check scripts --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8efa537..fab23ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,7 +51,7 @@ script: - junest setup -i junest-x86_64.tar.gz # TODO The check does not work at the moment: https://app.travis-ci.com/github/fsquillace/junest/builds/271706037 # Disabling it in order to avoid having stale version of junest images. - # - ${PWD}/lib/checks/check_all.sh + - ${PWD}/lib/checks/check_all.sh - yes | junest setup --delete From 0242749f8e39af96e5f1837e1ecfce3f4c146b07 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 12 Oct 2024 11:34:38 +0200 Subject: [PATCH 115/116] Replace yay with yay-git --- lib/core/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/build.sh b/lib/core/build.sh index 9d985ea..65a9474 100644 --- a/lib/core/build.sh +++ b/lib/core/build.sh @@ -76,7 +76,7 @@ Server = https://raw.githubusercontent.com/fsquillace/junest-repo/master/any EOT info "pacman.conf being used:" cat "${maindir}"/root/etc/pacman.conf - sudo pacman --noconfirm --config "${maindir}"/root/etc/pacman.conf --root "${maindir}"/root -Sy sudo-fake groot-git proot-static qemu-user-static-bin-alt yay + sudo pacman --noconfirm --config "${maindir}"/root/etc/pacman.conf --root "${maindir}"/root -Sy sudo-fake groot-git proot-static qemu-user-static-bin-alt yay-git echo "Generating the metadata info" sudo install -d -m 755 "${maindir}/root/etc/${CMD}" From 0037f96e159a143e37db978e537e3fb362ba3a5b Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sat, 12 Oct 2024 11:53:52 +0200 Subject: [PATCH 116/116] Add warning box for Ubuntu restriction --- README.md | 7 +++++++ VERSION | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a7001ce..1268f8b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,12 @@ JuNest ====== + +> [!IMPORTANT] +> Starting from Ubuntu 23.10+, [unprivileged user namespaces has been restricted](https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces). +> If using JuNest within Ubuntu, you may need root privileges in order to enable it. +> Alternatively, you can access JuNest using the `proot` mode as described +> [below](#Proot-based). + The lightweight Arch Linux based distro that runs, without root privileges, on top of any other Linux distro.

diff --git a/VERSION b/VERSION index 14ebea1..ef13716 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.4.9 +7.4.10