Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allows specifying another user to have zsh installed for within environment using -u argument #28

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
test:
strategy:
matrix:
image: [ ubuntu, ubuntu-14.04, alpine, debian, amazonlinux, centos7, rockylinux8, rockylinux9, fedora]
image: [ ubuntu, ubuntu-14.04, alpine, debian, amazonlinux, rockylinux8, rockylinux9, fedora]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/
RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v1.2.0/zsh-in-docker.sh)" -- \
-a 'CASE_SENSITIVE="true"'
```

- `-u <username>` - You can install zsh in a specified user's directory, for example if you want zsh to be installed but the user not to have access to privleges that the root user has.
- `-x` - Skip installation of dependencies: `zsh`, `git`, `curl`. If you are having issues with the script failing to
install these dependencies due to sudo permissions, you can install them yourself in a prior step, and use this flag
to make the script skip their installation
Expand All @@ -52,6 +52,13 @@ RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/
-t robbyrussell
```

```Dockerfile
# Same command as above, but installs zsh for specified user: dockeruser
RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v1.2.0/zsh-in-docker.sh)" -- \
-t robbyrussell \
-u dockeruser
```

```Dockerfile
# Uses "git", "ssh-agent" and "history-substring-search" bundled plugins
RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v1.2.0/zsh-in-docker.sh)" -- \
Expand Down
104 changes: 89 additions & 15 deletions test.sh
Original file line number Diff line number Diff line change
@@ -1,50 +1,124 @@
#!/usr/bin/env bash

source ./assert.sh

set -e

trap 'docker compose stop -t 1' EXIT INT


identify_os() {
container=$1
if docker exec $container sh -c "[ -f /etc/os-release ]"; then
docker exec $container sh -c "cat /etc/os-release" | grep -E "^ID=" | cut -d= -f2 | tr -d '"'
elif docker exec $container sh -c "[ -f /etc/alpine-release ]"; then
echo "alpine"
else
echo "unknown"
fi
}

create_user() {
container=$1
username=$2
os=$(identify_os $container)

case $os in
alpine)
docker exec $container adduser -D $username
;;
ubuntu|debian)
docker exec $container useradd -m $username
;;
amzn|amazonlinux)
docker exec $container yum install -y shadow-utils
docker exec $container useradd -m $username
;;
centos|rocky|fedora)
docker exec $container useradd -m $username
;;
*)
echo "Error: Unsupported operating system for user creation."
return 1
;;
esac
}

test_suite() {
image_name=$1
user_type=$2

echo
echo "########## Testing in a $image_name container"
echo "########## Testing in a $image_name container as $user_type"
echo

set -x
docker compose rm --force --stop test-$image_name || true

docker compose rm --force --stop test-$image_name || true
docker compose up -d test-$image_name

docker cp zsh-in-docker.sh zsh-in-docker-test-${image_name}-1:/tmp
docker exec zsh-in-docker-test-${image_name}-1 sh /tmp/zsh-in-docker.sh \
-t https://github.com/denysdovhan/spaceship-prompt \
-p git -p git-auto-fetch \
-p https://github.com/zsh-users/zsh-autosuggestions \
-p https://github.com/zsh-users/zsh-completions \
-a 'CASE_SENSITIVE="true"' \
-a 'HYPHEN_INSENSITIVE="true"'

if [ "$user_type" = "non-root" ]; then
# Create a non-root user
create_user zsh-in-docker-test-${image_name}-1 dockeruser
docker exec zsh-in-docker-test-${image_name}-1 sh /tmp/zsh-in-docker.sh \
-t https://github.com/denysdovhan/spaceship-prompt \
-p git -p git-auto-fetch \
-p https://github.com/zsh-users/zsh-autosuggestions \
-p https://github.com/zsh-users/zsh-completions \
-a 'CASE_SENSITIVE="true"' \
-a 'HYPHEN_INSENSITIVE="true"' \
-u dockeruser
else
docker exec zsh-in-docker-test-${image_name}-1 sh /tmp/zsh-in-docker.sh \
-t https://github.com/denysdovhan/spaceship-prompt \
-p git -p git-auto-fetch \
-p https://github.com/zsh-users/zsh-autosuggestions \
-p https://github.com/zsh-users/zsh-completions \
-a 'CASE_SENSITIVE="true"' \
-a 'HYPHEN_INSENSITIVE="true"'
fi

set +x

echo

VERSION=$(docker exec zsh-in-docker-test-${image_name}-1 zsh --version)
ZSHRC=$(docker exec zsh-in-docker-test-${image_name}-1 cat /root/.zshrc)

if [ "$user_type" = "non-root" ]; then
ZSHRC=$(docker exec zsh-in-docker-test-${image_name}-1 cat /home/dockeruser/.zshrc)
HOME_DIR="/home/dockeruser"
else
ZSHRC=$(docker exec zsh-in-docker-test-${image_name}-1 cat /root/.zshrc)
HOME_DIR="/root"
fi

echo "########################################################################################"
echo "$ZSHRC"
echo "########################################################################################"

echo "Test: zsh 5 was installed" && assert_contain "$VERSION" "zsh 5" "!"
echo "Test: ~/.zshrc was generated" && assert_contain "$ZSHRC" 'ZSH="/root/.oh-my-zsh"' "!"
echo "Test: ~/.zshrc was generated" && assert_contain "$ZSHRC" "ZSH=\"$HOME_DIR/.oh-my-zsh\"" "!"
echo "Test: theme was configured" && assert_contain "$ZSHRC" 'ZSH_THEME="spaceship-prompt/spaceship"' "!"
echo "Test: plugins were configured" && assert_contain "$ZSHRC" 'plugins=(git git-auto-fetch zsh-autosuggestions zsh-completions )' "!"
echo "Test: line 1 is appended to ~/.zshrc" && assert_contain "$ZSHRC" 'CASE_SENSITIVE="true"' "!"
echo "Test: line 2 is appended to ~/.zshrc" && assert_contain "$ZSHRC" 'HYPHEN_INSENSITIVE="true"' "!"
echo "Test: newline is expanded when append lines" && assert_not_contain "$ZSHRC" '\nCASE_SENSITIVE="true"' "!"

echo
echo "######### Success! All tests are passing for ${image_name}"
if [ "$user_type" = "non-root" ]; then
echo "Test: .zshrc owner is dockeruser" && assert_contain "$(docker exec zsh-in-docker-test-${image_name}-1 ls -l /home/dockeruser/.zshrc)" "dockeruser" "!"
echo "Test: .oh-my-zsh owner is dockeruser" && assert_contain "$(docker exec zsh-in-docker-test-${image_name}-1 ls -ld /home/dockeruser/.oh-my-zsh)" "dockeruser" "!"
fi

echo
echo "######### Success! All tests are passing for ${image_name} as ${user_type}"
docker compose stop -t 1 test-$image_name
}

images=${*:-"alpine ubuntu ubuntu-14.04 debian amazonlinux centos7 rockylinux8 rockylinux9 fedora"}

for image in $images; do
test_suite $image
done
test_suite $image "root"
test_suite $image "non-root"
done
47 changes: 34 additions & 13 deletions zsh-in-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ THEME=default
PLUGINS=""
ZSHRC_APPEND=""
INSTALL_DEPENDENCIES=true
TARGET_USER=$(whoami) # Default to current user

while getopts ":t:p:a:x" opt; do
while getopts ":t:p:a:xu:" opt; do
case ${opt} in
t) THEME=$OPTARG
;;
Expand All @@ -37,6 +38,8 @@ while getopts ":t:p:a:x" opt; do
;;
x) INSTALL_DEPENDENCIES=false
;;
u) TARGET_USER=$OPTARG
;;
\?)
echo "Invalid option: $OPTARG" 1>&2
;;
Expand All @@ -47,8 +50,20 @@ while getopts ":t:p:a:x" opt; do
done
shift $((OPTIND -1))

# Get the target user's home directory
if [ "$TARGET_USER" = "root" ]; then
TARGET_HOME=$HOME
else
TARGET_HOME=$(getent passwd "$TARGET_USER" | cut -d: -f6)
fi

if [ -z "$TARGET_HOME" ]; then
echo "Error: Unable to determine home directory for user $TARGET_USER"
exit 1
fi

echo
echo "Installing Oh-My-Zsh with:"
echo "Installing Oh-My-Zsh for user $TARGET_USER with:"
echo " THEME = $THEME"
echo " PLUGINS = $PLUGINS"
echo
Expand Down Expand Up @@ -150,17 +165,22 @@ fi

cd /tmp

# Install On-My-Zsh
if [ ! -d "$HOME"/.oh-my-zsh ]; then
sh -c "$(curl https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" "" --unattended
# Install Oh My Zsh
if [ ! -d "$TARGET_HOME/.oh-my-zsh" ]; then
su - $TARGET_USER -c '
export HOME="'"$TARGET_HOME"'"
export USER="'"$TARGET_USER"'"
export ZDOTDIR="$HOME"
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
'
fi

# Generate plugin list
plugin_list=""
for plugin in $PLUGINS; do
if [ "$(echo "$plugin" | grep -E '^http.*')" != "" ]; then
plugin_name=$(basename "$plugin")
git clone "$plugin" "$HOME"/.oh-my-zsh/custom/plugins/"$plugin_name"
su - $TARGET_USER -c "git clone '$plugin' '$TARGET_HOME/.oh-my-zsh/custom/plugins/$plugin_name'"
else
plugin_name=$plugin
fi
Expand All @@ -170,18 +190,19 @@ done
# Handle themes
if [ "$(echo "$THEME" | grep -E '^http.*')" != "" ]; then
theme_repo=$(basename "$THEME")
THEME_DIR="$HOME/.oh-my-zsh/custom/themes/$theme_repo"
git clone "$THEME" "$THEME_DIR"
theme_name=$(cd "$THEME_DIR"; ls *.zsh-theme | head -1)
THEME_DIR="$TARGET_HOME/.oh-my-zsh/custom/themes/$theme_repo"
su - $TARGET_USER -c "git clone '$THEME' '$THEME_DIR'"
theme_name=$(su - $TARGET_USER -c "cd '$THEME_DIR' && ls *.zsh-theme | head -1")
theme_name="${theme_name%.zsh-theme}"
THEME="$theme_repo/$theme_name"
fi

# Generate .zshrc
zshrc_template "$HOME" "$THEME" "$plugin_list" > "$HOME"/.zshrc
zshrc_template "$TARGET_HOME" "$THEME" "$plugin_list" > "$TARGET_HOME/.zshrc"
chown $TARGET_USER:$TARGET_USER "$TARGET_HOME/.zshrc"

# Install powerlevel10k if no other theme was specified
if [ "$THEME" = "default" ]; then
git clone --depth 1 https://github.com/romkatv/powerlevel10k "$HOME"/.oh-my-zsh/custom/themes/powerlevel10k
powerline10k_config >> "$HOME"/.zshrc
fi
su - $TARGET_USER -c "git clone --depth=1 https://github.com/romkatv/powerlevel10k.git '$TARGET_HOME/.oh-my-zsh/custom/themes/powerlevel10k'"
powerline10k_config >> "$TARGET_HOME/.zshrc"
fi