Files
operation-bin/firefox_shared_profile
Henrik Till Lemke 0513d6005b firefox_shared_profile: wait for ~/network_drives/home before touching it
firefox_as ssh's to localhost, which can start a new session; the old
mkdir -p then ran before mount-user-cifs-shares linked
~/network_drives/home, created a local tmpfs dir there (the mount
script's ln -sf then put its link inside it), and Firefox got a fresh
empty profile - and gopass broke for that session too.

Now: refuse if home is a plain directory (with repair hint), otherwise
wait up to 20s for the link (starting the mount service), and fail
with a message instead of creating a local profile. Also drop the
blank line before the shebang.
2026-10-15 13:10:59 +02:00

172 lines
6.4 KiB
Plaintext
Executable File

#!/usr/bin/env bash
# --- CONFIGURATION ---
# 1. Give your profile a distinct, single-word name (NO spaces)
PROFILE_NAME="SharedProfile"
# 2. Define exactly where the folder should live
PROFILE_DIR="$HOME/network_drives/home/.mozilla/shared_profile"
# Detect OS to set the correct Firefox binary path
if [[ "$OSTYPE" == "darwin"* ]]; then
FIREFOX_BIN="/Applications/Firefox.app/Contents/MacOS/firefox"
LOCK_FILE="$PROFILE_DIR/.parentlock"
else
FIREFOX_BIN="firefox" # Assumes 'firefox' is in your system PATH on Linux
LOCK_FILE="$PROFILE_DIR/lock"
fi
# ---------------------
# --- MAKE SURE THE SHARED HOME IS REALLY MOUNTED ---
# ~/network_drives/home is a symlink that mount-user-cifs-shares.service
# (/opt/pli/bin/create-network-drive-links) creates asynchronously at the
# start of a session. firefox_as ssh's to localhost, which often IS the
# start of a new session, so we can get here before that link exists.
# Never mkdir under it in that case: a plain directory there makes the
# mount script's "ln -sf" put its link INSIDE it, leaving the whole
# session with a local, empty "home" (new firefox profile, broken gopass).
fail() {
echo "[ERROR] $1" >&2
zenity --error --title="Firefox shared profile" --width=480 --text="$1" 2>/dev/null
exit 1
}
if [[ "$OSTYPE" != "darwin"* ]]; then
NET_HOME="$HOME/network_drives/home"
if [ -e "$NET_HOME" ] && [ ! -L "$NET_HOME" ]; then
fail "$NET_HOME is a local directory, not the link to your network home.\n\nSomething created it before the network drives were mounted, so this session cannot see the shared profile (or gopass).\n\nFix: close everything that uses it, then run:\n mv $NET_HOME ${NET_HOME}.broken\n setup-network-drives"
fi
for i in $(seq 1 20); do
[ -L "$NET_HOME" ] && [ -d "$NET_HOME/" ] && break
if [ "$i" -eq 3 ]; then
echo "[INFO] Waiting for network drives to be mounted..."
systemctl --user start mount-user-cifs-shares.service 2>/dev/null
fi
sleep 1
done
if ! [ -L "$NET_HOME" ] || ! [ -d "$NET_HOME/" ]; then
fail "Network home $NET_HOME is not available (no Kerberos ticket?).\n\nRun 'setup-network-drives' in a terminal as $USER, then try again."
fi
fi
# Ensure the parent directory folder physically exists first
mkdir -p "$PROFILE_DIR"
# Check if the folder is empty/doesn't exist
if [ ! -d "$PROFILE_DIR" ] || [ -z "$(ls -A "$PROFILE_DIR")" ]; then
echo "[INFO] Profile not found or empty. Forcing registration via Firefox CLI..."
# Modern Firefox fix: We use -CreateProfile paired with a dummy screenshot
# to force Firefox to write the directory structure and exit cleanly.
$FIREFOX_BIN -CreateProfile "$PROFILE_NAME $PROFILE_DIR" --headless --screenshot /dev/null > /dev/null 2>&1
echo "[SUCCESS] Profile '$PROFILE_NAME' registered at: $PROFILE_DIR"
else
echo "[INFO] Profile folder already exists. Skipping creation step."
fi
SIGNAL_FILE="$PROFILE_DIR/remote_shutdown.signal"
# --- NEW NETWORK-SAFE LOCK DETECTION LOGIC ---
echo "[INFO] Scanning for active network locks..."
# Force network share to drop local metadata cache
ls -la "$PROFILE_DIR" > /dev/null 2>&1
ACTIVE_LOCK_FOUND=false
# Check all 3 potential lock names
for POSSIBLE_LOCK in "lock" ".parentlock" "parent.lock"; do
TARGET_LOCK_PATH="$PROFILE_DIR/$POSSIBLE_LOCK"
if [ -e "$TARGET_LOCK_PATH" ] || [ -L "$TARGET_LOCK_PATH" ]; then
# FIXED: We use -newermt to see if the lock was touched within the last 25 seconds.
# This operates natively across Linux/Mac and accepts precise time strings safely.
IS_ACTIVE=$(find "$TARGET_LOCK_PATH" -newermt '25 seconds ago' 2>/dev/null)
if [ -n "$IS_ACTIVE" ]; then
echo "[WARN] Active remote lock verified: $POSSIBLE_LOCK (Modified within last 25s)"
ACTIVE_LOCK_FOUND=true
break
else
echo "[INFO] Stale lock ignored: $POSSIBLE_LOCK (Not modified recently)"
fi
fi
done
# Act on our findings
if [ "$ACTIVE_LOCK_FOUND" = true ]; then
zenity --question \
--title="Firefox Profile Warning" \
--text="This profile is actively running on another computer.\n\nDo you want to send a SHUTDOWN SIGNAL to close the other session remotely?" \
--ok-label="Close Other & Open Here" \
--cancel-label="Cancel Launch" \
--width=420 2>/dev/null
if [ $? -eq 0 ]; then
echo "[INFO] Creating shutdown signal file..."
touch "$SIGNAL_FILE"
(
for i in {1..12}; do
ls -la "$PROFILE_DIR" > /dev/null 2>&1
# Update the progress tracker loop to use the same -newermt logic
STILL_ACTIVE=$(find "$PROFILE_DIR" \( -name "lock" -o -name ".parentlock" -o -name "parent.lock" \) -newermt '25 seconds ago' 2>/dev/null)
if [ -z "$STILL_ACTIVE" ]; then
echo 100; break
fi
echo $((i * 8))
sleep 1
done
) | zenity --progress --title="Waiting" --text="Signaling remote session to close cleanly..." --auto-close --width=300 2>/dev/null
rm -f "$PROFILE_DIR/lock" "$PROFILE_DIR/.parentlock" "$PROFILE_DIR/parent.lock" "$SIGNAL_FILE"
else
echo "[INFO] Aborted by user."
exit 0
fi
fi
echo "[INFO] Launching Firefox instance..."
# FIX: Added the '&' back to the end of the line so the script can continue
# executing the background heartbeat loop while Firefox runs.
$FIREFOX_BIN --profile "$PROFILE_DIR" -no-remote > /dev/null 2>&1 &
FF_PID=$! # This will now successfully capture Firefox's background PID
echo "[INFO] Monitoring session (PID: $FF_PID). Close the window to exit."
# --- STEP 3: BACKGROUND MONITORING LOOP WITH HEARTBEAT ---
while kill -0 $FF_PID 2>/dev/null; do
# 1. Update our local lock file timestamp so other machines know we are alive
touch "$PROFILE_DIR/lock" "$PROFILE_DIR/.parentlock" 2>/dev/null
# 2. Check for the remote shutdown signal
if [ -f "$SIGNAL_FILE" ]; then
echo "[SIGNAL] Remote shutdown request received! Closing Firefox..."
kill -15 $FF_PID
rm -f "$SIGNAL_FILE"
wait $FF_PID 2>/dev/null
break
fi
sleep 3 # Heartbeat/check interval every 3 seconds
done
# Safety wait to ensure the process is fully reaped if closed manually
wait $FF_PID 2>/dev/null
# Final local cleanup
rm -f "$PROFILE_DIR/lock" "$PROFILE_DIR/.parentlock" "$PROFILE_DIR/parent.lock"
echo "[INFO] Session closed cleanly."
exit 0