diff --git a/usr/bin/lxcmgr b/usr/bin/lxcmgr index 52e1d66..e87293e 100755 --- a/usr/bin/lxcmgr +++ b/usr/bin/lxcmgr @@ -118,10 +118,12 @@ def install_app(app): def update_app(app): pm = PkgMgr() + app = App(app) run_install_action(pm.update_app, app) def uninstall_app(app): pm = PkgMgr() + app = App(app) run_install_action(pm.uninstall_app, app) args = parser.parse_args() diff --git a/usr/lib/python3.6/lxcmgr/pkgmgr.py b/usr/lib/python3.6/lxcmgr/pkgmgr.py index 02b7ac6..970ed98 100644 --- a/usr/lib/python3.6/lxcmgr/pkgmgr.py +++ b/usr/lib/python3.6/lxcmgr/pkgmgr.py @@ -109,6 +109,7 @@ class PkgMgr: self.download_scripts(app) # Purge old data to clean previous failed installation and unpack downloaded archives app.stage = Stage.UNPACK + self.destroy_containers(self.online_packages['apps'][app.name]['containers']) for image in images: self.purge_image(image) self.unpack_image(image) @@ -120,8 +121,7 @@ class PkgMgr: # Run uninstall script to clean previous failed installation self.run_uninstall_script(app.name) # Build containers and services - self.create_containers(app.name) - # TODO: Create 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]) @@ -209,38 +209,38 @@ class PkgMgr: del self.installed_packages['apps'][app] self.save_installed_packages() - def create_containers(self, app): + def create_containers(self, containers): # Create LXC containers from image and app metadata - for container in self.online_packages['apps'][app]['containers']: - image = self.online_packages['apps'][app]['containers'][container]['image'] + for container in containers: + image = containers[container]['image'] image = self.online_packages['images'][image].copy() - if 'mounts' in self.online_packages['apps'][app]['containers'][container]: - image['mounts'] = self.online_packages['apps'][app]['containers'][container]['mounts'] - if 'depends' in self.online_packages['apps'][app]['containers'][container]: - image['depends'] = self.online_packages['apps'][app]['containers'][container]['depends'] + if 'mounts' in containers[container]: + image['mounts'] = containers[container]['mounts'] + if 'depends' in containers[container]: + image['depends'] = containers[container]['depends'] lxcmgr.create_container(container, image) - svcmgr.create_service(app, container, image) + svcmgr.create_service(container, image) + + def destroy_containers(self, containers): + # Destroy LXC containers + for container in containers: + svcmgr.delete_service(container) + lxcmgr.destroy_container(container) @flock.flock_ex(REPO_LOCK) def uninstall_app(self, app): # Main uninstallation function. Wrapper for uninstall script and filesystem purge - if app not in self.installed_packages['apps']: + if app.name not in self.installed_packages['apps']: app.stage = Stage.DONE return app.stage = Stage.UNINSTALL - self.run_uninstall_script(app) - self.destroy_containers(app) - self.purge_scripts(app) - self.unregister_app(app) + self.run_uninstall_script(app.name) + self.destroy_containers(self.installed_packages['apps'][app.name]['containers']) + self.purge_scripts(app.name) + self.unregister_app(app.name) self.purge_unused_layers() app.stage = Stage.DONE - def destroy_containers(self, app): - # Destroy LXC containers - for container in self.installed_packages['apps'][app]['containers']: - svcmgr.delete_service(container) - lxcmgr.destroy_container(container) - def purge_unused_layers(self): # Remove layers which are no longer used by any installed application layers = set(os.list(LXC_STORAGE_DIR)) diff --git a/usr/lib/python3.6/lxcmgr/svcmgr.py b/usr/lib/python3.6/lxcmgr/svcmgr.py index 5343279..8c7da2f 100644 --- a/usr/lib/python3.6/lxcmgr/svcmgr.py +++ b/usr/lib/python3.6/lxcmgr/svcmgr.py @@ -6,14 +6,14 @@ import subprocess from .paths import AUTOSTART_SVC_DIR, SERVICE_DIR, STARTED_SVC_DIR from .templates import SERVICE -def create_service(app, container, image): +def create_service(container, image): depends = ' '.join(image['depends']) if 'depends' in image else '' # Add ready check to start_post # This could arguably be better done via some template engine, but introducing one for 2 template files seems like overkill start_post = '\nstart_post() {{\n timeout -t 60 lxc-attach {} -- sh -c \'until {}; do sleep 0.1; done\'\n}}\n'.format(container, image['ready']) if 'ready' in image else '' service_file = os.path.join(SERVICE_DIR, container) with open(service_file, 'w') as f: - f.write(SERVICE.format(app=app, container=container, depends=depends, start_post=start_post)) + f.write(SERVICE.format(container=container, depends=depends, start_post=start_post)) os.chmod(service_file, 0o755) update_services() @@ -24,9 +24,9 @@ def delete_service(service): update_service_autostart(service, False) try: os.unlink(os.path.join(SERVICE_DIR, service)) + update_services() except FileNotFoundError: pass - update_services() def update_services(): subprocess.run(['/sbin/rc-update', '-u'], check=True) @@ -39,14 +39,14 @@ def stop_service(service): if is_service_started(service): subprocess.run(['/sbin/service', service, 'stop'], check=True) -def is_service_started(self, app): +def is_service_started(service): # Check OpenRC service status without calling any binary - return os.path.exists(os.path.join(STARTED_SVC_DIR, app)) + return os.path.exists(os.path.join(STARTED_SVC_DIR, service)) -def is_service_autostarted(self, app): +def is_service_autostarted(service): # Check OpenRC service enablement - return os.path.exists(os.path.join(AUTOSTART_SVC_DIR, app)) + return os.path.exists(os.path.join(AUTOSTART_SVC_DIR, service)) -def update_service_autostart(self, service, enabled): - # Add/remove the app to OpenRC default runlevel +def update_service_autostart(service, enabled): + # Add/remove the service to/from OpenRC default runlevel subprocess.run(['/sbin/rc-update', 'add' if enabled else 'del', service]) diff --git a/usr/lib/python3.6/lxcmgr/templates.py b/usr/lib/python3.6/lxcmgr/templates.py index 673d458..ce3258e 100644 --- a/usr/lib/python3.6/lxcmgr/templates.py +++ b/usr/lib/python3.6/lxcmgr/templates.py @@ -51,7 +51,7 @@ lxc.include = /usr/share/lxc/config/userns.conf SERVICE = """#!/sbin/openrc-run -description="{app} {container} LXC container" +description="{container} LXC container" depend() {{ need cgroups {depends}