Compare commits
376 Commits
ipxe-study
...
main
|
|
@ -0,0 +1,47 @@
|
|||
# In all environments, the following files are loaded if they exist,
|
||||
# the latter taking precedence over the former:
|
||||
#
|
||||
# * .env contains default values for the environment variables needed by the app
|
||||
# * .env.local uncommitted file with local overrides
|
||||
# * .env.$APP_ENV committed environment-specific defaults
|
||||
# * .env.$APP_ENV.local uncommitted environment-specific overrides
|
||||
#
|
||||
# Real environment variables win over .env files.
|
||||
#
|
||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
||||
# https://symfony.com/doc/current/configuration/secrets.html
|
||||
#
|
||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
||||
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
APP_ENV=prod
|
||||
APP_SECRET=d423d1302b974417d415b10bcde25767
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
###> doctrine/doctrine-bundle ###
|
||||
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
|
||||
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
|
||||
#
|
||||
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
|
||||
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4"
|
||||
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=15&charset=utf8"
|
||||
###< doctrine/doctrine-bundle ###
|
||||
|
||||
###> symfony/messenger ###
|
||||
# Choose one of the transports below
|
||||
# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
|
||||
# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
|
||||
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
|
||||
###< symfony/messenger ###
|
||||
|
||||
###> symfony/mailer ###
|
||||
# MAILER_DSN=null://null
|
||||
###< symfony/mailer ###
|
||||
|
||||
### Opengnsys Variables
|
||||
#
|
||||
OGCORE_API_URL="https://127.0.0.1:8443"
|
||||
OGBOOT_IP="127.0.0.1"
|
||||
OGBOOT_PORT="8082"
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
**/*.swp
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
/.env.local
|
||||
/.env.local.php
|
||||
/.env.*.local
|
||||
/config/secrets/prod/prod.decrypt.private.php
|
||||
/public/bundles/
|
||||
/var/
|
||||
/vendor/
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
###> phpunit/phpunit ###
|
||||
/phpunit.xml
|
||||
.phpunit.result.cache
|
||||
###< phpunit/phpunit ###
|
||||
|
||||
###> symfony/phpunit-bridge ###
|
||||
.phpunit.result.cache
|
||||
/phpunit.xml
|
||||
###< symfony/phpunit-bridge ###
|
||||
### Debian packaging
|
||||
debian/ogboot
|
||||
debian/*.substvars
|
||||
debian/*.log
|
||||
debian/.debhelper/
|
||||
debian/files
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
# CHANGELOG
|
||||
|
||||
## [0.7.1] - 19/06/2025
|
||||
|
||||
### **Cambios principales**
|
||||
1. Añade scripts de grub y menu.lst para el arranque del Oglive por cache
|
||||
|
||||
## [0.7.0] - 19/06/2025
|
||||
|
||||
### **Cambios principales**
|
||||
1. No hay cambios, pasa el tag 0.5.12 a 0.6.0
|
||||
|
||||
## [0.6.0] - 25/02/2025
|
||||
|
||||
### **Cambios principales**
|
||||
1. No hay cambios, pasa el tag 0.5.12 a 0.6.0
|
||||
|
||||
## [0.5.12] - 25/02/2025
|
||||
|
||||
### **Cambios principales**
|
||||
1. Monta efivars al inicio del arranque del oglive
|
||||
2. Corrige un error en un awk a la hora de obtener entradas NVRAM
|
||||
3. Devuelve un array vacío cuando no hay oglives instalados
|
||||
4. Devuelve una excepción cuando se instala un Oglive ya instalado
|
||||
|
||||
## [0.5.11] - 06/02/2025
|
||||
|
||||
### **Cambios principales**
|
||||
1. Permite la lectura de otros usuarios en home `/opt/opengnsys`del usuario opengnsys
|
||||
|
||||
## [0.5.10] - 06/02/2025
|
||||
|
||||
### **Cambios principales**
|
||||
1. Cambia el home del usuario opengnsys como `/opt/opengnsys`
|
||||
|
||||
## [0.5.9] - 03/02/2025
|
||||
|
||||
### **Cambios principales**
|
||||
1. Añade puerto 8443 de ogcore al PostConf.lib
|
||||
|
||||
|
||||
## [0.5.8] - 13/01/2025
|
||||
|
||||
### **Cambios principales**
|
||||
1. Arregla bug que no añadía los parametros ogcore y oglog al crear los ficheros de arranque
|
||||
|
||||
## [0.5.7] - 13/01/2025
|
||||
|
||||
### **Cambios principales**
|
||||
1. Añade logs para todos los endpoints siguiendo un formato json preestablecido.
|
||||
2. Actualiza monolog.yaml para devolver logs al journal de la maquina.
|
||||
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.8.11] - 2024-09-11
|
||||
### Changed
|
||||
- Resuelve bug para que ejecute como sudo el comando cpio en el setsmbpass
|
||||
|
||||
## [0.8.10] - 2024-07-05
|
||||
### Changed
|
||||
- Añade oglive BIOS para el arranque de Windows al arrancarlo desde el ogbrowser
|
||||
- Elimina arranque MBR del menú de arranque
|
||||
|
||||
## [0.8.9] - 2024-06-30
|
||||
### Changed
|
||||
- Borra directorio samba de etc y modifica postint para que copie el fichero de configuración de la plantilla de samba
|
||||
|
||||
## [0.8.8] - 2024-06-27
|
||||
### Changed
|
||||
- Actualiza grub.exe para que soporte sistemas de particiones ext
|
||||
- Actualiza las plantillas de arranque de menu para bios para que use el nuevo grub.exe
|
||||
- Elimina la plantilla de bootmark obsoleta
|
||||
|
||||
## [0.8.7] - 2024-06-25
|
||||
### Changed
|
||||
- Elimina el parámetro de kernel ogdebug del controlador y se le añade a las plantillas de arranque de oglive
|
||||
|
||||
## [0.8.6] - 2024-06-24
|
||||
### Changed
|
||||
- Modifica la plantilla de arranque por disco y partición para no tener hardcodeado la partición EFI
|
||||
|
||||
## [0.8.5] - 2024-06-24
|
||||
### Changed
|
||||
- Comprueba si existe una etiqueta para asignar root cuando corresponda en la plantilla de arranque por disco y partición
|
||||
|
||||
## [0.8.4] - 2024-06-20
|
||||
### Changed
|
||||
- Corrige oglivecli para que desmonte los puntos de montaje ante cualquier fallo en el script de instalación de oglive
|
||||
|
||||
## [0.8.3] - 2024-06-20
|
||||
### Changed
|
||||
- Añade el cambio de la 0.8.2
|
||||
|
||||
## [0.8.2] - 2024-06-20
|
||||
### Changed
|
||||
- Corrige un bug en oglivecli que impide cambiar el propietario del oglive
|
||||
|
||||
## [0.8.1] - 2024-06-18
|
||||
### Changed
|
||||
- Añade nuevos modulos al grubx64.efi
|
||||
|
||||
## [0.8.0] - 2024-06-18
|
||||
### Changed
|
||||
- Actualiza a 0.8.0 para incluir los cambios de la versión 0.7.2
|
||||
|
||||
## [0.7.2] - 2024-06-05
|
||||
### Changed
|
||||
- Añade scripts de grub y menu.lst para el arranque por disco y partición
|
||||
- Añade plantilla ogliveadmin con permisos de administracion como parametro del kernel
|
||||
- Añade plantilla de menú para el arranque por disco y partición y caché
|
||||
|
||||
## [0.7.1] - 2024-05-19
|
||||
### Changed
|
||||
- Añade scripts de grub y menu.lst para el arranque del Oglive por cache
|
||||
|
||||
## [0.7.0] - 2024-03-26
|
||||
### Changed
|
||||
- Updated files location
|
||||
|
||||
## [0.6.3] - 2025-03-19
|
||||
### Changed
|
||||
- Jenkinsfile to upload debian packages
|
||||
|
||||
## [0.6.2] - 2025-03-19
|
||||
### Changed
|
||||
- Jenkinsfile to upload debian packages
|
||||
|
||||
## [0.6.1] - 2025-02-25
|
||||
|
||||
### Fixed
|
||||
- Arreglos menores
|
||||
|
||||
## [0.6.1] - 2025-02-25
|
||||
|
||||
### Fixed
|
||||
- Arreglos menores
|
||||
|
||||
## [0.6.0] - 2025-02-25
|
||||
|
||||
### Changed
|
||||
- No hay cambios en esta versión, se incrementa el tag de `0.5.12` a `0.6.0`.
|
||||
|
||||
## [0.5.12] - 2025-02-25
|
||||
|
||||
### Added
|
||||
- Monta `efivars` al inicio del arranque del `oglive`.
|
||||
|
||||
### Fixed
|
||||
- Corrige un error en un `awk` al obtener entradas NVRAM.
|
||||
- Devuelve un array vacío cuando no hay `oglives` instalados.
|
||||
- Devuelve una excepción cuando se intenta instalar un `Oglive` ya instalado.
|
||||
|
||||
## [0.5.11] - 2025-02-06
|
||||
|
||||
### Changed
|
||||
- Permite la lectura de otros usuarios en el home `/opt/opengnsys` del usuario `opengnsys`.
|
||||
|
||||
## [0.5.10] - 2025-02-06
|
||||
|
||||
### Changed
|
||||
- Cambia el home del usuario `opengnsys` a `/opt/opengnsys`.
|
||||
|
||||
## [0.5.9] - 2025-02-03
|
||||
|
||||
### Added
|
||||
- Añade el puerto `8443` de `ogcore` al `PostConf.lib`.
|
||||
|
||||
## [0.5.8] - 2025-01-13
|
||||
|
||||
### Fixed
|
||||
- Arregla un bug que no añadía los parámetros `ogcore` y `oglog` al crear los ficheros de arranque.
|
||||
|
||||
## [0.5.7] - 2025-01-13
|
||||
|
||||
### Added
|
||||
- Añade logs para todos los endpoints siguiendo un formato JSON preestablecido.
|
||||
|
||||
### Changed
|
||||
- Actualiza `monolog.yaml` para enviar logs al `journal` de la máquina.
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
@Library('jenkins-shared-library') _
|
||||
pipeline {
|
||||
agent {
|
||||
label 'jenkins-slave'
|
||||
}
|
||||
environment {
|
||||
DEBIAN_FRONTEND = 'noninteractive'
|
||||
DEFAULT_DEV_NAME = 'Opengnsys Team'
|
||||
DEFAULT_DEV_EMAIL = 'opengnsys@qindel.com'
|
||||
}
|
||||
options {
|
||||
skipDefaultCheckout()
|
||||
}
|
||||
parameters {
|
||||
string(name: 'DEV_NAME', defaultValue: '', description: 'Nombre del desarrollador')
|
||||
string(name: 'DEV_EMAIL', defaultValue: '', description: 'Email del desarrollador')
|
||||
}
|
||||
stages {
|
||||
stage('Prepare Workspace') {
|
||||
steps {
|
||||
script {
|
||||
env.BUILD_DIR = "${WORKSPACE}/ogboot"
|
||||
sh "mkdir -p ${env.BUILD_DIR}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
dir("${env.BUILD_DIR}") {
|
||||
checkout scm
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Generate Changelog') {
|
||||
when {
|
||||
expression {
|
||||
return env.TAG_NAME != null
|
||||
}
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
def devName = params.DEV_NAME ? params.DEV_NAME : env.DEFAULT_DEV_NAME
|
||||
def devEmail = params.DEV_EMAIL ? params.DEV_EMAIL : env.DEFAULT_DEV_EMAIL
|
||||
|
||||
generateDebianChangelog(env.BUILD_DIR, devName, devEmail)
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Generate Changelog (Nightly)'){
|
||||
when {
|
||||
branch 'main'
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
def devName = params.DEV_NAME ? params.DEV_NAME : env.DEFAULT_DEV_NAME
|
||||
def devEmail = params.DEV_EMAIL ? params.DEV_EMAIL : env.DEFAULT_DEV_EMAIL
|
||||
generateDebianChangelog(env.BUILD_DIR, devName, devEmail,'nightly')
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
steps {
|
||||
script {
|
||||
construirPaquete(env.BUILD_DIR, "../artifacts", "172.17.8.68", "/var/tmp/opengnsys/debian-repo/ogboot")
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ('Publish to Debian Repository') {
|
||||
when {
|
||||
expression {
|
||||
return env.TAG_NAME != null
|
||||
}
|
||||
}
|
||||
agent { label 'debian-repo' }
|
||||
steps {
|
||||
script {
|
||||
// Construir el patrón de versión esperado en el nombre del paquete
|
||||
def versionPattern = "${env.TAG_NAME}-${env.BUILD_NUMBER}"
|
||||
publicarEnAptly('/var/tmp/opengnsys/debian-repo/ogboot', 'opengnsys-devel', versionPattern)
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ('Publish to Debian Repository (Nightly)') {
|
||||
when {
|
||||
branch 'main'
|
||||
}
|
||||
agent { label 'debian-repo' }
|
||||
steps {
|
||||
script {
|
||||
// Construir el patrón de versión esperado en el nombre del paquete
|
||||
def versionPattern = "-${env.BUILD_NUMBER}~nightly"
|
||||
publicarEnAptly('/var/tmp/opengnsys/debian-repo/ogboot', 'nightly', versionPattern)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
success {
|
||||
script {
|
||||
// Solo lanzar cuando el build sea exitoso y en la rama main
|
||||
if (env.BRANCH_NAME == 'main') {
|
||||
build job: 'Aptly publish nightly repository',
|
||||
wait: false,
|
||||
parameters: [
|
||||
string(name: 'TRIGGERED_BY', value: "${env.JOB_NAME}-${env.BUILD_NUMBER}")
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
always {
|
||||
notifyBuildStatus('opengnsys@qindel.com')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# In all environments, the following files are loaded if they exist,
|
||||
# the latter taking precedence over the former:
|
||||
#
|
||||
# * .env contains default values for the environment variables needed by the app
|
||||
# * .env.local uncommitted file with local overrides
|
||||
# * .env.$APP_ENV committed environment-specific defaults
|
||||
# * .env.$APP_ENV.local uncommitted environment-specific overrides
|
||||
#
|
||||
# Real environment variables win over .env files.
|
||||
#
|
||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
||||
# https://symfony.com/doc/current/configuration/secrets.html
|
||||
#
|
||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
||||
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
APP_ENV=dev
|
||||
APP_SECRET=d423d1302b974417d415b10bcde25767
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
###> doctrine/doctrine-bundle ###
|
||||
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
|
||||
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
|
||||
#
|
||||
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
|
||||
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4"
|
||||
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=15&charset=utf8"
|
||||
###< doctrine/doctrine-bundle ###
|
||||
|
||||
###> symfony/messenger ###
|
||||
# Choose one of the transports below
|
||||
# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
|
||||
# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
|
||||
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
|
||||
###< symfony/messenger ###
|
||||
|
||||
###> symfony/mailer ###
|
||||
# MAILER_DSN=null://null
|
||||
###< symfony/mailer ###
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
use App\Kernel;
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||
|
||||
if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
|
||||
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
|
||||
}
|
||||
|
||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
||||
|
||||
return function (array $context) {
|
||||
$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||
|
||||
return new Application($kernel);
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
if (!ini_get('date.timezone')) {
|
||||
ini_set('date.timezone', 'UTC');
|
||||
}
|
||||
|
||||
if (is_file(dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit')) {
|
||||
if (PHP_VERSION_ID >= 80000) {
|
||||
require dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit';
|
||||
} else {
|
||||
define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php');
|
||||
require PHPUNIT_COMPOSER_INSTALL;
|
||||
PHPUnit\TextUI\Command::main();
|
||||
}
|
||||
} else {
|
||||
if (!is_file(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) {
|
||||
echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php';
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
{
|
||||
"type": "project",
|
||||
"license": "proprietary",
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true,
|
||||
"require": {
|
||||
"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": "^1.13",
|
||||
"symfony/asset": "5.*",
|
||||
"symfony/console": "5.*",
|
||||
"symfony/doctrine-messenger": "5.*",
|
||||
"symfony/dotenv": "5.*",
|
||||
"symfony/expression-language": "5.*",
|
||||
"symfony/flex": "^1.17",
|
||||
"symfony/form": "5.*",
|
||||
"symfony/framework-bundle": "5.*",
|
||||
"symfony/http-client": "5.*",
|
||||
"symfony/intl": "5.*",
|
||||
"symfony/mailer": "5.*",
|
||||
"symfony/mime": "5.*",
|
||||
"symfony/monolog-bundle": "^3.0",
|
||||
"symfony/notifier": "5.*",
|
||||
"symfony/process": "5.*",
|
||||
"symfony/property-access": "5.*",
|
||||
"symfony/property-info": "5.*",
|
||||
"symfony/runtime": "5.*",
|
||||
"symfony/security-bundle": "5.*",
|
||||
"symfony/serializer": "5.*",
|
||||
"symfony/string": "5.*",
|
||||
"symfony/translation": "5.*",
|
||||
"symfony/twig-bundle": "5.*",
|
||||
"symfony/validator": "5.*",
|
||||
"symfony/web-link": "5.*",
|
||||
"symfony/yaml": "5.*",
|
||||
"twig/extra-bundle": "^2.12|^3.0",
|
||||
"twig/twig": "^2.12|^3.0",
|
||||
"zircote/swagger-php": "^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5",
|
||||
"symfony/browser-kit": "5.*",
|
||||
"symfony/css-selector": "5.*",
|
||||
"symfony/debug-bundle": "5.*",
|
||||
"symfony/maker-bundle": "^1.0",
|
||||
"symfony/phpunit-bridge": "^5.0",
|
||||
"symfony/stopwatch": "5.*",
|
||||
"symfony/web-profiler-bundle": "5.*"
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "8.1"
|
||||
},
|
||||
"allow-plugins": {
|
||||
"composer/package-versions-deprecated": true,
|
||||
"symfony/flex": true,
|
||||
"symfony/runtime": true
|
||||
},
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": {
|
||||
"*": "dist"
|
||||
},
|
||||
"sort-packages": true
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"App\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"replace": {
|
||||
"symfony/polyfill-ctype": "*",
|
||||
"symfony/polyfill-iconv": "*",
|
||||
"symfony/polyfill-php72": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"auto-scripts": {
|
||||
"cache:clear": "symfony-cmd",
|
||||
"assets:install %PUBLIC_DIR%": "symfony-cmd"
|
||||
},
|
||||
"post-install-cmd": [
|
||||
"@auto-scripts"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@auto-scripts"
|
||||
]
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/symfony": "*"
|
||||
},
|
||||
"extra": {
|
||||
"symfony": {
|
||||
"allow-contrib": false,
|
||||
"require": "5.*"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
||||
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
|
||||
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
|
||||
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true],
|
||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
||||
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
|
||||
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
||||
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
||||
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
|
||||
App\OgBootBundle\OgBootBundle::class => ['all' => true],
|
||||
Nelmio\ApiDocBundle\NelmioApiDocBundle::class => ['all' => true],
|
||||
];
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
framework:
|
||||
cache:
|
||||
# Unique name of your app: used to compute stable namespaces for cache keys.
|
||||
#prefix_seed: your_vendor_name/app_name
|
||||
|
||||
# The "app" cache stores to the filesystem by default.
|
||||
# The data in this cache should persist between deploys.
|
||||
# Other options include:
|
||||
|
||||
# Redis
|
||||
#app: cache.adapter.redis
|
||||
#default_redis_provider: redis://localhost
|
||||
|
||||
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
|
||||
#app: cache.adapter.apcu
|
||||
|
||||
# Namespaced pools use the above "app" backend by default
|
||||
#pools:
|
||||
#my.dedicated.cache: null
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
when@dev:
|
||||
debug:
|
||||
# Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
|
||||
# See the "server:dump" command to start a new server.
|
||||
dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
doctrine:
|
||||
dbal:
|
||||
url: '%env(resolve:DATABASE_URL)%'
|
||||
|
||||
# IMPORTANT: You MUST configure your server version,
|
||||
# either here or in the DATABASE_URL env var (see .env file)
|
||||
#server_version: '16'
|
||||
use_savepoints: true
|
||||
orm:
|
||||
auto_generate_proxy_classes: true
|
||||
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
|
||||
auto_mapping: true
|
||||
mappings:
|
||||
App:
|
||||
is_bundle: false
|
||||
dir: '%kernel.project_dir%/src/Entity'
|
||||
prefix: 'App\Entity'
|
||||
alias: App
|
||||
|
||||
when@test:
|
||||
doctrine:
|
||||
dbal:
|
||||
# "TEST_TOKEN" is typically set by ParaTest
|
||||
dbname_suffix: '_test%env(default::TEST_TOKEN)%'
|
||||
|
||||
when@prod:
|
||||
doctrine:
|
||||
orm:
|
||||
auto_generate_proxy_classes: false
|
||||
proxy_dir: '%kernel.build_dir%/doctrine/orm/Proxies'
|
||||
query_cache_driver:
|
||||
type: pool
|
||||
pool: doctrine.system_cache_pool
|
||||
result_cache_driver:
|
||||
type: pool
|
||||
pool: doctrine.result_cache_pool
|
||||
|
||||
framework:
|
||||
cache:
|
||||
pools:
|
||||
doctrine.result_cache_pool:
|
||||
adapter: cache.app
|
||||
doctrine.system_cache_pool:
|
||||
adapter: cache.system
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
doctrine_migrations:
|
||||
migrations_paths:
|
||||
# namespace is arbitrary but should be different from App\Migrations
|
||||
# as migrations classes should NOT be autoloaded
|
||||
'DoctrineMigrations': '%kernel.project_dir%/migrations'
|
||||
enable_profiler: false
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# see https://symfony.com/doc/current/reference/configuration/framework.html
|
||||
framework:
|
||||
secret: '%env(APP_SECRET)%'
|
||||
#csrf_protection: true
|
||||
http_method_override: false
|
||||
|
||||
# Enables session support. Note that the session will ONLY be started if you read or write from it.
|
||||
# Remove or comment this section to explicitly disable session support.
|
||||
session:
|
||||
handler_id: null
|
||||
cookie_secure: auto
|
||||
cookie_samesite: lax
|
||||
storage_factory_id: session.storage.factory.native
|
||||
|
||||
#esi: true
|
||||
#fragments: true
|
||||
php_errors:
|
||||
log: true
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
test: true
|
||||
session:
|
||||
storage_factory_id: session.storage.factory.mock_file
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
framework:
|
||||
mailer:
|
||||
dsn: '%env(MAILER_DSN)%'
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
framework:
|
||||
messenger:
|
||||
# reset services after consuming messages
|
||||
reset_on_message: true
|
||||
|
||||
# Uncomment this (and the failed transport below) to send failed messages to this transport for later handling.
|
||||
# failure_transport: failed
|
||||
|
||||
transports:
|
||||
# https://symfony.com/doc/current/messenger.html#transport-configuration
|
||||
# async: '%env(MESSENGER_TRANSPORT_DSN)%'
|
||||
# failed: 'doctrine://default?queue_name=failed'
|
||||
# sync: 'sync://'
|
||||
|
||||
routing:
|
||||
# Route your messages to the transports
|
||||
# 'App\Message\YourMessage': async
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
monolog:
|
||||
channels:
|
||||
- deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists
|
||||
|
||||
when@dev:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
level: debug
|
||||
channels: ["!event"]
|
||||
# uncomment to get logging in your browser
|
||||
# you may have to allow bigger header sizes in your Web server configuration
|
||||
#firephp:
|
||||
# type: firephp
|
||||
# level: info
|
||||
#chromephp:
|
||||
# type: chromephp
|
||||
# level: info
|
||||
syslog:
|
||||
type: syslog
|
||||
ident: "ogboot" # Puedes dar un nombre de identificador personalizado
|
||||
level: info
|
||||
channels: ["!event"]
|
||||
console:
|
||||
type: console
|
||||
process_psr_3_messages: false
|
||||
channels: ["!event", "!doctrine", "!console"]
|
||||
|
||||
when@test:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: fingers_crossed
|
||||
action_level: error
|
||||
handler: nested
|
||||
excluded_http_codes: [404, 405]
|
||||
channels: ["!event"]
|
||||
nested:
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
level: debug
|
||||
|
||||
when@prod:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: fingers_crossed
|
||||
action_level: error
|
||||
handler: nested
|
||||
excluded_http_codes: [404, 405]
|
||||
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
|
||||
nested:
|
||||
type: stream
|
||||
path: php://stderr
|
||||
level: debug
|
||||
formatter: monolog.formatter.json
|
||||
console:
|
||||
type: console
|
||||
process_psr_3_messages: false
|
||||
channels: ["!event", "!doctrine"]
|
||||
deprecation:
|
||||
type: stream
|
||||
channels: [deprecation]
|
||||
path: php://stderr
|
||||
formatter: monolog.formatter.json
|
||||
syslog:
|
||||
type: syslog
|
||||
ident: "ogboot" # Puedes dar un nombre de identificador personalizado
|
||||
level: info
|
||||
channels: ["!event"]
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
nelmio_api_doc:
|
||||
documentation:
|
||||
info:
|
||||
title: OgBoot API
|
||||
description: OgBoot API documentation
|
||||
version: 1.0.0
|
||||
components:
|
||||
schemas:
|
||||
OgLive:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Unique identifier for the ogLive client (checksum)
|
||||
example: "6153d21e7bd7f2486c027c5b9b3b93b6"
|
||||
distribution:
|
||||
type: string
|
||||
description: Distribution name of the ogLive client
|
||||
example: "focal"
|
||||
kernel:
|
||||
type: string
|
||||
description: Kernel version of the ogLive client
|
||||
example: "5.13.0-27-beta"
|
||||
architecture:
|
||||
type: string
|
||||
description: Architecture of the ogLive client
|
||||
example: "amd64"
|
||||
revision:
|
||||
type: string
|
||||
description: Revision of the ogLive client
|
||||
example: "r20210706"
|
||||
directory:
|
||||
type: string
|
||||
description: Directory path where the ogLive client is stored
|
||||
example: "/opt/ogboot/tftpboot//ogLive-5.13.0-r20210706"
|
||||
DownloadOgLive:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Unique identifier for the ogLive client
|
||||
example: "1"
|
||||
filename:
|
||||
type: string
|
||||
description: Filename of the ogLive client
|
||||
example: "oglive-ubuntu-20.04.iso"
|
||||
installed:
|
||||
type: boolean
|
||||
description: Whether the client is installed
|
||||
example: true
|
||||
compatible:
|
||||
type: boolean
|
||||
description: Whether the client is compatible
|
||||
example: true
|
||||
|
||||
|
||||
areas: # to filter documented areas
|
||||
path_patterns:
|
||||
- ^/ogboot/ # Accepts routes under /api except /api/doc
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
framework:
|
||||
notifier:
|
||||
chatter_transports:
|
||||
texter_transports:
|
||||
channel_policy:
|
||||
# use chat/slack, chat/telegram, sms/twilio or sms/nexmo
|
||||
urgent: ['email']
|
||||
high: ['email']
|
||||
medium: ['email']
|
||||
low: ['email']
|
||||
admin_recipients:
|
||||
- { email: admin@example.com }
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
framework:
|
||||
router:
|
||||
utf8: true
|
||||
|
||||
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
|
||||
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
||||
#default_uri: http://localhost
|
||||
|
||||
when@prod:
|
||||
framework:
|
||||
router:
|
||||
strict_requirements: null
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
security:
|
||||
enable_authenticator_manager: true
|
||||
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
|
||||
password_hashers:
|
||||
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
|
||||
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
|
||||
providers:
|
||||
users_in_memory: { memory: null }
|
||||
firewalls:
|
||||
dev:
|
||||
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
||||
security: false
|
||||
main:
|
||||
lazy: true
|
||||
provider: users_in_memory
|
||||
|
||||
# activate different ways to authenticate
|
||||
# https://symfony.com/doc/current/security.html#the-firewall
|
||||
|
||||
# https://symfony.com/doc/current/security/impersonating_user.html
|
||||
# switch_user: true
|
||||
|
||||
# Easy way to control access for large sections of your site
|
||||
# Note: Only the *first* access control that matches will be used
|
||||
access_control:
|
||||
# - { path: ^/admin, roles: ROLE_ADMIN }
|
||||
# - { path: ^/profile, roles: ROLE_USER }
|
||||
|
||||
when@test:
|
||||
security:
|
||||
password_hashers:
|
||||
# By default, password hashers are resource intensive and take time. This is
|
||||
# important to generate secure password hashes. In tests however, secure hashes
|
||||
# are not important, waste resources and increase test times. The following
|
||||
# reduces the work factor to the lowest possible values.
|
||||
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
|
||||
algorithm: auto
|
||||
cost: 4 # Lowest possible value for bcrypt
|
||||
time_cost: 3 # Lowest possible value for argon
|
||||
memory_cost: 10 # Lowest possible value for argon
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
framework:
|
||||
default_locale: en
|
||||
translator:
|
||||
default_path: '%kernel.project_dir%/translations'
|
||||
fallbacks:
|
||||
- en
|
||||
providers:
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
twig:
|
||||
default_path: '%kernel.project_dir%/templates'
|
||||
|
||||
when@test:
|
||||
twig:
|
||||
strict_variables: true
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
framework:
|
||||
validation:
|
||||
email_validation_mode: html5
|
||||
|
||||
# Enables validator auto-mapping support.
|
||||
# For instance, basic validation constraints will be inferred from Doctrine's metadata.
|
||||
#auto_mapping:
|
||||
# App\Entity\: []
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
validation:
|
||||
not_compromised_password: false
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
when@dev:
|
||||
web_profiler:
|
||||
toolbar: true
|
||||
intercept_redirects: false
|
||||
|
||||
framework:
|
||||
profiler: { only_exceptions: false }
|
||||
|
||||
when@test:
|
||||
web_profiler:
|
||||
toolbar: false
|
||||
intercept_redirects: false
|
||||
|
||||
framework:
|
||||
profiler: { collect: false }
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
|
||||
require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#index:
|
||||
# path: /
|
||||
# controller: App\Controller\DefaultController::index
|
||||
app.swagger_ui:
|
||||
path: /ogboot/api/doc
|
||||
methods: GET
|
||||
defaults: { _controller: nelmio_api_doc.controller.swagger_ui }
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
controllers:
|
||||
resource: ../../src/OgBootBundle/Controller/
|
||||
type: annotation
|
||||
kernel:
|
||||
resource: ../../src/Kernel.php
|
||||
type: annotation
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
when@dev:
|
||||
_errors:
|
||||
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
|
||||
prefix: /_error
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
when@dev:
|
||||
web_profiler_wdt:
|
||||
resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
|
||||
prefix: /_wdt
|
||||
|
||||
web_profiler_profiler:
|
||||
resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
|
||||
prefix: /_profiler
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# This file is the entry point to configure your own services.
|
||||
# Files in the packages/ subdirectory configure your dependencies.
|
||||
|
||||
# Put parameters here that don't need to change on each machine where the app is deployed
|
||||
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
||||
parameters:
|
||||
tftpboot_dir: '%kernel.project_dir%/../tftpboot'
|
||||
services:
|
||||
# default configuration for services in *this* file
|
||||
_defaults:
|
||||
autowire: true # Automatically injects dependencies in your services.
|
||||
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
||||
bind:
|
||||
$ogCoreApiUrl: '%env(OGCORE_API_URL)%'
|
||||
$ogBootIP: '%env(OGBOOT_IP)%'
|
||||
$ogBootPort: '%env(OGBOOT_PORT)%'
|
||||
|
||||
# makes classes in src/ available to be used as services
|
||||
# this creates a service per class whose id is the fully-qualified class name
|
||||
App\:
|
||||
resource: '../src/'
|
||||
exclude:
|
||||
- '../src/DependencyInjection/'
|
||||
- '../src/Entity/'
|
||||
- '../src/Kernel.php'
|
||||
|
||||
# add more service definitions when explicit configuration is needed
|
||||
# please note that last definitions always *replace* previous ones
|
||||
App\OgBootBundle\Controller\:
|
||||
resource: '../src/OgBootBundle/Controller'
|
||||
tags: ['controller.service_arguments']
|
||||
# Register the OgLiveInstallCommand explicitly to ensure it's detected
|
||||
App\OgBootBundle\Command\OgLiveInstallCommand:
|
||||
tags: ['console.command']
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
use App\Kernel;
|
||||
|
||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
||||
|
||||
return function (array $context) {
|
||||
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||
};
|
||||
Binary file not shown.
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
|
||||
|
||||
class Kernel extends BaseKernel
|
||||
{
|
||||
use MicroKernelTrait;
|
||||
}
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
|
||||
namespace App\OgBootBundle\Command;
|
||||
|
||||
use App\OgBootBundle\Service\CurlRequestService;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Exception;
|
||||
|
||||
class OgLiveInstallCommand extends Command
|
||||
{
|
||||
protected static $defaultName = 'oglive:install';
|
||||
private $curlRequestService;
|
||||
private $httpClient;
|
||||
private $logger;
|
||||
private $ogCoreApiUrl;
|
||||
|
||||
public function __construct(
|
||||
CurlRequestService $curlRequestService,
|
||||
HttpClientInterface $httpClient,
|
||||
LoggerInterface $logger,
|
||||
string $ogCoreApiUrl
|
||||
) {
|
||||
parent::__construct();
|
||||
$this->curlRequestService = $curlRequestService;
|
||||
$this->httpClient = HttpClient::create([
|
||||
'verify_peer' => false, // Ignorar la verificación del certificado SSL
|
||||
'verify_host' => false, // Ignorar la verificación del nombre del host
|
||||
]);
|
||||
$this->logger = $logger;
|
||||
$this->ogCoreApiUrl = $ogCoreApiUrl;
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setDescription('Instala un ogLive en segundo plano')
|
||||
->addArgument('isoUrl', InputArgument::REQUIRED, 'URL del ISO de ogLive')
|
||||
->addArgument('transactionId', InputArgument::REQUIRED, 'ID de la transacción');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
ini_set('memory_limit', '-1');
|
||||
ini_set('max_execution_time', '3000');
|
||||
|
||||
$isoUrl = $input->getArgument('isoUrl');
|
||||
$transactionId = $input->getArgument('transactionId');
|
||||
|
||||
// Log inicial
|
||||
$this->logger->info('Starting ogLive installation process.', [
|
||||
'transactionId' => $transactionId,
|
||||
'isoUrl' => $isoUrl,
|
||||
]);
|
||||
|
||||
try {
|
||||
// Log: Iniciando la descarga
|
||||
$this->logger->info('Initiating ISO download.', ['isoUrl' => $isoUrl]);
|
||||
|
||||
// Llamada al servicio para iniciar la descarga del ISO
|
||||
$installResult = $this->curlRequestService->callOgLive("download " . escapeshellarg($isoUrl));
|
||||
|
||||
// Log: Descarga completada
|
||||
$this->logger->info('ISO download completed.', [
|
||||
'transactionId' => $transactionId,
|
||||
'installResult' => $installResult,
|
||||
]);
|
||||
|
||||
// Verificación de resultado
|
||||
$exitCode = $installResult['exitCode'];
|
||||
$status = ($exitCode === 0) ? 'success' : 'failure';
|
||||
$messageText = $installResult['output']['message'] ?? 'Unknown error';
|
||||
|
||||
if ($exitCode !== 0) {
|
||||
$this->logger->error('Installation failed.', [
|
||||
'transactionId' => $transactionId,
|
||||
'exitCode' => $exitCode,
|
||||
'error' => $messageText,
|
||||
]);
|
||||
} else {
|
||||
$this->logger->info('Installation completed successfully.', [
|
||||
'transactionId' => $transactionId,
|
||||
]);
|
||||
}
|
||||
|
||||
// Preparar datos para el webhook
|
||||
$webhookData = [
|
||||
'ogCoreId' => $transactionId,
|
||||
'status' => $status,
|
||||
'code' => ($exitCode === 0) ? 200 : $exitCode,
|
||||
'message' => $messageText,
|
||||
];
|
||||
|
||||
$this->logger->info('Webhook data prepared.', ['webhookData' => $webhookData]);
|
||||
|
||||
// Enviar al webhook
|
||||
$webhookUrl = "{$this->ogCoreApiUrl}/og-lives/install/webhook";
|
||||
$this->logger->info('Sending data to webhook.', ['webhookUrl' => $webhookUrl]);
|
||||
$this->notifyWebhook($webhookUrl, $webhookData);
|
||||
|
||||
} catch (Exception $e) {
|
||||
// Log de error
|
||||
$this->logger->error('Installation process failed.', [
|
||||
'transactionId' => $transactionId,
|
||||
'exception' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
// Enviar notificación de error al webhook
|
||||
$webhookData = [
|
||||
'ogCoreId' => $transactionId,
|
||||
'status' => 'failure',
|
||||
'code' => 500,
|
||||
'message' => $e->getMessage(),
|
||||
];
|
||||
|
||||
$webhookUrl = "{$this->ogCoreApiUrl}/og-lives/install/webhook";
|
||||
$this->logger->info('Sending error notification to webhook.', ['webhookUrl' => $webhookUrl]);
|
||||
$this->notifyWebhook($webhookUrl, $webhookData);
|
||||
}
|
||||
|
||||
// Log finalización
|
||||
$this->logger->info('Installation process ended.', ['transactionId' => $transactionId]);
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
private function notifyWebhook(string $webhookUrl, array $webhookData): void
|
||||
{
|
||||
try {
|
||||
$this->logger->info('Sending webhook notification.', ['webhookData' => $webhookData]);
|
||||
$this->httpClient->request('POST', $webhookUrl, [
|
||||
'headers' => [
|
||||
'accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
'body' => json_encode(['webhookData' => $webhookData]),
|
||||
]);
|
||||
$this->logger->info('Webhook notification sent successfully.', ['webhookUrl' => $webhookUrl]);
|
||||
} catch (Exception $e) {
|
||||
$this->logger->error('Error sending webhook notification.', [
|
||||
'webhookUrl' => $webhookUrl,
|
||||
'exception' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
// src/OgBootBundle/OgBootBundle.php
|
||||
|
||||
namespace App\OgBootBundle;
|
||||
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class OgBootBundle extends Bundle
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
// src/OgBootBundle/Service/CurlRequestService.php
|
||||
|
||||
namespace App\OgBootBundle\Service;
|
||||
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class CurlRequestService
|
||||
{
|
||||
private LoggerInterface $logger;
|
||||
|
||||
public function __construct(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function convertMaskToCIDR($mask)
|
||||
{
|
||||
$bits = 0;
|
||||
$mask = explode(".", $mask);
|
||||
|
||||
foreach ($mask as $octet) {
|
||||
$bits += strlen(str_replace("0", "", decbin($octet)));
|
||||
}
|
||||
|
||||
return $bits;
|
||||
}
|
||||
|
||||
public function callOgLive($parameter)
|
||||
{
|
||||
// Ruta completa al script oglivecli
|
||||
// $ogLiveCliPath = sprintf("%s/bin/oglivecli", dirname(dirname(dirname(__DIR__))));
|
||||
$ogLiveCliPath = sprintf("%s/../../../../bin/oglivecli", __DIR__);
|
||||
// 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
|
||||
$this->logger->debug('Action: ' . $action);
|
||||
$this->logger->debug('Arguments: ' . 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 para depuración
|
||||
$this->logger->debug('Command: ' . $commandToRun);
|
||||
|
||||
// Ejecutar el comando, capturando la salida y el código de salida
|
||||
$output = [];
|
||||
$exitCode = null;
|
||||
exec($commandToRun, $output, $exitCode);
|
||||
|
||||
// Unir la salida en una sola cadena y registrar en el logger
|
||||
$outputString = implode("\n", $output);
|
||||
$this->logger->debug('Output: ' . $outputString);
|
||||
$this->logger->debug('Exit Code: ' . $exitCode);
|
||||
|
||||
// Decodificar la salida JSON si es posible
|
||||
$decodedOutput = json_decode($outputString, true);
|
||||
$this->logger->debug('Decoded Output: ' . print_r($decodedOutput, true));
|
||||
|
||||
return [
|
||||
'output' => $decodedOutput, // Retorna la salida decodificada (JSON)
|
||||
'exitCode' => $exitCode // Retorna el código de salida del comando
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,734 @@
|
|||
#!/bin/bash
|
||||
|
||||
#/**
|
||||
#@file oglivecli
|
||||
#@brief Command line tool to manage ogLive clients.
|
||||
#@usage oglivecli Command [Options ...]
|
||||
#@param Command:
|
||||
#@param help show this help
|
||||
#@param config [Parameter] show configuration parameters
|
||||
#@param disk_usage show disk usage information
|
||||
#@param list_installed_oglives list installed ogLive clients
|
||||
#@param check_services_status check status of critical services
|
||||
#@param download show a menu to download an ogLive ISO image from the OpenGnsys website
|
||||
#@param download Iso download a specific ogLive ISO image from the OpenGnsys website
|
||||
#@param install Iso install a new ogLive client from a downloaded ISO image
|
||||
#@param uninstall uuid uninstall an ogLive client using its UUID
|
||||
#@param get_default get index value for default ogLive client
|
||||
#@param set_default uuid set default ogLive client using its UUID
|
||||
#@param get_info uuid get JSON information about an installed ogLive client using its UUID
|
||||
#@warning This script needs "jq" command.
|
||||
#@version 3.0.0 - Updated with to adapt to Ogboot.
|
||||
#@author Ramón M. Gómez - ETSII Univ. Sevilla
|
||||
#@author Qindel formacion y servicios SL
|
||||
#@date 2024-08-06
|
||||
#*/ ##
|
||||
|
||||
|
||||
# Global constants definition.
|
||||
PROG=$(basename "$(realpath "$0")") # Program name.
|
||||
PROGDIR=$(dirname "$(realpath "$0")") # Dir where program is
|
||||
OPENGNSYS=$(realpath $PROGDIR/../) # ogboot main directory.
|
||||
DOWNLOADDIR=$OPENGNSYS/lib # Directory to store ogLive images.
|
||||
#@DOWNLOADURL="https://ognproject.evlt.uma.es/trac/downloads" # Download URL.
|
||||
DOWNLOADURL="https://ognproject.evlt.uma.es/oglive/"
|
||||
TFTPDIR=$OPENGNSYS/tftpboot/ # TFTP directory.
|
||||
DEFOGLIVE="ogLive" # Default ogLive directory.
|
||||
MINREL=20190601 # Mininum ogLive compatibility release.
|
||||
INFOFILE=$OPENGNSYS/etc/ogliveinfo.json # Configuration file.
|
||||
|
||||
|
||||
# Global and secondary functions.
|
||||
|
||||
source $OPENGNSYS/lib/ogfunctions.sh || exit 1
|
||||
|
||||
|
||||
|
||||
# Check consistency, showing configuration problems.
|
||||
function check() {
|
||||
local ERR=0 AUX INST DEF
|
||||
[ $# -ne 0 ] && raiseError usage
|
||||
# Check for old system that needs conversion.
|
||||
if [ -z "$(stat -c "%N" $TFTPDIR/ogclient | awk '$3~/'$DEFOGLIVE'/ {print}')" ]; then
|
||||
echo "This server uses old ogclient, please run \"$PROG convert\" to update."
|
||||
let ERR++
|
||||
[ ! -f $INFOFILE ] && return $ERR
|
||||
fi
|
||||
# Check for other problems.
|
||||
[ ! -f $INFOFILE ] && echo "Configuration file does not exists: $INFOFILE" && let ERR++
|
||||
[ -f $INFOFILE -a "$(jq -c keys $INFOFILE 2>/dev/null)" != "[\"default\",\"oglive\"]" ] && echo "Format error in configuration file: $INFOFILE" && let ERR++
|
||||
[ ! -e $TFTPDIR ] && echo "TFTP directory does not exist: $TFTPDIR." && let ERR++
|
||||
# Check for installed ogLive clients.
|
||||
INST=( $(find $TFTPDIR/ -type d -name "$DEFOGLIVE-*" -a ! -name "*.old" -printf "%f\n" | sort) )
|
||||
[[ ${#INST[@]} -eq 0 ]] && echo "No ogLive clients are installed." && let ERR++
|
||||
DEF=( $(jq -r .oglive[].directory $INFOFILE 2>/dev/null | sort) )
|
||||
# Compare installed and defined ogLive clients.
|
||||
AUX=$(comm -23 <(printf "%s\n" ${INST[*]}) <(printf "%s\n" ${DEF[*]}))
|
||||
[ -n "$AUX" ] && echo "Some ogLive are installed but not defined: ${AUX//$'\n'/, }" && let ERR++
|
||||
AUX=$(comm -13 <(printf "%s\n" ${INST[*]}) <(printf "%s\n" ${DEF[*]}))
|
||||
[ -n "$AUX" ] && echo "Some ogLive are defined but not installed: ${AUX//$'\n'/, }" && let ERR++
|
||||
# Compare downloaded and defined ISO images.
|
||||
INST=( $(find $DOWNLOADDIR/ -type f -name "$DEFOGLIVE-*.iso" -printf "%f\n" | sort) )
|
||||
DEF=( $(jq -r .oglive[].iso $INFOFILE 2>/dev/null | sort) )
|
||||
AUX=$(comm -23 <(printf "%s\n" ${INST[*]}) <(printf "%s\n" ${DEF[*]}))
|
||||
[ -n "$AUX" ] && echo "Some ISOs are downloaded but not defined: ${AUX//$'\n'/, }" && let ERR++
|
||||
AUX=$(comm -13 <(printf "%s\n" ${INST[*]}) <(printf "%s\n" ${DEF[*]}))
|
||||
[ -n "$AUX" ] && echo "Some ISOs are defined but not downloaded: ${AUX//$'\n'/, }" && let ERR++
|
||||
# Check for new ISO files downloaded after installation.
|
||||
AUX=$(jq -r '.oglive[] as $og | $og.iso + ":" + $og.directory' $INFOFILE 2>/dev/null | \
|
||||
while IFS=":" read -r DEF INST; do
|
||||
[ $DOWNLOADDIR/$DEF -nt $TFTPDIR/$INST ] && echo "$DEF"
|
||||
done)
|
||||
[ -n "$AUX" ] && echo "Some ISOs are downloaded after installation: ${AUX//$'\n'/, }" && let ERR++
|
||||
AUX=$(jq -r '.oglive[] as $og | if ($og.revision[1:9] | tonumber) < '$MINREL' then $og.directory else "" end' $INFOFILE 2>/dev/null)
|
||||
[ -n "$AUX" ] && echo "Some installed ogLive aren't fully compatible: ${AUX//$'\n'/, }" && let ERR++
|
||||
DEF=$(jq -r ".oglive[$(getdefault)].directory" $INFOFILE 2>/dev/null)
|
||||
INST=$(stat -c "%N" $TFTPDIR/$DEFOGLIVE | cut -f4 -d\')
|
||||
[ "$DEF" != "$INST" ] && echo "Default ogLive is not linked to right directory: $DEF <> $INST" && let ERR++
|
||||
# Print result.
|
||||
[ $ERR -eq 0 ] && echo "OK!" || echo "Problems detected: $ERR"
|
||||
return $ERR
|
||||
}
|
||||
|
||||
# List installed ogLive clients.
|
||||
function list() {
|
||||
[ $# -ne 0 ] && raiseError usage
|
||||
[ ! -r $INFOFILE ] && raiseError access "Configuration file."
|
||||
# List all defined indexes, directories and check if missing.
|
||||
jq -r .oglive[].directory $INFOFILE | nl -v 0 | \
|
||||
awk '{system("echo -n "$0"; test -d '$TFTPDIR'/"$2" || echo -n \" (missing)\"; echo")}' | column -t
|
||||
}
|
||||
|
||||
# Show information about an installed ogLive client.
|
||||
function show() {
|
||||
local INDEX
|
||||
[ $# -ne 1 ] && raiseError usage
|
||||
[ ! -r $INFOFILE ] && raiseError access "Configuration file."
|
||||
# Show JSON entries.
|
||||
case "$1" in
|
||||
default) # Default index.
|
||||
INDEX="[$(jq -r .default $INFOFILE)]" ;;
|
||||
all) # All intries.
|
||||
;;
|
||||
[0-9]*) # Index.
|
||||
INDEX="[$1]" ;;
|
||||
*) # Directory.
|
||||
INDEX="[$(search "$1" 2>/dev/null)]" || raiseError notfound "Directory \"$1\"."
|
||||
;;
|
||||
esac
|
||||
jq ".oglive$INDEX" $INFOFILE || raiseError notfound "Index \"$1\"."
|
||||
}
|
||||
|
||||
# Show index or directory corresponding to searching parameter.
|
||||
function search() {
|
||||
[ $# -ne 1 ] && raiseError usage
|
||||
[ ! -r $INFOFILE ] && raiseError access "Configuration file."
|
||||
# Show corresponding index or directory.
|
||||
list | awk -v d="$1" '{if ($2==d) print $1; if ($1==d) print $2}' | grep . || raiseError notfound "Index/Directory \"$1\"."
|
||||
}
|
||||
function download() {
|
||||
local OGLIVEFILE TARGETFILE SOURCELENGTH
|
||||
|
||||
# Verificar si el directorio de descarga existe y tiene permisos de escritura.
|
||||
[ ! -d "$DOWNLOADDIR" ] && raiseError notfound "Directorio de descarga."
|
||||
[ ! -w "$DOWNLOADDIR" ] && raiseError access "Directorio de descarga."
|
||||
|
||||
# Si no se proporciona ningún parámetro, mostrar el menú de descargas.
|
||||
if [ -z "$1" ]; then
|
||||
downloadMenu
|
||||
else
|
||||
local download_url="$1"
|
||||
OGLIVEFILE=$(basename "$download_url")
|
||||
local oglive_name="${OGLIVEFILE%.iso}" # Nombre del ogLive sin la extensión .iso
|
||||
INSTALLED_PATH="$TFTPDIR/$oglive_name" # Ruta de instalación donde se verifica
|
||||
|
||||
# Validar que la URL apunte a un archivo ISO.
|
||||
if [[ ! "$OGLIVEFILE" =~ \.iso$ ]]; then
|
||||
raiseError download "La URL no apunta a un archivo ISO."
|
||||
fi
|
||||
|
||||
# Obtener el tamaño de descarga.
|
||||
SOURCELENGTH=$(curl -k --head --retry 5 --retry-delay 5 --max-time 30 "$download_url" | awk -F: '/Content-Length:/ {print $2}')
|
||||
[ -n "$SOURCELENGTH" ] || raiseError download "No se pudo obtener el tamaño del archivo desde \"$download_url\"."
|
||||
|
||||
# Verificar si el ogLive ya está instalado
|
||||
if [ -d "$INSTALLED_PATH" ]; then
|
||||
raiseError download "El ogLive \"$oglive_name\" ya está instalado en \"$INSTALLED_PATH\"."
|
||||
fi
|
||||
|
||||
# Descargar ogLive.
|
||||
TARGETFILE="$DOWNLOADDIR/$OGLIVEFILE"
|
||||
trap "rm -f $TARGETFILE" 1 2 3 6 9 15
|
||||
curl -k --retry 5 --retry-delay 5 "$download_url" -o "$TARGETFILE" || raiseError download "No se pudo descargar \"$OGLIVEFILE\"."
|
||||
if [ -f "$TARGETFILE" ]; then
|
||||
local file_type=$(file -b "$TARGETFILE")
|
||||
if [[ "$file_type" =~ "ISO 9660" ]] && [[ "$file_type" =~ "ogClient" ]]; then
|
||||
install "$OGLIVEFILE"
|
||||
else
|
||||
raiseError download "El archivo descargado no es un ogLive ISO válido."
|
||||
fi
|
||||
else
|
||||
raiseError download "El archivo no fue descargado correctamente."
|
||||
fi
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
# Muestra un menú para seleccionar y descargar un archivo ogLive ISO del sitio web de OpenGnsys.
|
||||
function downloadMenu() {
|
||||
local OGLIVE NISOS i HTTPCODE ISOREL
|
||||
# Usamos grep para filtrar solo los enlaces que contienen archivos ISO, pero eliminamos etiquetas HTML con sed
|
||||
OGLIVE=( $(curl -k --silent "$DOWNLOADURL" | grep -oP '(?<=href=")[^"]*\.iso' | sed 's/^.*\///') )
|
||||
NISOS=${#OGLIVE[@]}
|
||||
|
||||
local downloads=()
|
||||
|
||||
for i in $(seq 1 $NISOS); do
|
||||
installed=false
|
||||
compatible=false
|
||||
|
||||
# Obtener el nombre completo del archivo ISO
|
||||
OGLIVEFILE="${OGLIVE[i-1]}"
|
||||
|
||||
# Extraer la distribución, revisión y arquitectura
|
||||
OGLIVEDIST="$(echo $OGLIVEFILE | cut -f2 -d-)"
|
||||
OGLIVEREV="${OGLIVEFILE##*-}"; OGLIVEREV="${OGLIVEREV%%.*}"
|
||||
OGLIVEKRNL="$(echo $OGLIVEFILE | cut -f3- -d-)"; OGLIVEKRNL="${OGLIVEKRNL%-$OGLIVEREV.*}"
|
||||
OGLIVEARCH="$(echo $OGLIVEFILE | awk -F- '{print $(NF-1)}')"
|
||||
|
||||
case "$OGLIVEARCH" in
|
||||
i386|amd64)
|
||||
OGLIVEKRNL="${OGLIVEKRNL%-$OGLIVEARCH}" ;;
|
||||
*)
|
||||
OGLIVEARCH="i386" ;;
|
||||
esac
|
||||
|
||||
OGLIVEDIR="$TFTPDIR/$DEFOGLIVE-${OGLIVEKRNL%%-*}-$OGLIVEARCH-$OGLIVEREV"
|
||||
OGLIVEDIR="${OGLIVEDIR/amd64-/}"
|
||||
|
||||
# Verificar si el ogLive está instalado y no es un directorio .old
|
||||
if [ -d "$OGLIVEDIR" ] && [[ ! "$OGLIVEDIR" =~ \.old$ ]]; then
|
||||
installed=true
|
||||
else
|
||||
installed=false
|
||||
fi
|
||||
|
||||
ISOREL=${OGLIVE[i-1]##*-r}; ISOREL=${ISOREL%%.*}
|
||||
[ "$ISOREL" -ge "$MINREL" ] && compatible=true
|
||||
|
||||
url="$DOWNLOADURL/${OGLIVE[i-1]}"
|
||||
|
||||
local DATA=$(jq -n \
|
||||
--arg id "$i" \
|
||||
--arg filename "$OGLIVEFILE" \
|
||||
--arg url "$url" \
|
||||
--argjson installed "$installed" \
|
||||
--argjson compatible "$compatible" \
|
||||
'{id: $id, filename: $filename, url: $url, installed: $installed, compatible: $compatible}')
|
||||
|
||||
downloads+=("$DATA")
|
||||
done
|
||||
|
||||
jq -n --argjson downloads "$(printf '%s\n' "${downloads[@]}" | jq -s .)" \
|
||||
'{downloads: $downloads}'
|
||||
}
|
||||
|
||||
update_json() {
|
||||
local key=$1
|
||||
local value=$2
|
||||
result_json=$(jq --arg key "$key" --arg value "$value" '.[$key] = $value' <<< "$result_json")
|
||||
}
|
||||
|
||||
add_message() {
|
||||
local message=$1
|
||||
result_json=$(jq --arg message "$message" '.messages += [$message]' <<< "$result_json")
|
||||
}
|
||||
|
||||
# Install an ogLive client from a previously downloaded ISO image.
|
||||
function install() {
|
||||
local OGLIVEFILE OGLIVEDIST OGLIVEREV OGLIVEKRNL OGLIVEDIR OGINITRD OGSQFS OGCLIENT=ogclient
|
||||
local COMPRESS SAMBAPASS TMPDIR RSYNCSERV RSYNCCLNT JSON_OUTPUT
|
||||
[ $# -ne 1 ] && { echo "{\"error\": \"USAGE_ERROR\", \"message\": \"Usage: install {iso_file}\"}"; exit 400; }
|
||||
|
||||
OGLIVEFILE=$(realpath "$DOWNLOADDIR/$1")
|
||||
[ $(echo "$OGLIVEFILE" | wc -w) -gt 1 ] && { echo "{\"error\": \"USAGE_ERROR\", \"message\": \"Invalid ISO file: $1\"}"; exit 400; }
|
||||
[ ! -f "$OGLIVEFILE" ] && { echo "{\"error\": \"NOT_FOUND\", \"message\": \"ISO file $1 not found.\"}"; exit 404; }
|
||||
[ ! -r "$OGLIVEFILE" ] && { echo "{\"error\": \"ACCESS_DENIED\", \"message\": \"Cannot read ISO file $1.\"}"; exit 403; }
|
||||
[ ! -w "$(dirname "$INFOFILE")" ] && { echo "{\"error\": \"ACCESS_DENIED\", \"message\": \"Cannot write to configuration directory.\"}"; exit 403; }
|
||||
[ ! -w "$TFTPDIR" ] && { echo "{\"error\": \"ACCESS_DENIED\", \"message\": \"Cannot write to installation directory.\"}"; exit 403; }
|
||||
[ -z "$(file -b "$OGLIVEFILE" | grep "ISO.*ogClient")" ] && { echo "{\"error\": \"INVALID_FILE\", \"message\": \"File is not a valid ogLive ISO image.\"}"; exit 400; }
|
||||
|
||||
OGLIVEDIST="$(echo "$OGLIVEFILE" | cut -f2 -d-)"
|
||||
OGLIVEREV="${OGLIVEFILE##*-}"; OGLIVEREV="${OGLIVEREV%%.*}"
|
||||
OGLIVEKRNL="$(echo "$OGLIVEFILE" | cut -f3- -d-)"; OGLIVEKRNL="${OGLIVEKRNL%-$OGLIVEREV.*}"
|
||||
OGLIVEARCH="$(echo "$OGLIVEFILE" | awk -F- '{print $(NF-1)}')"
|
||||
case "$OGLIVEARCH" in
|
||||
i386|amd64)
|
||||
OGLIVEKRNL="${OGLIVEKRNL%-$OGLIVEARCH}" ;;
|
||||
*)
|
||||
OGLIVEARCH="i386" ;;
|
||||
esac
|
||||
#OGLIVEDIR="$TFTPDIR/$DEFOGLIVE-${OGLIVEKRNL%%-*}-$OGLIVEARCH-$OGLIVEREV"
|
||||
#OGLIVEDIR="${OGLIVEDIR/amd64-/}"
|
||||
OGLIVEDIR=$TFTPDIR$(basename "$OGLIVEFILE" .iso)
|
||||
OGINITRD="$OGLIVEDIR/oginitrd.img"
|
||||
|
||||
[ ! -r "$OGINITRD" ] && OGINITRD="$TFTPDIR/$DEFOGLIVE/oginitrd.img"
|
||||
if [ -r "$OGINITRD" ]; then
|
||||
COMPRESS=$(file -b "$OGINITRD" | awk '{print tolower($1);}')
|
||||
if [[ z$COMPRESS == zascii ]]; then
|
||||
COMPRESS=cat
|
||||
else
|
||||
COMPRESS="$COMPRESS -dc"
|
||||
fi
|
||||
SAMBAPASS=$($COMPRESS "$OGINITRD" | \
|
||||
cpio -i --to-stdout scripts/ogfunctions 2>/dev/null | \
|
||||
sed -n '/^[ \t].*OPTIONS=/s/.*pass=\(\w*\).*/\1/p')
|
||||
fi
|
||||
rm -fr "${OGLIVEDIR}.old" 2>/dev/null
|
||||
mv -f "$OGLIVEDIR" "${OGLIVEDIR}.old" 2>/dev/null
|
||||
|
||||
TMPDIR=$OPENGNSYS/mnt
|
||||
TMPDIR_SQUASHFS=/tmp/ogclient_mount
|
||||
mv -f "$OGLIVEFILE" "$DOWNLOADDIR/oglive.iso" 2>/dev/null || { echo "{\"error\": \"RENAME_FAILED\", \"message\": \"Cannot rename $OGLIVEFILE to oglive.iso.\"}"; exit 500; }
|
||||
OGLIVEFILE="$DOWNLOADDIR/oglive.iso"
|
||||
|
||||
mkdir -p "$OGLIVEDIR" "$TMPDIR" "$TMPDIR_SQUASHFS"
|
||||
[ ! -d "$OGLIVEDIR" ] && { echo "{\"error\": \"DIR_CREATION_FAILED\", \"message\": \"Failed to create/access directory $OGLIVEDIR.\"}"; exit 500; }
|
||||
[ ! -d "$TMPDIR" ] && { echo "{\"error\": \"DIR_CREATION_FAILED\", \"message\": \"Failed to create/access directory $TMPDIR.\"}"; exit 500; }
|
||||
[ ! -d "$TMPDIR_SQUASHFS" ] && { echo "{\"error\": \"DIR_CREATION_FAILED\", \"message\": \"Failed to create/access directory $TMPDIR_SQUASHFS.\"}"; exit 500; }
|
||||
|
||||
trap "umount $TMPDIR" 1 2 3 6 9 15
|
||||
|
||||
cleanup() {
|
||||
code=$?
|
||||
umount "$OGLIVEFILE" >/dev/null 2>&1
|
||||
umount "$TMPDIR" >/dev/null 2>&1
|
||||
umount "$TMPDIR_SQUASHFS" >/dev/null 2>&1
|
||||
if [ $code -ne 0 ]; then
|
||||
echo "Something went wrong (exit code $code), cleaning up..."
|
||||
rm -r "$OGLIVEDIR" >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
mount "$OGLIVEFILE" >/dev/null 2>&1 || { echo "{\"error\": \"MOUNT_FAILED\", \"message\": \"Failed to mount ISO file.\"}"; exit 500; }
|
||||
|
||||
cp -va "$TMPDIR/ogclient/"* "$OGLIVEDIR" >/dev/null 2>&1 || { echo "{\"error\": \"COPY_FAILED\", \"message\": \"Cannot copy files to $OGLIVEDIR.\"}"; exit 500; }
|
||||
chmod -R u+w "$OGLIVEDIR" || { echo "{\"error\": \"PERMISSION_CHANGE_FAILED\", \"message\": \"Failed to change permissions for $OGLIVEDIR.\"}"; exit 500; }
|
||||
umount "$TMPDIR" >/dev/null 2>&1
|
||||
|
||||
if [ ! -f "$INFOFILE" ]; then
|
||||
rm -f "$TFTPDIR/$DEFOGLIVE" "$TFTPDIR/$OGCLIENT"
|
||||
ln -vfs "$(basename "$OGLIVEDIR")" "$TFTPDIR/$DEFOGLIVE" >/dev/null 2>&1 || { echo "{\"error\": \"LINK_FAILED\", \"message\": \"Linking to $TFTPDIR/$DEFOGLIVE failed.\"}"; exit 500; }
|
||||
ln -vfs "$DEFOGLIVE" "$TFTPDIR/$OGCLIENT" >/dev/null 2>&1 || { echo "{\"error\": \"LINK_FAILED\", \"message\": \"Linking to $TFTPDIR/$OGCLIENT failed.\"}"; exit 500; }
|
||||
fi
|
||||
|
||||
if [ -n "$SAMBAPASS" ]; then
|
||||
echo -ne "$SAMBAPASS\n$SAMBAPASS\n" | $OPENGNSYS/bin/setsmbpass "$(basename "$OGLIVEDIR")" >/dev/null 2>&1 || { echo "{\"error\": \"SET_SMBPASS_FAILED\", \"message\": \"Failed to set Samba password with SAMBAPASS.\"}"; exit 500; }
|
||||
# else
|
||||
# $OPENGNSYS/bin/setsmbpass "$(basename "$OGLIVEDIR")" >/dev/null 2>&1 || { echo "{\"error\": \"SET_SMBPASS_FAILED\", \"message\": \"Failed to set Samba password without SAMBAPASS.\"}"; exit 500; }
|
||||
fi
|
||||
|
||||
find -L "$OGLIVEDIR" -type d -exec chmod 755 {} \; >/dev/null 2>&1 || { echo "{\"error\": \"CHMOD_FAILED\", \"message\": \"Failed to change permissions for directories in $OGLIVEDIR.\"}"; exit 500; }
|
||||
find -L "$OGLIVEDIR" -type f -exec chmod 644 {} \; >/dev/null 2>&1 || { echo "{\"error\": \"CHMOD_FAILED\", \"message\": \"Failed to change permissions for files in $OGLIVEDIR.\"}"; exit 500; }
|
||||
|
||||
|
||||
OGSQFS="$OGLIVEDIR/ogclient.sqfs"
|
||||
trap "exit 0" SIGINT
|
||||
TMPDIR=/tmp/oglive
|
||||
if mountpoint -q "$TMPDIR"; then
|
||||
umount "$TMPDIR" >/dev/null 2>&1 || { echo "{\"error\": \"UMOUNT_FAILED\", \"message\": \"Failed to unmount $TMPDIR.\"}"; exit 500; }
|
||||
fi
|
||||
|
||||
mount "$TMPDIR_SQUASHFS" || { echo "{\"error\": \"MOUNT_FAILED\", \"message\": \"Failed to mount $TMPDIR_SQUASHFS.\"}"; exit 500; }
|
||||
RSYNCSERV=$(rsync --version 2>/dev/null | awk '/protocol/ {print $6}')
|
||||
RSYNCCLNT=$($TMPDIR_SQUASHFS/usr/bin/rsync --version 2>/dev/null | awk '/protocol/ {print $6}')
|
||||
if [ -z "$RSYNCSERV" ] || [ "$RSYNCSERV" -gt "${RSYNCCLNT:-1}" ]; then
|
||||
[ -e "$OPENGNSYS/client/bin/rsync-$RSYNCSERV" ] && mv -f "$OPENGNSYS/client/bin/rsync-$RSYNCSERV" "$OPENGNSYS/client/bin/rsync" 2>/dev/null
|
||||
else
|
||||
[ -e "$OPENGNSYS/client/bin/rsync" ] && mv -f "$OPENGNSYS/client/bin/rsync" "$OPENGNSYS/client/bin/rsync-$($OPENGNSYS/client/bin/rsync --version 2>/dev/null | awk '/protocol/ {print $6}')"
|
||||
fi
|
||||
umount "$TMPDIR_SQUASHFS" || sudo rm -rf "$TMPDIR_SQUASHFS"
|
||||
|
||||
CHECKSUM_FILE="$OGLIVEDIR/ogclient.sqfs.sum"
|
||||
[ -f "$CHECKSUM_FILE" ] && OGLIVEID=$(cat "$CHECKSUM_FILE") || OGLIVEID="N/A"
|
||||
|
||||
jq -n \
|
||||
--arg OGLIVEDIST "$OGLIVEDIST" \
|
||||
--arg OGLIVEKRNL "$OGLIVEKRNL" \
|
||||
--arg OGLIVEARCH "$OGLIVEARCH" \
|
||||
--arg OGLIVEREV "$OGLIVEREV" \
|
||||
--arg OGLIVEDIR "$OGLIVEDIR" \
|
||||
'{
|
||||
OGLIVEDIST: $OGLIVEDIST,
|
||||
OGLIVEKRNL: $OGLIVEKRNL,
|
||||
OGLIVEARCH: $OGLIVEARCH,
|
||||
OGLIVEREV: $OGLIVEREV,
|
||||
OGLIVEDIR: $OGLIVEDIR
|
||||
}' > "$OGLIVEDIR/oglive_info.json"
|
||||
|
||||
[ ! -f "$OGLIVEDIR/oglive_info.json" ] && { echo "{\"error\": \"JSON_CREATION_FAILED\", \"message\": \"Failed to create oglive_info.json.\"}"; exit 500; }
|
||||
# chown -R :opengnsys "$OGLIVEDIR" >/dev/null 2>&1 || { echo "{\"error\": \"CHOWN_FAILED\", \"message\": \"Failed to change ownership for $OGLIVEDIR.\"}"; exit 500; }
|
||||
JSON_OUTPUT=$(jq -n \
|
||||
--arg id "$OGLIVEID" \
|
||||
--arg dist "$OGLIVEDIST" \
|
||||
--arg krnl "$OGLIVEKRNL" \
|
||||
--arg arch "$OGLIVEARCH" \
|
||||
--arg rev "$OGLIVEREV" \
|
||||
--arg dir "$OGLIVEDIR" \
|
||||
'{status: "success", message: {id: $id, distribution: $dist, kernel: $krnl, architecture: $arch, revision: $rev, directory: $dir}}')
|
||||
|
||||
echo "$JSON_OUTPUT"
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
||||
# Uninstall an ogLive client.
|
||||
function uninstall() {
|
||||
local CHECKSUM DIR DEFAULT_OGLIVE_DIR DEFAULT_CHECKSUM
|
||||
|
||||
# Validar que se proporcionó exactamente un argumento (el checksum)
|
||||
[ $# -ne 1 ] && { echo "{\"error\": \"BAD_REQUEST\", \"message\": \"usage: uninstall {checksum}\"}"; exit 400; }
|
||||
|
||||
CHECKSUM=$1
|
||||
|
||||
# Verificar acceso a los directorios necesarios
|
||||
[ ! -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 404
|
||||
if [ -z "$DIR" ]; then
|
||||
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, si no, devolver error 500
|
||||
if [ -d "$DIR" ]; then
|
||||
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"
|
||||
local DIR OGLIVEJSON OGLIVEDIST OGLIVEKRNL OGLIVEARCH OGLIVEREV OGLIVEDIR CHECKSUM_FILE CHECKSUM
|
||||
|
||||
# Verificar que el enlace simbólico del ogLive por defecto existe.
|
||||
if [ ! -L "$DEFAULT_LINK" ]; then
|
||||
echo "{\"error\": \"Default ogLive client link not found.\"}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Obtener el directorio real al que apunta el enlace simbólico.
|
||||
DIR=$(readlink -f "$DEFAULT_LINK")
|
||||
|
||||
# Si no se encuentra el directorio, devolver error.
|
||||
if [ -z "$DIR" ]; then
|
||||
echo "{\"error\": \"Default ogLive client directory not found.\"}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verificar que el archivo oglive_info.json existe en el directorio.
|
||||
OGLIVEJSON="$DIR/oglive_info.json"
|
||||
if [ ! -f "$OGLIVEJSON" ]; then
|
||||
echo "{\"error\": \"oglive_info.json not found in $DIR.\"}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Leer los datos del archivo JSON.
|
||||
OGLIVEDIST=$(jq -r '.OGLIVEDIST' "$OGLIVEJSON")
|
||||
OGLIVEKRNL=$(jq -r '.OGLIVEKRNL' "$OGLIVEJSON")
|
||||
OGLIVEARCH=$(jq -r '.OGLIVEARCH' "$OGLIVEJSON")
|
||||
OGLIVEREV=$(jq -r '.OGLIVEREV' "$OGLIVEJSON")
|
||||
OGLIVEDIR=$(jq -r '.OGLIVEDIR' "$OGLIVEJSON")
|
||||
|
||||
# Obtener el checksum del archivo ogclient.sqfs.sum
|
||||
CHECKSUM_FILE="$DIR/ogclient.sqfs.sum"
|
||||
if [ -f "$CHECKSUM_FILE" ]; then
|
||||
CHECKSUM=$(cat "$CHECKSUM_FILE" | cut -d ' ' -f 1)
|
||||
else
|
||||
CHECKSUM=""
|
||||
fi
|
||||
|
||||
# Construir el JSON con la información.
|
||||
local INFO=$(cat << EOT
|
||||
{
|
||||
"id": "$CHECKSUM",
|
||||
"distribution": "$OGLIVEDIST",
|
||||
"kernel": "$OGLIVEKRNL",
|
||||
"architecture": "$OGLIVEARCH",
|
||||
"revision": "$OGLIVEREV",
|
||||
"directory": "$OGLIVEDIR"
|
||||
}
|
||||
EOT
|
||||
)
|
||||
|
||||
# Devolver la información en formato JSON.
|
||||
echo "$INFO"
|
||||
}
|
||||
|
||||
|
||||
# Set default ogLive client by checksum.
|
||||
function set_default() {
|
||||
local CHECKSUM=$1
|
||||
local DIR
|
||||
|
||||
# Validar que se proporcionó exactamente un argumento (el checksum)
|
||||
[ $# -ne 1 ] && { echo "{\"error\": \"usage: set-default {checksum}\"}"; exit 1; }
|
||||
|
||||
# Verificar acceso a los directorios necesarios
|
||||
[ ! -w $TFTPDIR ] && { echo "{\"error\": \"access installation directory.\"}"; exit 1; }
|
||||
|
||||
# Buscar el directorio correspondiente al checksum
|
||||
DIR=$(find $TFTPDIR -type f -name 'ogclient.sqfs.sum' -exec grep -l "$CHECKSUM" {} \; | xargs -I{} dirname {} | grep -v ".old")
|
||||
|
||||
# Si no se encuentra el directorio, devolver error
|
||||
if [ -z "$DIR" ]; then
|
||||
echo "{\"error\": \"ogLive client with checksum $CHECKSUM not found.\"}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Eliminar el enlace simbólico existente y crear uno nuevo
|
||||
rm -f $TFTPDIR/$DEFOGLIVE > /dev/null 2>&1
|
||||
ln -vfs $(basename $DIR) $TFTPDIR/$DEFOGLIVE > /dev/null 2>&1
|
||||
|
||||
# Comprobar si el enlace simbólico se creó correctamente
|
||||
if [ "$(readlink -f $TFTPDIR/$DEFOGLIVE)" == "$(readlink -f $DIR)" ]; then
|
||||
echo "{\"message\": \"ogLive client set as default successfully.\", \"details\": \"$DIR\"}"
|
||||
else
|
||||
echo "{\"error\": \"Failed to set default ogLive client.\"}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get disk usage information
|
||||
function disk_usage() {
|
||||
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
|
||||
|
||||
# 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"
|
||||
local OGLIVEDIST=""
|
||||
local OGLIVEKRNL=""
|
||||
local OGLIVEARCH=""
|
||||
local OGLIVEREV=""
|
||||
local CHECKSUM=""
|
||||
local OGLIVEJSON="$OGLIVEDIR/oglive_info.json"
|
||||
local CHECKSUM_FILE="$OGLIVEDIR/ogclient.sqfs.sum"
|
||||
|
||||
# Intentar obtener el ID desde el archivo ogclient.sqfs.sum
|
||||
if [ -f "$CHECKSUM_FILE" ]; then
|
||||
CHECKSUM=$(cut -d ' ' -f 1 "$CHECKSUM_FILE")
|
||||
else
|
||||
local DATA=$(jq -n \
|
||||
--arg id "unknown" \
|
||||
--arg error "CHECKSUM_NOT_FOUND" \
|
||||
--arg message "Checksum file not found or invalid in $OGLIVEDIR. Manual deletion is recommended." \
|
||||
'{id: $id, error: $error, message: $message}')
|
||||
installed_ogLives+=("$DATA")
|
||||
continue
|
||||
fi
|
||||
|
||||
# Verificar que el archivo oglive_info.json existe en el directorio
|
||||
if [ -f "$OGLIVEJSON" ]; then
|
||||
OGLIVEDIST=$(jq -r '.OGLIVEDIST' "$OGLIVEJSON")
|
||||
OGLIVEKRNL=$(jq -r '.OGLIVEKRNL' "$OGLIVEJSON")
|
||||
OGLIVEARCH=$(jq -r '.OGLIVEARCH' "$OGLIVEJSON")
|
||||
OGLIVEREV=$(jq -r '.OGLIVEREV' "$OGLIVEJSON")
|
||||
|
||||
# Crear el JSON con los datos del ogLive
|
||||
local DATA=$(jq -n \
|
||||
--arg id "$CHECKSUM" \
|
||||
--arg dist "$OGLIVEDIST" \
|
||||
--arg krnl "$OGLIVEKRNL" \
|
||||
--arg arch "$OGLIVEARCH" \
|
||||
--arg rev "$OGLIVEREV" \
|
||||
--arg dir "$OGLIVEDIR" \
|
||||
'{id: $id, distribution: $dist, kernel: $krnl, architecture: $arch, revision: $rev, directory: $dir}')
|
||||
installed_ogLives+=("$DATA")
|
||||
else
|
||||
# Informar que el archivo oglive_info.json no existe y que el ogLive puede estar corrupto
|
||||
local DATA=$(jq -n \
|
||||
--arg id "$CHECKSUM" \
|
||||
--arg error "CORRUPT_OG_LIVE" \
|
||||
--arg message "oglive_info.json not found in $OGLIVEDIR. ogLive may be corrupted." \
|
||||
'{id: $id, error: $error, message: $message}')
|
||||
installed_ogLives+=("$DATA")
|
||||
continue
|
||||
fi
|
||||
|
||||
oglive_count=$((oglive_count + 1))
|
||||
|
||||
# Verificar si es el ogLive por defecto
|
||||
[ -n "$(stat -c "%N" "$TFTPDIR/$DEFOGLIVE" | awk '$3~/'$i'/ {print}')" ] && DEF="$i"
|
||||
done
|
||||
|
||||
# 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 \
|
||||
--arg default_oglive "$default_oglive" \
|
||||
--argjson installed_ogLives "$(printf '%s\n' "${installed_ogLives[@]}" | jq -s .)" \
|
||||
'{
|
||||
default_oglive: $default_oglive,
|
||||
installed_ogLives: $installed_ogLives
|
||||
}'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Get information about an installed ogLive client.
|
||||
function get_info() {
|
||||
local CHECKSUM="$1"
|
||||
local DIR OGLIVEDIST OGLIVEKRNL OGLIVEARCH OGLIVEREV OGLIVEDIR OGLIVEJSON
|
||||
|
||||
# Verificar que se proporcionó un checksum.
|
||||
[ -z "$CHECKSUM" ] && { echo "{\"error\": \"usage: get_info {checksum}\"}"; exit 1; }
|
||||
|
||||
# Verificar acceso al directorio de instalación.
|
||||
[ ! -w $TFTPDIR ] && { echo "{\"error\": \"access installation directory.\"}"; exit 1; }
|
||||
|
||||
# Buscar el directorio correspondiente al checksum, excluyendo los que terminan en .old.
|
||||
DIR=$(find $TFTPDIR -type f -name 'ogclient.sqfs.sum' -exec grep -l "$CHECKSUM" {} \; | grep -v '.old' | xargs -I{} dirname {})
|
||||
|
||||
# Si no se encuentra el directorio, devolver error.
|
||||
if [ -z "$DIR" ]; then
|
||||
echo "{\"error\": \"ogLive client with checksum $CHECKSUM not found.\"}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verificar que el archivo oglive_info.json existe en el directorio.
|
||||
OGLIVEJSON="$DIR/oglive_info.json"
|
||||
if [ ! -f "$OGLIVEJSON" ]; then
|
||||
echo "{\"error\": \"oglive_info.json not found in $DIR.\"}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Leer los datos del archivo JSON.
|
||||
OGLIVEDIST=$(jq -r '.OGLIVEDIST' "$OGLIVEJSON")
|
||||
OGLIVEKRNL=$(jq -r '.OGLIVEKRNL' "$OGLIVEJSON")
|
||||
OGLIVEARCH=$(jq -r '.OGLIVEARCH' "$OGLIVEJSON")
|
||||
OGLIVEREV=$(jq -r '.OGLIVEREV' "$OGLIVEJSON")
|
||||
OGLIVEDIR=$(jq -r '.OGLIVEDIR' "$OGLIVEJSON")
|
||||
|
||||
# Construir el JSON con los datos del ogLive y el checksum (id).
|
||||
local INFO=$(cat << EOT
|
||||
{
|
||||
"id": "$CHECKSUM",
|
||||
"distribution": "$OGLIVEDIST",
|
||||
"kernel": "$OGLIVEKRNL",
|
||||
"architecture": "$OGLIVEARCH",
|
||||
"revision": "$OGLIVEREV",
|
||||
"directory": "$OGLIVEDIR"
|
||||
}
|
||||
EOT
|
||||
)
|
||||
|
||||
# Devolver la información en formato JSON.
|
||||
echo "$INFO"
|
||||
}
|
||||
|
||||
# Function to check the status of services
|
||||
function check_services_status() {
|
||||
local SERVICES=("tftpd-hpa.service" "nginx.service")
|
||||
declare -A STATUS_MAP
|
||||
|
||||
for service in "${SERVICES[@]}"; do
|
||||
if systemctl list-units --type=service --all | grep -q "$service"; then
|
||||
STATUS=$(systemctl is-active "$service")
|
||||
STATUS_MAP[$service]=$STATUS
|
||||
else
|
||||
STATUS_MAP[$service]="not installed"
|
||||
fi
|
||||
done
|
||||
|
||||
local json_output=$(jq -n \
|
||||
--arg tftpboot "${STATUS_MAP['tftpd-hpa.service']}" \
|
||||
--arg nginx "${STATUS_MAP['nginx.service']}" \
|
||||
'{
|
||||
tftpboot: $tftpboot,
|
||||
nginx: $nginx
|
||||
}')
|
||||
|
||||
echo "$json_output"
|
||||
}
|
||||
# Main program.
|
||||
|
||||
# Access control.
|
||||
if [ "$USER" = "root" ] || [ "$USER" = "opengnsys" ] || groups $USER | grep -qw "opengnsys"; then
|
||||
ACCESS="root"
|
||||
else
|
||||
raiseError access "Need to be root, opengnsys or a member of the opengnsys group."
|
||||
fi
|
||||
|
||||
# Check dependencies.
|
||||
which sponge &>/dev/null || raiseError notfound "Need to install \"moreutils\"."
|
||||
|
||||
# Commands control.
|
||||
shopt -s extglob
|
||||
CMDS='+(help|disk_usage|list_installed_oglives|check_services_status|download|install|uninstall|get_default|set_default|get_info)'
|
||||
|
||||
case "$1" in
|
||||
$CMDS) COMMAND="${1/-/}"; shift; $COMMAND "$@" ;;
|
||||
*) raiseError usage ;;
|
||||
esac
|
||||
|
||||
exit $?
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
#!/bin/bash
|
||||
|
||||
PROG=$(basename $0)
|
||||
OPENGNSYS=${OPENGNSYS:-"/opt/opengnsys/ogboot"}
|
||||
SAMBAUSER="opengnsys" # Usuario por defecto.
|
||||
TFTPDIR=$OPENGNSYS/tftpboot
|
||||
INITRD=oginitrd.img
|
||||
TMPDIR=/tmp/oglive$$
|
||||
let CHANGES=0
|
||||
|
||||
# Control básico de errores.
|
||||
if [ "$USER" != "root" ] && [ "$USER" != "opengnsys" ] && ! id -nG "$USER" | grep -qw "opengnsys"; then
|
||||
echo "$PROG: Error: solo ejecutable por root, ogboot o miembros del grupo ogboot" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $# in
|
||||
0) # Cambios en todos los clientes ogLive instalados.
|
||||
if which oglivecli &>/dev/null; then
|
||||
LIST=$(./oglivecli list_installed_oglives | jq -r '.installed_ogLives[].directory' | xargs -n1 basename)
|
||||
else
|
||||
LIST="ogclient"
|
||||
fi ;;
|
||||
1) # Cambios en único ogLive (AVISO: puede crear inconsistencias con otros ogLive).
|
||||
LIST="$1" ;;
|
||||
*) # Error de formato.
|
||||
echo "$PROG: Error de ejecución" >&2
|
||||
echo "Formato: $PROG ogLive"
|
||||
exit 1 ;;
|
||||
esac
|
||||
|
||||
# Recuperar eco de consola si se corta el proceso.
|
||||
trap "stty echo 2>/dev/null" KILL
|
||||
# Buscar todos los clients ogLive instalados.
|
||||
for OGLIVE in $LIST; do
|
||||
# Crear clave para usuario de acceso a los recursos.
|
||||
CLIENTINITRD="$TFTPDIR/$OGLIVE/$INITRD"
|
||||
if [ -r "$CLIENTINITRD" ]; then
|
||||
if [ -z "$SAMBAPASS" ]; then
|
||||
# Obtener clave del teclado sin eco en pantalla.
|
||||
stty -echo 2>/dev/null
|
||||
echo -n "Clave del usuario Samba: "
|
||||
read -r SAMBAPASS
|
||||
# Solo se deben aceptar números y letras para la clave de acceso.
|
||||
if [[ "$SAMBAPASS" =~ [^a-zA-Z0-9] ]]; then
|
||||
echo
|
||||
echo "$PROG: Error: la clave solo debe contener caracteres alfanuméricos" >&2
|
||||
stty echo 2>/dev/null
|
||||
exit 2
|
||||
fi
|
||||
echo
|
||||
# Obtener confirmación clave sin eco en pantalla.
|
||||
echo -n "Confirmar clave: "
|
||||
read -r SAMBAPASS2
|
||||
echo
|
||||
stty echo 2>/dev/null
|
||||
if [ "$SAMBAPASS" != "$SAMBAPASS2" ]; then
|
||||
echo "$PROG: Error: las claves no coinciden" >&2
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
# Editar la parte de acceso del cliente:
|
||||
# descomprimir Initrd, sustituir clave y recomprimir Initrd).
|
||||
echo "Configurando cliente \"$OGLIVE\" ..."
|
||||
mkdir -p $TMPDIR
|
||||
echo "TMPDIR $TMPDIR"
|
||||
cd $TMPDIR || { echo "Error: no se pudo cambiar al directorio temporal."; exit 3; }
|
||||
|
||||
echo "Verificar si el archivo es gzip, lz4 o ASCII cpio antes de descomprimir"
|
||||
if file "$CLIENTINITRD" | grep -q "gzip compressed data"; then
|
||||
if ! gzip -dc "$CLIENTINITRD" | sudo cpio -im; then
|
||||
echo "Error: No se pudo descomprimir y extraer $CLIENTINITRD con gzip."
|
||||
exit 4
|
||||
fi
|
||||
COMPRESS_CMD="gzip -9c"
|
||||
elif file "$CLIENTINITRD" | grep -q "LZ4 compressed data"; then
|
||||
if ! lz4 -d "$CLIENTINITRD" | sudo cpio -im; then
|
||||
echo "Error: No se pudo descomprimir y extraer $CLIENTINITRD con lz4."
|
||||
exit 4
|
||||
fi
|
||||
COMPRESS_CMD="lz4 -c"
|
||||
elif file "$CLIENTINITRD" | grep -q "ASCII cpio archive"; then
|
||||
if ! sudo cpio -im < "$CLIENTINITRD"; then
|
||||
echo "Error: No se pudo extraer $CLIENTINITRD como archivo cpio."
|
||||
exit 4
|
||||
fi
|
||||
COMPRESS_CMD="cat" # No compresión, simplemente se pasa el archivo tal cual
|
||||
else
|
||||
echo "Error: $CLIENTINITRD no está en formato gzip, lz4 o ASCII cpio."
|
||||
exit 4
|
||||
fi
|
||||
|
||||
if [ -f scripts/ogfunctions ]; then
|
||||
sudo sed -i "s/OPTIONS=\(.*\)user=\w*\(.*\)pass=\w*\(.*\)/OPTIONS=\1user=$SAMBAUSER\2pass=$SAMBAPASS\3/" scripts/ogfunctions
|
||||
# TEMPORAL: solución ticket 554, actualizar cliente en caché (ogLive r3257).
|
||||
sudo sed -i "s/busybox reboot/reboot/" scripts/ogfunctions
|
||||
find . | sudo cpio -H newc -oa | gzip -9c > "$CLIENTINITRD"
|
||||
else
|
||||
echo "$PROG: Aviso: no se ha modificado la clave del cliente \"$OGLIVE\"."
|
||||
fi
|
||||
echo "intentando borrar $TMPDIR"
|
||||
rm -fr $TMPDIR
|
||||
echo "Calcular suma de comprobación"
|
||||
md5sum "$CLIENTINITRD" | cut -f1 -d" " | sudo tee "$CLIENTINITRD.sum" > /dev/null
|
||||
let CHANGES++
|
||||
else
|
||||
echo "$PROG: Cliente \"$OGLIVE\" no accesible."
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $CHANGES != 0 ]]; then
|
||||
# Cambiar clave Samba.
|
||||
echo "Cambiando clave samba en el servidor"
|
||||
echo -ne "$SAMBAPASS\n$SAMBAPASS\n" | sudo smbpasswd -a -s $SAMBAUSER
|
||||
echo "setsmbpass finish"
|
||||
else
|
||||
echo "$PROG: Aviso: no se ha modificado la clave de ningún cliente."
|
||||
fi
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
The Debian Package ogboot
|
||||
----------------------------
|
||||
|
||||
<Comments regarding the Package.>
|
||||
|
||||
-- vagrant <vagrant@build> Tue, 04 Mar 2025 15:42:24 +0000
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
ogboot for Debian
|
||||
----------------
|
||||
|
||||
<Possible notes regarding this package - if none, delete this file.>
|
||||
|
||||
-- vagrant <vagrant@build> Tue, 04 Mar 2025 15:42:24 +0000
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
ogboot for Debian
|
||||
----------------
|
||||
|
||||
<This file describes information about the source package, see Debian policy
|
||||
manual section 4.14. You WILL either need to modify or delete this file.>
|
||||
|
||||
|
||||
|
||||
-- vagrant <vagrant@build> Tue, 04 Mar 2025 15:42:24 +0000
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
ogboot (1.0.1+deb-pkg20250310-1) unstable; urgency=medium
|
||||
|
||||
* First debian installation
|
||||
* refs #1615 merge deb-package
|
||||
* refs #1615 remove client stuff
|
||||
* refs #1610 adds systctl in loadenviron.sh
|
||||
* refs #1593 add UEFILib and python scripts
|
||||
* refs #1609 set PATH and PYTHONPATH up
|
||||
* fix bug ogisefiactive
|
||||
* refs #1593 add python libs and executables
|
||||
* updates CHANGELOG 0.6.0
|
||||
* refs #1592 move client/shared files
|
||||
|
||||
-- Tu Nombre <tuemail@example.com> Mon, 10 Mar 2025 19:33:51 +0000
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
Source: ogboot
|
||||
Section: unknown
|
||||
Priority: optional
|
||||
Maintainer: vagrant <vagrant@build>
|
||||
Rules-Requires-Root: no
|
||||
Build-Depends:
|
||||
debhelper-compat (= 13),
|
||||
Standards-Version: 4.6.2
|
||||
Homepage: <insert the upstream URL, if relevant>
|
||||
#Vcs-Browser: https://salsa.debian.org/debian/ogboot
|
||||
#Vcs-Git: https://salsa.debian.org/debian/ogboot.git
|
||||
|
||||
Package: ogboot
|
||||
Architecture: any
|
||||
Multi-Arch: foreign
|
||||
Depends:
|
||||
${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
debconf (>= 1.5.0),
|
||||
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,
|
||||
libdbi-dev,
|
||||
libdbi1t64,
|
||||
libev-dev,
|
||||
libjansson-dev,
|
||||
liblz4-tool,
|
||||
libssl-dev,
|
||||
moreutils,
|
||||
netpipes,
|
||||
php8.3,
|
||||
php8.3-bcmath,
|
||||
php8.3-cli,
|
||||
php8.3-curl,
|
||||
php8.3-fpm,
|
||||
php8.3-gd,
|
||||
php8.3-ldap,
|
||||
php8.3-mbstring,
|
||||
php8.3-mysql,
|
||||
php8.3-common,
|
||||
php-pear,
|
||||
php8.3-xml,
|
||||
php8.3-zip,
|
||||
procps,
|
||||
coreutils,
|
||||
rsync,
|
||||
samba,
|
||||
samba-common-bin,
|
||||
schroot,
|
||||
shim-signed,
|
||||
squashfs-tools,
|
||||
subversion,
|
||||
tftpd-hpa,
|
||||
udpcast,
|
||||
unzip,
|
||||
wakeonlan,
|
||||
wget,
|
||||
xinetd,
|
||||
isolinux,
|
||||
file
|
||||
Conflicts: apache2
|
||||
Description: Opengnsys Ogboot package
|
||||
Files for the ogboot API and rest of configuration.
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Source: <url://example.com>
|
||||
Upstream-Name: ogboot
|
||||
Upstream-Contact: <preferred name and address to reach the upstream project>
|
||||
|
||||
Files:
|
||||
*
|
||||
Copyright:
|
||||
<years> <put author's name and email here>
|
||||
<years> <likewise for another author>
|
||||
License: GPL-3.0+
|
||||
|
||||
Files:
|
||||
debian/*
|
||||
Copyright:
|
||||
2025 vagrant <vagrant@build>
|
||||
License: GPL-3.0+
|
||||
|
||||
License: GPL-3.0+
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
Comment:
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
|
||||
# Please also look if there are files or directories which have a
|
||||
# different copyright/license attached and list them here.
|
||||
# Please avoid picking licenses with terms that are more restrictive than the
|
||||
# packaged work, as it may make Debian's contributions unacceptable upstream.
|
||||
#
|
||||
# If you need, there are some extra license texts available in two places:
|
||||
# /usr/share/debhelper/dh_make/licenses/
|
||||
# /usr/share/common-licenses/
|
||||
|
|
@ -0,0 +1 @@
|
|||
ogboot
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
README.source
|
||||
README.Debian
|
||||
README
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
. /usr/share/debconf/confmodule
|
||||
|
||||
db_input high opengnsys/ogboot_ip || true
|
||||
db_input high opengnsys/ogboot_port || true
|
||||
db_input high opengnsys/ogboot_ogcoreUrl || true
|
||||
db_input high opengnsys/ogboot_ogliveUrl || true
|
||||
# db_input high opengnsys/ogboot_sambaUser || true
|
||||
# db_input high opengnsys/ogboot_sambaUserPass || true
|
||||
|
||||
db_go
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/opt/opengnsys/ogboot/client_log
|
||||
/opt/opengnsys/ogboot/mnt
|
||||
/opt/opengnsys/ogboot/tftpboot
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
api /opt/opengnsys/ogboot
|
||||
etc /opt/opengnsys/ogboot
|
||||
lib /opt/opengnsys/ogboot
|
||||
bin /opt/opengnsys/ogboot
|
||||
tftpboot /opt/opengnsys/ogboot/
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
# Cargar el módulo de configuración de debconf
|
||||
. /usr/share/debconf/confmodule
|
||||
|
||||
# Leer las variables de configuración
|
||||
OGBOOT_ROOT="/opt/opengnsys/ogboot"
|
||||
OGBOOT_API_DIR="/opt/opengnsys/ogboot/api"
|
||||
db_get opengnsys/ogboot_ip
|
||||
OGBOOT_IP="$RET"
|
||||
db_get opengnsys/ogboot_port
|
||||
OGBOOT_PORT="$RET"
|
||||
db_get opengnsys/ogboot_ogcoreUrl
|
||||
OGCORE_API_URL="$RET"
|
||||
db_get opengnsys/ogboot_ogliveUrl
|
||||
OGCORE_OGLIVE_URL="$RET"
|
||||
# db_get opengnsys/ogboot_sambaUser
|
||||
# SAMBA_USER="$RET"
|
||||
# db_get opengnsys/ogboot_sambaUserPass
|
||||
# SAMBA_PASS="$RET"
|
||||
|
||||
|
||||
# IPXE_REPO="https://github.com/ipxe/ipxe.git"
|
||||
IPXE_REPO="https://ognproject.evlt.uma.es/gitea/narenas/opengnsys_ipxe.git"
|
||||
|
||||
# Asegurarse de que el usuario exista
|
||||
USER="opengnsys"
|
||||
USER_INFO=$(getent passwd "$USER")
|
||||
DEFAULT_OGLIVE=$OGCORE_OGLIVE_URL
|
||||
ENV_FILE=/opt/opengnsys/ogboot/api/.env
|
||||
if [ -z "$USER_INFO" ]; then
|
||||
echo "Error: El usuario '$USER' no existe." >&2
|
||||
exit 1
|
||||
fi
|
||||
USER_UID=$(echo "$USER_INFO" | cut -d: -f3)
|
||||
USER_GID=$(echo "$USER_INFO" | cut -d: -f4)
|
||||
|
||||
|
||||
INSTALL_OGBOOT_TARGET="/opt/opengnsys/ogboot"
|
||||
fstab_entries=(
|
||||
"$INSTALL_OGBOOT_TARGET/lib/oglive.iso $INSTALL_OGBOOT_TARGET/mnt iso9660 loop,ro,users,uid=$USER_UID,gid=$USER_GID,noauto 0 0"
|
||||
"/opt/opengnsys/ogboot/tftpboot/ogLive/ogclient.sqfs /tmp/ogclient_mount squashfs loop,ro,user,noauto 0 0"
|
||||
)
|
||||
fstab_file="/etc/fstab"
|
||||
|
||||
|
||||
configure_sudo() {
|
||||
echo "Copiando configuración de sudo"
|
||||
if [ ! -f /etc/sudoers.d/opengnsys ]; then
|
||||
cp /opt/opengnsys/ogboot/etc/ogboot.sudoers /etc/sudoers.d/opengnsys
|
||||
chmod 440 /etc/sudoers.d/opengnsys
|
||||
sed -i "s|__OGBOOT_TARGET__|$OGBOOT_ROOT|g" /etc/sudoers.d/opengnsys
|
||||
else
|
||||
echo "El archivo /etc/sudoers.d/opengnsys ya existe."
|
||||
fi
|
||||
}
|
||||
|
||||
add_fstab_entries(){
|
||||
echo "Añadiendo entradas a /etc/fstab"
|
||||
for entry in "${fstab_entries[@]}"; do
|
||||
if ! grep -Fxq "$entry" "$fstab_file"; then
|
||||
echo "$entry" | sudo tee -a "$fstab_file" > /dev/null
|
||||
echo "Entrada añadida a /etc/fstab: $entry"
|
||||
else
|
||||
echo "La entrada ya existe en /etc/fstab: $entry"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
update_opengnsys_user() {
|
||||
echo "Actualizando grupos del usuario opengnsys"
|
||||
usermod -aG disk "$USER"
|
||||
}
|
||||
|
||||
configure_tftp(){
|
||||
|
||||
echo "Modificando el archivo tftpboot"
|
||||
|
||||
# Comprobar si el archivo ya está desviado
|
||||
if ! dpkg-divert --list /etc/default/tftpd-hpa | grep -q "/etc/default/tftpd-hpa"; then
|
||||
echo "Creando divert para /etc/default/tftpd-hpa"
|
||||
dpkg-divert --add --rename --divert /etc/default/tftpd-hpa.orig /etc/default/tftpd-hpa
|
||||
fi
|
||||
|
||||
# Copiar archivo solo si no existe en la nueva ubicación
|
||||
if [ ! -f /etc/default/tftpd-hpa ]; then
|
||||
echo "Copiando configuración de tftpd-hpa"
|
||||
cp /opt/opengnsys/ogboot/etc/default/tftpd-hpa /etc/default/tftpd-hpa
|
||||
fi
|
||||
}
|
||||
|
||||
install_oglive(){
|
||||
echo "Download ogLive"
|
||||
MAX_ATTEMPTS=3
|
||||
ATTEMPT=1
|
||||
SUCCESS=0
|
||||
while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do
|
||||
/opt/opengnsys/ogboot/bin/oglivecli download "$DEFAULT_OGLIVE" && SUCCESS=1 && break
|
||||
echo "Intento $ATTEMPT de descarga de ogLive fallido."
|
||||
ATTEMPT=$((ATTEMPT+1))
|
||||
sleep 2
|
||||
done
|
||||
if [ $SUCCESS -eq 0 ]; then
|
||||
echo "Error: No se pudo descargar ogLive después de $MAX_ATTEMPTS intentos. Continuando..."
|
||||
fi
|
||||
}
|
||||
|
||||
configure_ipxe(){
|
||||
echo "Configure ipxe templates"
|
||||
cp $OGBOOT_ROOT/etc/dhcp_boot.ipxe.tmpl $OGBOOT_ROOT/tftpboot/ipxe_scripts/dhcp_boot.ipxe
|
||||
cp $OGBOOT_ROOT/etc/default.ipxe.tmpl $OGBOOT_ROOT/tftpboot/ipxe_scripts/default.ipxe
|
||||
sed -i "s|__SERVERIP__|$OGBOOT_IP|g" $OGBOOT_ROOT/tftpboot/ipxe_scripts/dhcp_boot.ipxe
|
||||
sed -i "s|__SERVERIP__|$OGBOOT_IP|g" $OGBOOT_ROOT/tftpboot/ipxe_scripts/default.ipxe
|
||||
|
||||
echo "Instalando ipxe"
|
||||
rm -rf /tmp/ipxe_repo
|
||||
git clone $IPXE_REPO /tmp/ipxe_repo
|
||||
if [ ! -f $OGBOOT_ROOT/tftpboot/undionly.kpxe ]; then
|
||||
cd /tmp/ipxe_repo/src
|
||||
make -j4 -s bin/undionly.kpxe EMBED=$OGBOOT_ROOT/tftpboot/ipxe_scripts/dhcp_boot.ipxe
|
||||
make -j4 -s bin-x86_64-efi/ipxe.efi EMBED=$OGBOOT_ROOT/tftpboot/ipxe_scripts/dhcp_boot.ipxe
|
||||
cp bin/undionly.kpxe $OGBOOT_ROOT/tftpboot/
|
||||
cp bin-x86_64-efi/ipxe.efi $OGBOOT_ROOT/tftpboot/
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
configure_api(){
|
||||
if ! grep -q "OGCORE_API_URL" $ENV_FILE; then
|
||||
echo "OGCORE_API_URL=$OGCORE_API_URL" >> $ENV_FILE
|
||||
fi
|
||||
if ! grep -q "OGBOOT_IP" $ENV_FILE; then
|
||||
echo "OGBOOT_IP=$OGBOOT_IP" >> $ENV_FILE
|
||||
fi
|
||||
if ! grep -q "OGBOOT_PORT" $ENV_FILE; then
|
||||
echo "OGBOOT_PORT=$OGBOOT_PORT" >> $ENV_FILE
|
||||
fi
|
||||
}
|
||||
|
||||
configure_nginx_and_fpm() {
|
||||
echo "Configure nginx"
|
||||
PHP_VERSION=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
|
||||
if [ ! -f /etc/nginx/sites-available/ogboot.conf ]; then
|
||||
cp /opt/opengnsys/ogboot/etc/nginxServer.conf.tmpl /etc/nginx/sites-available/ogboot.conf
|
||||
sed -i "s|__ROOT__|$OGBOOT_API_DIR|g" /etc/nginx/sites-available/ogboot.conf
|
||||
sed -i "s|__PHPVERSION__|$PHP_VERSION|g" /etc/nginx/sites-available/ogboot.conf
|
||||
sed -i "s|__SERVERIP__|$OGBOOT_IP|g" /etc/nginx/sites-available/ogboot.conf
|
||||
sed -i "s|__PORT__|$OGBOOT_PORT|g" /etc/nginx/sites-available/ogboot.conf
|
||||
sed -i "s|__TFTPPATH__|$OGBOOT_ROOT/tftpboot|g" /etc/nginx/sites-available/ogboot.conf
|
||||
ln -s /etc/nginx/sites-available/ogboot.conf /etc/nginx/sites-enabled/ogboot.conf
|
||||
else
|
||||
echo "El archivo /etc/nginx/sites-available/opengnsys ya existe."
|
||||
fi
|
||||
|
||||
echo "Modificando el fpm"
|
||||
if [ ! -f /etc/php/$PHP_VERSION/fpm/pool.d/ogboot.conf ]; then
|
||||
cp /opt/opengnsys/ogboot/etc/ogboot-fpm.conf /etc/php/$PHP_VERSION/fpm/pool.d/ogboot.conf
|
||||
fi
|
||||
}
|
||||
|
||||
configure_samba(){
|
||||
echo "Configurando Samba"
|
||||
cp /opt/opengnsys/ogboot/etc/smb-ogboot.conf.tmpl /etc/samba/smb-ogboot.conf
|
||||
sed -i "s|__OGBOOTDIR__|$OGBOOT_ROOT|g" /etc/samba/smb-ogboot.conf
|
||||
INCLUDE_LINE="include = /etc/samba/smb-ogboot.conf"
|
||||
if ! grep -q "$INCLUDE_LINE" /etc/samba/smb.conf; then
|
||||
echo "$INCLUDE_LINE" | sudo tee -a /etc/samba/smb.conf > /dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
configure_permissions(){
|
||||
echo "Cambiando la propiedad de los archivos al usuario $USER"
|
||||
chown opengnsys:www-data /opt/opengnsys/
|
||||
chown -R opengnsys:www-data /opt/opengnsys/ogboot
|
||||
}
|
||||
|
||||
restart_services(){
|
||||
systemctl daemon-reload
|
||||
systemctl restart nginx
|
||||
systemctl restart tftpd-hpa
|
||||
systemctl restart php8.3-fpm
|
||||
systemctl restart samba
|
||||
}
|
||||
|
||||
# Detectar si es una instalación nueva o una actualización
|
||||
if [ "$1" = "configure" ] && [ -z "$2" ]; then
|
||||
# Copy sudo configuration
|
||||
echo "Primera instalación"
|
||||
configure_sudo
|
||||
add_fstab_entries
|
||||
update_opengnsys_user
|
||||
configure_tftp
|
||||
install_oglive
|
||||
configure_ipxe
|
||||
configure_api
|
||||
configure_nginx_and_fpm
|
||||
configure_samba
|
||||
|
||||
|
||||
elif [ "$1" = "configure" ] && [ -n "$2" ]; then
|
||||
echo "Actualización desde la versión $2"
|
||||
configure_sudo
|
||||
configure_tftp
|
||||
configure_api
|
||||
configure_nginx_and_fpm
|
||||
configure_samba
|
||||
fi
|
||||
|
||||
configure_permissions
|
||||
restart_services
|
||||
|
||||
|
||||
exit 0
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
CONFIG_FILE="/etc/default/tftpd-hpa"
|
||||
DIVERTED_FILE="/etc/default/tftpd-hpa.orig"
|
||||
|
||||
if [ "$1" = "remove" ]; then
|
||||
echo "Restaurando archivo de configuración original..."
|
||||
|
||||
# Restaurar el archivo original si existe
|
||||
if [ -f "$DIVERTED_FILE" ]; then
|
||||
mv "$DIVERTED_FILE" "$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
# Eliminar la desviación
|
||||
dpkg-divert --remove --rename "$CONFIG_FILE"
|
||||
# Eliminar la linea de inclusión de samba en smb.conf si existe
|
||||
INCLUDE_LINE="include = /etc/samba/opengnsys/smb_ogboot.conf"
|
||||
if grep -q "$INCLUDE_LINE" /etc/samba/smb.conf; then
|
||||
sed -i "/$INCLUDE_LINE/d" /etc/samba/smb.conf
|
||||
fi
|
||||
|
||||
fi
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# Automatically added by dh_installdebconf/13.14.1ubuntu5
|
||||
if [ "$1" = purge ] && [ -e /usr/share/debconf/confmodule ]; then
|
||||
. /usr/share/debconf/confmodule
|
||||
db_purge
|
||||
fi
|
||||
# End automatically added section
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Asegurarse de que el usuario exista
|
||||
USER="opengnsys"
|
||||
HOME_DIR="/opt/opengnsys"
|
||||
if id "$USER" &>/dev/null; then
|
||||
echo "El usuario $USER ya existe."
|
||||
else
|
||||
echo "Creando el usuario $USER con home en $HOME_DIR."
|
||||
useradd -m -d "$HOME_DIR" -s /bin/bash "$USER"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
remove|upgrade|deconfigure)
|
||||
echo "Deteniendo servicios antes de la eliminación o actualización..."
|
||||
systemctl stop nginx || true
|
||||
systemctl stop tftpd-hpa || true
|
||||
systemctl stop php8.3-fpm || true
|
||||
systemctl stop samba || true
|
||||
|
||||
echo "Eliminando configuraciones específicas..."
|
||||
if [ "$1" = "remove" ]; then
|
||||
rm -f /etc/nginx/sites-enabled/ogboot.conf
|
||||
rm -f /etc/nginx/sites-available/ogboot.conf
|
||||
rm -f /etc/sudoers.d/opengnsys
|
||||
rm -f /etc/php/8.3/fpm/pool.d/ogboot.conf
|
||||
dpkg-divert --remove --rename --divert /etc/default/tftpd-hpa.orig /etc/default/tftpd-hpa || true
|
||||
dpkg-divert --remove --rename --divert /opt/opengnsys/ogboot/.env.local.php.orig /opt/opengnsys/ogboot/.env.local.php || true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
Template: opengnsys/ogboot_ip
|
||||
Type: string
|
||||
Default: 192.168.1.100
|
||||
Description: Introduce la IP donde se ejecutará OGBOOT
|
||||
Esta IP será utilizada para la configuración del servicio.
|
||||
|
||||
Template: opengnsys/ogboot_port
|
||||
Type: string
|
||||
Default: 8082
|
||||
Description: Puerto para OGBOOT
|
||||
Por favor introduce el puerto donde escuchará ogBoot
|
||||
|
||||
Template: opengnsys/ogboot_ogcoreUrl
|
||||
Type: string
|
||||
Default: https://127.0.0.1:8443
|
||||
Description: URL del API de ogCore
|
||||
Por favor introduzca la URL donde se ejecuta ogCore
|
||||
|
||||
Template: opengnsys/ogboot_ogliveUrl
|
||||
Type: string
|
||||
Default: https://ognproject.evlt.uma.es/oglive/ogLive-noble-6.8.0-31-generic-amd64-r20250116.538e3fa_20250120.iso
|
||||
Description: URL del OgLive a instalar
|
||||
Por favor introduzca la URL desde donde descargar el ogLive para su uso.
|
||||
|
||||
Template: opengnsys/ogboot_sambaUser
|
||||
Type: string
|
||||
Default: opengnsys
|
||||
Description: Usuario de samba para compartir tftpboot y client_log
|
||||
No cambiar a no ser que se sepa lo que se esta haciendo
|
||||
|
||||
Template: opengnsys/ogboot_sambaUserPass
|
||||
Type: password
|
||||
Default: og
|
||||
Description: Password del Usuario de samba para compartir tftpboot y client_log
|
||||
No cambiar a no ser que se sepa lo que se esta haciendo
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
# Ejecutar composer install durante la fase de construcción
|
||||
override_dh_auto_build:
|
||||
cd api/; \
|
||||
rm -rf var/cache/*; \
|
||||
mkdir -p public; \
|
||||
COMPOSER_ALLOW_SUPERUSER=1 APP_ENV=prod composer install --no-interaction --no-progress --optimize-autoloader; \
|
||||
COMPOSER_ALLOW_SUPERUSER=1 APP_ENV=prod composer update doctrine/dbal;
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
3.0 (native)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"project": "Ogboot",
|
||||
"version": "0.1.1",
|
||||
"codename": "Espeto",
|
||||
"definition": "http://www.andalucia.com/gastronomy/espeto.htm",
|
||||
"release": "",
|
||||
"ogagent": "1.1.2"
|
||||
}
|
||||
|
|
@ -0,0 +1,795 @@
|
|||
## Diseño de la Lógica y Comunicación entre los Endpoints del Componente `ogboot` y el Servidor `ogCore`
|
||||
|
||||
### Introducción
|
||||
|
||||
El componente `ogboot` se encarga de la gestión y configuración de archivos de arranque (iPXE) y plantillas en un entorno de despliegue de imágenes. El servidor `ogCore` es el núcleo que interactúa con `ogboot` para realizar operaciones de administración y configuración. Este documento describe la lógica y la comunicación entre los endpoints del componente `ogboot` y el servidor `ogCore`.
|
||||
|
||||
### Endpoints del Componente `ogboot`
|
||||
|
||||
|
||||
#### Endpoints del Recurso `oglive`
|
||||
|
||||
1. **Ver todos los ogLives instalados**
|
||||
- **URL**: `/ogboot/v1/oglives`
|
||||
- **Método HTTP**: GET
|
||||
- **Descripción**: Obtiene información sobre todos los ogLives instalados.
|
||||
- **Respuesta**:
|
||||
```json
|
||||
[
|
||||
"ogLive-5.0.0-r20190605",
|
||||
"ogLive-5.11.0-r20210413",
|
||||
"ogLive-5.13.0-27-r20210706"
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
2. **Obtener Información de un ogLive**
|
||||
- **URL**: `/ogboot/v1/oglives/{uuid}`
|
||||
- **Método HTTP**: GET
|
||||
- **Descripción**: Obtiene información sobre un cliente ogLive instalado utilizando su nombre.
|
||||
- **Parámetros**:
|
||||
- `uuid` (string): uuid del ogLive.
|
||||
- **Respuesta**:
|
||||
```json
|
||||
{
|
||||
"distribution": "uuid",
|
||||
"distribution": "focal",
|
||||
"kernel": "5.13.0-27",
|
||||
"architecture": "amd64",
|
||||
"revision": "r20210706.5b4bf5f",
|
||||
"directory": "ogLive-focal-5.13.0-27-beta-amd64-r20210706.5b4bf5f",
|
||||
"iso": "ogLive-focal-5.13.0-27-beta-amd64-r20210706.5b4bf5f.iso"
|
||||
}
|
||||
```
|
||||
- **Respuestas**:
|
||||
- **200 OK**: Información del ogLive obtenida exitosamente.
|
||||
- **404 Not Found**: ogLive no encontrado.
|
||||
|
||||
3. **Obtener Información del ogLive Predeterminado**
|
||||
- **URL**: `/ogboot/v1/oglives/default`
|
||||
- **Método HTTP**: GET
|
||||
- **Descripción**: Obtiene información sobre el cliente ogLive predeterminado.
|
||||
- **Ejemplo de Solicitud**:
|
||||
```bash
|
||||
curl -X GET -H "Authorization: $API_KEY" http://example.com/ogboot/v1/oglives/default
|
||||
```
|
||||
- **Respuesta**:
|
||||
```json
|
||||
{
|
||||
"distribution": "focal",
|
||||
"kernel": "5.13.0-27",
|
||||
"architecture": "amd64",
|
||||
"revision": "r20210706.5b4bf5f",
|
||||
"directory": "ogLive-focal-5.13.0-27-beta-amd64-r20210706.5b4bf5f",
|
||||
"iso": "ogLive-focal-5.13.0-27-beta-amd64-r20210706.5b4bf5f.iso"
|
||||
}
|
||||
```
|
||||
|
||||
- **Respuestas**:
|
||||
- **200 OK**: Información del ogLive predeterminado obtenida exitosamente.
|
||||
- **500 Internal Server Error**: Error al obtener la información del ogLive predeterminado.
|
||||
|
||||
|
||||
4. **Establecer ogLive Predeterminado**
|
||||
- **URL**: `/ogboot/v1/oglives/default/{uuid}`
|
||||
- **Método HTTP**: POST
|
||||
- **Descripción**: Establece un cliente ogLive como predeterminado utilizando su nombre.
|
||||
- **Parámetros**:
|
||||
- `uuid` (string): uuid del ogLive a establecer como predeterminado.
|
||||
- **Respuestas**:
|
||||
- **200 OK**: ogLive establecido como predeterminado exitosamente.
|
||||
- **404 Not Found**: ogLive no encontrado.
|
||||
- **500 Internal Server Error**: Error al establecer el ogLive como predeterminado.
|
||||
|
||||
|
||||
|
||||
5. **Ver la lista de ogLives disponibles para descargar**
|
||||
- **URL**: `/ogboot/v1/oglives/isos`
|
||||
- **Método HTTP**: GET
|
||||
- **Respuesta**:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"filename": "ogLive-focal-5.13.0-27-beta-amd64-r20210706.5b4bf5f.iso",
|
||||
"installed": false,
|
||||
"compatible": true
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"filename": "ogLive-focal-5.11.0-22-generic-amd64-r20210413.992ebb9.iso",
|
||||
"installed": false,
|
||||
"compatible": true
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"filename": "ogLive-focal-5.8.0-50-generic-amd64-r20210413.992ebb9.iso",
|
||||
"installed": false,
|
||||
"compatible": true
|
||||
},
|
||||
{
|
||||
"id": "4",
|
||||
"filename": "ogLive-bionic-5.4.0-40-generic-amd64-r20200629.85eceaf.iso",
|
||||
"installed": false,
|
||||
"compatible": true
|
||||
},
|
||||
|
||||
]
|
||||
|
||||
```
|
||||
- **500 Internal Server Error**: Error en la conexión.
|
||||
|
||||
|
||||
6. **Crear un ogLive**
|
||||
- **URL**: `/ogboot/v1/oglives`
|
||||
- **Método HTTP**: POST
|
||||
- **Descripción**: Crea un nuevo ogLive utilizando el nombre del ISO proporcionado.
|
||||
- **Cuerpo de la Solicitud**:
|
||||
```json
|
||||
{
|
||||
"isoName": "ogLive-focal-5.13.0-27-beta-amd64-r20210706.5b4bf5f.iso"
|
||||
}
|
||||
```
|
||||
- **Ejemplo de Solicitud**:
|
||||
```bash
|
||||
curl -X POST -H "Authorization: $API_KEY" -d '{"isoName": "ogLive-focal-5.13.0-27-beta-amd64-r20210706.5b4bf5f.iso"}' http://example.com/ogboot/v1/oglives
|
||||
```
|
||||
- **Respuestas**:
|
||||
- **200 OK**: ogLive creado exitosamente.
|
||||
- **400 Bad Request**: Error en los datos proporcionados.
|
||||
- **500 Internal Server Error**: Error al crear el ogLive.
|
||||
|
||||
7. **Eliminar un ogLive**
|
||||
- **URL**: `/ogboot/v1/oglives/{uuid}`
|
||||
- **Método HTTP**: DELETE
|
||||
- **Descripción**: Elimina un ogLive específico utilizando su nombre.
|
||||
- **Parámetros**:
|
||||
- `name` (string): Nombre del ogLive.
|
||||
- **Respuestas**:
|
||||
- **200 OK**: ogLive eliminado exitosamente.
|
||||
- **404 Not Found**: ogLive no encontrado.
|
||||
- **500 Internal Server Error**: Error al eliminar el ogLive.
|
||||
|
||||
|
||||
|
||||
#### Endpoints del Recurso `pxe` y `pxe-template`
|
||||
|
||||
1. **Obtener Todos los Archivos de Arranque**
|
||||
- **URL**: `/ogboot/v1/pxes`
|
||||
- **Método HTTP**: GET
|
||||
- **Descripción**: Obtiene una lista de todos los archivos de arranque disponibles.
|
||||
- **Respuesta**: Lista de archivos de arranque en formato JSON.
|
||||
|
||||
2. **Obtener Configuración de Arranque**
|
||||
- **URL**: `/ogboot/v1/pxes/{mac}`
|
||||
- **Método HTTP**: GET
|
||||
- **Descripción**: Obtiene el contenido del archivo de configuración de arranque específico para un cliente utilizando su dirección MAC.
|
||||
- **Respuesta**: Archivo de arranque en formato adecuado.
|
||||
```json
|
||||
{
|
||||
"template_name": "pxe",
|
||||
"mac": "00:50:56:22:11:12",
|
||||
"lang": "es_ES.UTF-8",
|
||||
"ip": "192.168.2.11",
|
||||
"server_ip": "192.168.2.1",
|
||||
"router": "192.168.2.1",
|
||||
"netmask": "255.255.255.0",
|
||||
"computer_name": "pc11",
|
||||
"netiface": "eth0",
|
||||
"group": "Aula_virtual",
|
||||
"ogrepo": "192.168.2.1",
|
||||
"oglive": "192.168.2.1",
|
||||
"oglog": "192.168.2.1",
|
||||
"ogshare": "192.168.2.1",
|
||||
"oglivedir": "ogLive",
|
||||
"ogprof": "false",
|
||||
"hardprofile": "",
|
||||
"ogntp": "",
|
||||
"ogdns": "",
|
||||
"ogproxy": "",
|
||||
"ogunit": "",
|
||||
"resolution": "788"
|
||||
}
|
||||
|
||||
```
|
||||
3. **Crear Archivo de Arranque**
|
||||
- **URL**: `/ogboot/v1/pxes`
|
||||
- **Método HTTP**: POST
|
||||
- **Descripción**: Crea un nuevo archivo de arranque utilizando los parámetros proporcionados.
|
||||
- **Cuerpo de la Solicitud**:
|
||||
```json
|
||||
{
|
||||
"template_name": "pxe",
|
||||
"mac": "00:50:56:22:11:12",
|
||||
"lang": "es_ES.UTF-8",
|
||||
"ip": "192.168.2.11",
|
||||
"server_ip": "192.168.2.1",
|
||||
"router": "192.168.2.1",
|
||||
"netmask": "255.255.255.0",
|
||||
"computer_name": "pc11",
|
||||
"netiface": "eth0",
|
||||
"group": "Aula_virtual",
|
||||
"ogrepo": "192.168.2.1",
|
||||
"oglive": "192.168.2.1",
|
||||
"oglog": "192.168.2.1",
|
||||
"ogshare": "192.168.2.1",
|
||||
"oglivedir": "ogLive",
|
||||
"ogprof": "false",
|
||||
"hardprofile": "",
|
||||
"ogntp": "",
|
||||
"ogdns": "",
|
||||
"ogproxy": "",
|
||||
"ogunit": "",
|
||||
"resolution": "788"
|
||||
}
|
||||
|
||||
```
|
||||
- **Respuesta**: Mensaje de éxito o error.
|
||||
|
||||
4. **Eliminar Archivo de Arranque**
|
||||
- **URL**: `/ogboot/v1/pxes/{name}`
|
||||
- **Método HTTP**: DELETE
|
||||
- **Descripción**: Elimina un archivo de arranque específico utilizando su dirección MAC.
|
||||
- **Respuesta**: Mensaje de éxito o error.
|
||||
|
||||
5. **Obtener Todas las Plantillas de Arranque**
|
||||
- **URL**: `/ogboot/v1/pxe-templates`
|
||||
- **Método HTTP**: GET
|
||||
- **Descripción**: Obtiene una lista de todas las plantillas de arranque disponibles.
|
||||
- **Respuesta**: Lista de plantillas en formato JSON.
|
||||
```json
|
||||
{
|
||||
"templates": [
|
||||
"pxe",
|
||||
"pxe2",
|
||||
"pxe_default"
|
||||
]
|
||||
}
|
||||
```
|
||||
6. **Obtener Contenido de una Plantilla**
|
||||
- **URL**: `/ogboot/v1/pxe-templates/{name}`
|
||||
- **Método HTTP**: GET
|
||||
- **Descripción**: Obtiene el contenido de una plantilla de arranque específica utilizando su nombre.
|
||||
- **Respuesta**: Contenido de la plantilla en formato adecuado.
|
||||
|
||||
7. **Crear Plantilla de Arranque**
|
||||
- **URL**: `/ogboot/v1/pxe-templates`
|
||||
- **Método HTTP**: POST
|
||||
- **Descripción**: Crea una nueva plantilla de arranque utilizando los datos proporcionados.
|
||||
- **Cuerpo de la Solicitud**:
|
||||
```json
|
||||
{
|
||||
"name_template": "pxe",
|
||||
"content_template": "contenido_de_la_plantilla"
|
||||
}
|
||||
```
|
||||
- **Respuesta**: Mensaje de éxito o error.
|
||||
|
||||
8. **Eliminar Plantilla de Arranque**
|
||||
- **URL**: `/ogboot/v1/pxe-templates/{name}`
|
||||
- **Método HTTP**: DELETE
|
||||
- **Descripción**: Elimina una plantilla de arranque específica utilizando su nombre.
|
||||
- **Respuesta**: Mensaje de éxito o error.
|
||||
|
||||
|
||||
|
||||
|
||||
## Flujos de Trabajo
|
||||
|
||||
Para los nuevos flujos de trabajo, asumimos que habrá al menos una nueva tabla en ogCore para almacenar la información de los ogLives y su estado. Esta tabla permitirá a ogCore gestionar y sincronizar la información con ogBoot.
|
||||
|
||||
|
||||
### Propuesta de definición de la tabla `ogLive`
|
||||
|
||||
|
||||
| Atributo | Tipo de Dato | Descripción |
|
||||
|----------------|----------------|-----------------------------------------------------------------|
|
||||
| `id` | `SERIAL` | Identificador del ogLive que corresponde a su suma de comprobación |
|
||||
| `distribution` | `VARCHAR(50)` | Nombre de la distribución del ogLive (por ejemplo, "focal"). |
|
||||
| `kernel` | `VARCHAR(100)` | Versión del kernel del ogLive. |
|
||||
| `architecture` | `VARCHAR(10)` | Arquitectura del ogLive (por ejemplo, "amd64"). |
|
||||
| `revision` | `VARCHAR(50)` | Revisión del ogLive (por ejemplo, "r20210706"). |
|
||||
| `directory` | `VARCHAR(100)` | Nombre del directorio del ogLive en el sistema de archivos. |
|
||||
| `iso` | `VARCHAR(255)` | Nombre del archivo ISO del ogLive. |
|
||||
| `is_default` | `BOOLEAN` | Indica si el ogLive es el predeterminado (`true` o `false`). |
|
||||
|
||||
### Ejemplo de Registro
|
||||
|
||||
| `id` | `distribution` | `kernel` | `architecture` | `revision` | `directory` | `iso` | `is_default` |
|
||||
|------|----------------|---------------------|----------------|-------------|--------------------------|-------------------------------------------------------|--------------|
|
||||
| 1 | focal | 5.13.0-27-beta | amd64 | r20210706 | ogLive-5.13.0-r20210706 | ogLive-focal-5.13.0-27-beta-amd64-r20210706.5b4bf5f.iso | true |
|
||||
|
||||
|
||||
|
||||
|
||||
### Flujo de trabajo para instalar un `ogLive`
|
||||
|
||||
#### 1. Consultar los `ogLives` Instalados
|
||||
|
||||
- **Descripción**: Obtener la lista de `ogLives` que están actualmente instalados en el sistema.
|
||||
- **Interacción en la Web**:
|
||||
- El usuario navega a la sección de `ogLives` en el panel de administración.
|
||||
- Hace clic en "Ver `ogLives` instalados".
|
||||
- El sistema realiza una llamada a la API para obtener la lista de `ogLives` instalados.
|
||||
|
||||
**Realización**: Puede realizarse directamente desde **`ogCore`** mediante una consulta a la base de datos `oglives`.
|
||||
|
||||
**Consulta SQL**:
|
||||
```sql
|
||||
SELECT * FROM oglives;
|
||||
```
|
||||
|
||||
**Endpoint**:
|
||||
- **`ogBoot`**: `/ogboot/v1/oglives`
|
||||
- **Método**: `GET`
|
||||
|
||||
#### 2. Consultar los `ogLives` disponibles para descargar
|
||||
|
||||
- **Descripción**: Obtener una lista de `ogLives` disponibles para descargar desde el servidor.
|
||||
- **Interacción en la Web**:
|
||||
- El usuario selecciona "Descargar nuevos `ogLives`" en la interfaz.
|
||||
- Aparece una lista de `ogLives` disponibles, obtenida mediante una consulta al servidor.
|
||||
|
||||
**Realización**: Necesita comunicación con **`ogBoot`**. Nota: Este proceso requiere de una consulta a Trac (o web) que se podría llevar a cabo desde el ogCore.
|
||||
|
||||
**Endpoint**:
|
||||
- **`ogBoot`**: `/ogboot/v1/isos`
|
||||
- **Método**: `GET`
|
||||
|
||||
#### 3. Instalar un `ogLive`
|
||||
|
||||
- **Descripción**: Instalar un `ogLive` seleccionado en el sistema.
|
||||
- **Interacción en la Web**:
|
||||
- El usuario selecciona un `ogLive` de la lista de disponibles y hace clic en "Instalar".
|
||||
- El sistema muestra un cuadro de confirmación, y al confirmar, se inicia el proceso de instalación.
|
||||
|
||||
**Realización**: Requiere comunicación con **`ogBoot`** para iniciar la instalación. Primero, se construye el JSON con los parámetros necesarios. La inserción en la base de datos `ogCore` solo se realiza después de que la instalación en `ogBoot` sea confirmada como exitosa.
|
||||
|
||||
- **Proceso de Instalación**:
|
||||
1. **Generación de JSON**: `ogCore` genera un JSON con los detalles del `ogLive`, incluyendo un UUID temporal.
|
||||
2. **Solicitud de Instalación**:
|
||||
- **Endpoint**: `/ogboot/v1/oglives`
|
||||
- **Método**: `POST`
|
||||
- **Cuerpo de la Solicitud**:
|
||||
```json
|
||||
{
|
||||
"uuid": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"directory": "ogLive-5.11.0-r20210413",
|
||||
"distribution": "focal",
|
||||
"kernel": "5.11.0-22-generic",
|
||||
"architecture": "amd64",
|
||||
"revision": "r20210413",
|
||||
"iso": "ogLive-focal-5.11.0-22-generic-amd64-r20210413.992ebb9.iso"
|
||||
}
|
||||
```
|
||||
3. **Validación de Instalación**: `ogBoot` intenta instalar el `ogLive` y devuelve un estado de éxito o fallo.
|
||||
4. **Actualización de Base de Datos**:
|
||||
- **Instalación Exitosa**: Si `ogBoot` confirma el éxito, `ogCore` inserta el nuevo `ogLive` en la base de datos:
|
||||
```sql
|
||||
INSERT INTO oglives (uuid, distribution, kernel, architecture, revision, directory, iso, is_default)
|
||||
VALUES ('550e8400-e29b-41d4-a716-446655440000', 'focal', '5.11.0-22-generic', 'amd64', 'r20210413', 'ogLive-5.11.0-r20210413', 'ogLive-focal-5.11.0-22-generic-amd64-r20210413.992ebb9.iso', false);
|
||||
```
|
||||
- **Instalación Fallida**: Si `ogBoot` reporta un fallo, no se realiza ninguna inserción y se maneja el error adecuadamente en la interfaz de usuario.
|
||||
|
||||
#### 4. Revisar un `ogLive` Instalado
|
||||
|
||||
- **Descripción**: Obtener detalles sobre un `ogLive` específico que está instalado.
|
||||
- **Interacción en la Web**:
|
||||
- El usuario selecciona un `ogLive` de la lista de instalados para ver detalles.
|
||||
- Se muestra la información detallada del `ogLive` seleccionado.
|
||||
|
||||
**Realización**: Puede realizarse desde **`ogCore`** mediante una consulta a la base de datos `oglives`.
|
||||
|
||||
**Consulta SQL**:
|
||||
```sql
|
||||
SELECT * FROM oglives WHERE directory = 'ogLive-5.13.0-r20210706';
|
||||
```
|
||||
|
||||
|
||||
### Flujo de trabajo para cambiar el `oglive` por defecto
|
||||
|
||||
#### 1. Consultar los `ogLives` Instalados
|
||||
|
||||
- **Descripción**: Obtener la lista de `ogLives` que están actualmente instalados en el sistema.
|
||||
- **Interacción en la Web**:
|
||||
- El usuario navega a la sección de `ogLives` en el panel de administración.
|
||||
- Hace clic en "Ver `ogLives` instalados".
|
||||
- El sistema realiza una llamada a la API para obtener la lista de `ogLives` instalados.
|
||||
|
||||
**Realización**: Puede realizarse directamente desde **`ogCore`** mediante una consulta a la base de datos `oglives`. Lo ideal sería hacerlo hacia **`ogBoot`** ya que tiene la fuente de información fidedigna del estado de los `ogLives` en el componente.
|
||||
|
||||
**Consulta SQL**:
|
||||
```sql
|
||||
SELECT * FROM oglives;
|
||||
```
|
||||
|
||||
**Endpoint**:
|
||||
- **`ogBoot`**: `/ogboot/v1/oglives`
|
||||
- **Método**: `GET`
|
||||
|
||||
#### 2. Ver el `ogLive` por Defecto
|
||||
|
||||
- **Descripción**: Obtener el `ogLive` que está configurado como predeterminado.
|
||||
- **Interacción en la Web**:
|
||||
- El usuario navega a la sección de configuración de `ogLives` en el panel de administración.
|
||||
- Hace clic en en el `ogLive` que está marcado por defecto.
|
||||
- El sistema realiza una consulta a la base de datos para obtener el `ogLive` predeterminado.
|
||||
|
||||
**Realización**: Puede realizarse desde **`ogCore`** mediante una consulta a la base de datos `oglives`.
|
||||
|
||||
**Consulta SQL**:
|
||||
```sql
|
||||
SELECT * FROM oglives WHERE directory = 'ogLive-5.13.0-r20210706';
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 3. Asignar `ogLive` por Defecto
|
||||
|
||||
- **Descripción**: Configurar un `ogLive` instalado como el predeterminado.
|
||||
- **Interacción en la Web**:
|
||||
- El usuario selecciona un `ogLive` de la lista de instalados.
|
||||
- Hace clic en "Configurar como `ogLive` por defecto".
|
||||
- Tras la confirmación, el sistema envía una solicitud para actualizar el `ogLive` por defecto.
|
||||
- El sistema actualiza la base de datos y comunica el cambio a `ogBoot`.
|
||||
|
||||
**Realización**: Requiere comunicación con **`ogBoot`** para modificar el `ogLive` por defecto en el TFTP boot del **`ogBoot`**.
|
||||
|
||||
**Consulta SQL**:
|
||||
```sql
|
||||
SELECT * FROM oglives WHERE directory = 'ogLive-5.13.0-r20210706';
|
||||
```
|
||||
|
||||
**Endpoint**:
|
||||
- **`ogBoot`**: `/ogboot/v1/oglives/default/550e8400-e29b-41d4-a716-446655440000`
|
||||
- **Método**: `POST`
|
||||
|
||||
**Actualizar Base de Datos**:
|
||||
- Tras la actualización en `ogBoot`, se debe actualizar la base de datos para reflejar el nuevo `ogLive` por defecto:
|
||||
```sql
|
||||
UPDATE oglives SET is_default = false WHERE is_default = true;
|
||||
UPDATE oglives SET is_default = true WHERE uuid = '550e8400-e29b-41d4-a716-446655440000';
|
||||
```
|
||||
|
||||
|
||||
### Flujo de trabajo para desinstalar un `ogLive`
|
||||
|
||||
#### 1. Consultar los `ogLives` Instalados
|
||||
|
||||
- **Descripción**: Obtener la lista de `ogLives` que están actualmente instalados en el sistema.
|
||||
- **Interacción en la Web**:
|
||||
- El usuario navega a la sección de `ogLives` en el panel de administración.
|
||||
- Hace clic en "Ver `ogLives` instalados".
|
||||
- El sistema realiza una llamada a la API para obtener la lista de `ogLives` instalados.
|
||||
|
||||
**Realización**: Puede realizarse directamente desde **`ogCore`** mediante una consulta a la base de datos `oglives`.
|
||||
|
||||
**Consulta SQL**:
|
||||
```sql
|
||||
SELECT * FROM oglives;
|
||||
```
|
||||
|
||||
**Endpoint**:
|
||||
- **`ogBoot`**: `/ogboot/v1/oglives`
|
||||
- **Método**: `GET`
|
||||
|
||||
|
||||
#### 2. Desinstalar `ogLive`
|
||||
|
||||
- **Descripción**: Iniciar el proceso de desinstalación del `ogLive` seleccionado en `ogBoot`.
|
||||
- **Interacción en la Web**:
|
||||
- En la lista de `ogLives` instalados, el usuario elige el `ogLive` a desinstalar.
|
||||
- Hace clic en el botón "Desinstalar" junto al `ogLive` seleccionado.
|
||||
- El sistema muestra un cuadro de confirmación preguntando si el usuario está seguro de desinstalar el `ogLive`.
|
||||
- El usuario hace clic en "Confirmar" para proceder.
|
||||
- El sistema envía una solicitud a `ogBoot` para desinstalar el `ogLive`.
|
||||
|
||||
**Realización**:
|
||||
- **Endpoint**: `/ogboot/v1/oglives/550e8400-e29b-41d4-a716-446655440000`
|
||||
- **Método**: `DELETE`
|
||||
- **Validación de Instalación**: `ogBoot` intenta desinstalar el `ogLive` y devuelve un estado de éxito o fallo.
|
||||
- **Actualización de Base de Datos**:
|
||||
- **Desinstalación Exitosa**: Si `ogBoot` confirma el éxito, `ogCore` elimina el `ogLive` en la base de datos:
|
||||
```sql
|
||||
DELETE FROM oglives WHERE uuid = '550e8400-e29b-41d4-a716-446655440000';
|
||||
```
|
||||
- **Instalación Fallida**: Si `ogBoot` reporta un fallo, no se realiza ningún borrado y se maneja el error adecuadamente en la interfaz de usuario.
|
||||
|
||||
|
||||
### Flujo de trabajo para corregir las incongruencias entre `ogCore` y `ogBoot`
|
||||
|
||||
|
||||
|
||||
#### 8. Revisar estado de ogboot
|
||||
|
||||
- **Descripción**: Comparar el estado actual de `ogboot` con la base de datos de `ogCore`, generando un informe de discrepancias.
|
||||
- **Realización**: Requiere comunicación con **`ogBoot`** para obtener el estado actual de los `ogLives` instalados, el `ogLive` por defecto, y las plantillas de arranque (`pxes`). Luego, `ogCore` compara estos datos con su base de datos y devuelve un informe de discrepancias.
|
||||
|
||||
**Endpoint**:
|
||||
- **`ogBoot`**: `/ogboot/v1/oglive/status`
|
||||
- **Método**: `GET`
|
||||
- **Resultado de la Solicitud**:
|
||||
```json
|
||||
{
|
||||
"installed_oglives": [
|
||||
{
|
||||
"name": "ogLive-5.13.0-r20210706",
|
||||
"kernel": "5.13.0-27-beta",
|
||||
"revision": "r20210706",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "ogLive-5.11.0-r20210413",
|
||||
"kernel": "5.11.0-22-generic",
|
||||
"revision": "r20210413",
|
||||
"default": false
|
||||
}
|
||||
],
|
||||
"installed_pxe_templates": [
|
||||
"default.ipxe",
|
||||
"template1.ipxe"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Informe de Discrepancias** (Ejemplo):
|
||||
```json
|
||||
{
|
||||
"discrepancies": {
|
||||
"oglives": [
|
||||
{
|
||||
"expected": {
|
||||
"name": "ogLive-5.13.0-r20210706",
|
||||
"default": true
|
||||
},
|
||||
"actual": {
|
||||
"name": "ogLive-5.11.0-r20210413",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"pxe_templates": [
|
||||
{
|
||||
"expected": "default.ipxe",
|
||||
"actual": "template1.ipxe"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### 9. Sincronizar Datos de `ogboot` con `ogCore`
|
||||
|
||||
- **Descripción**: `ogCore` sincroniza su base de datos con el estado actual de `ogboot`. Este proceso solo actualiza las discrepancias detectadas.
|
||||
- **Realización**: Requiere comunicación con **`ogBoot`** para obtener el estado actual. Luego, `ogCore` actualiza su base de datos con cualquier cambio detectado en los `ogLives` instalados, el `ogLive` por defecto, y las plantillas de arranque (`pxes`).
|
||||
|
||||
**Endpoint**:
|
||||
- **`ogBoot`**: `/ogboot/v1/sync`
|
||||
- **Método**: `GET`
|
||||
- **Resultado de la Solicitud**:
|
||||
```json
|
||||
{
|
||||
"installed_oglives": [
|
||||
{
|
||||
"name": "ogLive-5.13.0-r20210706",
|
||||
"kernel": "5.13.0-27-beta",
|
||||
"revision": "r20210706",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"name": "ogLive-5.11.0-r20210413",
|
||||
"kernel": "5.11.0-22-generic",
|
||||
"revision": "r20210413",
|
||||
"default": false
|
||||
}
|
||||
],
|
||||
"installed_pxe_templates": [
|
||||
"default.ipxe",
|
||||
"template1.ipxe"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### Flujo de Trabajo: `pxe y pxe-template`
|
||||
|
||||
#### NOTA
|
||||
|
||||
En la implementación actual de OpenGnsys, se realiza una consulta SQL a la tabla `ordenadores`, haciendo joins con tablas como `aulas`, `centros`, `entidades`, etc. (consultar fichero `opengnsys/server/bin/setclientmode`) para obtener todos los parámetros necesarios para la creación de archivos PXE. Es necesario estudiar si existe la necesidad de crear una tabla `pxe` para almacenar estos parámetros. En caso de decidirse la creación de dicha tabla, podría tener los siguientes atributos:
|
||||
|
||||
- `template_name` (nombre de la plantilla)
|
||||
- `mac` (dirección MAC)
|
||||
- `lang` (idioma)
|
||||
- `ip` (dirección IP)
|
||||
- `server_ip` (dirección IP del servidor)
|
||||
- `router` (router)
|
||||
- `netmask` (máscara de red)
|
||||
- `computer_name` (nombre del equipo)
|
||||
- `netiface` (interfaz de red)
|
||||
- `group` (grupo)
|
||||
- `ogrepo` (IP del repositorio)
|
||||
- `oglive` (IP del servidor en vivo)
|
||||
- `oglog` (IP del servidor de logs)
|
||||
- `ogshare` (IP del servidor compartido)
|
||||
- `oglivedir` (directorio en vivo)
|
||||
- `ogprof` (es profesor)
|
||||
- `hardprofile` (perfil de hardware)
|
||||
- `ogntp` (servidor NTP)
|
||||
- `ogdns` (servidor DNS)
|
||||
- `ogproxy` (servidor proxy)
|
||||
- `ogunit` (directorio de unidad)
|
||||
- `resolution` (resolución de pantalla)
|
||||
|
||||
---
|
||||
|
||||
#### NOTA 2
|
||||
|
||||
¿Tiene sentido hacer una tabla para las plantillas pxe-templates? Solo tendrian dos atributos: template-name y content. ¿No sería mejor que quedasen guardadas en el ogboot y se usen cuando se vaya a crear un fichero de arranque?
|
||||
|
||||
|
||||
Para estos flujos asumiremos que NO se han creado tablas a mayores de pxe ni de pxe-templates. Este es el flujo original que se produce actualmente en ogboot.
|
||||
|
||||
|
||||
|
||||
1. **Obtener Todos los Archivos de Arranque**
|
||||
- **URL**: `/ogboot/v1/pxes`
|
||||
- **Método HTTP**: GET
|
||||
- **Cuerpo de la Solicitud**:
|
||||
```json
|
||||
{
|
||||
{
|
||||
"boot_files": [
|
||||
"01-00:50:56:20:69:11",
|
||||
"01-00:50:56:20:69:12"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
2. **Obtener Configuración de Arranque por MAC**
|
||||
- **URL**: `/ogboot/v1/pxes/{mac}`
|
||||
- **Método HTTP**: GET
|
||||
- **Cuerpo de la Solicitud**:
|
||||
- **Respuesta**:
|
||||
```json
|
||||
{
|
||||
"template_name": "pxe",
|
||||
"mac": "00:50:56:22:11:12",
|
||||
"lang": "es_ES.UTF-8",
|
||||
"ip": "192.168.2.11",
|
||||
"server_ip": "192.168.2.1",
|
||||
"router": "192.168.2.1",
|
||||
"netmask": "255.255.255.0",
|
||||
"computer_name": "pc11",
|
||||
"netiface": "eth0",
|
||||
"group": "Aula_virtual",
|
||||
"ogrepo": "192.168.2.1",
|
||||
"oglive": "192.168.2.1",
|
||||
"oglog": "192.168.2.1",
|
||||
"ogshare": "192.168.2.1",
|
||||
"oglivedir": "ogLive",
|
||||
"ogprof": "false",
|
||||
"hardprofile": "",
|
||||
"ogntp": "",
|
||||
"ogdns": "",
|
||||
"ogproxy": "",
|
||||
"ogunit": "",
|
||||
"resolution": "788"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
3. **Obtener Todas las Plantillas de Arranque**
|
||||
- **URL**: `/ogboot/v1/pxe-templates`
|
||||
- **Método HTTP**: GET
|
||||
- **Respuesta**:
|
||||
```json
|
||||
{
|
||||
"templates": [
|
||||
"pxe",
|
||||
"pxe_default"
|
||||
]
|
||||
}
|
||||
```
|
||||
4. **Crear Plantilla de Arranque**
|
||||
- **URL**: `/ogboot/v1/pxes-templates`
|
||||
- **Método HTTP**: POST
|
||||
- **Cuerpo de la Solicitud**:
|
||||
```json
|
||||
{
|
||||
"name_template": "pxe2",
|
||||
"content_template": "#!ipxe\\nset timeout 0\\nset timeout-style hidden\\n\\nset ISODIR ogLive\\nset default 0\\nset kernelargs INFOHOST\\nkernel tftp://SERVERIP/ogLive/ogvmlinuz ${kernelargs}\\ninitrd tftp://SERVERIP/ogLive/oginitrd.img\\nboot"
|
||||
}
|
||||
```
|
||||
- **Respuesta**:
|
||||
```json
|
||||
{
|
||||
"message": "Plantilla creada exitosamente.",
|
||||
"template": "#!ipxe\\nset timeout 0\\nset timeout-style hidden\\n\\nset ISODIR ogLive\\nset default 0\\nset kernelargs INFOHOST\\nkernel tftp://SERVERIP/ogLive/ogvmlinuz ${kernelargs}\\ninitrd tftp://SERVERIP/ogLive/oginitrd.img\\nboot"
|
||||
}
|
||||
```
|
||||
|
||||
5. **Obtener Todas las Plantillas de Arranque**
|
||||
- **URL**: `/ogboot/v1/pxe-templates`
|
||||
- **Método HTTP**: GET
|
||||
- **Respuesta**:
|
||||
```json
|
||||
{
|
||||
"templates": [
|
||||
"pxe",
|
||||
"pxe2"
|
||||
"pxe_default"
|
||||
]
|
||||
}
|
||||
```
|
||||
6. **Crear archivo de Arranque**
|
||||
- **URL**: `/ogboot/v1/pxes`
|
||||
- **Método HTTP**: POST
|
||||
- **Respuesta**:
|
||||
```json
|
||||
{
|
||||
"template_name": "pxe2",
|
||||
"mac": "00:50:56:22:11:13",
|
||||
"lang": "es_ES.UTF-8",
|
||||
"ip": "192.168.2.11",
|
||||
"server_ip": "192.168.2.1",
|
||||
"router": "192.168.2.1",
|
||||
"netmask": "255.255.255.0",
|
||||
"computer_name": "pc13",
|
||||
"netiface": "eth0",
|
||||
"group": "Aula_virtual",
|
||||
"ogrepo": "192.168.2.1",
|
||||
"oglive": "192.168.2.1",
|
||||
"oglog": "192.168.2.1",
|
||||
"ogshare": "192.168.2.1",
|
||||
"oglivedir": "ogLive",
|
||||
"ogprof": "false",
|
||||
"hardprofile": "",
|
||||
"ogntp": "",
|
||||
"ogdns": "",
|
||||
"ogproxy": "",
|
||||
"ogunit": "",
|
||||
"resolution": "788"
|
||||
}
|
||||
```
|
||||
7. **Obtener Todos los Archivos de Arranque**
|
||||
- **URL**: `/ogboot/v1/pxes`
|
||||
- **Método HTTP**: GET
|
||||
- **Cuerpo de la Solicitud**:
|
||||
```json
|
||||
{
|
||||
{
|
||||
"boot_files": [
|
||||
"01-00:50:56:20:69:11",
|
||||
"01-00:50:56:20:69:12",
|
||||
"01-00:50:56:20:69:13"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
8. **Borrado de un fichero de arranque**
|
||||
- **URL**: `/ogboot/v1/pxes/{mac}`
|
||||
- **Método HTTP**: DELETE
|
||||
- **Respuesta**:
|
||||
```json
|
||||
{
|
||||
"message": "El archivo de arranque se eliminó correctamente"
|
||||
}
|
||||
```
|
||||
|
||||
9. **Borrado de una plantilla**
|
||||
- **URL**: `/ogboot/v1/pxe-templates/{name}`
|
||||
- **Método HTTP**: DELETE
|
||||
- **Respuesta**:
|
||||
```json
|
||||
{
|
||||
"message": "Plantilla eliminada correctamente."
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
#!ipxe
|
||||
|
||||
# Detectar si se está ejecutando en modo UEFI o BIOS
|
||||
iseq ${platform} efi && goto uefi_menu || goto bios_mbr
|
||||
|
||||
:bios_mbr
|
||||
echo "Running in BIOS mode - Booting MBR"
|
||||
chain tftp://__SERVERIP__/grub.exe --config-file="title MBR;chainloader (hd0)+1;rootnoverify (hd0);boot" || echo "Failed to boot MBR in BIOS mode"
|
||||
exit
|
||||
|
||||
:uefi_menu
|
||||
echo "Running in UEFI mode - Searching boot loaders"
|
||||
|
||||
set detected no
|
||||
|
||||
# Buscar y configurar opciones de arranque
|
||||
echo "Searching Grub"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\grub\Boot\grubx64.efi && goto add_grub
|
||||
|
||||
:add_grub
|
||||
set detected yes
|
||||
echo "Grub found"
|
||||
goto boot_grub
|
||||
|
||||
:boot_grub
|
||||
echo "Booting Grub"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\grub\Boot\grubx64.efi || echo "Failed to boot Grub"
|
||||
exit
|
||||
|
||||
:refind
|
||||
echo "Searching rEFInd"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\refind\shimx64.efi.signed && goto add_refind
|
||||
|
||||
:add_refind
|
||||
set detected yes
|
||||
echo "rEFInd found"
|
||||
goto boot_refind
|
||||
|
||||
:boot_refind
|
||||
echo "Booting rEFInd"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\refind\shimx64.efi.signed || echo "Failed to boot rEFInd"
|
||||
exit
|
||||
|
||||
:part_01_02
|
||||
echo "Searching Part-01-02"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\Part-01-02\Boot\ogloader.efi && goto add_part_01_02
|
||||
|
||||
:add_part_01_02
|
||||
set detected yes
|
||||
echo "Part-01-02 found"
|
||||
goto boot_part_01_02
|
||||
|
||||
:boot_part_01_02
|
||||
echo "Booting Part-01-02"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\Part-01-02\Boot\ogloader.efi || echo "Failed to boot Part-01-02"
|
||||
exit
|
||||
|
||||
:part_01_03
|
||||
echo "Searching Part-01-03"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\Part-01-03\Boot\ogloader.efi && goto add_part_01_03
|
||||
|
||||
:add_part_01_03
|
||||
set detected yes
|
||||
echo "Part-01-03 found"
|
||||
goto boot_part_01_03
|
||||
|
||||
:boot_part_01_03
|
||||
echo "Booting Part-01-03"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\Part-01-03\Boot\ogloader.efi || echo "Failed to boot Part-01-03"
|
||||
exit
|
||||
|
||||
:microsoft
|
||||
echo "Searching Microsoft"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\Microsoft\Boot\bootmgfw.efi && goto add_microsoft
|
||||
|
||||
:add_microsoft
|
||||
set detected yes
|
||||
echo "Microsoft Boot Manager found"
|
||||
goto boot_microsoft
|
||||
|
||||
:boot_microsoft
|
||||
echo "Booting Microsoft Boot Manager"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\Microsoft\Boot\bootmgfw.efi || echo "Failed to boot Microsoft Boot Manager"
|
||||
exit
|
||||
|
||||
:ubuntu
|
||||
echo "Searching Ubuntu"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\ubuntu\grubx64.efi && goto add_ubuntu
|
||||
|
||||
:add_ubuntu
|
||||
set detected yes
|
||||
echo "Ubuntu found"
|
||||
goto boot_ubuntu
|
||||
|
||||
:boot_ubuntu
|
||||
echo "Booting Ubuntu"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\ubuntu\grubx64.efi || echo "Failed to boot Ubuntu"
|
||||
exit
|
||||
|
||||
:no_os_detected
|
||||
iseq ${detected} no && echo "OpenGnsys no ha detectado ningún sistema operativo en este equipo"
|
||||
exit
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# /etc/default/tftpd-hpa
|
||||
|
||||
TFTP_USERNAME="opengnsys"
|
||||
TFTP_DIRECTORY="/opt/opengnsys/ogboot/tftpboot"
|
||||
TFTP_ADDRESS="0.0.0.0:69"
|
||||
TFTP_OPTIONS="--secure -v"
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#!ipxe
|
||||
echo Booting by ipxe
|
||||
set macaddress ${net0/mac}
|
||||
set prefix tftp://__SERVERIP__/ipxe_scripts
|
||||
set configfile ${prefix}/01-${net0/mac}
|
||||
ifopen net0
|
||||
route
|
||||
# Intentar cargar la configuración personalizada por MAC
|
||||
chain ${configfile} ||
|
||||
# Si no se encuentra la configuración personalizada, cargar la configuración por defecto
|
||||
chain ${prefix}/default.ipxe
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#!ipxe
|
||||
set timeout 0
|
||||
set timeout-style hidden
|
||||
set ISODIR ogLive
|
||||
set default 0
|
||||
set kernelargs ro boot=oginit quiet splash irqpoll acpi=on og2nd=sqfs ogprotocol=smb ogactiveadmin=true ogdebug=true ogtmpfs=15 oglivedir=${ISODIR} LANG=es_ES.UTF-8 ip=IP_ADDRESS:192.168.2.1:192.168.2.1:255.255.255.0:HOSTNAME:eth0:none group=Aula_virtual ogrepo=192.168.2.1 oglive=192.168.2.1 oglog=192.168.2.1 ogshare=192.168.2.1 ogprof=false vga=788
|
||||
echo "OgLive $ISODIR"
|
||||
ifopen net0
|
||||
route
|
||||
kernel tftp://__SERVERIP__/ogLive/ogvmlinuz ${kernelargs}
|
||||
initrd tftp://__SERVERIP__/ogLive/oginitrd.img
|
||||
boot
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
server {
|
||||
listen __PORT__;
|
||||
server_name __SERVERIP__ localhost; # IP del servidor
|
||||
|
||||
# Raíz del documento para el proyecto Symfony
|
||||
root __ROOT__/public;
|
||||
|
||||
# Bloque para manejar las solicitudes a /ogboot
|
||||
location /ogboot {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
# Aumentar el tiempo de espera por el install oglive
|
||||
proxy_read_timeout 600;
|
||||
proxy_connect_timeout 600;
|
||||
proxy_send_timeout 600;
|
||||
send_timeout 600;
|
||||
}
|
||||
|
||||
# Bloque para manejar las solicitudes a index.php
|
||||
location ~ ^/index.php(/|$) {
|
||||
include fastcgi_params;
|
||||
fastcgi_pass unix:/run/php/php__PHPVERSION__-fpm-ogboot.sock; # Asegúrate de que esto sea correcto
|
||||
fastcgi_split_path_info ^(.+\.php)(/.*)$;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
fastcgi_param DOCUMENT_ROOT $document_root;
|
||||
internal;
|
||||
}
|
||||
|
||||
# Bloque para devolver 404 en cualquier solicitud a archivos PHP que no sean index.php
|
||||
location ~ \.php$ {
|
||||
return 404;
|
||||
}
|
||||
|
||||
# Logs de error y acceso para el proyecto Symfony
|
||||
error_log /var/log/nginx/ogboot_error.log;
|
||||
access_log /var/log/nginx/ogboot_access.log;
|
||||
|
||||
location /ogboot/api/doc {
|
||||
try_files $uri /index.php?$query_string;
|
||||
}
|
||||
|
||||
# Ruta base para servir archivos de TFTP
|
||||
location /tftpboot {
|
||||
alias __TFTPPATH__;
|
||||
autoindex on; # Permitir listado de directorios
|
||||
try_files $uri $uri/ =404; # Intentar servir archivos, si no se encuentra devolver 404
|
||||
|
||||
# Seguridad
|
||||
location ~ \.php$ {
|
||||
return 404;
|
||||
}
|
||||
|
||||
# Logs de error y acceso para tftpboot
|
||||
error_log /var/log/nginx/tftpboot_error.log;
|
||||
access_log /var/log/nginx/tftpboot_access.log;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
[ogboot]
|
||||
user = opengnsys
|
||||
group = www-data
|
||||
listen = /var/run/php/php8.3-fpm-ogboot.sock
|
||||
listen.owner = opengnsys
|
||||
listen.group = www-data
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
# Variables para facilitar la lectura
|
||||
Cmnd_Alias MOUNT_RECOVERY = \
|
||||
/usr/bin/mkdir -p /mnt/recovery, \
|
||||
/usr/bin/mount /dev/* /mnt/recovery, \
|
||||
/usr/bin/mount --bind /dev /mnt/recovery/dev, \
|
||||
/usr/bin/mount --bind /proc /mnt/recovery/proc, \
|
||||
/usr/bin/mount --bind /sys /mnt/recovery/sys, \
|
||||
/usr/bin/umount /mnt/recovery/dev, \
|
||||
/usr/bin/umount /mnt/recovery/proc, \
|
||||
/usr/bin/umount /mnt/recovery/sys, \
|
||||
/usr/bin/umount -l /mnt/recovery
|
||||
|
||||
|
||||
Cmnd_Alias OGBOOT = \
|
||||
/opt/bin/oglivecli, \
|
||||
/usr/bin/chmod, \
|
||||
/usr/bin/chown, \
|
||||
/usr/bin/md5sum, \
|
||||
/usr/bin/smbpasswd, \
|
||||
/usr/bin/cat, \
|
||||
/usr/bin/tee, \
|
||||
/usr/bin/sed, \
|
||||
/usr/bin/gzip, \
|
||||
/usr/bin/lz4, \
|
||||
/usr/bin/cpio, \
|
||||
/usr/bin/find, \
|
||||
/bin/tee, \
|
||||
/usr/bin/dd, \
|
||||
/usr/bin/mkfs.ext4, \
|
||||
/usr/bin/rsync, \
|
||||
/opt/opengnsys/ogboot/lib/*.iso /mnt
|
||||
|
||||
|
||||
Cmnd_Alias CHROOT_GRUB = \
|
||||
/usr/sbin/chroot /mnt/recovery /usr/sbin/grub-install --target=i386-pc *, \
|
||||
/usr/sbin/chroot /mnt/recovery /usr/sbin/grub-mkconfig -o /boot/grub/grub.cfg
|
||||
|
||||
Cmnd_Alias LOOP_KPARTX = \
|
||||
/usr/sbin/losetup -d *, \
|
||||
/usr/sbin/kpartx -av /opt/opengnsys/ogrepository/images_virtual/*, \
|
||||
/usr/sbin/kpartx -d /opt/opengnsys/ogrepository/images_virtual/*, \
|
||||
/usr/sbin/blkid /dev/mapper/*
|
||||
|
||||
Cmnd_Alias KILL_BT = \
|
||||
/usr/bin/pkill -9 btlaunchmany, \
|
||||
/usr/bin/pkill -9 bttrack, \
|
||||
/usr/bin/kill -9 *
|
||||
|
||||
Cmnd_Alias PYTHON_OGREPO = /usr/bin/python3 /opt/opengnsys/ogrepository/bin/*
|
||||
|
||||
# Permitir al usuario opengnsys ejecutar estos comandos sin contraseña
|
||||
opengnsys ALL=(root) NOPASSWD: MOUNT_RECOVERY, CHROOT_GRUB, LOOP_KPARTX, OGBOOT, KILL_BT, PYTHON_OGREPO
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
[tftpboot]
|
||||
comment = OpenGnsys init files
|
||||
browseable = no
|
||||
writeable = no
|
||||
path = __OGBOOTDIR__/tftpboot
|
||||
guest ok = no
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"ogCore_ServerIP": "172.17.8.82:8081",
|
||||
"ogBoot_ServerIP": "172.17.8.37:8082",
|
||||
"ogBoot_Dir": "/opt/opengnsys/ogboot",
|
||||
"ogLive_Default": "https://ognproject.evlt.uma.es/oglive/ogLive-noble-6.8.0-31-generic-amd64-r20241128.62778c9_20241129.iso",
|
||||
"ogBootSambaUser": "opengnsys",
|
||||
"ogBootSambaPass": "og"
|
||||
}
|
||||
|
|
@ -0,0 +1,894 @@
|
|||
#!/usr/bin/env python3
|
||||
##################################################################################
|
||||
##### ogBoot installer script ####
|
||||
##### Developed by: Luis Gerardo Romero García <lromero@qindel.com> ####
|
||||
##### Antonio Emmanuel Guerrero Silva <aguerrero@qindel.com> ####
|
||||
##### Last: 2024-07-08 ####
|
||||
##################################################################################
|
||||
|
||||
import platform, os, sys, subprocess, datetime, shutil, pwd, glob, logging, distro, re, json
|
||||
import tempfile
|
||||
|
||||
ipxe_repo_url = "https://github.com/ipxe/ipxe.git"
|
||||
|
||||
SAMBACFGDIR = "/etc/samba"
|
||||
TFTPCFGDIR = "/var/lib/tftpboot"
|
||||
|
||||
PROGRAM = os.path.splitext(os.path.basename(sys.argv[0]))[0]
|
||||
PROGRAM_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))
|
||||
REPO_DIR = os.path.realpath (os.path.join (os.path.dirname (sys.argv[0]), '..'))
|
||||
PROGRAM_NAME = os.path.basename(sys.argv[0])
|
||||
|
||||
config_file = os.path.join(PROGRAM_DIR, 'config.json')
|
||||
with open(config_file, 'r') as f:
|
||||
config = json.load(f)
|
||||
|
||||
#OGCORE_IP = config["ogCore_ServerIP"]
|
||||
|
||||
ogcore_ip_port = config['ogCore_ServerIP']
|
||||
if ':' in ogcore_ip_port:
|
||||
OGCORE_IP, OGCORE_PORT = ogcore_ip_port.split(':')
|
||||
else:
|
||||
OGCORE_IP = ogcore_ip_port
|
||||
OGCORE_PORT = "8443"
|
||||
|
||||
#Para el caso de que pasen una ip con puerto separamos la ip y el puerto
|
||||
#Pasamos el puerto para conexiones por http
|
||||
#No pasamos el puerto para conexiones tftp y parámetros del kernel
|
||||
#Si solo pasan la IP usaremos el puerto por defecto 8082
|
||||
ogboot_ip_port = config['ogBoot_ServerIP']
|
||||
if ':' in ogboot_ip_port:
|
||||
OGBOOT_IP, OGBOOT_PORT = ogboot_ip_port.split(':')
|
||||
else:
|
||||
OGBOOT_IP = ogboot_ip_port
|
||||
OGBOOT_PORT = "8082"
|
||||
oglive_iso_url = config["ogLive_Default"]
|
||||
INSTALL_OGBOOT_TARGET = config["ogBoot_Dir"]
|
||||
OPENGNSYS_CLIENT_USER = config["ogBootSambaUser"]
|
||||
OPENGNSYS_CLIENT_PASSWD = config["ogBootSambaPass"]
|
||||
|
||||
DEFAULTDEV = ""
|
||||
DEVICE = []
|
||||
SERVERIP = []
|
||||
NETIP = []
|
||||
NETMASK = []
|
||||
NETBROAD = []
|
||||
ROUTERIP = []
|
||||
BRANCH = sys.argv[1] if len(sys.argv) > 1 else "main"
|
||||
|
||||
UBUNTU_OS_VERSION = "24"
|
||||
PYTHON_VERSION = 3
|
||||
|
||||
os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
|
||||
|
||||
log_file = f'/var/log/{PROGRAM}.log'
|
||||
os.makedirs(os.path.dirname(log_file), exist_ok=True)
|
||||
subprocess.run(['touch', log_file])
|
||||
subprocess.run(['chmod', '775', log_file])
|
||||
|
||||
#Configure the log
|
||||
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? [y/N]: ")
|
||||
if go_on.upper() != "Y":
|
||||
logger.error("Leaving the installation.")
|
||||
exit()
|
||||
|
||||
###############################################################################
|
||||
###:::::::::::::::::::::::::::::: INSTALL ::::::::::::::::::::::::::::::::::###
|
||||
###############################################################################
|
||||
|
||||
def get_missing_packages():
|
||||
PACKAGES_TO_INSTALL = []
|
||||
|
||||
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", "libdbi-dev", "libdbi1t64", "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", "samba-common-bin", "schroot", "shim-signed", "squashfs-tools", "subversion", "tftpd-hpa", "udpcast", "unzip", "wakeonlan", "wget", "xinetd", "jq", "moreutils", "net-tools", "isolinux", "syslinux"]
|
||||
case "24.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", "libdbi-dev", "libdbi1t64", "libev-dev", "libjansson-dev", "liblz4-tool", "libssl-dev", "moreutils", "netpipes", "php8.3", "php8.3-bcmath", "php8.3-cli", "php8.3-curl", "php8.3-fpm", "php8.3-gd", "php8.3-ldap", "php8.3-mbstring", "php8.3-mysql", "php8.3-common", "php-pear", "php8.3-xml", "php8.3-zip", "procps", "coreutils", "rsync", "samba", "samba-common-bin", "schroot", "shim-signed", "squashfs-tools", "subversion", "tftpd-hpa", "udpcast", "unzip", "wakeonlan", "wget", "xinetd", "jq", "moreutils", "isolinux", "syslinux", "file"]
|
||||
case _:
|
||||
PACKAGES_TO_INSTALL = ["bash", "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)
|
||||
|
||||
installed = []
|
||||
for l in subprocess.run (['dpkg', '-s'] + PACKAGES_TO_INSTALL, capture_output=True, text=True).stdout.splitlines():
|
||||
if l.startswith ('Package:'):
|
||||
installed.append (l.split (':')[1].strip())
|
||||
faltantes = list (set(PACKAGES_TO_INSTALL) - set(installed))
|
||||
logger.info(f"Packages to install: {faltantes}")
|
||||
return faltantes
|
||||
|
||||
def install_packages(log_packages_file="/tmp/installed_packages.log"):
|
||||
missing = get_missing_packages()
|
||||
if not missing:
|
||||
logger.info("All packages are already installed.")
|
||||
return
|
||||
|
||||
logger.info("Upgrading the system...")
|
||||
|
||||
subprocess.run(["apt-get", "update"], check=True)
|
||||
subprocess.run(
|
||||
["apt-get", "install", "--allow-change-held-packages", "-y", "--no-install-recommends"] + missing + ['apache2-'],
|
||||
check=True
|
||||
)
|
||||
|
||||
with open(log_packages_file, "a") as log:
|
||||
for package in missing:
|
||||
logger.info(f"{package} installed correctly.")
|
||||
log.write(package + "\n")
|
||||
|
||||
logger.info("All missing packages have been installed.")
|
||||
|
||||
# Check PHP version and install corresponding php-fpm package
|
||||
php_version = subprocess.check_output(["php", "-v"]).decode("utf-8")
|
||||
if "PHP 8.1" in php_version:
|
||||
subprocess.run(["apt-get", "install", "-y", "php8.1-fpm"], check=True)
|
||||
elif "PHP 8.3" in php_version:
|
||||
subprocess.run(["apt-get", "install", "-y", "php8.3-fpm"], check=True)
|
||||
else:
|
||||
logger.warning("PHP version not supported.")
|
||||
|
||||
def add_sudoers_permissions():
|
||||
sudoers_entry = """
|
||||
opengnsys ALL=(ALL) NOPASSWD: /opt/bin/oglivecli
|
||||
opengnsys ALL=(root) NOPASSWD: /usr/bin/chmod, /usr/bin/chown, /usr/bin/md5sum, /usr/bin/smbpasswd, /usr/bin/cat, /usr/bin/tee, /usr/bin/sed, /usr/bin/gzip, /usr/bin/lz4, /usr/bin/cpio, /usr/bin/find, /bin/tee, /usr/bin/dd, /usr/bin/mkfs.ext4, /usr/bin/rsync
|
||||
opengnsys ALL=(root) NOPASSWD: __OGBOOT_TARGET__/lib/*.iso /mnt
|
||||
"""
|
||||
|
||||
sudoers_file = '/etc/sudoers.d/ogboot'
|
||||
|
||||
try:
|
||||
with open(sudoers_file, 'w') as file:
|
||||
file.write(sudoers_entry.replace ('__OGBOOT_TARGET__', INSTALL_OGBOOT_TARGET))
|
||||
print("Sudoers permissions for 'opengnsys' added successfully.")
|
||||
except IOError as e:
|
||||
print(f"Failed to write to {sudoers_file}: {e}")
|
||||
|
||||
|
||||
def og_core_create_user(u):
|
||||
try:
|
||||
user_info = pwd.getpwnam(u)
|
||||
current_home = user_info.pw_dir
|
||||
logger.info(f"User {u} already exists with home {current_home}")
|
||||
|
||||
if u == "opengnsys" and current_home != "/opt/opengnsys":
|
||||
logger.info(f"Updating home directory for user {u} to /opt/opengnsys")
|
||||
|
||||
subprocess.run(["usermod", "-d", "/opt/opengnsys", "-m", u], check=True)
|
||||
logger.info(f"User {u} home changed successfully to /opt/opengnsys")
|
||||
else:
|
||||
logger.info(f"User {u} already has the correct home directory.")
|
||||
|
||||
except KeyError:
|
||||
# El usuario no existe, crearlo con el home correcto, si es opengnsys le ponemos su home_dir como opt/opengnsys
|
||||
# Si no es opengnsys le creamos el home en /home/<usuario>
|
||||
home_dir = "/opt/opengnsys" if u == "opengnsys" else f"/home/{u}"
|
||||
logger.info(f"Creating user {u} with home {home_dir}")
|
||||
subprocess.run(["useradd", "--create-home", "-d", home_dir, "--shell", "/bin/bash", u], check=True)
|
||||
logger.info(f"User {u} created successfully with home {home_dir}")
|
||||
|
||||
def og_boot_create_dirs():
|
||||
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("/opt/opengnsys", mode=0o775, exist_ok=True)
|
||||
subprocess.run(["chmod", "775", "/opt/opengnsys"])
|
||||
os.makedirs(INSTALL_OGBOOT_TARGET, mode=0o775, exist_ok=True)
|
||||
api_dir = os.path.join(INSTALL_OGBOOT_TARGET, "api")
|
||||
os.makedirs(api_dir, mode=0o775, exist_ok=True)
|
||||
|
||||
# Cambiar el propietario de los directorios
|
||||
subprocess.run(["chown", "-R", "opengnsys:opengnsys", INSTALL_OGBOOT_TARGET])
|
||||
|
||||
|
||||
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():
|
||||
logger.info("Creating Symfony application skeleton...")
|
||||
|
||||
try:
|
||||
api_dir = os.path.join(INSTALL_OGBOOT_TARGET, "api")
|
||||
os.makedirs(api_dir, exist_ok=True) # Asegurar que el directorio api existe
|
||||
# Cambio de .env y composer.json bajo /api
|
||||
api_source = os.path.join(REPO_DIR, "api")
|
||||
env_src = os.path.join(api_source, ".env")
|
||||
composer_src = os.path.join(api_source, "composer.json")
|
||||
env_dest = os.path.join(api_dir, ".env")
|
||||
composer_dest = os.path.join(api_dir, "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='opengnsys', group='opengnsys')
|
||||
shutil.chown(composer_dest, user='opengnsys', group='opengnsys')
|
||||
logger.info(f"Set permissions and owner for {env_dest} and {composer_dest}")
|
||||
|
||||
# Añadir la línea OGCORE_API_URL utilizando OGCORE_IP y OGCORE_PORT
|
||||
ogcore_api_url = f'OGCORE_API_URL="https://{OGCORE_IP}:{OGCORE_PORT}"'
|
||||
with open(env_dest, 'a') as env_file:
|
||||
env_file.write(f"\n{ogcore_api_url}\n")
|
||||
logger.info(f"Added OGCORE_API_URL to {env_dest} with IP: {OGCORE_IP}")
|
||||
|
||||
ogboot_ip = f'OGBOOT_IP="{OGBOOT_IP}"'
|
||||
with open(env_dest, 'a') as env_file:
|
||||
env_file.write(f"\n{ogboot_ip}\n")
|
||||
logger.info(f"Added OGBOOT_IP to {env_dest} with IP: {OGBOOT_IP}")
|
||||
ogboot_port = f'OGBOOT_PORT="{OGBOOT_PORT}"'
|
||||
with open(env_dest, 'a') as env_file:
|
||||
env_file.write(f"\n{ogboot_port}\n")
|
||||
logger.info(f"Added OGBOOT_PORT to {env_dest} with IP: {OGBOOT_PORT}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"An error occurred while copying files or modifying .env: {e}")
|
||||
raise
|
||||
|
||||
|
||||
|
||||
def og_boot_copy_files():
|
||||
api_dir = os.path.join(INSTALL_OGBOOT_TARGET, "api")
|
||||
api_source = os.path.join(REPO_DIR, "api")
|
||||
|
||||
# api/bin que contendría los scripts composer y console de symfony
|
||||
bin_api_source = os.path.join(api_source, "bin")
|
||||
bin_api_dest = os.path.join(api_dir, "bin")
|
||||
# api/bin que contendría los scripts oglivecli y setsmbpass
|
||||
bin_source = os.path.join(REPO_DIR, "bin")
|
||||
bin_dest = os.path.join(INSTALL_OGBOOT_TARGET, "bin")
|
||||
|
||||
src_source = os.path.join(api_source, "src")
|
||||
src_dest = os.path.join(api_dir, "src")
|
||||
config_source = os.path.join(api_source, "config")
|
||||
config_dest = os.path.join(api_dir, "config")
|
||||
# lib va fuera de /api
|
||||
lib_source = os.path.join(REPO_DIR, "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(bin_api_dest):
|
||||
shutil.rmtree(bin_api_dest)
|
||||
shutil.copytree(bin_api_source, bin_api_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_OGBOOT_TARGET, "etc"), mode=0o775, exist_ok=True)
|
||||
os.makedirs(os.path.join(INSTALL_OGBOOT_TARGET, "client"), mode=0o775, exist_ok=True)
|
||||
public_dir = os.path.join(api_dir, "public")
|
||||
os.makedirs(public_dir, mode=0o775, exist_ok=True)
|
||||
|
||||
subprocess.run(["chmod", "-R", "775", INSTALL_OGBOOT_TARGET])
|
||||
subprocess.run(["chown", "-R", "opengnsys:opengnsys", INSTALL_OGBOOT_TARGET])
|
||||
|
||||
def og_boot_composer_install():
|
||||
api_dir = os.path.join(INSTALL_OGBOOT_TARGET, "api")
|
||||
result = subprocess.run(
|
||||
["sudo", "-u", "opengnsys", "composer", "install", "--no-interaction", "--working-dir", api_dir]
|
||||
)
|
||||
|
||||
# Ejecutar Composer como el usuario 'opengnsys' para actualizar el paquete doctrine/dbal
|
||||
result = subprocess.run(["sudo", "-u", "opengnsys", INSTALL_OGBOOT_TARGET+"/api/bin/composer.phar", "update", "doctrine/dbal", "--working-dir", api_dir])
|
||||
if result.returncode != 0:
|
||||
logger.error("Error updating doctrine/dbal package using Composer")
|
||||
return
|
||||
|
||||
subprocess.call(["chown", "-R", "opengnsys:opengnsys", f"{api_dir}/public"])
|
||||
|
||||
logger.info("Application skeleton created.")
|
||||
|
||||
###############################################################################
|
||||
###:::::::::::::::::::::::::::: CONFIGURE ::::::::::::::::::::::::::::::::::###
|
||||
###############################################################################
|
||||
|
||||
# Obtener la UID y GID del usuario ogboot
|
||||
def get_ogboot_uid_gid():
|
||||
try:
|
||||
user_info = pwd.getpwnam('opengnsys')
|
||||
uid = user_info.pw_uid
|
||||
gid = user_info.pw_gid
|
||||
return uid, gid
|
||||
except KeyError:
|
||||
raise Exception("El usuario 'opengnsys' no existe.")
|
||||
|
||||
# Añadir líneas al fstab
|
||||
def add_fstab_entries(uid, gid):
|
||||
try:
|
||||
fstab_entries = [
|
||||
f'{INSTALL_OGBOOT_TARGET}/lib/oglive.iso {INSTALL_OGBOOT_TARGET}/mnt iso9660 loop,ro,users,uid={uid},gid={gid},noauto 0 0\n',
|
||||
f'/var/lib/tftpboot/ogLive/ogclient.sqfs /tmp/ogclient_mount squashfs loop,ro,user,noauto 0 0\n'
|
||||
]
|
||||
|
||||
with open('/etc/fstab', 'r') as fstab:
|
||||
existing_entries = fstab.readlines()
|
||||
|
||||
# Check if the entries already exist in /etc/fstab
|
||||
for entry in fstab_entries:
|
||||
if entry not in existing_entries:
|
||||
with open('/etc/fstab', 'a') as fstab:
|
||||
fstab.writelines(entry)
|
||||
logger.info("Entradas añadidas a /etc/fstab correctamente.")
|
||||
else:
|
||||
logger.info("Las entradas ya existen en /etc/fstab. No se añadieron nuevamente.")
|
||||
|
||||
except IOError:
|
||||
raise Exception("Error al escribir en /etc/fstab.")
|
||||
|
||||
# Añadir el usuario opengnsys al grupo disk
|
||||
def add_user_to_disk_group():
|
||||
try:
|
||||
subprocess.run(['usermod', '-aG', 'disk', 'opengnsys'], check=True)
|
||||
logger.info("Usuario 'opengnsys' añadido al grupo 'disk' correctamente.")
|
||||
except subprocess.CalledProcessError:
|
||||
raise Exception("Error al añadir el usuario 'opengnsys' al grupo 'disk'.")
|
||||
|
||||
def tftpConfigure():
|
||||
logger.info("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 -v"
|
||||
"""
|
||||
with open("/tmp/tftpd-hpa", "w") as config_file:
|
||||
config_file.write(tftpd_config)
|
||||
|
||||
shutil.move("/tmp/tftpd-hpa", "/etc/default/tftpd-hpa")
|
||||
|
||||
logger.info("\t2-Creating and setting permissions for the TFTP directory...")
|
||||
os.makedirs(TFTPCFGDIR, exist_ok=True)
|
||||
|
||||
logger.info("\t3-Setting permissions for /var/lib/tftpboot directory...")
|
||||
subprocess.run(f"chown -R tftp:opengnsys {TFTPCFGDIR}", shell=True, text=True, capture_output=True)
|
||||
subprocess.run(f"chmod -R 775 {TFTPCFGDIR}", shell=True, text=True, capture_output=True)
|
||||
|
||||
subprocess.run("systemctl restart tftpd-hpa", shell=True, text=True, capture_output=True)
|
||||
|
||||
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.lchown(symlink_target, pwd.getpwnam("tftp").pw_uid, pwd.getpwnam("opengnsys").pw_gid)
|
||||
else:
|
||||
logger.warning(f"The symbolic link already exists: {symlink_target}")
|
||||
|
||||
logger.info("Downloading oglive...")
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[INSTALL_OGBOOT_TARGET+"/bin/oglivecli", "download", oglive_iso_url],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
# Comprobar si oglivecli ha fallado
|
||||
if result.returncode != 0:
|
||||
try:
|
||||
# Parsear la salida como JSON
|
||||
error_output = json.loads(result.stdout)
|
||||
if error_output.get("status") == "error":
|
||||
logger.error(f"oglivecli error: {error_output.get('error')}")
|
||||
except json.JSONDecodeError:
|
||||
logger.error("Failed to parse oglivecli error output.")
|
||||
logger.error("Continuing with the installation despite oglivecli failure.")
|
||||
else:
|
||||
logger.info("Successful download")
|
||||
symlink_target_ogLive = f"{INSTALL_OGBOOT_TARGET}/tftpboot/ogLive"
|
||||
symlink_target_ogclient = f"{INSTALL_OGBOOT_TARGET}/tftpboot/ogclient"
|
||||
if os.path.exists(symlink_target_ogLive):
|
||||
subprocess.run(["chown", "-R", f"tftp:opengnsys", f"{INSTALL_OGBOOT_TARGET}/tftpboot"], check=True)
|
||||
os.lchown(symlink_target_ogLive, pwd.getpwnam("tftp").pw_uid, pwd.getpwnam("opengnsys").pw_gid)
|
||||
os.lchown(symlink_target_ogclient, pwd.getpwnam("tftp").pw_uid, pwd.getpwnam("opengnsys").pw_gid)
|
||||
logger.info(f"Changing properties for {symlink_target_ogLive} and {symlink_target_ogclient}")
|
||||
else:
|
||||
logger.error(f"{symlink_target_ogLive} link does not exist.")
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.error(f"Subprocess failed: {e}")
|
||||
logger.error("Continuing with the installation...")
|
||||
|
||||
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 install_ipxe():
|
||||
clone_dir = "/tmp/ipxe_repo"
|
||||
if os.path.exists(f"{INSTALL_OGBOOT_TARGET}/tftpboot/undionly.kpxe"):
|
||||
logger.info('iPXE already present--not compiling again')
|
||||
return True
|
||||
|
||||
if not os.path.exists(clone_dir):
|
||||
os.makedirs(clone_dir)
|
||||
logger.info(f"Cloning the repository {ipxe_repo_url}")
|
||||
if subprocess.call(["git", "-c", "http.sslVerify=false", "clone", ipxe_repo_url, clone_dir]) == 0:
|
||||
logger.info("Repository cloned successfully.")
|
||||
else:
|
||||
logger.error(f"ERROR: Could not clone the repository {ipxe_repo_url}.")
|
||||
return False
|
||||
else:
|
||||
logger.info(f"Repository already exists at {clone_dir}")
|
||||
|
||||
cwd = os.getcwd()
|
||||
os.chdir(f"{clone_dir}/src")
|
||||
|
||||
logger.info("Generating make of undionly.kpxe:")
|
||||
if subprocess.run(["make", "-s", "bin/undionly.kpxe", f"EMBED={INSTALL_OGBOOT_TARGET}/tftpboot/ipxe_scripts/dhcp_boot.ipxe"], capture_output=True).returncode == 0:
|
||||
logger.info("Boot file mounted correctly.")
|
||||
else:
|
||||
logger.error("Failed to mount boot file.")
|
||||
return False
|
||||
logger.info("Copying undionly.kpxe with user opengnsys:")
|
||||
subprocess.call(["cp", "bin/undionly.kpxe", f"{INSTALL_OGBOOT_TARGET}/tftpboot"])
|
||||
|
||||
logger.info("Generating make of ipxe.efi:")
|
||||
if subprocess.run(["make", "-s", "bin-x86_64-efi/ipxe.efi", f"EMBED={INSTALL_OGBOOT_TARGET}/tftpboot/ipxe_scripts/dhcp_boot.ipxe"], capture_output=True).returncode == 0:
|
||||
logger.info("Properly constructed EFI file.")
|
||||
else:
|
||||
logger.error("Could not build EFI file.")
|
||||
return False
|
||||
subprocess.call(["cp", "bin-x86_64-efi/ipxe.efi", f"{INSTALL_OGBOOT_TARGET}/tftpboot"])
|
||||
subprocess.call(["cp", f"{REPO_DIR}/tftpboot/grub.exe", f"{INSTALL_OGBOOT_TARGET}/tftpboot/"])
|
||||
os.makedirs(f"{INSTALL_OGBOOT_TARGET}/tftpboot/ipxe_scripts/templates", exist_ok=True)
|
||||
subprocess.call(["cp", "-r", f"{REPO_DIR}/tftpboot/ipxe_scripts/templates/.", f"{INSTALL_OGBOOT_TARGET}/tftpboot/ipxe_scripts/templates"])
|
||||
subprocess.run(["chmod", "-R", "775", f"{INSTALL_OGBOOT_TARGET}/tftpboot/"])
|
||||
subprocess.call(["chown", "-R", "opengnsys:opengnsys", f"{INSTALL_OGBOOT_TARGET}/tftpboot/"])
|
||||
|
||||
os.chdir(cwd)
|
||||
return True
|
||||
|
||||
def get_ip_address(interface):
|
||||
try:
|
||||
result = subprocess.check_output(["ip", "addr", "show", interface]).decode()
|
||||
for line in result.split('\n'):
|
||||
if "inet " in line:
|
||||
ip_address = line.strip().split()[1].split('/')[0]
|
||||
return ip_address
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.error(f"Error get address IP: {e}")
|
||||
return None
|
||||
|
||||
def generate_ipxe_script():
|
||||
ip_address_server = OGBOOT_IP
|
||||
ip_address = re.match(r"^(.*?):", ip_address_server)
|
||||
ip_address = ip_address.group(1) if ip_address else ip_address_server
|
||||
template = os.path.join(REPO_DIR, "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=0o775, exist_ok=True)
|
||||
#shutil.copy(template, ipxe_output)
|
||||
with open(template, "r") as ipxe_file:
|
||||
ipxe_content = ipxe_file.read()
|
||||
ipxe_content = ipxe_content.replace("__SERVERIP__", ip_address)
|
||||
with open(ipxe_output, "w") as ipxe_file:
|
||||
ipxe_file.write(ipxe_content)
|
||||
|
||||
template_default = os.path.join(REPO_DIR, "etc/default.ipxe.tmpl")
|
||||
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)
|
||||
with open(default_output, "w") as default_ipxe_file:
|
||||
default_ipxe_file.write(default_ipxe_content)
|
||||
logger.info("ipxe files created correctly.")
|
||||
|
||||
def user_exists(user):
|
||||
try:
|
||||
result = subprocess.run(["pdbedit", "-L", "-u", user], capture_output=True, text=True)
|
||||
return user in result.stdout
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.error(f"Error checking if user exists: {e}")
|
||||
return False
|
||||
|
||||
def smbConfigure():
|
||||
smb_conf = f"{SAMBACFGDIR}/smb.conf"
|
||||
if os.path.exists (smb_conf):
|
||||
dateymd = datetime.datetime.now().strftime("%Y%m%d")
|
||||
shutil.copy2 (smb_conf, f"{smb_conf}-{dateymd}")
|
||||
|
||||
# Copiar plantilla de recursos para OpenGnsys
|
||||
with open(os.path.join(REPO_DIR, 'etc/smb-ogboot.conf.tmpl'), 'r') as tmpl_file:
|
||||
template = tmpl_file.read()
|
||||
replaced_template = template.replace('__OGBOOTDIR__', INSTALL_OGBOOT_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/", smb_conf])
|
||||
if "smb-ogboot" not in open(smb_conf).read():
|
||||
with open(smb_conf, "a") as file:
|
||||
file.write(f"include = {SAMBACFGDIR}/smb-ogboot.conf\n")
|
||||
service = "smbd"
|
||||
logger.info(f"Enabling {service} service.")
|
||||
subprocess.run(["systemctl", "enable", f"{service}.service"])
|
||||
logger.info(f"Restarting {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
|
||||
# Ejecutar el comando smbpasswd para agregar el usuario de Samba
|
||||
try:
|
||||
if user_exists(OPENGNSYS_CLIENT_USER):
|
||||
logger.info(f"{OPENGNSYS_CLIENT_USER} user exists. Changing password...")
|
||||
extra_params = []
|
||||
else:
|
||||
logger.info(f"{OPENGNSYS_CLIENT_USER} user does not exist. Registering user...")
|
||||
extra_params = ['-a']
|
||||
|
||||
subprocess.run(
|
||||
["smbpasswd"] + extra_params + [OPENGNSYS_CLIENT_USER],
|
||||
input=f"{OPENGNSYS_CLIENT_PASSWD}\n{OPENGNSYS_CLIENT_PASSWD}\n",
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=True
|
||||
)
|
||||
logger.info("Add/Modify user: Operation completed successfully.")
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.error(f"Error adding/modifying user: {e}")
|
||||
return 0
|
||||
|
||||
def setup_nginx():
|
||||
try:
|
||||
# Obtener la IP del servidor
|
||||
ip_address_server = OGBOOT_IP
|
||||
port_address_server = OGBOOT_PORT
|
||||
php_version = get_php_fpm_version()
|
||||
api_dir = os.path.join(INSTALL_OGBOOT_TARGET, "api")
|
||||
# Leer y modificar la plantilla de configuración de nginx
|
||||
template_path = os.path.join(REPO_DIR, "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)
|
||||
nginx_content = nginx_content.replace("__PORT__", port_address_server)
|
||||
nginx_content = nginx_content.replace("__PHPVERSION__", php_version)
|
||||
nginx_content = nginx_content.replace("__ROOT__", api_dir)
|
||||
nginx_content = nginx_content.replace("__TFTPPATH__", f"{INSTALL_OGBOOT_TARGET}/tftpboot")
|
||||
|
||||
# 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(["ln", "-sf", nginx_output, "/etc/nginx/sites-enabled/ogboot.conf"])
|
||||
|
||||
logger.info("Symbolic link for nginx configuration created 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 opengnsys;")
|
||||
|
||||
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 opengnsys.")
|
||||
|
||||
# Reiniciar el servicio de samba
|
||||
subprocess.run(["systemctl", "restart", "nginx.service"])
|
||||
|
||||
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"
|
||||
new_fpm_conf_path = f"/etc/php/{php_version}/fpm/pool.d/ogboot.conf"
|
||||
socket_path = f"/run/php/php{php_version}-fpm-ogboot.sock"
|
||||
|
||||
if os.path.exists(new_fpm_conf_path):
|
||||
logger.info(f"Archivo {new_fpm_conf_path} ya existe. No se realizarán modificaciones.")
|
||||
return
|
||||
|
||||
try:
|
||||
# Copiar www.conf a ogboot.conf
|
||||
subprocess.run(["cp", php_fpm_conf_path, new_fpm_conf_path], check=True)
|
||||
logger.info(f"Archivo {php_fpm_conf_path} copiado a {new_fpm_conf_path}")
|
||||
|
||||
# Leer el archivo copiado opengnsys.conf
|
||||
with open(new_fpm_conf_path, 'r') as file:
|
||||
config_lines = file.readlines()
|
||||
|
||||
# Modificar las líneas necesarias
|
||||
with open(new_fpm_conf_path, 'w') as file:
|
||||
for line in config_lines:
|
||||
if line.startswith('[www]'):
|
||||
file.write('[ogboot]\n') # Cambiar el nombre del pool
|
||||
elif line.startswith('user ='):
|
||||
file.write('user = opengnsys\n')
|
||||
elif line.startswith('group ='):
|
||||
file.write('group = opengnsys\n')
|
||||
elif line.startswith('listen ='):
|
||||
file.write(f'listen = {socket_path}\n') # Cambiar el nombre del socket
|
||||
elif line.startswith('listen.owner ='):
|
||||
file.write('listen.owner = opengnsys\n')
|
||||
elif line.startswith('listen.group ='):
|
||||
file.write('listen.group = opengnsys\n')
|
||||
else:
|
||||
file.write(line)
|
||||
|
||||
logger.info(f"Archivo {new_fpm_conf_path} modificado correctamente.")
|
||||
|
||||
# Reiniciar el servicio PHP-FPM
|
||||
subprocess.run(["systemctl", "restart", f"php{php_version}-fpm"], check=True)
|
||||
logger.info("Servicio PHP-FPM reiniciado correctamente.")
|
||||
subprocess.run(["systemctl", "restart", "nginx.service"])
|
||||
# Verificar que el socket se ha creado
|
||||
if os.path.exists(socket_path):
|
||||
logger.info(f"Socket {socket_path} creado correctamente.")
|
||||
else:
|
||||
logger.error(f"El socket {socket_path} no se ha creado.")
|
||||
exit(1)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Ocurrió un error: {e}")
|
||||
exit(1)
|
||||
|
||||
###############################################################################
|
||||
###:::::::::::::::::::::::::::::::: MAIN :::::::::::::::::::::::::::::::::::###
|
||||
###############################################################################
|
||||
|
||||
logger.info(f":::::::::::::::::::::::: Starting ogBoot installation ::::::::::::::::::::::::")
|
||||
|
||||
logger.info("environment variables")
|
||||
logger.info(f"OGCORE_IP:{OGCORE_IP}")
|
||||
logger.info(f"INSTALL_OGBOOT_TARGET:{INSTALL_OGBOOT_TARGET}")
|
||||
|
||||
if os.geteuid() != 0:
|
||||
logger.error("This program must be run with root privileges..")
|
||||
exit(1)
|
||||
|
||||
## doc no existe nunca
|
||||
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)
|
||||
|
||||
try:
|
||||
logger.info("Verifying Python distribution and version.")
|
||||
check_distribution()
|
||||
check_python_version()
|
||||
except Exception as e:
|
||||
logger.error(f"Error verifying Python distribution or version: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Installing necessary packages.")
|
||||
install_packages()
|
||||
except Exception as e:
|
||||
logger.error(f"Error installing necessary packages: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Obtaining the default network configuration.")
|
||||
DEFAULTDEV = get_first_network_interface_with_traffic()
|
||||
logger.info(f"Network interface default:[{DEFAULTDEV}]")
|
||||
except Exception as e:
|
||||
logger.error(f"Error obtaining network configuration: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
add_sudoers_permissions()
|
||||
except Exception as e:
|
||||
logger.error(f"Error adding sudoers permissions: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Creating ogBoot project.")
|
||||
og_core_create_user("opengnsys")
|
||||
og_core_create_user(OPENGNSYS_CLIENT_USER)
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating ogBoot project or users: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Creating directories.")
|
||||
og_boot_create_dirs()
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating directories: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Copying installation files.")
|
||||
og_boot_copy_files()
|
||||
except Exception as e:
|
||||
logger.error(f"Error copying installation files: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Installing Symfony.")
|
||||
og_boot_symfony_install()
|
||||
except Exception as e:
|
||||
logger.error(f"Error installing Symfony: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Installing Composer.")
|
||||
og_boot_composer_install()
|
||||
except Exception as e:
|
||||
logger.error(f"Error installing Composer: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Obteniendo UID y GID del usuario 'opengnsys'.")
|
||||
uid, gid = get_ogboot_uid_gid()
|
||||
|
||||
logger.info("Añadiendo entradas al archivo /etc/fstab.")
|
||||
add_fstab_entries(uid, gid)
|
||||
|
||||
logger.info("Añadiendo el usuario 'opengnsys' al grupo 'disk'.")
|
||||
add_user_to_disk_group()
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error durante la configuración: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Configuring tftpd-hpa service.")
|
||||
tftpConfigure()
|
||||
except Exception as e:
|
||||
logger.error(f"Error configuring tftpd-hpa service: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Configuring IPXE services")
|
||||
generate_ipxe_script()
|
||||
except Exception as e:
|
||||
logger.error(f"Error configuring IPXE services: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Installing iPXE")
|
||||
if not install_ipxe():
|
||||
logger.error(f"Error installing iPXE")
|
||||
exit(1)
|
||||
except Exception as e:
|
||||
logger.error(f"Error installing iPXE: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Setup nginx")
|
||||
setup_nginx()
|
||||
except Exception as e:
|
||||
logger.error(f"Error setting up nginx: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Configure php fpm")
|
||||
modify_php_fpm_config()
|
||||
except Exception as e:
|
||||
logger.error(f"Error configuring php fpm: {e}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
logger.info("Configuring Samba")
|
||||
smbConfigure()
|
||||
except Exception as e:
|
||||
logger.error(f"Error configuring Samba: {e}")
|
||||
exit(1)
|
||||
|
||||
logger.info(f"ogBoot installation finished.")
|
||||
|
||||
logging.shutdown()
|
||||
console_handler.close()
|
||||
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "Hello world"
|
||||
touch "Hello world"
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash
|
||||
set -x
|
||||
URL_REPO="https://ognproject.evlt.uma.es/gitea/opengnsys/ogboot.git"
|
||||
BRANCH=${OGBOOT_BRANCH:-"main"}
|
||||
DOWNLOADDIR=${OGBOOT_DOWNLOADDIR:-"/tmp/ogboot"}
|
||||
apt install -y git vim python3
|
||||
git config --global http.sslVerify false
|
||||
git clone -b $BRANCH $URL_REPO $DOWNLOADDIR
|
||||
cd $DOWNLOADDIR/installer
|
||||
|
||||
ogCore_ServerIP=${1:-"172.17.8.82"}
|
||||
ogBoot_ServerIP=${2:-"172.17.8.37"}
|
||||
ogBoot_Dir=${3:-"/opt/opengnsys/ogboot"}
|
||||
ogLive_Default=${4:-"https://ognproject.evlt.uma.es/oglive/ogLive-noble-6.8.0-31-generic-amd64-r20241128.62778c9_20241129.iso"}
|
||||
ogBootSambaUser=${5:-"opengnsys"}
|
||||
ogBootSambaPass=${6:-"og"}
|
||||
|
||||
cat > config.json <<EOF
|
||||
{
|
||||
"ogCore_ServerIP": "$ogCore_ServerIP",
|
||||
"ogBoot_ServerIP": "$ogBoot_ServerIP",
|
||||
"ogBoot_Dir": "$ogBoot_Dir",
|
||||
"ogLive_Default": "$ogLive_Default",
|
||||
"ogBootSambaUser": "$ogBootSambaUser",
|
||||
"ogBootSambaPass": "$ogBootSambaPass"
|
||||
}
|
||||
EOF
|
||||
python3 ogboot_installer.py
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
import os
|
||||
import json
|
||||
import subprocess
|
||||
import shutil
|
||||
import logging
|
||||
|
||||
# Configuración básica del logger
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Cargar configuración desde config.json
|
||||
PROGRAM_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
config_file = os.path.join(PROGRAM_DIR, 'config.json')
|
||||
with open(config_file, 'r') as f:
|
||||
config = json.load(f)
|
||||
|
||||
# Extraer parámetros relevantes
|
||||
INSTALL_OGBOOT_TARGET = config["ogBoot_Dir"]
|
||||
|
||||
|
||||
def og_boot_copy_files():
|
||||
"""
|
||||
Copia los archivos necesarios al punto de montaje de ogBoot.
|
||||
Preserva el directorio client/images si existe.
|
||||
"""
|
||||
repo_dir = os.path.dirname(PROGRAM_DIR) # Ruta al directorio ogboot
|
||||
directories = {
|
||||
"bin": os.path.join(repo_dir, "bin"),
|
||||
"src": os.path.join(repo_dir, "src"),
|
||||
"config": os.path.join(repo_dir, "config"),
|
||||
"lib": os.path.join(repo_dir, "lib"),
|
||||
"client": os.path.join(repo_dir, "client"),
|
||||
}
|
||||
|
||||
for key, source in directories.items():
|
||||
dest = os.path.join(INSTALL_OGBOOT_TARGET, key)
|
||||
if key == "client":
|
||||
# Preservar el directorio client/images si existe
|
||||
images_dir = os.path.join(dest, "images")
|
||||
if os.path.exists(images_dir):
|
||||
temp_images_dir = os.path.join("/tmp", "ogboot_client_images")
|
||||
logger.info(f"Preservando el directorio {images_dir} temporalmente en {temp_images_dir}.")
|
||||
shutil.move(images_dir, temp_images_dir)
|
||||
# Reemplazar todo el directorio client
|
||||
if os.path.exists(dest):
|
||||
shutil.rmtree(dest)
|
||||
shutil.copytree(source, dest)
|
||||
# Restaurar el directorio images
|
||||
if os.path.exists(temp_images_dir):
|
||||
os.makedirs(dest, exist_ok=True)
|
||||
shutil.move(temp_images_dir, os.path.join(dest, "images"))
|
||||
logger.info(f"Directorio images restaurado en {dest}.")
|
||||
else:
|
||||
# Reemplazar otros directorios
|
||||
if os.path.exists(dest):
|
||||
shutil.rmtree(dest)
|
||||
shutil.copytree(source, dest)
|
||||
logger.info(f"Copiado {key} desde {source} a {dest}.")
|
||||
|
||||
# Crear directorios adicionales si no existen
|
||||
additional_dirs = ["etc", "public"]
|
||||
for dir_name in additional_dirs:
|
||||
os.makedirs(os.path.join(INSTALL_OGBOOT_TARGET, dir_name), mode=0o775, exist_ok=True)
|
||||
|
||||
subprocess.run(["chmod", "-R", "775", INSTALL_OGBOOT_TARGET])
|
||||
subprocess.run(["chown", "-R", "opengnsys:opengnsys", INSTALL_OGBOOT_TARGET])
|
||||
logger.info("Archivos copiados y permisos ajustados correctamente.")
|
||||
|
||||
|
||||
def og_boot_composer_install():
|
||||
"""
|
||||
Ejecuta Composer para instalar y actualizar las dependencias.
|
||||
"""
|
||||
result = subprocess.run(
|
||||
["sudo", "-u", "opengnsys", "composer", "install", "--no-interaction", "--working-dir", INSTALL_OGBOOT_TARGET]
|
||||
)
|
||||
if result.returncode != 0:
|
||||
logger.error("Error creando el proyecto Symfony usando Composer.")
|
||||
return False
|
||||
result = subprocess.run(
|
||||
["sudo", "-u", "opengnsys", f"{INSTALL_OGBOOT_TARGET}/bin/composer.phar", "update", "doctrine/dbal",
|
||||
"--working-dir", INSTALL_OGBOOT_TARGET]
|
||||
)
|
||||
if result.returncode != 0:
|
||||
logger.error("Error actualizando el paquete doctrine/dbal usando Composer.")
|
||||
return False
|
||||
|
||||
subprocess.call(["chown", "-R", "opengnsys:opengnsys", f"{INSTALL_OGBOOT_TARGET}/public"])
|
||||
logger.info("Composer ejecutado correctamente y permisos ajustados.")
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
og_boot_copy_files()
|
||||
|
||||
if not og_boot_composer_install():
|
||||
raise Exception("Error en la ejecución de Composer.")
|
||||
|
||||
logger.info("Actualización de ogBoot completada correctamente.")
|
||||
except Exception as e:
|
||||
logger.error(f"ERROR\tFallo crítico: {e}")
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
import os
|
||||
import json
|
||||
import subprocess
|
||||
import logging
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
PROGRAM_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
config_file = os.path.join(PROGRAM_DIR, 'config.json')
|
||||
with open(config_file, 'r') as f:
|
||||
config = json.load(f)
|
||||
|
||||
INSTALL_OGBOOT_TARGET = config["ogBoot_Dir"]
|
||||
|
||||
|
||||
def update_ipxe_boot_files():
|
||||
"""
|
||||
Actualiza los archivos de arranque iPXE.
|
||||
"""
|
||||
ipxe_repo_url = "https://github.com/ipxe/ipxe.git"
|
||||
install_ogboot_target = INSTALL_OGBOOT_TARGET
|
||||
cwd = os.getcwd()
|
||||
clone_dir = "/tmp/ipxe_repo"
|
||||
|
||||
if not os.path.exists(clone_dir):
|
||||
os.makedirs(clone_dir)
|
||||
logger.info(f"Clonando el repositorio {ipxe_repo_url}")
|
||||
clone_cmd = ["git", "-c", "http.sslVerify=false", "clone", ipxe_repo_url, clone_dir]
|
||||
|
||||
if subprocess.call(clone_cmd) == 0:
|
||||
logger.info("Repositorio clonado correctamente.")
|
||||
else:
|
||||
logger.error(f"ERROR\tNo se pudo clonar el repositorio {ipxe_repo_url}.")
|
||||
return False
|
||||
else:
|
||||
logger.info(f"Usando el repositorio clonado previamente en {clone_dir}")
|
||||
|
||||
os.chdir(f"{clone_dir}/src")
|
||||
|
||||
logger.info("Generando make de undionly.kpxe:")
|
||||
undionly_cmd = [
|
||||
"make", "-s", "bin/undionly.kpxe",
|
||||
f"EMBED={install_ogboot_target}/tftpboot/ipxe_scripts/dhcp_boot.ipxe"
|
||||
]
|
||||
if subprocess.run(undionly_cmd, capture_output=True).returncode == 0:
|
||||
logger.info("Boot file undionly.kpxe generado correctamente.")
|
||||
else:
|
||||
logger.error("ERROR\tNo se pudo generar el archivo undionly.kpxe.")
|
||||
return False
|
||||
|
||||
logger.info("Copiando undionly.kpxe al directorio de destino:")
|
||||
dest_undionly = os.path.join(install_ogboot_target, "tftpboot")
|
||||
if subprocess.call(["cp", "bin/undionly.kpxe", dest_undionly]) == 0:
|
||||
logger.info(f"Archivo undionly.kpxe copiado a {dest_undionly}")
|
||||
else:
|
||||
logger.error("ERROR\tNo se pudo copiar el archivo undionly.kpxe.")
|
||||
return False
|
||||
|
||||
logger.info("Generando make de ipxe.efi:")
|
||||
ipxe_efi_cmd = [
|
||||
"make", "-s", "bin-x86_64-efi/ipxe.efi",
|
||||
f"EMBED={install_ogboot_target}/tftpboot/ipxe_scripts/dhcp_boot.ipxe"
|
||||
]
|
||||
if subprocess.run(ipxe_efi_cmd, capture_output=True).returncode == 0:
|
||||
logger.info("Archivo ipxe.efi generado correctamente.")
|
||||
else:
|
||||
logger.error("ERROR\tNo se pudo generar el archivo ipxe.efi.")
|
||||
return False
|
||||
|
||||
logger.info("Copiando ipxe.efi al directorio de destino:")
|
||||
dest_ipxe_efi = os.path.join(install_ogboot_target, "tftpboot")
|
||||
if subprocess.call(["cp", "bin-x86_64-efi/ipxe.efi", dest_ipxe_efi]) == 0:
|
||||
logger.info(f"Archivo ipxe.efi copiado a {dest_ipxe_efi}")
|
||||
else:
|
||||
logger.error("ERROR\tNo se pudo copiar el archivo ipxe.efi.")
|
||||
return False
|
||||
|
||||
os.chdir(cwd)
|
||||
logger.info("Proceso completado exitosamente.")
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
if update_ipxe_boot_files():
|
||||
logger.info("Archivos de arranque actualizados correctamente.")
|
||||
else:
|
||||
logger.error("Hubo un error durante la actualización de los archivos de arranque.")
|
||||
except Exception as e:
|
||||
logger.error(f"ERROR\tFallo crítico: {e}")
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
#!/bin/bash
|
||||
#/**
|
||||
#@file ogfunctions.sh
|
||||
#@brief Generic functions for OpenGnsys Server and OpenGnsys Repository.
|
||||
#@version 1.1.1 - Initial version
|
||||
#@author Ramón M. Gómez, ETSII Universidad de Sevilla
|
||||
#@date 2017-10-08
|
||||
#*/
|
||||
|
||||
|
||||
# Showing an error message.
|
||||
function raiseError() {
|
||||
case "$1" in
|
||||
usage)
|
||||
echo "$PROG: Usage error: Type \"$PROG help\"" >&2
|
||||
exit 1 ;;
|
||||
notfound)
|
||||
echo "$PROG: Resource not found: $2" >&2
|
||||
exit 2 ;;
|
||||
access)
|
||||
echo "$PROG: Access error: $2" >&2
|
||||
exit 3 ;;
|
||||
download)
|
||||
echo "$PROG: Download error: $2" >&2
|
||||
exit 4 ;;
|
||||
*)
|
||||
echo "$PROG: Unknown error" >&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Showing help message.
|
||||
function help() {
|
||||
[ -n "$1" ] && DESCRIPTION="$1" || DESCRIPTION=$(grep "^#@brief" "$0" | cut -f2- -d" ")
|
||||
shift
|
||||
if [ -n "$1" ]; then
|
||||
USAGE="$1"
|
||||
shift
|
||||
else
|
||||
USAGE=$(grep "^#@usage" "$0" | cut -f2- -d" ")
|
||||
[ -n "$USAGE" ] && PARAMS=$(awk '$1=="#@param" {sub($1,""); print "\t",$0}' "$0")
|
||||
fi
|
||||
# Showing help.
|
||||
echo "$PROG: ${DESCRIPTION:-"no description"}"
|
||||
echo "Usage: ${USAGE:-"no usage info"}"
|
||||
[ -n "$PARAMS" ] && echo -e "$PARAMS"
|
||||
if [ -n "$*" ]; then
|
||||
echo "Examples:"
|
||||
while (( "$#" )); do
|
||||
echo -e "\t$1"
|
||||
shift
|
||||
done
|
||||
fi
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Metafunction to check if JSON result exists.
|
||||
JQ=$(which jq 2>/dev/null) || raiseError notfound "Need to install \"jq\"."
|
||||
function jq() {
|
||||
local OUTPUT
|
||||
OUTPUT=$($JQ "$@") || return $?
|
||||
[[ "$OUTPUT" = "null" ]] && return 1
|
||||
echo "$OUTPUT"
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
cat grub.cfg
|
||||
##NO-TOCAR-ESTA-LINEA ogLive
|
||||
set timeout=0
|
||||
set timeout_style=hidden
|
||||
|
||||
echo ">>> GRUB lanzador detectando MAC..."
|
||||
sleep 1
|
||||
|
||||
echo ">>> MAC detectada: ${net_default_mac}"
|
||||
sleep 1
|
||||
|
||||
echo ">>> Intentando cargar menú específico: /menu.lst/01-${net_default_mac}"
|
||||
sleep 1
|
||||
|
||||
configfile /menu.lst/01-${net_default_mac}
|
||||
|
||||
echo ">>> No se pudo cargar /menu.lst/01-${net_default_mac}"
|
||||
sleep 5
|
||||
reboot
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,103 @@
|
|||
#!ipxe
|
||||
|
||||
# Detectar si se está ejecutando en modo UEFI o BIOS
|
||||
iseq ${platform} efi && goto uefi_menu || goto bios_mbr
|
||||
|
||||
:bios_mbr
|
||||
echo "Running in BIOS mode - Booting MBR"
|
||||
chain tftp://172.17.8.61/grub.exe --config-file="title MBR;chainloader (hd0)+1;rootnoverify (hd0);boot" || echo "Failed to boot MBR in BIOS mode"
|
||||
exit
|
||||
|
||||
:uefi_menu
|
||||
echo "Running in UEFI mode - Searching boot loaders"
|
||||
|
||||
set detected no
|
||||
|
||||
# Buscar y configurar opciones de arranque
|
||||
echo "Searching Grub"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\grub\Boot\grubx64.efi && goto add_grub
|
||||
|
||||
:add_grub
|
||||
set detected yes
|
||||
echo "Grub found"
|
||||
goto boot_grub
|
||||
|
||||
:boot_grub
|
||||
echo "Booting Grub"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\grub\Boot\grubx64.efi || echo "Failed to boot Grub"
|
||||
exit
|
||||
|
||||
:refind
|
||||
echo "Searching rEFInd"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\refind\shimx64.efi.signed && goto add_refind
|
||||
|
||||
:add_refind
|
||||
set detected yes
|
||||
echo "rEFInd found"
|
||||
goto boot_refind
|
||||
|
||||
:boot_refind
|
||||
echo "Booting rEFInd"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\refind\shimx64.efi.signed || echo "Failed to boot rEFInd"
|
||||
exit
|
||||
|
||||
:part_01_02
|
||||
echo "Searching Part-01-02"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\Part-01-02\Boot\ogloader.efi && goto add_part_01_02
|
||||
|
||||
:add_part_01_02
|
||||
set detected yes
|
||||
echo "Part-01-02 found"
|
||||
goto boot_part_01_02
|
||||
|
||||
:boot_part_01_02
|
||||
echo "Booting Part-01-02"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\Part-01-02\Boot\ogloader.efi || echo "Failed to boot Part-01-02"
|
||||
exit
|
||||
|
||||
:part_01_03
|
||||
echo "Searching Part-01-03"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\Part-01-03\Boot\ogloader.efi && goto add_part_01_03
|
||||
|
||||
:add_part_01_03
|
||||
set detected yes
|
||||
echo "Part-01-03 found"
|
||||
goto boot_part_01_03
|
||||
|
||||
:boot_part_01_03
|
||||
echo "Booting Part-01-03"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\Part-01-03\Boot\ogloader.efi || echo "Failed to boot Part-01-03"
|
||||
exit
|
||||
|
||||
:microsoft
|
||||
echo "Searching Microsoft"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\Microsoft\Boot\bootmgfw.efi && goto add_microsoft
|
||||
|
||||
:add_microsoft
|
||||
set detected yes
|
||||
echo "Microsoft Boot Manager found"
|
||||
goto boot_microsoft
|
||||
|
||||
:boot_microsoft
|
||||
echo "Booting Microsoft Boot Manager"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\Microsoft\Boot\bootmgfw.efi || echo "Failed to boot Microsoft Boot Manager"
|
||||
exit
|
||||
|
||||
:ubuntu
|
||||
echo "Searching Ubuntu"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\ubuntu\grubx64.efi && goto add_ubuntu
|
||||
|
||||
:add_ubuntu
|
||||
set detected yes
|
||||
echo "Ubuntu found"
|
||||
goto boot_ubuntu
|
||||
|
||||
:boot_ubuntu
|
||||
echo "Booting Ubuntu"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\ubuntu\grubx64.efi || echo "Failed to boot Ubuntu"
|
||||
exit
|
||||
|
||||
:no_os_detected
|
||||
iseq ${detected} no && echo "OpenGnsys no ha detectado ningún sistema operativo en este equipo"
|
||||
exit
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#!ipxe
|
||||
|
||||
# Detectar si se está ejecutando en modo UEFI o BIOS
|
||||
iseq ${platform} efi && goto uefi_boot || goto bios_boot
|
||||
|
||||
:bios_boot
|
||||
echo "Running in BIOS mode - Booting first disk"
|
||||
chain http://__SERVERIP__/tftpboot/grub.exe --config-file="timeout 0; title FirstHardDisk;chainloader (hd0)+1;rootnoverify (hd0);boot" || echo "Failed to boot in BIOS mode"
|
||||
exit
|
||||
|
||||
:uefi_boot
|
||||
echo "Running in UEFI mode - Booting first disk"
|
||||
sanboot --no-describe --drive 0 --filename \EFI\grub\Boot\grubx64.efi || echo "Failed to boot in UEFI mode"
|
||||
exit
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#!ipxe
|
||||
|
||||
# Detectar si se está ejecutando en modo UEFI o BIOS
|
||||
iseq ${platform} efi && goto uefi_boot || goto bios_boot
|
||||
|
||||
:bios_boot
|
||||
echo "Running in BIOS mode - Booting first disk, first partition"
|
||||
chain http://__SERVERIP__/tftpboot/grub.exe --config-file="timeout 0; title FirstHardDisk-FirstPartition;root (hd0,0);chainloader (hd0,0)+1;boot" || echo "Failed to boot in BIOS mode"
|
||||
exit
|
||||
|
||||
:uefi_boot
|
||||
echo "Running in UEFI mode - Booting first disk, first partition"
|
||||
chain http://__SERVERIP__/tftpboot/grubx64.efi
|
||||
exit
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!ipxe
|
||||
|
||||
# Detectar si se está ejecutando en modo UEFI o BIOS
|
||||
iseq ${platform} efi && goto uefi_boot || goto bios_boot
|
||||
|
||||
:bios_boot
|
||||
echo "Running in BIOS mode - Booting first disk, second partition"
|
||||
chain http://__SERVERIP__/tftpboot/grub.exe --config-file="timeout 0; title FirstHardDisk-SecondPartition;root (hd0,1);chainloader (hd0,1)+1;boot" || echo "Failed to boot in BIOS mode"
|
||||
exit
|
||||
|
||||
:uefi_boot
|
||||
echo "Running in UEFI mode - Booting first disk, second partition"
|
||||
chain http://__SERVERIP__/tftpboot/grubx64.efi
|
||||
exit
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!ipxe
|
||||
|
||||
# Detectar si se está ejecutando en modo UEFI o BIOS
|
||||
iseq ${platform} efi && goto uefi_boot || goto bios_boot
|
||||
|
||||
:bios_boot
|
||||
echo "Running in BIOS mode - Booting first disk, third partition"
|
||||
chain http://__SERVERIP__/tftpboot/grub.exe --config-file="timeout 0; title FirstHardDisk-ThirdPartition;root (hd0,2);chainloader (hd0,2)+1;boot" || echo "Failed to boot in BIOS mode"
|
||||
exit
|
||||
|
||||
:uefi_boot
|
||||
echo "Running in UEFI mode - Booting first disk, third partition"
|
||||
chain http://__SERVERIP__/tftpboot/grubx64.efi
|
||||
exit
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
#!ipxe
|
||||
|
||||
# Detectar si se está ejecutando en modo UEFI o BIOS
|
||||
iseq ${platform} efi && goto uefi_boot || goto bios_boot
|
||||
|
||||
:bios_boot
|
||||
set timeout 3000
|
||||
set esc:hex 1b
|
||||
set bold ${esc:string}[1m
|
||||
set boldoff ${esc:string}[22m
|
||||
set fg_cya ${esc:string}[36m
|
||||
set fg_whi ${esc:string}[37m
|
||||
set ISODIR __OGLIVE__
|
||||
set default 0
|
||||
set kernelargs __INFOHOST__
|
||||
|
||||
:main_menu
|
||||
clear menu
|
||||
menu ${bold}${fg_cya}OpenGnsys iPXE Disk Boot Menu${boldoff}
|
||||
item part1 FirstDisk-FirstPartition
|
||||
item part2 FirstHardDisk-SecondPartition
|
||||
item part3 FirstDisk-ThirdPartition
|
||||
item ogcache OpenGnsys CACHE
|
||||
item ognet OpenGnsys NET
|
||||
item ognetdef OpenGnsys NET Default
|
||||
item shell iPXE Shell
|
||||
choose --timeout ${timeout} --default ogcache target && goto ${target}
|
||||
|
||||
:part1
|
||||
echo Booting FirstDisk-FirstPartition...
|
||||
chain http://__SERVERIP__/tftpboot/grub.exe --config-file="timeout 1; title FirstDisk-FirstPartition; root (hd0,0); chainloader (hd0,0)+1; boot" || echo Failed to boot part1
|
||||
exit
|
||||
|
||||
:part2
|
||||
echo Booting FirstHardDisk-SecondPartition...
|
||||
chain http://__SERVERIP__/tftpboot/grub.exe --config-file="timeout 1; title FirstHardDisk-SecondPartition; root (hd0,1); chainloader (hd0,1)+1; boot" || echo Failed to boot part2
|
||||
exit
|
||||
|
||||
:part3
|
||||
echo Booting FirstDisk-ThirdPartition...
|
||||
chain http://__SERVERIP__/tftpboot/grub.exe --config-file="timeout 1; title FirstDisk-ThirdPartition; root (hd0,2); chainloader (hd0,2)+1; boot" || echo Failed to boot part3
|
||||
exit
|
||||
|
||||
:ogcache
|
||||
echo Booting OpenGnsys-CACHE...
|
||||
chain http://__SERVERIP__/tftpboot/grub.exe --config-file="timeout 1; title OpenGnsys-CACHE; find --set-root /boot/__OGLIVE__/ogvmlinuz; kernel /boot/__OGLIVE__/ogvmlinuz ogactiveadmin=true ogdebug=true __INFOHOST__; initrd /boot/__OGLIVE__/oginitrd.img; boot"
|
||||
|
||||
:ognet
|
||||
echo Booting OpenGnsys-NET...
|
||||
kernel http://__SERVERIP__/tftpboot/${ISODIR}/ogvmlinuz ogactiveadmin=false ogdebug=false ${kernelargs} || goto fallback
|
||||
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
|
||||
boot
|
||||
|
||||
:ognetdef
|
||||
echo Booting OpenGnsys-NET Default...
|
||||
set ISODIR ogLive
|
||||
kernel http://__SERVERIP__/tftpboot/${ISODIR}/ogvmlinuz ogactiveadmin=false ogdebug=false ${kernelargs}
|
||||
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
|
||||
boot
|
||||
|
||||
:shell
|
||||
echo Launching iPXE shell...
|
||||
shell
|
||||
|
||||
:uefi_boot
|
||||
echo "Running in UEFI mode - Booting Menu"
|
||||
chain http://__SERVERIP__/tftpboot/grubx64.efi
|
||||
exit
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#!ipxe
|
||||
set timeout 0
|
||||
set timeout-style hidden
|
||||
|
||||
set ISODIR __OGLIVE__
|
||||
set default 0
|
||||
set kernelargs __INFOHOST__
|
||||
# Menú de entrada para seleccionar OgLive
|
||||
:try_iso
|
||||
kernel http://__SERVERIP__/tftpboot/${ISODIR}/ogvmlinuz ogdebug=false ${kernelargs} || goto fallback
|
||||
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
|
||||
boot
|
||||
|
||||
:fallback
|
||||
echo "OgLive default"
|
||||
set ISODIR ogLive
|
||||
kernel http://__SERVERIP__/tftpboot/${ISODIR}/ogvmlinuz ogdebug=false ${kernelargs}
|
||||
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
|
||||
boot
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#!ipxe
|
||||
set timeout 0
|
||||
set timeout-style hidden
|
||||
|
||||
set ISODIR __OGLIVE__
|
||||
set default 0
|
||||
set kernelargs __INFOHOST__
|
||||
# Menú de entrada para seleccionar OgLive
|
||||
:try_iso
|
||||
kernel http://__SERVERIP__/tftpboot/${ISODIR}/ogvmlinuz ogactiveadmin=true ogdebug=true ${kernelargs} || goto fallback
|
||||
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
|
||||
boot
|
||||
|
||||
:fallback
|
||||
echo "OgLive default"
|
||||
set ISODIR ogLive
|
||||
kernel http://__SERVERIP__/tftpboot/${ISODIR}/ogvmlinuz ogactiveadmin=true ogdebug=true ${kernelargs}
|
||||
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
|
||||
boot
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#!ipxe
|
||||
|
||||
#Template: ogliveBios
|
||||
|
||||
# Detectar si se está ejecutando en modo UEFI o BIOS
|
||||
iseq ${platform} efi && goto uefi_boot || goto bios_boot
|
||||
|
||||
:uefi_boot
|
||||
set timeout 0
|
||||
set timeout-style hidden
|
||||
|
||||
set ISODIR __OGLIVE__
|
||||
set default 0
|
||||
set kernelargs ogactiveadmin=true ogdebug=true __INFOHOST__
|
||||
# Menú de entrada para seleccionar OgLive
|
||||
:try_iso
|
||||
kernel http://__SERVERIP__/tftpboot/${ISODIR}/ogvmlinuz ${kernelargs} || goto fallback
|
||||
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
|
||||
boot
|
||||
|
||||
:fallback
|
||||
echo "OgLive default"
|
||||
set ISODIR ogLive
|
||||
kernel http://__SERVERIP__/tftpboot/${ISODIR}/ogvmlinuz ${kernelargs}
|
||||
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
|
||||
boot
|
||||
|
||||
|
||||
:bios_boot
|
||||
set PIPE |
|
||||
set SERVERIP __SERVERIP__
|
||||
set ISODIR __OGLIVE__
|
||||
set kernelargs ogactiveadmin=true ogdebug=true __INFOHOST__
|
||||
|
||||
set CFG_PREFIX default saved; timeout 1; hiddenmenu; fallback 1 2 3 4; set ISODIR=${ISODIR};
|
||||
set CFG_FIRSTBOOT title firsboot; find --set-root --ignore-floppies --ignore-cd /ogboot.me checkrange 0x07 parttype > nul; cmp /ogboot.me /ogboot.firstboot ${PIPE}${PIPE} ls FALLBACK; write /ogboot.firstboot iniciado; chainloader +1; boot;
|
||||
set CFG_SECONDBOOT title secondboot; find --set-root --ignore-floppies --ignore-cd /ogboot.me checkrange 0x07 parttype > nul; cmp /ogboot.me /ogboot.secondboot; write /ogboot.secondboot iniciado; chainloader +1; boot;
|
||||
set CFG_OGCACHE title OpenGnsys-CACHE; find --set-root --ignore-floppies --ignore-cd /boot/%ISODIR%/ogvmlinuz; kernel /boot/%ISODIR%/ogvmlinuz ogactiveadmin=false ogdebug=false ogupdateinitrd=true ${kernelargs}; initrd /boot/%ISODIR%/oginitrd.img; boot;
|
||||
#set CFG_OGNET title OpenGnsys-NET; kernel (pd)/%ISODIR%/ogvmlinuz ${kernelargs}; initrd (pd)/%ISODIR%/oginitrd.img; boot;
|
||||
#set CFG_OGNET_DEFAULT title OpenGnsys-NET default; kernel (pd)/ogLive/ogvmlinuz ${kernelargs}; initrd (pd)/ogLive/oginitrd.img; boot;
|
||||
|
||||
set default 0
|
||||
# Menú de entrada para seleccionar OgLive
|
||||
:try_iso
|
||||
chain http://${SERVERIP}/tftpboot/grub.exe --config-file="${CFG_PREFIX} ${CFG_FIRSTBOOT} ${CFG_SECONDBOOT} ${CFG_OGCACHE}"
|
||||
boot
|
||||
|
||||
:fallback
|
||||
echo "OgLive default"
|
||||
set ISODIR ogLive
|
||||
kernel http://${SERVERIP}/tftpboot/${ISODIR}/ogvmlinuz ogactiveadmin=true ogdebug=true ${kernelargs}
|
||||
initrd http://${SERVERIP}/tftpboot/${ISODIR}/oginitrd.img
|
||||
boot
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!ipxe
|
||||
|
||||
# Detectar si se está ejecutando en modo UEFI o BIOS
|
||||
iseq ${platform} efi && goto uefi_boot || goto bios_boot
|
||||
|
||||
:bios_boot
|
||||
echo "Running in BIOS mode"
|
||||
# Si el cliente es BIOS, arranca el grub.pxe
|
||||
chain http://__SERVERIP__/tftpboot/grub.exe --config-file="timeout 1; title OpenGnsys-CACHE; find --set-root /boot/__OGLIVE__/ogvmlinuz; kernel /boot/__OGLIVE__/ogvmlinuz ogactiveadmin=true ogdebug=true __INFOHOST__; initrd /boot/__OGLIVE__/oginitrd.img; boot"
|
||||
exit
|
||||
|
||||
:uefi_boot
|
||||
echo "Running in UEFI mode"
|
||||
# Si el cliente es UEFI, arranca el grubx64.efi
|
||||
chain http://__SERVERIP__/tftpboot/grubx64.efi
|
||||
exit
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
##NO-TOCAR-ESTA-LINEA ogLive
|
||||
set timeout=0
|
||||
set timeout_style=hidden
|
||||
|
||||
echo ">>> Iniciando GRUB embebido"
|
||||
|
||||
set ISODIR=__OGLIVE__
|
||||
echo ">>> ISODIR definido como: $ISODIR"
|
||||
|
||||
echo ">>> Buscando ogvmlinuz en particiones locales..."
|
||||
search --file --set=root /boot/$ISODIR/ogvmlinuz
|
||||
|
||||
if [ -n "$root" ]; then
|
||||
echo ">>> OgLive encontrado en CACHE en $root"
|
||||
echo ">>> Cargando kernel..."
|
||||
linux /boot/$ISODIR/ogvmlinuz __INFOHOST__
|
||||
echo ">>> Cargando initrd..."
|
||||
initrd /boot/$ISODIR/oginitrd.img
|
||||
echo ">>> Ejecutando boot"
|
||||
boot
|
||||
else
|
||||
echo ">>> ogvmlinuz no encontrado en CACHE."
|
||||
echo ">>> Reintentando en red o abortando..."
|
||||
reboot
|
||||
fi
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
if ! search --file --set root /Part-__DISK__-__PART__; then
|
||||
search --file --set root /EFI/Part-__DISK__-__PART__/Boot/ogloader.efi
|
||||
fi
|
||||
search --file --set rootEFI /EFI/Part-__DISK__-__PART__/Boot/ogloader.efi
|
||||
chainloader ($rootEFI)/EFI/Part-__DISK__-__PART__/Boot/ogloader.efi
|
||||
boot
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
set timeout=30
|
||||
|
||||
set detectado='no'
|
||||
# Compruebo si existen distintos cargadores.
|
||||
echo "Searching Grub"
|
||||
set ISODIR=__OGLIVE__
|
||||
search --file --set rootGrub /EFI/grub/Boot/grubx64.efi
|
||||
if [ "$rootGrub" != "" ]; then
|
||||
set detectado='si'
|
||||
menuentry "Grub" {
|
||||
root="$rootGrub"
|
||||
chainloader /EFI/grub/Boot/grubx64.efi
|
||||
}
|
||||
fi
|
||||
|
||||
echo "Searching rEFInd"
|
||||
search --file --set rootRefind /EFI/refind/shimx64.efi.signed
|
||||
if [ "$rootRefind" != "" ]; then
|
||||
menuentry "rEFInd" {
|
||||
root="$rootRefind"
|
||||
chainloader /EFI/refind/shimx64.efi.signed
|
||||
}
|
||||
fi
|
||||
|
||||
if ! search --file --set rootP2 /Part-01-02; then
|
||||
search --file --set rootP2 /EFI/Part-01-02/Boot/ogloader.efi
|
||||
fi
|
||||
search --file --set rootEFI /EFI/Part-01-02/Boot/ogloader.efi
|
||||
|
||||
if [ "$rootP2" != "" ]; then
|
||||
set detectado='si'
|
||||
menuentry "Part-01-02" {
|
||||
root="$rootP2"
|
||||
chainloader ($rootEFI)/EFI/Part-01-02/Boot/ogloader.efi
|
||||
}
|
||||
fi
|
||||
|
||||
if ! search --file --set rootP3 /Part-01-03; then
|
||||
search --file --set rootP3 /EFI/Part-01-03/Boot/ogloader.efi
|
||||
fi
|
||||
|
||||
search --file --set rootEFI /EFI/Part-01-03/Boot/ogloader.efi
|
||||
|
||||
if [ "$rootEFI" != "" ]; then
|
||||
set detectado='si'
|
||||
menuentry "Part-01-03" {
|
||||
root="$rootP3"
|
||||
chainloader ($rootEFI)/EFI/Part-01-03/Boot/ogloader.efi
|
||||
}
|
||||
fi
|
||||
|
||||
echo "Searching Windows"
|
||||
search --file --set rootMS /EFI/Microsoft/Boot/bootmgfw.efi
|
||||
if [ "$rootMS" != "" ]; then
|
||||
set detectado='si'
|
||||
menuentry "Windows" {
|
||||
root="$rootMS"
|
||||
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
|
||||
}
|
||||
fi
|
||||
|
||||
echo "Searching Ubuntu"
|
||||
search --file --set rootUb /EFI/ubuntu/grubx64.efi
|
||||
if [ "$rootUb" != "" ]; then
|
||||
set detectado='si'
|
||||
menuentry "Ubuntu"{
|
||||
root="$rootUb"
|
||||
chainloader /EFI/ubuntu/grubx64.efi
|
||||
}
|
||||
fi
|
||||
|
||||
|
||||
echo "Buscando ogvmlinuz en particiones locales..."
|
||||
search --file --set=rootOgCache /boot/$ISODIR/ogvmlinuz
|
||||
if [ "$rootOgCache" != "" ]; then
|
||||
set detectado='si'
|
||||
menuentry "Oglive Cache"{
|
||||
root="$rootOgCache"
|
||||
linux /boot/$ISODIR/ogvmlinuz __INFOHOST__
|
||||
initrd /boot/$ISODIR/oginitrd.img
|
||||
}
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Si no hay ningún sistema operativo muestro mensaje.
|
||||
if [ $detectado == 'no' ]; then
|
||||
menuentry "OpenGnsys no ha detectado ningún sistema operativo" {
|
||||
# para evitar mensajes de error.
|
||||
set root="(hd0,gpt1)"
|
||||
}
|
||||
fi
|
||||
Loading…
Reference in New Issue