Issue #91: Add the architecture option

This commit is contained in:
Filippo Squillace 2015-06-25 18:49:41 +00:00
parent 8475d8eb41
commit 0cf7c624ec
7 changed files with 129 additions and 54 deletions

View file

@ -23,6 +23,7 @@ The main advantages on using JuNest are:
- Isolated environment in which you can install packages without affecting a production system.
- Access to a wide range of packages in particular on GNU/Linux distros that may contain limited repositories (such as CentOS and RedHat).
- Available for x86\_64, x86 and ARM architectures but you can build your own image from scratch too!
- Run on a different architecture from the host OS via QEMU
- All Arch Linux lovers can have their favourite distro everywhere!
JuNest follows the [Arch Linux philosophy](https://wiki.archlinux.org/index.php/The_Arch_Way).
@ -101,6 +102,13 @@ Related wiki page:
- [How to build a JuNest image using QEMU](https://github.com/fsquillace/junest/wiki/How-to-build-a-JuNest-image-using-QEMU)
## Run JuNest using a different architecture via QEMU ##
The following command will download the ARM JuNest image and will run QEMU in
case the host OS runs on either x86\_64 or x86 architectures:
$> JUNEST_HOME=~/.junest-arm junest -a arm -- uname -m
armv7l
## Bind directories ##
To bind a host directory to a guest location, you can use proot arguments:
@ -153,6 +161,11 @@ image.
The JuNest images are built every week so that you can always get the most
updated package versions.
##Static QEMU binaries##
There are static QEMU binaries included in JuNest image that allows to run JuNest
in a different architecture from the host system. They are located in `/opt/qemu`
directory.
Troubleshooting
===============

View file

@ -34,6 +34,8 @@ usage() {
echo -e "-f, --fakeroot Run $NAME with fakeroot privileges"
echo -e "-r, --root Run $NAME with root privileges"
echo -e "-p, --proot-args Proot arguments"
echo -e "-a, --arch $NAME architecture to use (x86_64, x86, arm)."
echo -e " Defaults to the host architecture ($ARCH)"
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 "-d, --delete Delete $NAME from ${JUNEST_HOME}"
@ -92,12 +94,12 @@ check_cli(){
then
die "You must access to $NAME with either fakeroot or root permissions"
fi
if $OPT_PROOT_ARGS
if $OPT_PROOT_ARGS || $OPT_ARCH
then
if $OPT_BUILD_IMAGE || $OPT_DELETE || $OPT_HELP || $OPT_SETUP_FROM_FILE || \
if $OPT_BUILD_IMAGE || $OPT_DELETE || $OPT_HELP || \
$OPT_ROOT || $OPT_VERSION || $OPT_DISABLE_VALIDATION
then
die "Invalid syntax: Proot args are not allowed with the other options"
die "Invalid syntax: Proot and arch args are not allowed with the other options"
fi
fi
if [ "$ARGS" != "" ]
@ -120,6 +122,8 @@ function parse_arguments(){
OPT_ROOT=false
OPT_PROOT_ARGS=false
PROOT_ARGS=""
OPT_ARCH=false
ARCH_ARG=""
OPT_BUILD_IMAGE=false
OPT_DISABLE_VALIDATION=false
OPT_DELETE=false
@ -132,6 +136,7 @@ function parse_arguments(){
-f|--fakeroot) OPT_FAKEROOT=true ; shift ;;
-r|--root) OPT_ROOT=true ; shift ;;
-p|--proot-args) OPT_PROOT_ARGS=true ; shift ; PROOT_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 ;;
-d|--delete) OPT_DELETE=true ; shift ;;
@ -167,18 +172,18 @@ function execute_operation(){
if $OPT_SETUP_FROM_FILE; then
setup_env_from_file $IMAGE_FILE
else
setup_env
setup_env $ARCH_ARG
fi
elif $OPT_SETUP_FROM_FILE; then
die "Error: The image cannot be installed since $JUNEST_HOME is not empty."
fi
if $OPT_FAKEROOT; then
run_env_as_fakeroot "${PROOT_ARGS}" "${ARGS[@]}"
run_env_as_fakeroot "${ARCH_ARG}" "${PROOT_ARGS}" "${ARGS[@]}"
elif $OPT_ROOT; then
run_env_as_root "${ARGS[@]}"
else
run_env_as_user "${PROOT_ARGS}" "${ARGS[@]}"
run_env_as_user "${ARCH_ARG}" "${PROOT_ARGS}" "${ARGS[@]}"
fi
}

View file

@ -167,12 +167,17 @@ function _setup_env(){
function setup_env(){
local arch=$ARCH
[ -z $1 ] || arch="$1"
contains_element $arch "${ARCH_LIST[@]}" || \
die "The architecture is not one of: ${ARCH_LIST[@]}"
local maindir=$(TMPDIR=$JUNEST_TEMPDIR mktemp -d -t ${CMD}.XXXXXXXXXX)
_prepare_build_directory
info "Downloading ${NAME}..."
builtin cd ${maindir}
local imagefile=${CMD}-${ARCH}.tar.gz
local imagefile=${CMD}-${arch}.tar.gz
download_cmd ${ENV_REPO}/${imagefile}
info "Installing ${NAME}..."
@ -210,7 +215,6 @@ function run_env_as_root(){
}
function _run_env_with_proot(){
local proot_args="$1"
shift
@ -222,28 +226,39 @@ function _run_env_with_proot(){
fi
}
function _run_env_with_qemu(){
local proot_args="$2"
if [ "$1" != "" ] && [ "$1" != "$ARCH" ]
then
local qemu_bin="/tmp/qemu-$1-static-$ARCH-$RANDOM"
trap - QUIT EXIT ABRT KILL TERM INT
trap "[ -e ${qemu_bin} ] && rm_cmd -f ${qemu_bin}" EXIT QUIT ABRT KILL TERM INT
contains_element $1 "${ARCH_LIST[@]}" || \
die "The architecture is not one of: ${ARCH_LIST[@]}"
[ -e "${JUNEST_HOME}/opt/qemu/qemu-$1-static-$ARCH" ] || \
die "The JuNest image in ${JUNEST_HOME} is not an $1 architecture"
warn "Emulating $NAME via QEMU..."
[ -e ${qemu_bin} ] || \
ln_cmd -s ${JUNEST_HOME}/opt/qemu/qemu-$1-static-$ARCH ${qemu_bin}
proot_args="-q ${qemu_bin} $2"
fi
shift 2
_run_env_with_proot "$proot_args" "${@}"
}
function run_env_as_fakeroot(){
(( EUID == 0 )) && \
die "You cannot access with root privileges. Use --root option instead."
local proot_args="$1"
shift
[ ! -e ${JUNEST_HOME}/etc/mtab ] && ln_cmd -s /proc/self/mounts ${JUNEST_HOME}/etc/mtab
_run_env_with_proot "-S ${JUNEST_HOME} $proot_args" "${@}"
_run_env_with_qemu "$1" "-S ${JUNEST_HOME} $2" "${@:3}"
}
function run_env_as_user(){
(( EUID == 0 )) && \
die "You cannot access with root privileges. Use --root option instead."
local proot_args="$1"
shift
[ -e ${JUNEST_HOME}/etc/mtab ] && rm_cmd -f ${JUNEST_HOME}/etc/mtab
_run_env_with_proot "-R ${JUNEST_HOME} $proot_args" "${@}"
_run_env_with_qemu "$1" "-R ${JUNEST_HOME} $2" "${@:3}"
}

View file

@ -85,3 +85,9 @@ function insert_quotes_on_spaces(){
done
echo $C
}
contains_element () {
local e
for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
return 1
}

View file

@ -27,17 +27,21 @@ function setup_env(){
echo "setup_env"
}
function run_env_as_fakeroot(){
local proot_args="$1"
local arch_arg="$1"
local proot_args="$2"
shift
echo "run_env_as_fakeroot($proot_args,$@)"
shift
echo "run_env_as_fakeroot($arch_arg,$proot_args,$@)"
}
function run_env_as_root(){
echo "run_env_as_root $@"
}
function run_env_as_user(){
local proot_args="$1"
local arch_arg="$1"
local proot_args="$2"
shift
echo "run_env_as_user($proot_args,$@)"
shift
echo "run_env_as_user($arch_arg,$proot_args,$@)"
}
function wrap_env(){
@ -72,27 +76,31 @@ function test_delete_env(){
}
function test_run_env_as_fakeroot(){
local output=$(wrap_env -f)
assertEquals $output "run_env_as_fakeroot(,)"
assertEquals $output "run_env_as_fakeroot(,,)"
local output=$(wrap_env --fakeroot)
assertEquals $output "run_env_as_fakeroot(,)"
assertEquals $output "run_env_as_fakeroot(,,)"
local output=$(wrap_env -f -p "-b arg")
assertEquals "${output[@]}" "run_env_as_fakeroot(-b arg,)"
assertEquals "${output[@]}" "run_env_as_fakeroot(,-b arg,)"
local output=$(wrap_env -f -p "-b arg" -- command -kv)
assertEquals "${output[@]}" "run_env_as_fakeroot(-b arg,command -kv)"
assertEquals "${output[@]}" "run_env_as_fakeroot(,-b arg,command -kv)"
local output=$(wrap_env -f command --as)
assertEquals "${output[@]}" "run_env_as_fakeroot(,command --as)"
assertEquals "${output[@]}" "run_env_as_fakeroot(,,command --as)"
local output=$(wrap_env -a "myarch" -f command --as)
assertEquals "${output[@]}" "run_env_as_fakeroot(myarch,,command --as)"
}
function test_run_env_as_user(){
local output=$(wrap_env)
assertEquals $output "run_env_as_user(,)"
assertEquals $output "run_env_as_user(,,)"
local output=$(wrap_env -p "-b arg")
assertEquals "$output" "run_env_as_user(-b arg,)"
assertEquals "$output" "run_env_as_user(,-b arg,)"
local output=$(wrap_env -p "-b arg" -- command -ll)
assertEquals "$output" "run_env_as_user(-b arg,command -ll)"
assertEquals "$output" "run_env_as_user(,-b arg,command -ll)"
local output=$(wrap_env command -ls)
assertEquals "$output" "run_env_as_user(,command -ls)"
assertEquals "$output" "run_env_as_user(,,command -ls)"
local output=$(wrap_env -a "myarch" -- command -ls)
assertEquals "$output" "run_env_as_user(myarch,,command -ls)"
}
function test_run_env_as_root(){
local output=$(wrap_env -r)
@ -117,6 +125,8 @@ function test_check_cli(){
assertEquals $? 1
$(wrap_env -p args -v 2> /dev/null)
assertEquals $? 1
$(wrap_env -a arch -v 2> /dev/null)
assertEquals $? 1
$(wrap_env -d args 2> /dev/null)
assertEquals $? 1
}

View file

@ -149,6 +149,9 @@ function test_setup_env(){
setup_env 1> /dev/null
assertTrue "[ -e $JUNEST_HOME/file ]"
assertTrue "[ -e $JUNEST_HOME/run/lock ]"
$(setup_env "noarch" 2> /dev/null)
assertEquals 1 $?
}
@ -237,21 +240,28 @@ function test_run_env_as_junest_root(){
function test_run_env_as_user(){
install_mini_env
local output=$(run_env_as_user "-k 3.10" "/usr/bin/mkdir" "-v" "/newdir2" | awk -F: '{print $1}')
local output=$(run_env_as_user "" "-k 3.10" "/usr/bin/mkdir" "-v" "/newdir2" | awk -F: '{print $1}')
assertEquals "$output" "/usr/bin/mkdir"
assertTrue "[ -e $JUNEST_HOME/newdir2 ]"
SH=("/usr/bin/mkdir" "-v" "/newdir")
local output=$(run_env_as_user "-k 3.10" | awk -F: '{print $1}')
local output=$(run_env_as_user "" "-k 3.10" | awk -F: '{print $1}')
assertEquals "$output" "/usr/bin/mkdir"
assertTrue "[ -e $JUNEST_HOME/newdir ]"
$(run_env_as_user "noarch" "-k 3.10" "mycommand" 2> /dev/null)
assertEquals 1 $?
local different_arch=(${ARCH_LIST[@]/$ARCH})
$(run_env_as_user "${different_arch[0]}" "-k 3.10" "mycommand" 2> /dev/null)
assertEquals 1 $?
}
function test_run_env_as_proot_mtab(){
install_mini_env
$(run_env_as_fakeroot "-k 3.10" "echo")
$(run_env_as_fakeroot "" "-k 3.10" "echo")
assertTrue "[ -e $JUNEST_HOME/etc/mtab ]"
$(run_env_as_user "-k 3.10" "echo")
$(run_env_as_user "" "-k 3.10" "echo")
assertTrue "[ ! -e $JUNEST_HOME/etc/mtab ]"
}
@ -268,32 +278,32 @@ function test_run_env_as_root_mtab(){
function test_run_env_with_quotes(){
install_mini_env
local output=$(run_env_as_user "-k 3.10" "bash" "-c" "/usr/bin/mkdir -v /newdir2" | awk -F: '{print $1}')
assertEquals "$output" "/usr/bin/mkdir"
local output=$(run_env_as_user "" "-k 3.10" "bash" "-c" "/usr/bin/mkdir -v /newdir2" | awk -F: '{print $1}')
assertEquals "/usr/bin/mkdir" "$output"
assertTrue "[ -e $JUNEST_HOME/newdir2 ]"
}
function test_run_env_as_user_proot_args(){
install_mini_env
run_env_as_user "--help" "" &> /dev/null
assertEquals $? 0
run_env_as_user "" "--help" "" &> /dev/null
assertEquals 0 $?
mkdir $JUNEST_TEMPDIR/newdir
touch $JUNEST_TEMPDIR/newdir/newfile
run_env_as_user "-b $JUNEST_TEMPDIR/newdir:/newdir -k 3.10" "ls" "-l" "/newdir/newfile" &> /dev/null
assertEquals $? 0
run_env_as_user "" "-b $JUNEST_TEMPDIR/newdir:/newdir -k 3.10" "ls" "-l" "/newdir/newfile" &> /dev/null
assertEquals 0 $?
$(_run_env_with_proot --helps 2> /dev/null)
assertEquals $? 1
assertEquals 1 $?
}
function test_run_env_with_proot_compat(){
PROOT_COMPAT="/bin/true"
_run_env_with_proot "" "" &> /dev/null
assertEquals $? 0
assertEquals 0 $?
$(PROOT_COMPAT="/bin/false" _run_env_with_proot --helps 2> /dev/null)
assertEquals $? 1
assertEquals 1 $?
}
function test_run_env_with_proot_as_root(){
@ -302,44 +312,51 @@ function test_run_env_with_proot_as_root(){
install_mini_env
$(sudo run_env_as_user 2> /dev/null)
assertEquals $? 1
assertEquals 1 $?
$(sudo run_env_as_fakeroot 2> /dev/null)
assertEquals $? 1
assertEquals 1 $?
}
function test_run_proot_seccomp(){
PROOT_COMPAT=env
local output=$(proot_cmd | grep "^PROOT_NO_SECCOMP")
assertEquals "$output" ""
assertEquals "" "$output"
envv(){
env | grep "^PROOT_NO_SECCOMP"
}
PROOT_COMPAT=envv
local output=$(proot_cmd 2> /dev/null | grep "^PROOT_NO_SECCOMP")
assertEquals "$output" "PROOT_NO_SECCOMP=1"
assertEquals "PROOT_NO_SECCOMP=1" "$output"
}
function test_run_env_as_fakeroot(){
install_mini_env
local output=$(run_env_as_fakeroot "-k 3.10" "id" | awk '{print $1}')
assertEquals "$output" "uid=0(root)"
local output=$(run_env_as_fakeroot "" "-k 3.10" "id" | awk '{print $1}')
assertEquals "uid=0(root)" "$output"
$(run_env_as_fakeroot "noarch" "-k 3.10" "mycommand" 2> /dev/null)
assertEquals 1 $?
local different_arch=(${ARCH_LIST[@]/$ARCH})
$(run_env_as_fakeroot "${different_arch[0]}" "-k 3.10" "mycommand" 2> /dev/null)
assertEquals 1 $?
}
function test_delete_env(){
install_mini_env
echo "N" | delete_env 1> /dev/null
is_env_installed
assertEquals $? 0
assertEquals 0 $?
echo "Y" | delete_env 1> /dev/null
is_env_installed
assertEquals $? 1
assertEquals 1 $?
}
function test_nested_env(){
install_mini_env
JUNEST_ENV=1 bash -ic "source $CURRPWD/$(dirname $0)/../lib/core.sh" &> /dev/null
assertEquals $? 1
assertEquals 1 $?
}
source $(dirname $0)/shunit2

View file

@ -60,4 +60,13 @@ function test_insert_quotes_on_spaces(){
assertEquals "this is \"a test\"" "$actual"
}
function test_contains_element(){
array=("something to search for" "a string" "test2000")
contains_element "a string" "${array[@]}"
assertEquals "$?" "0"
contains_element "blabla" "${array[@]}"
assertEquals "$?" "1"
}
source $(dirname $0)/shunit2