Template
Add one-click panel auto-update from git.evilfox.cc (v2.4.0).
Check Gitea releases in Settings and install the latest tag via git fetch/checkout with pip sync and restart when running from a git checkout.
This commit is contained in:
@@ -46,6 +46,7 @@ from managers.awg_manager import AWGManager
|
||||
from managers.xray_manager import XrayManager
|
||||
from managers.wireguard_manager import WireGuardManager
|
||||
from managers.backup_manager import BackupManager
|
||||
from managers.update_manager import UpdateManager, version_gt, api_latest_url, repo_url
|
||||
import telegram_bot as tg_bot
|
||||
|
||||
# Configure logging
|
||||
@@ -101,9 +102,9 @@ else:
|
||||
application_path = os.path.dirname(__file__)
|
||||
|
||||
DATA_FILE = os.path.join(application_path, 'data.json') # legacy JSON; used only for one-shot import / export
|
||||
CURRENT_VERSION = "v2.3.0"
|
||||
RELEASES_REPO_URL = "https://git.evilfox.cc/test2/Amnezia-Web-Panel-main"
|
||||
RELEASES_API_LATEST = "https://git.evilfox.cc/api/v1/repos/test2/Amnezia-Web-Panel-main/releases/latest"
|
||||
CURRENT_VERSION = "v2.4.0"
|
||||
RELEASES_REPO_URL = repo_url()
|
||||
RELEASES_API_LATEST = api_latest_url()
|
||||
BIN_DIR = os.environ.get('TUNNEL_BIN_DIR', os.path.join(application_path, 'bin'))
|
||||
TUNNEL_STATE_FILE = os.environ.get('TUNNEL_STATE_FILE', os.path.join(application_path, 'tunnels_state.json'))
|
||||
|
||||
@@ -1992,6 +1993,11 @@ class TunnelStartRequest(BaseModel):
|
||||
authtoken: Optional[str] = None
|
||||
|
||||
|
||||
class ApplyUpdateRequest(BaseModel):
|
||||
target_version: Optional[str] = None
|
||||
allow_dirty: bool = False
|
||||
|
||||
|
||||
# ======================== Startup ========================
|
||||
|
||||
@app.on_event("startup")
|
||||
@@ -5498,6 +5504,8 @@ async def api_check_updates(request: Request):
|
||||
if not _check_admin(request):
|
||||
return JSONResponse({'error': 'Forbidden'}, status_code=403)
|
||||
try:
|
||||
updater = UpdateManager(application_path, CURRENT_VERSION)
|
||||
mode = updater.detect_mode()
|
||||
async with httpx.AsyncClient(timeout=15.0, follow_redirects=True) as client:
|
||||
resp = await client.get(
|
||||
RELEASES_API_LATEST,
|
||||
@@ -5511,20 +5519,61 @@ async def api_check_updates(request: Request):
|
||||
data = resp.json() if resp.content else {}
|
||||
latest = (data.get('tag_name') or data.get('name') or '').strip()
|
||||
html_url = (data.get('html_url') or f'{RELEASES_REPO_URL}/releases').strip()
|
||||
body = (data.get('body') or '')[:4000]
|
||||
current = CURRENT_VERSION
|
||||
update_available = bool(latest) and latest != current
|
||||
update_available = bool(latest) and version_gt(latest, current)
|
||||
return {
|
||||
'current_version': current,
|
||||
'latest_version': latest,
|
||||
'update_available': update_available,
|
||||
'html_url': html_url,
|
||||
'releases_url': f'{RELEASES_REPO_URL}/releases',
|
||||
'body': body,
|
||||
'can_auto_update': bool(mode.get('can_auto_update')),
|
||||
'update_mode': mode.get('mode'),
|
||||
'mode': mode,
|
||||
}
|
||||
except Exception as e:
|
||||
logger.exception('Error checking for updates')
|
||||
return JSONResponse({'error': str(e)}, status_code=502)
|
||||
|
||||
|
||||
@app.post('/api/settings/apply_update', tags=["Settings"])
|
||||
async def api_apply_update(request: Request, req: ApplyUpdateRequest):
|
||||
"""Pull the selected release tag from git.evilfox.cc and restart the panel."""
|
||||
if not _check_admin(request):
|
||||
return JSONResponse({'error': 'Forbidden'}, status_code=403)
|
||||
updater = UpdateManager(application_path, CURRENT_VERSION)
|
||||
target = (req.target_version or '').strip()
|
||||
if not target:
|
||||
# Resolve latest if UI did not pass a tag
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=15.0, follow_redirects=True) as client:
|
||||
resp = await client.get(
|
||||
RELEASES_API_LATEST,
|
||||
headers={'Accept': 'application/json'},
|
||||
)
|
||||
if resp.status_code < 400 and resp.content:
|
||||
payload = resp.json()
|
||||
target = (payload.get('tag_name') or payload.get('name') or '').strip()
|
||||
except Exception:
|
||||
logger.exception('Failed to resolve latest tag for apply_update')
|
||||
if not target:
|
||||
return JSONResponse({'error': 'No target version specified'}, status_code=400)
|
||||
|
||||
result = await asyncio.to_thread(
|
||||
updater.apply_update,
|
||||
target,
|
||||
bool(req.allow_dirty),
|
||||
)
|
||||
if result.get('status') != 'success':
|
||||
return JSONResponse({'error': result.get('message') or 'Update failed', **result}, status_code=500)
|
||||
|
||||
if result.get('restart'):
|
||||
UpdateManager.schedule_restart(1.5)
|
||||
return result
|
||||
|
||||
|
||||
@app.get('/api/settings/tunnels/status', tags=["Settings"])
|
||||
async def api_tunnels_status(request: Request):
|
||||
if not _check_admin(request):
|
||||
|
||||
Reference in New Issue
Block a user