From a7d3dc5b5d4a43bcbd7ce6c879f35d3ce20c4abd Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 15 Aug 2026 02:58:59 +0000 Subject: [PATCH] Fix imported file ownership in the generated PikaPods migration script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generated migrate-from-pikapods.sh (services/mattermost.sh's existing "Migrating from an existing Mattermost instance?" prompt on fresh installs) already correctly parameterizes PROJECT_DIR/MM_CONTAINER/DB_CONTAINER per instance — no bug there. What it missed: after rsync/cp-ing files in from the export, it never touched ownership, so the imported ./data landed owned by whoever ran the script instead of the fixed UID 2000 mattermost/mattermost-team-edition runs as. Every file write then failed with permission denied — confirmed live as the actual cause of a client-side "stream closed" error on image/file uploads after a real migration. Adds chown -R 2000:2000 ./data right after the copy step, and a root check up front since chowning to an arbitrary UID needs it (docker/psql access already implied running as root in practice, just never enforced explicitly). Usage lines updated to say `sudo` to match. Verified by reconstructing the exact generated script from the real source heredocs (head + variable substitution + body, the same three pieces the actual cat/cat>> sequence produces) and syntax-checking the result — root check and chown both land in the right place, and PROJECT_DIR/MM_CONTAINER/DB_CONTAINER still resolve correctly per instance. --- services/mattermost.sh | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/services/mattermost.sh b/services/mattermost.sh index 309d3e6..1d4c1c3 100644 --- a/services/mattermost.sh +++ b/services/mattermost.sh @@ -788,7 +788,7 @@ MD # before running. # # Usage: -# ./migrate-from-pikapods.sh +# sudo ./migrate-from-pikapods.sh ################################################################################ MIGRATE_HEAD @@ -803,13 +803,18 @@ MIGRATE_VARS cat >> "$DIR/migrate-from-pikapods.sh" << 'MIGRATE_BODY' set -uo pipefail + +# Needed for the chown to UID 2000 near the end (an ordinary user generally +# can't chown files to an arbitrary UID that isn't their own). +[ "${EUID:-$(id -u)}" -eq 0 ] || { echo "Run as root: sudo $0 ..."; exit 1; } + cd "$PROJECT_DIR" || exit 1 SQL_DUMP="${1:-}" FILES_DIR="${2:-}" if [ -z "$SQL_DUMP" ] || [ -z "$FILES_DIR" ]; then - echo "Usage: $0 " + echo "Usage: sudo $0 " exit 1 fi [ -f "$SQL_DUMP" ] || { echo "SQL dump not found: $SQL_DUMP"; exit 1; } @@ -856,6 +861,14 @@ echo "Copying files into ./data..." mkdir -p ./data rsync -a "$FILES_DIR"/ ./data/ 2>/dev/null || cp -a "$FILES_DIR"/. ./data/ +# mattermost/mattermost-team-edition runs as fixed UID/GID 2000 — an SFTP'd +# copy from elsewhere lands owned by whoever ran this script instead, and +# every file write then fails with "permission denied" until this is +# fixed. Confirmed live: this is what broke image/file uploads with a +# client-side "stream closed" error after a migration. +echo "Fixing ownership on imported files (mattermost image expects UID/GID 2000)..." +chown -R 2000:2000 ./data + echo "Starting Mattermost..." docker compose up -d