1
0
mirror of https://github.com/mail-in-a-box/mailinabox.git synced 2025-04-07 00:47:05 +00:00

avoid using PYTHONPATH to enable setup mod hooks, which is problematic for managment command line tool use

- save the directory path to setup mods in /etc/mailinabox.conf
- dynamically add the path to python during hook initialization
This commit is contained in:
downtownallday 2022-10-24 16:24:44 -04:00
parent bb969f16ae
commit 7fa070aed8
5 changed files with 73 additions and 24 deletions

View File

@ -35,5 +35,6 @@ if [ $? -eq 0 ]; then
ehdd/postinstall.sh || exit 1 ehdd/postinstall.sh || exit 1
else else
echo "setup/start.sh failed" echo "setup/start.sh failed"
exit 1
fi fi

View File

@ -20,12 +20,29 @@ log = logging.getLogger(__name__)
# update_hook_handlers() for the format # update_hook_handlers() for the format
# #
mutex = Lock() mutex = Lock()
initialized = False
handlers = [] handlers = []
mods_env = {} # dict derived from /etc/mailinabox_mods.conf mods_env = {} # dict of /etc/mailinabox.conf and /etc/mailinabox_mods.conf
def update_hook_handlers(): def update_hook_handlers():
global handlers, mods_env global handlers, mods_env
# load /etc/mailinabox.conf and /etc/mailinabox_mods.conf
new_mods_env = load_environment()
if os.path.isfile('/etc/mailinabox_mods.conf'):
load_env_vars_from_file(
'/etc/mailinabox_mods.conf',
strip_quotes=True,
merge_env=new_mods_env
)
new_handlers= [] new_handlers= []
if 'LOCAL_MODS_DIR' in new_mods_env:
dir = new_mods_env['LOCAL_MODS_DIR']
if dir not in sys.path:
sys.path.append(dir)
for dir in sys.path: for dir in sys.path:
hooks_dir = os.path.join(dir, "management_hooks_d") hooks_dir = os.path.join(dir, "management_hooks_d")
if not os.path.isdir(hooks_dir): if not os.path.isdir(hooks_dir):
@ -47,19 +64,11 @@ def update_hook_handlers():
new_handlers = sorted(new_handlers, key=lambda path: path['sort_id']) new_handlers = sorted(new_handlers, key=lambda path: path['sort_id'])
log.info('%s hook handlers', len(new_handlers)) log.info('%s hook handlers', len(new_handlers))
# load /etc/mailinabox_mods.conf
new_mods_env = load_environment()
if os.path.isfile('/etc/mailinabox_mods.conf'):
load_env_vars_from_file(
'/etc/mailinabox_mods.conf',
strip_quotes=True,
merge_env=new_mods_env
)
# update globals # update globals
mutex.acquire() mutex.acquire()
handlers = new_handlers handlers = new_handlers
mods_env = new_mods_env mods_env = new_mods_env
initialized = True
mutex.release() mutex.release()
@ -68,6 +77,9 @@ def exec_hooks(hook_name, data):
# contents of which are specific to the type of hook. Handlers may # contents of which are specific to the type of hook. Handlers may
# modify the dictionary to return updates to the caller. # modify the dictionary to return updates to the caller.
if not initialized:
update_hook_handlers()
mutex.acquire() mutex.acquire()
cur_handlers = handlers cur_handlers = handlers
cur_mods_env = mods_env cur_mods_env = mods_env

View File

@ -317,18 +317,54 @@ say() {
echo "$@" echo "$@"
} }
wait_for_management_daemon() {
local progress="${1:-progress}" # show progress? "progress"/"no-progress"
local max_wait="${2:-60}" # seconds, 0=forever
local start=$(date +%s)
local elapsed=0 now
[ "$max_wait" = "forever" ] && max_wait=0
# Wait for the management daemon to start...
until nc -z -w 4 127.0.0.1 10222
do
now=$(date +%s)
# let returns 1 if the equasion evaluates to zero, which will
# cause the script to exit because of set -e. add one.
[ $now -eq $start ] && let now+=1
let elapsed="$now - $start"
if [ $max_wait -ne 0 -a $elapsed -gt $max_wait ]; then
echo "Timeout waiting for Mail-in-a-Box management daemon to start"
return 1
fi
if [ "$progress" = "progress" ]; then
echo Waiting for the Mail-in-a-Box management daemon to start...
fi
sleep 2
done
}
install_hook_handler() { install_hook_handler() {
# this is used by local setup mods to install a hook handler for # this is used by local setup mods to install a hook handler for
# the management daemon # the management daemon. source /etc/mailinabox.conf before
# calling
local handler_file="$1" local handler_file="$1"
local dst="${LOCAL_MODS_DIR:-local}/management_hooks_d" local dst="${LOCAL_MODS_DIR:-local}/management_hooks_d"
mkdir -p "$dst" if [ ! -d "$dst" -o -e "$dst/$(basename "$handler_file")" ]; then
cp "$handler_file" "$dst" mkdir -p "$dst"
# let the daemon know there's a new hook handler cp "$handler_file" "$dst"
tools/hooks_update >/dev/null if systemctl is-active --quiet mailinabox; then
systemctl restart mailinabox
wait_for_management_daemon no-progress
fi
else
cp "$handler_file" "$dst"
# let the daemon know there's a new hook handler
tools/hooks_update >/dev/null
fi
} }
remove_hook_handler() { remove_hook_handler() {
# source /etc/mailinabox.conf before calling
local hook_py=$(basename "$1") local hook_py=$(basename "$1")
local dst="${LOCAL_MODS_DIR:-local}/management_hooks_d/$hook_py" local dst="${LOCAL_MODS_DIR:-local}/management_hooks_d/$hook_py"
if [ -e "$dst" ]; then if [ -e "$dst" ]; then

View File

@ -103,7 +103,7 @@ tr -cd '[:xdigit:]' < /dev/urandom | head -c 32 > /var/lib/mailinabox/api.key
chmod 640 /var/lib/mailinabox/api.key chmod 640 /var/lib/mailinabox/api.key
source $venv/bin/activate source $venv/bin/activate
export PYTHONPATH=$(pwd)/management:${LOCAL_MODS_DIR:-$(pwd)/local} export PYTHONPATH=$(pwd)/management
exec gunicorn --log-level ${MGMT_LOG_LEVEL:-info} -b localhost:10222 -w 1 --timeout 630 wsgi:app exec gunicorn --log-level ${MGMT_LOG_LEVEL:-info} -b localhost:10222 -w 1 --timeout 630 wsgi:app
EOF EOF
chmod +x $inst_dir/start chmod +x $inst_dir/start

View File

@ -105,6 +105,9 @@ if [ ! -f $STORAGE_ROOT/mailinabox-ldap.version ]; then
chown $STORAGE_USER.$STORAGE_USER $STORAGE_ROOT/mailinabox-ldap.version chown $STORAGE_USER.$STORAGE_USER $STORAGE_ROOT/mailinabox-ldap.version
fi fi
# normalize the directory path for setup mods
LOCAL_MODS_DIR="$(realpath -m "${LOCAL_MODS_DIR:-${DEFAULT_LOCAL_MODS_DIR:-local}}")"
# Save the global options in /etc/mailinabox.conf so that standalone # Save the global options in /etc/mailinabox.conf so that standalone
# tools know where to look for data. The default MTA_STS_MODE setting # tools know where to look for data. The default MTA_STS_MODE setting
# is blank unless set by an environment variable, but see web.sh for # is blank unless set by an environment variable, but see web.sh for
@ -118,6 +121,7 @@ PUBLIC_IPV6=$PUBLIC_IPV6
PRIVATE_IP=$PRIVATE_IP PRIVATE_IP=$PRIVATE_IP
PRIVATE_IPV6=$PRIVATE_IPV6 PRIVATE_IPV6=$PRIVATE_IPV6
MTA_STS_MODE=${DEFAULT_MTA_STS_MODE:-enforce} MTA_STS_MODE=${DEFAULT_MTA_STS_MODE:-enforce}
LOCAL_MODS_DIR=$LOCAL_MODS_DIR
EOF EOF
# Start service configuration. # Start service configuration.
@ -139,11 +143,7 @@ source setup/management-capture.sh
source setup/munin.sh source setup/munin.sh
# Wait for the management daemon to start... # Wait for the management daemon to start...
until nc -z -w 4 127.0.0.1 10222 wait_for_management_daemon progress forever
do
echo Waiting for the Mail-in-a-Box management daemon to start...
sleep 2
done
# ...and then have it write the DNS and nginx configuration files and start those # ...and then have it write the DNS and nginx configuration files and start those
# services. # services.
@ -174,9 +174,9 @@ fi
# #
# Run setup mods # Run setup mods
# #
if [ -d "${LOCAL_MODS_DIR:-local}" ]; then if [ -d "$LOCAL_MODS_DIR" ]; then
for mod in $(ls "${LOCAL_MODS_DIR:-local}" | grep -v '~$'); do for mod in $(ls "$LOCAL_MODS_DIR" | grep -v '~$'); do
mod_path="${LOCAL_MODS_DIR:-local}/$mod" mod_path="$LOCAL_MODS_DIR/$mod"
if [ -f "$mod_path" -a -x "$mod_path" ]; then if [ -f "$mod_path" -a -x "$mod_path" ]; then
echo "" echo ""
echo "Running mod: $mod_path" echo "Running mod: $mod_path"