mirror of
https://github.com/fsquillace/junest.git
synced 2026-07-20 17:59:38 +00:00
Merge pull request #183 from fsquillace/issue_174_namespace
Issue 174 namespace
This commit is contained in:
commit
3456857d7a
21 changed files with 1313 additions and 529 deletions
11
.travis.yml
11
.travis.yml
|
|
@ -17,9 +17,14 @@ install:
|
|||
|
||||
script:
|
||||
- bash --version
|
||||
- bash ./tests/unit-tests/unit-tests.sh
|
||||
- bash ./tests/checkstyle/checkstyle.sh
|
||||
- junest --check ./bin/junest
|
||||
- bash ./tests/unit-tests/unit-tests.sh
|
||||
|
||||
# Multiple tests against different execution modes:
|
||||
- junest -f -- ${PWD}/lib/checks/check.sh
|
||||
- junest -u -- ${PWD}/lib/checks/check.sh --skip-aur-tests
|
||||
- sudo -E ${PWD}/bin/junest -g -- ${PWD}/lib/checks/check.sh --run-root-tests
|
||||
- yes | junest --delete
|
||||
- JUNEST_HOME=~/.junest-arm junest --check ./bin/junest --skip-root-tests
|
||||
|
||||
- JUNEST_HOME=~/.junest-arm junest -f -- ./lib/checks/check.sh
|
||||
- yes | JUNEST_HOME=~/.junest-arm junest --delete
|
||||
|
|
|
|||
107
README.md
107
README.md
|
|
@ -11,13 +11,13 @@ The Arch Linux based distro that runs upon any Linux distros without root access
|
|||
|
||||
|Project Status|Donation|Communication|
|
||||
|:------------:|:------:|:-----------:|
|
||||
| [](https://travis-ci.org/fsquillace/junest) [](https://www.openhub.net/p/junest) | [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8LEHQKBCYTACY) [](https://gratipay.com/junest/) | [](https://gitter.im/fsquillace/junest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://webchat.freenode.net/?channels=junest) [](https://groups.google.com/d/forum/junest) [](http://fsquillace.github.io/junest-site/feed.xml) |
|
||||
| [](https://travis-ci.org/fsquillace/junest) [](https://www.openhub.net/p/junest) | [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8LEHQKBCYTACY) [](https://gratipay.com/junest/) | [](https://gitter.im/fsquillace/junest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://webchat.freenode.net/?channels=junest) [](https://groups.google.com/d/forum/junest) [](http://fsquillace.github.io/junest-site/feed.xml) |
|
||||
|
||||
**Table of Contents**
|
||||
- [Description](#description)
|
||||
- [Quickstart](#quickstart)
|
||||
- [Installation](#installation)
|
||||
- [Dependencies](#dependencies)
|
||||
- [Usage](#usage)
|
||||
- [Advanced usage](#advanced-usage)
|
||||
- [Internals](#internals)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
|
|
@ -48,19 +48,22 @@ JuNest follows the [Arch Linux philosophy](https://wiki.archlinux.org/index.php/
|
|||
|
||||
Quickstart
|
||||
==========
|
||||
There are three different ways you can run JuNest:
|
||||
The basic way to run JuNest is via the [Proot](https://wiki.archlinux.org/index.php/Proot) as the backend program:
|
||||
|
||||
- As normal user - Allow to make basic operations: ```junest```
|
||||
|
||||
- As fakeroot - Allow to install/remove packages: ```junest -f```
|
||||
|
||||
- As root - Allow to have fully root privileges inside JuNest environment (you need to be root for executing this): ```junest -r```
|
||||
To know more about the JuNest execution modes depending on the backend program
|
||||
used, see the [Usage](#usage) section below.
|
||||
|
||||
After running JuNest
|
||||
--------------------
|
||||
If the JuNest image has not been downloaded yet, the script will download
|
||||
the image and will place it to the default directory ~/.junest.
|
||||
You can change the default directory by changing the environment variable *JUNEST\_HOME*.
|
||||
the image from the repository and will place it to the default directory `~/.junest`.
|
||||
You can change the default directory by changing the environment variable `JUNEST_HOME`.
|
||||
|
||||
If you are new on Archlinux and you are not familiar with *pacman* package manager
|
||||
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
|
||||
|
|
@ -90,7 +93,7 @@ Just clone the JuNest repo somewhere (for example in ~/.local/share/junest):
|
|||
### 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/):
|
||||
|
||||
yogurt -S junest-git
|
||||
yaourt -S junest-git
|
||||
export PATH=/opt/junest/bin:$PATH
|
||||
|
||||
## Method two ##
|
||||
|
|
@ -98,12 +101,72 @@ Alternatively, another installation method would be to directly download the JuN
|
|||
|
||||
ARCH=<one of "x86_64", "x86", "arm">
|
||||
mkdir ~/.junest
|
||||
curl https://dl.dropboxusercontent.com/u/42449030/junest/junest-${ARCH}.tar.gz | tar -xz -C ~/.junest
|
||||
curl https://s3-eu-west-1.amazonaws.com/junest-repo/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.
|
||||
|
||||
PRoot based
|
||||
-----------
|
||||
[Proot](https://wiki.archlinux.org/index.php/Proot) represents the default
|
||||
program used for accessing to the JuNest environments.
|
||||
The main reason to choose Proot as default backend program is because
|
||||
it represents a portable solution that 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:
|
||||
|
||||
- As normal user - Allow to make basic operations: ```junest```
|
||||
|
||||
- As fakeroot - Allow to install/remove packages: ```junest -f```
|
||||
|
||||
Linux namespaces based
|
||||
----------------------
|
||||
The [Linux namespaces](http://man7.org/linux/man-pages/man7/namespaces.7.html)
|
||||
represents the next generation backend program for JuNest.
|
||||
The major drawback about the namespace is portability, as certain requirements
|
||||
need to be satisfied: 1) Only starting from Linux 3.8, unprivileged processes can
|
||||
create the required user and mount namespaces.
|
||||
2) Moreover, the Linux kernel distro must have the user namespace enabled.
|
||||
Hopefully, in the future the major GNU/Linux distros will start enabling such feature by default.
|
||||
For instance, Ubuntu (version 14.04+) already has such feature enabled.
|
||||
|
||||
In order to run JuNest via Linux namespaces:
|
||||
|
||||
- As fakeroot - Allow to install/remove packages: ```junest -u```
|
||||
|
||||
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`
|
||||
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
|
||||
work, JuNest is even providing the possibility to run the environment directly via
|
||||
the pure `chroot` command.
|
||||
|
||||
In order to run JuNest via `chroot` solutions:
|
||||
|
||||
- As root via `GRoot` - Allow to have fully root privileges inside JuNest environment (you need to be root for executing this): ```junest -g```
|
||||
|
||||
- As root via `chroot` - Allow to have fully root privileges inside JuNest environment (you need to be root for executing this): ```junest -r```
|
||||
|
||||
Execution modes comparison table
|
||||
----------------
|
||||
The following table shows the capabilities that each backend program is able to perform:
|
||||
|
||||
| | QEMU | Root privileges required | Manage Official Packages | Manage AUR Packages | Portability | Support | User modes |
|
||||
| --- | ---- | ------------------------ | ------------------------ | ------------------- | ----------- | ------- | ---------- |
|
||||
| **Proot** | YES | NO | YES | YES | YES | Poor | Normal user and `fakeroot` |
|
||||
| **Linux Namespaces** | NO | NO | YES | NO | Poor | YES | `fakeroot` only |
|
||||
| **Chroot** | NO | YES | YES | YES | YES | YES | `root` only |
|
||||
|
||||
Advanced usage
|
||||
==============
|
||||
|
||||
## Build image ##
|
||||
You can build a new JuNest image from scratch by running the following command:
|
||||
|
||||
|
|
@ -114,7 +177,7 @@ files in order to make JuNest working properly (such as pacman, yogurt and proot
|
|||
The option **-n** will skip the final validation tests if they are not needed.
|
||||
Remember that the script to build the image must run in an Arch Linux OS with
|
||||
arch-install-scripts, package-query, git and the base-devel packages installed.
|
||||
To change the build directory just use the *JUNEST_TEMPDIR* (by default /tmp).
|
||||
To change the build directory just use the `JUNEST_TEMPDIR` (by default /tmp).
|
||||
|
||||
After creating the image junest-x86\_64.tar.gz you can install it by running:
|
||||
|
||||
|
|
@ -141,12 +204,12 @@ To bind a host directory to a guest location, you can use proot arguments:
|
|||
|
||||
junest -p "-b /mnt/mydata:/home/user/mydata"
|
||||
|
||||
Check out the proot options with:
|
||||
This will works with PRoot, Namespace and GRoot backend programs.
|
||||
Check out the backend program options by passing `--help` option:
|
||||
|
||||
junest -p "--help"
|
||||
junest [-u|-g] -p "--help"
|
||||
|
||||
## Systemd integration ##
|
||||
|
||||
Although JuNest has not been designed to be a complete container, it is even possible to
|
||||
virtualize the process tree thanks to the [systemd container](https://wiki.archlinux.org/index.php/Systemd-nspawn).
|
||||
The JuNest containter allows to run services inside the container that can be
|
||||
|
|
@ -169,14 +232,14 @@ 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
|
||||
jchroot, a small and portable version of
|
||||
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 jchroot fails for some reasons in the host system (i.e. it is not able to
|
||||
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.
|
||||
|
||||
|
|
@ -345,6 +408,18 @@ Troubleshooting
|
|||
> since JuNest will try to preserve the JuNest environment by assigning ownership
|
||||
> of the files to the real user.
|
||||
|
||||
## Not enabled User namespace or kernel too old ##
|
||||
|
||||
> **Q**: Why do I get warning when I run JuNest via Linux namespaces?
|
||||
|
||||
$> junest -u
|
||||
User namespace is not enabled or Kernel too old (<3.8). Proceeding anyway...
|
||||
|
||||
> **A**: This means that JuNest detected that the host OS either
|
||||
> does not have a newer Linux version or the user namespace is not enabled.
|
||||
> JuNest does not stop the execution of the program but it attempts to run it
|
||||
> anyway. Try to use Proot as backend program in case is not possible to invoke namespaces.
|
||||
|
||||
More documentation
|
||||
==================
|
||||
There are additional tutorials in the
|
||||
|
|
|
|||
190
bin/groot
Executable file
190
bin/groot
Executable file
|
|
@ -0,0 +1,190 @@
|
|||
#!/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
|
||||
MOUNTPOINT=mountpoint
|
||||
MKDIR=mkdir
|
||||
TOUCH=touch
|
||||
CUT=cut
|
||||
SORT=sort
|
||||
UNIQ=uniq
|
||||
GREP=grep
|
||||
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 chroot_teardown() {
|
||||
# Remove all mounts starting from the most nested ones.
|
||||
# Suffix the CHROOTDIR with / to avoid umounting directories not belonging
|
||||
# to CHROOTDIR.
|
||||
for mp in $($GREP "${CHROOTDIR%/}/" $MOUNTS_FILE | $CUT -f2 -d' ' | $SORT -r | $UNIQ)
|
||||
do
|
||||
$UMOUNT $mp
|
||||
done
|
||||
$UMOUNT ${CHROOTDIR%/}
|
||||
}
|
||||
|
||||
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 "! $MOUNTPOINT -q '$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 --rbind "${host_path}" "${CHROOTDIR}${guest_path}"
|
||||
done
|
||||
}
|
||||
|
||||
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 <<EOF
|
||||
$NAME (v$(cat $JUNEST_BASE/VERSION)): $DESCRIPTION
|
||||
|
||||
Usage:
|
||||
$CMD [options] [<chroot-dir> [command]]
|
||||
|
||||
Options:
|
||||
-b, --bind <path>
|
||||
Make the content of <path> 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 <host_path>:<guest_location>. This option can
|
||||
be invoked multiple times and the paths specified must be absolutes.
|
||||
-n, --no-umount
|
||||
Do not umount after chroot session finished.
|
||||
|
||||
-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() {
|
||||
OPT_BIND=false
|
||||
BINDINGS=()
|
||||
OPT_NO_UMOUNT=false
|
||||
OPT_HELP=false
|
||||
OPT_VERSION=false
|
||||
for opt in "$@"
|
||||
do
|
||||
case "$1" in
|
||||
-b|--bind) OPT_BIND=true ; shift ; BINDINGS+=("$1") ; shift ;;
|
||||
-n|--no-umount) OPT_NO_UMOUNT=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 "$@"
|
||||
98
bin/jchroot
98
bin/jchroot
|
|
@ -1,98 +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="$(readlink -f $(dirname $(readlink -f "$0"))/..)"
|
||||
|
||||
source "${JUNEST_BASE}/lib/utils/utils.sh"
|
||||
|
||||
################################ MAIN FUNCTIONS ###########################
|
||||
|
||||
chroot_add_mount() {
|
||||
mount "$@" && CHROOT_ACTIVE_MOUNTS=("$2" "${CHROOT_ACTIVE_MOUNTS[@]}")
|
||||
}
|
||||
|
||||
chroot_maybe_add_mount() {
|
||||
local cond=$1; shift
|
||||
if eval "$cond"; then
|
||||
chroot_add_mount "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
chroot_setup() {
|
||||
CHROOT_ACTIVE_MOUNTS=()
|
||||
[[ $(trap -p EXIT) ]] && die '(BUG): attempting to overwrite existing EXIT trap'
|
||||
trap 'chroot_teardown' EXIT
|
||||
|
||||
chroot_maybe_add_mount "! mountpoint -q '$1'" "$1" "$1" --bind &&
|
||||
chroot_add_mount proc "$1/proc" -t proc -o nosuid,noexec,nodev &&
|
||||
chroot_add_mount sys "$1/sys" -t sysfs -o nosuid,noexec,nodev,ro &&
|
||||
chroot_add_mount udev "$1/dev" -t devtmpfs -o mode=0755,nosuid &&
|
||||
chroot_add_mount devpts "$1/dev/pts" -t devpts -o mode=0620,gid=5,nosuid,noexec &&
|
||||
chroot_add_mount shm "$1/dev/shm" -t tmpfs -o mode=1777,nosuid,nodev &&
|
||||
chroot_add_mount run "$1/run" -t tmpfs -o nosuid,nodev,mode=0755 &&
|
||||
chroot_add_mount tmp "$1/tmp" -t tmpfs -o mode=1777,atime,nodev,nosuid &&
|
||||
mkdir -p "$1/$HOME" &&
|
||||
chroot_add_mount $HOME "$1/$HOME" --bind
|
||||
|
||||
mkdir -p "$1/run/lock"
|
||||
}
|
||||
|
||||
chroot_teardown() {
|
||||
umount "${CHROOT_ACTIVE_MOUNTS[@]}"
|
||||
unset CHROOT_ACTIVE_MOUNTS
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
usage: ${0##*/} chroot-dir [command]
|
||||
|
||||
-h Print this help message
|
||||
|
||||
If 'command' is unspecified, ${0##*/} will launch /bin/sh.
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
chroot_add_resolv_conf() {
|
||||
local chrootdir=$1 resolv_conf=$1/etc/resolv.conf
|
||||
|
||||
# Handle resolv.conf as a symlink to somewhere else.
|
||||
if [[ -L $chrootdir/etc/resolv.conf ]]; then
|
||||
# readlink(1) should always give us *something* since we know at this point
|
||||
# it's a symlink. For simplicity, ignore the case of nested symlinks.
|
||||
resolv_conf=$(readlink "$chrootdir/etc/resolv.conf")
|
||||
if [[ $resolv_conf = /* ]]; then
|
||||
resolv_conf=$chrootdir$resolv_conf
|
||||
else
|
||||
resolv_conf=$chrootdir/etc/$resolv_conf
|
||||
fi
|
||||
|
||||
# ensure file exists to bind mount over
|
||||
if [[ ! -f $resolv_conf ]]; then
|
||||
install -Dm644 /dev/null "$resolv_conf" || return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
chroot_add_mount /etc/resolv.conf "$resolv_conf" --bind
|
||||
}
|
||||
|
||||
if [[ -z $1 || $1 == -h || $1 == --help ]]; then
|
||||
usage
|
||||
exit $(( $# ? 0 : 1 ))
|
||||
fi
|
||||
|
||||
(( EUID == 0 )) || die 'This script must be run with root privileges'
|
||||
chrootdir=$1
|
||||
shift
|
||||
|
||||
[[ -d $chrootdir ]] || die "Can't create chroot on non-directory $chrootdir"
|
||||
|
||||
chroot_setup "$chrootdir" || die "failed to setup chroot $chrootdir"
|
||||
chroot_add_resolv_conf "$chrootdir" || die "failed to setup resolv.conf"
|
||||
|
||||
SHELL="/bin/sh" chroot "$chrootdir" "$@"
|
||||
100
bin/junest
100
bin/junest
|
|
@ -3,14 +3,21 @@
|
|||
# This file is part of JuNest (https://github.com/fsquillace/junest).
|
||||
#
|
||||
|
||||
JUNEST_BASE="$(readlink -f $(dirname $(readlink -f "$0"))/..)"
|
||||
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"))/..)}"
|
||||
|
||||
source "${JUNEST_BASE}/lib/utils/utils.sh"
|
||||
source "${JUNEST_BASE}/lib/core/common.sh"
|
||||
|
||||
source "${JUNEST_BASE}/lib/core/build.sh"
|
||||
source "${JUNEST_BASE}/lib/core/setup.sh"
|
||||
source "${JUNEST_BASE}/lib/core/proot.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/setup.sh"
|
||||
|
||||
|
||||
###################################
|
||||
### General functions ###
|
||||
|
|
@ -29,19 +36,21 @@ usage() {
|
|||
echo
|
||||
echo -e "Access options:"
|
||||
echo -e "-f, --fakeroot Run $NAME with fakeroot privileges"
|
||||
echo -e "-r, --root Run $NAME with root privileges"
|
||||
echo -e "-p, --proot-args <args> Proot arguments (use $CMD -p \"--help\" to check out the proot options)"
|
||||
echo -e "-g, --groot Run $NAME with root privileges via GRoot"
|
||||
echo -e "-r, --root Run $NAME with root privileges via classic chroot"
|
||||
echo -e "-u, --namespace Use Linux Namespace (with GRoot) instead of PRoot"
|
||||
echo -e "-p, --backend-args <args> Arguments for backend program (PRoot or GRoot)"
|
||||
echo -e " ($CMD -p \"--help\" to check out the PRoot options"
|
||||
echo -e " $CMD -g -p \"--help\" to check out the GRoot options"
|
||||
echo -e " $CMD -r -p \"--help\" to check out the chroot options)"
|
||||
echo
|
||||
echo -e "Building options:"
|
||||
echo -e "-b, --build-image Build a $NAME image (must run in ArchLinux)"
|
||||
echo -e "-n, --disable-validation Disable the $NAME image validation"
|
||||
echo -e "-c, --check <${CMD}_script> Validate the env located in ${JUNEST_HOME}"
|
||||
echo -e " using ${CMD}_script. This will alterate the environment"
|
||||
echo -e "-s, --skip-root-tests Skip the root tests during the validation process"
|
||||
echo
|
||||
echo -e "General options:"
|
||||
echo -e "-h, --help Show this help message"
|
||||
echo -e "-v, --version Show the $NAME version"
|
||||
echo -e "-V, --version Show the $NAME version"
|
||||
}
|
||||
|
||||
version() {
|
||||
|
|
@ -50,33 +59,17 @@ version() {
|
|||
|
||||
check_cli(){
|
||||
if $OPT_BUILD_IMAGE
|
||||
then
|
||||
if $OPT_DELETE || $OPT_HELP || $OPT_VERSION || $OPT_SETUP_FROM_FILE || \
|
||||
$OPT_FAKEROOT || $OPT_ROOT || $OPT_CHECK
|
||||
then
|
||||
die "The build image option must be used exclusively"
|
||||
fi
|
||||
fi
|
||||
if $OPT_SKIP_ROOT_TEST
|
||||
then
|
||||
if $OPT_DELETE || $OPT_HELP || $OPT_VERSION || $OPT_SETUP_FROM_FILE || \
|
||||
$OPT_FAKEROOT || $OPT_ROOT
|
||||
then
|
||||
die "The skip root tests option must be used with either build image or check options"
|
||||
fi
|
||||
fi
|
||||
if $OPT_CHECK
|
||||
then
|
||||
if $OPT_DELETE || $OPT_HELP || $OPT_VERSION || $OPT_SETUP_FROM_FILE || \
|
||||
$OPT_FAKEROOT || $OPT_ROOT || $OPT_BUILD_IMAGE
|
||||
then
|
||||
die "The validation image option must be used exclusively"
|
||||
die "The build image option must be used exclusively"
|
||||
fi
|
||||
fi
|
||||
if $OPT_DISABLE_VALIDATION
|
||||
then
|
||||
if $OPT_DELETE || $OPT_HELP || $OPT_VERSION || $OPT_SETUP_FROM_FILE || \
|
||||
$OPT_FAKEROOT || $OPT_ROOT || $OPT_CHECK
|
||||
$OPT_FAKEROOT || $OPT_ROOT
|
||||
then
|
||||
die "The disable validation option must be used with the build image option only"
|
||||
fi
|
||||
|
|
@ -84,7 +77,7 @@ check_cli(){
|
|||
if $OPT_DELETE
|
||||
then
|
||||
if $OPT_BUILD_IMAGE || $OPT_HELP || $OPT_VERSION || $OPT_SETUP_FROM_FILE || \
|
||||
$OPT_FAKEROOT || $OPT_ROOT || $OPT_DISABLE_VALIDATION || $OPT_CHECK
|
||||
$OPT_FAKEROOT || $OPT_ROOT || $OPT_DISABLE_VALIDATION
|
||||
then
|
||||
die "The $NAME delete option must be used exclusively"
|
||||
fi
|
||||
|
|
@ -92,7 +85,7 @@ check_cli(){
|
|||
if $OPT_HELP
|
||||
then
|
||||
if $OPT_BUILD_IMAGE || $OPT_DELETE || $OPT_VERSION || $OPT_SETUP_FROM_FILE || \
|
||||
$OPT_FAKEROOT || $OPT_ROOT || $OPT_DISABLE_VALIDATION || $OPT_CHECK
|
||||
$OPT_FAKEROOT || $OPT_ROOT || $OPT_DISABLE_VALIDATION
|
||||
then
|
||||
die "The $NAME help option must be used exclusively"
|
||||
fi
|
||||
|
|
@ -100,7 +93,7 @@ check_cli(){
|
|||
if $OPT_VERSION
|
||||
then
|
||||
if $OPT_BUILD_IMAGE || $OPT_DELETE || $OPT_HELP || $OPT_SETUP_FROM_FILE || \
|
||||
$OPT_FAKEROOT || $OPT_ROOT || $OPT_DISABLE_VALIDATION || $OPT_CHECK
|
||||
$OPT_FAKEROOT || $OPT_ROOT || $OPT_DISABLE_VALIDATION
|
||||
then
|
||||
die "The $NAME version option must be used exclusively"
|
||||
fi
|
||||
|
|
@ -109,10 +102,10 @@ check_cli(){
|
|||
then
|
||||
die "You must access to $NAME with either fakeroot or root permissions"
|
||||
fi
|
||||
if $OPT_PROOT_ARGS || $OPT_ARCH
|
||||
if $OPT_BACKEND_ARGS || $OPT_ARCH
|
||||
then
|
||||
if $OPT_BUILD_IMAGE || $OPT_DELETE || $OPT_HELP || \
|
||||
$OPT_ROOT || $OPT_VERSION || $OPT_DISABLE_VALIDATION || $OPT_CHECK
|
||||
$OPT_ROOT || $OPT_VERSION || $OPT_DISABLE_VALIDATION
|
||||
then
|
||||
die "Invalid syntax: Proot and arch args are not allowed with the other options"
|
||||
fi
|
||||
|
|
@ -120,7 +113,7 @@ check_cli(){
|
|||
if [ "$ARGS" != "" ]
|
||||
then
|
||||
if $OPT_BUILD_IMAGE || $OPT_DELETE || $OPT_HELP || $OPT_SETUP_FROM_FILE || \
|
||||
$OPT_VERSION || $OPT_DISABLE_VALIDATION || $OPT_CHECK
|
||||
$OPT_VERSION || $OPT_DISABLE_VALIDATION
|
||||
then
|
||||
die "No arguments are needed. For the CLI syntax run: $CMD --help"
|
||||
fi
|
||||
|
|
@ -135,15 +128,15 @@ function parse_arguments(){
|
|||
IMAGE_FILE=""
|
||||
OPT_FAKEROOT=false
|
||||
OPT_ROOT=false
|
||||
OPT_PROOT_ARGS=false
|
||||
PROOT_ARGS=""
|
||||
OPT_GROOT=false
|
||||
OPT_USER_NAMESPACE=false
|
||||
OPT_BACKEND_ARGS=false
|
||||
BACKEND_ARGS=""
|
||||
OPT_ARCH=false
|
||||
ARCH_ARG=""
|
||||
OPT_BUILD_IMAGE=false
|
||||
OPT_DISABLE_VALIDATION=false
|
||||
OPT_CHECK=false
|
||||
CHECK_ARG=""
|
||||
OPT_SKIP_ROOT_TEST=false
|
||||
OPT_DELETE=false
|
||||
OPT_HELP=false
|
||||
OPT_VERSION=false
|
||||
|
|
@ -153,15 +146,15 @@ function parse_arguments(){
|
|||
-i|--setup-from-file) OPT_SETUP_FROM_FILE=true ; shift ; IMAGE_FILE=$1 ; shift ;;
|
||||
-f|--fakeroot) OPT_FAKEROOT=true ; shift ;;
|
||||
-r|--root) OPT_ROOT=true ; shift ;;
|
||||
-p|--proot-args) OPT_PROOT_ARGS=true ; shift ; PROOT_ARGS=$1; shift ;;
|
||||
-g|--groot) OPT_GROOT=true ; shift ;;
|
||||
-u|--namespace) OPT_USER_NAMESPACE=true ; shift ;;
|
||||
-p|--backend-args) OPT_BACKEND_ARGS=true ; shift ; BACKEND_ARGS=$1; shift ;;
|
||||
-a|--arch) OPT_ARCH=true ; shift ; ARCH_ARG=$1; shift ;;
|
||||
-b|--build-image) OPT_BUILD_IMAGE=true ; shift ;;
|
||||
-n|--disable-validation) OPT_DISABLE_VALIDATION=true ; shift ;;
|
||||
-c|--check) OPT_CHECK=true ; shift ; CHECK_ARG=$1; shift ;;
|
||||
-s|--skip-root-tests) OPT_SKIP_ROOT_TEST=true ; shift ;;
|
||||
-d|--delete) OPT_DELETE=true ; shift ;;
|
||||
-h|--help) OPT_HELP=true ; shift ;;
|
||||
-v|--version) OPT_VERSION=true ; shift ;;
|
||||
-V|--version) OPT_VERSION=true ; shift ;;
|
||||
--) shift ; break ;;
|
||||
-*) die "Invalid option $1" ;;
|
||||
*) break ;;
|
||||
|
|
@ -180,14 +173,11 @@ function execute_operation(){
|
|||
$OPT_VERSION && version && return
|
||||
|
||||
if $OPT_BUILD_IMAGE; then
|
||||
build_image_env $OPT_DISABLE_VALIDATION $OPT_SKIP_ROOT_TEST
|
||||
build_image_env $OPT_DISABLE_VALIDATION
|
||||
return
|
||||
elif $OPT_DELETE; then
|
||||
delete_env
|
||||
return
|
||||
elif $OPT_CHECK; then
|
||||
check_env "${JUNEST_HOME}" "${CHECK_ARG}" $OPT_SKIP_ROOT_TEST
|
||||
return
|
||||
fi
|
||||
|
||||
if ! is_env_installed
|
||||
|
|
@ -205,20 +195,28 @@ function execute_operation(){
|
|||
[ -z "${ARCH_ARG}" ] || \
|
||||
die "The option --arch cannot be specified since JuNest has already been downloaded in $JUNEST_HOME"
|
||||
|
||||
if $OPT_FAKEROOT; then
|
||||
run_env_as_fakeroot "${PROOT_ARGS}" "${ARGS[@]}"
|
||||
local run_env
|
||||
if $OPT_USER_NAMESPACE; then
|
||||
run_env=run_env_with_namespace
|
||||
elif $OPT_FAKEROOT; then
|
||||
run_env=run_env_as_fakeroot
|
||||
elif $OPT_ROOT; then
|
||||
run_env_as_root "${ARGS[@]}"
|
||||
run_env=run_env_as_chroot
|
||||
elif $OPT_GROOT; then
|
||||
run_env=run_env_as_groot
|
||||
else
|
||||
run_env_as_user "${PROOT_ARGS}" "${ARGS[@]}"
|
||||
run_env=run_env_as_user
|
||||
fi
|
||||
|
||||
$run_env "${BACKEND_ARGS}" "${ARGS[@]}"
|
||||
|
||||
}
|
||||
|
||||
function cli() {
|
||||
function main() {
|
||||
parse_arguments "$@"
|
||||
check_cli
|
||||
execute_operation
|
||||
}
|
||||
|
||||
cli "$@"
|
||||
main "$@"
|
||||
# vim: set ts=4 sw=4 noet:
|
||||
|
|
|
|||
62
lib/checks/check.sh
Executable file
62
lib/checks/check.sh
Executable file
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# This modules is used for:
|
||||
# - Running checks against the building JuNest image
|
||||
# - Integration tests on JuNest script against different execution modes (i.e. -f, -u, -r modes)
|
||||
#
|
||||
# Dependencies:
|
||||
# - None
|
||||
#
|
||||
# vim: ft=sh
|
||||
|
||||
set -eu
|
||||
|
||||
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
|
||||
|
||||
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"))/../..)}"
|
||||
|
||||
source "${JUNEST_BASE}/lib/utils/utils.sh"
|
||||
source "${JUNEST_BASE}/lib/core/common.sh"
|
||||
|
||||
info "Validating JuNest located in ${JUNEST_HOME}..."
|
||||
|
||||
info "Initial JuNest setup..."
|
||||
echo "Server = ${DEFAULT_MIRROR}" >> /etc/pacman.d/mirrorlist
|
||||
pacman --noconfirm -Syy
|
||||
pacman --noconfirm -S base-devel
|
||||
|
||||
info "Checking essential executables work..."
|
||||
pacman -Qi pacman 1> /dev/null
|
||||
yogurt -V 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}
|
||||
tree -L 1
|
||||
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}
|
||||
|
||||
if ! $SKIP_AUR_TESTS
|
||||
then
|
||||
aur_package=tcptraceroute
|
||||
info "Checking ${aur_package} package from AUR repo..."
|
||||
yogurt -A --noconfirm -S ${aur_package}
|
||||
$RUN_ROOT_TESTS && tcptraceroute localhost
|
||||
pacman --noconfirm -Rsn ${aur_package}
|
||||
fi
|
||||
|
|
@ -40,7 +40,6 @@ function build_image_env(){
|
|||
_check_package git
|
||||
|
||||
local disable_validation=$1
|
||||
local skip_root_tests=$2
|
||||
|
||||
local maindir=$(TMPDIR=$JUNEST_TEMPDIR mktemp -d -t ${CMD}.XXXXXXXXXX)
|
||||
sudo mkdir -p ${maindir}/root
|
||||
|
|
@ -51,7 +50,8 @@ function build_image_env(){
|
|||
# All the essential executables (ln, mkdir, chown, etc) are in coreutils
|
||||
# yaourt requires sed
|
||||
# localedef (called by locale-gen) requires gzip
|
||||
sudo pacstrap -G -M -d ${maindir}/root pacman coreutils libunistring archlinux-keyring sed gzip
|
||||
# unshare command belongs to util-linux
|
||||
sudo pacstrap -G -M -d ${maindir}/root pacman coreutils libunistring archlinux-keyring sed gzip util-linux
|
||||
sudo bash -c "echo 'Server = $DEFAULT_MIRROR' >> ${maindir}/root/etc/pacman.d/mirrorlist"
|
||||
sudo mkdir -p ${maindir}/root/run/lock
|
||||
|
||||
|
|
@ -69,11 +69,11 @@ function build_image_env(){
|
|||
# sed command is required for locale-gen
|
||||
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/jchroot ${maindir}/root locale-gen
|
||||
sudo ${maindir}/root/opt/junest/bin/groot ${maindir}/root locale-gen
|
||||
sudo bash -c "echo LANG=\"en_US.UTF-8\" >> ${maindir}/root/etc/locale.conf"
|
||||
|
||||
info "Setting up the pacman keyring (this might take a while!)..."
|
||||
sudo ${maindir}/root/opt/junest/bin/jchroot ${maindir}/root bash -c \
|
||||
sudo ${maindir}/root/opt/junest/bin/groot ${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"
|
||||
|
||||
sudo rm ${maindir}/root/var/cache/pacman/pkg/*
|
||||
|
|
@ -88,7 +88,8 @@ function build_image_env(){
|
|||
then
|
||||
mkdir -p ${maindir}/root_test
|
||||
$TAR -zxpf ${imagefile} -C "${maindir}/root_test"
|
||||
check_env "${maindir}/root_test" "${maindir}/root_test/opt/${CMD}/bin/${CMD}" $skip_root_tests
|
||||
JUNEST_HOME="${maindir}/root_test" ${maindir}/root_test/opt/${CMD}/bin/${CMD} -f ./lib/checks/check.sh
|
||||
JUNEST_HOME="${maindir}/root_test" sudo -E ${maindir}/root_test/opt/${CMD}/bin/${CMD} -g ./lib/checks/check.sh --run-root-tests
|
||||
fi
|
||||
|
||||
sudo cp ${maindir}/output/${imagefile} ${ORIGIN_WD}
|
||||
|
|
@ -97,44 +98,3 @@ function build_image_env(){
|
|||
trap - QUIT EXIT ABRT KILL TERM INT
|
||||
sudo rm -fr "$maindir"
|
||||
}
|
||||
|
||||
function check_env(){
|
||||
local testdir=$1
|
||||
local cmd=$2
|
||||
local skip_root_tests=$3
|
||||
info "Validating ${NAME} located in ${testdir} using the ${cmd} script..."
|
||||
echo "Server = ${DEFAULT_MIRROR}" >> ${testdir}/etc/pacman.d/mirrorlist
|
||||
JUNEST_HOME=${testdir} ${cmd} -f pacman --noconfirm -Syy
|
||||
|
||||
# Check most basic executables work
|
||||
$skip_root_tests || JUNEST_HOME=${testdir} sudo -E ${cmd} -r pacman -Qi pacman 1> /dev/null
|
||||
JUNEST_HOME=${testdir} ${cmd} -- pacman -Qi pacman 1> /dev/null
|
||||
JUNEST_HOME=${testdir} ${cmd} -f -- pacman -Qi pacman 1> /dev/null
|
||||
$skip_root_tests || JUNEST_HOME=${testdir} sudo -E ${cmd} -r yogurt -V 1> /dev/null
|
||||
JUNEST_HOME=${testdir} ${cmd} -- yogurt -V 1> /dev/null
|
||||
JUNEST_HOME=${testdir} ${cmd} -f -- yogurt -V 1> /dev/null
|
||||
$skip_root_tests || JUNEST_HOME=${testdir} sudo -E ${cmd} -r /opt/proot/proot-$ARCH --help 1> /dev/null
|
||||
JUNEST_HOME=${testdir} ${cmd} -- /opt/proot/proot-$ARCH --help 1> /dev/null
|
||||
JUNEST_HOME=${testdir} ${cmd} -f -- /opt/proot/proot-$ARCH --help 1> /dev/null
|
||||
|
||||
local repo_package=tree
|
||||
info "Installing ${repo_package} package from official repo using proot..."
|
||||
JUNEST_HOME=${testdir} ${cmd} -f pacman --noconfirm -S ${repo_package}
|
||||
JUNEST_HOME=${testdir} ${cmd} tree
|
||||
JUNEST_HOME=${testdir} ${cmd} -f tree
|
||||
|
||||
local repo_package=iftop
|
||||
info "Installing ${repo_package} package from official repo using root..."
|
||||
JUNEST_HOME=${testdir} ${cmd} -f pacman --noconfirm -S ${repo_package}
|
||||
$skip_root_tests || JUNEST_HOME=${testdir} sudo -E ${cmd} -r iftop -t -s 5
|
||||
|
||||
JUNEST_HOME=${testdir} ${cmd} -f pacman --noconfirm -S base-devel
|
||||
local aur_package=tcptraceroute
|
||||
info "Installing ${aur_package} package from AUR repo using proot..."
|
||||
JUNEST_HOME=${testdir} ${cmd} -f -- yogurt -A --noconfirm -S ${aur_package}
|
||||
$skip_root_tests || JUNEST_HOME=${testdir} sudo -E ${cmd} -r tcptraceroute localhost
|
||||
|
||||
info "Removing the previous packages..."
|
||||
JUNEST_HOME=${testdir} ${cmd} -f pacman --noconfirm -Rsn tcptraceroute tree iftop
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,27 +8,12 @@
|
|||
#
|
||||
# vim: ft=sh
|
||||
|
||||
#######################################
|
||||
# Run JuNest as real root.
|
||||
#
|
||||
# Globals:
|
||||
# JUNEST_HOME (RO) : The JuNest home directory.
|
||||
# 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.
|
||||
# Arguments:
|
||||
# cmd ($@?) : The command to run inside JuNest environment.
|
||||
# Default command is defined by SH variable.
|
||||
# Returns:
|
||||
# $ARCHITECTURE_MISMATCH : If host and JuNest architecture are different.
|
||||
# Output:
|
||||
# - : The command output.
|
||||
#######################################
|
||||
function run_env_as_root(){
|
||||
source ${JUNEST_HOME}/etc/junest/info
|
||||
[ "$JUNEST_ARCH" != "$ARCH" ] && \
|
||||
die_on_status $ARCHITECTURE_MISMATCH "The host system architecture is not correct: $ARCH != $JUNEST_ARCH"
|
||||
function _run_env_as_xroot(){
|
||||
local cmd=$1
|
||||
local backend_args="$2"
|
||||
shift 2
|
||||
|
||||
check_same_arch
|
||||
|
||||
local uid=$UID
|
||||
# SUDO_USER is more reliable compared to SUDO_UID
|
||||
|
|
@ -41,5 +26,63 @@ function run_env_as_root(){
|
|||
trap - QUIT EXIT ABRT KILL TERM INT
|
||||
trap "[ -z $uid ] || chown_cmd -R ${uid} ${JUNEST_HOME};" EXIT QUIT ABRT KILL TERM INT
|
||||
|
||||
JUNEST_ENV=1 chroot_cmd "$JUNEST_HOME" "${SH[@]}" "-c" "${main_cmd}"
|
||||
copy_common_files
|
||||
|
||||
check_nested_env
|
||||
|
||||
JUNEST_ENV=1 $cmd $backend_args "$JUNEST_HOME" "${SH[@]}" "-c" "${main_cmd}"
|
||||
}
|
||||
|
||||
#######################################
|
||||
# Run JuNest as real root via GRoot command.
|
||||
#
|
||||
# Globals:
|
||||
# JUNEST_HOME (RO) : The JuNest home directory.
|
||||
# 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.
|
||||
# Arguments:
|
||||
# backend_args ($1) : The arguments to pass to proot
|
||||
# cmd ($2-?) : The command to run inside JuNest environment.
|
||||
# Default command is defined by SH variable.
|
||||
# Returns:
|
||||
# $ARCHITECTURE_MISMATCH : If host and JuNest architecture are different.
|
||||
# Output:
|
||||
# - : The command output.
|
||||
#######################################
|
||||
function run_env_as_groot(){
|
||||
local backend_args="$1"
|
||||
shift
|
||||
|
||||
provide_common_bindings
|
||||
local bindings=${RESULT}
|
||||
unset RESULT
|
||||
|
||||
_run_env_as_xroot "$GROOT $bindings" "$backend_args" "$@"
|
||||
}
|
||||
|
||||
#######################################
|
||||
# Run JuNest as real root via chroot command.
|
||||
#
|
||||
# Globals:
|
||||
# JUNEST_HOME (RO) : The JuNest home directory.
|
||||
# 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.
|
||||
# Arguments:
|
||||
# backend_args ($1) : The arguments to pass to proot
|
||||
# cmd ($2-?) : The command to run inside JuNest environment.
|
||||
# Default command is defined by SH variable.
|
||||
# Returns:
|
||||
# $ARCHITECTURE_MISMATCH : If host and JuNest architecture are different.
|
||||
# Output:
|
||||
# - : The command output.
|
||||
#######################################
|
||||
function run_env_as_chroot(){
|
||||
local backend_args="$1"
|
||||
shift
|
||||
|
||||
_run_env_as_xroot chroot_cmd "$backend_args" "$@"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@
|
|||
#
|
||||
# vim: ft=sh
|
||||
|
||||
set -e
|
||||
|
||||
NAME='JuNest'
|
||||
CMD='junest'
|
||||
DESCRIPTION='The Arch Linux based distro that runs upon any Linux distros without root access'
|
||||
|
|
@ -19,21 +17,11 @@ ARCHITECTURE_MISMATCH=104
|
|||
ROOT_ACCESS_ERROR=105
|
||||
NESTED_ENVIRONMENT=106
|
||||
VARIABLE_NOT_SET=107
|
||||
NO_CONFIG_FOUND=108
|
||||
|
||||
if [ "$JUNEST_ENV" == "1" ]
|
||||
then
|
||||
die_on_status $NESTED_ENVIRONMENT "Error: Nested ${NAME} environments are not allowed"
|
||||
elif [ ! -z $JUNEST_ENV ] && [ "$JUNEST_ENV" != "0" ]
|
||||
then
|
||||
die_on_status $VARIABLE_NOT_SET "The variable JUNEST_ENV is not properly set"
|
||||
fi
|
||||
|
||||
[ -z ${JUNEST_HOME} ] && JUNEST_HOME=~/.${CMD}
|
||||
[ -z ${JUNEST_BASE} ] && JUNEST_BASE=${JUNEST_HOME}/opt/junest
|
||||
if [ -z ${JUNEST_TEMPDIR} ] || [ ! -d ${JUNEST_TEMPDIR} ]
|
||||
then
|
||||
JUNEST_TEMPDIR=/tmp
|
||||
fi
|
||||
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
|
||||
# found on different locations
|
||||
|
|
@ -78,8 +66,8 @@ SH=("/bin/sh" "--login")
|
|||
|
||||
# List of executables that are run in the host OS:
|
||||
PROOT="${JUNEST_HOME}/opt/proot/proot-${ARCH}"
|
||||
CHROOT=${JUNEST_BASE}/bin/jchroot
|
||||
CLASSIC_CHROOT="chroot"
|
||||
GROOT=${JUNEST_BASE}/bin/groot
|
||||
CLASSIC_CHROOT=chroot
|
||||
WGET="wget --no-check-certificate"
|
||||
CURL="curl -L -J -O -k"
|
||||
TAR=tar
|
||||
|
|
@ -89,6 +77,9 @@ RM=rm
|
|||
MKDIR=mkdir
|
||||
GETENT=getent
|
||||
CP=cp
|
||||
# Used for checking user namespace in config.gz file
|
||||
ZGREP=zgrep
|
||||
UNSHARE=unshare
|
||||
|
||||
LD_EXEC="$LD_LIB --library-path ${JUNEST_HOME}/usr/lib:${JUNEST_HOME}/lib"
|
||||
|
||||
|
|
@ -97,27 +88,58 @@ 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 "$@"
|
||||
}
|
||||
|
||||
function download_cmd(){
|
||||
$WGET "$@" || $CURL "$@"
|
||||
}
|
||||
|
||||
function chroot_cmd(){
|
||||
$CLASSIC_CHROOT "$@" || $LD_EXEC ${JUNEST_HOME}/usr/bin/$CLASSIC_CHROOT "$@"
|
||||
}
|
||||
|
||||
function unshare_cmd(){
|
||||
# Most of the distros do not have the `unshare` command updated
|
||||
# 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
|
||||
# they are not supported by dash.
|
||||
if $LD_EXEC ${JUNEST_HOME}/usr/bin/$UNSHARE --user "${SH[0]}" "-c" ":"
|
||||
then
|
||||
$LD_EXEC ${JUNEST_HOME}/usr/bin/$UNSHARE "${@}"
|
||||
elif $UNSHARE --user "${SH[0]}" "-c" ":"
|
||||
then
|
||||
$UNSHARE "$@"
|
||||
else
|
||||
die "Error: Something went wrong with unshare command. Exiting"
|
||||
fi
|
||||
}
|
||||
|
||||
function proot_cmd(){
|
||||
|
|
@ -130,20 +152,60 @@ function proot_cmd(){
|
|||
then
|
||||
PROOT_NO_SECCOMP=1 ${PROOT} ${proot_args} "${@}"
|
||||
else
|
||||
die "Error: Check if the ${CMD} arguments are correct and if the kernel is too old use the option ${CMD} -p \"-k 3.10\""
|
||||
die "Error: Something went wrong with proot command. Exiting"
|
||||
fi
|
||||
}
|
||||
|
||||
function download_cmd(){
|
||||
$WGET $@ || $CURL $@
|
||||
}
|
||||
|
||||
function chroot_cmd(){
|
||||
$CHROOT "$@" || $CLASSIC_CHROOT "$@" || $LD_EXEC ${JUNEST_HOME}/usr/bin/chroot "$@"
|
||||
}
|
||||
|
||||
############## COMMON FUNCTIONS ###############
|
||||
|
||||
#######################################
|
||||
# Check if the executable is being running inside a JuNest environment.
|
||||
#
|
||||
# Globals:
|
||||
# JUNEST_ENV (RO) : The boolean junest env check
|
||||
# NESTED_ENVIRONMENT (RO) : The nest env exception
|
||||
# VARIABLE_NOT_SET (RO) : The var not set exception
|
||||
# NAME (RO) : The JuNest name
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# VARIABLE_NOT_SET : If no JUNEST_ENV is not properly set
|
||||
# NESTED_ENVIRONMENT : If the script is executed inside JuNest env
|
||||
# Output:
|
||||
# None
|
||||
#######################################
|
||||
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" ]]
|
||||
then
|
||||
die_on_status $VARIABLE_NOT_SET "The variable JUNEST_ENV is not properly set"
|
||||
fi
|
||||
}
|
||||
|
||||
#######################################
|
||||
# Check if the architecture between Host OS and Guest OS is the same.
|
||||
#
|
||||
# Globals:
|
||||
# JUNEST_HOME (RO) : The JuNest home path.
|
||||
# ARCHITECTURE_MISMATCH (RO) : The arch mismatch exception
|
||||
# ARCH (RO) : The host OS arch
|
||||
# JUNEST_ARCH (RO) : The JuNest arch
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# ARCHITECTURE_MISMATCH : If arch between host and guest is not the same
|
||||
# Output:
|
||||
# None
|
||||
#######################################
|
||||
function check_same_arch() {
|
||||
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
|
||||
}
|
||||
|
||||
#######################################
|
||||
# Provide the proot common binding options for both normal user and fakeroot.
|
||||
# The list of bindings can be found in `proot --help`. This function excludes
|
||||
|
|
@ -160,7 +222,7 @@ function chroot_cmd(){
|
|||
# Output:
|
||||
# None
|
||||
#######################################
|
||||
function _provide_common_bindings(){
|
||||
function provide_common_bindings(){
|
||||
RESULT=""
|
||||
local re='(.*):.*'
|
||||
for bind in "/dev" "/sys" "/proc" "/tmp" "$HOME"
|
||||
|
|
@ -191,7 +253,7 @@ function _provide_common_bindings(){
|
|||
# Output:
|
||||
# None
|
||||
#######################################
|
||||
function _copy_passwd_and_group(){
|
||||
function copy_passwd_and_group(){
|
||||
# Enumeration of users/groups is disabled/limited depending on how nsswitch.conf
|
||||
# is configured.
|
||||
# Try to at least get the current user via `getent passwd $USER` since it uses
|
||||
|
|
@ -200,27 +262,27 @@ 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 ${JUNEST_HOME}/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 ${JUNEST_HOME}/etc/group
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
function _copy_file() {
|
||||
function copy_file() {
|
||||
local file="${1}"
|
||||
[[ -r "$file" ]] && cp_cmd "$file" "${JUNEST_HOME}/$file"
|
||||
return 0
|
||||
}
|
||||
|
||||
function _copy_common_files() {
|
||||
_copy_file /etc/host.conf
|
||||
_copy_file /etc/hosts
|
||||
_copy_file /etc/nsswitch.conf
|
||||
_copy_file /etc/resolv.conf
|
||||
function copy_common_files() {
|
||||
copy_file /etc/host.conf
|
||||
copy_file /etc/hosts
|
||||
copy_file /etc/nsswitch.conf
|
||||
copy_file /etc/resolv.conf
|
||||
return 0
|
||||
}
|
||||
|
|
|
|||
100
lib/core/namespace.sh
Normal file
100
lib/core/namespace.sh
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# This module contains all namespace functionalities for JuNest.
|
||||
#
|
||||
# http://man7.org/linux/man-pages/man7/namespaces.7.html
|
||||
# http://man7.org/linux/man-pages/man2/unshare.2.html
|
||||
#
|
||||
# Dependencies:
|
||||
# - lib/utils/utils.sh
|
||||
# - lib/core/common.sh
|
||||
#
|
||||
# vim: ft=sh
|
||||
|
||||
CONFIG_PROC_FILE="/proc/config.gz"
|
||||
CONFIG_BOOT_FILE="/boot/config-$($UNAME -r)"
|
||||
|
||||
function _is_user_namespace_enabled() {
|
||||
local config_file=""
|
||||
if [[ -e $CONFIG_PROC_FILE ]]
|
||||
then
|
||||
config_file=$CONFIG_PROC_FILE
|
||||
elif [[ -e $CONFIG_BOOT_FILE ]]
|
||||
then
|
||||
config_file=$CONFIG_BOOT_FILE
|
||||
else
|
||||
return $NOT_EXISTING_FILE
|
||||
fi
|
||||
|
||||
if ! zgrep_cmd -q "CONFIG_USER_NS=y" $config_file
|
||||
then
|
||||
return $NO_CONFIG_FOUND
|
||||
fi
|
||||
}
|
||||
|
||||
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 "User namespace is not enabled or Kernel too old (<3.8). Proceeding anyway..." ;;
|
||||
esac
|
||||
set -e
|
||||
}
|
||||
|
||||
function _run_env_with_namespace(){
|
||||
local backend_args="$1"
|
||||
shift
|
||||
|
||||
check_nested_env
|
||||
|
||||
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 -n $bindings $backend_args "$JUNEST_HOME" "${SH[@]}" "-c" "$(insert_quotes_on_spaces "${@}")"
|
||||
else
|
||||
JUNEST_ENV=1 unshare_cmd --mount --user --map-root-user $GROOT -n $bindings $backend_args "$JUNEST_HOME" "${SH[@]}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#######################################
|
||||
# Run JuNest as fakeroot user via user namespace.
|
||||
#
|
||||
# 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 proot
|
||||
# cmd ($2-?) : 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() {
|
||||
local backend_args="$1"
|
||||
shift
|
||||
_check_user_namespace
|
||||
|
||||
check_same_arch
|
||||
|
||||
copy_common_files
|
||||
copy_file /etc/hosts.equiv
|
||||
copy_file /etc/netgroup
|
||||
copy_file /etc/networks
|
||||
# No need for localtime as it is setup during the image build
|
||||
#copy_file /etc/localtime
|
||||
copy_passwd_and_group
|
||||
|
||||
_run_env_with_namespace "$backend_args" "$@"
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ function _run_env_with_proot(){
|
|||
local proot_args="$1"
|
||||
shift
|
||||
|
||||
check_nested_env
|
||||
if [ "$1" != "" ]
|
||||
then
|
||||
JUNEST_ENV=1 proot_cmd "${proot_args}" "${SH[@]}" "-c" "$(insert_quotes_on_spaces "${@}")"
|
||||
|
|
@ -44,30 +45,33 @@ function _run_env_with_qemu(){
|
|||
# Run JuNest as fakeroot.
|
||||
#
|
||||
# Globals:
|
||||
# JUNEST_HOME (RO) : The JuNest home directory.
|
||||
# EUID (RO) : The user ID.
|
||||
# SH (RO) : Contains the default command to run in JuNest.
|
||||
# JUNEST_HOME (RO) : The JuNest home directory.
|
||||
# EUID (RO) : The user ID.
|
||||
# SH (RO) : Contains the default command to run in JuNest.
|
||||
# Arguments:
|
||||
# cmd ($@?) : The command to run inside JuNest environment.
|
||||
# backend_args ($1) : The arguments to pass to proot
|
||||
# cmd ($2-?) : The command to run inside JuNest environment.
|
||||
# Default command is defined by SH variable.
|
||||
# Returns:
|
||||
# $ROOT_ACCESS_ERROR : If the user is the real root.
|
||||
# $ROOT_ACCESS_ERROR : If the user is the real root.
|
||||
# Output:
|
||||
# - : The command output.
|
||||
# - : The command output.
|
||||
#######################################
|
||||
function run_env_as_fakeroot(){
|
||||
(( EUID == 0 )) && \
|
||||
die_on_status $ROOT_ACCESS_ERROR "You cannot access with root privileges. Use --root option instead."
|
||||
die_on_status $ROOT_ACCESS_ERROR "You cannot access with root privileges. Use --groot option instead."
|
||||
local backend_args="$1"
|
||||
shift
|
||||
|
||||
_copy_common_files
|
||||
copy_common_files
|
||||
|
||||
_provide_common_bindings
|
||||
provide_common_bindings
|
||||
local bindings=${RESULT}
|
||||
unset RESULT
|
||||
|
||||
# An alternative is via -S option:
|
||||
#_run_env_with_qemu "-S ${JUNEST_HOME} $1" "${@:2}"
|
||||
_run_env_with_qemu "-0 ${bindings} -r ${JUNEST_HOME} $1" "${@:2}"
|
||||
_run_env_with_qemu "-0 ${bindings} -r ${JUNEST_HOME} $backend_args" "$@"
|
||||
}
|
||||
|
||||
#######################################
|
||||
|
|
@ -78,7 +82,8 @@ function run_env_as_fakeroot(){
|
|||
# EUID (RO) : The user ID.
|
||||
# SH (RO) : Contains the default command to run in JuNest.
|
||||
# Arguments:
|
||||
# cmd ($@?) : The command to run inside JuNest environment.
|
||||
# backend_args ($1) : The arguments to pass to proot
|
||||
# cmd ($2-?) : The command to run inside JuNest environment.
|
||||
# Default command is defined by SH variable.
|
||||
# Returns:
|
||||
# $ROOT_ACCESS_ERROR : If the user is the real root.
|
||||
|
|
@ -87,23 +92,25 @@ function run_env_as_fakeroot(){
|
|||
#######################################
|
||||
function run_env_as_user(){
|
||||
(( EUID == 0 )) && \
|
||||
die_on_status $ROOT_ACCESS_ERROR "You cannot access with root privileges. Use --root option instead."
|
||||
die_on_status $ROOT_ACCESS_ERROR "You cannot access with root privileges. Use --groot option instead."
|
||||
local backend_args="$1"
|
||||
shift
|
||||
|
||||
# Files to bind are visible in `proot --help`.
|
||||
# This function excludes /etc/mtab file so that
|
||||
# it will not give conflicts with the related
|
||||
# symlink in the Arch Linux image.
|
||||
_copy_common_files
|
||||
_copy_file /etc/hosts.equiv
|
||||
_copy_file /etc/netgroup
|
||||
_copy_file /etc/networks
|
||||
copy_common_files
|
||||
copy_file /etc/hosts.equiv
|
||||
copy_file /etc/netgroup
|
||||
copy_file /etc/networks
|
||||
# No need for localtime as it is setup during the image build
|
||||
#_copy_file /etc/localtime
|
||||
_copy_passwd_and_group
|
||||
#copy_file /etc/localtime
|
||||
copy_passwd_and_group
|
||||
|
||||
_provide_common_bindings
|
||||
provide_common_bindings
|
||||
local bindings=${RESULT}
|
||||
unset RESULT
|
||||
|
||||
_run_env_with_qemu "${bindings} -r ${JUNEST_HOME} $1" "${@:2}"
|
||||
_run_env_with_qemu "${bindings} -r ${JUNEST_HOME} $backend_args" "$@"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,6 +170,20 @@ 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
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ function oneTimeSetUp(){
|
|||
function setUp(){
|
||||
cwdSetUp
|
||||
junestSetUp
|
||||
init_mocks
|
||||
}
|
||||
|
||||
function tearDown(){
|
||||
|
|
@ -25,28 +26,42 @@ function tearDown(){
|
|||
cwdTearDown
|
||||
}
|
||||
|
||||
function test_run_env_as_root_different_arch(){
|
||||
echo "JUNEST_ARCH=XXX" > ${JUNEST_HOME}/etc/junest/info
|
||||
assertCommandFailOnStatus 104 run_env_as_root pwd
|
||||
}
|
||||
|
||||
function _test_run_env_as_root() {
|
||||
function init_mocks() {
|
||||
chroot_cmd() {
|
||||
[ "$JUNEST_ENV" != "1" ] && return 1
|
||||
echo $@
|
||||
echo "chroot_cmd $@"
|
||||
}
|
||||
|
||||
assertCommandSuccess run_env_as_root $@
|
||||
GROOT=chroot_cmd
|
||||
}
|
||||
|
||||
function test_run_env_as_root_cmd(){
|
||||
_test_run_env_as_root pwd
|
||||
assertEquals "$JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)"
|
||||
function test_run_env_as_groot_cmd(){
|
||||
assertCommandSuccess run_env_as_groot "" 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_classic_root_no_cmd(){
|
||||
_test_run_env_as_root
|
||||
assertEquals "$JUNEST_HOME /bin/sh --login -c /bin/sh --login" "$(cat $STDOUTF)"
|
||||
function test_run_env_as_groot_no_cmd(){
|
||||
assertCommandSuccess run_env_as_groot ""
|
||||
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_cmd_with_backend_args(){
|
||||
assertCommandSuccess run_env_as_groot "-n -b /home/blah" 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 "" 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 ""
|
||||
assertEquals "chroot_cmd $JUNEST_HOME /bin/sh --login -c /bin/sh --login" "$(cat $STDOUTF)"
|
||||
}
|
||||
|
||||
function test_run_env_as_chroot_cmd_with_backend_args(){
|
||||
assertCommandSuccess run_env_as_chroot "-n -b /home/blah" pwd
|
||||
assertEquals "chroot_cmd -n -b /home/blah $JUNEST_HOME /bin/sh --login -c pwd" "$(cat $STDOUTF)"
|
||||
}
|
||||
|
||||
source $JUNEST_ROOT/tests/utils/shunit2
|
||||
|
|
|
|||
|
|
@ -1,181 +0,0 @@
|
|||
#!/bin/bash
|
||||
source "$(dirname $0)/../utils/utils.sh"
|
||||
|
||||
source $(dirname $0)/../../bin/junest -h &> /dev/null
|
||||
|
||||
# Disable the exiterr
|
||||
set +e
|
||||
|
||||
function oneTimeSetUp(){
|
||||
setUpUnitTests
|
||||
}
|
||||
|
||||
function setUp(){
|
||||
function is_env_installed(){
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
## Mock functions ##
|
||||
function usage(){
|
||||
echo "usage"
|
||||
}
|
||||
function version(){
|
||||
echo "version"
|
||||
}
|
||||
function build_image_env(){
|
||||
local disable_validation=$1
|
||||
local skip_root_tests=$2
|
||||
echo "build_image_env($disable_validation,$skip_root_tests)"
|
||||
}
|
||||
function check_env(){
|
||||
local env_home=$1
|
||||
local cmd_script=$2
|
||||
local skip_root_tests=$3
|
||||
echo "check_env($env_home,$cmd_script,$skip_root_tests)"
|
||||
}
|
||||
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_fakeroot(){
|
||||
local proot_args="$1"
|
||||
shift
|
||||
echo "run_env_as_fakeroot($proot_args,$@)"
|
||||
}
|
||||
function run_env_as_root(){
|
||||
echo "run_env_as_root $@"
|
||||
}
|
||||
function run_env_as_user(){
|
||||
local proot_args="$1"
|
||||
shift
|
||||
echo "run_env_as_user($proot_args,$@)"
|
||||
}
|
||||
|
||||
function test_help(){
|
||||
assertCommandSuccess cli -h
|
||||
assertEquals "usage" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli --help
|
||||
assertEquals "usage" "$(cat $STDOUTF)"
|
||||
}
|
||||
function test_version(){
|
||||
assertCommandSuccess cli -v
|
||||
assertEquals "version" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli --version
|
||||
assertEquals "version" "$(cat $STDOUTF)"
|
||||
}
|
||||
function test_build_image_env(){
|
||||
assertCommandSuccess cli -b
|
||||
assertEquals "build_image_env(false,false)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli --build-image
|
||||
assertEquals "build_image_env(false,false)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli -b -s
|
||||
assertEquals "build_image_env(false,true)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli -b -n
|
||||
assertEquals "build_image_env(true,false)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli -b -n -s
|
||||
assertEquals "build_image_env(true,true)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli --build-image --disable-validation --skip-root-tests
|
||||
assertEquals "build_image_env(true,true)" "$(cat $STDOUTF)"
|
||||
}
|
||||
function test_check_env(){
|
||||
assertCommandSuccess cli -c myscript
|
||||
assertEquals "check_env(${JUNEST_HOME},myscript,false)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli --check myscript
|
||||
assertEquals "check_env(${JUNEST_HOME},myscript,false)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli -c myscript -s
|
||||
assertEquals "check_env(${JUNEST_HOME},myscript,true)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli --check myscript --skip-root-tests
|
||||
assertEquals "check_env(${JUNEST_HOME},myscript,true)" "$(cat $STDOUTF)"
|
||||
}
|
||||
function test_delete_env(){
|
||||
assertCommandSuccess cli -d
|
||||
assertEquals "delete_env" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli --delete
|
||||
assertEquals "delete_env" "$(cat $STDOUTF)"
|
||||
}
|
||||
function test_setup_env_from_file(){
|
||||
is_env_installed(){
|
||||
return 1
|
||||
}
|
||||
assertCommandSuccess cli -i myimage
|
||||
assertEquals "$(echo -e "setup_env_from_file(myimage)\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli --setup-from-file myimage
|
||||
assertEquals "$(echo -e "setup_env_from_file(myimage)\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
|
||||
|
||||
is_env_installed(){
|
||||
return 0
|
||||
}
|
||||
assertCommandFail cli -i myimage
|
||||
}
|
||||
|
||||
function test_setup_env(){
|
||||
is_env_installed(){
|
||||
return 1
|
||||
}
|
||||
assertCommandSuccess cli -a arm
|
||||
assertEquals "$(echo -e "setup_env(arm)\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli --arch arm
|
||||
assertEquals "$(echo -e "setup_env(arm)\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli
|
||||
assertEquals "$(echo -e "setup_env()\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
|
||||
|
||||
is_env_installed(){
|
||||
return 0
|
||||
}
|
||||
assertCommandFail cli -a arm
|
||||
}
|
||||
function test_run_env_as_fakeroot(){
|
||||
assertCommandSuccess cli -f
|
||||
assertEquals "run_env_as_fakeroot(,)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli --fakeroot
|
||||
assertEquals "run_env_as_fakeroot(,)" "$(cat $STDOUTF)"
|
||||
|
||||
assertCommandSuccess cli -f -p "-b arg"
|
||||
assertEquals "run_env_as_fakeroot(-b arg,)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli -f -p "-b arg" -- command -kv
|
||||
assertEquals "run_env_as_fakeroot(-b arg,command -kv)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli -f command --as
|
||||
assertEquals "run_env_as_fakeroot(,command --as)" "$(cat $STDOUTF)"
|
||||
assertCommandFail cli -a "myarch" -f command --as
|
||||
}
|
||||
function test_run_env_as_user(){
|
||||
assertCommandSuccess cli
|
||||
assertEquals "run_env_as_user(,)" "$(cat $STDOUTF)"
|
||||
|
||||
assertCommandSuccess cli -p "-b arg"
|
||||
assertEquals "run_env_as_user(-b arg,)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli -p "-b arg" -- command -ll
|
||||
assertEquals "run_env_as_user(-b arg,command -ll)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli command -ls
|
||||
assertEquals "run_env_as_user(,command -ls)" "$(cat $STDOUTF)"
|
||||
|
||||
assertCommandFail cli -a "myarch" -- command -ls
|
||||
}
|
||||
function test_run_env_as_root(){
|
||||
assertCommandSuccess cli -r
|
||||
assertEquals "run_env_as_root " "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli -r command
|
||||
assertEquals "run_env_as_root command" "$(cat $STDOUTF)"
|
||||
}
|
||||
|
||||
function test_check_cli(){
|
||||
assertCommandFail cli -b -h
|
||||
assertCommandFail cli -b -c
|
||||
assertCommandFail cli -d -s
|
||||
assertCommandFail cli -n -v
|
||||
assertCommandFail cli -d -r
|
||||
assertCommandFail cli -h -f
|
||||
assertCommandFail cli -v -i fsd
|
||||
assertCommandFail cli -f -r
|
||||
assertCommandFail cli -p args -v
|
||||
assertCommandFail cli -a arch -v
|
||||
assertCommandFail cli -d args
|
||||
}
|
||||
|
||||
source $(dirname $0)/../utils/shunit2
|
||||
|
|
@ -20,10 +20,20 @@ function oneTimeTearDown(){
|
|||
}
|
||||
|
||||
function setUp(){
|
||||
ld_exec() {
|
||||
ld_exec_mock() {
|
||||
echo "ld_exec $@"
|
||||
}
|
||||
LD_EXEC=ld_exec
|
||||
ld_exec_mock_false() {
|
||||
echo "ld_exec $@"
|
||||
return 1
|
||||
}
|
||||
LD_EXEC=ld_exec_mock
|
||||
|
||||
unshare_mock() {
|
||||
echo "unshare $@"
|
||||
}
|
||||
UNSHARE=unshare_mock
|
||||
|
||||
}
|
||||
|
||||
function test_ln(){
|
||||
|
|
@ -100,17 +110,40 @@ function test_mkdir(){
|
|||
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)"
|
||||
|
||||
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
|
||||
ZGREP=false assertCommandSuccess zgrep_cmd new_file
|
||||
assertEquals "zgrep" "$(cat $STDOUTF)"
|
||||
|
||||
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)"
|
||||
|
||||
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)"
|
||||
|
||||
UNSHARE=false LD_EXEC=false assertCommandFail unshare_cmd new_program
|
||||
}
|
||||
|
||||
function test_chroot(){
|
||||
CHROOT=echo assertCommandSuccess chroot_cmd root
|
||||
CLASSIC_CHROOT=echo assertCommandSuccess chroot_cmd root
|
||||
assertEquals "root" "$(cat $STDOUTF)"
|
||||
|
||||
CHROOT=false 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)"
|
||||
|
||||
CHROOT=false CLASSIC_CHROOT=false assertCommandSuccess chroot_cmd root
|
||||
assertEquals "ld_exec $JUNEST_HOME/usr/bin/chroot root" "$(cat $STDOUTF)"
|
||||
|
||||
CHROOT=false CLASSIC_CHROOT=false LD_EXEC=false assertCommandFail chroot_cmd root
|
||||
CLASSIC_CHROOT=false LD_EXEC=false assertCommandFail chroot_cmd root
|
||||
}
|
||||
|
||||
function test_proot_cmd_compat(){
|
||||
|
|
@ -143,7 +176,7 @@ function test_copy_passwd_and_group(){
|
|||
getent_cmd_mock() {
|
||||
echo $@
|
||||
}
|
||||
GETENT=getent_cmd_mock assertCommandSuccess _copy_passwd_and_group
|
||||
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)"
|
||||
}
|
||||
|
|
@ -152,20 +185,31 @@ function test_copy_passwd_and_group_fallback(){
|
|||
cp_cmd_mock() {
|
||||
echo $@
|
||||
}
|
||||
CP=cp_cmd_mock GETENT=false LD_EXEC=false assertCommandSuccess _copy_passwd_and_group
|
||||
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)"
|
||||
}
|
||||
|
||||
function test_copy_passwd_and_group_failure(){
|
||||
CP=false GETENT=false LD_EXEC=false assertCommandFailOnStatus 1 _copy_passwd_and_group
|
||||
CP=false GETENT=false LD_EXEC=false assertCommandFailOnStatus 1 copy_passwd_and_group
|
||||
}
|
||||
|
||||
function test_nested_env(){
|
||||
JUNEST_ENV=1 assertCommandFailOnStatus 106 bash -c "source $JUNEST_ROOT/lib/utils/utils.sh; source $JUNEST_ROOT/lib/core/common.sh"
|
||||
JUNEST_ENV=1 assertCommandFailOnStatus 106 check_nested_env
|
||||
}
|
||||
|
||||
function test_nested_env_not_set_variable(){
|
||||
JUNEST_ENV=aaa assertCommandFailOnStatus 107 bash -c "source $JUNEST_ROOT/lib/utils/utils.sh; source $JUNEST_ROOT/lib/core/common.sh"
|
||||
JUNEST_ENV=aaa assertCommandFailOnStatus 107 check_nested_env
|
||||
}
|
||||
|
||||
function test_check_same_arch_not_same(){
|
||||
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
|
||||
assertCommandSuccess check_same_arch
|
||||
}
|
||||
|
||||
|
||||
source $JUNEST_ROOT/tests/utils/shunit2
|
||||
|
|
|
|||
161
tests/unit-tests/test-groot.sh
Executable file
161
tests/unit-tests/test-groot.sh
Executable file
|
|
@ -0,0 +1,161 @@
|
|||
#!/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 mount() {
|
||||
echo "mount($@)"
|
||||
}
|
||||
function umount() {
|
||||
echo "umount($@)"
|
||||
}
|
||||
function check_and_trap() {
|
||||
echo "check_and_trap($@)"
|
||||
}
|
||||
}
|
||||
|
||||
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(){
|
||||
mountpoint_mock() {
|
||||
echo "mountpoint($@)"
|
||||
}
|
||||
MOUNTPOINT=mountpoint_mock
|
||||
assertCommandSuccess main chrootdir
|
||||
assertEquals "$(echo -e "check_and_trap(chroot_teardown QUIT EXIT ABRT KILL TERM INT)\nmountpoint(-q chrootdir)\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)\nmountpoint(-q chrootdir)\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)\nmountpoint(-q chrootdir)\nmount(--bind chrootdir chrootdir)\nmount(--rbind /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)\nmountpoint(-q chrootdir)\nmount(--bind chrootdir chrootdir)\nmount(--rbind ${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)\nmountpoint(-q chrootdir)\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)\nmountpoint(-q chrootdir)\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)\nmountpoint(-q chrootdir)\nmount(--bind chrootdir chrootdir)\nmount(--rbind /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)\nmountpoint(-q chrootdir)\nmount(--bind chrootdir chrootdir)\nmount(--rbind /tmp chrootdir/home/tmp)\nmount(--rbind /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)\nmountpoint(-q chrootdir)\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)\nmountpoint(-q chrootdir)\nmount(--bind chrootdir chrootdir)\nmount(--rbind /tmp chrootdir/home/tmp)\nmount(--rbind /dev chrootdir/dev)\nchroot(chrootdir ls -la -h)")" "$(cat $STDOUTF)"
|
||||
}
|
||||
function test_groot_with_bind_no_umount(){
|
||||
assertCommandSuccess main -n chrootdir
|
||||
assertEquals "$(echo -e "mountpoint(-q chrootdir)\nmount(--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_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)"
|
||||
}
|
||||
|
||||
source $(dirname $0)/../utils/shunit2
|
||||
189
tests/unit-tests/test-junest.sh
Executable file
189
tests/unit-tests/test-junest.sh
Executable file
|
|
@ -0,0 +1,189 @@
|
|||
#!/bin/bash
|
||||
source "$(dirname $0)/../utils/utils.sh"
|
||||
|
||||
JUNEST_BASE="$(dirname $0)/../.."
|
||||
source $JUNEST_BASE/bin/junest -h &> /dev/null
|
||||
|
||||
# Disable the exiterr
|
||||
set +e
|
||||
|
||||
function oneTimeSetUp(){
|
||||
setUpUnitTests
|
||||
}
|
||||
|
||||
function setUp(){
|
||||
function is_env_installed(){
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
## Mock functions ##
|
||||
function usage(){
|
||||
echo "usage"
|
||||
}
|
||||
function version(){
|
||||
echo "version"
|
||||
}
|
||||
function build_image_env(){
|
||||
local disable_validation=$1
|
||||
echo "build_image_env($disable_validation)"
|
||||
}
|
||||
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_fakeroot(){
|
||||
local backend_args="$1"
|
||||
shift
|
||||
echo "run_env_as_fakeroot($backend_args,$@)"
|
||||
}
|
||||
function run_env_as_groot(){
|
||||
echo "run_env_as_groot $@"
|
||||
}
|
||||
function run_env_as_chroot(){
|
||||
echo "run_env_as_chroot $@"
|
||||
}
|
||||
function run_env_as_user(){
|
||||
local backend_args="$1"
|
||||
shift
|
||||
echo "run_env_as_user($backend_args,$@)"
|
||||
}
|
||||
function run_env_with_namespace(){
|
||||
local backend_args="$1"
|
||||
shift
|
||||
echo "run_env_with_namespace($backend_args,$@)"
|
||||
}
|
||||
|
||||
function test_help(){
|
||||
assertCommandSuccess main -h
|
||||
assertEquals "usage" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main --help
|
||||
assertEquals "usage" "$(cat $STDOUTF)"
|
||||
}
|
||||
function test_version(){
|
||||
assertCommandSuccess main -V
|
||||
assertEquals "version" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main --version
|
||||
assertEquals "version" "$(cat $STDOUTF)"
|
||||
}
|
||||
function test_build_image_env(){
|
||||
assertCommandSuccess main -b
|
||||
assertEquals "build_image_env(false)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main --build-image
|
||||
assertEquals "build_image_env(false)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main -b -n
|
||||
assertEquals "build_image_env(true)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main --build-image --disable-validation
|
||||
assertEquals "build_image_env(true)" "$(cat $STDOUTF)"
|
||||
}
|
||||
function test_delete_env(){
|
||||
assertCommandSuccess main -d
|
||||
assertEquals "delete_env" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main --delete
|
||||
assertEquals "delete_env" "$(cat $STDOUTF)"
|
||||
}
|
||||
function test_setup_env_from_file(){
|
||||
is_env_installed(){
|
||||
return 1
|
||||
}
|
||||
assertCommandSuccess main -i myimage
|
||||
assertEquals "$(echo -e "setup_env_from_file(myimage)\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main --setup-from-file myimage
|
||||
assertEquals "$(echo -e "setup_env_from_file(myimage)\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
|
||||
|
||||
is_env_installed(){
|
||||
return 0
|
||||
}
|
||||
assertCommandFail main -i myimage
|
||||
}
|
||||
|
||||
function test_setup_env(){
|
||||
is_env_installed(){
|
||||
return 1
|
||||
}
|
||||
assertCommandSuccess main -a arm
|
||||
assertEquals "$(echo -e "setup_env(arm)\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main --arch arm
|
||||
assertEquals "$(echo -e "setup_env(arm)\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main
|
||||
assertEquals "$(echo -e "setup_env()\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
|
||||
|
||||
is_env_installed(){
|
||||
return 0
|
||||
}
|
||||
assertCommandFail main -a arm
|
||||
}
|
||||
function test_run_env_as_fakeroot(){
|
||||
assertCommandSuccess main -f
|
||||
assertEquals "run_env_as_fakeroot(,)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main --fakeroot
|
||||
assertEquals "run_env_as_fakeroot(,)" "$(cat $STDOUTF)"
|
||||
|
||||
assertCommandSuccess main -f -p "-b arg"
|
||||
assertEquals "run_env_as_fakeroot(-b arg,)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main -f -p "-b arg" -- command -kv
|
||||
assertEquals "run_env_as_fakeroot(-b arg,command -kv)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main -f command --as
|
||||
assertEquals "run_env_as_fakeroot(,command --as)" "$(cat $STDOUTF)"
|
||||
assertCommandFail main -a "myarch" -f command --as
|
||||
}
|
||||
function test_run_env_as_user(){
|
||||
assertCommandSuccess main
|
||||
assertEquals "run_env_as_user(,)" "$(cat $STDOUTF)"
|
||||
|
||||
assertCommandSuccess main -p "-b arg"
|
||||
assertEquals "run_env_as_user(-b arg,)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main -p "-b arg" -- command -ll
|
||||
assertEquals "run_env_as_user(-b arg,command -ll)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main command -ls
|
||||
assertEquals "run_env_as_user(,command -ls)" "$(cat $STDOUTF)"
|
||||
|
||||
assertCommandFail main -a "myarch" -- command -ls
|
||||
}
|
||||
function test_run_env_as_groot(){
|
||||
assertCommandSuccess main -g
|
||||
assertEquals "run_env_as_groot " "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main -g command
|
||||
assertEquals "run_env_as_groot command" "$(cat $STDOUTF)"
|
||||
}
|
||||
function test_run_env_as_chroot(){
|
||||
assertCommandSuccess main -r
|
||||
assertEquals "run_env_as_chroot " "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main -r command
|
||||
assertEquals "run_env_as_chroot command" "$(cat $STDOUTF)"
|
||||
}
|
||||
|
||||
function test_run_env_with_namespace(){
|
||||
assertCommandSuccess main -u -f
|
||||
assertEquals "run_env_with_namespace(,)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main --namespace --fakeroot
|
||||
assertEquals "run_env_with_namespace(,)" "$(cat $STDOUTF)"
|
||||
|
||||
assertCommandSuccess main -u -f -p "-b arg"
|
||||
assertEquals "run_env_with_namespace(-b arg,)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main -u -f -p "-b arg" -- command -kv
|
||||
assertEquals "run_env_with_namespace(-b arg,command -kv)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess main -u -f command --as
|
||||
assertEquals "run_env_with_namespace(,command --as)" "$(cat $STDOUTF)"
|
||||
}
|
||||
|
||||
function test_check_cli(){
|
||||
assertCommandFail main -b -h
|
||||
assertCommandFail main -b -c
|
||||
assertCommandFail main -d -s
|
||||
assertCommandFail main -n -v
|
||||
assertCommandFail main -d -r
|
||||
assertCommandFail main -h -f
|
||||
assertCommandFail main -v -i fsd
|
||||
assertCommandFail main -f -r
|
||||
assertCommandFail main -p args -v
|
||||
assertCommandFail main -a arch -v
|
||||
assertCommandFail main -d args
|
||||
}
|
||||
|
||||
source $(dirname $0)/../utils/shunit2
|
||||
113
tests/unit-tests/test-namespace.sh
Executable file
113
tests/unit-tests/test-namespace.sh
Executable file
|
|
@ -0,0 +1,113 @@
|
|||
#!/bin/bash
|
||||
|
||||
JUNEST_ROOT=$(readlink -f $(dirname $0)/../..)
|
||||
|
||||
source "$JUNEST_ROOT/tests/utils/utils.sh"
|
||||
|
||||
source "$JUNEST_ROOT/lib/utils/utils.sh"
|
||||
|
||||
# Disable the exiterr
|
||||
set +e
|
||||
|
||||
function oneTimeSetUp(){
|
||||
setUpUnitTests
|
||||
}
|
||||
|
||||
## Mock functions ##
|
||||
function init_mocks() {
|
||||
function unshare_cmd(){
|
||||
echo "unshare $@"
|
||||
}
|
||||
}
|
||||
|
||||
function setUp(){
|
||||
cwdSetUp
|
||||
junestSetUp
|
||||
|
||||
# Attempt to source the files under test to revert variable
|
||||
# overrides (i.e. SH variable)
|
||||
source "$JUNEST_ROOT/lib/core/common.sh"
|
||||
source "$JUNEST_ROOT/lib/core/namespace.sh"
|
||||
set +e
|
||||
|
||||
init_mocks
|
||||
}
|
||||
|
||||
function tearDown(){
|
||||
junestTearDown
|
||||
cwdTearDown
|
||||
}
|
||||
|
||||
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)"
|
||||
}
|
||||
|
||||
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 ${JUNEST_HOME}/etc/passwd ]]
|
||||
assertEquals 0 $?
|
||||
[[ -e ${JUNEST_HOME}/etc/group ]]
|
||||
assertEquals 0 $?
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
function test_is_user_namespace_enabled_no_config(){
|
||||
touch config
|
||||
gzip config
|
||||
CONFIG_PROC_FILE="config.gz"
|
||||
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"
|
||||
assertCommandSuccess _is_user_namespace_enabled
|
||||
}
|
||||
|
||||
function test_run_env_with_namespace() {
|
||||
assertCommandSuccess run_env_with_namespace "" ""
|
||||
assertEquals "unshare --mount --user --map-root-user $GROOT -n -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /bin/sh --login" "$(cat $STDOUTF)"
|
||||
|
||||
_test_copy_common_files
|
||||
_test_copy_remaining_files
|
||||
}
|
||||
|
||||
function test_run_env_with_namespace_with_bindings() {
|
||||
assertCommandSuccess run_env_with_namespace "-b /usr -b /lib:/tmp/lib" ""
|
||||
assertEquals "unshare --mount --user --map-root-user $GROOT -n -b $HOME -b /tmp -b /proc -b /sys -b /dev -b /usr -b /lib:/tmp/lib $JUNEST_HOME /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 "" "ls -la"
|
||||
assertEquals "unshare --mount --user --map-root-user $GROOT -n -b $HOME -b /tmp -b /proc -b /sys -b /dev $JUNEST_HOME /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" "ls -la"
|
||||
assertEquals "unshare --mount --user --map-root-user $GROOT -n -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)"
|
||||
|
||||
_test_copy_common_files
|
||||
_test_copy_remaining_files
|
||||
}
|
||||
|
||||
source $JUNEST_ROOT/tests/utils/shunit2
|
||||
|
|
@ -29,6 +29,24 @@ function tearDown(){
|
|||
cwdTearDown
|
||||
}
|
||||
|
||||
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)"
|
||||
}
|
||||
|
||||
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 ${JUNEST_HOME}/etc/passwd ]]
|
||||
assertEquals 0 $?
|
||||
[[ -e ${JUNEST_HOME}/etc/group ]]
|
||||
assertEquals 0 $?
|
||||
}
|
||||
|
||||
function test_run_env_as_user(){
|
||||
_run_env_with_qemu() {
|
||||
echo $@
|
||||
|
|
@ -40,19 +58,8 @@ function test_run_env_as_user(){
|
|||
assertCommandSuccess run_env_as_user "-k 3.10"
|
||||
assertEquals "-b $HOME -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat $STDOUTF)"
|
||||
|
||||
[[ -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.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/passwd ]]
|
||||
assertEquals 0 $?
|
||||
[[ -e /etc/group ]]
|
||||
assertEquals 0 $?
|
||||
|
||||
_test_copy_common_files
|
||||
_test_copy_remaining_files
|
||||
}
|
||||
|
||||
function test_run_env_as_fakeroot(){
|
||||
|
|
@ -66,10 +73,7 @@ function test_run_env_as_fakeroot(){
|
|||
assertCommandSuccess run_env_as_fakeroot "-k 3.10"
|
||||
assertEquals "-0 -b ${HOME} -b /tmp -b /proc -b /sys -b /dev -r ${JUNEST_HOME} -k 3.10" "$(cat $STDOUTF)"
|
||||
|
||||
[[ -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)"
|
||||
_test_copy_common_files
|
||||
}
|
||||
|
||||
function test_run_env_with_quotes(){
|
||||
|
|
|
|||
|
|
@ -79,6 +79,28 @@ 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)"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
OLD_CWD=${PWD}
|
||||
function cwdSetUp(){
|
||||
ORIGIN_CWD=$(TMPDIR=/tmp mktemp -d -t junest-cwd.XXXXXXXXXX)
|
||||
cd $ORIGIN_CWD
|
||||
|
|
@ -5,6 +6,7 @@ function cwdSetUp(){
|
|||
|
||||
function cwdTearDown(){
|
||||
rm -rf $ORIGIN_CWD
|
||||
cd $OLD_CWD
|
||||
}
|
||||
|
||||
function junestSetUp(){
|
||||
|
|
@ -12,15 +14,12 @@ function junestSetUp(){
|
|||
mkdir -p ${JUNEST_HOME}/etc/junest
|
||||
echo "JUNEST_ARCH=x86_64" > ${JUNEST_HOME}/etc/junest/info
|
||||
mkdir -p ${JUNEST_HOME}/etc/ca-certificates
|
||||
trap - QUIT EXIT ABRT KILL TERM INT
|
||||
trap "rm -rf ${JUNEST_HOME}" EXIT QUIT ABRT KILL TERM INT
|
||||
}
|
||||
|
||||
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
|
||||
trap - QUIT EXIT ABRT KILL TERM INT
|
||||
unset JUNEST_HOME
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue