conductor/scripts/build-upgrade-bundle.py

36 lines
2.6 KiB
Python

"""Build a local VM upgrade kit. The core image and published app release are unchanged."""
import argparse,hashlib,pathlib,shutil,tarfile,tempfile
ROOT=pathlib.Path(__file__).resolve().parent.parent
parser=argparse.ArgumentParser()
parser.add_argument('--scripts',type=pathlib.Path,default=ROOT.parent/'skeletonworks-scripts')
parser.add_argument('--legacy-app-release',type=pathlib.Path,default=ROOT.parent/'social-scheduler/release/social-scheduler-0.5.0.tar.gz')
parser.add_argument('--migration-recipe',type=pathlib.Path,default=ROOT.parent/'social-scheduler/integration/conductor-migration.json')
args=parser.parse_args()
expected='e5a9e230a53c750c63aefeed6ec91fb6ca04e678a7cb75418e921b48ac27fdbd'
if hashlib.sha256(args.legacy_app_release.read_bytes()).hexdigest()!=expected:raise SystemExit('The legacy frontend migration requires the verified, published Social Scheduler 0.5.0 kit.')
out=ROOT/'release';out.mkdir(exist_ok=True)
with tempfile.TemporaryDirectory(prefix='conductor-upgrade-') as temp:
kit=pathlib.Path(temp)/'conductor-upgrade';kit.mkdir()
for name in ['update-conductor.sh','setup-conductor.sh','backup-conductor.sh','restore-conductor.sh']:
shutil.copy2(args.scripts/name,kit/name)
guide=ROOT/'docs/CONDUCTOR_UPGRADE.md'
if guide.exists():shutil.copy2(guide,kit/'INSTALL.md')
packages=kit/'conductor-app-packages';packages.mkdir()
# Only the app-owned browser package and declarative connection mapping are bundled.
with tarfile.open(args.legacy_app_release) as archive:
prefix='social-scheduler/dist/conductor-app/'
for member in archive:
if not member.name.startswith(prefix) or member.isdir():continue
relative=pathlib.PurePosixPath(member.name[len(prefix):])
if not member.isfile() or relative.is_absolute() or '..' in relative.parts:raise SystemExit('Unsafe release package asset.')
target=packages/'social-scheduler'/str(relative);target.parent.mkdir(parents=True,exist_ok=True)
target.write_bytes(archive.extractfile(member).read())
shutil.copy2(args.migration_recipe,packages/'social-scheduler/conductor-migration.json')
files=sorted(p for p in kit.rglob('*') if p.is_file())
(kit/'SHA256SUMS').write_text(''.join(hashlib.sha256(p.read_bytes()).hexdigest()+' '+str(p.relative_to(kit))+'\n' for p in files))
output=out/'conductor-upgrade-1.1.0.tar.gz'
with tarfile.open(output.with_suffix('.gz.new'),'w:gz') as archive:archive.add(kit,arcname=kit.name)
output.with_suffix('.gz.new').replace(output)
(out/(output.name+'.sha256')).write_text(hashlib.sha256(output.read_bytes()).hexdigest()+' '+output.name+'\n')
print(output)