refs #503 #504 #639 updates installer deletes some echos to oglivecli, adapts ogboot service to call oglivecli directly and adds a route to the nginx template to call the nelmio swagger documentation

ogboot_debian_installer
Luis Gerardo Romero Garcia 2024-08-19 22:47:08 +00:00
parent 8465a6f2c9
commit 23e660610f
8 changed files with 98 additions and 82 deletions

2
.env
View File

@ -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 ###

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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']);
}
/**

View File

@ -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;
}
}