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/systemctlthat 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 "$@"proxyexecddaemon - 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-updatefor 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.socketusing 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.