Implement actual update function, lazy-load online_packages
This commit is contained in:
parent
ecb09001d4
commit
be36199640
@ -56,7 +56,6 @@ def print_apps(packages):
|
|||||||
|
|
||||||
def list_online():
|
def list_online():
|
||||||
pm = PkgMgr()
|
pm = PkgMgr()
|
||||||
pm.fetch_online_packages()
|
|
||||||
apps = pm.online_packages['apps']
|
apps = pm.online_packages['apps']
|
||||||
if apps:
|
if apps:
|
||||||
print_apps(apps)
|
print_apps(apps)
|
||||||
|
@ -15,6 +15,10 @@ from . import lxcmgr
|
|||||||
from . import svcmgr
|
from . import svcmgr
|
||||||
from .paths import LXC_STORAGE_DIR, REPO_CACHE_DIR, REPO_CONF_FILE, REPO_LOCAL_FILE, REPO_LOCK, REPO_SIG_FILE
|
from .paths import LXC_STORAGE_DIR, REPO_CACHE_DIR, REPO_CONF_FILE, REPO_LOCAL_FILE, REPO_LOCK, REPO_SIG_FILE
|
||||||
|
|
||||||
|
INSTALL_SCRIPT = 'install.sh'
|
||||||
|
UPDATE_SCRIPT = 'update.sh'
|
||||||
|
UNINSTALL_SCRIPT = 'uninstall.sh'
|
||||||
|
|
||||||
class Stage(Enum):
|
class Stage(Enum):
|
||||||
QUEUED = 1
|
QUEUED = 1
|
||||||
DOWNLOAD = 2
|
DOWNLOAD = 2
|
||||||
@ -49,10 +53,20 @@ class PkgMgr:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.repo_url = None
|
self.repo_url = None
|
||||||
self.repo_auth = None
|
self.repo_auth = None
|
||||||
self.online_packages = None
|
self._online_packages = None
|
||||||
with open(REPO_LOCAL_FILE, 'r') as f:
|
with open(REPO_LOCAL_FILE, 'r') as f:
|
||||||
self.installed_packages = json.load(f)
|
self.installed_packages = json.load(f)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def online_packages(self):
|
||||||
|
if not self._online_packages:
|
||||||
|
# Fetches and verifies online packages. Can raise InvalidSignature
|
||||||
|
packages = self.get_repo_resource('packages').content
|
||||||
|
packages_sig = self.get_repo_resource('packages.sig').content
|
||||||
|
crypto.verify_signature(REPO_SIG_FILE, packages, packages_sig)
|
||||||
|
self._online_packages = json.loads(packages)
|
||||||
|
return self._online_packages
|
||||||
|
|
||||||
def save_installed_packages(self):
|
def save_installed_packages(self):
|
||||||
with open(REPO_LOCAL_FILE, 'w') as f:
|
with open(REPO_LOCAL_FILE, 'w') as f:
|
||||||
json.dump(self.installed_packages, f, sort_keys=True, indent=4)
|
json.dump(self.installed_packages, f, sort_keys=True, indent=4)
|
||||||
@ -79,21 +93,26 @@ class PkgMgr:
|
|||||||
raise RepoBadRequest(r.url)
|
raise RepoBadRequest(r.url)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def fetch_online_packages(self):
|
|
||||||
# Fetches and verifies online packages. Can raise InvalidSignature
|
|
||||||
packages = self.get_repo_resource('packages').content
|
|
||||||
packages_sig = self.get_repo_resource('packages.sig').content
|
|
||||||
crypto.verify_signature(REPO_SIG_FILE, packages, packages_sig)
|
|
||||||
self.online_packages = json.loads(packages)
|
|
||||||
|
|
||||||
@flock.flock_ex(REPO_LOCK)
|
@flock.flock_ex(REPO_LOCK)
|
||||||
def install_app(self, app):
|
def install_app(self, app):
|
||||||
# Main installation function. Wrapper for download, registration and install script
|
# Main installation function. Wrapper for download, registration and install script
|
||||||
if app.name in self.installed_packages['apps']:
|
if app.name in self.installed_packages['apps']:
|
||||||
app.stage = Stage.DONE
|
app.stage = Stage.DONE
|
||||||
return
|
return
|
||||||
if not self.online_packages:
|
self.download_and_unpack_deps(app)
|
||||||
self.fetch_online_packages()
|
# Run setup scripts
|
||||||
|
app.stage = Stage.INSTALL
|
||||||
|
# Run uninstall script to clean previous failed installation
|
||||||
|
self.run_script(app.name, UNINSTALL_SCRIPT)
|
||||||
|
# Build containers and services
|
||||||
|
self.create_containers(self.online_packages['apps'][app.name]['containers'])
|
||||||
|
# Run install script and register the app
|
||||||
|
self.run_script(app.name, INSTALL_SCRIPT)
|
||||||
|
self.register_app(app.name, self.online_packages['apps'][app.name])
|
||||||
|
app.stage = Stage.DONE
|
||||||
|
|
||||||
|
def download_and_unpack_deps(self, app):
|
||||||
|
# Common download and unpack function for install and update
|
||||||
# Get all packages on which the app and its containers depend and which have not been installed yet
|
# Get all packages on which the app and its containers depend and which have not been installed yet
|
||||||
images = []
|
images = []
|
||||||
image_deps = [container['image'] for container in self.online_packages['apps'][app.name]['containers'].values()]
|
image_deps = [container['image'] for container in self.online_packages['apps'][app.name]['containers'].values()]
|
||||||
@ -116,16 +135,6 @@ class PkgMgr:
|
|||||||
self.register_image(image, self.online_packages['images'][image])
|
self.register_image(image, self.online_packages['images'][image])
|
||||||
self.purge_scripts(app.name)
|
self.purge_scripts(app.name)
|
||||||
self.unpack_scripts(app.name)
|
self.unpack_scripts(app.name)
|
||||||
# Run setup scripts
|
|
||||||
app.stage = Stage.INSTALL
|
|
||||||
# Run uninstall script to clean previous failed installation
|
|
||||||
self.run_uninstall_script(app.name)
|
|
||||||
# Build containers and services
|
|
||||||
self.create_containers(self.online_packages['apps'][app.name]['containers'])
|
|
||||||
# Run install script and register the app
|
|
||||||
self.run_install_script(app.name)
|
|
||||||
self.register_app(app.name, self.online_packages['apps'][app.name])
|
|
||||||
app.stage = Stage.DONE
|
|
||||||
|
|
||||||
def download_image(self, app, image):
|
def download_image(self, app, image):
|
||||||
# Download image archive and verify hash
|
# Download image archive and verify hash
|
||||||
@ -184,14 +193,6 @@ class PkgMgr:
|
|||||||
subprocess.run(['tar', 'xJf', tmp_archive], cwd=os.path.join(REPO_CACHE_DIR, 'apps'), check=True)
|
subprocess.run(['tar', 'xJf', tmp_archive], cwd=os.path.join(REPO_CACHE_DIR, 'apps'), check=True)
|
||||||
os.unlink(tmp_archive)
|
os.unlink(tmp_archive)
|
||||||
|
|
||||||
def run_uninstall_script(self, app):
|
|
||||||
# Runs uninstall.sh for an app, if the script is present
|
|
||||||
self.run_script(app, 'uninstall.sh')
|
|
||||||
|
|
||||||
def run_install_script(self, app):
|
|
||||||
# Runs install.sh for a package, if the script is present
|
|
||||||
self.run_script(app, 'install.sh')
|
|
||||||
|
|
||||||
def run_script(self, app, script):
|
def run_script(self, app, script):
|
||||||
# Runs script for an app, if the script is present
|
# Runs script for an app, if the script is present
|
||||||
script_dir = os.path.join(REPO_CACHE_DIR, 'apps', app)
|
script_dir = os.path.join(REPO_CACHE_DIR, 'apps', app)
|
||||||
@ -239,7 +240,7 @@ class PkgMgr:
|
|||||||
app.stage = Stage.DONE
|
app.stage = Stage.DONE
|
||||||
return
|
return
|
||||||
app.stage = Stage.UNINSTALL
|
app.stage = Stage.UNINSTALL
|
||||||
self.run_uninstall_script(app.name)
|
self.run_script(app.name, UNINSTALL_SCRIPT)
|
||||||
self.destroy_containers(self.installed_packages['apps'][app.name]['containers'])
|
self.destroy_containers(self.installed_packages['apps'][app.name]['containers'])
|
||||||
self.purge_scripts(app.name)
|
self.purge_scripts(app.name)
|
||||||
self.unregister_app(app.name)
|
self.unregister_app(app.name)
|
||||||
@ -259,17 +260,20 @@ class PkgMgr:
|
|||||||
self.purge_layer(layer)
|
self.purge_layer(layer)
|
||||||
|
|
||||||
@flock.flock_ex(REPO_LOCK)
|
@flock.flock_ex(REPO_LOCK)
|
||||||
def update_app(self, app, item):
|
def update_app(self, app):
|
||||||
# Main update function.
|
# Main update function.
|
||||||
# TODO: Implement actual update
|
self.download_and_unpack_deps(app)
|
||||||
uninstall_app(app)
|
# Run setup scripts
|
||||||
install_app(app, item)
|
app.stage = Stage.UPDATE
|
||||||
|
# Build containers and services
|
||||||
|
self.create_containers(self.online_packages['apps'][app.name]['containers'])
|
||||||
|
# Run update script and register the app
|
||||||
|
self.run_script(app.name, UPDATE_SCRIPT)
|
||||||
|
self.register_app(app.name, self.online_packages['apps'][app.name])
|
||||||
app.stage = Stage.DONE
|
app.stage = Stage.DONE
|
||||||
|
|
||||||
def has_update(self, app):
|
def has_update(self, app):
|
||||||
# Check if online repository list a newer version of app
|
# Check if online repository list a newer version of app
|
||||||
if not self.online_packages:
|
|
||||||
self.fetch_online_packages()
|
|
||||||
if app not in self.online_packages['apps']:
|
if app not in self.online_packages['apps']:
|
||||||
# Application has been removed from online repo
|
# Application has been removed from online repo
|
||||||
return False
|
return False
|
||||||
|
@ -174,7 +174,7 @@ class WSGIApp:
|
|||||||
# Application manager view.
|
# Application manager view.
|
||||||
repo_error = None
|
repo_error = None
|
||||||
try:
|
try:
|
||||||
self.appmgr.pkgmgr.fetch_online_packages()
|
self.appmgr.pkgmgr.fetch_online_packages() # TODO: fetch is now automatic in @property
|
||||||
except InvalidSignature:
|
except InvalidSignature:
|
||||||
repo_error = request.session.lang.invalid_packages_signature()
|
repo_error = request.session.lang.invalid_packages_signature()
|
||||||
except Unauthorized:
|
except Unauthorized:
|
||||||
|
Loading…
Reference in New Issue
Block a user