FossilRepo
Protect user data: uninstall preserves repos, DB, SSH keys - Uninstall script no longer deletes .fossil repos, database, or SSH keys - Docker uninstall uses 'compose down' not 'compose down -v' (preserves volumes) - Prints clear instructions for manual data removal - Backs up .env and .credentials to /tmp before removing install dir - clone_repo handles existing installs without moving data directories
Commit
9644f9b165e68971e4d7ceeebc93fdfad2858b1c55380b40470bebed1978f6cb
Parent
01683ffbbb98d11…
1 file changed
+57
-18
+57
-18
| --- install.sh | ||
| +++ install.sh | ||
| @@ -1519,13 +1519,24 @@ | ||
| 1519 | 1519 | if [[ -d "${OPT_PREFIX}/.git" ]]; then |
| 1520 | 1520 | log_info "Updating existing repo..." |
| 1521 | 1521 | git config --global --add safe.directory "$OPT_PREFIX" 2>/dev/null || true |
| 1522 | 1522 | git -C "$OPT_PREFIX" pull --ff-only || true |
| 1523 | 1523 | elif [[ -d "$OPT_PREFIX" ]]; then |
| 1524 | - log_warn "${OPT_PREFIX} exists but is not a git repo. Backing up and cloning fresh..." | |
| 1525 | - mv "$OPT_PREFIX" "${OPT_PREFIX}.bak.$(date +%s)" | |
| 1526 | - git clone "$repo_url" "$OPT_PREFIX" | |
| 1524 | + # Safety: never move a directory that contains user data | |
| 1525 | + if [[ -d "${OPT_PREFIX}/.venv" ]] || [[ -f "${OPT_PREFIX}/.env" ]]; then | |
| 1526 | + log_warn "${OPT_PREFIX} exists (previous install). Cloning into subfolder..." | |
| 1527 | + local src_dir="${OPT_PREFIX}/src" | |
| 1528 | + rm -rf "$src_dir" | |
| 1529 | + git clone "$repo_url" "$src_dir" | |
| 1530 | + # Move source files up, preserving .env and .venv | |
| 1531 | + find "$src_dir" -maxdepth 1 -not -name src -not -name . -exec mv -n {} "$OPT_PREFIX/" \; | |
| 1532 | + rm -rf "$src_dir" | |
| 1533 | + else | |
| 1534 | + log_warn "${OPT_PREFIX} exists but is not a git repo or fossilrepo install. Backing up..." | |
| 1535 | + mv "$OPT_PREFIX" "${OPT_PREFIX}.bak.$(date +%s)" | |
| 1536 | + git clone "$repo_url" "$OPT_PREFIX" | |
| 1537 | + fi | |
| 1527 | 1538 | else |
| 1528 | 1539 | log_info "Cloning fossilrepo to ${OPT_PREFIX}..." |
| 1529 | 1540 | git clone "$repo_url" "$OPT_PREFIX" |
| 1530 | 1541 | fi |
| 1531 | 1542 | chown -R fossilrepo:fossilrepo "$OPT_PREFIX" |
| @@ -2063,24 +2074,34 @@ | ||
| 2063 | 2074 | [[ \"\$confirm\" == \"YES\" ]] || { echo 'Aborted.'; exit 1; }" |
| 2064 | 2075 | |
| 2065 | 2076 | if [[ "$OPT_MODE" == "docker" ]]; then |
| 2066 | 2077 | uninstall_content+=" |
| 2067 | 2078 | |
| 2068 | -echo 'Stopping Docker services...' | |
| 2079 | +echo 'Stopping Docker services (preserving volumes)...' | |
| 2069 | 2080 | cd '${OPT_PREFIX}' |
| 2070 | -docker compose down -v 2>/dev/null || true | |
| 2081 | +docker compose down 2>/dev/null || true | |
| 2082 | + | |
| 2083 | +echo '' | |
| 2084 | +echo ' NOTE: Docker volumes have been preserved.' | |
| 2085 | +echo ' To remove them (DELETES ALL DATA): docker volume prune' | |
| 2086 | +echo '' | |
| 2071 | 2087 | |
| 2072 | 2088 | echo 'Removing systemd service...' |
| 2073 | 2089 | systemctl stop fossilrepo.service 2>/dev/null || true |
| 2074 | 2090 | systemctl disable fossilrepo.service 2>/dev/null || true |
| 2075 | 2091 | rm -f /etc/systemd/system/fossilrepo.service |
| 2076 | 2092 | systemctl daemon-reload |
| 2077 | 2093 | |
| 2078 | -echo 'Removing install directory...' | |
| 2094 | +echo 'Removing application code (preserving .env backup)...' | |
| 2095 | +cp -f '${OPT_PREFIX}/.env' '/tmp/fossilrepo-env.bak' 2>/dev/null || true | |
| 2096 | +cp -f '${OPT_PREFIX}/.credentials' '/tmp/fossilrepo-creds.bak' 2>/dev/null || true | |
| 2079 | 2097 | rm -rf '${OPT_PREFIX}' |
| 2098 | +echo ' Backup of .env saved to /tmp/fossilrepo-env.bak' | |
| 2080 | 2099 | |
| 2081 | -echo 'Done. Docker images may still be cached -- run \"docker system prune\" to reclaim space.'" | |
| 2100 | +echo 'Done. Docker volumes and images may still be cached.' | |
| 2101 | +echo ' To remove volumes (DELETES DATA): docker volume prune' | |
| 2102 | +echo ' To remove images: docker system prune'" | |
| 2082 | 2103 | else |
| 2083 | 2104 | uninstall_content+=" |
| 2084 | 2105 | |
| 2085 | 2106 | echo 'Stopping services...' |
| 2086 | 2107 | systemctl stop fossilrepo-web.service 2>/dev/null || true |
| @@ -2101,30 +2122,48 @@ | ||
| 2101 | 2122 | rm -f /etc/systemd/system/fossilrepo-celery-beat.service |
| 2102 | 2123 | rm -f /etc/systemd/system/fossilrepo-litestream.service |
| 2103 | 2124 | rm -f /etc/systemd/system/caddy.service |
| 2104 | 2125 | systemctl daemon-reload |
| 2105 | 2126 | |
| 2106 | -echo 'Removing PostgreSQL database and user...' | |
| 2107 | -sudo -u postgres psql -c \"DROP DATABASE IF EXISTS ${OPT_DB_NAME};\" 2>/dev/null || true | |
| 2108 | -sudo -u postgres psql -c \"DROP USER IF EXISTS ${OPT_DB_USER};\" 2>/dev/null || true | |
| 2109 | - | |
| 2110 | 2127 | echo 'Removing Caddy config...' |
| 2111 | 2128 | rm -f /etc/caddy/Caddyfile |
| 2112 | 2129 | |
| 2113 | 2130 | echo 'Removing logrotate config...' |
| 2114 | 2131 | rm -f /etc/logrotate.d/fossilrepo |
| 2115 | 2132 | |
| 2116 | -echo 'Removing data directories...' | |
| 2117 | -rm -rf '${DATA_DIR}/repos' | |
| 2118 | -rm -rf '${DATA_DIR}/trash' | |
| 2119 | -rm -rf '${DATA_DIR}/ssh' | |
| 2120 | -rm -rf '${DATA_DIR}/git-mirrors' | |
| 2121 | -rm -rf '${DATA_DIR}/ssh-keys' | |
| 2133 | +echo 'Removing log files...' | |
| 2122 | 2134 | rm -rf '${LOG_DIR}' |
| 2123 | 2135 | |
| 2124 | -echo 'Removing install directory...' | |
| 2136 | +echo '' | |
| 2137 | +echo '================================================================' | |
| 2138 | +echo ' DATA PRESERVATION NOTICE' | |
| 2139 | +echo '================================================================' | |
| 2140 | +echo '' | |
| 2141 | +echo ' The following data has been PRESERVED (not deleted):' | |
| 2142 | +echo '' | |
| 2143 | +echo ' Fossil repositories: ${DATA_DIR}/repos/' | |
| 2144 | +echo ' PostgreSQL database: ${OPT_DB_NAME} (user: ${OPT_DB_USER})' | |
| 2145 | +echo ' Git mirrors: ${DATA_DIR}/git-mirrors/' | |
| 2146 | +echo ' SSH keys: ${DATA_DIR}/ssh/' | |
| 2147 | +echo '' | |
| 2148 | +echo ' To remove the database:' | |
| 2149 | +echo ' sudo -u postgres psql -c \"DROP DATABASE IF EXISTS ${OPT_DB_NAME};\"' | |
| 2150 | +echo ' sudo -u postgres psql -c \"DROP USER IF EXISTS ${OPT_DB_USER};\"' | |
| 2151 | +echo '' | |
| 2152 | +echo ' To remove repo data (IRREVERSIBLE):' | |
| 2153 | +echo ' rm -rf ${DATA_DIR}/repos' | |
| 2154 | +echo ' rm -rf ${DATA_DIR}/git-mirrors' | |
| 2155 | +echo ' rm -rf ${DATA_DIR}/ssh' | |
| 2156 | +echo '' | |
| 2157 | +echo ' These are left intact so you can back them up or migrate.' | |
| 2158 | +echo '================================================================' | |
| 2159 | + | |
| 2160 | +echo 'Removing application code (preserving .env backup)...' | |
| 2161 | +cp -f '${OPT_PREFIX}/.env' '/tmp/fossilrepo-env.bak' 2>/dev/null || true | |
| 2162 | +cp -f '${OPT_PREFIX}/.credentials' '/tmp/fossilrepo-creds.bak' 2>/dev/null || true | |
| 2125 | 2163 | rm -rf '${OPT_PREFIX}' |
| 2164 | +echo ' Backup of .env saved to /tmp/fossilrepo-env.bak' | |
| 2126 | 2165 | |
| 2127 | 2166 | echo 'Removing system user...' |
| 2128 | 2167 | userdel -r fossilrepo 2>/dev/null || true |
| 2129 | 2168 | |
| 2130 | 2169 | echo 'Done. System packages (PostgreSQL, Redis, Fossil, Caddy) were NOT removed.'" |
| 2131 | 2170 |
| --- install.sh | |
| +++ install.sh | |
| @@ -1519,13 +1519,24 @@ | |
| 1519 | if [[ -d "${OPT_PREFIX}/.git" ]]; then |
| 1520 | log_info "Updating existing repo..." |
| 1521 | git config --global --add safe.directory "$OPT_PREFIX" 2>/dev/null || true |
| 1522 | git -C "$OPT_PREFIX" pull --ff-only || true |
| 1523 | elif [[ -d "$OPT_PREFIX" ]]; then |
| 1524 | log_warn "${OPT_PREFIX} exists but is not a git repo. Backing up and cloning fresh..." |
| 1525 | mv "$OPT_PREFIX" "${OPT_PREFIX}.bak.$(date +%s)" |
| 1526 | git clone "$repo_url" "$OPT_PREFIX" |
| 1527 | else |
| 1528 | log_info "Cloning fossilrepo to ${OPT_PREFIX}..." |
| 1529 | git clone "$repo_url" "$OPT_PREFIX" |
| 1530 | fi |
| 1531 | chown -R fossilrepo:fossilrepo "$OPT_PREFIX" |
| @@ -2063,24 +2074,34 @@ | |
| 2063 | [[ \"\$confirm\" == \"YES\" ]] || { echo 'Aborted.'; exit 1; }" |
| 2064 | |
| 2065 | if [[ "$OPT_MODE" == "docker" ]]; then |
| 2066 | uninstall_content+=" |
| 2067 | |
| 2068 | echo 'Stopping Docker services...' |
| 2069 | cd '${OPT_PREFIX}' |
| 2070 | docker compose down -v 2>/dev/null || true |
| 2071 | |
| 2072 | echo 'Removing systemd service...' |
| 2073 | systemctl stop fossilrepo.service 2>/dev/null || true |
| 2074 | systemctl disable fossilrepo.service 2>/dev/null || true |
| 2075 | rm -f /etc/systemd/system/fossilrepo.service |
| 2076 | systemctl daemon-reload |
| 2077 | |
| 2078 | echo 'Removing install directory...' |
| 2079 | rm -rf '${OPT_PREFIX}' |
| 2080 | |
| 2081 | echo 'Done. Docker images may still be cached -- run \"docker system prune\" to reclaim space.'" |
| 2082 | else |
| 2083 | uninstall_content+=" |
| 2084 | |
| 2085 | echo 'Stopping services...' |
| 2086 | systemctl stop fossilrepo-web.service 2>/dev/null || true |
| @@ -2101,30 +2122,48 @@ | |
| 2101 | rm -f /etc/systemd/system/fossilrepo-celery-beat.service |
| 2102 | rm -f /etc/systemd/system/fossilrepo-litestream.service |
| 2103 | rm -f /etc/systemd/system/caddy.service |
| 2104 | systemctl daemon-reload |
| 2105 | |
| 2106 | echo 'Removing PostgreSQL database and user...' |
| 2107 | sudo -u postgres psql -c \"DROP DATABASE IF EXISTS ${OPT_DB_NAME};\" 2>/dev/null || true |
| 2108 | sudo -u postgres psql -c \"DROP USER IF EXISTS ${OPT_DB_USER};\" 2>/dev/null || true |
| 2109 | |
| 2110 | echo 'Removing Caddy config...' |
| 2111 | rm -f /etc/caddy/Caddyfile |
| 2112 | |
| 2113 | echo 'Removing logrotate config...' |
| 2114 | rm -f /etc/logrotate.d/fossilrepo |
| 2115 | |
| 2116 | echo 'Removing data directories...' |
| 2117 | rm -rf '${DATA_DIR}/repos' |
| 2118 | rm -rf '${DATA_DIR}/trash' |
| 2119 | rm -rf '${DATA_DIR}/ssh' |
| 2120 | rm -rf '${DATA_DIR}/git-mirrors' |
| 2121 | rm -rf '${DATA_DIR}/ssh-keys' |
| 2122 | rm -rf '${LOG_DIR}' |
| 2123 | |
| 2124 | echo 'Removing install directory...' |
| 2125 | rm -rf '${OPT_PREFIX}' |
| 2126 | |
| 2127 | echo 'Removing system user...' |
| 2128 | userdel -r fossilrepo 2>/dev/null || true |
| 2129 | |
| 2130 | echo 'Done. System packages (PostgreSQL, Redis, Fossil, Caddy) were NOT removed.'" |
| 2131 |
| --- install.sh | |
| +++ install.sh | |
| @@ -1519,13 +1519,24 @@ | |
| 1519 | if [[ -d "${OPT_PREFIX}/.git" ]]; then |
| 1520 | log_info "Updating existing repo..." |
| 1521 | git config --global --add safe.directory "$OPT_PREFIX" 2>/dev/null || true |
| 1522 | git -C "$OPT_PREFIX" pull --ff-only || true |
| 1523 | elif [[ -d "$OPT_PREFIX" ]]; then |
| 1524 | # Safety: never move a directory that contains user data |
| 1525 | if [[ -d "${OPT_PREFIX}/.venv" ]] || [[ -f "${OPT_PREFIX}/.env" ]]; then |
| 1526 | log_warn "${OPT_PREFIX} exists (previous install). Cloning into subfolder..." |
| 1527 | local src_dir="${OPT_PREFIX}/src" |
| 1528 | rm -rf "$src_dir" |
| 1529 | git clone "$repo_url" "$src_dir" |
| 1530 | # Move source files up, preserving .env and .venv |
| 1531 | find "$src_dir" -maxdepth 1 -not -name src -not -name . -exec mv -n {} "$OPT_PREFIX/" \; |
| 1532 | rm -rf "$src_dir" |
| 1533 | else |
| 1534 | log_warn "${OPT_PREFIX} exists but is not a git repo or fossilrepo install. Backing up..." |
| 1535 | mv "$OPT_PREFIX" "${OPT_PREFIX}.bak.$(date +%s)" |
| 1536 | git clone "$repo_url" "$OPT_PREFIX" |
| 1537 | fi |
| 1538 | else |
| 1539 | log_info "Cloning fossilrepo to ${OPT_PREFIX}..." |
| 1540 | git clone "$repo_url" "$OPT_PREFIX" |
| 1541 | fi |
| 1542 | chown -R fossilrepo:fossilrepo "$OPT_PREFIX" |
| @@ -2063,24 +2074,34 @@ | |
| 2074 | [[ \"\$confirm\" == \"YES\" ]] || { echo 'Aborted.'; exit 1; }" |
| 2075 | |
| 2076 | if [[ "$OPT_MODE" == "docker" ]]; then |
| 2077 | uninstall_content+=" |
| 2078 | |
| 2079 | echo 'Stopping Docker services (preserving volumes)...' |
| 2080 | cd '${OPT_PREFIX}' |
| 2081 | docker compose down 2>/dev/null || true |
| 2082 | |
| 2083 | echo '' |
| 2084 | echo ' NOTE: Docker volumes have been preserved.' |
| 2085 | echo ' To remove them (DELETES ALL DATA): docker volume prune' |
| 2086 | echo '' |
| 2087 | |
| 2088 | echo 'Removing systemd service...' |
| 2089 | systemctl stop fossilrepo.service 2>/dev/null || true |
| 2090 | systemctl disable fossilrepo.service 2>/dev/null || true |
| 2091 | rm -f /etc/systemd/system/fossilrepo.service |
| 2092 | systemctl daemon-reload |
| 2093 | |
| 2094 | echo 'Removing application code (preserving .env backup)...' |
| 2095 | cp -f '${OPT_PREFIX}/.env' '/tmp/fossilrepo-env.bak' 2>/dev/null || true |
| 2096 | cp -f '${OPT_PREFIX}/.credentials' '/tmp/fossilrepo-creds.bak' 2>/dev/null || true |
| 2097 | rm -rf '${OPT_PREFIX}' |
| 2098 | echo ' Backup of .env saved to /tmp/fossilrepo-env.bak' |
| 2099 | |
| 2100 | echo 'Done. Docker volumes and images may still be cached.' |
| 2101 | echo ' To remove volumes (DELETES DATA): docker volume prune' |
| 2102 | echo ' To remove images: docker system prune'" |
| 2103 | else |
| 2104 | uninstall_content+=" |
| 2105 | |
| 2106 | echo 'Stopping services...' |
| 2107 | systemctl stop fossilrepo-web.service 2>/dev/null || true |
| @@ -2101,30 +2122,48 @@ | |
| 2122 | rm -f /etc/systemd/system/fossilrepo-celery-beat.service |
| 2123 | rm -f /etc/systemd/system/fossilrepo-litestream.service |
| 2124 | rm -f /etc/systemd/system/caddy.service |
| 2125 | systemctl daemon-reload |
| 2126 | |
| 2127 | echo 'Removing Caddy config...' |
| 2128 | rm -f /etc/caddy/Caddyfile |
| 2129 | |
| 2130 | echo 'Removing logrotate config...' |
| 2131 | rm -f /etc/logrotate.d/fossilrepo |
| 2132 | |
| 2133 | echo 'Removing log files...' |
| 2134 | rm -rf '${LOG_DIR}' |
| 2135 | |
| 2136 | echo '' |
| 2137 | echo '================================================================' |
| 2138 | echo ' DATA PRESERVATION NOTICE' |
| 2139 | echo '================================================================' |
| 2140 | echo '' |
| 2141 | echo ' The following data has been PRESERVED (not deleted):' |
| 2142 | echo '' |
| 2143 | echo ' Fossil repositories: ${DATA_DIR}/repos/' |
| 2144 | echo ' PostgreSQL database: ${OPT_DB_NAME} (user: ${OPT_DB_USER})' |
| 2145 | echo ' Git mirrors: ${DATA_DIR}/git-mirrors/' |
| 2146 | echo ' SSH keys: ${DATA_DIR}/ssh/' |
| 2147 | echo '' |
| 2148 | echo ' To remove the database:' |
| 2149 | echo ' sudo -u postgres psql -c \"DROP DATABASE IF EXISTS ${OPT_DB_NAME};\"' |
| 2150 | echo ' sudo -u postgres psql -c \"DROP USER IF EXISTS ${OPT_DB_USER};\"' |
| 2151 | echo '' |
| 2152 | echo ' To remove repo data (IRREVERSIBLE):' |
| 2153 | echo ' rm -rf ${DATA_DIR}/repos' |
| 2154 | echo ' rm -rf ${DATA_DIR}/git-mirrors' |
| 2155 | echo ' rm -rf ${DATA_DIR}/ssh' |
| 2156 | echo '' |
| 2157 | echo ' These are left intact so you can back them up or migrate.' |
| 2158 | echo '================================================================' |
| 2159 | |
| 2160 | echo 'Removing application code (preserving .env backup)...' |
| 2161 | cp -f '${OPT_PREFIX}/.env' '/tmp/fossilrepo-env.bak' 2>/dev/null || true |
| 2162 | cp -f '${OPT_PREFIX}/.credentials' '/tmp/fossilrepo-creds.bak' 2>/dev/null || true |
| 2163 | rm -rf '${OPT_PREFIX}' |
| 2164 | echo ' Backup of .env saved to /tmp/fossilrepo-env.bak' |
| 2165 | |
| 2166 | echo 'Removing system user...' |
| 2167 | userdel -r fossilrepo 2>/dev/null || true |
| 2168 | |
| 2169 | echo 'Done. System packages (PostgreSQL, Redis, Fossil, Caddy) were NOT removed.'" |
| 2170 |