Ship a get-py in /opt/examples

This commit is contained in:
Kevin Lange 2016-12-19 23:42:12 +09:00
parent 8ef8dec183
commit b7f7da2733

142
hdd/opt/examples/get-py Executable file
View File

@ -0,0 +1,142 @@
#!/usr/bin/python3
import json
import subprocess
import sys
import hashlib
import os
import stat
url = 'http://toaruos.org'
if not os.getuid() == 0:
print(f"{sys.argv[0]}: must be root")
sys.exit(1)
def compare_version(left,right):
if left[0] > right[0]: return True
if left[0] == right[0] and left[1] > right[1]: return True
if left[0] == right[0] and left[1] == right[1] and left[2] > right[2]: return True
return False
def fetch_file(path, output, check=False, url=url):
loop = 0
while loop < 3:
subprocess.call(['fetch','-o',output,f'{url}/{path}'])
if check:
s = hashlib.sha512()
with open(output,'rb') as f:
for chunk in iter(lambda: f.read(4096), b""):
s.update(chunk)
if s.hexdigest() != check:
if loop == 2:
print("Too many bad checksums, bailing.")
else:
print("Bad checksum, trying again...")
loop += 1
continue
break
fetch_file('manifest.json','/tmp/manifest.json')
with open('/tmp/manifest.json') as f:
manifest = json.load(f)
try:
with open('/tmp/installed.json') as f:
installed_packages = json.load(f)
except:
installed_packages = {}
if not 'packages' in manifest:
print("Invalid manifest file.")
sys.exit(1)
if len(sys.argv) < 2:
print("Available packages:")
packages = sorted(manifest['packages'].keys())
for k in packages:
print(f" - {k}","(installed)" if k in installed_packages else "")
sys.exit(0)
packages_to_install = []
upgrade_packages = []
install_packages = []
def process_package(name):
if not name in manifest['packages']:
print(f"Unknown package: {arg}")
sys.exit(1)
package = manifest['packages'][name]
if 'deps' in package:
for dep in package['deps']:
if dep not in packages_to_install:
process_package(dep)
packages_to_install.append(name)
for arg in sys.argv[1:]:
process_package(arg)
for name in packages_to_install:
if name in installed_packages:
if compare_version(manifest['packages'][name]['version'],installed_packages[name]):
upgrade_packages.append(name)
else:
install_packages.append(name)
def install_file(file,source):
print(f"- Retreiving file {file[0]}","and checking hash" if file[2] else "")
fetch_file(file[0],file[1],file[2],source)
def run_install_step(step):
if step[0] == 'ln':
print(f"- Linking {step[2]} -> {step[1]}")
subprocess.call(['ln','-s',step[1],step[2]])
elif step[0] == 'tmpfs':
print(f"- Mounting tmpfs at {step[1]}")
subprocess.call(['mount','tmpfs','x',step[1]])
elif step[0] == 'ext2':
print(f"- Mounting ext2 image {step[1]} at {step[2]}")
subprocess.call(['mount','ext2',step[1],step[2]])
elif step[0] == 'chmodx':
print(f"- Making {step[1]} executable")
current = os.stat(step[1]).st_mode
os.chmod(step[1],current | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
else:
print("Unknown step:",step)
def install_package(name):
if not name in manifest['packages']:
print(f"Unknown package: {arg}")
sys.exit(1)
package = manifest['packages'][name]
if 'pre_steps' in package:
for step in package['pre_steps']:
run_install_step(step)
if 'files' in package:
url_source = url
if 'source' in package:
source = package['source']
if source not in manifest['sources']:
print(f"Bad source '{source}', will try locally.")
url_source = manifest['sources'][source]
for file in package['files']:
install_file(file,url_source)
if 'post_steps' in package:
for step in package['post_steps']:
run_install_step(step)
installed_packages[name] = package['version']
for package in packages_to_install:
if package in upgrade_packages:
print(f"Upgrading {package}...")
install_package(package)
elif package in install_packages:
print(f"Installing {package}...")
install_package(package)
if not upgrade_packages and not install_packages:
print(f"{sys.argv[0]}: up to date")
with open('/tmp/installed.json','w') as f:
json.dump(installed_packages, f)