v0.36.5
This commit is contained in:
1 parent
6ef01212ec
commit
d7fb869783
4 files changed
+41
-6
No files matched your search
Executable → Regular
+27
-1
@@ -28,6 +28,7 @@ import subprocess
|
||||
import sys
|
||||
import time
|
||||
import uuid
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
|
||||
@@ -41,6 +42,12 @@ GEOIP_SOURCES = {
|
||||
'user-country-ipv6.csv': 'https://github.com/sapics/ip-location-db/releases/download/latest/user-country-ipv6.csv',
|
||||
}
|
||||
GEOIP_MAX_BYTES = 256 * 1024 * 1024
|
||||
GEOIP_FETCH_ATTEMPTS = 4
|
||||
GEOIP_RETRY_DELAYS = (3, 6, 12)
|
||||
|
||||
|
||||
class GeoipUnavailable(RuntimeError):
|
||||
"""The GeoIP CSV download failed after retries; the deployment itself can continue."""
|
||||
|
||||
|
||||
def run(args: list[str], **kwargs) -> subprocess.CompletedProcess:
|
||||
@@ -93,7 +100,7 @@ def digest(path: Path) -> str:
|
||||
return result.hexdigest()
|
||||
|
||||
|
||||
def fetch_https(url: str, max_bytes: int) -> bytes:
|
||||
def _fetch_https_once(url: str, max_bytes: int) -> bytes:
|
||||
if urllib.parse.urlparse(url).scheme != 'https':
|
||||
raise ValueError('GeoIP downloads require HTTPS.')
|
||||
request = urllib.request.Request(url, headers={'User-Agent': 'RustProxy-installer'})
|
||||
@@ -114,6 +121,25 @@ def fetch_https(url: str, max_bytes: int) -> bytes:
|
||||
return bytes(result)
|
||||
|
||||
|
||||
def fetch_https(url: str, max_bytes: int) -> bytes:
|
||||
"""Download with retries; transient gateway/network failures (502/503/504, timeouts) are retried."""
|
||||
last: BaseException | None = None
|
||||
for attempt in range(GEOIP_FETCH_ATTEMPTS):
|
||||
try:
|
||||
return _fetch_https_once(url, max_bytes)
|
||||
except urllib.error.HTTPError as error:
|
||||
last = error
|
||||
if error.code not in (408, 425, 429) and error.code < 500:
|
||||
break
|
||||
except (urllib.error.URLError, TimeoutError, ConnectionError, ssl.SSLError) as error:
|
||||
last = error
|
||||
if attempt + 1 < GEOIP_FETCH_ATTEMPTS:
|
||||
delay = GEOIP_RETRY_DELAYS[min(attempt, len(GEOIP_RETRY_DELAYS) - 1)]
|
||||
print(f'GeoIP download failed ({last}); retrying in {delay}s ({attempt + 1}/{GEOIP_FETCH_ATTEMPTS - 1}).', file=sys.stderr)
|
||||
time.sleep(delay)
|
||||
raise GeoipUnavailable(f'GeoIP download from {url} failed: {last}')
|
||||
|
||||
|
||||
def acquire_geoip_update_lock(data: Path, uid: int | None = None, gid: int | None = None) -> int:
|
||||
"""Serialize installer/manual GeoIP refresh with the in-process worker."""
|
||||
path = data / '.geoip-update.lock'
|
||||
|
||||
Executable → Regular
+10
-2
@@ -365,7 +365,12 @@ def update(record: dict, binary: Path, sha: str, start: bool, refresh_geoip: boo
|
||||
if refresh_geoip:
|
||||
# Shared lock with the runtime worker prevents concurrent upgrades.
|
||||
geoip_lock_fd = acquire_geoip_update_lock(data, account.pw_uid, account.pw_gid)
|
||||
geoip_stage, geoip_names = prepare_geoip_update(data, prefix)
|
||||
try:
|
||||
geoip_stage, geoip_names = prepare_geoip_update(data, prefix)
|
||||
except GeoipUnavailable as error:
|
||||
# GeoIP is refreshed best-effort: the update must not be blocked by a flaky download.
|
||||
print(f'WARNING: GeoIP refresh skipped, keeping the installed country data: {error}', file=sys.stderr)
|
||||
geoip_stage, geoip_names = None, []
|
||||
active = subprocess.run(['systemctl', 'is-active', '--quiet', SERVICE], check=False, stdout=subprocess.DEVNULL).returncode == 0
|
||||
stop_for_managed_update(data)
|
||||
try:
|
||||
@@ -434,7 +439,10 @@ def install(record: dict, binary: Path, sha: str, start: bool, install_geoip: bo
|
||||
prefix.mkdir(parents=True, mode=0o755, exist_ok=True); os.chmod(prefix, 0o755)
|
||||
data.mkdir(parents=True, mode=0o700, exist_ok=True); os.chmod(data, 0o700); os.chown(data, account.pw_uid, account.pw_gid)
|
||||
if install_geoip:
|
||||
download_geoip(data, account.pw_uid, account.pw_gid)
|
||||
try:
|
||||
download_geoip(data, account.pw_uid, account.pw_gid)
|
||||
except GeoipUnavailable as error:
|
||||
print(f'WARNING: GeoIP download skipped ({error}). Country allow/block lists will use data fetched later by the GeoIP updater, or rerun update.sh.', file=sys.stderr)
|
||||
release, version = stage(binary, prefix, record['user'], sha)
|
||||
record.update(release=release, version=version, sha256=sha)
|
||||
switch(prefix, release)
|
||||
|
||||
Reference in new issue
Block a user