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