hosting/clore_hosting/docker_configurator.py

147 lines
7.5 KiB
Python

from lib import config as config_module
from lib import docker_interface
from lib import custom_entrypoint
from lib import networking
from lib import wireguard
from lib import logging as logging_lib
from clore_hosting import utils as hosting_utils
import shutil
import os
import re
log = logging_lib.log
config = config_module.config
default_network_names=[]
for default_network in config.clore_default_networks:
if "name" in default_network:
default_network_names.append(default_network["name"])
def get_last_ip_occurrence_and_text(input_string):
# Find all occurrences of "--ip" in the string
matches = re.finditer(r'--ip', input_string)
last_occurrence = None
for match in matches:
last_occurrence = match
if last_occurrence:
# Get the text after the last occurrence of "--ip"
text_after_last_ip = input_string[last_occurrence.end():]
return last_occurrence.group(), text_after_last_ip
else:
return None, None
def configure(containers):
valid_containers = []
newly_created_networks = []
containers_required_networks = []
docker_networks = docker_interface.get_docker_networks()
docker_containers = docker_interface.get_containers(all=True)
current_startup_files = os.listdir(config.startup_scripts_folder)
current_wireguard_configs = os.listdir(config.wireguard_config_folder)
used_startup_files=[]
used_wireguard_configs=[]
startup_sctipt_creation_fail = False
use_hive_flightsheet = False
if type(containers) == list:
custom_entrypoint_state = custom_entrypoint.cache_entrypoints(containers)
if type(custom_entrypoint_state)!=list:
return False, valid_containers, use_hive_flightsheet
for index, container in enumerate(containers):
ok_custom_entrypoint = False
invalid_hostname = False
if index < len(custom_entrypoint_state):
ok_custom_entrypoint = custom_entrypoint_state[index]
startup_script_name = f"{container['name']}.sh"
if "hostname" in container and not hosting_utils.validate_hostname(container["hostname"]):
invalid_hostname = True
if "ip" in container and len(container["ip"])>6 and type(container["ip"])==str:
if container["ip"][:8] == "; echo '":
last_occurrence, text_after_last_ip = get_last_ip_occurrence_and_text(container["ip"])
if last_occurrence:
container["ip"] = text_after_last_ip.strip().split(' ',1)[0]
else:
del container["ip"]
if "wireguard" in container and "name" in container:
wireguard.generate_config(container)
used_wireguard_configs.append(container["name"])
if "command" in container and container["command"]!='' and not startup_script_name in current_startup_files:
try:
with open(os.path.join(config.startup_scripts_folder, startup_script_name), 'w') as file:
file.write(container["command"])
except Exception as e:
startup_sctipt_creation_fail=True
elif "command" in container and container["command"]!='' and startup_script_name in current_startup_files:
used_startup_files.append(startup_script_name)
used_startup_files.append(f"{container['name']}.finished")
if "image" in container and container["image"]=="cloreai/hive-use-flightsheet":
use_hive_flightsheet=True
elif "network" in container and "network_subnet" in container and "network_gateway" in container and container["network"][:len(config.clore_network_name_prefix)]==config.clore_network_name_prefix:
if not container["network"] in containers_required_networks:
containers_required_networks.append(container["network"])
if not container["network"] in default_network_names:
is_network_created=False
any_fail = False
for docker_network in docker_networks:
if docker_network["Name"]==container["network"]:
is_network_created=True
break
if (not is_network_created) and container["network"] not in newly_created_networks:
creation_success = docker_interface.create_docker_network(container["network"], container["network_subnet"], container["network_gateway"])
if creation_success:
newly_created_networks.append(container["network"])
else:
any_fail=True
if not any_fail and ok_custom_entrypoint and not invalid_hostname:
valid_containers.append(container)
elif "network" in container and container["network"][:len(config.clore_network_name_prefix)]==config.clore_network_name_prefix: # Subnet & gateway not defined, must be some of default networks, otherwise dump it
if container["network"] in default_network_names:
for docker_network in docker_networks:
if docker_network["Name"]==container["network"]:
for ipam in docker_network["IPAM"]:
if not ok_custom_entrypoint or invalid_hostname:
break
elif not "ip" in container:
valid_containers.append(container)
break
elif networking.is_ip_in_network(container["ip"], ipam["Subnet"]):
valid_containers.append(container)
break
for docker_network in docker_networks:
if not docker_network["Name"] in containers_required_networks and not docker_network["Name"] in default_network_names:
if docker_network["Name"][:len(config.clore_network_name_prefix)]==config.clore_network_name_prefix:
docker_interface.remove_docker_network(docker_network["Name"])
for existing_wireguard_config in current_wireguard_configs:
if not existing_wireguard_config in used_wireguard_configs:
try:
directory_path = os.path.join(config.wireguard_config_folder, existing_wireguard_config)
shutil.rmtree(directory_path)
log.debug(f"DOCKER CONFIGURATOR | WIREGUARD CLEANUP | The directory {directory_path} has been removed successfully.")
except Exception as e:
log.error(f"DOCKER CONFIGURATOR | WIREGUARD CLEANUP | Error: {e}")
for remaining_file in current_startup_files:
if not remaining_file in used_startup_files:
try:
if str(remaining_file).endswith(".sh") or str(remaining_file).endswith(".finished"):
log.debug(f"REMOVIN {os.path.join(config.startup_scripts_folder, str(remaining_file))}")
os.remove(os.path.join(config.startup_scripts_folder, str(remaining_file)))
except Exception as e:
pass
if config.log_containers_strings:
print("FROM DOCKER CONFIGURATOR", valid_containers)
validation_and_security = docker_interface.validate_and_secure_networks()
if startup_sctipt_creation_fail:
validation_and_security=False
return validation_and_security, valid_containers, use_hive_flightsheet