mirror of
https://github.com/fsquillace/junest.git
synced 2026-07-22 10:37:20 +00:00
Merge branch 'fsquillace:master' into master
This commit is contained in:
commit
b41b1f67d5
9 changed files with 97 additions and 59 deletions
37
README.md
37
README.md
|
|
@ -110,9 +110,9 @@ used, see the [Usage](#usage) section below.
|
|||
Run JuNest installed programs directly from host OS
|
||||
---------------------------------------
|
||||
|
||||
Program installed within JuNest can be accessible directly from host machine
|
||||
without entering directly into a JuNest session
|
||||
(no need to call `junest` command first).
|
||||
Programs installed within JuNest can be accessible directly from host machine
|
||||
without entering into a JuNest session
|
||||
(namely, no need to call `junest` command first).
|
||||
For instance, supposing the host OS is an Ubuntu distro you can directly
|
||||
run `pacman` by simply updating the `PATH` variable:
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ htop
|
|||
```
|
||||
|
||||
By default the wrappers use `ns` mode. To use the `ns --fakeroot` you can use the convenient command helper `sudoj`.
|
||||
For more control on backend mode you can use the `JUNEST_ARGS` environment variable.
|
||||
For more control on backend modes you can use the `JUNEST_ARGS` environment variable too.
|
||||
For instance, if you want to run `iftop` with real root privileges:
|
||||
|
||||
```
|
||||
|
|
@ -138,6 +138,22 @@ corrupted) with:
|
|||
junest create-bin-wrappers -f
|
||||
```
|
||||
|
||||
Bin wrappers are automatically generated each time they get installed inside JuNest.
|
||||
This only works for executables located in `/usr/bin` path.
|
||||
For executables in other locations (say `/usr/mybinpath`) you can only create
|
||||
wrappers manually by executing the command:
|
||||
|
||||
```
|
||||
junest create-bin-wrappers --bin-path /usr/mybinpath
|
||||
```
|
||||
|
||||
Obviously, to get access to the corresponding bin wrappers you will need to
|
||||
update your `PATH` variable accordingly:
|
||||
|
||||
```
|
||||
export PATH="$PATH:~/.junest/usr/mybinpath_wrappers"
|
||||
```
|
||||
|
||||
Install packages from AUR
|
||||
-------------------------
|
||||
|
||||
|
|
@ -149,14 +165,11 @@ command. In `proot` mode, JuNest does no longer support the building of AUR pack
|
|||
first:
|
||||
|
||||
```sh
|
||||
pacman -Syu --ignore sudo base-devel
|
||||
:: sudo is in IgnorePkg/IgnoreGroup. Install anyway? [Y/n] n
|
||||
...
|
||||
...
|
||||
pacman -S base-devel
|
||||
```
|
||||
|
||||
JuNest uses a modified version of `sudo`. That's why the original `sudo`
|
||||
package **must be ignored** in the previous command.
|
||||
JuNest uses a modified version of `sudo` provided by `junest/sudo-fake`. And the original `core/sudo`
|
||||
package will be ignored **(and must not be installed)** during the installation of `base-devel`.
|
||||
|
||||
Have fun!
|
||||
---------
|
||||
|
|
@ -387,9 +400,9 @@ For Arch Linux related FAQs take a look at the [General troubleshooting page](ht
|
|||
> In order to install AUR packages you need to install the package group `base-devel` first
|
||||
> that contains all the essential packages for compiling from source code (such as gcc, make, patch, etc):
|
||||
|
||||
#> pacman -S --ignore sudo base-devel
|
||||
#> pacman -S base-devel
|
||||
|
||||
> Remember to ignore `sudo` as it conflicts with `sudo-fake` package.
|
||||
> Remember to not install `core/sudo` as it conflicts with `junest/sudo-fake` package.
|
||||
|
||||
## Can't set user and group as root
|
||||
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
7.4.3
|
||||
7.4.7
|
||||
|
|
|
|||
12
bin/junest
12
bin/junest
|
|
@ -69,8 +69,11 @@ usage() {
|
|||
echo -e " b[uild] Build a $NAME image (must run in ArchLinux)"
|
||||
echo -e " -n, --disable-check Disable the $NAME image check"
|
||||
echo
|
||||
echo -e " create-bin-wrappers Create bin wrappers in $JUNEST_HOME/usr/bin_wrappers"
|
||||
echo -e " create-bin-wrappers Create a bin wrappers directory according to --bin-path option"
|
||||
echo -e " Default path is $JUNEST_HOME/usr/bin_wrappers"
|
||||
echo -e " -f, --force Create the wrapper files even if they already exist"
|
||||
echo -e " -p, --bin-path The source directory where executable are located in JuNest"
|
||||
echo -e " Default value is: /usr/bin"
|
||||
echo
|
||||
}
|
||||
|
||||
|
|
@ -215,10 +218,12 @@ function _parse_build_opts() {
|
|||
|
||||
function _parse_create_wrappers_opts() {
|
||||
OPT_FORCE=false
|
||||
OPT_BIN_PATH=""
|
||||
while [[ -n "$1" ]]
|
||||
do
|
||||
case "$1" in
|
||||
-f|--force) OPT_FORCE=true ; shift ;;
|
||||
-p|--bin-path) shift ; OPT_BIN_PATH="$1" ; shift ;;
|
||||
*) die "Invalid option $1" ;;
|
||||
esac
|
||||
done
|
||||
|
|
@ -276,7 +281,7 @@ function execute_operation() {
|
|||
fi
|
||||
|
||||
if $ACT_CREATE_WRAPPERS; then
|
||||
create_wrappers $OPT_FORCE
|
||||
create_wrappers $OPT_FORCE "$OPT_BIN_PATH"
|
||||
exit
|
||||
fi
|
||||
|
||||
|
|
@ -300,7 +305,8 @@ function execute_operation() {
|
|||
fi
|
||||
|
||||
# Call create_wrappers in case new bin files have been created
|
||||
trap "create_wrappers" EXIT QUIT TERM
|
||||
# shellcheck disable=SC2064
|
||||
trap "PATH=$PATH create_wrappers" EXIT QUIT TERM
|
||||
$run_env "$BACKEND_COMMAND" "${BACKEND_ARGS}" $OPT_NO_COPY_FILES "${ARGS[@]}"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,4 +24,8 @@ sudo -E "$JUNEST_SCRIPT" groot -- "$CHECK_SCRIPT" --run-root-tests --skip-aur-te
|
|||
# Test the wrappers work
|
||||
"$JUNEST_SCRIPT" create-bin-wrappers --force
|
||||
"$JUNEST_HOME"/usr/bin_wrappers/pacman --help
|
||||
|
||||
"$JUNEST_SCRIPT" create-bin-wrappers --force --bin-path /usr/bin/core_perl/
|
||||
"$JUNEST_HOME"/usr/bin/core_perl_wrappers/shasum --help
|
||||
|
||||
"${JUNEST_BASE}/bin/sudoj" pacman -Syu
|
||||
|
|
|
|||
|
|
@ -15,8 +15,24 @@ COMMON_BWRAP_OPTION="--bind "$JUNEST_HOME" / --bind "$HOME" "$HOME" --bind /tmp
|
|||
CONFIG_PROC_FILE="/proc/config.gz"
|
||||
CONFIG_BOOT_FILE="/boot/config-$($UNAME -r)"
|
||||
PROC_USERNS_CLONE_FILE="/proc/sys/kernel/unprivileged_userns_clone"
|
||||
PROC_USERNS_FILE="/proc/$$/ns/user"
|
||||
|
||||
function _is_user_namespace_enabled() {
|
||||
if [[ -L $PROC_USERNS_FILE ]]
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ -e $PROC_USERNS_CLONE_FILE ]]
|
||||
then
|
||||
# `-q` option in zgrep may cause a gzip: stdout: Broken pipe
|
||||
# Use redirect to /dev/null instead
|
||||
if zgrep_cmd "1" "$PROC_USERNS_CLONE_FILE" > /dev/null
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
local config_file=""
|
||||
if [[ -e $CONFIG_PROC_FILE ]]
|
||||
then
|
||||
|
|
@ -35,19 +51,7 @@ function _is_user_namespace_enabled() {
|
|||
return "$NO_CONFIG_FOUND"
|
||||
fi
|
||||
|
||||
if [[ ! -e $PROC_USERNS_CLONE_FILE ]]
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# `-q` option in zgrep may cause a gzip: stdout: Broken pipe
|
||||
# Use redirect to /dev/null instead
|
||||
if ! zgrep_cmd "1" $PROC_USERNS_CLONE_FILE > /dev/null
|
||||
then
|
||||
return "$UNPRIVILEGED_USERNS_DISABLED"
|
||||
fi
|
||||
|
||||
return 0
|
||||
return "$UNPRIVILEGED_USERNS_DISABLED"
|
||||
}
|
||||
|
||||
function _check_user_namespace() {
|
||||
|
|
@ -101,8 +105,9 @@ function run_env_as_bwrap_fakeroot(){
|
|||
local args=()
|
||||
[[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")")
|
||||
|
||||
# Fix PATH to /usr/bin to make sudo working and avoid polluting with host related bin paths
|
||||
# shellcheck disable=SC2086
|
||||
BWRAP="${backend_command}" JUNEST_ENV=1 bwrap_cmd $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 $backend_args sudo "${DEFAULT_SH[@]}" "${args[@]}"
|
||||
PATH="/usr/bin" BWRAP="${backend_command}" JUNEST_ENV=1 bwrap_cmd $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 $backend_args sudo "${DEFAULT_SH[@]}" "${args[@]}"
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -150,8 +155,9 @@ function run_env_as_bwrap_user() {
|
|||
local args=()
|
||||
[[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")")
|
||||
|
||||
# Resets PATH to avoid polluting with host related bin paths
|
||||
# shellcheck disable=SC2086
|
||||
BWRAP="${backend_command}" JUNEST_ENV=1 bwrap_cmd $COMMON_BWRAP_OPTION $backend_args "${DEFAULT_SH[@]}" "${args[@]}"
|
||||
PATH='' BWRAP="${backend_command}" JUNEST_ENV=1 bwrap_cmd $COMMON_BWRAP_OPTION $backend_args "${DEFAULT_SH[@]}" "${args[@]}"
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ function _run_env_with_proot(){
|
|||
local args=()
|
||||
[[ "$1" != "" ]] && args=("-c" "$(insert_quotes_on_spaces "${@}")")
|
||||
|
||||
PROOT="${backend_command}" JUNEST_ENV=1 proot_cmd "${backend_args}" "${DEFAULT_SH[@]}" "${args[@]}"
|
||||
# Resets PATH to avoid polluting with host related bin paths
|
||||
PATH='' PROOT="${backend_command}" JUNEST_ENV=1 proot_cmd "${backend_args}" "${DEFAULT_SH[@]}" "${args[@]}"
|
||||
}
|
||||
|
||||
function _run_env_with_qemu(){
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@
|
|||
#######################################
|
||||
function create_wrappers() {
|
||||
local force=${1:-false}
|
||||
mkdir -p "${JUNEST_HOME}/usr/bin_wrappers"
|
||||
local bin_path=${2:-/usr/bin}
|
||||
bin_path=${bin_path%/}
|
||||
mkdir -p "${JUNEST_HOME}${bin_path}_wrappers"
|
||||
# Arguments inside a variable (i.e. `JUNEST_ARGS`) separated by quotes
|
||||
# are not recognized normally unless using `eval`. More info here:
|
||||
# https://github.com/fsquillace/junest/issues/262
|
||||
|
|
@ -33,26 +35,26 @@ junest "\${junest_args_array[@]}" -- \$(basename \${0}) "\$@"
|
|||
EOF
|
||||
chmod +x "${JUNEST_HOME}/usr/bin/junest_wrapper"
|
||||
|
||||
cd "${JUNEST_HOME}/usr/bin" || return 1
|
||||
cd "${JUNEST_HOME}${bin_path}" || return 1
|
||||
for file in *
|
||||
do
|
||||
[[ -d $file ]] && continue
|
||||
# Symlinks outside junest appear as broken even though the are correct
|
||||
# Symlinks outside junest appear as broken even though they are correct
|
||||
# within a junest session. The following do not skip broken symlinks:
|
||||
[[ -x $file || -L $file ]] || continue
|
||||
if [[ -e ${JUNEST_HOME}/usr/bin_wrappers/$file ]] && ! $force
|
||||
if [[ -e ${JUNEST_HOME}${bin_path}_wrappers/$file ]] && ! $force
|
||||
then
|
||||
continue
|
||||
fi
|
||||
rm -f "${JUNEST_HOME}/usr/bin_wrappers/$file"
|
||||
ln -s "../bin/junest_wrapper" "${JUNEST_HOME}/usr/bin_wrappers/$file"
|
||||
rm -f "${JUNEST_HOME}${bin_path}_wrappers/$file"
|
||||
ln -s "${JUNEST_HOME}/usr/bin/junest_wrapper" "${JUNEST_HOME}${bin_path}_wrappers/$file"
|
||||
done
|
||||
|
||||
# Remove wrappers no longer needed
|
||||
cd "${JUNEST_HOME}/usr/bin_wrappers" || return 1
|
||||
cd "${JUNEST_HOME}${bin_path}_wrappers" || return 1
|
||||
for file in *
|
||||
do
|
||||
[[ -e ${JUNEST_HOME}/usr/bin/$file || -L ${JUNEST_HOME}/usr/bin/$file ]] || rm -f "$file"
|
||||
[[ -e ${JUNEST_HOME}${bin_path}/$file || -L ${JUNEST_HOME}${bin_path}/$file ]] || rm -f "$file"
|
||||
done
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,50 +58,45 @@ function _test_copy_remaining_files() {
|
|||
}
|
||||
|
||||
function test_is_user_namespace_enabled_no_config_file(){
|
||||
PROC_USERNS_FILE="blah"
|
||||
PROC_USERNS_CLONE_FILE="blah"
|
||||
CONFIG_PROC_FILE="blah"
|
||||
CONFIG_BOOT_FILE="blah"
|
||||
assertCommandFailOnStatus "$NOT_EXISTING_FILE" _is_user_namespace_enabled
|
||||
}
|
||||
|
||||
function test_is_user_namespace_enabled_no_config(){
|
||||
PROC_USERNS_FILE="blah"
|
||||
PROC_USERNS_CLONE_FILE="blah"
|
||||
touch config
|
||||
gzip config
|
||||
# shellcheck disable=SC2034
|
||||
CONFIG_PROC_FILE="config.gz"
|
||||
# shellcheck disable=SC2034
|
||||
CONFIG_BOOT_FILE="blah"
|
||||
assertCommandFailOnStatus "$NO_CONFIG_FOUND" _is_user_namespace_enabled
|
||||
}
|
||||
|
||||
function test_is_user_namespace_enabled_with_config(){
|
||||
echo "CONFIG_USER_NS=y" > config
|
||||
gzip config
|
||||
CONFIG_PROC_FILE="config.gz"
|
||||
CONFIG_BOOT_FILE="blah"
|
||||
PROC_USERNS_CLONE_FILE="not-existing-file"
|
||||
assertCommandSuccess _is_user_namespace_enabled
|
||||
}
|
||||
|
||||
function test_is_user_namespace_enabled_with_userns_clone_file_disabled(){
|
||||
echo "CONFIG_USER_NS=y" > config
|
||||
gzip config
|
||||
CONFIG_PROC_FILE="config.gz"
|
||||
CONFIG_BOOT_FILE="blah"
|
||||
PROC_USERNS_FILE="blah"
|
||||
PROC_USERNS_CLONE_FILE="unprivileged_userns_clone"
|
||||
echo "0" > $PROC_USERNS_CLONE_FILE
|
||||
assertCommandFailOnStatus "$UNPRIVILEGED_USERNS_DISABLED" _is_user_namespace_enabled
|
||||
}
|
||||
|
||||
function test_is_user_namespace_enabled_with_userns_clone_file_enabled(){
|
||||
echo "CONFIG_USER_NS=y" > config
|
||||
gzip config
|
||||
# shellcheck disable=SC2034
|
||||
CONFIG_PROC_FILE="config.gz"
|
||||
# shellcheck disable=SC2034
|
||||
CONFIG_BOOT_FILE="blah"
|
||||
PROC_USERNS_CLONE_FILE="unprivileged_userns_clone"
|
||||
echo "1" > $PROC_USERNS_CLONE_FILE
|
||||
assertCommandSuccess _is_user_namespace_enabled
|
||||
}
|
||||
|
||||
function test_is_user_namespace_enabled_with_proc_userns_file_existing(){
|
||||
PROC_USERNS_FILE="user"
|
||||
ln -s . $PROC_USERNS_FILE
|
||||
PROC_USERNS_CLONE_FILE="blah"
|
||||
assertCommandSuccess _is_user_namespace_enabled
|
||||
}
|
||||
|
||||
function test_run_env_as_bwrap_fakeroot() {
|
||||
assertCommandSuccess run_env_as_bwrap_fakeroot "" "" "false"
|
||||
assertEquals "$BWRAP $COMMON_BWRAP_OPTION --cap-add ALL --uid 0 --gid 0 sudo /bin/sh --login" "$(cat "$STDOUTF")"
|
||||
|
|
|
|||
|
|
@ -124,4 +124,15 @@ function test_create_wrappers_executable_no_longer_exist(){
|
|||
assertTrue "myfile wrapper should not exist" "[ ! -x $JUNEST_HOME/usr/bin_wrappers/myfile ]"
|
||||
}
|
||||
|
||||
function test_create_wrappers_custom_bin_path(){
|
||||
mkdir -p "$JUNEST_HOME"/usr/mybindir
|
||||
touch "$JUNEST_HOME"/usr/mybindir/myfile
|
||||
chmod +x "$JUNEST_HOME"/usr/mybindir/myfile
|
||||
assertCommandSuccess create_wrappers false /usr/mybindir/
|
||||
assertEquals "" "$(cat "$STDOUTF")"
|
||||
assertTrue "bin_wrappers should exist" "[ -e $JUNEST_HOME/usr/mybindir_wrappers ]"
|
||||
assertTrue "myfile wrapper should exist" "[ -x $JUNEST_HOME/usr/mybindir_wrappers/myfile ]"
|
||||
}
|
||||
|
||||
|
||||
source "$(dirname "$0")"/../utils/shunit2
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue