Skip to content

Commit 74aa4b2

Browse files
authored
Use local Github clone as backup + fallback to statically.io (#2778)
* Add local repository backup fallback to avoid GitHub rate limits - Add ensure_local_backup_repo() to clone repo fresh on each update - Add try_local_backup() to copy files from local backup when GitHub fails - Modify curl_to_dir() to automatically fall back to local backup - Update fetch_lib.sh to use local backup when downloading lib.sh fails - Call ensure_local_backup_repo() in update and install scripts This solves issue #2771 by providing a local fallback when GitHub raw.githubusercontent.com hits rate limits. The implementation: - Prioritizes GitHub (online-first approach) - Falls back to local clone automatically on download failures - Clones fresh repo on each update run (no stale files) - Minimal code changes (~55 lines across 4 files) - Zero breaking changes - fully backward compatible * Fix menu.sh to work offline with local backup Remove network_ok check in menu.sh to allow running offline. The run_script function will automatically: 1. Try to download from GitHub (if online) 2. Fall back to local backup (if offline or rate limited) This allows users to run menu.sh for configuration changes even when completely offline, as requested in issue #2771. * Add Statically.io CDN as middle-tier fallback - Add CDN fallback between GitHub and local backup - Update curl_to_dir() in lib.sh to try cdn.statically.io - Update fetch_lib.sh with CDN fallback - Update nextcloud_update.sh initial source with CDN fallback - Statically.io caches main branch for 1 day (helps with rate limits) - Fallback order: GitHub → Statically CDN → Local backup * Use fetch_lib.sh in update script instead of duplicating fallback logic - Source fetch_lib.sh which handles GitHub → CDN → Local backup - Check for local fetch_lib.sh first before downloading - Add CDN fallback for fetch_lib.sh itself - Cleaner code, no duplication of fallback logic
1 parent 8b9d63c commit 74aa4b2

File tree

5 files changed

+145
-13
lines changed

5 files changed

+145
-13
lines changed

lib.sh

Lines changed: 102 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,7 @@ fi
613613
}
614614

615615
# A function to fetch a file with curl to a directory
616+
# Falls back to local backup if download fails
616617
# 1 = https://example.com
617618
# 2 = name of file
618619
# 3 = directory that the file should end up in
@@ -624,18 +625,50 @@ fi
624625
rm -f "$3"/"$2"
625626
if [ -n "$download_script_function_in_use" ]
626627
then
627-
curl -sfL "$1"/"$2" -o "$3"/"$2"
628+
if ! curl -sfL "$1"/"$2" -o "$3"/"$2"
629+
then
630+
# Try Statically.io CDN if this is a GitHub URL
631+
if [[ "$1" == *"raw.githubusercontent.com"* ]]
632+
then
633+
local cdn_url="${1/raw.githubusercontent.com/cdn.statically.io\/gh}"
634+
cdn_url="${cdn_url//\/nextcloud\/vm\//\/nextcloud\/vm\/main\/}"
635+
if curl -sfL "$cdn_url"/"$2" -o "$3"/"$2"
636+
then
637+
return 0
638+
fi
639+
fi
640+
# Try local backup
641+
try_local_backup "$1" "$2" "$3"
642+
fi
628643
else
629644
local retries=0
630645
while :
631646
do
632647
if [ "$retries" -ge 10 ]
633648
then
634-
if yesno_box_yes "Tried 10 times but didn't succeed. We will now exit the script because it might break things. You can choose 'No' to continue on your own risk."
649+
# Try Statically.io CDN if this is a GitHub URL
650+
if [[ "$1" == *"raw.githubusercontent.com"* ]]
635651
then
636-
exit 1
652+
local cdn_url="${1/raw.githubusercontent.com/cdn.statically.io\/gh}"
653+
cdn_url="${cdn_url//\/nextcloud\/vm\//\/nextcloud\/vm\/main\/}"
654+
if curl -sfL "$cdn_url"/"$2" -o "$3"/"$2"
655+
then
656+
print_text_in_color "$IGreen" "✓ Used Statically.io CDN"
657+
break
658+
fi
659+
fi
660+
# Exhausted retries, try local backup
661+
if try_local_backup "$1" "$2" "$3"
662+
then
663+
print_text_in_color "$IGreen" "✓ Used local backup copy"
664+
break
637665
else
638-
return 1
666+
if yesno_box_yes "Tried 10 times but didn't succeed. We will now exit the script because it might break things. You can choose 'No' to continue on your own risk."
667+
then
668+
exit 1
669+
else
670+
return 1
671+
fi
639672
fi
640673
fi
641674
if ! curl -sfL "$1"/"$2" -o "$3"/"$2"
@@ -2280,6 +2313,71 @@ https://shop.hanssonit.se/product/upgrade-between-major-owncloud-nextcloud-versi
22802313
fi
22812314
}
22822315

2316+
## LOCAL REPOSITORY BACKUP FUNCTIONS
2317+
# These functions provide fallback to a local clone when GitHub is unavailable
2318+
2319+
# Clone or refresh local backup of repository
2320+
# This runs during update to keep a fresh copy as fallback
2321+
ensure_local_backup_repo() {
2322+
local BACKUP_REPO="/var/scripts/vm-repo-backup"
2323+
2324+
# Install git if needed
2325+
install_if_not git
2326+
2327+
# Remove old clone and get fresh copy
2328+
print_text_in_color "$ICyan" "Creating local backup of repository (in case of network issues)..."
2329+
rm -rf "$BACKUP_REPO"
2330+
2331+
# Clone with timeout, don't fail if it doesn't work
2332+
if timeout 120 git clone --depth 1 --branch main \
2333+
https://github.com/nextcloud/vm.git "$BACKUP_REPO" &>/dev/null
2334+
then
2335+
chmod -R +rx "$BACKUP_REPO"
2336+
print_text_in_color "$IGreen" "✓ Local backup ready"
2337+
return 0
2338+
else
2339+
print_text_in_color "$IYellow" "Could not create local backup (continuing anyway)"
2340+
return 1
2341+
fi
2342+
}
2343+
2344+
# Try to copy file from local backup repository
2345+
# Called when curl download fails (rate limits, network issues)
2346+
try_local_backup() {
2347+
local url="$1"
2348+
local file="$2"
2349+
local dest_dir="$3"
2350+
local BACKUP_REPO="/var/scripts/vm-repo-backup"
2351+
2352+
# Check if backup exists
2353+
if [ ! -d "$BACKUP_REPO" ]
2354+
then
2355+
return 1
2356+
fi
2357+
2358+
# Convert URL to local path
2359+
# https://raw.githubusercontent.com/nextcloud/vm/main/apps/script.sh -> apps/script.sh
2360+
local path_part
2361+
path_part=$(echo "$url" | sed 's|https://raw.githubusercontent.com/nextcloud/vm/main/||' | sed 's|https://raw.githubusercontent.com/nextcloud/vm/master/||')
2362+
2363+
# If path_part is empty, we're downloading from root
2364+
if [ -z "$path_part" ]
2365+
then
2366+
local local_file="$BACKUP_REPO/$file"
2367+
else
2368+
local local_file="$BACKUP_REPO/$path_part/$file"
2369+
fi
2370+
2371+
if [ -f "$local_file" ]
2372+
then
2373+
print_text_in_color "$IYellow" "⚠ GitHub unavailable, using local backup: $file"
2374+
cp "$local_file" "$dest_dir/$file"
2375+
return 0
2376+
else
2377+
return 1
2378+
fi
2379+
}
2380+
22832381
## bash colors
22842382
# Reset
22852383
Color_Off='\e[0m' # Text Reset

menu/menu.sh

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ root_check
1919
mkdir -p "$SCRIPTS"
2020
print_text_in_color "$ICyan" "Running the main menu script..."
2121

22-
if network_ok
23-
then
24-
# Delete, download, run
25-
run_script MENU main_menu
26-
fi
22+
# Try to run main_menu - will use local backup if GitHub unavailable
23+
run_script MENU main_menu
2724

2825
exit

nextcloud_install_production.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ install_if_not iputils-ping
164164

165165
# Download needed libraries before execution of the first script
166166
mkdir -p "$SCRIPTS"
167+
168+
# Create local backup (in case GitHub is rate limited during install)
169+
ensure_local_backup_repo
170+
167171
download_script GITHUB_REPO lib
168172
download_script STATIC fetch_lib
169173

nextcloud_update.sh

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,22 @@
1111
true
1212
SCRIPT_NAME="Nextcloud Update Script"
1313
# shellcheck source=lib.sh
14-
source <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/main/lib.sh)
14+
if [ -f /var/scripts/fetch_lib.sh ]
15+
then
16+
# shellcheck source=static/fetch_lib.sh
17+
source /var/scripts/fetch_lib.sh
18+
elif ! source <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/main/static/fetch_lib.sh)
19+
then
20+
source <(curl -sL https://cdn.statically.io/gh/nextcloud/vm/main/static/fetch_lib.sh)
21+
fi
1522

1623
# Get all needed variables from the library
1724
ncdb
1825
nc_update
1926

27+
# Create local backup of repository (for fallback if GitHub has issues)
28+
ensure_local_backup_repo
29+
2030
# Check for errors + debug code and abort if something isn't right
2131
# 1 = ON
2232
# 0 = OFF

static/fetch_lib.sh

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,36 @@ if ! [ -f /var/scripts/lib.sh ]
2222
then
2323
if ! curl -sfL https://raw.githubusercontent.com/nextcloud/vm/main/lib.sh -o /var/scripts/lib.sh
2424
then
25-
print_text_in_color "$IRed" "You don't seem to have an internet \
25+
# Try Statically.io CDN
26+
if curl -sfL https://cdn.statically.io/gh/nextcloud/vm/main/lib.sh -o /var/scripts/lib.sh
27+
then
28+
print_text_in_color "$IGreen" "✓ Used Statically.io CDN"
29+
# Try local backup
30+
elif [ -f /var/scripts/vm-repo-backup/lib.sh ]
31+
then
32+
print_text_in_color "$IYellow" "⚠ GitHub unavailable, using local backup: lib.sh"
33+
cp /var/scripts/vm-repo-backup/lib.sh /var/scripts/lib.sh
34+
else
35+
print_text_in_color "$IRed" "You don't seem to have an internet \
2636
connection and the local lib isn't available. Hence you cannot run this script."
27-
exit 1
37+
exit 1
38+
fi
2839
fi
2940
elif ! [ -f /var/scripts/nextcloud-startup-script.sh ]
3041
then
31-
curl -sfL https://raw.githubusercontent.com/nextcloud/vm/main/lib.sh -o /var/scripts/lib.sh
42+
if ! curl -sfL https://raw.githubusercontent.com/nextcloud/vm/main/lib.sh -o /var/scripts/lib.sh
43+
then
44+
# Try Statically.io CDN
45+
if curl -sfL https://cdn.statically.io/gh/nextcloud/vm/main/lib.sh -o /var/scripts/lib.sh
46+
then
47+
print_text_in_color "$IGreen" "✓ Used Statically.io CDN"
48+
# Try local backup
49+
elif [ -f /var/scripts/vm-repo-backup/lib.sh ]
50+
then
51+
print_text_in_color "$IYellow" "⚠ GitHub unavailable, using local backup: lib.sh"
52+
cp /var/scripts/vm-repo-backup/lib.sh /var/scripts/lib.sh
53+
fi
54+
fi
3255
fi
3356

3457
# shellcheck source=lib.sh

0 commit comments

Comments
 (0)