refs #868 #864 #866 #949 #943 #870 Return hard info of disk usage, adds id to get default oglive, return error code in oglivecli, control error code in service and controller endpoints, updates swagger documentation in some oglives endpoints, adds new errores 400 and 404 in oglivecli functions and control errores in getOglives, getOgliveDefault and uninstall. Dont allow to uninstall default oglive

pull/5/head
Luis Gerardo Romero Garcia 2024-10-15 12:51:55 +00:00
parent 3b26f78a2d
commit fedd164b02
3 changed files with 202 additions and 134 deletions

View File

@ -436,37 +436,57 @@ function install() {
# Uninstall an ogLive client.
function uninstall() {
local CHECKSUM DIR
local CHECKSUM DIR DEFAULT_OGLIVE_DIR DEFAULT_CHECKSUM
# Validar que se proporcionó exactamente un argumento (el checksum)
[ $# -ne 1 ] && { echo "{\"error\": \"usage: uninstall {checksum}\"}"; exit 1; }
[ $# -ne 1 ] && { echo "{\"error\": \"BAD_REQUEST\", \"message\": \"usage: uninstall {checksum}\"}"; exit 400; }
CHECKSUM=$1
# Verificar acceso a los directorios necesarios
[ ! -w $TFTPDIR ] && { echo "{\"error\": \"access installation directory.\"}"; exit 1; }
[ ! -w $TFTPDIR ] && { echo "{\"error\": \"SERVER_ERROR\", \"message\": \"access installation directory.\"}"; exit 500; }
# Verificar el enlace simbólico del ogLive por defecto
if [ -L "$TFTPDIR/ogLive" ]; then
DEFAULT_OGLIVE_DIR=$(readlink -f "$TFTPDIR/ogLive")
DEFAULT_CHECKSUM_FILE="$DEFAULT_OGLIVE_DIR/ogclient.sqfs.sum"
# Verificar si el archivo de checksum del ogLive por defecto existe
if [ -f "$DEFAULT_CHECKSUM_FILE" ]; then
DEFAULT_CHECKSUM=$(cat "$DEFAULT_CHECKSUM_FILE" | cut -d ' ' -f 1)
# Comparar el checksum proporcionado con el del ogLive por defecto
if [ "$CHECKSUM" == "$DEFAULT_CHECKSUM" ]; then
echo "{\"error\": \"FORBIDDEN\", \"message\": \"Cannot uninstall the default ogLive client.\"}"
exit 403
fi
fi
fi
# Buscar el directorio correspondiente al checksum
DIR=$(find $TFTPDIR -type f -name 'ogclient.sqfs.sum' -exec grep -l "$CHECKSUM" {} \; | xargs -I{} dirname {})
# Si no se encuentra el directorio, devolver error
# Si no se encuentra el directorio, devolver error 404
if [ -z "$DIR" ]; then
echo "{\"error\": \"ogLive client with checksum $CHECKSUM not found.\"}"
exit 1
echo "{\"error\": \"NOT_FOUND\", \"message\": \"ogLive client with checksum $CHECKSUM not found.\"}"
exit 404
fi
# Eliminar archivos y directorio, redirigiendo la salida a /dev/null
rm -vfr $DIR > /dev/null 2>&1
# Comprobar si la eliminación tuvo éxito
# Comprobar si la eliminación tuvo éxito, si no, devolver error 500
if [ -d "$DIR" ]; then
echo "{\"error\": \"Failed to uninstall ogLive client in $DIR.\"}"
exit 1
echo "{\"error\": \"SERVER_ERROR\", \"message\": \"Failed to uninstall ogLive client in $DIR.\"}"
exit 500
fi
# Devolver mensaje de éxito
echo "{\"message\": \"ogLive client uninstalled successfully.\", \"details\": \"Removed directory: $DIR\"}"
exit 200
}
# Get information about the default ogLive client.
function get_default() {
local DEFAULT_LINK="$TFTPDIR/$DEFOGLIVE"
@ -562,15 +582,29 @@ function set_default() {
# Get disk usage information
function disk_usage() {
DISK_INFO=$(df -h / | awk 'NR==2{print "{\"total\":\""$2"\", \"used\":\""$3"\", \"available\":\""$4"\", \"percentage\":\""$5"\"}"}')
DISK_INFO=$(df / | awk 'NR==2{print "{\"total\":\""$2"\", \"used\":\""$3"\", \"available\":\""$4"\", \"percentage\":\""$5"\"}"}')
echo $DISK_INFO
}
# Function to list installed ogLive clients and the default ogLive client
function list_installed_oglives() {
local INST NF DEF
INST=$(find $TFTPDIR/ -type d -name "$DEFOGLIVE-*" -a ! -name "*.old" -printf "%f\n" | sort)
# Verificar si el directorio TFTPDIR es accesible
if [ ! -d "$TFTPDIR" ]; then
echo "{\"error\": \"SERVER_ERROR\", \"message\": \"TFTP directory not found or not accessible.\"}"
exit 500
fi
# Buscar directorios de ogLive instalados
INST=$(find "$TFTPDIR/" -type d -name "$DEFOGLIVE-*" -a ! -name "*.old" -printf "%f\n" 2>/dev/null | sort)
if [ -z "$INST" ]; then
echo "{\"error\": \"NOT_FOUND\", \"message\": \"No installed ogLive clients found.\"}"
exit 404
fi
local installed_ogLives=()
local oglive_count=0
for i in $INST; do
local OGLIVEDIR="$TFTPDIR/$i"
@ -589,13 +623,16 @@ function list_installed_oglives() {
OGLIVEARCH=$(jq -r '.OGLIVEARCH' "$OGLIVEJSON")
OGLIVEREV=$(jq -r '.OGLIVEREV' "$OGLIVEJSON")
else
echo "{\"error\": \"oglive_info.json not found in $OGLIVEDIR.\"}"
continue
echo "{\"error\": \"NOT_FOUND\", \"message\": \"oglive_info.json not found in $OGLIVEDIR.\"}"
continue # Continuar con el siguiente ogLive en lugar de detener el proceso
fi
# Obtener el checksum del archivo ogclient.sqfs.sum
if [ -f "$CHECKSUM_FILE" ]; then
CHECKSUM=$(cat "$CHECKSUM_FILE" | cut -d ' ' -f 1)
else
echo "{\"error\": \"NOT_FOUND\", \"message\": \"Checksum file not found in $OGLIVEDIR.\"}"
continue
fi
# Crear el JSON con los datos del ogLive
@ -609,12 +646,19 @@ function list_installed_oglives() {
'{id: $id, distribution: $dist, kernel: $krnl, architecture: $arch, revision: $rev, directory: $dir}')
installed_ogLives+=("$DATA")
oglive_count=$((oglive_count + 1))
# Verificar si es el ogLive por defecto
[ -n "$(stat -c "%N" $TFTPDIR/$DEFOGLIVE | awk '$3~/'$i'/ {print}')" ] && DEF="$i"
[ -n "$(stat -c "%N" "$TFTPDIR/$DEFOGLIVE" | awk '$3~/'$i'/ {print}')" ] && DEF="$i"
done
local default_oglive=$(basename $(readlink -f $TFTPDIR/$DEFOGLIVE))
# Verificar si se encontraron ogLives
if [ "$oglive_count" -eq 0 ]; then
echo "{\"error\": \"NOT_FOUND\", \"message\": \"No valid ogLive clients found.\"}"
exit 404
fi
local default_oglive=$(basename "$(readlink -f "$TFTPDIR/$DEFOGLIVE")")
# Crear el JSON final con la lista de ogLives instalados y el ogLive por defecto
jq -n \
@ -624,6 +668,7 @@ function list_installed_oglives() {
default_oglive: $default_oglive,
installed_ogLives: $installed_ogLives
}'
exit 0
}
# Get information about an installed ogLive client.
@ -726,3 +771,4 @@ esac
exit $?

View File

@ -125,12 +125,10 @@ public function getStatus(): Response
* response=200,
* description="Isos retrieved successfully",
* @OA\JsonContent(
* type="array",
* @OA\Items(type="object",
* @OA\Property(property="id", type="integer"),
* @OA\Property(property="filename", type="string"),
* @OA\Property(property="installed", type="boolean"),
* @OA\Property(property="compatible", type="boolean")
* type="object",
* @OA\Property(property="success", type="string"),
* @OA\Property(property="message", type="array",
* @OA\Items(ref="#/components/schemas/DownloadOgLive")
* )
* )
* ),
@ -140,22 +138,32 @@ public function getStatus(): Response
* @OA\JsonContent(
* type="object",
* @OA\Property(property="error", type="string"),
* @OA\Property(property="details", type="string")
* @OA\Property(property="message", type="string")
* )
* )
* )
*/
public function getDownloadMenu(): Response
{
// Llamar al servicio para obtener las ISOs disponibles
$downloadsOutput = $this->curlRequestService->callOgLive("download");
if (is_array($downloadsOutput) && isset($downloadsOutput['success']) && $downloadsOutput['success'] === false) {
return new JsonResponse(['error' => 'Failed to retrieve downloads', 'details' => $downloadsOutput['error']], Response::HTTP_INTERNAL_SERVER_ERROR);
// Verificar si hubo un error en la respuesta
if (is_array($downloadsOutput) && isset($downloadsOutput['error'])) {
return new JsonResponse(
['error' => 'FAILED_TO_RETRIEVE_ISOS', 'message' => $downloadsOutput['message']],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
return new JsonResponse($downloadsOutput, Response::HTTP_OK);
}
// Formatear la respuesta según el nuevo formato
$response = [
'success' => 'ISOs retrieved successfully',
'message' => $downloadsOutput['output']['downloads'] // Aquí la estructura ya está en el formato correcto de la salida del shell script
];
return new JsonResponse($response, Response::HTTP_OK);
}
/**
* @Route("/ogboot/v1/oglives", name="getOglives", methods={"GET"})
* @OA\Get(
@ -163,45 +171,90 @@ public function getDownloadMenu(): Response
* summary="Get list of all installed ogLive clients",
* @OA\Response(
* response=200,
* description="Successful operation",
* description="List of installed ogLive clients retrieved successfully",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="default_oglive", type="string", description="Default ogLive client"),
* @OA\Property(
* property="installed_ogLives",
* type="array",
* @OA\Items(
* type="object",
* @OA\Property(property="id", type="string", description="Unique identifier for the ogLive client"),
* @OA\Property(property="filename", type="string", description="Filename of the ogLive client"),
* @OA\Property(property="distribution", type="string", description="Distribution name of the installed ogLive client"),
* @OA\Property(property="kernel", type="string", description="Kernel version of the installed ogLive client"),
* @OA\Property(property="architecture", type="string", description="Architecture of the installed ogLive client"),
* @OA\Property(property="revision", type="string", description="Revision of the installed ogLive client"),
* @OA\Property(property="directory", type="string", description="Directory name of the installed ogLive client"),
* @OA\Property(property="iso", type="string", description="ISO file name of the installed ogLive client")
* @OA\Property(property="success", type="string", example="ogLive clients retrieved successfully"),
* @OA\Property(property="message", type="object",
* @OA\Property(property="default_oglive", type="string", description="The default ogLive client"),
* @OA\Property(property="installed_ogLives", type="array",
* @OA\Items(ref="#/components/schemas/OgLive")
* )
* )
* )
* ),
* @OA\Response(
* response=404,
* description="No ogLive clients found"
* description="No ogLive clients found",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="error", type="string", example="NOT_FOUND"),
* @OA\Property(property="message", type="string", example="No ogLive clients found.")
* )
* ),
* @OA\Response(
* response=500,
* description="Server or unknown error occurred",
* @OA\JsonContent(
* oneOf={
* @OA\Schema(
* @OA\Property(property="error", type="string", example="SERVER_ERROR"),
* @OA\Property(property="message", type="string", example="Failed to retrieve ogLive clients due to server error.")
* ),
* @OA\Schema(
* @OA\Property(property="error", type="string", example="UNKNOWN_ERROR"),
* @OA\Property(property="message", type="string", example="An unknown error occurred.")
* )
* }
* )
* )
* )
*/
public function getOglives(): Response
{
// Llama al servicio que ejecuta el comando oglivecli y procesa la salida
$ogLiveConfigResult = $this->curlRequestService->callOgLive("list_installed_oglives");
// Llama al servicio que ejecuta el comando oglivecli y obtiene tanto el output como el código de salida
$response = $this->curlRequestService->callOgLive("list_installed_oglives");
$ogLiveConfigResult = $response['output'];
$exitCode = $response['exitCode'];
if (empty($ogLiveConfigResult) || !isset($ogLiveConfigResult['installed_ogLives'])) {
return new JsonResponse(['error' => 'No ogLive clients found'], Response::HTTP_NOT_FOUND);
// Manejo de errores basado en el código de salida
if ($exitCode === 404) {
return new JsonResponse(
['error' => 'NOT_FOUND', 'message' => 'No ogLive clients found.'],
Response::HTTP_NOT_FOUND
);
} elseif ($exitCode === 500) {
return new JsonResponse(
['error' => 'SERVER_ERROR', 'message' => 'Failed to retrieve ogLive clients due to server error.'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
} elseif ($exitCode !== 0) {
// Manejar otros posibles códigos de error no esperados
return new JsonResponse(
['error' => 'UNKNOWN_ERROR', 'message' => 'An unknown error occurred.'],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
return new JsonResponse($ogLiveConfigResult, Response::HTTP_OK);
// Verificar si la salida es válida
if (empty($ogLiveConfigResult) || !isset($ogLiveConfigResult['installed_ogLives'])) {
return new JsonResponse(
['error' => 'NOT_FOUND', 'message' => 'No ogLive clients found.'],
Response::HTTP_NOT_FOUND
);
}
// Formatear la respuesta final en caso de éxito
$response = [
'success' => 'ogLive clients retrieved successfully',
'message' => $ogLiveConfigResult // Incluye la estructura completa con default_oglive e installed_ogLives
];
return new JsonResponse($response, Response::HTTP_OK);
}
/**
* @Route("/ogboot/v1/oglives/default", name="getOgliveDefault", methods={"GET"})
* @OA\Get(
@ -212,36 +265,8 @@ public function getOglives(): Response
* description="Successful operation",
* @OA\JsonContent(
* type="object",
* @OA\Property(
* property="distribution",
* type="string",
* description="Distribution name of the default ogLive client"
* ),
* @OA\Property(
* property="kernel",
* type="string",
* description="Kernel version of the default ogLive client"
* ),
* @OA\Property(
* property="architecture",
* type="string",
* description="Architecture of the default ogLive client"
* ),
* @OA\Property(
* property="revision",
* type="string",
* description="Revision of the default ogLive client"
* ),
* @OA\Property(
* property="directory",
* type="string",
* description="Directory name of the default ogLive client"
* ),
* @OA\Property(
* property="iso",
* type="string",
* description="ISO file name of the default ogLive client"
* )
* @OA\Property(property="success", type="string", example="Se han obtenido la lista de oglives instalados correctamente"),
* @OA\Property(property="message", ref="#/components/schemas/OgLive")
* )
* ),
* @OA\Response(
@ -281,36 +306,8 @@ public function getOgliveDefault(Request $request): Response
* description="Successful operation",
* @OA\JsonContent(
* type="object",
* @OA\Property(
* property="distribution",
* type="string",
* description="Distribution name of the installed ogLive client"
* ),
* @OA\Property(
* property="kernel",
* type="string",
* description="Kernel version of the installed ogLive client"
* ),
* @OA\Property(
* property="architecture",
* type="string",
* description="Architecture of the installed ogLive client"
* ),
* @OA\Property(
* property="revision",
* type="string",
* description="Revision of the installed ogLive client"
* ),
* @OA\Property(
* property="directory",
* type="string",
* description="Directory name of the installed ogLive client"
* ),
* @OA\Property(
* property="iso",
* type="string",
* description="ISO file name of the installed ogLive client"
* )
* @OA\Property(property="success", type="string", example="Se han obtenido la lista de oglives instalados correctamente"),
* @OA\Property(property="message", ref="#/components/schemas/OgLive")
* )
* ),
* @OA\Response(
@ -332,10 +329,6 @@ public function getOglive(string $checksum): Response
/**
* @Route("/ogboot/v1/oglives/default", name="setOgliveDefault", methods={"PUT"})
* @OA\Put(
@ -486,8 +479,8 @@ public function setOgliveDefault(Request $request): Response
// Responder que la instalación se ha completado
return new JsonResponse([
'message' => 'ogLive client installation completed',
'details' => $installResult
'success' => 'ogLive client installation completed',
'message' => $installResult
], JsonResponse::HTTP_OK);
} catch (Exception $e) {
@ -565,32 +558,53 @@ public function uninstallOglive(string $checksum): Response
{
// Llamada al servicio para desinstalar el cliente ogLive
error_log("Calling curlRequestService with checksum: $checksum");
$result = $this->curlRequestService->callOgLive("uninstall " . escapeshellarg($checksum));
// Ejecutar el comando y capturar tanto el resultado como el código de salida
$response = $this->curlRequestService->callOgLive("uninstall " . escapeshellarg($checksum));
$result = $response['output'];
$exitCode = $response['exitCode'];
// Verificar la respuesta del servicio
// Verificar la respuesta del servicio según el código de salida
error_log("Service call result: " . print_r($result, true));
error_log("Exit code: " . $exitCode);
if (is_array($result) && isset($result['error'])) {
// Error encontrado en la respuesta
error_log("Error found in response: " . $result['error']);
return new JsonResponse(['error' => $result['error']], Response::HTTP_INTERNAL_SERVER_ERROR);
} elseif (is_array($result) && isset($result['message'])) {
// Respuesta exitosa
error_log("Success response: " . print_r($result, true));
if ($exitCode === 404) {
// ogLive client no encontrado
return new JsonResponse([
'error' => 'NOT_FOUND',
'message' => $result['message'] ?? 'ogLive client not found.'
], Response::HTTP_NOT_FOUND);
} elseif ($exitCode === 403) {
// Intento de desinstalar el ogLive por defecto
return new JsonResponse([
'error' => 'FORBIDDEN',
'message' => $result['message'] ?? 'Cannot uninstall the default ogLive client.'
], Response::HTTP_FORBIDDEN);
} elseif ($exitCode === 500) {
// Error interno del servidor
return new JsonResponse([
'error' => 'SERVER_ERROR',
'message' => $result['message'] ?? 'Failed to uninstall ogLive client.'
], Response::HTTP_INTERNAL_SERVER_ERROR);
} elseif ($exitCode === 200) {
// Desinstalación exitosa
return new JsonResponse([
'message' => $result['message'],
'details' => $result['details'] ?? ''
], Response::HTTP_OK);
} else {
// Manejar el caso en que no se recibió una respuesta válida del servicio
error_log("Failed to uninstall ogLive client, empty result from service");
return new JsonResponse(['error' => 'Failed to uninstall ogLive client'], Response::HTTP_INTERNAL_SERVER_ERROR);
// Manejar otros códigos de error no previstos
return new JsonResponse([
'error' => 'UNKNOWN_ERROR',
'message' => 'An unknown error occurred.'
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* @Route("/ogboot/v1/pxes", name="get_boot_files", methods={"GET"})
* @OA\Get(
@ -653,8 +667,7 @@ public function getBootFiles(): JsonResponse
* response=200,
* description="Successful operation",
* @OA\JsonContent(
* type="obj/opt/ogboot/var/log
* ect",
* type="object",
* @OA\Property(property="template_name", type="string", description="Template name", example="pxe"),
* @OA\Property(property="mac", type="string", description="MAC address", example="00:50:56:22:11:12"),
* @OA\Property(property="lang", type="string", description="Language", example="es_ES.UTF-8"),
@ -1170,3 +1183,4 @@ public function createTemplate(Request $request)
}

View File

@ -43,18 +43,26 @@ public function callOgLive($parameter)
$commandToRun = $ogLiveCliPath . ' ' . $action . ' ' . implode(' ', $cleanedArgs);
// Registrar el comando en syslog para depuración
syslog(LOG_INFO, 'command ' . $commandToRun);
// Ejecutar el comando, capturando la salida y el código de salida
$output = [];
$exitCode = null;
exec($commandToRun, $output, $exitCode); // Ejecuta el comando, captura la salida y el código de salida
// Ejecutar el comando
$output = shell_exec($commandToRun);
syslog(LOG_INFO, 'output ' . $output);
// Unir la salida en una sola cadena y registrar en syslog
$outputString = implode("\n", $output);
syslog(LOG_INFO, 'output ' . $outputString);
syslog(LOG_INFO, 'exitCode ' . $exitCode);
// Decodificar la salida JSON si es posible
$decodedOutput = json_decode($output, true);
return $decodedOutput;
$decodedOutput = json_decode($outputString, true);
error_log('Decoded Output: ' . print_r($decodedOutput, true));
return [
'output' => $decodedOutput, // Retorna la salida decodificada (JSON)
'exitCode' => $exitCode // Retorna el código de salida del comando
];
}
}