rollback-web.py 1.8 KB

1234567891011121314151617181920
  1. """Restore this release's saved admin entry; preserve all versioned assets."""
  2. from pathlib import Path
  3. import hashlib, importlib.util, json, sys, urllib.request
  4. assert sys.argv[1:] == ['--apply'], 'Use --apply only for the authorized release rollback'
  5. root=Path('/Users/mac/.local/state/xiaoshu/cloud-releases/2026-11-10-admin-speed-round2/admin')
  6. origin='https://xiaoshu-admin.obs.cn-south-1.myhuaweicloud.com/'
  7. sha=lambda b:hashlib.sha256(b).hexdigest()
  8. current=json.loads(urllib.request.urlopen(origin+'deployment-version.json',timeout=30).read())
  9. expected=json.loads((root/'site/deployment-version.json').read_text())
  10. baseline=json.loads((root/'baseline/deployment-version.json').read_text())
  11. assert current['releaseId'] in [expected['releaseId'],baseline['releaseId']], 'Unrelated release has replaced this batch'
  12. for file in baseline['files']:
  13. assert sha(urllib.request.urlopen(origin+file['path'],timeout=30).read() if file['path']!='index.html' else (root/'baseline/index.html').read_bytes()) == file['sha256'], 'Baseline asset missing'
  14. spec=importlib.util.spec_from_file_location('cloud','/Users/mac/.local/state/xiaoshu/cloud-releases/2026-10-15-mobile-web/cloud.py')
  15. cloud=importlib.util.module_from_spec(spec);spec.loader.exec_module(cloud)
  16. for name in ['deployment-version.json','index.html']:
  17. (root/('rollback-'+name+'.log')).write_text(cloud.run('obs',['cp',str(root/'baseline'/name),'obs://xiaoshu-admin/'+name,'-vmd5','-acl=public-read']))
  18. assert sha(urllib.request.urlopen(origin+name,timeout=30).read())==sha((root/'baseline'/name).read_bytes())
  19. (root/'rollback-cdn.json').write_text(cloud.run('cdn',['CreateRefreshTasks/v2','--refresh_task.type=directory','--refresh_task.mode=all','--refresh_task.urls.1=https://admin.xiaoshu.pro/']))
  20. print(json.dumps({'restored':baseline['releaseId'],'originVerified':True}))