# -*- coding: utf-8 -*- import os import subprocess #from .pkgmgr import Pkg, PkgMgr class AppMgr: def __init__(self, conf): self.conf = conf self.pkgmgr = None #PkgMgr(conf) def start_app(self, item): # Start the actual app service app = item.key if app in self.conf['apps'] and not self.is_service_started(app): self.start_service(app) def start_service(self, service): subprocess.run(['/sbin/service', service, 'start'], check=True) def stop_app(self, item): # Stop the actual app service app = item.key if app in self.conf['apps'] and self.is_service_started(app): self.stop_service(app) # Stop the app service's dependencies if they are not used by another running app deps = self.get_services_deps() for dep in self.get_service_deps(app): if not any([self.is_service_started(d) for d in deps[dep]]): self.stop_service(dep) def stop_service(self, service): subprocess.run(['/sbin/service', service, 'stop'], check=True) def update_app_visibility(self, app, visible): # Update visibility for the app in the configuration if app in self.conf['apps']: self.conf['apps'][app]['visible'] = visible self.conf.save() def update_app_autostart(self, app, enabled): # Add/remove the app to OpenRC default runlevel if app in self.conf['apps']: subprocess.run(['/sbin/rc-update', 'add' if enabled else 'del', app]) def is_service_started(self, app): # Check OpenRC service status without calling any binary return os.path.exists(os.path.join('/run/openrc/started', app)) def is_service_autostarted(self, app): # Check OpenRC service enablement return os.path.exists(os.path.join('/etc/runlevels/default', app)) def install_app(self, item): # Main installation function. Wrapper for download, registration and install script item.data = None #Pkg() self.pkgmgr.install_app(item.key, item.data) def uninstall_app(self, item): # Main uninstallation function. Wrapper for uninstall script, filesystem purge and unregistration app = item.key self.stop_app(item) if self.is_service_autostarted(app): self.update_app_autostart(app, False) self.pkgmgr.uninstall_app(app) def update_app(self, item): # Main update function. Wrapper for download and update script self.stop_app(item) item.data = None #Pkg() self.pkgmgr.update_app(item.key, item.data) def get_services_deps(self): # Fisrt, build a dictionary of {app: [needs]} needs = {} for app in self.conf['apps'].copy(): needs[app] = self.get_service_deps(app) # Then reverse it to {need: [apps]} deps = {} for app, need in needs.items(): for n in need: deps.setdefault(n, []).append(app) return deps def get_service_deps(self, app): # Get "need" line from init script and split it to a list try: with open(os.path.join('/etc/init.d', app), 'r') as f: return [l for l in f.readlines() if l.strip().startswith('need')][0].split()[1:] except: pass return [] def update_repo_settings(self, url, user, pwd): # Update lxc repository configuration self.conf['repo']['url'] = url self.conf['repo']['user'] = user self.conf['repo']['pwd'] = pwd self.conf.save()