Commit 877c42f5 authored by Dobli's avatar Dobli
Browse files

Additional services by default are placed on paths

parent bda93352
#!/usr/bin/env python3 #!/usr/bin/env python3
import bcrypt """ Python module to assist creating and maintaining docker openHab stacks."""
import crypt import crypt
import docker
import logging import logging
import os import os
# import yaml
from shutil import copy2 from shutil import copy2
from subprocess import run, PIPE from subprocess import PIPE, run
import bcrypt
import docker
from PyInquirer import prompt from PyInquirer import prompt
from ruamel.yaml import YAML from ruamel.yaml import YAML
...@@ -85,25 +85,16 @@ def add_sftp_service(base_dir, hostname, number=0): ...@@ -85,25 +85,16 @@ def add_sftp_service(base_dir, hostname, number=0):
base_path = base_dir + '/' + CUSTOM_DIR base_path = base_dir + '/' + CUSTOM_DIR
# compose file # compose file
compose_path = base_path + '/' + COMPOSE_NAME compose_path = base_path + '/' + COMPOSE_NAME
# template
template = get_service_template(base_dir, SERVICES['sftp'])
# service name # service name
service_name = f'sftp_{hostname}' service_name = f'sftp_{hostname}'
# template
template = get_service_template(base_dir, SERVICES['sftp'])
# only label contraint is building
template['deploy']['placement']['constraints'][0] = (
f"{CONSTRAINTS['building']} == {hostname}")
template['ports'] = [f'{2222 + number}:22']
with open(compose_path, 'r+') as compose_f: add_or_update_compose_service(compose_path, service_name, template)
# load compose file
compose = yaml.load(compose_f)
# only label contraint is building
template['deploy']['placement']['constraints'][0] = (
f"{CONSTRAINTS['building']} == {hostname}")
template['ports'] = [f'{2222 + number}:22']
compose['services'][service_name] = template
# write content starting from first line
compose_f.seek(0)
# write new compose content
yaml.dump(compose, compose_f)
# reduce file to new size
compose_f.truncate()
def add_openhab_service(base_dir, hostname): def add_openhab_service(base_dir, hostname):
...@@ -115,38 +106,27 @@ def add_openhab_service(base_dir, hostname): ...@@ -115,38 +106,27 @@ def add_openhab_service(base_dir, hostname):
base_path = base_dir + '/' + CUSTOM_DIR base_path = base_dir + '/' + CUSTOM_DIR
# compose file # compose file
compose_path = base_path + '/' + COMPOSE_NAME compose_path = base_path + '/' + COMPOSE_NAME
# template
template = get_service_template(base_dir, SERVICES['openhab'])
# service name # service name
service_name = f'openhab_{hostname}' service_name = f'openhab_{hostname}'
# template
with open(compose_path, 'r+') as compose_f: template = get_service_template(base_dir, SERVICES['openhab'])
# load compose file # only label contraint is building
compose = yaml.load(compose_f) template['deploy']['placement']['constraints'][0] = (
# only label contraint is building f"{CONSTRAINTS['building']} == {hostname}")
template['deploy']['placement']['constraints'][0] = ( # include in backups of this building
f"{CONSTRAINTS['building']} == {hostname}") template['deploy']['labels'].append(f'backup={hostname}')
# include in backups of this building # traefik backend
template['deploy']['labels'].append(f'backup={hostname}') template['deploy']['labels'].append(f'traefik.backend={service_name}')
# traefik backend # traefik frontend domain->openhab
template['deploy']['labels'].append(f'traefik.backend={service_name}') template['deploy']['labels'].extend(
# traefik frontend domain->openhab generate_traefik_host_labels(hostname, segment='main'))
template['deploy']['labels'].append( # traefik frontend subdomain openhab_hostname.* -> openhab
f'traefik.main.frontend.rule=HostRegexp:{{domain:{hostname}}}') template['deploy']['labels'].append(
template['deploy']['labels'].append('traefik.main.frontend.priority=1') f'traefik.sub.frontend.rule=HostRegexp:'
# traefik frontend subdomain openhab_hostname.* -> openhab f'{service_name}.{{domain:[a-zA-z0-9-]+}}')
template['deploy']['labels'].append( template['deploy']['labels'].append('traefik.sub.frontend.priority=2')
f'traefik.sub.frontend.rule=HostRegexp:'
f'{service_name}.{{domain:[a-zA-z0-9-]+}}') add_or_update_compose_service(compose_path, service_name, template)
template['deploy']['labels'].append('traefik.sub.frontend.priority=2')
compose['services'][service_name] = template
# write content starting from first line
compose_f.seek(0)
# write new compose content
yaml.dump(compose, compose_f)
# reduce file to new size
compose_f.truncate()
def add_nodered_service(base_dir, hostname): def add_nodered_service(base_dir, hostname):
...@@ -158,30 +138,19 @@ def add_nodered_service(base_dir, hostname): ...@@ -158,30 +138,19 @@ def add_nodered_service(base_dir, hostname):
base_path = base_dir + '/' + CUSTOM_DIR base_path = base_dir + '/' + CUSTOM_DIR
# compose file # compose file
compose_path = base_path + '/' + COMPOSE_NAME compose_path = base_path + '/' + COMPOSE_NAME
# template
template = get_service_template(base_dir, SERVICES['nodered'])
# service name # service name
service_name = f'nodered_{hostname}' service_name = f'nodered_{hostname}'
# template
template = get_service_template(base_dir, SERVICES['nodered'])
# only label contraint is building
template['deploy']['placement']['constraints'][0] = (
f"{CONSTRAINTS['building']} == {hostname}")
template['deploy']['labels'].append(f'traefik.backend={service_name}')
template['deploy']['labels'].append(f'backup={hostname}')
template['deploy']['labels'].extend(
generate_traefik_path_labels(service_name, segment='main'))
with open(compose_path, 'r+') as compose_f: add_or_update_compose_service(compose_path, service_name, template)
# load compose file
compose = yaml.load(compose_f)
# only label contraint is building
template['deploy']['placement']['constraints'][0] = (
f"{CONSTRAINTS['building']} == {hostname}")
template['deploy']['labels'].append(f'traefik.backend={service_name}')
template['deploy']['labels'].append(f'backup={hostname}')
template['deploy']['labels'].append(
f'traefik.frontend.rule=HostRegexp:'
f'{service_name}.{{domain:[a-zA-z0-9-]+}}')
template['deploy']['labels'].append('traefik.frontend.priority=2')
compose['services'][service_name] = template
# write content starting from first line
compose_f.seek(0)
# write new compose content
yaml.dump(compose, compose_f)
# reduce file to new size
compose_f.truncate()
def add_mqtt_service(base_dir, hostname, number=0): def add_mqtt_service(base_dir, hostname, number=0):
...@@ -194,29 +163,20 @@ def add_mqtt_service(base_dir, hostname, number=0): ...@@ -194,29 +163,20 @@ def add_mqtt_service(base_dir, hostname, number=0):
base_path = base_dir + '/' + CUSTOM_DIR base_path = base_dir + '/' + CUSTOM_DIR
# compose file # compose file
compose_path = base_path + '/' + COMPOSE_NAME compose_path = base_path + '/' + COMPOSE_NAME
# template
template = get_service_template(base_dir, SERVICES['mqtt'])
# service name # service name
service_name = f'mqtt_{hostname}' service_name = f'mqtt_{hostname}'
# template
template = get_service_template(base_dir, SERVICES['mqtt'])
# only label contraint is building
template['deploy']['placement']['constraints'][0] = (
f"{CONSTRAINTS['building']} == {hostname}")
# ports incremented by number of services
template['ports'] = [f'{1883 + number}:1883', f'{9001 + number}:9001']
with open(compose_path, 'r+') as compose_f: add_or_update_compose_service(compose_path, service_name, template)
# load compose file
compose = yaml.load(compose_f)
# only label contraint is building
template['deploy']['placement']['constraints'][0] = (
f"{CONSTRAINTS['building']} == {hostname}")
# ports incremented by number of services
template['ports'] = [f'{1883 + number}:1883', f'{9001 + number}:9001']
# write template as service
compose['services'][service_name] = template
# write content starting from first line
compose_f.seek(0)
# write new compose content
yaml.dump(compose, compose_f)
# reduce file to new size
compose_f.truncate()
# Helper functions
def get_service_template(base_dir, service_name): def get_service_template(base_dir, service_name):
"""Gets a service template entry from the template yaml """Gets a service template entry from the template yaml
...@@ -229,6 +189,67 @@ def get_service_template(base_dir, service_name): ...@@ -229,6 +189,67 @@ def get_service_template(base_dir, service_name):
template_content = yaml.load(templates_file) template_content = yaml.load(templates_file)
return template_content['services'][service_name] return template_content['services'][service_name]
def generate_traefik_host_labels(hostname, segment=None, priority=1):
"""Generates a traefik path url with necessary redirects
:hostname: Hostname that gets assigned by the label
:segment: Optional traefik segment when using multiple rules
:priority: Priority of frontend rule
:returns: list of labels for traefik
"""
label_list = []
# check segment
segment = f'.{segment}' if segment is not None else ''
# fill list
label_list.append(
f'traefik{segment}.frontend.rule=HostRegexp:{{domain:{hostname}}}')
label_list.append(f'traefik{segment}.frontend.priority={priority}')
return label_list
def generate_traefik_path_labels(url_path, segment=None, priority=2):
"""Generates a traefik path url with necessary redirects
:url_path: path that should be used for the site
:segment: Optional traefik segment when using multiple rules
:priority: Priority of frontend rule
:returns: list of labels for traefik
"""
label_list = []
# check segment
segment = f'.{segment}' if segment is not None else ''
# fill list
label_list.append(f'traefik{segment}.frontend.priority={priority}')
label_list.append(
f'traefik{segment}.frontend.redirect.regex=^(.*)/{url_path}$$')
label_list.append(
f'traefik{segment}.frontend.redirect.replacement=$$1/{url_path}/')
label_list.append(
f'traefik{segment}.frontend.rule=PathPrefix:/{url_path};'
f'ReplacePathRegex:^/{url_path}/(.*) /$$1')
return label_list
def add_or_update_compose_service(compose_path, service_name, service_content):
"""Adds or replaces a service in a compose file
:compose_path: path of the compose file to change
:service_name: name of the service to add/replace
:service_content: service definition to add
"""
with open(compose_path, 'r+') as compose_f:
# load compose file
compose = yaml.load(compose_f)
# add / update service with template
compose['services'][service_name] = service_content
# write content starting from first line
compose_f.seek(0)
# write new compose content
yaml.dump(compose, compose_f)
# reduce file to new size
compose_f.truncate()
# }}} # }}}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment