refs #1131 fix bug in create boot files that dont adds ogcore and oglog parameters

engine-branch opengnsys_devel-0.0.22
Luis Gerardo Romero Garcia 2025-01-16 13:14:34 +01:00
parent 9756b73ed9
commit 538e3fafe1
1 changed files with 87 additions and 61 deletions

View File

@ -1464,6 +1464,8 @@ public function getBootFiles(): JsonResponse
* )
* )
*/
public function createBootFile(Request $request): JsonResponse
{
$operation = 'ogboot.createBootFile';
@ -1477,29 +1479,17 @@ public function createBootFile(Request $request): JsonResponse
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$data = json_decode($request->getContent(), true);
$templateName = $data['template_name'] ?? null;
$mac = $this->validateAndFormatMac($data['mac'] ?? null);
//Si nos pasan el puerto se lo quitamos ya que server_ip siempre tirara por Samba
$serverIp = $data['server_ip'] ?? null;
if ($serverIp && strpos($serverIp, ':') !== false) {
$serverIp = explode(':', $serverIp)[0];
}
$ogLiveDir = $data['oglivedir'] ?? 'ogLive';
$this->logger->debug(json_encode([
'severity' => 'DEBUG',
'operation' => $operation,
'component' => $component,
'params' => [
'template_name' => $templateName,
'mac' => $mac,
'server_ip' => $serverIp,
'oglivedir' => $ogLiveDir
],
'desc' => 'Input data for PXE file creation.'
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
// Verificación de los campos obligatorios
if (!$templateName || !$mac) {
$httpCode = '400';
$this->logger->warning(json_encode([
@ -1509,13 +1499,10 @@ public function createBootFile(Request $request): JsonResponse
'http_code' => $httpCode,
'desc' => 'Missing required fields: mac and/or template_name.'
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
return new JsonResponse(
['error' => 'Missing required fields: mac and template_name'],
Response::HTTP_BAD_REQUEST
);
return new JsonResponse(['error' => 'Missing required fields: mac and template_name'], Response::HTTP_BAD_REQUEST);
}
// Validación adicional para asegurarnos de que no hay caracteres inseguros
if (!preg_match('/^[a-zA-Z0-9._-]+$/', $templateName) || strpos($templateName, '..') !== false) {
$httpCode = '400';
$this->logger->warning(json_encode([
@ -1526,16 +1513,41 @@ public function createBootFile(Request $request): JsonResponse
'params' => ['template_name' => $templateName],
'desc' => 'Invalid template name or unauthorized access attempt.'
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
return new JsonResponse(
['error' => 'INVALID_TEMPLATE_NAME', 'message' => 'Invalid template name or unauthorized access attempt.'],
['error' => 'INVALID_TEMPLATE_NAME', 'message' => 'Nombre de la plantilla no válido o intento de acceso no autorizado.'],
Response::HTTP_BAD_REQUEST
);
}
// Parámetros opcionales
$parameters = [
'LANG' => $data['lang'] ?? 'es_ES.UTF-8',
'ip' => $data['ip'] ?? '',
'router' => $data['router'] ?? '',
'netmask' => $data['netmask'] ?? '',
'computer_name' => $data['computer_name'] ?? '',
'netiface' => $data['netiface'] ?? '',
'group' => $data['group'] ?? '',
'ogrepo' => isset($data['ogrepo']) ? explode(':', $data['ogrepo'])[0] : '',
'ogcore' => isset($data['ogcore']) ? explode(':', $data['ogcore'])[0] : '',
'oglive' => isset($data['oglive']) ? explode(':', $data['oglive'])[0] : $serverIp,
'oglog' => isset($data['oglog']) ? explode(':', $data['oglog'])[0] : $serverIp,
'ogshare' => isset($data['ogshare']) ? explode(':', $data['ogshare'])[0] : $serverIp,
'oglivedir' => $data['oglivedir'] ?? '',
'ogprof' => $data['ogprof'] ?? 'false',
'hardprofile' => $data['hardprofile'] ?? '',
'ogntp' => $data['ogntp'] ?? '',
'ogdns' => $data['ogdns'] ?? '',
'ogproxy' => $data['ogproxy'] ?? '',
'ogunit' => $data['ogunit'] ?? '',
'resolution' => $data['resolution'] ?? '788'
];
$templateDir = $this->tftpbootDir . '/ipxe_scripts/templates';
$templatePath = $templateDir . '/' . $templateName;
// Verificar si la plantilla existe
if (!file_exists($templatePath)) {
$httpCode = '404';
$this->logger->info(json_encode([
@ -1546,11 +1558,7 @@ public function createBootFile(Request $request): JsonResponse
'params' => ['template_path' => $templatePath],
'desc' => 'Template not found.'
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
return new JsonResponse(
['error' => 'TEMPLATE_NOT_FOUND', 'message' => 'Template not found.'],
Response::HTTP_NOT_FOUND
);
return new JsonResponse(['error' => 'TEMPLATE_NOT_FOUND', 'message' => 'No se encontró la plantilla especificada'], Response::HTTP_NOT_FOUND);
}
$templateContent = file_get_contents($templatePath);
@ -1564,45 +1572,61 @@ public function createBootFile(Request $request): JsonResponse
'params' => ['template_path' => $templatePath],
'desc' => 'Failed to read the template.'
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
return new JsonResponse(
['error' => 'FAILED_TO_READ_TEMPLATE', 'message' => 'Failed to read template.'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
return new JsonResponse(['error' => 'FAILED_TO_READ_TEMPLATE', 'message' => 'Error al leer la plantilla'], Response::HTTP_INTERNAL_SERVER_ERROR);
}
$this->logger->debug(json_encode([
'severity' => 'DEBUG',
'operation' => $operation,
'component' => $component,
'desc' => 'Template content loaded.'
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
// Construcción de los argumentos del kernel
$kernelArgs = 'ro boot=oginit quiet splash irqpoll acpi=on og2nd=sqfs ogprotocol=smb ogactiveadmin=true ogdebug=true ogtmpfs=15 ' .
'oglivedir=${ISODIR} ' .
'LANG=' . ($data['lang'] ?? 'es_ES.UTF-8') . ' ' .
'ip=' . ($data['ip'] ?? '') . ':' . $serverIp . ':' . ($data['router'] ?? '') . ':' . ($data['netmask'] ?? '') . ':' . ($data['computer_name'] ?? '') . ':' . ($data['netiface'] ?? '') . ':none ';
$this->logger->debug(json_encode([
'severity' => 'DEBUG',
'operation' => $operation,
'component' => $component,
'params' => ['kernelArgs' => $kernelArgs],
'desc' => 'Kernel arguments constructed.'
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
'oglivedir=${ISODIR}' . ' ' .
'LANG=' . $parameters['LANG'] . ' ' .
'ip=' . $parameters['ip'] . ':' . $serverIp . ':' . $parameters['router'] . ':' . $parameters['netmask'] . ':' . $parameters['computer_name'] . ':' . $parameters['netiface'] . ':none ' .
'group=' . str_replace(' ', '_', trim($parameters['group'])) . ' ' .
'ogrepo=' . $parameters['ogrepo'] . ' ' .
'ogcore=' . $parameters['ogcore'] . ' ' .
'oglive=' . $parameters['oglive'] . ' ' .
'oglog=' . $parameters['oglog'] . ' ' .
'ogshare=' . $parameters['ogshare'] . ' ' .
'ogprof=' . ($parameters['ogprof'] === 'true' ? 'true' : 'false') . ' ' .
(!empty($parameters['hardprofile']) ? 'hardprofile=' . str_replace(' ', '_', trim($parameters['hardprofile'])) . ' ' : '') .
(!empty($parameters['ogntp']) ? 'ogntp=' . $parameters['ogntp'] . ' ' : '') .
(!empty($parameters['ogdns']) ? 'ogdns=' . $parameters['ogdns'] . ' ' : '') .
(!empty($parameters['ogproxy']) ? 'ogproxy=' . $parameters['ogproxy'] . ' ' : '') .
(!empty($parameters['ogunit']) ? 'ogunit=' . $parameters['ogunit'] . ' ' : '') .
(is_numeric($parameters['resolution']) && $parameters['resolution'] <= 999 ? 'vga=' . $parameters['resolution'] :
(strpos($parameters['resolution'], ':') !== false ? 'video=' . $parameters['resolution'] : ' ' . $parameters['resolution']));
// Esta será llamada a http para arrancar kernel e imagen de inicialización
// Si lo requiriese debe llevar puerto ya que se comunica con nginx
$serverIpPort = $this->ogBootIP;
if (!empty($this->ogBootPort)) {
$serverIpPort .= ':' . $this->ogBootPort;
}
// Extraer solo el nombre del directorio si contiene una ruta completa PROVISIONAL
if (strpos($ogLiveDir, '/') !== false) {
$ogLiveDir = basename($ogLiveDir);
}
$pxeContent = str_replace(
['__INFOHOST__', '__SERVERIP__', '__OGLIVE__'],
[$kernelArgs, $serverIpPort, basename($ogLiveDir)],
[$kernelArgs, $serverIpPort, $ogLiveDir],
$templateContent
);
if (file_put_contents($this->tftpbootDir . '/ipxe_scripts/01-' . $mac, $pxeContent) === false) {
// Insertar el comentario con el nombre de la plantilla después de #!ipxe
if (strpos($pxeContent, '#!ipxe') === 0) {
$pxeContent = "#!ipxe\n#Template: $templateName\n" . substr($pxeContent, 6);
} else {
$pxeContent = "#!ipxe\n#Template: $templateName\n" . $pxeContent;
}
// Nombre del archivo PXE basado en la MAC
$pxeFileName = '01-' . $mac;
// Ruta para guardar el archivo PXE
$pxeFilePath = $this->tftpbootDir . '/ipxe_scripts/' . $pxeFileName;
// Crear el archivo PXE
if (file_put_contents($pxeFilePath, $pxeContent) === false) {
$httpCode = '500';
$this->logger->error(json_encode([
'severity' => 'ERROR',
@ -1611,13 +1635,8 @@ public function createBootFile(Request $request): JsonResponse
'http_code' => $httpCode,
'desc' => 'Failed to create PXE file.'
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
return new JsonResponse(
['error' => 'FAILED_TO_CREATE_PXE_FILE', 'message' => 'Failed to create PXE file.'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
return new JsonResponse(['error' => 'FAILED_TO_CREATE_PXE_FILE', 'message' => 'Error al crear el archivo PXE'], Response::HTTP_INTERNAL_SERVER_ERROR);
}
$httpCode = '200';
$this->logger->info(json_encode([
'severity' => 'INFO',
@ -1631,10 +1650,14 @@ public function createBootFile(Request $request): JsonResponse
'success' => 'PXE file created successfully',
'message' => $pxeContent
], Response::HTTP_OK);
// Retornar la plantilla creada en el formato solicitado
return new JsonResponse([
'success' => 'PXE file created successfully',
'message' => $pxeContent
], Response::HTTP_OK);
}
function validateAndFormatMac($mac)
{
@ -1657,6 +1680,9 @@ function validateAndFormatMac($mac)
}
/**
* @Route("/ogboot/v1/pxes/{mac}", name="ogboot_delete_boot_file", methods={"DELETE"})
* @OA\Delete(