Destroy containers on install to cleanup previous
This commit is contained in:
parent
7591cf2d47
commit
6045349f9c
@ -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()
|
||||
|
@ -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))
|
||||
|
@ -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])
|
||||
|
@ -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}
|
||||
|
Loading…
Reference in New Issue
Block a user