Per user dockerd installation scripts. (#13)

This commit is contained in:
Ravin Perera
2021-06-17 13:47:06 +05:30
committed by GitHub
parent fb25a4025b
commit f2e70be7f6
6 changed files with 179 additions and 120 deletions

View File

@@ -1,93 +0,0 @@
#!/bin/sh
# Sashimono installation script.
sashimono_user=sashimono
sashimono_user_dir=/home/$sashimono_user
sashimono_agent_dir=$sashimono_user_dir/sashimono-agent
dockerd_user=sashidockerd
dockerd_user_dir=/home/$dockerd_user
dockerd_socket_dir=$dockerd_user_dir/.docker/run
dockerd_socket=unix://$dockerd_socket_dir/docker.sock
mod_netfilter=br_netfilter
# Check if users already exists.
[ `id -u $sashimono_user 2>/dev/null || echo -1` -ge 0 ] && echo "User '$sashimono_user' already exists." && exit 1
[ `id -u $dockerd_user 2>/dev/null || echo -1` -ge 0 ] && echo "User '$dockerd_user' already exists." && exit 1
# Install curl if not exists (required to download installation artifacts).
[ ! $(command -v curl &> /dev/null) ] && apt-get install -y curl
# --------------------------------------
# Setup dockerd user and service.
# --------------------------------------
useradd --shell /usr/sbin/nologin -m $dockerd_user
usermod --lock $dockerd_user
loginctl enable-linger $dockerd_user # Enable lingering to support rootless dockerd service installation.
chmod o-rwx $dockerd_user_dir
echo "Created '$dockerd_user' user."
dockerd_user_runtime_dir=/run/user/$(id -u $dockerd_user)
# Download and install rootless dockerd.
sudo -u $dockerd_user mkdir -p $dockerd_socket_dir
loginctl enable-linger $dockerd_user
echo "Installing rootless dockerd..."
curl --silent -fSL https://get.docker.com/rootless | sudo -u $dockerd_user XDG_RUNTIME_DIR=$dockerd_user_runtime_dir sh > /dev/null
echo "Installed rootless dockerd."
# After installing rootless dockerd, we need to stop and restart the dockerd service with our own daemon config.
# Create new daemon config.
# - Disable dockerd inter-container communication.
# - Specify custom docker socket path. (So we can specify custom dir execute permission to user group)
sudo -u $dockerd_user mkdir -p $dockerd_user_dir/.config/docker
echo '{"icc":false,"hosts":["'$dockerd_socket'"]}' | sudo -u $dockerd_user tee $dockerd_user_dir/.config/docker/daemon.json >/dev/null
# We need br_netfilter kernel module to make icc=false work. Otherwise dockerd won't start.
echo "Checking for '$mod_netfilter' kernel module..."
modprobe -n --first-time $mod_netfilter && modprobe $mod_netfilter && echo "Adding $mod_netfilter to /etc/modules" && printf "\n$mod_netfilter\n" >>/etc/modules
# Stop and start the dockerd service.
sudo -u $dockerd_user XDG_RUNTIME_DIR=$dockerd_user_runtime_dir systemctl --user stop docker.service
sudo -u $dockerd_user XDG_RUNTIME_DIR=$dockerd_user_runtime_dir systemctl --user start docker.service
echo "Restarted dockerd service with Sashimono configuration."
# Setup env variables for dockerd user.
echo "
export XDG_RUNTIME_DIR=$dockerd_user_runtime_dir
export PATH=$dockerd_user_dir/bin:\$PATH
export DOCKER_HOST=$dockerd_socket" >>$dockerd_user_dir/.bashrc
# --------------------------------------
# Setup Sashimono user and agent.
# --------------------------------------
useradd --shell /usr/sbin/nologin -m $sashimono_user
usermod --lock $sashimono_user
chmod o-rwx $sashimono_user_dir
echo "Created '$sashimono_user' user."
# Following two permissions are required for Sashimono to interact with the dockerd UNIX socket.
# Add sashimono user to docker user group.
usermod -a -G $dockerd_user $sashimono_user
# Assign group execute permission for docker socket dir.
chmod g+x $dockerd_socket_dir
# Setup sashimono agent directory.
mkdir -p $sashimono_agent_dir
# Copy docker client for sashimono user.
cp $dockerd_user_dir/bin/docker $sashimono_agent_dir/
# TODO: Copy sashimono agent binaries.
# Set owner and group to be sashimono user.
chown --recursive $sashimono_user.$sashimono_user $sashimono_agent_dir
echo "Configured $sashimono_agent_dir"
# Configure docker client context.
sudo -u $sashimono_user $sashimono_agent_dir/docker context create sashidockerctx --docker host=$dockerd_socket >/dev/null
sudo -u $sashimono_user $sashimono_agent_dir/docker context use sashidockerctx >/dev/null
# Set PATH for convenience during interactive shell sessions.
echo "export PATH=$sashimono_agent_dir:\$PATH" >>$sashimono_user_dir/.bashrc
echo "Done."

42
installer/sashimono-install.sh Executable file
View File

@@ -0,0 +1,42 @@
#!/bin/bash
# Sashimono agent installation script.
# This must be executed with root privileges.
sashimono_bin=/usr/bin/sashimono-agent
docker_bin=/usr/bin/sashimono-dockerbin
echo "Installing Sashimono..."
# Create bin dirs first so it automatically checks for privileged access.
mkdir -p $sashimono_bin
[ "$?" == "1" ] && echo "Could not create '$sashimono_bin'. Make sure you are running as sudo." && exit 1
mkdir -p $docker_bin
[ "$?" == "1" ] && echo "Could not create '$docker_bin'. Make sure you are running as sudo." && exit 1
# Install curl if not exists (required to download installation artifacts).
if ! command -v curl &> /dev/null
then
apt-get install -y curl
fi
# Install Sashimono agent binaries into sashimono bin dir.
# TODO.
# Download docker packages into a tmp dir and extract into docker bin.
echo "Installing rootless docker packages into $docker_bin"
tmp=$(mktemp -d)
cd $tmp
curl https://download.docker.com/linux/static/stable/$(uname -m)/docker-20.10.7.tgz --output docker.tgz
curl https://download.docker.com/linux/static/stable/$(uname -m)/docker-rootless-extras-20.10.7.tgz --output rootless.tgz
cd $docker_bin
tar zxf $tmp/docker.tgz --strip-components=1
tar zxf $tmp/rootless.tgz --strip-components=1
rm -r $tmp
# Check whether installation dir is still empty.
[ -z "$(ls -A $docker_bin 2>/dev/null)" ] && echo "Installation failed." && exit 1
echo "Done."
exit 0

View File

@@ -0,0 +1,13 @@
#!/bin/bash
# Sashimono agent uninstall script.
sashimono_bin=/usr/bin/sashimono-agent
docker_bin=/usr/bin/sashimono-dockerbin
# TODO: Uninstall all contract instance users
echo "Deleting binaries..."
rm -r $sashimono_bin
rm -r $docker_bin
echo "Done."

View File

@@ -1,27 +0,0 @@
#!/bin/sh
# Sashimono agent uninstall script.
sashimono_user=sashimono
dockerd_user=sashidockerd
dockerd_user_dir=/home/$dockerd_user
# Uninstall rootless dockerd.
echo "Uninstalling rootless dockerd..."
sudo -u $dockerd_user bash -i -c "$dockerd_user_dir/bin/dockerd-rootless-setuptool.sh uninstall"
echo "Removing rootless Docker data..."
sudo -u $dockerd_user $dockerd_user_dir/bin/rootlesskit rm -rf $dockerd_user_dir/.local/share/docker
# Kill all processes for users.
echo "Killing user processes..."
loginctl disable-linger $dockerd_user
pkill -SIGKILL -u $dockerd_user
pkill -SIGKILL -u $sashimono_user
echo "Deleting users..."
userdel $sashimono_user # Remove sashimono user first because it's in docker user's group.
userdel $dockerd_user
rm -r /home/$sashimono_user
rm -r /home/$dockerd_user
echo "Done."

61
installer/user-install.sh Executable file
View File

@@ -0,0 +1,61 @@
#!/bin/bash
# Sashimono contract instance user installation script.
# This is intended to be called by Sashimono agent.
# $1 - A number with 25 or less digits.
uid=$1
[ -z "$uid" ] && echo "ARGS,INST_ERR" && exit 1
[ ${#uid} -gt 25 ] && echo "ARGS,INST_ERR" && exit 1
[[ "$uid" =~ [^0-9] ]] && echo "ARGS,INST_ERR" && exit 1
user="sashi$uid"
user_dir=/home/$user
docker_bin=/usr/bin/sashimono-dockerbin
# Check if users already exists.
[ `id -u $user 2>/dev/null || echo -1` -ge 0 ] && echo "HAS_USER,INST_ERR" && exit 1
function rollback() {
echo "Rolling back user installation. $1"
$(pwd)/user-uninstall.sh $uid
echo "Rolled back the installation."
echo "$1,INST_ERR" && exit 1
}
# Setup user and dockerd service.
useradd --shell /usr/sbin/nologin -m $user
usermod --lock $user
loginctl enable-linger $user # Enable lingering to support rootless dockerd service installation.
chmod o-rwx $user_dir
echo "Created '$user' user."
user_id=$(id -u $user)
user_runtime_dir="/run/user/$user_id"
dockerd_socket="unix://$user_runtime_dir/docker.sock"
# Setup env variables for the user.
echo "
export XDG_RUNTIME_DIR=$user_runtime_dir
export PATH=$docker_bin:\$PATH
export DOCKER_HOST=$dockerd_socket" >>$user_dir/.bashrc
echo "Updated user .bashrc."
# Wait until user systemd is functionning.
user_systemd=""
for (( i=0; i<30; i++ ))
do
sleep 0.1
user_systemd=$(sudo -u $user XDG_RUNTIME_DIR=$user_runtime_dir systemctl --user is-system-running 2>/dev/null)
[ "$user_systemd" == "running" ] && break
done
[ "$user_systemd" != "running" ] && rollback "NO_SYSTEMD"
echo "Installing rootless dockerd for user."
sudo -u $user bash -i -c "$docker_bin/dockerd-rootless-setuptool.sh install"
svcstat=$(sudo -u $user XDG_RUNTIME_DIR=$user_runtime_dir systemctl --user is-active docker.service)
[ "$svcstat" != "active" ] && rollback "NO_DOCKERSVC"
echo "Installed rootless dockerd."
echo "$user_id,$user,$dockerd_socket,INST_SUC"
exit 0

63
installer/user-uninstall.sh Executable file
View File

@@ -0,0 +1,63 @@
#!/bin/bash
# Sashimono contract instance user uninstall script.
# This is intended to be called by Sashimono agent or via the user-install script for rollback.
# $1 - A number with 25 or less digits.
uid=$1
[ -z "$uid" ] && echo "ARGS,UNINST_ERR" && exit 1
[ ${#1} -gt 25 ] && echo "ARGS,UNINST_ERR" && exit 1
[[ "$uid" =~ [^0-9] ]] && echo "ARGS,UNINST_ERR" && exit 1
user="sashi$uid"
user_dir=/home/$user
docker_bin=/usr/bin/sashimono-dockerbin
# Check if users exists.
if [[ `id -u $user 2>/dev/null || echo -1` -ge 0 ]]; then
:
else
echo "NO_USER,UNINST_ERR"
exit 1
fi
# Uninstall rootless dockerd.
echo "Uninstalling rootless dockerd."
sudo -u $user bash -i -c "$docker_bin/dockerd-rootless-setuptool.sh uninstall"
echo "Removing rootless docker data."
sudo -u $user $docker_bin/rootlesskit rm -rf $user_dir/.local/share/docker
# Gracefully terminate user processes.
echo "Terminating user processes."
loginctl disable-linger $user
pkill -SIGINT -u $user
sleep 0.5
echo "Unmounting user filesystems."
fsmounts=$(cat /proc/mounts | cut -d ' ' -f 2 | grep "/home/$user")
readarray -t mntarr <<<"$fsmounts"
for mnt in "${mntarr[@]}"
do
[ -z "$mnt" ] || umount $mnt
done
# Force kill user processes.
procs=$(ps -U root 2>/dev/null | wc -l)
if [ "$procs" != "0" ]; then
# Wait for some time and check again.
sleep 1
procs=$(ps -U root 2>/dev/null | wc -l)
if [ "$procs" != "0" ]; then
echo "Force killing user processes."
pkill -SIGKILL -u $user
fi
fi
echo "Deleting user."
userdel $user
rm -r /home/$user
[ -d /home/$user ] && echo "NOT_CLEAN,UNINST_ERR" && exit 1
echo "UNINST_SUC"
exit 0