mirror of
https://github.com/fsquillace/junest.git
synced 2026-01-23 02:34:30 +00:00
Issue #174: Add namespace module and check for user namespace
This commit is contained in:
parent
f85c62274f
commit
0ec35a4088
6 changed files with 181 additions and 17 deletions
43
bin/junest
43
bin/junest
|
|
@ -7,10 +7,13 @@ 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,8 +32,11 @@ 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 "-r, --root Run $NAME with root privileges via jchroot"
|
||||
echo -e "-p, --backend-args <args> Arguments for backend program (PRoot or jchroot)"
|
||||
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 "-u, --user-namespace Use Linux User Namespace instead of PRoot"
|
||||
echo
|
||||
echo -e "Building options:"
|
||||
echo -e "-b, --build-image Build a $NAME image (must run in ArchLinux)"
|
||||
|
|
@ -109,7 +115,7 @@ 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
|
||||
|
|
@ -135,8 +141,9 @@ function parse_arguments(){
|
|||
IMAGE_FILE=""
|
||||
OPT_FAKEROOT=false
|
||||
OPT_ROOT=false
|
||||
OPT_PROOT_ARGS=false
|
||||
PROOT_ARGS=""
|
||||
OPT_USER_NAMESPACE=false
|
||||
OPT_BACKEND_ARGS=false
|
||||
BACKEND_ARGS=""
|
||||
OPT_ARCH=false
|
||||
ARCH_ARG=""
|
||||
OPT_BUILD_IMAGE=false
|
||||
|
|
@ -153,7 +160,8 @@ 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 ;;
|
||||
-u|--user-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 ;;
|
||||
|
|
@ -205,13 +213,22 @@ 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[@]}"
|
||||
elif $OPT_ROOT; then
|
||||
run_env_as_root "${ARGS[@]}"
|
||||
if $OPT_USER_NAMESPACE; then
|
||||
if $OPT_FAKEROOT; then
|
||||
run_env_as_fakeroot_with_namespace "${BACKEND_ARGS}" "${ARGS[@]}"
|
||||
else
|
||||
run_env_as_user_with_namespace "${BACKEND_ARGS}" "${ARGS[@]}"
|
||||
fi
|
||||
else
|
||||
run_env_as_user "${PROOT_ARGS}" "${ARGS[@]}"
|
||||
if $OPT_FAKEROOT; then
|
||||
run_env_as_fakeroot "${BACKEND_ARGS}" "${ARGS[@]}"
|
||||
elif $OPT_ROOT; then
|
||||
run_env_as_root "${ARGS[@]}"
|
||||
else
|
||||
run_env_as_user "${BACKEND_ARGS}" "${ARGS[@]}"
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
function cli() {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ ARCHITECTURE_MISMATCH=104
|
|||
ROOT_ACCESS_ERROR=105
|
||||
NESTED_ENVIRONMENT=106
|
||||
VARIABLE_NOT_SET=107
|
||||
NO_CONFIG_FOUND=108
|
||||
|
||||
if [ "$JUNEST_ENV" == "1" ]
|
||||
then
|
||||
|
|
@ -89,6 +90,8 @@ RM=rm
|
|||
MKDIR=mkdir
|
||||
GETENT=getent
|
||||
CP=cp
|
||||
# Used for checking user namespace in config.gz file
|
||||
ZGREP=zgrep
|
||||
|
||||
LD_EXEC="$LD_LIB --library-path ${JUNEST_HOME}/usr/lib:${JUNEST_HOME}/lib"
|
||||
|
||||
|
|
@ -120,6 +123,10 @@ function mkdir_cmd(){
|
|||
$MKDIR $@ || $LD_EXEC ${JUNEST_HOME}/usr/bin/$MKDIR $@
|
||||
}
|
||||
|
||||
function zgrep_cmd(){
|
||||
$ZGREP $@ || $LD_EXEC ${JUNEST_HOME}/usr/bin/$ZGREP $@
|
||||
}
|
||||
|
||||
function proot_cmd(){
|
||||
local proot_args="$1"
|
||||
shift
|
||||
|
|
|
|||
47
lib/core/namespace.sh
Normal file
47
lib/core/namespace.sh
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#!/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 "CONFIG_USER_NS=y" $config_file
|
||||
then
|
||||
return $NO_CONFIG_FOUND
|
||||
fi
|
||||
}
|
||||
|
||||
function run_env_as_user_with_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. Proceeding anyway..." ;;
|
||||
esac
|
||||
set -e
|
||||
}
|
||||
|
||||
function run_env_as_fakeroot_with_namespace() {
|
||||
die_on_status 1 "Not implemented yet"
|
||||
}
|
||||
|
|
@ -44,17 +44,27 @@ function setup_env(){
|
|||
echo "setup_env($1)"
|
||||
}
|
||||
function run_env_as_fakeroot(){
|
||||
local proot_args="$1"
|
||||
local backend_args="$1"
|
||||
shift
|
||||
echo "run_env_as_fakeroot($proot_args,$@)"
|
||||
echo "run_env_as_fakeroot($backend_args,$@)"
|
||||
}
|
||||
function run_env_as_root(){
|
||||
echo "run_env_as_root $@"
|
||||
}
|
||||
function run_env_as_user(){
|
||||
local proot_args="$1"
|
||||
local backend_args="$1"
|
||||
shift
|
||||
echo "run_env_as_user($proot_args,$@)"
|
||||
echo "run_env_as_user($backend_args,$@)"
|
||||
}
|
||||
function run_env_as_fakeroot_with_namespace(){
|
||||
local backend_args="$1"
|
||||
shift
|
||||
echo "run_env_as_fakeroot_with_namespace($backend_args,$@)"
|
||||
}
|
||||
function run_env_as_user_with_namespace(){
|
||||
local backend_args="$1"
|
||||
shift
|
||||
echo "run_env_as_user_with_namespace($backend_args,$@)"
|
||||
}
|
||||
|
||||
function test_help(){
|
||||
|
|
@ -164,6 +174,31 @@ function test_run_env_as_root(){
|
|||
assertEquals "run_env_as_root command" "$(cat $STDOUTF)"
|
||||
}
|
||||
|
||||
function test_run_env_as_fakeroot_with_namespace(){
|
||||
assertCommandSuccess cli -u -f
|
||||
assertEquals "run_env_as_fakeroot_with_namespace(,)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli --user-namespace --fakeroot
|
||||
assertEquals "run_env_as_fakeroot_with_namespace(,)" "$(cat $STDOUTF)"
|
||||
|
||||
assertCommandSuccess cli -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
|
||||
assertEquals "run_env_as_fakeroot_with_namespace(-b arg,command -kv)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli -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
|
||||
assertEquals "run_env_as_user_with_namespace(,)" "$(cat $STDOUTF)"
|
||||
|
||||
assertCommandSuccess cli -u -p "-b arg"
|
||||
assertEquals "run_env_as_user_with_namespace(-b arg,)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli -u -p "-b arg" -- command -ll
|
||||
assertEquals "run_env_as_user_with_namespace(-b arg,command -ll)" "$(cat $STDOUTF)"
|
||||
assertCommandSuccess cli -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
|
||||
|
|
|
|||
|
|
@ -100,6 +100,16 @@ 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)"
|
||||
|
||||
ZGREP=false assertCommandSuccess zgrep_cmd new_file
|
||||
assertEquals "ld_exec ${JUNEST_HOME}/usr/bin/false new_file" "$(cat $STDOUTF)"
|
||||
|
||||
ZGREP=false LD_EXEC=false assertCommandFail zgrep_cmd new_file
|
||||
}
|
||||
|
||||
function test_chroot(){
|
||||
CHROOT=echo assertCommandSuccess chroot_cmd root
|
||||
assertEquals "root" "$(cat $STDOUTF)"
|
||||
|
|
|
|||
48
tests/unit-tests/test-namespace.sh
Executable file
48
tests/unit-tests/test-namespace.sh
Executable file
|
|
@ -0,0 +1,48 @@
|
|||
#!/bin/bash
|
||||
|
||||
JUNEST_ROOT=$(readlink -f $(dirname $0)/../..)
|
||||
|
||||
source "$JUNEST_ROOT/tests/utils/utils.sh"
|
||||
|
||||
source "$JUNEST_ROOT/lib/utils/utils.sh"
|
||||
source "$JUNEST_ROOT/lib/core/common.sh"
|
||||
source "$JUNEST_ROOT/lib/core/namespace.sh"
|
||||
|
||||
# Disable the exiterr
|
||||
set +e
|
||||
|
||||
function oneTimeSetUp(){
|
||||
setUpUnitTests
|
||||
}
|
||||
|
||||
function setUp(){
|
||||
cwdSetUp
|
||||
}
|
||||
|
||||
function tearDown(){
|
||||
cwdTearDown
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
source $JUNEST_ROOT/tests/utils/shunit2
|
||||
Loading…
Add table
Add a link
Reference in a new issue