Skip to content

Commit 233668e

Browse files
authored
Merge pull request #172 from dirkpetersen/dev
Dev - some installer improvements
2 parents 7db71bd + 0a9e71c commit 233668e

File tree

3 files changed

+182
-44
lines changed

3 files changed

+182
-44
lines changed

froster/froster.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7818,8 +7818,27 @@ def compare_versions(version1, version2):
78187818
log(f' Current version: froster v{current}')
78197819
log(f' Latest version: froster v{latest}')
78207820
log(f'\nYou can update froster using the command:')
7821-
log(f' curl -s https://raw.githubusercontent.com/dirkpetersen/froster/main/install.sh?$(date +%s) | bash\n\nor in --verbose mode for troubleshooting:')
7822-
log(f' curl -s https://raw.githubusercontent.com/dirkpetersen/froster/main/install.sh?$(date +%s) | bash -s -- --verbose\n')
7821+
log(f' curl -s https://raw.githubusercontent.com/dirkpetersen/froster/main/install.sh?$(date +%s) | bash')
7822+
log(f'\nOr in --verbose mode for troubleshooting:')
7823+
log(f' curl -s https://raw.githubusercontent.com/dirkpetersen/froster/main/install.sh?$(date +%s) | bash -s -- --verbose')
7824+
log(f'\nWould you like to update now? (yes/no): ', end='', flush=True)
7825+
7826+
response = input()
7827+
7828+
if response.lower() in ['yes', 'y']:
7829+
log('\nExecuting update command...\n')
7830+
timestamp = int(datetime.datetime.now().timestamp())
7831+
update_cmd = f'curl -s https://raw.githubusercontent.com/dirkpetersen/froster/main/install.sh?{timestamp} | bash'
7832+
7833+
result = subprocess.run(update_cmd, shell=True)
7834+
7835+
if result.returncode == 0:
7836+
log('\nUpdate completed successfully!')
7837+
else:
7838+
log('\nUpdate failed. You can retry the command above manually.\n')
7839+
return False
7840+
else:
7841+
log('\nUpdate cancelled.\n')
78237842
else:
78247843
if not mute_no_update:
78257844
log(f'\nFroster is up to date: froster v{current}\n')

install.sh

Lines changed: 160 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,12 @@ catch() {
5656

5757
if [ "$1" != "0" ]; then
5858
echo -e "\nError: $2: Installation failed!\n"
59+
echo "Your config and data remain safe in:"
60+
echo " Config: ${froster_config_dir}"
61+
echo " Data: ${froster_data_dir}"
62+
echo ""
5963

60-
# Restore (if any) backed up froster config files
61-
if [[ -d ${froster_config_backup_dir} ]]; then
62-
mv -f ${froster_config_backup_dir} ${froster_config_dir} >/dev/null 2>&1
63-
fi
64-
65-
# Restore (if any) backed up froster data files
66-
if [[ -d ${froster_data_backup_dir} ]]; then
67-
mv -f ${froster_data_backup_dir} ${froster_data_dir} >/dev/null 2>&1
68-
fi
69-
64+
# Clean up temporary installation files
7065
rm -rf ${pwalk_path} >/dev/null 2>&1
7166
rm -rf rclone-current-linux-*.zip rclone-v*/ >/dev/null 2>&1
7267
fi
@@ -259,43 +254,180 @@ check_dependencies() {
259254

260255
}
261256

262-
# Backup older installations (if any) but keep the froster-archive.json and config.ini files
257+
# Get the actual location of froster-archives.json by reading config
258+
get_data_file_location() {
259+
local config_file="$1"
260+
local default_location="${XDG_DATA_HOME}/froster/froster-archives.json"
261+
262+
# If no config exists, return default location
263+
if [[ ! -f "$config_file" ]]; then
264+
echo "$default_location"
265+
return
266+
fi
267+
268+
# Try to read shared data directory from config
269+
# Config format: [general] section with shared_data_dir key
270+
local shared_dir=$(grep -A 10 "^\[general\]" "$config_file" 2>/dev/null | grep "^shared_data_dir" | cut -d'=' -f2 | tr -d ' ')
271+
272+
if [[ -n "$shared_dir" && -d "$shared_dir" ]]; then
273+
echo "${shared_dir}/froster-archives.json"
274+
else
275+
echo "$default_location"
276+
fi
277+
}
278+
279+
# Check if we should restore from backup (for users affected by previous buggy installer)
280+
check_and_restore_from_backup() {
281+
local config_file="${froster_config_dir}/config.ini"
282+
local data_file_location
283+
284+
# Determine where froster-archives.json should be
285+
data_file_location=$(get_data_file_location "$config_file")
286+
287+
# Check if BOTH main files are missing
288+
local config_missing=false
289+
local data_missing=false
290+
291+
if [[ ! -f "$config_file" ]]; then
292+
config_missing=true
293+
fi
294+
295+
if [[ ! -f "$data_file_location" ]]; then
296+
data_missing=true
297+
fi
298+
299+
# If at least one file exists, no restore needed
300+
if [[ "$config_missing" == false || "$data_missing" == false ]]; then
301+
return 0
302+
fi
303+
304+
# Both files are missing, look for backups
305+
echo -e "\nChecking for previous Froster backups..."
306+
307+
# Find the most recent backup directory that has BOTH files
308+
local latest_backup=""
309+
local backup_config_file=""
310+
local backup_data_file=""
311+
312+
# Search for backups in reverse chronological order (newest first)
313+
for backup_dir in $(find ${froster_all_config_backups} -maxdepth 1 -type d -name "froster_*.bak" 2>/dev/null | sort -r); do
314+
local test_config="${backup_dir}/config.ini"
315+
316+
# Check if config exists in this backup
317+
if [[ ! -f "$test_config" ]]; then
318+
continue
319+
fi
320+
321+
# Get data location from this backup's config
322+
local test_data_location=$(get_data_file_location "$test_config")
323+
324+
# Check if we can find the data file in corresponding data backup
325+
local backup_timestamp=$(basename "$backup_dir" | sed 's/froster_\(.*\)\.bak/\1/')
326+
local corresponding_data_backup="${froster_all_data_backups}/froster_${backup_timestamp}.bak"
327+
328+
# Construct potential data file path in backup
329+
local test_data="${corresponding_data_backup}/froster-archives.json"
330+
331+
# Also check if data was in a shared location mentioned in backup config
332+
if [[ "$test_data_location" != "${XDG_DATA_HOME}/froster/froster-archives.json" ]]; then
333+
# Data might be in shared location, but we can't restore shared data
334+
# Only check local backup
335+
test_data="${corresponding_data_backup}/froster-archives.json"
336+
fi
337+
338+
if [[ -f "$test_data" ]]; then
339+
# Found a backup with BOTH files
340+
latest_backup="$backup_dir"
341+
backup_config_file="$test_config"
342+
backup_data_file="$test_data"
343+
break
344+
fi
345+
done
346+
347+
# If we found a complete backup, ask user
348+
if [[ -n "$latest_backup" ]]; then
349+
local backup_date=$(basename "$latest_backup" | sed 's/froster_\([0-9]\{8\}\)\([0-9]\{6\}\)\.bak/\1 \2/' | sed 's/\([0-9]\{4\}\)\([0-9]\{2\}\)\([0-9]\{2\}\) \([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)/\1-\2-\3 \4:\5:\6/')
350+
351+
echo ""
352+
echo "==========================================="
353+
echo " Froster Backup Found"
354+
echo "==========================================="
355+
echo ""
356+
echo "Your config and data files are missing, but we found a backup from:"
357+
echo " Date: $backup_date"
358+
echo ""
359+
echo "Backup location:"
360+
echo " Config: $backup_config_file"
361+
echo " Data: $backup_data_file"
362+
echo ""
363+
echo -n "Would you like to restore these files? (yes/no): "
364+
read -r response
365+
echo ""
366+
367+
if [[ "$response" =~ ^[Yy]([Ee][Ss])?$ ]]; then
368+
echo "Restoring from backup..."
369+
370+
# Create directories if needed
371+
mkdir -p "${froster_config_dir}"
372+
mkdir -p "$(dirname "$data_file_location")"
373+
374+
# Restore config
375+
cp -f "$backup_config_file" "$config_file"
376+
echo " ✓ Config restored to: $config_file"
377+
378+
# Restore data
379+
cp -f "$backup_data_file" "$data_file_location"
380+
echo " ✓ Data restored to: $data_file_location"
381+
382+
echo ""
383+
echo "Backup restoration completed successfully!"
384+
echo ""
385+
else
386+
echo "Skipping backup restoration. You can manually restore later from:"
387+
echo " $latest_backup"
388+
echo ""
389+
fi
390+
fi
391+
}
392+
393+
# Create backup directories for user reference (optional safety net)
394+
# NOTE: Config and data are NEVER deleted, so backups are just for user peace of mind
263395
backup_old_installation() {
264396

265397
# Make sure we did not left any backup files from previous updates.
266398
# Move all backups to the data or config backup directories
267399
mkdir -p ${froster_all_data_backups}
268400
mkdir -p ${froster_all_config_backups}
269-
find ${XDG_DATA_HOME} -maxdepth 1 -type d -name "froster_*.bak" -print0 | xargs -0 -I {} mv {} $froster_all_data_backups
270-
find ${XDG_CONFIG_HOME} -maxdepth 1 -type d -name "froster_*.bak" -print0 | xargs -0 -I {} mv {} $froster_all_config_backups
401+
find ${XDG_DATA_HOME} -maxdepth 1 -type d -name "froster_*.bak" -print0 2>/dev/null | xargs -0 -I {} mv {} $froster_all_data_backups 2>/dev/null || true
402+
find ${XDG_CONFIG_HOME} -maxdepth 1 -type d -name "froster_*.bak" -print0 2>/dev/null | xargs -0 -I {} mv {} $froster_all_config_backups 2>/dev/null || true
271403

272404

273-
# Back up (if any) older froster data files
405+
# Create a reference backup of data (optional, for user peace of mind)
274406
if [[ -d ${froster_data_dir} ]]; then
275407

276-
echo -e "\nBacking Froster data folder ..."
408+
echo -e "\nCreating reference backup of Froster data folder..."
277409

278410
# Copy the froster directory to froster_YYYYMMDD.bak
279411
cp -rf ${froster_data_dir} ${froster_data_backup_dir}
280412

281413
echo " source: ${froster_data_dir}"
282414
echo " destination: ${froster_data_backup_dir}"
283415

284-
echo "...data backed up"
416+
echo "...reference backup created"
285417
fi
286418

287-
# Back up (if any) older froster configurations
419+
# Create a reference backup of config (optional, for user peace of mind)
288420
if [[ -d ${froster_config_dir} ]]; then
289421

290-
echo -e "\nBacking Froster config folder ..."
422+
echo -e "\nCreating reference backup of Froster config folder..."
291423

292424
echo " source: ${froster_config_dir}"
293425
echo " destination: ${froster_config_backup_dir}"
294426

295-
# Move the froster config directory to froster.bak
427+
# Copy the froster config directory to backup
296428
cp -rf ${froster_config_dir} ${froster_config_backup_dir}
297429

298-
echo "...config backed up"
430+
echo "...reference backup created"
299431
fi
300432
}
301433

@@ -334,13 +466,12 @@ install_pipx() {
334466

335467
install_froster() {
336468

337-
echo -e "\nRemoving old froster files..."
338-
rm -rf ${froster_data_dir}
339-
rm -rf ${froster_config_dir}
469+
echo -e "\nRemoving old froster binaries only (keeping config and data)..."
470+
# ONLY remove executables, NEVER touch user config or data
340471
rm -f ${HOME}/.local/bin/froster
341472
rm -f ${HOME}/.local/bin/froster.py
342473
rm -f ${HOME}/.local/bin/s3-restore.py
343-
echo "...old froster files removed"
474+
echo "...old froster binaries removed"
344475

345476
if [ "$LOCAL_INSTALL" = "true" ]; then
346477

@@ -372,23 +503,8 @@ install_froster() {
372503
done
373504
echo " ...froster command verified."
374505

375-
# Keep the config.ini file (if any)
376-
if [[ -f ${froster_config_backup_dir}/config.ini ]]; then
377-
# Create the froster directory if it does not exist
378-
mkdir -p ${froster_config_dir}
379-
380-
# Copy the config file to the data directory
381-
cp -f ${froster_config_backup_dir}/config.ini ${froster_config_dir}
382-
fi
383-
384-
# Keep the froster-archives.json file (if any)
385-
if [[ -f ${froster_data_backup_dir}/froster-archives.json ]]; then
386-
# Create the froster directory if it does not exist
387-
mkdir -p ${froster_data_dir}
388-
389-
# Copy the froster-archives.json file to the data directory
390-
cp -f ${froster_data_backup_dir}/froster-archives.json ${froster_data_dir}
391-
fi
506+
# Config and data directories are NEVER deleted, they persist across upgrades
507+
# Users' settings and archive database remain intact
392508
}
393509

394510
install_pwalk() {
@@ -516,6 +632,9 @@ check_dependencies
516632
# Set rw permissions on anyone in file's group
517633
umask 0002
518634

635+
# Check if we need to restore from backup (for users hit by previous buggy installer)
636+
check_and_restore_from_backup
637+
519638
# Backup old installation (if any)
520639
backup_old_installation
521640

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
44

55
[tool.poetry]
66
name = "froster"
7-
version = "0.21.0"
7+
version = "0.21.1"
88

99
description = "Froster is a tool for easy archive and restore between local file systems and AWS S3 storage."
1010
authors = ["Dirk Petersen <no@mail.com>", "Victor Machado <victor.machado@hpcnow.com>"]

0 commit comments

Comments
 (0)