1136 lines
46 KiB
Python
1136 lines
46 KiB
Python
#!/usr/bin/env python3
|
|
|
|
#################################################################################
|
|
##### ogBoot installer script ########
|
|
##### Autor: Antonio Emmanuel Guerrero Silva <aguerrero@qindel.com> ########
|
|
#################################################################################
|
|
|
|
import platform, os, sys, subprocess, datetime, shutil, pwd, glob, zipfile, urllib.request, logging, distro, re
|
|
|
|
# Reload variables from bashrc
|
|
# subprocess.run(['source', '~/.bashrc'], shell=True)
|
|
|
|
# Leer variables de entorno
|
|
#env_ogCore_ServerIP = os.getenv('OGCORE_SERVER_IP') #"172.17.8.82"
|
|
#env_ogCore_Server = os.getenv('OGCORE_SERVER') #"opengnsys.es"
|
|
#env_ogCore_Dir = os.getenv('OGCORE_DIR') #{INSTALL_OPENGNSYS_TARGET}
|
|
#env_ogBoot_Dir = os.getenv('OGBOOT_DIR') #{INSTALL_OGBOOT_TARGET}
|
|
#env_ogBoot_GitRepo = os.getenv('OGBOOT_GIT_REPO') #"ssh://git@ognproject.evlt.uma.es:21987/opengnsys/ogboot.git"
|
|
|
|
# Constantes, ambiente de desarrollo
|
|
env_ogCore_ServerIP = "172.17.8.82"
|
|
env_ogCore_Server = "opengnsys.es"
|
|
env_ogCore_Dir = "/opt/opengnsys"
|
|
env_ogBoot_Dir = "/opt/ogboot"
|
|
env_ogBoot_GitRepo = "ssh://git@ognproject.evlt.uma.es:21987/opengnsys/ogboot.git"
|
|
|
|
PROGRAM = os.path.splitext(os.path.basename(sys.argv[0]))[0]
|
|
PROGRAM_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))
|
|
PROGRAM_NAME = os.path.basename(sys.argv[0])
|
|
|
|
OGCORE_IP = f"{env_ogCore_ServerIP}"
|
|
OGCORE_SERVER = f"{env_ogCore_Server}"
|
|
INSTALL_TARGET = f"{env_ogBoot_Dir}"
|
|
INSTALL_OPENGNSYS_TARGET = f"{env_ogCore_Dir}"
|
|
INSTALL_OGBOOT_TARGET = f"{env_ogBoot_Dir}"
|
|
GIT_REPO = f"{env_ogBoot_GitRepo}"
|
|
|
|
OSDISTRIB = ""
|
|
OSVERSION = ""
|
|
IPXE_DIR = "/tmp/ipxe"
|
|
WORKDIR ="/tmp/ogboot_installer"
|
|
TFTPSERV = "tftpd-hpa"
|
|
SAMBASERV = "smbd"
|
|
SAMBACFGDIR = "/etc/samba"
|
|
TFTPCFGDIR = "/var/lib/tftpboot"
|
|
INETDCFGDIR = "/etc/xinetd.d/"
|
|
|
|
DEFAULTDEV = ""
|
|
PACKAGES_TO_INSTALL = ["htop"]
|
|
DEVICE = []
|
|
SERVERIP = []
|
|
NETIP = []
|
|
NETMASK = []
|
|
NETBROAD = []
|
|
ROUTERIP = []
|
|
BRANCH = sys.argv[1] if len(sys.argv) > 1 else "main"
|
|
INETDSERV = "xinetd"
|
|
OPENGNSYS_CLIENT_PASSWD="og"
|
|
OPENGNSYS_CLIENT_USER="opengnsys"
|
|
|
|
UBUNTU_OS_VERSION = "22"
|
|
PYTHON_VERSION = 3
|
|
|
|
if os.path.isdir(f"{PROGRAM_DIR}/../installer"):
|
|
REMOTE = 0
|
|
else:
|
|
REMOTE = 1
|
|
|
|
# Create log file with sudo and set owner to ogboot
|
|
log_file = f'/var/log/{PROGRAM}.log'
|
|
os.makedirs(os.path.dirname(log_file), exist_ok=True)
|
|
subprocess.run(['sudo', 'touch', log_file])
|
|
#subprocess.run(['sudo', 'chown', 'ogboot', log_file])
|
|
subprocess.run(['sudo', 'chmod', '777', log_file])
|
|
|
|
#Configurar el registro
|
|
logging.basicConfig(level=logging.DEBUG,
|
|
format='%(asctime)s %(levelname)s\t%(message)s',
|
|
filename=f'/var/log/{PROGRAM}.log',
|
|
filemode='a')
|
|
logger = logging.getLogger()
|
|
console_handler = logging.StreamHandler()
|
|
console_handler.setLevel(logging.DEBUG)
|
|
formatter = logging.Formatter('%(levelname)s\t%(message)s')
|
|
console_handler.setFormatter(formatter)
|
|
logger.addHandler(console_handler)
|
|
|
|
###############################################################################
|
|
###::::::::::::::::::::::::::::::: UTILS :::::::::::::::::::::::::::::::::::###
|
|
###############################################################################
|
|
def check_python_version():
|
|
try:
|
|
python_version = platform.python_version()
|
|
python_version_tuple = tuple(map(int, python_version.split('.')))
|
|
if python_version_tuple >= (PYTHON_VERSION, 0):
|
|
logger.info(f"Python version installed: {python_version}")
|
|
else:
|
|
logger.error(f"Python version is lower than required. Installed version: {python_version}" + ".")
|
|
exit()
|
|
except Exception as e:
|
|
logger.error(f"Problem verifying Python version: {e}")
|
|
exit()
|
|
|
|
def check_distribution():
|
|
if os.path.exists("/etc/os-release"):
|
|
with open("/etc/os-release", "r") as file:
|
|
for line in file:
|
|
if line.startswith("VERSION"):
|
|
VERSION = line.split("=")[1].strip().strip('"')
|
|
break
|
|
if VERSION.startswith(UBUNTU_OS_VERSION + "."):
|
|
return
|
|
logger.info(f"The ogBoot installation has been tested with full functionality on Ubuntu. {UBUNTU_OS_VERSION}")
|
|
go_on = input("Would you like to continue? [s/N]: ")
|
|
if go_on.upper() != "S":
|
|
logger.error("Leaving the installation.")
|
|
exit()
|
|
|
|
def cidr2mask(cidr):
|
|
args = [5 - (cidr // 8), 255, 255, 255, 255, (255 << (8 - (cidr % 8))) & 255, 0, 0, 0]
|
|
if args[0] > 1:
|
|
args = args[args[0]:]
|
|
else:
|
|
args = args[1:]
|
|
return f"{args[0]}.{args[1]}.{args[2]}.{args[3]}"
|
|
|
|
def downloadCode(url):
|
|
if len(url) != 1:
|
|
logger.error("Invalid number of parameters")
|
|
exit(1)
|
|
subprocess.run(["GIT_SSH_COMMAND=ssh -o StrictHostKeyChecking=accept-new git archive --remote=" + url + " --format zip --output opengnsys.zip --prefix=opengnsys/ " + BRANCH + " && unzip opengnsys.zip"], shell=True)
|
|
if subprocess.returncode != 0:
|
|
logger.error("Error getting OpenGnsys code from " + url)
|
|
return 1
|
|
subprocess.run(["rm -f opengnsys.zip"], shell=True)
|
|
logger.info("downloadCode(): code was downloaded")
|
|
return 0
|
|
|
|
###############################################################################
|
|
###:::::::::::::::::::::::::::::: INSTALL ::::::::::::::::::::::::::::::::::###
|
|
###############################################################################
|
|
|
|
def is_installed(package):
|
|
try:
|
|
subprocess.run(["dpkg", "-s", package], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
return True
|
|
except subprocess.CalledProcessError:
|
|
return False
|
|
|
|
def get_missing_packages():
|
|
global PACKAGES_TO_INSTALL
|
|
faltantes = []
|
|
OSDISTRIB = distro.name()
|
|
OSVERSION = distro.version()
|
|
logger.info(f"OSDISTRIB: {OSDISTRIB}")
|
|
logger.info(f"OSVERSION: {OSVERSION}")
|
|
match OSDISTRIB.lower():
|
|
case "ubuntu":
|
|
match OSVERSION:
|
|
case "20.04":
|
|
PACKAGES_TO_INSTALL = ["vim", "curl", "htop"]
|
|
case "18.04":
|
|
PACKAGES_TO_INSTALL = ["nano", "wget", "tree"]
|
|
case "22.04":
|
|
PACKAGES_TO_INSTALL = ["nfs-common", "xorriso", "genisoimage", "syslinux", "liblzma-dev", "nginx", "arp-scan", "automake", "build-essential", "btrfs-progs", "composer", "curl", "ctorrent", "debootstrap", "g++-multilib", "gawk", "gettext", "graphviz", "grub-efi-amd64-signed", "jq", "libapache2-mod-php", "libdbi-dev", "libdbi1", "libev-dev", "libjansson-dev", "liblz4-tool", "libssl-dev", "moreutils", "netpipes", "php", "php-bcmath", "php-cli", "php-curl", "php-fpm", "php-gd", "php-json", "php-ldap", "php-mbstring", "php-mysql", "php8.1-common", "php-pear", "php-xml", "php-zip", "procps", "coreutils", "rsync", "samba", "schroot", "shim-signed", "squashfs-tools", "subversion", "tftpd-hpa", "udpcast", "unzip", "wakeonlan", "wget", "xinetd", "jq", "moreutils", "net-tools", "isolinux", "syslinux"]
|
|
case _:
|
|
PACKAGES_TO_INSTALL = ["bash", "nc", "rsync"]
|
|
case "suse":
|
|
match OSVERSION:
|
|
case "15":
|
|
PACKAGES_TO_INSTALL = ["zypper", "mc", "gcc"]
|
|
case "12":
|
|
PACKAGES_TO_INSTALL = ["perl", "tar", "man"]
|
|
case _:
|
|
PACKAGES_TO_INSTALL = ["openssl", "ncurses", "zip"]
|
|
case "redhat":
|
|
match OSVERSION:
|
|
case "8":
|
|
PACKAGES_TO_INSTALL = ["yum", "tar", "perl"]
|
|
case "7":
|
|
PACKAGES_TO_INSTALL = ["bash", "rpm", "tcpdump"]
|
|
case _:
|
|
PACKAGES_TO_INSTALL = ["grep", "sed", "awk"]
|
|
case _:
|
|
logger.error("Distribution not supported by ogBoot.")
|
|
exit(1)
|
|
|
|
for package in PACKAGES_TO_INSTALL:
|
|
if not is_installed(package):
|
|
faltantes.append(package)
|
|
logger.info(f"::::::Package to install: {package}...")
|
|
return faltantes
|
|
|
|
def install_packages(missing, log_packages_file=f"/tmp/installed_packages.log"):
|
|
if not missing:
|
|
logger.warning("All packages are already installed.")
|
|
return
|
|
logger.info("Upgrading the system...")
|
|
original_debian_frontend = os.environ.get('DEBIAN_FRONTEND')
|
|
try:
|
|
os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
|
|
subprocess.run(["sudo", "apt-get", "update"], check=True)
|
|
with open(log_packages_file, "a") as log:
|
|
for package in missing:
|
|
subprocess.run(["sudo", "apt-get", "install", "--allow-change-held-packages", "-y", package], check=True)
|
|
logger.info(f"{package} installed correctly.")
|
|
log.write(package + "\n")
|
|
logger.info("All missing packages have been installed.")
|
|
finally:
|
|
# Restaurar el valor original de DEBIAN_FRONTEND
|
|
if original_debian_frontend is not None:
|
|
os.environ['DEBIAN_FRONTEND'] = original_debian_frontend
|
|
else:
|
|
del os.environ['DEBIAN_FRONTEND']
|
|
|
|
def autoConfigure():
|
|
global OSDISTRIB, OSVERSION
|
|
#distribution = platform.linux_distribution()
|
|
#distribution = distro.linux_distribution()
|
|
#OSDISTRIB = distribution[0]
|
|
OSDISTRIB = distro.name()
|
|
OSVERSION = distro.version()
|
|
#OSVERSION = distribution[1]
|
|
logger.info(f"OSDISTRIB: {OSDISTRIB}")
|
|
logger.info(f"OSVERSION: {OSVERSION}")
|
|
# Configuración según la distribución OSDISTRIB
|
|
|
|
def generate_config_url():
|
|
with open('/etc/os-release', 'r') as file:
|
|
lines = file.readlines()
|
|
codename = None
|
|
version = None
|
|
for line in lines:
|
|
if line.startswith('VERSION_CODENAME') or line.startswith('UBUNTU_CODENAME'):
|
|
codename = line.split('=')[1].strip().strip('"')
|
|
elif line.startswith('VERSION_ID'):
|
|
version = line.split('=')[1].strip().strip('"')
|
|
arch = os.uname().machine
|
|
return f"https://dl.cloudsmith.io/public/isc/kea-2-0/config.deb.txt?distro=ubuntu&codename={codename}&version={version}&arch={arch}"
|
|
|
|
def downloadComposer():
|
|
global WORKDIR, INSTALL_OGBOOT_TARGET
|
|
_______logger.info("Downloading composer.phar...")
|
|
os.makedirs(os.path.join(WORKDIR, "ogboot", "bin"), mode=0o750, exist_ok=True)
|
|
subprocess.run(["curl", "-sS", "-o", os.path.join(WORKDIR, "ogboot", "bin", "composer.phar"), "https://getcomposer.org/installer"], check=True)
|
|
if not os.path.isfile(os.path.join(WORKDIR, "ogboot", "bin", "composer.phar")):
|
|
logger.error("Failed to download composer.phar")
|
|
return 1
|
|
logger.info(f"composer.phar downloaded to {INSTALL_OGBOOT_TARGET}/bin")
|
|
return 0
|
|
|
|
def install_swagger_ui():
|
|
global INSTALL_TARGET
|
|
# Define la URL del archivo de Swagger UI que quieres descargar
|
|
swagger_ui_url = "https://github.com/swagger-api/swagger-ui/archive/refs/heads/master.zip"
|
|
# Define la ruta donde quieres descomprimir Swagger UI
|
|
swagger_ui_path = "/tmp/swagger-ui"
|
|
# Define la ruta de destino para los archivos de Swagger UI
|
|
destination_path = os.path.join(INSTALL_TARGET, "public")
|
|
# Crea los directorios si no existen
|
|
os.makedirs(swagger_ui_path, exist_ok=True)
|
|
os.makedirs(destination_path, exist_ok=True)
|
|
# Descarga el archivo de Swagger UI
|
|
urllib.request.urlretrieve(swagger_ui_url, "/tmp/swagger-ui.zip")
|
|
# Descomprime el archivo de Swagger UI en la ruta especificada
|
|
with zipfile.ZipFile("/tmp/swagger-ui.zip", "r") as zip_ref:
|
|
zip_ref.extractall(swagger_ui_path)
|
|
# Copia los archivos de Swagger UI al directorio de destino
|
|
for file_path in glob.glob(os.path.join(swagger_ui_path, "swagger-ui-master", "dist", "*")):
|
|
shutil.copy(file_path, destination_path)
|
|
# Elimina el archivo descargado y el directorio temporal
|
|
os.remove("/tmp/swagger-ui.zip")
|
|
shutil.rmtree(swagger_ui_path)
|
|
# Genera el archivo swagger.json
|
|
os.system(f"{os.path.join(INSTALL_TARGET, 'vendor', 'bin', 'openapi')} {INSTALL_TARGET}/src/OgBootBundle/Controller/ -o {destination_path}/swagger.json")
|
|
logger.info(f"Swagger UI installed on {destination_path}.")
|
|
|
|
def og_core_create_user(OPENGNSYS_CLIENT_USER):
|
|
try:
|
|
pwd.getpwnam(OPENGNSYS_CLIENT_USER)
|
|
logger.warning(f"User {OPENGNSYS_CLIENT_USER} already exists")
|
|
except KeyError:
|
|
subprocess.run(["sudo", "useradd", "-m", OPENGNSYS_CLIENT_USER])
|
|
logger.info(f"User {OPENGNSYS_CLIENT_USER} created successfully.")
|
|
|
|
def og_boot_create_dirs():
|
|
global INSTALL_OGBOOT_TARGET
|
|
if os.path.exists(INSTALL_OGBOOT_TARGET):
|
|
if not os.path.isdir(INSTALL_OGBOOT_TARGET):
|
|
raise NotADirectoryError(f"{INSTALL_OGBOOT_TARGET} exists and is not a directory.")
|
|
else:
|
|
logger.warning(f"{INSTALL_OGBOOT_TARGET} directory already exists.")
|
|
else:
|
|
try:
|
|
# Crear los directorios necesarios
|
|
os.makedirs(INSTALL_OGBOOT_TARGET, mode=0o750, exist_ok=True)
|
|
os.makedirs(os.path.join(INSTALL_OGBOOT_TARGET, "client"), mode=0o750, exist_ok=True)
|
|
os.makedirs("/opt/ogboot/tftpboot/", mode=0o750, exist_ok=True)
|
|
os.makedirs("/opt/ogboot/tftpboot/ipxe_scripts", mode=0o750, exist_ok=True)
|
|
os.makedirs("/opt/ogboot/tftpboot/ipxe_scripts/templates", mode=0o750, exist_ok=True)
|
|
|
|
# Cambiar el propietario de los directorios
|
|
subprocess.run(["sudo", "chown", "-R", "ogboot:ogboot", INSTALL_OGBOOT_TARGET])
|
|
subprocess.run(["sudo", "chown", "-R", "ogboot:ogboot", "/opt/ogboot/tftpboot/"])
|
|
|
|
logger.info(f"{INSTALL_OGBOOT_TARGET} directory created successfully.")
|
|
except OSError:
|
|
logger.error("Error while creating directory paths!")
|
|
exit(1)
|
|
|
|
def og_boot_symfony_install():
|
|
global WORKDIR, INSTALL_OGBOOT_TARGET
|
|
logger.info("Creating Symfony application skeleton...")
|
|
|
|
try:
|
|
# Copiar los archivos .env y composer.json primero
|
|
env_src = os.path.join(f"{WORKDIR}", "ogboot/.env")
|
|
composer_src = os.path.join(f"{WORKDIR}", "ogboot/composer.json")
|
|
env_dest = os.path.join(f"{INSTALL_OGBOOT_TARGET}", ".env")
|
|
composer_dest = os.path.join(f"{INSTALL_OGBOOT_TARGET}", "composer.json")
|
|
|
|
shutil.copy(env_src, env_dest)
|
|
shutil.copy(composer_src, composer_dest)
|
|
logger.info(f"Copied environment source {env_src} to {env_dest}")
|
|
logger.info(f"Copied composer source{composer_src} to {composer_dest}")
|
|
|
|
# Cambiar permisos y propietario de los archivos copiados
|
|
os.chmod(env_dest, 0o644)
|
|
os.chmod(composer_dest, 0o644)
|
|
shutil.chown(env_dest, user='ogboot', group='ogboot')
|
|
shutil.chown(composer_dest, user='ogboot', group='ogboot')
|
|
logger.info(f"Set permissions and owner for {env_dest} and {composer_dest}")
|
|
|
|
logger.info(f".env and composer.json files copied to {INSTALL_OGBOOT_TARGET}")
|
|
except Exception as e:
|
|
logger.error(f"An error occurred while copying files: {e}")
|
|
raise
|
|
|
|
def og_boot_copy_files():
|
|
global INSTALL_TARGET, WORKDIR
|
|
bin_source = os.path.join(WORKDIR, "ogboot/bin")
|
|
bin_dest = os.path.join(INSTALL_OGBOOT_TARGET, "bin")
|
|
src_source = os.path.join(WORKDIR, "ogboot/src")
|
|
src_dest = os.path.join(INSTALL_OGBOOT_TARGET, "src")
|
|
|
|
config_source = os.path.join(WORKDIR, "ogboot/config")
|
|
config_dest = os.path.join(INSTALL_OGBOOT_TARGET, "config")
|
|
|
|
lib_source = os.path.join(WORKDIR, "ogboot/lib")
|
|
lib_dest = os.path.join(INSTALL_OGBOOT_TARGET, "lib")
|
|
|
|
if os.path.exists(bin_dest):
|
|
shutil.rmtree(bin_dest)
|
|
shutil.copytree(bin_source, bin_dest)
|
|
|
|
if os.path.exists(src_dest):
|
|
shutil.rmtree(src_dest)
|
|
shutil.copytree(src_source, src_dest)
|
|
|
|
if os.path.exists(config_dest):
|
|
shutil.rmtree(config_dest)
|
|
shutil.copytree(config_source, config_dest)
|
|
|
|
if os.path.exists(lib_dest):
|
|
shutil.rmtree(lib_dest)
|
|
shutil.copytree(lib_source, lib_dest)
|
|
|
|
os.makedirs(os.path.join(INSTALL_TARGET, "etc"), mode=0o750, exist_ok=True)
|
|
os.makedirs(os.path.join(INSTALL_TARGET, "client"), mode=0o750, exist_ok=True)
|
|
os.makedirs(os.path.join(INSTALL_TARGET, "public"), mode=0o750, exist_ok=True)
|
|
|
|
subprocess.run(["sudo", "chmod", "-R", "755", INSTALL_OGBOOT_TARGET])
|
|
subprocess.run(["sudo", "chown", "-R", "ogboot:ogboot", INSTALL_OGBOOT_TARGET])
|
|
|
|
def og_boot_composer_install():
|
|
# Ejecutar Composer como el usuario 'ogboot' para instalar el proyecto Symfony
|
|
result = subprocess.run(["sudo", "-u", "ogboot", "/opt/ogboot/bin/composer.phar", "install", "--no-interaction", "--working-dir", INSTALL_OGBOOT_TARGET])
|
|
if result.returncode != 0:
|
|
logger.error("Error creating Symfony project using Composer")
|
|
return
|
|
|
|
# Eliminar composer.lock si existe
|
|
composer_lock_path = os.path.join(INSTALL_OGBOOT_TARGET, "composer.lock")
|
|
if os.path.exists(composer_lock_path):
|
|
os.remove(composer_lock_path)
|
|
|
|
install_swagger_ui() # Instalar Swagger UI
|
|
|
|
logger.info("Application skeleton created and composer.lock file removed.")
|
|
|
|
#def createDirs(INSTALL_TARGET):
|
|
# if not os.path.exists(INSTALL_TARGET):
|
|
# try:
|
|
# os.makedirs(INSTALL_TARGET)
|
|
# os.makedirs(os.path.join(INSTALL_TARGET, "client"))
|
|
# logger.info(f"{INSTALL_TARGET} directory created successfully.")
|
|
# except OSError:
|
|
# logger.error("Error while creating directory paths!")
|
|
# exit(1)
|
|
# else:
|
|
# logger.info(f"Directory {INSTALL_TARGET} already exists.")
|
|
|
|
###############################################################################
|
|
###:::::::::::::::::::::::::::: CONFIGURE ::::::::::::::::::::::::::::::::::###
|
|
###############################################################################
|
|
|
|
def install_isc_kea():
|
|
url = generate_config_url()
|
|
print(f"URL generada: {url}")
|
|
print("Ejecutando curl para obtener el archivo de configuración del repositorio KEA...")
|
|
subprocess.run(["curl", "-1sLf", url, ">", "/etc/apt/sources.list.d/isc-kea-2-0.list"], check=True)
|
|
print("El archivo de configuración del repositorio KEA ha sido guardado en /etc/apt/sources.list.d/isc-kea-2-0.list")
|
|
|
|
print("Descargando y agregando la clave GPG del repositorio KEA...")
|
|
subprocess.run(["curl", "-1sLf", "https://dl.cloudsmith.io/public/isc/kea-2-0/gpg.8029D4AFA58CBB5E.key", "|", "gpg", "--dearmor", ">>", "/usr/share/keyrings/isc-kea-2-0-archive-keyring.gpg"], check=True)
|
|
print("La clave GPG del repositorio KEA ha sido descargada y agregada correctamente")
|
|
|
|
print("Ejecutando apt-get update...")
|
|
subprocess.run(["apt-get", "update"], check=True)
|
|
|
|
print("Comprobando disponibilidad de los paquetes...")
|
|
if subprocess.run(["apt-cache", "show", "isc-kea-common"], capture_output=True).returncode == 0:
|
|
print("El paquete isc-kea-common está disponible para ser instalado.")
|
|
print("Descargando e instalando el paquete isc-kea-common...")
|
|
subprocess.run(["apt-get", "install", "-y", "isc-kea-common"], check=True)
|
|
print("El paquete isc-kea-common ha sido descargado e instalado correctamente.")
|
|
else:
|
|
print("El paquete isc-kea-common no está disponible en los repositorios apt.")
|
|
|
|
if subprocess.run(["apt-cache", "show", "isc-kea-dhcp4-server"], capture_output=True).returncode == 0:
|
|
print("El paquete isc-kea-dhcp4-server está disponible para ser instalado.")
|
|
print("Descargando e instalando el paquete isc-kea-dhcp4-server...")
|
|
subprocess.run(["apt-get", "install", "-y", "isc-kea-dhcp4-server"], check=True)
|
|
print("El paquete isc-kea-dhcp4-server ha sido descargado e instalado correctamente.")
|
|
else:
|
|
print("El paquete isc-kea-dhcp4-server no está disponible en los repositorios apt.")
|
|
|
|
if subprocess.run(["apt-cache", "show", "isc-kea-dhcp6-server"], capture_output=True).returncode == 0:
|
|
print("El paquete isc-kea-dhcp6-server está disponible para ser instalado.")
|
|
print("Descargando e instalando el paquete isc-kea-dhcp6-server...")
|
|
subprocess.run(["apt-get", "install", "-y", "isc-kea-dhcp6-server"], check=True)
|
|
print("El paquete isc-kea-dhcp6-server ha sido descargado e instalado correctamente.")
|
|
else:
|
|
print("El paquete isc-kea-dhcp6-server no está disponible en los repositorios apt.")
|
|
|
|
if subprocess.run(["apt-cache", "show", "isc-kea-dhcp-ddns-server"], capture_output=True).returncode == 0:
|
|
print("El paquete isc-kea-dhcp-ddns-server está disponible para ser instalado.")
|
|
print("Descargando e instalando el paquete isc-kea-dhcp-ddns-server...")
|
|
subprocess.run(["apt-get", "install", "-y", "isc-kea-dhcp-ddns-server"], check=True)
|
|
print("El paquete isc-kea-dhcp-ddns-server ha sido descargado e instalado correctamente.")
|
|
else:
|
|
print("El paquete isc-kea-dhcp-ddns-server no está disponible en los repositorios apt.")
|
|
|
|
if subprocess.run(["apt-cache", "show", "isc-kea-ctrl-agent"], capture_output=True).returncode == 0:
|
|
print("El paquete isc-kea-ctrl-agent está disponible para ser instalado.")
|
|
print("Descargando e instalando el paquete isc-kea-ctrl-agent...")
|
|
subprocess.run(["apt-get", "install", "-y", "isc-kea-ctrl-agent"], check=True)
|
|
print("El paquete isc-kea-ctrl-agent ha sido descargado e instalado correctamente.")
|
|
else:
|
|
print("El paquete isc-kea-ctrl-agent no está disponible en los repositorios apt.")
|
|
|
|
def install_kea():
|
|
print(f"{install_kea.__name__}(): Instalación de muestra para el servicio DHCP de Kea.")
|
|
|
|
def backupFile(file):
|
|
if not os.path.isfile(file):
|
|
logger.warning(f"File {file} doesn't exist")
|
|
return
|
|
logger.info(f"Making backup of {file}")
|
|
shutil.copy2(file, f"{file}-LAST")
|
|
dateymd = datetime.datetime.now().strftime("%Y%m%d")
|
|
backup_file = f"{file}-{dateymd}"
|
|
if not os.path.isfile(backup_file):
|
|
shutil.copy2(file, backup_file)
|
|
logger.info(f"Backup of {file} successful")
|
|
|
|
def isc_keaDhcpConfigure():
|
|
global DEVICE, NETMASK, NETIP, ROUTERIP, DNSIP, SERVERIP
|
|
print(f"{isc_keaDhcpConfigure.__name__}(): Configuración de muestra para el servicio DHCP de Kea.")
|
|
errcode = 0
|
|
i = 0
|
|
interfaces = "["
|
|
#DEVICE = ["eth0", "eth1"] # Define the DEVICE variable with appropriate values
|
|
#NETMASK = "255.255.255.0" # Replace with the actual value of NETMASK
|
|
#NETIP = "192.168.0.1" # Replace with the actual value of NETIP
|
|
#ROUTERIP = "192.168.0.1" # Replace with the actual value of ROUTERIP
|
|
DNSIP = "192.168.0.1" # Replace with the actual value of DNSIP
|
|
#SERVERIP = "192.168.0.1" # Replace with the actual value of SERVERIP
|
|
# Rest of the code...
|
|
# Define the NETMASK variable
|
|
# Construir la lista de interfaces
|
|
print(NETIP)
|
|
print(NETMASK)
|
|
#CIDR = mask2cidr(NETMASK)
|
|
#print(CIDR) # Salida: 24
|
|
print(ROUTERIP)
|
|
print(DNSIP)
|
|
with open("/etc/kea/kea-dhcp4.conf", "w") as file:
|
|
file.write(
|
|
f"""
|
|
"interfaces": {interfaces},
|
|
"SERVERIP": "{SERVERIP}",
|
|
"NETIP": "{NETIP}",
|
|
"NETMASK": "{NETMASK}",
|
|
"ROUTERIP": "{ROUTERIP}",
|
|
"DNSIP": "{DNSIP}"
|
|
"""
|
|
)
|
|
# Si hubo errores al configurar, muestra un mensaje de error y sale de la función
|
|
if errcode != 0:
|
|
print(f"{isc_keaDhcpConfigure.__name__}(): Error al configurar el servicio DHCP de Kea.")
|
|
return 1
|
|
print(f"{isc_keaDhcpConfigure.__name__}(): Configuración de muestra para el servicio DHCP de Kea configurada en \"/etc/kea/kea-dhcp4.conf\".")
|
|
return 0
|
|
|
|
def testPxe():
|
|
global TFTPCFGDIR
|
|
logger.info(f"Checking TFTP service... please wait.")
|
|
subprocess.run(["echo", "test"], stdout=open(f"{TFTPCFGDIR}/testpxe", "w"))
|
|
try:
|
|
subprocess.run(["tftp", "-v", "127.0.0.1", "-c", "get", "testpxe", "/tmp/testpxe"], check=True)
|
|
logger.info("TFTP service is OK.")
|
|
except subprocess.CalledProcessError:
|
|
logger.error("TFTP service is down.")
|
|
os.remove(f"{TFTPCFGDIR}/testpxe")
|
|
|
|
def run_command(command):
|
|
result = subprocess.run(command, shell=True, text=True, capture_output=True)
|
|
if result.returncode != 0:
|
|
print(f"Error executing command: {command}")
|
|
print(result.stderr)
|
|
exit(1)
|
|
print(result.stdout)
|
|
|
|
def tftpConfigure():
|
|
global TFTPSERV, INETDSERV, TFTPCFGDIR
|
|
# Update the package list
|
|
#print("Updating package list...")
|
|
run_command("sudo apt update")
|
|
|
|
run_command("sudo DEBIAN_FRONTEND=noninteractive apt install -y build-essential")
|
|
|
|
# Install tftpd-hpa in non-interactive mode
|
|
print("Installing tftpd-hpa...")
|
|
run_command("sudo DEBIAN_FRONTEND=noninteractive apt install -y tftpd-hpa")
|
|
|
|
# Configure tftpd-hpa
|
|
print("Configuring tftpd-hpa...")
|
|
tftpd_config = """
|
|
# /etc/default/tftpd-hpa
|
|
|
|
TFTP_USERNAME="tftp"
|
|
TFTP_DIRECTORY="/var/lib/tftpboot"
|
|
TFTP_ADDRESS="0.0.0.0:69"
|
|
TFTP_OPTIONS="--secure"
|
|
"""
|
|
with open("/tmp/tftpd-hpa", "w") as config_file:
|
|
config_file.write(tftpd_config)
|
|
|
|
run_command("sudo mv /tmp/tftpd-hpa /etc/default/tftpd-hpa")
|
|
|
|
# Create and set permissions for the TFTP directory
|
|
print("Creating and setting permissions for the TFTP directory...")
|
|
run_command("sudo mkdir -p /var/lib/tftpboot")
|
|
run_command("sudo chown -R tftp:tftp /var/lib/tftpboot")
|
|
run_command("sudo chmod -R 755 /var/lib/tftpboot")
|
|
|
|
# Restart the tftpd-hpa service
|
|
print("Restarting tftpd-hpa service...")
|
|
run_command("sudo systemctl restart tftpd-hpa")
|
|
|
|
# Check the status of the tftpd-hpa service
|
|
print("Checking tftpd-hpa service status...")
|
|
run_command("sudo systemctl status tftpd-hpa")
|
|
# if TFTPSERV:
|
|
# logger.info(f"TFTPSERV is configured: {TFTPSERV}")
|
|
# inetd_cfg_path = f"{INETDCFGDIR}/{TFTPSERV}"
|
|
# if os.path.isfile(inetd_cfg_path):
|
|
# logger.error(f"The inetd configuration file exists: {inetd_cfg_path}")
|
|
# with open(inetd_cfg_path, "r+") as file:
|
|
# content = file.read()
|
|
# new_content = content.replace("disable.*", "disable = no")
|
|
# file.seek(0)
|
|
# file.write(new_content)
|
|
# file.truncate()
|
|
# logger.info(f"Modified inetd configuration file: {inetd_cfg_path}")
|
|
# else:
|
|
# service = TFTPSERV
|
|
# logger.info(f"Enabling and starting the service {service}.service")
|
|
# subprocess.run(["systemctl", "enable", f"{service}.service"], check=True)
|
|
# subprocess.run(["systemctl", "start", f"{service}.service"], check=True)
|
|
# service = INETDSERV
|
|
# logger.info(f"Enabling and starting the service {service}.service")
|
|
#subprocess.run(["systemctl", "enable", f"{service}.service"], check=True)
|
|
# subprocess.run(["systemctl", "start", f"{service}.service"], check=True)
|
|
#Crear directorio /var/lib/tftpboot
|
|
if not os.path.exists(TFTPCFGDIR):
|
|
os.makedirs(TFTPCFGDIR, mode=0o750, exist_ok=True)
|
|
logger.info(f"Directory {TFTPCFGDIR} created.")
|
|
else:
|
|
logger.warning(f"Directory {TFTPCFGDIR} exist.")
|
|
#Descargar oglive
|
|
logger.info("Downloading oglive...")
|
|
#Temporalmente se copia desde ~/oglive
|
|
# copiar desde el montaje /mnt/srv/artefactos/ogboot/tftpboot/
|
|
subprocess.run(["cp", "-r", f"/tmp/tftpboot/ogLive-5.11.0-r20210413", f"{TFTPCFGDIR}/"])
|
|
# subprocess.run(["cp", "-r", f"/tmp/ipxe/tftpboot/ipxe", f"{TFTPCFGDIR}/"])
|
|
#Crear enlace simbólico de oglive-5.11.0-r20210413 a /var/lib/tftpboot/ogLive
|
|
subprocess.run(["ln", "-s", f"{TFTPCFGDIR}/ogLive-5.11.0-r20210413", f"{TFTPCFGDIR}/ogLive"])
|
|
#Crear enlace simbólico de /var/lib/tftpboot/ogLive a /var/lib/tftpboot/ogLive/ogclient
|
|
subprocess.run(["ln", "-s", f"{TFTPCFGDIR}/ogLive", f"{TFTPCFGDIR}/ogclient"])
|
|
|
|
symlink_target = f"{INSTALL_OGBOOT_TARGET}/tftpboot"
|
|
logger.info(f"Creating symbolic link from {TFTPCFGDIR} to {symlink_target}")
|
|
if not os.path.exists(symlink_target):
|
|
os.symlink(TFTPCFGDIR, symlink_target)
|
|
os.chown(symlink_target, pwd.getpwnam("ogboot").pw_uid, pwd.getpwnam("ogboot").pw_gid)
|
|
else:
|
|
logger.warning(f"The symbolic link already exists: {symlink_target}")
|
|
#logger.info("Creating symbolic link from /opt/ogboot/tftpboot to /var/lib/tftpboot...")
|
|
#if os.path.islink(symlink_target):
|
|
# run_command(f"sudo rm -rf {symlink_target}")
|
|
#elif os.path.exists(symlink_target):
|
|
# run_command(f"sudo ln -s {TFTPCFGDIR} {INSTALL_OGBOOT_TARGET}")
|
|
|
|
def servicesCompilation():
|
|
global WORKDIR
|
|
hayErrores = 0
|
|
process = subprocess.run(["make"], cwd=f"{WORKDIR}/ogboot/sources/clients/ogAdmClient")
|
|
subprocess.run(["mv", f"{WORKDIR}/ogboot/sources/clients/ogAdmClient/ogAdmClient", f"{WORKDIR}/ogboot/client/shared/bin"])
|
|
if process.returncode != 0:
|
|
logger.info(f"{servicesCompilation.__name__}(): error while compiling OpenGnsys Admin Client")
|
|
hayErrores = 1
|
|
return hayErrores
|
|
|
|
def copyInterfaceAdm():
|
|
global WORKDIR, INSTALL_TARGET
|
|
hayErrores = 0
|
|
cp_process = subprocess.run(["cp", "-ar", f"{WORKDIR}/ogboot/sources/interface", f"{INSTALL_TARGET}/client/interfaceAdm"])
|
|
if cp_process.returncode != 0:
|
|
logger.error(f"Error while copying Administration Interface Folder")
|
|
hayErrores = 1
|
|
return hayErrores
|
|
|
|
def copyClientFiles():
|
|
global WORKDIR, INSTALL_TARGET
|
|
errstatus = 0
|
|
logger.info(f"Copying OpenGnsys Client files.")
|
|
source_files = glob.glob(f"{WORKDIR}/ogboot/client/shared/*")
|
|
# Copy each file individually
|
|
for file in source_files:
|
|
cp_process = subprocess.run(["cp", "-a", file, f"{INSTALL_TARGET}/client"])
|
|
if cp_process.returncode != 0:
|
|
logger.error(f"Error while copying client structure: {file}")
|
|
errstatus = 1
|
|
logger.info(f"Copying OpenGnsys Cloning Engine files.")
|
|
os.makedirs(f"{INSTALL_TARGET}/client/lib/engine/bin", mode=0o750, exist_ok=True)
|
|
engine_files = glob.glob(f"{WORKDIR}/ogboot/client/engine/*.lib*")
|
|
# Copiar cada archivo individualmente
|
|
for file in engine_files:
|
|
cp_engine_process = subprocess.run(["cp", "-a", file, f"{INSTALL_TARGET}/client/lib/engine/bin"])
|
|
if cp_engine_process.returncode != 0:
|
|
logger.error(f"Error while copying engine files: {file}")
|
|
errstatus = 1
|
|
if errstatus == 0:
|
|
logger.info(f"Client copy files success.")
|
|
else:
|
|
logger.error(f"Client copy files with errors")
|
|
return errstatus
|
|
|
|
def cidr2mask(bits):
|
|
args = [5 - (bits // 8), 255, 255, 255, 255, (255 << (8 - (bits % 8))) & 255, 0, 0, 0]
|
|
if args[0] > 1:
|
|
args = args[args[0]:]
|
|
else:
|
|
args = args[1:]
|
|
return ".".join(str(arg) for arg in args)
|
|
|
|
def mask2cidr(mask):
|
|
addr = mask.split(".")
|
|
cidr = 0
|
|
for i in addr:
|
|
cidr += bin(int(i)).count("1")
|
|
return cidr
|
|
|
|
def get_first_network_interface_with_traffic():
|
|
with open('/proc/net/dev') as f:
|
|
for line in f:
|
|
if ':' in line:
|
|
parts = line.split(':')
|
|
if len(parts) > 1:
|
|
interface = parts[0].strip()
|
|
if interface != "lo":
|
|
traffic_data = parts[1].strip().split()
|
|
received_bytes = int(traffic_data[0])
|
|
transmitted_bytes = int(traffic_data[8])
|
|
if received_bytes > 0 or transmitted_bytes > 0:
|
|
return interface
|
|
|
|
def getNetworkSettings():
|
|
global DEVICE, SERVERIP, NETMASK, NETBROAD, NETIP, ROUTERIP, DEFAULTDEV
|
|
DHCPNET = "127.0.0.1"
|
|
#print("getNetworkSettings(): Detecting network parameters.")
|
|
output = subprocess.check_output(["ip", "-o", "link", "show", "up"]).decode("utf-8")
|
|
lines = output.strip().split("\n")
|
|
for line in lines:
|
|
dev = line.split(":")[1].split("@")[0].strip()
|
|
output = subprocess.check_output(["ip", "-o", "addr", "show", "dev", dev]).decode("utf-8")
|
|
addr_lines = output.strip().split("\n")
|
|
for addr_line in addr_lines:
|
|
addr_parts = addr_line.split()
|
|
cidr_netmask = addr_parts[3].split("/")[1]
|
|
cidr_netmask = int(cidr_netmask)
|
|
if cidr_netmask >= 0 and cidr_netmask <= 32:
|
|
netmask = ".".join([str((0xffffffff << (32 - cidr_netmask) >> i) & 0xff) for i in [24, 16, 8, 0]])
|
|
if addr_parts[2] == "inet":
|
|
DEVICE.append(dev)
|
|
SERVERIP.append(addr_parts[3].split("/")[0])
|
|
NETMASK.append(netmask)
|
|
NETBROAD.append(addr_parts[5])
|
|
NETIP.append(addr_parts[3].split("/")[0])
|
|
ROUTERIP.append(subprocess.check_output(["ip", "route", "list", "default"]).decode("utf-8").split()[2])
|
|
if DHCPNET == NETIP[-1]:
|
|
DEFAULTDEV = dev
|
|
else:
|
|
DEFAULTDEV = DEFAULTDEV if "DEFAULTDEV" in locals() else dev
|
|
if len(NETIP) == 0 or len(NETMASK) == 0:
|
|
return (1)
|
|
else:
|
|
return (0)
|
|
|
|
def openGnsysConfigure():
|
|
global DEFAULTDEV, INSTALL_TARGET, OGCORE_IP, WORKDIR
|
|
i = 0
|
|
dev = ""
|
|
CONSOLEURL = ""
|
|
CONSOLEURL = f"https://{OGCORE_IP}/opengnsys"
|
|
with open(f"{WORKDIR}/ogboot/etc/ogAdmClient.cfg") as file:
|
|
content = file.read()
|
|
content = content.replace("SERVERIP", OGCORE_IP)
|
|
content = content.replace("OPENGNSYSURL", CONSOLEURL)
|
|
with open(f"{INSTALL_TARGET}/client/etc/ogAdmClient-{DEFAULTDEV}.cfg", "w") as outfile:
|
|
outfile.write(content)
|
|
if os.path.islink(f"{INSTALL_TARGET}/client/etc/ogAdmClient.cfg"):
|
|
logger.warning(f"Link {INSTALL_TARGET}/client/etc/ogAdmClient.cfg exists.")
|
|
else:
|
|
try:
|
|
os.symlink(f"{INSTALL_TARGET}/client/etc/ogAdmClient-{DEFAULTDEV}.cfg", f"{INSTALL_TARGET}/client/etc/ogAdmClient.cfg")
|
|
print(f"Symbolic link created: {INSTALL_TARGET}/client/etc/ogAdmClient-{DEFAULTDEV}.cfg -> {INSTALL_TARGET}/client/etc/ogAdmClient.cfg")
|
|
except OSError as e:
|
|
logger.error(f"Error creating symbolic link: {e}")
|
|
TZ = subprocess.check_output(["timedatectl", "status"]).decode().split("\n")[2].split(":")[1].strip()
|
|
with open(f"{INSTALL_TARGET}/client/etc/engine.cfg", "a") as file:
|
|
file.write(f"# OpenGnsys Server timezone.\nTZ=\"{TZ.replace(' ', '')}\"\n")
|
|
logger.info(f"OpenGnsys config files created.")
|
|
|
|
def mount_NFS():
|
|
global IPXE_DIR, INSTALL_OPENGNSYS_TARGET
|
|
if subprocess.call(["sudo", "mount", "-t", "nfs", "ognartefactos.evlt.uma.es:/", "/mnt"]) == 0:
|
|
logger.info("Properly mounted NFS system.")
|
|
else:
|
|
logger.error("Could not mount the NFS system.")
|
|
exit(1)
|
|
logger.info("copying tftpboot files")
|
|
#subprocess.call(["ls", "/mnt/"])
|
|
subprocess.call(["sudo", "cp", "-r", "/mnt/srv/artefactos/ogboot/tftpboot/", "/tmp"])
|
|
if not os.path.exists(IPXE_DIR + "/tftpboot"):
|
|
os.makedirs(IPXE_DIR + "/tftpboot")
|
|
#os.chdir(f"{IPXE_DIR}/tftpboot")
|
|
logger.info("copying ipxe files")
|
|
subprocess.call(["sudo", "cp", "-r", "/mnt/srv/artefactos/ogboot/ipxe/", "/tmp"])
|
|
if not os.path.exists(IPXE_DIR + "/src"):
|
|
os.makedirs(IPXE_DIR + "/src")
|
|
logger.info(f"make to {IPXE_DIR}/src")
|
|
os.chdir(f"{IPXE_DIR}/src")
|
|
if subprocess.call(["sudo", "make", "-s", "-j", "4"]) == 0:
|
|
logger.info(f"Directory {IPXE_DIR}/src correctly mounted.")
|
|
else:
|
|
logger.error(f"ERROR\tCould not mount the directory {IPXE_DIR}/src.")
|
|
exit(1)
|
|
|
|
if not os.path.exists("/opt/opengnsys"):
|
|
os.symlink("/opt/ogboot/", "/opt/opengnsys")
|
|
logger.info("Symbolic link created successfully.")
|
|
#logger.info(f"copy ipxe(2):::::::::::::::::::::::::::: EMBED={INSTALL_OPENGNSYS_TARGET}/tftpboot/ipxe_scripts/dhcp_boot.ipxe")
|
|
#if subprocess.call(["sudo", "make", "-s", "bin/undionly.kpxe", f"EMBED={INSTALL_OPENGNSYS_TARGET}/tftpboot/ipxe_scripts/dhcp_boot.ipxe"]) == 0:
|
|
# logger.info("Boot file mounted correctly.")
|
|
#else:
|
|
# logger.error("Failed to mount boot file.")
|
|
# exit(1)
|
|
subprocess.call(["sudo", "cp", "bin/undionly.kpxe", f"{INSTALL_OPENGNSYS_TARGET}/tftpboot"])
|
|
if subprocess.call(["sudo", "make", "-s", "bin-x86_64-efi/ipxe.efi", f"EMBED={INSTALL_OPENGNSYS_TARGET}/tftpboot/ipxe_scripts/dhcp_boot.ipxe"]) == 0:
|
|
logger.info("Properly constructed EFI file.")
|
|
else:
|
|
logger.error("Could not build EFI file.")
|
|
exit(1)
|
|
subprocess.call(["sudo", "cp", "bin-x86_64-efi/ipxe.efi", f"{INSTALL_OPENGNSYS_TARGET}/tftpboot"])
|
|
|
|
def generate_ipxe_script():
|
|
global DEFAULTDEV, INSTALL_OGBOOT_TARGET, WORKDIR
|
|
ip_address_server = subprocess.check_output(["ifconfig", DEFAULTDEV]).decode().split("\n")[1].split()[1]
|
|
template = os.path.join(WORKDIR, "ogboot/etc/dhcp_boot.ipxe.tmpl")
|
|
ipxe_output = f"{INSTALL_OGBOOT_TARGET}/tftpboot/ipxe_scripts/dhcp_boot.ipxe"
|
|
os.makedirs(os.path.dirname(ipxe_output), mode=0o750, exist_ok=True)
|
|
shutil.copy(template, ipxe_output)
|
|
with open(ipxe_output, "r") as ipxe_file:
|
|
ipxe_content = ipxe_file.read()
|
|
ipxe_content = ipxe_content.replace("__SERVERIP__", ip_address_server)
|
|
with open(ipxe_output, "w") as ipxe_file:
|
|
ipxe_file.write(ipxe_content)
|
|
# Reemplazar SERVERIP con la dirección IP en la plantilla y guardarla en el archivo de salida
|
|
# with open(template, "r") as tmpl_file:
|
|
# template_content = tmpl_file.read()
|
|
# ipxe_content = template_content.replace("SERVERIP", ip_address_server)
|
|
# with open(ipxe_output, "w") as ipxe_file:
|
|
# ipxe_file.write(ipxe_content)
|
|
template_default = os.path.join(WORKDIR, "ogboot/tftpboot/ipxe_scripts/default.ipxe")
|
|
default_output = os.path.join(INSTALL_OGBOOT_TARGET, "tftpboot/ipxe_scripts/default.ipxe")
|
|
with open(template_default, "r") as default_tmpl_file:
|
|
default_template_content = default_tmpl_file.read()
|
|
default_ipxe_content = default_template_content.replace("__SERVERIP__", ip_address_server)
|
|
with open(default_output, "w") as default_ipxe_file:
|
|
default_ipxe_file.write(default_ipxe_content)
|
|
logger.info("ipxe files created correctly.")
|
|
|
|
def smbConfigure():
|
|
global SAMBACFGDIR, SAMBASERV, OPENGNSYS_CLIENT_PASSWD, OPENGNSYS_CLIENT_USER, PYTHON_VERSION
|
|
#logger.info(f"{smbConfigure.__name__}(): Configuring Samba service.")
|
|
backupFile(f"{SAMBACFGDIR}/smb.conf")
|
|
# Copiar plantilla de recursos para OpenGnsys
|
|
with open(os.path.join(WORKDIR, 'ogboot/etc/smb-ogboot.conf.tmpl'), 'r') as tmpl_file:
|
|
template = tmpl_file.read()
|
|
replaced_template = template.replace('__OGBOOTDIR__', INSTALL_OPENGNSYS_TARGET)
|
|
with open(os.path.join(SAMBACFGDIR, 'smb-ogboot.conf'), 'w') as conf_file:
|
|
conf_file.write(replaced_template)
|
|
# Configurar y recargar Samba"
|
|
subprocess.run(["perl", "-pi", "-e", "s/WORKGROUP/OPENGNSYS/; s/server string \=.*/server string \= ogBoot Samba Server/", f"{SAMBACFGDIR}/smb.conf"])
|
|
if "smb-ogboot" not in open(f"{SAMBACFGDIR}/smb.conf").read():
|
|
with open(f"{SAMBACFGDIR}/smb.conf", "a") as file:
|
|
file.write(f"include = {SAMBACFGDIR}/smb-ogboot.conf\n")
|
|
service = SAMBASERV
|
|
subprocess.run(["systemctl", "enable", f"{service}.service"])
|
|
subprocess.run(["systemctl", "restart", f"{service}.service"])
|
|
# Comprobar si se ha configurado correctamente Samba
|
|
if subprocess.run(["systemctl", "is-active", f"{service}.service"]).returncode == 0:
|
|
logger.info(f"{service} service started successfully.")
|
|
else:
|
|
logger.error(f"Failed to start {service} service.")
|
|
return 1
|
|
# Establecer la contraseña para el usuario opengnsys
|
|
smbpasswd_command = f"(echo {OPENGNSYS_CLIENT_PASSWD}; echo {OPENGNSYS_CLIENT_PASSWD}) | sudo smbpasswd -s -a {OPENGNSYS_CLIENT_USER}"
|
|
if "Python 3.7" in {PYTHON_VERSION}:
|
|
result = subprocess.run(smbpasswd_command, shell=True, capture_output=True, text=True)
|
|
if result.returncode == 0:
|
|
logger.info(f"The password for the user {OPENGNSYS_CLIENT_USER} has been set correctly..")
|
|
else:
|
|
logger.error(f"Error setting password: {result.stderr}")
|
|
else:
|
|
process = subprocess.Popen(smbpasswd_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
stdout, stderr = process.communicate()
|
|
if process.returncode == 0:
|
|
logger.info(f"The password for the user {OPENGNSYS_CLIENT_USER} has been set correctly..")
|
|
else:
|
|
logger.error(f"Error setting password: {stderr}")
|
|
logger.info(f"Added Samba configuration.")
|
|
return 0
|
|
|
|
def setup_nginx():
|
|
global DEFAULTDEV, WORKDIR
|
|
try:
|
|
# Obtener la IP del servidor
|
|
ip_address_server = subprocess.check_output(["ifconfig", DEFAULTDEV]).decode().split("\n")[1].split()[1]
|
|
|
|
# Leer y modificar la plantilla de configuración de nginx
|
|
template_path = os.path.join(WORKDIR, "ogboot/etc/nginxServer.conf.tmpl")
|
|
with open(template_path, 'r') as nginx_file:
|
|
nginx_content = nginx_file.read()
|
|
|
|
nginx_content = nginx_content.replace("__SERVERIP__", ip_address_server)
|
|
|
|
# Ruta de destino para la configuración de nginx
|
|
nginx_output = "/etc/nginx/sites-available/ogboot.conf"
|
|
with open(nginx_output, 'w') as nginx_file:
|
|
nginx_file.write(nginx_content)
|
|
|
|
logger.info("Nginx configuration file created successfully.")
|
|
|
|
# Crear el enlace simbólico en sites-enabled
|
|
subprocess.run(["sudo", "ln", "-sf", nginx_output, "/etc/nginx/sites-enabled/ogboot.conf"])
|
|
|
|
logger.info("Symbolic link for nginx configuration created successfully.")
|
|
|
|
# Reiniciar el servicio de samba
|
|
subprocess.run(["sudo", "systemctl", "restart", "smbd.service"])
|
|
|
|
logger.info("Samba service restarted successfully.")
|
|
|
|
# Modificar el archivo de configuración de nginx para ejecutarse como ogboot
|
|
nginx_conf_path = "/etc/nginx/nginx.conf"
|
|
with open(nginx_conf_path, 'r') as nginx_conf_file:
|
|
nginx_conf_content = nginx_conf_file.read()
|
|
|
|
nginx_conf_content = nginx_conf_content.replace("user www-data;", "user ogboot;")
|
|
|
|
with open(nginx_conf_path, 'w') as nginx_conf_file:
|
|
nginx_conf_file.write(nginx_conf_content)
|
|
|
|
logger.info("Nginx configuration file modified to run as ogboot.")
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
logger.error(f"Subprocess error: {e}")
|
|
exit(1)
|
|
except OSError as e:
|
|
logger.error(f"OS error: {e}")
|
|
exit(1)
|
|
|
|
def get_php_fpm_version():
|
|
try:
|
|
# Obtener la versión de PHP
|
|
php_version_output = subprocess.check_output(["php", "-v"]).decode()
|
|
# Extraer la versión principal y secundaria (por ejemplo, "7.4")
|
|
match = re.search(r"PHP (\d+\.\d+)", php_version_output)
|
|
if match:
|
|
php_version = match.group(1)
|
|
return php_version
|
|
else:
|
|
raise RuntimeError("No se pudo determinar la versión de PHP.")
|
|
except subprocess.CalledProcessError as e:
|
|
logger.error(f"Error al obtener la versión de PHP: {e}")
|
|
exit(1)
|
|
|
|
def modify_php_fpm_config():
|
|
php_version = get_php_fpm_version()
|
|
php_fpm_conf_path = f"/etc/php/{php_version}/fpm/pool.d/www.conf"
|
|
|
|
try:
|
|
# Leer el archivo de configuración
|
|
with open(php_fpm_conf_path, 'r') as file:
|
|
config_lines = file.readlines()
|
|
|
|
# Modificar las líneas necesarias
|
|
with open(php_fpm_conf_path, 'w') as file:
|
|
for line in config_lines:
|
|
if line.startswith('user ='):
|
|
file.write('user = www-data\n')
|
|
elif line.startswith('group ='):
|
|
file.write('group = ogboot\n')
|
|
elif line.startswith('listen.owner ='):
|
|
file.write('listen.owner = www-data\n')
|
|
elif line.startswith('listen.group ='):
|
|
file.write('listen.group = ogboot\n')
|
|
else:
|
|
file.write(line)
|
|
|
|
logger.info("PHP-FPM configuration file modified successfully.")
|
|
|
|
# Reiniciar el servicio PHP-FPM
|
|
subprocess.run(["sudo", "systemctl", "restart", f"php{php_version}-fpm"])
|
|
logger.info("PHP-FPM service restarted successfully.")
|
|
except Exception as e:
|
|
logger.error(f"An error occurred: {e}")
|
|
exit(1)
|
|
|
|
def install_oglive_daemon():
|
|
global WORKDIR, INSTALL_TARGET
|
|
try:
|
|
DAEMON_SCRIPT_SRC = os.path.join(WORKDIR, "ogboot/bin/oglive_daemon.py")
|
|
DAEMON_SCRIPT_DEST = os.path.join(INSTALL_TARGET, "bin", "oglive_daemon.py")
|
|
SERVICE_FILE_SRC = os.path.join(WORKDIR, "ogboot/etc/oglive_daemon.service")
|
|
SERVICE_FILE_DEST = "/etc/systemd/system/oglive_daemon.service"
|
|
|
|
# Crear directorio de destino si no existe
|
|
os.makedirs(os.path.dirname(DAEMON_SCRIPT_DEST), exist_ok=True)
|
|
|
|
# Copiar el script del demonio al directorio de destino
|
|
shutil.copyfile(DAEMON_SCRIPT_SRC, DAEMON_SCRIPT_DEST)
|
|
logger.info(f"Copied {DAEMON_SCRIPT_SRC} to {DAEMON_SCRIPT_DEST}")
|
|
|
|
# Hacer el script ejecutable
|
|
os.chmod(DAEMON_SCRIPT_DEST, 0o755)
|
|
logger.info(f"Set executable permissions for {DAEMON_SCRIPT_DEST}")
|
|
|
|
# Copiar el archivo de servicio de systemd
|
|
shutil.copyfile(SERVICE_FILE_SRC, SERVICE_FILE_DEST)
|
|
logger.info(f"Copied {SERVICE_FILE_SRC} to {SERVICE_FILE_DEST}")
|
|
|
|
# Recargar systemd para reconocer el nuevo servicio
|
|
subprocess.run(["systemctl", "daemon-reload"], check=True)
|
|
logger.info("Reloaded systemd daemon")
|
|
|
|
# Habilitar el servicio para que arranque al inicio
|
|
subprocess.run(["systemctl", "enable", "oglive_daemon.service"], check=True)
|
|
logger.info("Enabled oglive_daemon service")
|
|
|
|
# Arrancar el servicio
|
|
subprocess.run(["systemctl", "start", "oglive_daemon.service"], check=True)
|
|
logger.info("Started oglive_daemon service")
|
|
|
|
except (shutil.Error, OSError) as e:
|
|
logger.error(f"File operation error: {e}")
|
|
except subprocess.CalledProcessError as e:
|
|
logger.error(f"Subprocess error: {e}")
|
|
except Exception as e:
|
|
logger.error(f"An unexpected error occurred: {e}")
|
|
|
|
###############################################################################
|
|
###:::::::::::::::::::::::::::::::: MAIN :::::::::::::::::::::::::::::::::::###
|
|
###############################################################################
|
|
|
|
logger.info(f"Starting installation of ogBoot.")
|
|
|
|
logger.info("environment variables")
|
|
logger.info(f"OGCORE_IP:{OGCORE_IP}")
|
|
logger.info(f"OGCORE_SERVER:{OGCORE_SERVER}")
|
|
logger.info(f"INSTALL_TARGET:{INSTALL_TARGET}")
|
|
logger.info(f"INSTALL_OGBOOT_TARGET:{INSTALL_OGBOOT_TARGET}")
|
|
logger.info(f"INSTALL_OPENGNSYS_TARGET:{INSTALL_OPENGNSYS_TARGET}")
|
|
logger.info(f"GIT_REPO:{GIT_REPO}")
|
|
|
|
if os.geteuid() != 0:
|
|
logger.error("This program must be run with root privileges..")
|
|
exit(1)
|
|
if os.path.exists(os.path.join(INSTALL_OGBOOT_TARGET, "/doc/")):
|
|
logger.warning(f"ogBoot is already installed. Run {INSTALL_OGBOOT_TARGET}/lib/ogboot_devel_update.py” with root privileges to update..")
|
|
exit(2)
|
|
|
|
logger.info("Verifying Python distribution and version.")
|
|
check_distribution()
|
|
check_python_version()
|
|
|
|
logger.info("Checking the operating system.")
|
|
autoConfigure()
|
|
|
|
logger.info("Installing necessary packages.")
|
|
Missing = get_missing_packages ()
|
|
install_packages(Missing)
|
|
|
|
logger.info("Obtaining the default network configuration.")
|
|
DEFAULTDEV = get_first_network_interface_with_traffic()
|
|
logger.info(f"Network interface default:[{DEFAULTDEV}]")
|
|
if getNetworkSettings() != 0:
|
|
logger.error("Error reading default network settings.")
|
|
exit(1)
|
|
|
|
logger.info("Configuring package repositories.")
|
|
if REMOTE == 1:
|
|
downloadCode(GIT_REPO)
|
|
if os.system("echo $?") != 0:
|
|
logger.error("Error while getting code from the repository")
|
|
exit(1)
|
|
else:
|
|
if not os.path.exists(f"{WORKDIR}/ogboot"):
|
|
logger.warning(f"Does not exist {WORKDIR}/ogboot")
|
|
if not os.path.exists(WORKDIR):
|
|
os.makedirs(WORKDIR, mode=0o750, exist_ok=True)
|
|
logger.info(f"ogBoot directory not found, create a symbolic link to the directory where the code is located {WORKDIR} To {os.path.dirname(PROGRAM_DIR)}")
|
|
os.symlink(os.path.dirname(PROGRAM_DIR), f"{WORKDIR}/ogboot")
|
|
|
|
#logger.info("Creating directories.")
|
|
#createDirs(INSTALL_TARGET)
|
|
#if os.system("echo $?") != 0:
|
|
# logger.error("Error while creating directory paths!")
|
|
# exit(1)
|
|
|
|
logger.info("Creating ogBoot project.")
|
|
og_core_create_user("ogboot")
|
|
|
|
logger.info("Creating directories.")
|
|
og_boot_create_dirs()
|
|
|
|
logger.info("Copying installation files.")
|
|
og_boot_copy_files()
|
|
|
|
logger.info("Installing Symfony.")
|
|
og_boot_symfony_install()
|
|
og_boot_composer_install()
|
|
|
|
|
|
#if os.system("echo $?") != 0:
|
|
# logger.error("Error while creating skeleton directory!")
|
|
# exit(1)
|
|
|
|
logger.info("Configuring IPXE services")
|
|
generate_ipxe_script()
|
|
|
|
logger.info("Setting up NFS system")
|
|
mount_NFS()
|
|
|
|
logger.info("Configuring TFTP service.")
|
|
tftpConfigure()
|
|
|
|
logger.info("Compiling OpenGnsys services source code")
|
|
servicesCompilation()
|
|
if subprocess.run(["echo", "$?"]).returncode != 0:
|
|
logger.error("Error while compiling OpenGnsys services")
|
|
exit(1)
|
|
|
|
logger.info("Copy folder Interface between administration and cloning engine")
|
|
copyInterfaceAdm()
|
|
if subprocess.run(["echo", "$?"]).returncode != 0:
|
|
logger.error("Error while copying Administration Interface")
|
|
exit(1)
|
|
|
|
logger.info("Create the structure of the accesses to the server from the client (shared)")
|
|
copyClientFiles()
|
|
if subprocess.run(["echo", "$?"]).returncode != 0:
|
|
logger.error("Error creating client structure")
|
|
|
|
logger.info("Setup nginx")
|
|
setup_nginx()
|
|
if subprocess.run(["echo", "$?"]).returncode != 0:
|
|
logger.error("Error setup nginx")
|
|
|
|
logger.info("Configure php fpm")
|
|
modify_php_fpm_config()
|
|
if subprocess.run(["echo", "$?"]).returncode != 0:
|
|
logger.error("Error configure php fpm")
|
|
|
|
|
|
logger.info("Configure ogboot daemon")
|
|
install_oglive_daemon()
|
|
if subprocess.run(["echo", "$?"]).returncode != 0:
|
|
logger.error("Error configure ogboot daemon")
|
|
|
|
logger.info("Configuring ogCore")
|
|
openGnsysConfigure()
|
|
|
|
|
|
logger.info("Configuring Samba")
|
|
smbConfigure()
|
|
|
|
logger.info(f"ogBoot installation finished.")
|
|
|
|
logging.shutdown()
|
|
console_handler.close()
|