# -*- coding: utf-8 -*- import os import subprocess from .paths import AUTOSTART_SVC_DIR, SERVICE_DIR, STARTED_SVC_DIR from .templates import SERVICE def lxcize(service): # Prepend lxc- to service name, otherwise there's much greater risk of naming conflict with other host services return 'lxc-{}'.format(service) def create_service(container, image): depends = ' '.join([lxcize(service) for service in image['depends']]) if 'depends' in image else '' # Add ready check to start_post # This could arguably be done better via some template engine, but introducing one for a single template file seems like an 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, lxcize(container)) with open(service_file, 'w') as f: f.write(SERVICE.format(container=container, depends=depends, start_post=start_post)) os.chmod(service_file, 0o755) def delete_service(service): if is_service_started(service): stop_service(service) if is_service_autostarted(service): update_service_autostart(service, False) try: os.unlink(os.path.join(SERVICE_DIR, lxcize(service))) except FileNotFoundError: pass def update_services(): subprocess.run(['/sbin/rc-update', '-u'], check=True) def start_service(service): if not is_service_started(service): subprocess.run(['/sbin/service', lxcize(service), 'start'], check=True) def stop_service(service): if is_service_started(service): subprocess.run(['/sbin/service', lxcize(service), 'stop'], check=True) def is_service_started(service): # Check OpenRC service status without calling any binary return os.path.exists(os.path.join(STARTED_SVC_DIR, lxcize(service))) def is_service_autostarted(service): # Check OpenRC service enablement return os.path.exists(os.path.join(AUTOSTART_SVC_DIR, lxcize(service))) 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', lxcize(service)])