2019-09-24 09:59:45 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
|
|
|
|
from .paths import AUTOSTART_SVC_DIR, SERVICE_DIR, STARTED_SVC_DIR
|
|
|
|
from .templates import SERVICE
|
|
|
|
|
2019-11-30 22:10:26 +01:00
|
|
|
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)
|
|
|
|
|
2019-09-24 19:45:25 +02:00
|
|
|
def create_service(container, image):
|
2019-11-30 22:10:26 +01:00
|
|
|
depends = ' '.join([lxcize(service) for service in image['depends']]) if 'depends' in image else ''
|
2019-09-24 19:14:16 +02:00
|
|
|
# Add ready check to start_post
|
2019-11-30 22:10:26 +01:00
|
|
|
# This could arguably be done better via some template engine, but introducing one for a single template file seems like an overkill
|
2019-09-24 19:14:16 +02:00
|
|
|
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 ''
|
2019-11-30 22:10:26 +01:00
|
|
|
service_file = os.path.join(SERVICE_DIR, lxcize(container))
|
2019-09-24 19:14:16 +02:00
|
|
|
with open(service_file, 'w') as f:
|
2019-09-24 19:45:25 +02:00
|
|
|
f.write(SERVICE.format(container=container, depends=depends, start_post=start_post))
|
2019-09-24 19:14:16 +02:00
|
|
|
os.chmod(service_file, 0o755)
|
2019-09-24 09:59:45 +02:00
|
|
|
update_services()
|
|
|
|
|
|
|
|
def delete_service(service):
|
|
|
|
if is_service_started(service):
|
|
|
|
stop_service(service)
|
|
|
|
if is_service_autostarted(service):
|
|
|
|
update_service_autostart(service, False)
|
|
|
|
try:
|
2019-11-30 22:10:26 +01:00
|
|
|
os.unlink(os.path.join(SERVICE_DIR, lxcize(service)))
|
2019-09-24 19:45:25 +02:00
|
|
|
update_services()
|
2019-09-24 09:59:45 +02:00
|
|
|
except FileNotFoundError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
def update_services():
|
|
|
|
subprocess.run(['/sbin/rc-update', '-u'], check=True)
|
|
|
|
|
|
|
|
def start_service(service):
|
|
|
|
if not is_service_started(service):
|
2019-11-30 22:10:26 +01:00
|
|
|
subprocess.run(['/sbin/service', lxcize(service), 'start'], check=True)
|
2019-09-24 09:59:45 +02:00
|
|
|
|
|
|
|
def stop_service(service):
|
|
|
|
if is_service_started(service):
|
2019-11-30 22:10:26 +01:00
|
|
|
subprocess.run(['/sbin/service', lxcize(service), 'stop'], check=True)
|
2019-09-24 09:59:45 +02:00
|
|
|
|
2019-09-24 19:45:25 +02:00
|
|
|
def is_service_started(service):
|
2019-09-24 09:59:45 +02:00
|
|
|
# Check OpenRC service status without calling any binary
|
2019-11-30 22:10:26 +01:00
|
|
|
return os.path.exists(os.path.join(STARTED_SVC_DIR, lxcize(service)))
|
2019-09-24 09:59:45 +02:00
|
|
|
|
2019-09-24 19:45:25 +02:00
|
|
|
def is_service_autostarted(service):
|
2019-09-24 09:59:45 +02:00
|
|
|
# Check OpenRC service enablement
|
2019-11-30 22:10:26 +01:00
|
|
|
return os.path.exists(os.path.join(AUTOSTART_SVC_DIR, lxcize(service)))
|
2019-09-24 09:59:45 +02:00
|
|
|
|
2019-09-24 19:45:25 +02:00
|
|
|
def update_service_autostart(service, enabled):
|
|
|
|
# Add/remove the service to/from OpenRC default runlevel
|
2019-11-30 22:10:26 +01:00
|
|
|
subprocess.run(['/sbin/rc-update', 'add' if enabled else 'del', lxcize(service)])
|