#!/bin/bash copyFile() { local silent_flag="$1" local file="$2" local file_name=$(basename "$file") local save_dir="$3" local save_dir_file=$(basename "$save_dir") local user_name="$4" # advisory — the destination path determines the owner local flags="$5" local flags_full="" [[ "$flags" == "overwrite" ]] && flags_full="-f" # Write as the destination's owner — no root, no chown. Under # /docker/containers/ that's the docker install user (runFileOp); # the manager-owned control plane (configs/logs/etc.) is runInstallOp. # Mirrors createTouch's path-based ownership; $user_name is now advisory. local op="runInstallOp" [[ "$save_dir" == "$containers_dir"* || "$save_dir" == "${LP_CONTAINERS_DIR:-/libreportal-containers}"/* ]] && op="runFileOp" if [ "$silent_flag" == "loud" ]; then local result; result=$($op cp $flags_full "$file" "$save_dir") checkSuccess "Copying $file_name to $save_dir_file" else $op cp $flags_full "$file" "$save_dir" >/dev/null 2>&1 fi } # Docker materialises a missing bind-mount source as an empty DIRECTORY when the # container starts. Where the mount is a FILE (an app's .config), that # directory is self-perpetuating: tar extraction fails with "Cannot open: File # exists", `cp` drops the real file INSIDE it, `-e`/`-r` checks still pass, and # the container reads a directory (EISDIR) and exits on boot. # Restore the regular file: promote a same-named file from inside the stub if the # copy already landed there, then drop the stub. Returns non-zero if the path is # still a directory afterwards. repairStubDirForFile() { local target="$1" local silent_flag="${2:-silent}" [[ -d "$target" ]] || return 0 local op="runInstallOp" [[ "$target" == "$containers_dir"* || "$target" == "${LP_CONTAINERS_DIR:-/libreportal-containers}"/* ]] && op="runFileOp" local name; name=$(basename "$target") local staged="$target.stub-repair.$$" if [[ -f "$target/$name" ]]; then $op cp -f "$target/$name" "$staged" >/dev/null 2>&1 $op rm -rf "$target" >/dev/null 2>&1 $op mv "$staged" "$target" >/dev/null 2>&1 else $op rm -rf "$target" >/dev/null 2>&1 fi if [[ -d "$target" ]]; then isNotice "Could not repair '$target' — it is a directory where a file is required." return 1 fi [[ "$silent_flag" == "loud" ]] && isNotice "Repaired '$name' (Docker had created it as a bind-mount directory)." return 0 }