Add initial setup scripts and configuration files for development environment
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
import os
|
||||
import uuid
|
||||
import shutil
|
||||
import json
|
||||
import socket
|
||||
import subprocess
|
||||
import petname
|
||||
import hashlib
|
||||
import platform
|
||||
from datetime import datetime
|
||||
|
||||
# Archivo JSON para guardar los datos de los contenedores
|
||||
CONTAINER_DATA_FILE = 'containers.json'
|
||||
# Nombre y etiqueta para la imagen base
|
||||
BASE_IMAGE_TAG = 'debian_vscode:tag'
|
||||
|
||||
#Lita de puertos internos
|
||||
PUERTOS_INTERNOS = [3000, 5000, 8000, 8080, 17000]
|
||||
|
||||
# Numero de conteineres a crear
|
||||
NUM_CONTAINERS = 1
|
||||
|
||||
|
||||
|
||||
# -------------------------------
|
||||
# Función: Comprobar si un puerto está libre con nmap
|
||||
# -------------------------------
|
||||
def is_port_available(port):
|
||||
# Ejecuta nmap para comprobar si el puerto está abierto
|
||||
command = f"nmap -p {port} 127.0.0.1"
|
||||
print(f"[INFO] Ejecutando nmap para el puerto {port}...")
|
||||
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||
|
||||
# Muestra el resultado del comando nmap
|
||||
print(f"[DEBUG] Resultado de nmap para el puerto {port}:\n{result.stdout}")
|
||||
|
||||
# Analiza el resultado para ver si el puerto está cerrado
|
||||
if "closed" in result.stdout:
|
||||
return True # Puerto libre
|
||||
else:
|
||||
return False # Puerto ocupado
|
||||
|
||||
|
||||
|
||||
# -------------------------------
|
||||
# Función: Ejecutar contenedor y guardar datos
|
||||
# -------------------------------
|
||||
def run_docker_compose(internal_ports=None):
|
||||
# Genera un UUID único
|
||||
unique_uuid = str(uuid.uuid4())
|
||||
# Genera un nombre único para el contenedor
|
||||
uuid_palabras = petname.Generate(3, separator='-')
|
||||
|
||||
|
||||
# Nombres únicos para el servicio, contenedor y la red
|
||||
service_name = f"{uuid_palabras}"
|
||||
container_name = f"{uuid_palabras}"
|
||||
network_name = f"alpine_network_{unique_uuid}"
|
||||
|
||||
# Nombre de la imagen local a usar
|
||||
image_tag = BASE_IMAGE_TAG # Usar la imagen local directamente
|
||||
|
||||
# Nombre del archivo docker-compose nuevo
|
||||
new_docker_compose_file = f'docker-compose-{unique_uuid}.yml'
|
||||
|
||||
try:
|
||||
# Configuración personalizada de puertos
|
||||
ports_mapping = []
|
||||
custom_ports = []
|
||||
host_port = 27000 # Puerto inicial
|
||||
print(f"[INFO] Iniciando la configuración de puertos a partir del puerto {host_port}")
|
||||
|
||||
if internal_ports:
|
||||
for internal_port in internal_ports:
|
||||
print(f"[INFO] Configurando puerto interno: {internal_port}")
|
||||
|
||||
# Buscar el siguiente puerto disponible usando nmap
|
||||
while host_port <= 65000:
|
||||
if is_port_available(host_port):
|
||||
print(f"[INFO] Asignando puerto {host_port} para el puerto interno {internal_port}...")
|
||||
custom_ports.append(f" - \"{host_port}:{internal_port}\"")
|
||||
ports_mapping.append({
|
||||
"host_port": host_port,
|
||||
"internal_port": internal_port
|
||||
})
|
||||
host_port += 1 # Incrementa el puerto para el siguiente uso
|
||||
break
|
||||
else:
|
||||
print(f"[WARNING] Puerto {host_port} ocupado, probando el siguiente...")
|
||||
host_port += 1 # Incrementa si el puerto está ocupado
|
||||
|
||||
if host_port > 65000:
|
||||
raise Exception("Se superó el límite de puertos disponibles.")
|
||||
|
||||
custom_ports_yaml = "\n".join(custom_ports)
|
||||
print(f"[INFO] Puertos personalizados configurados:\n{custom_ports_yaml}")
|
||||
else:
|
||||
custom_ports_yaml = "" # No agrega puertos si no se especifican
|
||||
print("[INFO] No se especificaron puertos internos.")
|
||||
|
||||
# Genera el contenido del archivo docker-compose dinámicamente
|
||||
docker_compose_content = f"""
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
{service_name}:
|
||||
image: {image_tag} # Usar la imagen base directamente
|
||||
container_name: {container_name}
|
||||
networks:
|
||||
- {network_name}
|
||||
restart: always
|
||||
tty: true
|
||||
volumes:
|
||||
- ./app:/app
|
||||
ports:
|
||||
{custom_ports_yaml}
|
||||
command: tail -f /dev/null # Mantener activo el contenedor
|
||||
|
||||
networks:
|
||||
{network_name}:
|
||||
driver: bridge
|
||||
"""
|
||||
|
||||
# Guarda el archivo docker-compose generado
|
||||
with open(new_docker_compose_file, 'w') as file:
|
||||
file.write(docker_compose_content)
|
||||
|
||||
# Muestra el contenido generado para depuración
|
||||
print(f"[DEBUG] Contenido del archivo {new_docker_compose_file}:\n")
|
||||
print(docker_compose_content)
|
||||
|
||||
# Ejecuta docker-compose con el archivo nuevo y captura la salida
|
||||
print("[INFO] Ejecutando docker compose...")
|
||||
result = subprocess.run(
|
||||
f'docker compose -f {new_docker_compose_file} up -d --no-build',
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
# Muestra el resultado del comando
|
||||
if result.returncode != 0:
|
||||
print(f"[ERROR] Error al ejecutar docker compose:\n{result.stderr}")
|
||||
raise Exception("Error al ejecutar docker-compose")
|
||||
else:
|
||||
print(f"[INFO] Contenedor iniciado exitosamente:\n{result.stdout}")
|
||||
|
||||
# Mostrar contenedores activos y detenidos
|
||||
print("[DEBUG] Contenedores activos y detenidos:")
|
||||
subprocess.run("docker ps -a", shell=True)
|
||||
|
||||
# Obtener el ID del contenedor creado
|
||||
container_id = subprocess.getoutput(f"docker ps -qf name={container_name}")
|
||||
if not container_id:
|
||||
print(f"[ERROR] No se pudo obtener el ID del contenedor {container_name}.")
|
||||
raise Exception("No se pudo obtener el ID del contenedor")
|
||||
|
||||
print(f"[INFO] ID del contenedor: {container_id}")
|
||||
|
||||
# Mostrar logs del contenedor si está detenido
|
||||
print("[INFO] Mostrando logs del contenedor:")
|
||||
subprocess.run(f"docker logs {container_id}", shell=True)
|
||||
|
||||
# Guardar los datos del contenedor en el archivo JSON
|
||||
save_container_data({
|
||||
'id': container_id,
|
||||
'name': container_name,
|
||||
'network': network_name,
|
||||
'image': image_tag,
|
||||
'compose_file': new_docker_compose_file,
|
||||
'creation_timestamp': datetime.now().isoformat(),
|
||||
'ports': ports_mapping # Agrega la información de los puertos mapeados
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Error: {str(e)}")
|
||||
|
||||
finally:
|
||||
# Eliminar el archivo docker-compose generado si existe
|
||||
if os.path.exists(new_docker_compose_file):
|
||||
print(f"[INFO] Eliminando archivo temporal: {new_docker_compose_file}")
|
||||
os.remove(new_docker_compose_file)
|
||||
|
||||
|
||||
|
||||
# -------------------------------
|
||||
# Función: Guardar datos del contenedor en JSON
|
||||
# -------------------------------
|
||||
def save_container_data(container_data):
|
||||
# Cargar datos existentes si el archivo existe y no está vacío
|
||||
if os.path.exists(CONTAINER_DATA_FILE) and os.path.getsize(CONTAINER_DATA_FILE) > 0:
|
||||
with open(CONTAINER_DATA_FILE, 'r') as file:
|
||||
try:
|
||||
data = json.load(file) # Cargar datos existentes
|
||||
except json.JSONDecodeError:
|
||||
data = [] # Si hay error al leer, inicializar como lista vacía
|
||||
else:
|
||||
# Crear el archivo vacío y usar una lista vacía
|
||||
with open(CONTAINER_DATA_FILE, 'w') as file:
|
||||
json.dump([], file)
|
||||
data = [] # Inicializar como lista vacía
|
||||
|
||||
# Agregar nuevo contenedor
|
||||
data.append(container_data)
|
||||
|
||||
# Guardar datos actualizados
|
||||
with open(CONTAINER_DATA_FILE, 'w') as file:
|
||||
json.dump(data, file, indent=4)
|
||||
|
||||
|
||||
|
||||
# -------------------------------
|
||||
# Función: Limpiar imágenes huérfanas
|
||||
# -------------------------------
|
||||
def clean_unused_images():
|
||||
print("➤ Eliminando imágenes huérfanas...")
|
||||
os.system('docker image prune -f')
|
||||
|
||||
# -------------------------------
|
||||
# Función: Limpiar redes huérfanas
|
||||
# -------------------------------
|
||||
def clean_unused_networks():
|
||||
print("➤ Eliminando redes huérfanas...")
|
||||
os.system('docker network prune -f')
|
||||
|
||||
|
||||
######################################### -------------------------------
|
||||
# Ejecución del script
|
||||
######################################### -------------------------------
|
||||
if __name__ == "__main__":
|
||||
|
||||
|
||||
# Crear contenedores y guardarlos en el JSON
|
||||
for _ in range(NUM_CONTAINERS):
|
||||
run_docker_compose(internal_ports=PUERTOS_INTERNOS)
|
||||
print("➤ Contenedores creados y guardados en el JSON")
|
||||
|
||||
# Limpiar imágenes huérfanas
|
||||
clean_unused_images()
|
||||
# Limpiar redes huérfanas
|
||||
clean_unused_networks()
|
||||
Reference in New Issue
Block a user