LibrePortal/scripts/config/docker/docker_config_to_container.sh
librelad 68110d199c fix(rootless): slirp4netns default, manager-vs-container helper split, sysctl path
Reinstall test on Debian 12 surfaced three rootless-only breakages (rooted
was byte-identical/fine):

1. pasta blocked by Debian's passt AppArmor profile (DENIED ptrace read ->
   can't open container netns -> rootless dockerd never starts). Default
   CFG_ROOTLESS_NET back to slirp4netns (reliable); pasta stays selectable
   for hosts that relax the profile.
2. de-sudo mis-assigned helpers by owner. /docker management layer (apps DB
   chowned to libreportal by install_sqlite, /docker/logs) is MANAGER-owned,
   not dockerinstall. Add runInstallWrite; move apps-DB sqlite3 -> runInstallOp
   and /docker/logs appends -> runInstallWrite. Revert ownership-SETUP scripts
   (libreportal_folders, app_folder) to runSystem — they must run as root to
   establish ownership during install. Container files (/docker/containers/<app>)
   stay runFileOp.
3. kernel hardening sysctls written to /etc/sysctl/99-custom.conf, which
   'sysctl --system' does not read -> never applied. Write them to
   /etc/sysctl.d/99-libreportal-hardening.conf instead.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-24 00:12:06 +01:00

246 lines
12 KiB
Bash
Executable File

#!/bin/bash
dockerConfigSetupToContainer()
{
local silent_flag="$1"
local app_name="$2"
local flags="$3"
local config_overrides="$4"
local target_path="$containers_dir$app_name"
local source_file="$install_containers_dir$app_name/$app_name.config"
local config_file="$app_name.config"
if [ "$app_name" == "" ]; then
isError "The app_name is empty."
fi
if [ -d "$target_path" ]; then
if [ "$silent_flag" == "loud" ]; then
isNotice "The directory '$target_path' already exists."
fi
else
createFolders "$silent_flag" "" "$target_path"
fi
if [ ! -f "$source_file" ]; then
isError "The config file '$source_file' does not exist."
fi
# Atomic file write function
atomicWriteConfig() {
local content="$1"
local target_file="$2"
local temp_file="${target_file}.tmp.$$"
# Write to temp file first
echo "$content" > "$temp_file"
# Atomic rename (instantaneous)
mv "$temp_file" "$target_file"
}
if [ ! -f "$target_path/$config_file" ]; then
if [ "$silent_flag" == "loud" ]; then
isNotice "Copying config file to '$target_path/$config_file'..."
fi
copyFile "$silent_flag" "$source_file" "$target_path/$config_file" $sudo_user_name | runInstallWrite -a "$logs_dir/$docker_log_file" 2>&1
fi
if [[ -n "$config_overrides" ]]; then
local deployed_config_pre="$target_path/$config_file"
if [[ -f "$deployed_config_pre" ]]; then
IFS='|' read -ra override_pairs_pre <<< "$config_overrides"
for pair in "${override_pairs_pre[@]}"; do
if [[ "$pair" =~ ^(CFG_[A-Z0-9_]+)=(.*)$ ]]; then
local _value="${BASH_REMATCH[2]//%7C/|}"
updateConfigOption "${BASH_REMATCH[1]}" "$_value" "$deployed_config_pre"
fi
done
fi
fi
if runFileOp grep -qE 'RANDOMIZED(PASSWORD|USERNAME|BCRYPTPASSWORD|HEX|VAPID|APPKEY)[0-9]*' "$target_path/$config_file" 2>/dev/null; then
scanFileForRandomPasswordKeysUsers "$target_path/$config_file"
runFileOp chmod a+r "$target_path/$config_file" 2>/dev/null || true
source "$target_path/$config_file"
fi
fixConfigPermissions $silent_flag $app_name;
# Check if the file exists
if [ ! -e "$target_path/$config_file" ]; then
isError "File $target_path/$config_file does not exist"
fi
# Check if the user has read permission on target_path/config_file
if [ ! -r "$target_path/$config_file" ]; then
isError "Insufficient permissions to read $target_path/$config_file"
fi
if [[ "$flags" == "install" ]]; then
if [ -f "$target_path/$config_file" ]; then
# Same content check
if runFileOp cmp -s "$source_file" "$target_path/$config_file"; then
isNotice "Config file for $app_name contains no edits."
while true; do
#isQuestion "? (y/n): "
#read -rp "" editconfigaccept
#echo ""
editconfigaccept="n" # No longer needed due to webui
case $editconfigaccept in
[yY])
# Calculate checksum of the original file
local original_checksum=$(runFileOp md5sum "$target_path/$config_file")
# Open the file with $CFG_TEXT_EDITOR for editing
runFileOp $CFG_TEXT_EDITOR "$target_path/$config_file"
# Calculate checksum of the edited file
local edited_checksum=$(runFileOp md5sum "$target_path/$config_file")
# Compare the checksums to check if changes were made
if [[ "$original_checksum" != "$edited_checksum" ]]; then
source $target_path/$config_file
initializeAppVariables $app_name;
isSuccessful "Changes have been made to the $config_file."
fi
break
;;
[nN])
break # Exit the loop without updating
;;
*)
isNotice "Please provide a valid input (y or n)."
;;
esac
done
else
echo ""
isNotice "Config file for $app_name has been updated..."
echo ""
while true; do
#isQuestion "Would you like to reset the config file? (y/n): "
#read -rp "" resetconfigaccept
#echo ""
resetconfigaccept="n" # No longer needed due to webui
case $resetconfigaccept in
[yY])
isNotice "Resetting $app_name config file."
copyFile "loud" "$source_file" "$target_path/$config_file" $docker_install_user | runInstallWrite -a "$logs_dir/$docker_log_file" 2>&1
source $target_path/$config_file
dockerConfigSetupToContainer "loud" $app_name;
while true; do
#isQuestion "Would you like to make edits to the config file? (y/n): "
#read -rp "" editconfigaccept
#echo ""
editconfigaccept="n" # No longer needed due to webui
case $editconfigaccept in
[yY])
# Calculate the checksum of the original file
local original_checksum=$(runFileOp md5sum "$target_path/$config_file")
# Open the file with $CFG_TEXT_EDITOR for editing
runFileOp $CFG_TEXT_EDITOR "$target_path/$config_file"
# Calculate the checksum of the edited file
local edited_checksum=$(runFileOp md5sum "$target_path/$config_file")
# Compare the checksums to check if changes were made
if [[ "$original_checksum" != "$edited_checksum" ]]; then
source $target_path/$config_file
initializeAppVariables $app_name;
isSuccessful "Changes have been made to the $config_file."
fi
break
;;
[nN])
break # Exit the loop without updating
;;
*)
isNotice "Please provide a valid input (y or n)."
;;
esac
done
break
;;
[nN])
while true; do
#isQuestion "Would you like to make edits to the config file? (y/n): "
#read -rp "" editconfigaccept
#echo ""
editconfigaccept="n" # No longer needed due to webui
case $editconfigaccept in
[yY])
# Calculate the checksum of the original file
local original_checksum=$(runFileOp md5sum "$target_path/$config_file")
# Open the file with $CFG_TEXT_EDITOR for editing
runFileOp $CFG_TEXT_EDITOR "$target_path/$config_file"
# Calculate the checksum of the edited file
local edited_checksum=$(runFileOp md5sum "$target_path/$config_file")
# Compare the checksums to check if changes were made
if [[ "$original_checksum" != "$edited_checksum" ]]; then
source $target_path/$config_file
initializeAppVariables $app_name;
isSuccessful "Changes have been made to the $config_file."
fi
break
;;
[nN])
break # Exit the loop without updating
;;
*)
isNotice "Please provide a valid input (y or n)."
;;
esac
done
break # Exit the loop without updating
;;
*)
isNotice "Please provide a valid input (y or n)."
;;
esac
done
fi
else
isNotice "Config file for $app_name does not exist. Creating it..."
copyFile "loud" "$source_file" "$target_path/$config_file" $docker_install_user | runInstallWrite -a "$logs_dir/$docker_log_file" 2>&1
isNotice "Config file for $app_name contains no edits."
while true; do
#isQuestion "Would you like to make edits to the config file? (y/n): "
#read -rp "" editconfigaccept
#echo ""
editconfigaccept="n" # No longer needed due to webui
case $editconfigaccept in
[yY])
# Calculate the checksum of the original file
local original_checksum=$(runFileOp md5sum "$target_path/$config_file")
# Open the file with $CFG_TEXT_EDITOR for editing
runFileOp $CFG_TEXT_EDITOR "$target_path/$config_file"
# Calculate the checksum of the edited file
local edited_checksum=$(runFileOp md5sum "$target_path/$config_file")
# Compare the checksums to check if changes were made
if [[ "$original_checksum" != "$edited_checksum" ]]; then
source $target_path/$config_file
initializeAppVariables $app_name;
isSuccessful "Changes have been made to the $config_file."
fi
break
;;
[nN])
break # Exit the loop without updating
;;
*)
isNotice "Please provide a valid input (y or n)."
;;
esac
done
fi
fi
sourceScanFiles "app_configs";
}