Issue #174: Add new program GRoot and change version option for JuNest!

This replaces jchroot because GRoot can be also used in a user namespace environment.
This commit is contained in:
Filippo Squillace 2017-03-17 17:49:00 +00:00
parent 426b708d2d
commit 0f7fd33c53
13 changed files with 458 additions and 184 deletions

View file

@ -169,14 +169,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.

180
bin/groot Executable file
View file

@ -0,0 +1,180 @@
#!/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
NOT_EXISTING_FILE=103
NOT_ABSOLUTE_PATH=111
NO_ROOT_PRIVILEGES=110
source "${JUNEST_BASE}/lib/utils/utils.sh"
################################ MAIN FUNCTIONS ###########################
function chroot_add_mount() {
$MOUNT "$@" && CHROOT_ACTIVE_MOUNTS=("${@: -1}" "${CHROOT_ACTIVE_MOUNTS[@]}")
}
function chroot_teardown() {
$UMOUNT "${CHROOT_ACTIVE_MOUNTS[@]}"
unset CHROOT_ACTIVE_MOUNTS
}
function chroot_maybe_add_mount() {
local cond=$1
shift
if eval "$cond"; then
chroot_add_mount "$@"
return
fi
return 1
}
function chroot_setup() {
CHROOT_ACTIVE_MOUNTS=()
check_and_trap 'chroot_teardown' EXIT
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}"
chroot_add_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.
-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_HELP=false
OPT_VERSION=false
for opt in "$@"
do
case "$1" in
-b|--bind) OPT_BIND=true ; shift ; BINDINGS+=("$1") ; 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 "$@"

View file

@ -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" "$@"

View file

@ -3,7 +3,11 @@
# 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"
@ -32,10 +36,10 @@ usage() {
echo
echo -e "Access options:"
echo -e "-f, --fakeroot Run $NAME with fakeroot privileges"
echo -e "-r, --root Run $NAME with root privileges via jchroot"
echo -e "-p, --backend-args <args> Arguments for backend program (PRoot or jchroot)"
echo -e "-r, --root Run $NAME with root privileges via GRoot"
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 -u -p \"--help\" to check out the jchroot options)"
echo -e " $CMD -u -p \"--help\" to check out the GRoot options)"
echo -e "-u, --user-namespace Use Linux User Namespace instead of PRoot"
echo
echo -e "Building options:"
@ -47,7 +51,7 @@ usage() {
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() {
@ -169,7 +173,7 @@ function parse_arguments(){
-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 ;;
@ -231,11 +235,11 @@ function execute_operation(){
}
function cli() {
function main() {
parse_arguments "$@"
check_cli
execute_operation
}
cli "$@"
main "$@"
# vim: set ts=4 sw=4 noet:

View file

@ -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/*

View file

@ -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'
@ -79,7 +77,7 @@ SH=("/bin/sh" "--login")
# List of executables that are run in the host OS:
PROOT="${JUNEST_HOME}/opt/proot/proot-${ARCH}"
JCHROOT=${JUNEST_BASE}/bin/jchroot
GROOT=${JUNEST_BASE}/bin/groot
CLASSIC_CHROOT=chroot
WGET="wget --no-check-certificate"
CURL="curl -L -J -O -k"
@ -125,7 +123,8 @@ function mkdir_cmd(){
}
function zgrep_cmd(){
$ZGREP $@ || $LD_EXEC ${JUNEST_HOME}/usr/bin/$ZGREP $@
# No need for LD_EXEC as zgrep is a POSIX shell script
$ZGREP $@ || ${JUNEST_HOME}/usr/bin/$ZGREP $@
}
function unshare_cmd(){
@ -151,7 +150,7 @@ function download_cmd(){
}
function chroot_cmd(){
$JCHROOT "$@" || $CLASSIC_CHROOT "$@" || $LD_EXEC ${JUNEST_HOME}/usr/bin/$CLASSIC_CHROOT "$@"
$GROOT "$@" || $CLASSIC_CHROOT "$@" || $LD_EXEC ${JUNEST_HOME}/usr/bin/$CLASSIC_CHROOT "$@"
}
############## COMMON FUNCTIONS ###############

View file

@ -59,7 +59,7 @@ function run_env_as_user_with_namespace() {
local bindings=${RESULT}
unset RESULT
unshare_cmd --mount --user --map-root-user $JCHROOT $bindings $backend_args "$JUNEST_HOME"
unshare_cmd --mount --user --map-root-user $GROOT $bindings $backend_args "$JUNEST_HOME"
}
function run_env_as_fakeroot_with_namespace() {
@ -69,9 +69,19 @@ function run_env_as_fakeroot_with_namespace() {
copy_common_files
#mkdir -p "$chrootdir/$HOME"
#mkdir -p "$chrootdir/run/lock"
#chroot_add_mount --rbind /proc "$chrootdir/proc/"
#chroot_add_mount --rbind /dev "$chrootdir/dev/"
#chroot_add_mount --rbind /sys "$chrootdir/sys/"
#chroot_add_mount --rbind /tmp "$chrootdir/tmp/"
## alternately create a new tmp istead of binding it:
##chroot_add_mount -t tmpfs tmp "$chrootdir/tmp/"
#chroot_add_mount --rbind $HOME "$chrootdir/$HOME"
provide_common_bindings
local bindings=${RESULT}
unset RESULT
JUNEST_ENV=1 unshare_cmd --mount --user --map-root-user $JCHROOT $bindings $backend_args "$JUNEST_HOME"
JUNEST_ENV=1 unshare_cmd --mount --user --map-root-user $GROOT $bindings $backend_args "$JUNEST_HOME"
}

View file

@ -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

View file

@ -104,10 +104,16 @@ function test_zgrep(){
ZGREP=echo assertCommandSuccess zgrep_cmd new_file
assertEquals "new_file" "$(cat $STDOUTF)"
ZGREP=false assertCommandSuccess zgrep_cmd new_file
assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false new_file" "$(cat $STDOUTF)"
mkdir -p ${JUNEST_HOME}/usr/bin
touch ${JUNEST_HOME}/usr/bin/false
chmod +x ${JUNEST_HOME}/usr/bin/false
ZGREP=false LD_EXEC=false assertCommandFail zgrep_cmd new_file
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(){
@ -121,16 +127,16 @@ function test_unshare(){
}
function test_chroot(){
JCHROOT=echo assertCommandSuccess chroot_cmd root
GROOT=echo assertCommandSuccess chroot_cmd root
assertEquals "root" "$(cat $STDOUTF)"
JCHROOT=false CLASSIC_CHROOT=echo assertCommandSuccess chroot_cmd root
GROOT=false CLASSIC_CHROOT=echo assertCommandSuccess chroot_cmd root
assertEquals "root" "$(cat $STDOUTF)"
JCHROOT=false CLASSIC_CHROOT=false assertCommandSuccess chroot_cmd root
GROOT=false CLASSIC_CHROOT=false assertCommandSuccess chroot_cmd root
assertEquals "ld_exec $JUNEST_HOME/usr/bin/false root" "$(cat $STDOUTF)"
JCHROOT=false CLASSIC_CHROOT=false LD_EXEC=false assertCommandFail chroot_cmd root
GROOT=false CLASSIC_CHROOT=false LD_EXEC=false assertCommandFail chroot_cmd root
}
function test_proot_cmd_compat(){

137
tests/unit-tests/test-groot.sh Executable file
View file

@ -0,0 +1,137 @@
#!/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 EXIT)\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 EXIT)\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 EXIT)\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 EXIT)\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 EXIT)\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 EXIT)\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 EXIT)\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 EXIT)\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 EXIT)\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 EXIT)\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)"
}
source $(dirname $0)/../utils/shunit2

View file

@ -1,7 +1,8 @@
#!/bin/bash
source "$(dirname $0)/../utils/utils.sh"
source $(dirname $0)/../../bin/junest -h &> /dev/null
JUNEST_BASE="$(dirname $0)/../.."
source $JUNEST_BASE/bin/junest -h &> /dev/null
# Disable the exiterr
set +e
@ -68,149 +69,149 @@ function run_env_as_user_with_namespace(){
}
function test_help(){
assertCommandSuccess cli -h
assertCommandSuccess main -h
assertEquals "usage" "$(cat $STDOUTF)"
assertCommandSuccess cli --help
assertCommandSuccess main --help
assertEquals "usage" "$(cat $STDOUTF)"
}
function test_version(){
assertCommandSuccess cli -v
assertCommandSuccess main -V
assertEquals "version" "$(cat $STDOUTF)"
assertCommandSuccess cli --version
assertCommandSuccess main --version
assertEquals "version" "$(cat $STDOUTF)"
}
function test_build_image_env(){
assertCommandSuccess cli -b
assertCommandSuccess main -b
assertEquals "build_image_env(false,false)" "$(cat $STDOUTF)"
assertCommandSuccess cli --build-image
assertCommandSuccess main --build-image
assertEquals "build_image_env(false,false)" "$(cat $STDOUTF)"
assertCommandSuccess cli -b -s
assertCommandSuccess main -b -s
assertEquals "build_image_env(false,true)" "$(cat $STDOUTF)"
assertCommandSuccess cli -b -n
assertCommandSuccess main -b -n
assertEquals "build_image_env(true,false)" "$(cat $STDOUTF)"
assertCommandSuccess cli -b -n -s
assertCommandSuccess main -b -n -s
assertEquals "build_image_env(true,true)" "$(cat $STDOUTF)"
assertCommandSuccess cli --build-image --disable-validation --skip-root-tests
assertCommandSuccess main --build-image --disable-validation --skip-root-tests
assertEquals "build_image_env(true,true)" "$(cat $STDOUTF)"
}
function test_check_env(){
assertCommandSuccess cli -c myscript
assertCommandSuccess main -c myscript
assertEquals "check_env(${JUNEST_HOME},myscript,false)" "$(cat $STDOUTF)"
assertCommandSuccess cli --check myscript
assertCommandSuccess main --check myscript
assertEquals "check_env(${JUNEST_HOME},myscript,false)" "$(cat $STDOUTF)"
assertCommandSuccess cli -c myscript -s
assertCommandSuccess main -c myscript -s
assertEquals "check_env(${JUNEST_HOME},myscript,true)" "$(cat $STDOUTF)"
assertCommandSuccess cli --check myscript --skip-root-tests
assertCommandSuccess main --check myscript --skip-root-tests
assertEquals "check_env(${JUNEST_HOME},myscript,true)" "$(cat $STDOUTF)"
}
function test_delete_env(){
assertCommandSuccess cli -d
assertCommandSuccess main -d
assertEquals "delete_env" "$(cat $STDOUTF)"
assertCommandSuccess cli --delete
assertCommandSuccess main --delete
assertEquals "delete_env" "$(cat $STDOUTF)"
}
function test_setup_env_from_file(){
is_env_installed(){
return 1
}
assertCommandSuccess cli -i myimage
assertCommandSuccess main -i myimage
assertEquals "$(echo -e "setup_env_from_file(myimage)\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
assertCommandSuccess cli --setup-from-file myimage
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 cli -i myimage
assertCommandFail main -i myimage
}
function test_setup_env(){
is_env_installed(){
return 1
}
assertCommandSuccess cli -a arm
assertCommandSuccess main -a arm
assertEquals "$(echo -e "setup_env(arm)\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
assertCommandSuccess cli --arch arm
assertCommandSuccess main --arch arm
assertEquals "$(echo -e "setup_env(arm)\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
assertCommandSuccess cli
assertCommandSuccess main
assertEquals "$(echo -e "setup_env()\nrun_env_as_user(,)")" "$(cat $STDOUTF)"
is_env_installed(){
return 0
}
assertCommandFail cli -a arm
assertCommandFail main -a arm
}
function test_run_env_as_fakeroot(){
assertCommandSuccess cli -f
assertCommandSuccess main -f
assertEquals "run_env_as_fakeroot(,)" "$(cat $STDOUTF)"
assertCommandSuccess cli --fakeroot
assertCommandSuccess main --fakeroot
assertEquals "run_env_as_fakeroot(,)" "$(cat $STDOUTF)"
assertCommandSuccess cli -f -p "-b arg"
assertCommandSuccess main -f -p "-b arg"
assertEquals "run_env_as_fakeroot(-b arg,)" "$(cat $STDOUTF)"
assertCommandSuccess cli -f -p "-b arg" -- command -kv
assertCommandSuccess main -f -p "-b arg" -- command -kv
assertEquals "run_env_as_fakeroot(-b arg,command -kv)" "$(cat $STDOUTF)"
assertCommandSuccess cli -f command --as
assertCommandSuccess main -f command --as
assertEquals "run_env_as_fakeroot(,command --as)" "$(cat $STDOUTF)"
assertCommandFail cli -a "myarch" -f command --as
assertCommandFail main -a "myarch" -f command --as
}
function test_run_env_as_user(){
assertCommandSuccess cli
assertCommandSuccess main
assertEquals "run_env_as_user(,)" "$(cat $STDOUTF)"
assertCommandSuccess cli -p "-b arg"
assertCommandSuccess main -p "-b arg"
assertEquals "run_env_as_user(-b arg,)" "$(cat $STDOUTF)"
assertCommandSuccess cli -p "-b arg" -- command -ll
assertCommandSuccess main -p "-b arg" -- command -ll
assertEquals "run_env_as_user(-b arg,command -ll)" "$(cat $STDOUTF)"
assertCommandSuccess cli command -ls
assertCommandSuccess main command -ls
assertEquals "run_env_as_user(,command -ls)" "$(cat $STDOUTF)"
assertCommandFail cli -a "myarch" -- command -ls
assertCommandFail main -a "myarch" -- command -ls
}
function test_run_env_as_root(){
assertCommandSuccess cli -r
assertCommandSuccess main -r
assertEquals "run_env_as_root " "$(cat $STDOUTF)"
assertCommandSuccess cli -r command
assertCommandSuccess main -r command
assertEquals "run_env_as_root command" "$(cat $STDOUTF)"
}
function test_run_env_as_fakeroot_with_namespace(){
assertCommandSuccess cli -u -f
assertCommandSuccess main -u -f
assertEquals "run_env_as_fakeroot_with_namespace(,)" "$(cat $STDOUTF)"
assertCommandSuccess cli --user-namespace --fakeroot
assertCommandSuccess main --user-namespace --fakeroot
assertEquals "run_env_as_fakeroot_with_namespace(,)" "$(cat $STDOUTF)"
assertCommandSuccess cli -u -f -p "-b arg"
assertCommandSuccess main -u -f -p "-b arg"
assertEquals "run_env_as_fakeroot_with_namespace(-b arg,)" "$(cat $STDOUTF)"
assertCommandSuccess cli -u -f -p "-b arg" -- command -kv
assertCommandSuccess main -u -f -p "-b arg" -- command -kv
assertEquals "run_env_as_fakeroot_with_namespace(-b arg,command -kv)" "$(cat $STDOUTF)"
assertCommandSuccess cli -u -f command --as
assertCommandSuccess main -u -f command --as
assertEquals "run_env_as_fakeroot_with_namespace(,command --as)" "$(cat $STDOUTF)"
}
function test_run_env_as_user_with_namespace(){
assertCommandSuccess cli -u
assertCommandSuccess main -u
assertEquals "run_env_as_user_with_namespace(,)" "$(cat $STDOUTF)"
assertCommandSuccess cli -u -p "-b arg"
assertCommandSuccess main -u -p "-b arg"
assertEquals "run_env_as_user_with_namespace(-b arg,)" "$(cat $STDOUTF)"
assertCommandSuccess cli -u -p "-b arg" -- command -ll
assertCommandSuccess main -u -p "-b arg" -- command -ll
assertEquals "run_env_as_user_with_namespace(-b arg,command -ll)" "$(cat $STDOUTF)"
assertCommandSuccess cli -u command -ls
assertCommandSuccess main -u command -ls
assertEquals "run_env_as_user_with_namespace(,command -ls)" "$(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
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

View file

@ -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)"

View file

@ -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
}