Issue
- Can't use cPanel ea-podman to deploy containers, the following error appears:
$ /scripts/ea-podman install ea-tomcat101
“ea-tomcat101” looks like an EA4 package but it is not a container based EA4 package. Please use the correct package name (or install it if it was uninstalled but its directory left behind) or use a name that does not start w/ `ea-`.or
/usr/local/cpanel/scripts/ea-podman install ea-redis62
Can't exec "podman": No such file or directory at /opt/cpanel/ea-podman/lib/ea_podman/util.pm line 90.
Failed to create container - How to run a few select podman containers based on images we allow
Environment
- cPanel
- CageFS
- ea-podman
Solution
A proxyexec machinery is used to implement this workaround. Should work on CloudLinux 8 and CloudLinux 9.
- Make sure to install the packages
dnf install ea-tomcat101 ea-podman
- Create systemctl wrapper at
/usr/local/bin/systemctl
that setsDBUS_SESSION_BUS_ADDRESS envvar
(it’s needed because proxyexec seemingly does not forward environment variables to the#!/usr/bin/env bash
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus
exec /usr/bin/systemctl "$@"proxyexecd
daemon - not all, at least):
- Make it executable:
chmod a+x /usr/local/bin/systemctl
- Create the following proxy commands config at
/etc/cagefs/ea-podman.proxy.commands
:
PODMAN=/usr/bin/podman
SYSTEMCTL=/usr/local/bin/systemctl - Add RPM into CageFS
cagefsctl --addrpm ea-cpanel-tools
- Create the following cagefs config at
/etc/cagefs/conf.d/ea-podman.cnf
:
[ea-podman]
paths=/usr/bin/podman, /usr/local/bin/systemctl - Run
cagefsctl --force-update
for configs to take effect. - Follow this instruction (from under the user that has cagefs enabled)
Note: Before installing for user runloginctl enable-linger <username>
- As this user, you can now connect to the
~/ea-podman/<redis-container-name>/redis.socket
using any client Redis client.
Additional considerations
For increased security, systemctl
and podman
binaries (that will be executed outside cagefs) might be additionally guarded with custom wrappers.
For example, create /usr/share/cagefs/safeprograms/cagefs.proxy.systemctl
proxy wrapper with the below code
To use this proxy, modify /etc/cagefs/ea-podman.proxy.commands
as follows
PODMAN=/usr/bin/podman
SYSTEMCTL:cagefs.proxy.systemctl=/usr/local/bin/systemctl
Here is /usr/share/cagefs/safeprograms/cagefs.proxy.systemctl file content:
#!/bin/bash
# Main script logic
if [[ $EUID -eq 0 ]]; then
echo 'Cannot be run as root'
exit 1
fi
# Function to check if the service corresponds to a running container
is_container() {
local container_name=${1#container-}
container_name=${container_name%.service}
podman ps -a --format "{{.Names}}" | grep -q "^${container_name}$"
}
# Function to check for the --user flag and trimming it
validate_params() {
echo "$@"
local user_flag_found=0
local remaining_args=()
for arg in "$@"; do
if [[ "$arg" == "--user" ]]; then
user_flag_found=1
else
remaining_args+=("$arg")
fi
done
if [[ $user_flag_found -ne 1 ]]; then
echo "Error: Script must be called with the --user flag."
exit 1
fi
local action=${remaining_args[0]}
# Check if the action is valid
if [[ "$action" != "start" && "$action" != "stop" && "$action" != "restart" && "$action" != "enable" && "$action" != "disable" && "$action" == "daemon-reload" && "$action" == "reset-failed" ]]; then
echo "Error: Action must be 'start', 'stop', 'restart', 'enable', 'disable', 'daemon-reload' and 'reset-failed'."
exit 1
fi
if [[ "$action" != "daemon-reload" && "$action" != "reset-failed" ]]; then
local service_name=${remaining_args[1]}
# Check if the service corresponds to a running container
if ! is_container "$service_name"; then
echo "Error: No container corresponds to the provided service name."
exit 1
fi
fi
}
validate_params "$@"
USR=`/usr/bin/whoami`
TOKEN=`/bin/cat /var/.cagefs/.cagefs.token`
# It's user's tmp directory and write to it is secure procedure
# because this script is running only under usual user
PIDFILE="/tmp/.cagefs.proxy.$$"
USER_INTERRUPT=13
CWD=`pwd`
ctrl_c_handler() {
if [[ -f "$PIDFILE" ]]; then
pid=`/bin/cat $PIDFILE`
/bin/rm -f $PIDFILE > /dev/null 2>&1
/bin/kill -s SIGINT "$pid" > /dev/null 2>&1
fi
exit $USER_INTERRUPT
}
if [[ -e /var/.cagefs/origin ]]; then
ORIGIN=`/bin/cat /var/.cagefs/origin`
REMOTE="/usr/bin/ssh -F /etc/ssh/cagefs-rexec_config $USR@$ORIGIN"
$REMOTE CAGEFS_TOKEN="$TOKEN" /usr/sbin/proxyexec -c cagefs.sock "$USR" "$CWD" ALIAS $$ "$@"
RETVAL=$?
else
trap 'ctrl_c_handler' 2
CAGEFS_TOKEN="$TOKEN" /usr/sbin/proxyexec -c cagefs.sock "$USR" "$CWD" ALIAS $$ "$@"
RETVAL=$?
/bin/rm -f $PIDFILE > /dev/null 2>&1
fi
exit $RETVAL
Comments
0 comments
Please sign in to leave a comment.