diff --git a/.env b/.env index 645dd5c..87b4f61 100644 --- a/.env +++ b/.env @@ -15,7 +15,7 @@ # https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration ###> symfony/framework-bundle ### -APP_ENV=dev +APP_ENV=prod APP_SECRET=d423d1302b974417d415b10bcde25767 ###< symfony/framework-bundle ### diff --git a/bin/oglivecli b/bin/oglivecli index 9c17dc1..9233cc1 100755 --- a/bin/oglivecli +++ b/bin/oglivecli @@ -157,7 +157,7 @@ function download() { if [ -f "$TARGETFILE" ]; then local file_type=$(file -b "$TARGETFILE") if [[ "$file_type" =~ "ISO 9660" ]] && [[ "$file_type" =~ "ogClient" ]]; then - echo "Archivo ISO válido descargado: $TARGETFILE" + install "$OGLIVEFILE" else raiseError download "El archivo descargado no es un ogLive ISO válido." fi @@ -165,8 +165,6 @@ function download() { raiseError download "El archivo no fue descargado correctamente." fi - # Continuar con la instalación. - install "$OGLIVEFILE" fi } @@ -200,7 +198,6 @@ function downloadMenu() { OGLIVEDIR="$TFTPDIR/$DEFOGLIVE-${OGLIVEKRNL%%-*}-$OGLIVEARCH-$OGLIVEREV" OGLIVEDIR="${OGLIVEDIR/amd64-/}" - echo "Verificando si está instalado: $OGLIVEDIR" # Verificar si el ogLive está instalado y no es un directorio .old if [ -d "$OGLIVEDIR" ] && [[ ! "$OGLIVEDIR" =~ \.old$ ]]; then @@ -208,7 +205,6 @@ function downloadMenu() { else installed=false fi - echo "Estado de 'installed': $installed" ISOREL=${OGLIVE[i-1]##*-r}; ISOREL=${ISOREL%%.*} [ $ISOREL -ge $MINREL ] && compatible=true diff --git a/composer.json b/composer.json index 7f0c85e..44b9252 100644 --- a/composer.json +++ b/composer.json @@ -4,17 +4,16 @@ "minimum-stability": "stable", "prefer-stable": true, "require": { - "php": ">=7.2.0", + "php": ">=8.1", "ext-ctype": "*", "ext-iconv": "*", "doctrine/annotations": "^1.6", "doctrine/doctrine-bundle": "^2.0", "doctrine/doctrine-migrations-bundle": "^3.0", "doctrine/orm": "^2.7", + "nelmio/api-doc-bundle": "^4.29", "phpdocumentor/reflection-docblock": "^5.0", - "phpstan/phpdoc-parser": "^0.4", - "zircote/swagger-php": "3.*", - "symfony/runtime": "5.*", + "phpstan/phpdoc-parser": "^1.13", "symfony/asset": "5.*", "symfony/console": "5.*", "symfony/doctrine-messenger": "5.*", @@ -32,6 +31,7 @@ "symfony/process": "5.*", "symfony/property-access": "5.*", "symfony/property-info": "5.*", + "symfony/runtime": "5.*", "symfony/security-bundle": "5.*", "symfony/serializer": "5.*", "symfony/string": "5.*", @@ -41,7 +41,8 @@ "symfony/web-link": "5.*", "symfony/yaml": "5.*", "twig/extra-bundle": "^2.12|^3.0", - "twig/twig": "^2.12|^3.0" + "twig/twig": "^2.12|^3.0", + "zircote/swagger-php": "^4.0" }, "require-dev": { "phpunit/phpunit": "^8.5", @@ -55,7 +56,7 @@ }, "config": { "platform": { - "php": "7.2.24" + "php": "8.1" }, "allow-plugins": { "composer/package-versions-deprecated": true, diff --git a/etc/nginxServer.conf.tmpl b/etc/nginxServer.conf.tmpl index 7f7c821..0d36042 100644 --- a/etc/nginxServer.conf.tmpl +++ b/etc/nginxServer.conf.tmpl @@ -1,6 +1,6 @@ server { listen 80; - server_name __SERVERIP__; # IP del servidor + server_name __SERVERIP__ localhost; # IP del servidor # Raíz del documento para el proyecto Symfony root /opt/ogboot/public; @@ -35,6 +35,10 @@ server { error_log /var/log/nginx/ogboot_error.log; access_log /var/log/nginx/ogboot_access.log; + location /api/doc { + try_files $uri /index.php?$query_string; + } + # Ruta base para servir archivos de TFTP location /tftpboot { alias /opt/ogboot/tftpboot; diff --git a/installer/ogboot_installer.py b/installer/ogboot_installer.py index 47a20d8..076e2fe 100755 --- a/installer/ogboot_installer.py +++ b/installer/ogboot_installer.py @@ -350,7 +350,7 @@ def og_boot_copy_files(): 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]) + result = subprocess.run(["sudo", "-u", "ogboot", "composer", "install", "--no-interaction", "--working-dir", INSTALL_OGBOOT_TARGET]) if result.returncode != 0: logger.error("Error creating Symfony project using Composer") return diff --git a/sources/clients/ogAdmClient/ogAdmClient b/sources/clients/ogAdmClient/ogAdmClient deleted file mode 100755 index 0c086d2..0000000 Binary files a/sources/clients/ogAdmClient/ogAdmClient and /dev/null differ diff --git a/src/OgBootBundle/Controller/OgBootController.php b/src/OgBootBundle/Controller/OgBootController.php index c38d811..73361d4 100644 --- a/src/OgBootBundle/Controller/OgBootController.php +++ b/src/OgBootBundle/Controller/OgBootController.php @@ -550,10 +550,10 @@ public function installOglive(Request $request): Response if (!isset($data['iso_url'])) { return new JsonResponse(['error' => 'Invalid input data'], Response::HTTP_BAD_REQUEST); } - $isoUrl = $data['iso_url']; - $result = $this->curlRequestService->callOgLive("download " . escapeshellarg($isoUrl)); + // No usar escapeshellarg, sino simplemente agregar las comillas simples para que el comando se interprete correctamente + $result = $this->curlRequestService->callOgLive("download " . escapeshellarg($isoUrl)); if (is_array($result) && isset($result['success']) && $result['success'] === false) { return new JsonResponse(['error' => 'Failed to install ogLive client', 'details' => $result['error']], Response::HTTP_INTERNAL_SERVER_ERROR); } @@ -1068,69 +1068,69 @@ public function getBootFile(string $mac): Response return new Response($content, Response::HTTP_OK, ['Content-Type' => 'text/plain']); } - /** - * @Route("/ogboot/v1/pxe-templates", methods={"POST"}) - * - * @OA\Post( - * path="/ogboot/v1/pxe-templates", - * summary="Crear Plantilla", - * description="Crea una nueva plantilla de arranque utilizando los datos proporcionados.", - * @OA\RequestBody( - * required=true, - * @OA\JsonContent( - * type="object", - * @OA\Property(property="name_template", type="string", example="pxe"), - * @OA\Property(property="content_template", type="string", example="#!ipxe\nset timeout 0\nset timeout-style hidden\n\nset ISODIR __OGLIVE__\nset default 0\nset kernelargs __INFOHOST__\n# Menú de entrada para seleccionar OgLive\n:try_iso\nkernel tftp://__SERVERIP__/${ISODIR}/ogvmlinuz ${kernelargs} || goto fallback\ninitrd tftp://__SERVERIP__/${ISODIR}/oginitrd.img\nboot\n\n:fallback\necho \"OgLive default\"\nset ISODIR ogLive\nkernel tftp://__SERVERIP__/${ISODIR}/ogvmlinuz ${kernelargs}\ninitrd tftp://__SERVERIP__/${ISODIR}/oginitrd.img\nboot") - * ) - * ), - * @OA\Response( - * response=200, - * description="La plantilla de arranque se creó exitosamente.", - * @OA\JsonContent( - * type="object", - * @OA\Property(property="message", type="string", example="Plantilla creada exitosamente."), - * @OA\Property(property="template", type="string", example="#!ipxe\nset timeout 0\nset timeout-style hidden\n\nset ISODIR __OGLIVE__\nset default 0\nset kernelargs __INFOHOST__\n# Menú de entrada para seleccionar OgLive\n:try_iso\nkernel tftp://__SERVERIP__/${ISODIR}/ogvmlinuz ${kernelargs} || goto fallback\ninitrd tftp://__SERVERIP__/${ISODIR}/oginitrd.img\nboot\n\n:fallback\necho \"OgLive default\"\nset ISODIR ogLive\nkernel tftp://__SERVERIP__/${ISODIR}/ogvmlinuz ${kernelargs}\ninitrd tftp://__SERVERIP__/${ISODIR}/oginitrd.img\nboot") - * ) - * ), - * @OA\Response( - * response=400, - * description="La solicitud no pudo ser procesada debido a un error en los datos proporcionados en el cuerpo de la solicitud." - * ), - * @OA\Response( - * response=500, - * description="Ocurrió un error al crear la plantilla de arranque." - * ) - * ) - */ - public function createTemplate(Request $request) - { - $data = json_decode($request->getContent(), true); +/** + * @Route("/ogboot/v1/pxe-templates", methods={"POST"}) + * + * @OA\Post( + * path="/ogboot/v1/pxe-templates", + * summary="Crear Plantilla", + * description="Crea una nueva plantilla de arranque utilizando los datos proporcionados.", + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * type="object", + * @OA\Property(property="name_template", type="string", example=""), + * @OA\Property(property="content_template", type="string", example="") + * ) + * ), + * @OA\Response( + * response=200, + * description="La plantilla de arranque se creó exitosamente.", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="message", type="string", example=""), + * @OA\Property(property="template", type="string", example="") + * ) + * ), + * @OA\Response( + * response=400, + * description="La solicitud no pudo ser procesada debido a un error en los datos proporcionados en el cuerpo de la solicitud." + * ), + * @OA\Response( + * response=500, + * description="Ocurrió un error al crear la plantilla de arranque." + * ) + * ) + */ +public function createTemplate(Request $request) +{ + $data = json_decode($request->getContent(), true); - if (!isset($data['name_template']) || !isset($data['content_template'])) { - return new Response('La solicitud no pudo ser procesada debido a un error en los datos proporcionados en el cuerpo de la solicitud.', 400); - } - - $nameTemplate = $data['name_template']; - $contentTemplate = $data['content_template']; - $templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates'; - if (!preg_match('/^[a-zA-Z0-9._-]+$/', $nameTemplate)) { - return new Response('Nombre de la plantilla no válido.', 400); - } - - $filePath = $templateDir . '/' . $nameTemplate; - $contentTemplate = str_replace("\\n", "\n", $contentTemplate); - try { - file_put_contents($filePath, $contentTemplate); - } catch (\Exception $e) { - return new Response('Ocurrió un error al crear la plantilla de arranque. ' . $e->getMessage(), 500); - } - - return new Response(json_encode([ - 'message' => 'Plantilla creada exitosamente.', - 'template' => $contentTemplate - ]), 200, ['Content-Type' => 'application/json']); + if (!isset($data['name_template']) || !isset($data['content_template'])) { + return new Response('La solicitud no pudo ser procesada debido a un error en los datos proporcionados en el cuerpo de la solicitud.', 400); } + $nameTemplate = $data['name_template']; + $contentTemplate = $data['content_template']; + $templateDir = '/opt/ogboot/tftpboot/ipxe_scripts/templates'; + if (!preg_match('/^[a-zA-Z0-9._-]+$/', $nameTemplate)) { + return new Response('Nombre de la plantilla no válido.', 400); + } + + $filePath = $templateDir . '/' . $nameTemplate; + $contentTemplate = str_replace("\\n", "\n", $contentTemplate); + try { + file_put_contents($filePath, $contentTemplate); + } catch (\Exception $e) { + return new Response('Ocurrió un error al crear la plantilla de arranque. ' . $e->getMessage(), 500); + } + + return new Response(json_encode([ + 'message' => 'Plantilla creada exitosamente.', + 'template' => $contentTemplate + ]), 200, ['Content-Type' => 'application/json']); +} + /** diff --git a/src/OgBootBundle/Service/CurlRequestService.php b/src/OgBootBundle/Service/CurlRequestService.php index 4f077af..79bb496 100644 --- a/src/OgBootBundle/Service/CurlRequestService.php +++ b/src/OgBootBundle/Service/CurlRequestService.php @@ -27,19 +27,34 @@ public function callOgLive($parameter) // Ruta completa al script oglivecli $ogLiveCliPath = sprintf("%s/bin/oglivecli", dirname(dirname(dirname(__DIR__)))); - // Construir el comando sin sudo ni contraseña - $command = sprintf('%s %s', $ogLiveCliPath, escapeshellarg($parameter)); + // Dividir el parámetro en acción y argumentos + $args = array_map('trim', explode(' ', $parameter)); + $action = array_shift($args); + + // Registrar la acción y los argumentos + syslog(LOG_INFO, 'action ' . $action); + syslog(LOG_INFO, 'args ' . json_encode($args)); + + // Limpiar los argumentos de comillas innecesarias + $cleanedArgs = array_map(function($arg) { + return trim($arg, '\'\"'); + }, $args); + // Construir el comando final sin añadir comillas alrededor de cada elemento + $commandToRun = $ogLiveCliPath . ' ' . $action . ' ' . implode(' ', $cleanedArgs); // Registrar el comando en syslog para depuración - syslog(LOG_INFO, 'command ' . $command); + syslog(LOG_INFO, 'command ' . $commandToRun); // Ejecutar el comando - $output = shell_exec($command); + $output = shell_exec($commandToRun); + syslog(LOG_INFO, 'output ' . $output); - return $output; + // Decodificar la salida JSON si es posible + $decodedOutput = json_decode($output, true); + + return $decodedOutput; } - }