Compare commits

..

4 Commits

105 changed files with 2712 additions and 7091 deletions

View File

@ -38,4 +38,3 @@ MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
###> symfony/mailer ###
# MAILER_DSN=null://null
###< symfony/mailer ###

View File

@ -1,47 +0,0 @@
# 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"

7
.gitignore vendored
View File

@ -1,4 +1,3 @@
**/*.swp
###> symfony/framework-bundle ###
/.env.local
@ -19,9 +18,3 @@
.phpunit.result.cache
/phpunit.xml
###< symfony/phpunit-bridge ###
### Debian packaging
debian/ogboot
debian/*.substvars
debian/*.log
debian/.debhelper/
debian/files

View File

@ -1,52 +0,0 @@
# 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.

View File

@ -1,87 +0,0 @@
# 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.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.

View File

@ -1,104 +0,0 @@
@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 {
always {
notifyBuildStatus('narenas@qindel.com')
}
}
}

1393
README.md

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +0,0 @@
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

View File

@ -1,5 +0,0 @@
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)%"

View File

@ -1,44 +0,0 @@
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

View File

@ -1,6 +0,0 @@
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

View File

@ -1,24 +0,0 @@
# 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

View File

@ -1,3 +0,0 @@
framework:
mailer:
dsn: '%env(MAILER_DSN)%'

View File

@ -1,17 +0,0 @@
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

View File

@ -1,72 +0,0 @@
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"]

View File

@ -1,59 +0,0 @@
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

View File

@ -1,12 +0,0 @@
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 }

View File

@ -1,12 +0,0 @@
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

View File

@ -1,40 +0,0 @@
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

View File

@ -1,7 +0,0 @@
framework:
default_locale: en
translator:
default_path: '%kernel.project_dir%/translations'
fallbacks:
- en
providers:

View File

@ -1,6 +0,0 @@
twig:
default_path: '%kernel.project_dir%/templates'
when@test:
twig:
strict_variables: true

View File

@ -1,13 +0,0 @@
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

View File

@ -1,15 +0,0 @@
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 }

View File

@ -1,5 +0,0 @@
<?php
if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
}

View File

@ -1,7 +0,0 @@
#index:
# path: /
# controller: App\Controller\DefaultController::index
app.swagger_ui:
path: /ogboot/api/doc
methods: GET
defaults: { _controller: nelmio_api_doc.controller.swagger_ui }

View File

@ -1,4 +0,0 @@
when@dev:
_errors:
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
prefix: /_error

View File

@ -1,8 +0,0 @@
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

View File

@ -1,9 +0,0 @@
<?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']);
};

View File

@ -1,151 +0,0 @@
<?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

View File

@ -1,73 +0,0 @@
<?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
];
}
}

Binary file not shown.

View File

@ -15,4 +15,3 @@ return function (array $context) {
return new Application($kernel);
};

View File

@ -0,0 +1,85 @@
import os
import socket
import json
import subprocess
import logging
import stat
# Configuración de logging
logging.basicConfig(level=logging.INFO, filename='/var/log/oglive_daemon.log', filemode='a', format='%(asctime)s - %(levelname)s - %(message)s')
def handle_command(command):
action = command.get('action')
args = command.get('args', [])
cleaned_args = [arg.strip('\'"') for arg in args]
logging.info(f'Handling command: {action} with args: {cleaned_args}')
try:
if action in ['config', 'install', 'download', 'show', 'check', 'uninstall', 'disk_usage','list_installed_oglives','get_info','get_default','set_default','check_services_status']:
command_to_run = ['sudo', '/opt/ogboot/bin/oglivecli', action] + cleaned_args
logging.info(f'Running command: {" ".join(command_to_run)}')
process = subprocess.Popen(command_to_run, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
stdout, stderr = process.communicate()
logging.info(f'Command stdout: {stdout}')
logging.error(f'Command stderr: {stderr}')
# Asumimos que `stdout` contendrá el JSON válido
try:
json_output = json.loads(stdout)
return {"success": True, "output": json_output}
except json.JSONDecodeError as e:
logging.error(f'Error parsing JSON: {e} - Raw output: {stdout}')
return {"success": False, "error": f'Error parsing JSON: {str(e)} - Raw output: {stdout}'}
else:
return {"success": False, "error": "Unknown command"}
except Exception as e:
logging.error(f'Error handling command {action}: {e}')
return {"success": False, "error": str(e)}
def main():
# Crea el directorio si no existe
if not os.path.exists('/var/run/oglive'):
os.makedirs('/var/run/oglive', exist_ok=True)
socket_path = '/var/run/oglive/oglive_daemon.sock'
# Elimina el socket si existe
if os.path.exists(socket_path):
os.remove(socket_path)
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
server.bind(socket_path)
# Establece los permisos del socket
os.chmod(socket_path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) # Permisos para todos los usuarios
server.listen()
try:
while True:
logging.info('Daemon ready to accept connections')
conn, _ = server.accept()
with conn:
logging.info('Accepted connection')
data = conn.recv(1024)
if not data:
continue
try:
command = json.loads(data.decode('utf-8'))
logging.info(f'Received command: {command}')
except json.JSONDecodeError:
logging.error('Failed to decode JSON')
conn.sendall(json.dumps({"success": False, "error": "Invalid JSON"}).encode('utf-8'))
continue
response = handle_command(command)
conn.sendall(json.dumps(response).encode('utf-8'))
finally:
server.close()
if os.path.exists(socket_path):
os.remove(socket_path)
if __name__ == '__main__':
main()

View File

@ -5,34 +5,45 @@
#@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
#@param help show this help
#@param version show script version
#@param config [Parameter] show configuration parameters
#@param check check system consistency
#@param convert convert old ogclient to new default ogLive client
#@param list list installed ogLive clients
#@param show all show JSON information about all installed ogLive clients
#@param show default show JSON information about ogLive client marked as default
#@param show Index|Dir show JSON information about an installed ogLive client
#@param search Index|Dir show corresponding index or directory
#@param download show a menu to download an ogLive ISO image from the OpenGnsys website
#@param download Iso download an specific ogLive ISO image from the OpenGnsys website
#@param install Iso install a new ogLive client from a downloaded ISO image
#@param uninstall Iso remove ISO image and uninstall its ogLive client
#@param uninstall Index|Dir uninstall an ogLive client
#@param get-default get index value for default ogLive client
#@param set-default Index set default ogLive client
#@param rebuild rebuild a lost configuration file
#@param assign Iso Index assign an ISO file to a JSON entry
#@param Options:
#@param Index a number, starting by 0
#@param Dir directory (relative to installation directory)
#@param Iso ISO file name (relative to download URL or download directory)
#@warning This script needs "jq" command.
#@version 3.0.0 - Updated with to adapt to Ogboot.
#@version 1.1.0 - Initial version.
#@author Ramón M. Gómez - ETSII Univ. Sevilla
#@author Qindel formacion y servicios SL
#@date 2024-08-06
#@date 2016-12-05
#@version 1.1.1b - Use reduced directory names.
#@author Ramón M. Gómez - ETSII Univ. Sevilla
#@date 2020-01-17
#*/ ##
# Global constants definition.
PROG=$(basename "$(realpath "$0")") # Program name.
PROGDIR=$(dirname "$(realpath "$0")") # Dir where program is
OPENGNSYS=$(realpath $PROGDIR/../) # ogboot main directory.
OPENGNSYS=/opt/ogboot # OpenGnsys 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.
DOWNLOADURL="https://ognproject.evlt.uma.es/trac/downloads" # Download URL.
TFTPDIR=$OPENGNSYS/tftpboot # TFTP directory.
DEFOGLIVE="ogLive" # Default ogLive directory.
MINREL=20190601 # Mininum ogLive compatibility release.
INFOFILE=$OPENGNSYS/etc/ogliveinfo.json # Configuration file.
@ -42,7 +53,93 @@ INFOFILE=$OPENGNSYS/etc/ogliveinfo.json # Configuration file.
source $OPENGNSYS/lib/ogfunctions.sh || exit 1
# Create/edit JSON file about installed ogLive clients.
function addToJson() {
local i DATA OGLIVEDIST="$1" OGLIVEKRNL="$2" OGLIVEARCH="$3" OGLIVEREV="$4"
local OGLIVEDIR=$(basename $5 2>/dev/null) OGLIVEISO=$(basename $6 2>/dev/null)
# JSON data for installed ogLive.
DATA=$(cat << EOT | jq .
{"distribution":"$OGLIVEDIST","kernel":"$OGLIVEKRNL","architecture":"$OGLIVEARCH","revision":"$OGLIVEREV","directory":"$OGLIVEDIR","iso":"$OGLIVEISO"}
EOT
)
# Check JSON file consistency.
if [ "$(jq -c keys $INFOFILE 2>/dev/null)" == '["default","oglive"]' ]; then
# Check if ogLive is defined into JSON file.
n=$(jq ".oglive | length" $INFOFILE)
for ((i=0; i<n; i++)); do
[ "$(jq ".check=$DATA | .check==.oglive[$i]" $INFOFILE)" == "true" ] && INDEX=$i
done
# Check if it needs to insert data.
if [ -z "$INDEX" ]; then
INDEX=$n
jq ".oglive |= (. + [$DATA])" $INFOFILE | sponge $INFOFILE
fi
# Show JSON entry.
jq ".oglive[$INDEX]" $INFOFILE
else
# Create new JSON file.
cat << EOT | jq . | tee $INFOFILE
{"oglive":[$DATA],"default":0}
EOT
fi
}
# Command functions.
# Convert default ogclient to a new ogLive format.
function convert() {
local OGCLIENT=ogclient OLDINFOFILE=$OPENGNSYS/doc/veroglive.txt
local OGLIVEKRNL OGLIVEDIR OGLIVEISO
[ $# -ne 0 ] && raiseError usage
[ ! -w $(dirname $INFOFILE) ] && raiseError access "Configuration file."
[ -n "$(stat -c "%N" $TFTPDIR/ogclient | awk '$3~/'$DEFOGLIVE'/ {print}')" ] && raiseError access "ogLive is already converted."
pushd $TFTPDIR >/dev/null || raiseError access "Installation directory."
[ ! -f $OGCLIENT/ogvmlinuz ] && raiseError notfound "\"ogclient\"."
# Add entry to JSON file using ogclient kernel version.
OGLIVEKRNL=$(file -bkr $OGCLIENT/ogvmlinuz | awk '/Linux/ {for(i=1;i<=NF;i++) if($i~/version/) {v=$(i+1);sub(/-.*/,"",v);print v}}')
OGLIVEDIR=$DEFOGLIVE-$OGLIVEKRNL
[ -r $OLDINFOFILE ] && OGLIVEISO="$(head -1 $OLDINFOFILE)"
addToJson "$(echo $OGLIVEISO|cut -f2 -d-)" "$OGLIVEKRNL" "i386" "${OGLIVEISO##*-}" "$OGLIVEDIR" "$OGLIVEISO.iso"
# Rename directory, link to default and clean old files.
mv -v $OGCLIENT $OGLIVEDIR
ln -vfs $OGLIVEDIR $DEFOGLIVE
rm -f $OGCLIENT
ln -vfs $DEFOGLIVE $OGCLIENT
mv -v $OGCLIENT.old $OGLIVEDIR.old 2>/dev/null
rm -fv {ogvmlinuz,oginitrd.img}{,.sum} $OLDINFOFILE
popd >/dev/null
# Delete old config file.
rm -f $OLDINFOFILE
}
# Show script configuration parameters.
function config() {
local DATA
DATA=$(cat << EOT
[
{ "param": "config-file", "description": "Configuration file", "value": "$INFOFILE" },
{ "param": "download-url", "description": "ogLive download URL", "value": "$DOWNLOADURL" },
{ "param": "download-dir", "description": "ogLive download directory", "value": "$DOWNLOADDIR" },
{ "param": "install-dir", "description": "ogLive installation directory", "value": "$TFTPDIR" },
{ "param": "default-name", "description": "Default ogLive name", "value": "$DEFOGLIVE" },
{ "param": "min-release", "description": "Minimum compatibility release", "value": "r$MINREL" }
]
EOT
)
case $# in
0) # Show all parameters.
echo "$DATA" | jq -r '.[] | .description + " (" + .param + ")," + .value' | column -ts,
;;
1) # Show specified parameter.
DATA=$(echo "$DATA" | jq -r ".[] | select(.param==\"$1\").value")
[ "$DATA" ] || raiseError notfound "\"$1\"."
echo "$DATA"
;;
*) # Usage error.
raiseError usage
;;
esac
}
# Check consistency, showing configuration problems.
function check() {
@ -126,8 +223,9 @@ function search() {
# 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
local OGLIVE NISOS i HTTPCODE ISOREL
# Verificar si el directorio de descarga existe y tiene permisos de escritura.
[ ! -d "$DOWNLOADDIR" ] && raiseError notfound "Directorio de descarga."
@ -137,94 +235,55 @@ function download() {
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
local selected_name="$1"
# 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 la lista de archivos disponibles.
OGLIVE=( $(curl -k --silent $DOWNLOADURL | grep "$DEFOGLIVE.*iso") )
# Buscar el archivo seleccionado por nombre.
OGLIVEFILE=""
for iso in "${OGLIVE[@]}"; do
if [[ "$iso" == *"$selected_name"* ]]; then
OGLIVEFILE=$iso
break
fi
done
[ -n "$OGLIVEFILE" ] || raiseError download "Nombre \"$selected_name\" inválido."
# 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
local SOURCELENGTH=$(curl -k --head --retry 5 --retry-delay 5 --max-time 30 "$DOWNLOADURL/$OGLIVEFILE" | awk -F: '/Content-Length:/ {print $2}')
[ -n "$SOURCELENGTH" ] || raiseError download "$OGLIVEFILE"
# Descargar ogLive.
TARGETFILE="$DOWNLOADDIR/$OGLIVEFILE"
local 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
curl -k --retry 5 --retry-delay 5 "$DOWNLOADURL/$OGLIVEFILE" -o "$TARGETFILE" || raiseError download "\"$OGLIVEFILE\"."
install "$OGLIVEFILE"
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/^.*\///') )
OGLIVE=( $(curl -k --silent $DOWNLOADURL | grep "$DEFOGLIVE.*iso") )
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
local installed=false
local compatible=false
[ -e $DOWNLOADDIR/${OGLIVE[i-1]} ] && installed=true
ISOREL=${OGLIVE[i-1]##*-r}; ISOREL=${ISOREL%%.*}
[ "$ISOREL" -ge "$MINREL" ] && compatible=true
url="$DOWNLOADURL/${OGLIVE[i-1]}"
[ $ISOREL -ge $MINREL ] && compatible=true
local DATA=$(jq -n \
--arg id "$i" \
--arg filename "$OGLIVEFILE" \
--arg url "$url" \
--arg filename "${OGLIVE[i-1]}" \
--argjson installed "$installed" \
--argjson compatible "$compatible" \
'{id: $id, filename: $filename, url: $url, installed: $installed, compatible: $compatible}')
'{id: $id, filename: $filename, installed: $installed, compatible: $compatible}')
downloads+=("$DATA")
done
@ -233,7 +292,6 @@ function downloadMenu() {
'{downloads: $downloads}'
}
# Show a menu to select and download an ogLive ISO image from the OpenGnsys website.
function download_old() {
local OGLIVE NISOS i HTTPCODE TARGETFILE
@ -283,186 +341,137 @@ add_message() {
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; }
[ $# -ne 1 ] && { echo "{\"status\": \"error\", \"error\": \"usage\"}"; exit 1; }
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; }
OGLIVEFILE=$(realpath $DOWNLOADDIR/$1)
[ $(echo $OGLIVEFILE | wc -w) -gt 1 ] && { echo "{\"status\": \"error\", \"error\": \"usage\"}"; exit 1; }
[ ! -f $OGLIVEFILE ] && { echo "{\"status\": \"error\", \"error\": \"not found $1.\"}"; exit 1; }
[ ! -r $OGLIVEFILE ] && { echo "{\"status\": \"error\", \"error\": \"access $1.\"}"; exit 1; }
[ ! -w $(dirname $INFOFILE) ] && { echo "{\"status\": \"error\", \"error\": \"access configuration directory.\"}"; exit 1; }
[ ! -w $TFTPDIR ] && { echo "{\"status\": \"error\", \"error\": \"access installation directory.\"}"; exit 1; }
[ -z "$(file -b $OGLIVEFILE | grep "ISO.*ogClient")" ] && { echo "{\"status\": \"error\", \"error\": \"File is not an ogLive ISO image.\"}"; exit 1; }
OGLIVEDIST="$(echo "$OGLIVEFILE" | cut -f2 -d-)"
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)}')"
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"
OGLIVEDIR="$TFTPDIR/$DEFOGLIVE-${OGLIVEKRNL%%-*}-$OGLIVEARCH-$OGLIVEREV"
OGLIVEDIR="${OGLIVEDIR/amd64-/}"
[ ! -r "$OGINITRD" ] && OGINITRD="$TFTPDIR/$DEFOGLIVE/oginitrd.img"
if [ -r "$OGINITRD" ]; then
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" | \
SAMBAPASS=$($COMPRESS -dc $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"
rm -fr ${OGLIVEDIR}.old
mv -f $OGLIVEDIR ${OGLIVEDIR}.old 2>/dev/null
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; }
TMPDIR=/tmp/${OGLIVEFILE%.iso}
mkdir -p $OGLIVEDIR $TMPDIR
trap "umount $TMPDIR; rm -fr $TMPDIR" 1 2 3 6 9 15
mount -o loop,ro $OGLIVEFILE $TMPDIR >/dev/null 2>&1 || { echo "{\"status\": \"error\", \"error\": \"mount failed.\"}"; exit 1; }
cp -va $TMPDIR/ogclient/* $OGLIVEDIR >/dev/null 2>&1 || { echo "{\"status\": \"error\", \"error\": \"Cannot copy files to ogLive directory.\"}"; exit 1; }
umount $TMPDIR >/dev/null 2>&1
trap "umount $TMPDIR" 1 2 3 6 9 15
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; }
if [ ! -f $INFOFILE ]; then
rm -f $TFTPDIR/$DEFOGLIVE $TFTPDIR/$OGCLIENT
ln -vfs $(basename $OGLIVEDIR) $TFTPDIR/$DEFOGLIVE >/dev/null 2>&1 || { echo "{\"status\": \"error\", \"error\": \"Linking to $TFTPDIR/$DEFOGLIVE failed.\"}"; exit 1; }
ln -vfs $DEFOGLIVE $TFTPDIR/$OGCLIENT >/dev/null 2>&1 || { echo "{\"status\": \"error\", \"error\": \"Linking to $TFTPDIR/$OGCLIENT failed.\"}"; exit 1; }
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
echo -ne "$SAMBAPASS\n$SAMBAPASS\n" | $OPENGNSYS/bin/setsmbpass "$(basename $OGLIVEDIR)" >/dev/null 2>&1 || { echo "{\"status\": \"error\", \"error\": \"setsmbpass failed.\"}"; exit 1; }
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}')"
$OPENGNSYS/bin/setsmbpass "$(basename $OGLIVEDIR)" >/dev/null 2>&1 || { echo "{\"status\": \"error\", \"error\": \"setsmbpass failed.\"}"; exit 1; }
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"
find -L $OGLIVEDIR -type d -exec chmod 755 {} \; >/dev/null 2>&1 || { echo "{\"status\": \"error\", \"error\": \"chmod directories failed.\"}"; exit 1; }
find -L $OGLIVEDIR -type f -exec chmod 644 {} \; >/dev/null 2>&1 || { echo "{\"status\": \"error\", \"error\": \"chmod files failed.\"}"; exit 1; }
chown -R :opengnsys $OGLIVEDIR >/dev/null 2>&1 || { echo "{\"status\": \"error\", \"error\": \"chown failed.\"}"; exit 1; }
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"
OGSQFS=$OGLIVEDIR/ogclient.sqfs
[ ! -f "$OGLIVEDIR/oglive_info.json" ] && { echo "{\"error\": \"JSON_CREATION_FAILED\", \"message\": \"Failed to create oglive_info.json.\"}"; exit 500; }
sudo chown -R :opengnsys "$OGLIVEDIR" >/dev/null 2>&1 || { echo "{\"error\": \"CHOWN_FAILED\", \"message\": \"Failed to change ownership for $OGLIVEDIR.\"}"; exit 500; }
if mount -o loop,ro $OGSQFS $TMPDIR >/dev/null 2>&1; then
RSYNCSERV=$(rsync --version 2>/dev/null | awk '/protocol/ {print $6}')
RSYNCCLNT=$(chroot $TMPDIR /usr/bin/rsync --version 2>/dev/null | awk '/protocol/ {print $6}')
if [ -z "$RSYNCSERV" ] || [ "$RSYNCSERV" -gt "${RSYNCCLNT:-1}" ]; then
if [ -e "$OPENGNSYS/client/bin/rsync-$RSYNCSERV" ]; then
mv -f "$OPENGNSYS/client/bin/rsync-$RSYNCSERV" "$OPENGNSYS/client/bin/rsync" 2>/dev/null
fi
else
if [ -e "$OPENGNSYS/client/bin/rsync" ]; then
mv -f "$OPENGNSYS/client/bin/rsync" "$OPENGNSYS/client/bin/rsync-$($OPENGNSYS/client/bin/rsync --version 2>/dev/null | awk '/protocol/ {print $6}')"
fi
fi
umount $TMPDIR >/dev/null 2>&1
rmdir $TMPDIR >/dev/null 2>&1 || rm -rf $TMPDIR >/dev/null 2>&1
fi
# Crear JSON output
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}}')
--arg iso "$(basename "$OGLIVEFILE")" \
'{status: "success", messages: [], result: {distribution: $dist, kernel: $krnl, architecture: $arch, revision: $rev, directory: $dir, iso: $iso}}')
echo "$JSON_OUTPUT"
exit 0
}
# Uninstall an ogLive client.
function uninstall() {
local CHECKSUM DIR DEFAULT_OGLIVE_DIR DEFAULT_CHECKSUM
local CHECKSUM DIR
# Validar que se proporcionó exactamente un argumento (el checksum)
[ $# -ne 1 ] && { echo "{\"error\": \"BAD_REQUEST\", \"message\": \"usage: uninstall {checksum}\"}"; exit 400; }
[ $# -ne 1 ] && { echo "{\"error\": \"usage: uninstall {checksum}\"}"; exit 1; }
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
[ ! -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 {})
# Si no se encuentra el directorio, devolver error 404
# Si no se encuentra el directorio, devolver error
if [ -z "$DIR" ]; then
echo "{\"error\": \"NOT_FOUND\", \"message\": \"ogLive client with checksum $CHECKSUM not found.\"}"
exit 404
echo "{\"error\": \"ogLive client with checksum $CHECKSUM not found.\"}"
exit 1
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
# Comprobar si la eliminación tuvo éxito
if [ -d "$DIR" ]; then
echo "{\"error\": \"SERVER_ERROR\", \"message\": \"Failed to uninstall ogLive client in $DIR.\"}"
exit 500
echo "{\"error\": \"Failed to uninstall ogLive client in $DIR.\"}"
exit 1
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
local DIR OGLIVEDIST OGLIVEKRNL OGLIVEARCH OGLIVEREV OGLIVEISO OGLIVEDIR
# Verificar que el enlace simbólico del ogLive por defecto existe.
if [ ! -L "$DEFAULT_LINK" ]; then
@ -479,37 +488,23 @@ function get_default() {
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
# Obtener la información del ogLive a partir del nombre del directorio.
OGLIVEDIR=$(basename "$DIR")
OGLIVEDIST="$(echo $OGLIVEDIR | cut -d- -f2)"
OGLIVEKRNL="$(echo $OGLIVEDIR | cut -d- -f3)"
OGLIVEARCH="amd64" # Suponiendo que siempre es amd64
OGLIVEREV="$(echo $OGLIVEDIR | cut -d- -f4)"
OGLIVEISO="" # No tenemos la información del ISO aquí, podría necesitarse un ajuste si se requiere
# Construir el JSON con la información.
local INFO=$(cat << EOT
{
"id": "$CHECKSUM",
"distribution": "$OGLIVEDIST",
"kernel": "$OGLIVEKRNL",
"architecture": "$OGLIVEARCH",
"revision": "$OGLIVEREV",
"directory": "$OGLIVEDIR"
"directory": "$DIR",
"iso": "$OGLIVEISO"
}
EOT
)
@ -518,7 +513,6 @@ EOT
echo "$INFO"
}
# Set default ogLive client by checksum.
function set_default() {
local CHECKSUM=$1
@ -552,98 +546,90 @@ function set_default() {
fi
}
# Rebuild a lost configuration file.
function rebuild() {
local i INST NF DEF
[ $# -ne 0 ] && raiseError usage
[ -f $INFOFILE ] && raiseError access "Configuration file exists."
INST=$(find $TFTPDIR/ -type d -name "$DEFOGLIVE-*" -a ! -name "*.old" -printf "%f\n" | sort)
for i in $INST; do
NF=$(echo $i | awk -F- '{print NF-1}')
case $NF in
1) addToJson "" "$(echo $i|cut -f2 -d-)" "i386" "" "$i" "" ;;
2) eval addToJson $(echo $i | awk -F- '{printf "\"\" %s amd64 %s %s \"\"",$2,$3,$0}') ;;
3) eval addToJson $(echo $i | awk -F- '{if ($3=="i386") printf "\"\" %s %s %s %s \"\"",$2,$3,$4,$0; else printf "%s %s i386 %s %s \"\"",$2,$3,$4,$0}') ;;
4) eval addToJson $(echo $i | awk -F- '{printf "%s %s %s %s %s \"\"",$2,$3,$4,$5,$0}') ;;
esac
# Check for is default oglive.
[ -n "$(stat -c "%N" $TFTPDIR/$DEFOGLIVE | awk '$3~/'$i'/ {print}')" ] && DEF="$i"
done
# Set default ogLive.
[ -n "$DEF" ] && setdefault $(search $DEF)
}
# Assign an ISO file to a JSON entry.
function assign() {
local ISOFILE DIR
[ $# -ne 2 ] && raiseError usage
[ ! -w $INFOFILE ] && raiseError access "Configuration file."
# Check if ISO file and index directory exist.
ISOFILE=$DOWNLOADFILE/$1
[ ! -f $DOWNLOADDIR/$ISOFILE ] && raiseError notfound "ISO file \"$1\"."
DIR=$(search $2 2>/dev/null)
[ ! -d $TFTPDIR/$DIR ] && raiseError notfound "Directory for index \"$2\"."
# Assign ISO file to JSON entry.
jq ".oglive[$2].iso=\"$1\"" $INFOFILE | sponge $INFOFILE && jq ".oglive[$2]" $INFOFILE
}
# Get disk usage information
function disk_usage() {
DISK_INFO=$(df / | awk 'NR==2{print "{\"total\":\""$2"\", \"used\":\""$3"\", \"available\":\""$4"\", \"percentage\":\""$5"\"}"}')
DISK_INFO=$(df -h / | 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
INST=$(find $TFTPDIR/ -type d -name "$DEFOGLIVE-*" -a ! -name "*.old" -printf "%f\n" | sort)
local installed_ogLives=()
local oglive_count=0
for i in $INST; do
local OGLIVEDIR="$TFTPDIR/$i"
NF=$(echo $i | awk -F- '{print NF-1}')
local OGLIVEDIST=""
local OGLIVEKRNL=""
local OGLIVEARCH=""
local OGLIVEREV=""
local CHECKSUM=""
local OGLIVEJSON="$OGLIVEDIR/oglive_info.json"
local CHECKSUM_FILE="$OGLIVEDIR/ogclient.sqfs.sum"
local CHECKSUM_FILE="$TFTPDIR/$i/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
CHECKSUM=$(cat "$CHECKSUM_FILE" | cut -d ' ' -f 1)
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")
case $NF in
1) OGLIVEDIST="" OGLIVEKRNL=$(echo $i|cut -f2 -d-) OGLIVEARCH="i386" OGLIVEREV="" ;;
2) eval $(echo $i | awk -F- '{printf "OGLIVEDIST=\"\" OGLIVEKRNL=%s OGLIVEARCH=amd64 OGLIVEREV=%s OGLIVEDIR=%s",$2,$3,$0}') ;;
3) eval $(echo $i | awk -F- '{if ($3=="i386") printf "OGLIVEDIST=\"\" OGLIVEKRNL=%s OGLIVEARCH=%s OGLIVEREV=%s OGLIVEDIR=%s",$2,$3,$4,$0; else printf "OGLIVEDIST=%s OGLIVEKRNL=%s OGLIVEARCH=i386 OGLIVEREV=%s OGLIVEDIR=%s",$2,$3,$4,$0}') ;;
4) eval $(echo $i | awk -F- '{printf "OGLIVEDIST=%s OGLIVEKRNL=%s OGLIVEARCH=%s OGLIVEREV=%s OGLIVEDIR=%s",$2,$3,$4,$5,$0}') ;;
esac
# 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
local DATA=$(jq -n \
--arg id "$CHECKSUM" \
--arg dist "$OGLIVEDIST" \
--arg krnl "$OGLIVEKRNL" \
--arg arch "$OGLIVEARCH" \
--arg rev "$OGLIVEREV" \
--arg dir "$TFTPDIR/$OGLIVEDIR" \
--arg iso "" \
'{id: $id, distribution: $dist, kernel: $krnl, architecture: $arch, revision: $rev, directory: $dir, iso: $iso}')
oglive_count=$((oglive_count + 1))
installed_ogLives+=("$DATA")
# Verificar si es el ogLive por defecto
[ -n "$(stat -c "%N" "$TFTPDIR/$DEFOGLIVE" | awk '$3~/'$i'/ {print}')" ] && DEF="$i"
[ -n "$(stat -c "%N" $TFTPDIR/$DEFOGLIVE | awk '$3~/'$i'/ {print}')" ] && DEF="$i"
done
# 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))
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 .)" \
@ -651,13 +637,12 @@ function list_installed_oglives() {
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
local DIR OGLIVEDIST OGLIVEKRNL OGLIVEARCH OGLIVEREV OGLIVEISO OGLIVEDIR
# Verificar que se proporcionó un checksum.
[ -z "$CHECKSUM" ] && { echo "{\"error\": \"usage: get_info {checksum}\"}"; exit 1; }
@ -674,29 +659,23 @@ function get_info() {
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
# Obtener la información del ogLive a partir del nombre del directorio.
OGLIVEDIR=$(basename "$DIR")
OGLIVEDIST="$(echo $OGLIVEDIR | cut -d- -f2)"
OGLIVEKRNL="$(echo $OGLIVEDIR | cut -d- -f3)"
OGLIVEARCH="amd64" # Suponiendo que siempre es amd64
OGLIVEREV="$(echo $OGLIVEDIR | cut -d- -f4)"
OGLIVEISO="" # No tenemos la información del ISO aquí, podría necesitarse un ajuste si se requiere
# 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).
# Construir el JSON con la información.
local INFO=$(cat << EOT
{
"id": "$CHECKSUM",
"distribution": "$OGLIVEDIST",
"kernel": "$OGLIVEKRNL",
"architecture": "$OGLIVEARCH",
"revision": "$OGLIVEREV",
"directory": "$OGLIVEDIR"
"directory": "$DIR",
"iso": "$OGLIVEISO"
}
EOT
)
@ -707,7 +686,7 @@ EOT
# Function to check the status of services
function check_services_status() {
local SERVICES=("tftpd-hpa.service" "nginx.service")
local SERVICES=("oglive_daemon.service" "tftpd-hpa.service" "nginx.service")
declare -A STATUS_MAP
for service in "${SERVICES[@]}"; do
@ -720,31 +699,32 @@ function check_services_status() {
done
local json_output=$(jq -n \
--arg oglive_daemon "${STATUS_MAP['oglive_daemon.service']}" \
--arg tftpboot "${STATUS_MAP['tftpd-hpa.service']}" \
--arg nginx "${STATUS_MAP['nginx.service']}" \
'{
oglive_daemon: $oglive_daemon,
tftpboot: $tftpboot,
nginx: $nginx
}')
echo "$json_output"
}
# Main program.
# Main progrram.
# 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
[ -r $OPENGNSYS/www/controlacceso.php ] && ACCESS="web"
[ "$USER" = "root" ] && ACCESS="root"
[ -z "$ACCESS" ] && raiseError access "Need to be root."
# 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 "$ACCESS" in
root) CMDS='+(help|version|convert|config|check|list|show|search|download|install|uninstall|get-default|set-default|rebuild|assign|disk_usage|list_installed_oglives|get_info|get_default|set_default|check_services_status)' ;;
web) CMDS='+(list|show|search|get-default)' ;;
esac
case "$1" in
$CMDS) COMMAND="${1/-/}"; shift; $COMMAND "$@" ;;
*) raiseError usage ;;
@ -752,4 +732,3 @@ esac
exit $?

View File

@ -1,20 +1,36 @@
#!/bin/bash
PROG=$(basename $0)
OPENGNSYS=${OPENGNSYS:-"/opt/ogboot"}
OGCFGFILE=$OPENGNSYS/etc/ogboot_samba.json
SAMBAUSER="opengnsys" # Usuario por defecto.
#/**
# setsmbpass
#@file setsmbpass [ogLive]
#@brief Cambia la contraseña del usuario del cliente para acceder a los servicios Samba.
#@warning Se modifica el Initrd del cliente y se cambia la clave en el servidor.
#@warning No se modifica el usuario de acceso (usuario "opengnsys").
#@version 1.0.2 - Versión inicial.
#@author Ramón M. Gómez - ETSII Univ. Sevilla
#@date 2011-07-28
#@version 1.1.0 - Soporte para varios clientes ogLive.
#@author Ramón M. Gómez - ETSII Univ. Sevilla
#@date 2017-06-20
#*/ ##
# Variables.
PROG=$(basename "$0")
PATH=$PATH:$(dirname "$(realpath "$0")")
OPENGNSYS=${OPENGNSYS:-"/opt/opengnsys"}
OGCFGFILE=$OPENGNSYS/etc/opengnsys.json
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
if [ "$USER" != "root" ]; then
echo "$PROG: Error: solo ejecutable por root" >&2
exit 1
fi
case $# in
0) # Cambios en todos los clientes ogLive instalados.
if which oglivecli &>/dev/null; then
@ -24,7 +40,7 @@ case $# in
fi ;;
1) # Cambios en único ogLive (AVISO: puede crear inconsistencias con otros ogLive).
LIST="$1" ;;
*) # Error de formato.
*) # Error de formato.
echo "$PROG: Error de ejecución" >&2
echo "Formato: $PROG ogLive"
exit 1 ;;
@ -38,36 +54,35 @@ for OGLIVE in $LIST; do
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"
# 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
cd $TMPDIR || { echo "Error: no se pudo cambiar al directorio temporal."; exit 3; }
# Verificar si el archivo es gzip o lz4 antes de descomprimir.
if file "$CLIENTINITRD" | grep -q "gzip compressed data"; then
if ! gzip -dc "$CLIENTINITRD" | cpio -im; then
echo "Error: No se pudo descomprimir y extraer $CLIENTINITRD con gzip."
@ -80,80 +95,47 @@ for OGLIVE in $LIST; do
exit 4
fi
COMPRESS_CMD="lz4 -c"
elif file "$CLIENTINITRD" | grep -q "ASCII cpio archive"; then
if ! 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."
echo "Error: $CLIENTINITRD no está en formato gzip o lz4."
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
# FIN CÓDIGO TEMPORAL.
# Ticket 565, preparar acceso Rsync cliente.
echo "$SAMBAPASS" | sudo tee scripts/passrsync > /dev/null
echo "Guardar tokens de seguridad"
cat <<EOT | sudo tee scripts/client.cfg > /dev/null
if [ -f scripts/ogfunctions ]; then
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).
sed -i "s/busybox reboot/reboot/" scripts/ogfunctions
# FIN CÓDIGO TEMPORAL.
# Ticket 565, preparar acceso Rsync cliente.
echo "$SAMBAPASS" > scripts/passrsync
# Guardar tokens de seguridad.
cat << EOT > scripts/client.cfg
CLIENTID=$(jq -r .client.id $OGCFGFILE)
CLIENTSECRET=$(jq -r .client.secret $OGCFGFILE)
EOT
sudo chown ogboot:ogboot scripts/passrsync scripts/client.cfg
# pwd
# sudo find . -print > /tmp/filelist.txt
# if [ $? -ne 0 ]; then
# echo "Error: No se pudo encontrar los archivos."
# exit 5
# fi
# cpio -H newc -oa < /tmp/filelist.txt > /tmp/initrd.cpio
# if [ $? -ne 0 ]; then
# echo "Error: No se pudo crear el archivo CPIO."
# exit 5
# fi
# $COMPRESS_CMD < /tmp/initrd.cpio > /tmp/initrd.cpio.gz
# if [ $? -ne 0 ]; then
# echo "Error: No se pudo comprimir el archivo CPIO."
# exit 5
# fi
# echo "Copiando el contenido del archivo /tmp/initrd.cpio.gz al archivo /opt/opengnsys/tftpboot/ogLive-5.11.0-r20210413/oginitrd.img."
# echo $CLIENTINITRD
# dd if=/tmp/initrd.cpio.gz of=/opt/opengnsys/tftpboot/ogLive-5.11.0-r20210413/oginitrd.img
# echo "dd ejecutado correctamente"
# if [ $? -ne 0 ]; then
# echo "Error: No se pudo escribir el archivo comprimido en el destino."
# exit 5
# fi
# echo "borrando rm /tmp/initrd.cpio /tmp/initrd.cpio.gz"
# sudo rm /tmp/initrd.cpio /tmp/initrd.cpio.gz
find . | cpio -H newc -oa | gzip -9c > "$CLIENTINITRD"
else
echo "$PROG: Aviso: no se ha modificado la clave del cliente \"$OGLIVE\"."
chown root.root scripts/passrsync scripts/client.cfg
chmod 400 scripts/passrsync scripts/client.cfg
# Generar Initrd del cliente.
if ! find . | cpio -H newc -oa | $COMPRESS_CMD > "$CLIENTINITRD"; then
echo "Error: No se pudo recomprimir $CLIENTINITRD."
exit 5
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: Aviso: no se ha modificado la clave del cliente \"$OGLIVE\"."
fi
rm -fr $TMPDIR
# Calcular suma de comprobación.
md5sum "$CLIENTINITRD" | cut -f1 -d" " > "$CLIENTINITRD.sum"
let CHANGES++
else
echo "$PROG: Cliente \"$OGLIVE\" no accesible."
fi
done
if [[ $CHANGES != 0 ]]; then
# Ticket 565, preparar acceso Rsync servidor.
echo "$SAMBAUSER:$SAMBAPASS" | sudo tee /etc/rsyncd.secrets > /dev/null
echo "chown debugging"
sudo chown root:root /etc/rsyncd.secrets
sudo chmod 600 /etc/rsyncd.secrets
echo "$SAMBAUSER:$SAMBAPASS" > /etc/rsyncd.secrets
chown root.root /etc/rsyncd.secrets
chmod 600 /etc/rsyncd.secrets
# Cambiar clave Samba.
echo -ne "$SAMBAPASS\n$SAMBAPASS\n" | sudo smbpasswd -a -s $SAMBAUSER
echo "setsmbpass finish"
echo -ne "$SAMBAPASS\n$SAMBAPASS\n" | smbpasswd -a -s $SAMBAUSER
else
echo "$PROG: Aviso: no se ha modificado la clave de ningún cliente."
fi

View File

@ -4,16 +4,17 @@
"minimum-stability": "stable",
"prefer-stable": true,
"require": {
"php": ">=8.1",
"php": ">=7.2.0",
"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",
"phpstan/phpdoc-parser": "^0.4",
"zircote/swagger-php": "3.*",
"symfony/runtime": "5.*",
"symfony/asset": "5.*",
"symfony/console": "5.*",
"symfony/doctrine-messenger": "5.*",
@ -31,7 +32,6 @@
"symfony/process": "5.*",
"symfony/property-access": "5.*",
"symfony/property-info": "5.*",
"symfony/runtime": "5.*",
"symfony/security-bundle": "5.*",
"symfony/serializer": "5.*",
"symfony/string": "5.*",
@ -41,8 +41,7 @@
"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"
"twig/twig": "^2.12|^3.0"
},
"require-dev": {
"phpunit/phpunit": "^8.5",
@ -56,7 +55,7 @@
},
"config": {
"platform": {
"php": "8.1"
"php": "7.2.24"
},
"allow-plugins": {
"composer/package-versions-deprecated": true,

View File

@ -12,5 +12,4 @@ return [
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],
];

View File

@ -4,16 +4,12 @@
# 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
@ -29,6 +25,3 @@ services:
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']

6
debian/README vendored
View File

@ -1,6 +0,0 @@
The Debian Package ogboot
----------------------------
<Comments regarding the Package.>
-- vagrant <vagrant@build> Tue, 04 Mar 2025 15:42:24 +0000

View File

@ -1,6 +0,0 @@
ogboot for Debian
----------------
<Possible notes regarding this package - if none, delete this file.>
-- vagrant <vagrant@build> Tue, 04 Mar 2025 15:42:24 +0000

10
debian/README.source vendored
View File

@ -1,10 +0,0 @@
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

14
debian/changelog vendored
View File

@ -1,14 +0,0 @@
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

80
debian/control vendored
View File

@ -1,80 +0,0 @@
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.

43
debian/copyright vendored
View File

@ -1,43 +0,0 @@
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/

View File

@ -1 +0,0 @@
ogboot

View File

@ -1,3 +0,0 @@
README.source
README.Debian
README

14
debian/ogboot.config vendored
View File

@ -1,14 +0,0 @@
#!/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

3
debian/ogboot.dirs vendored
View File

@ -1,3 +0,0 @@
/opt/opengnsys/ogboot/client_log
/opt/opengnsys/ogboot/mnt
/opt/opengnsys/ogboot/tftpboot

View File

@ -1,8 +0,0 @@
api /opt/opengnsys/ogboot
etc /opt/opengnsys/ogboot
lib /opt/opengnsys/ogboot
bin /opt/opengnsys/ogboot
tftpboot /opt/opengnsys/ogboot/

206
debian/ogboot.postinst vendored
View File

@ -1,206 +0,0 @@
#!/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"
/opt/opengnsys/ogboot/bin/oglivecli download "$DEFAULT_OGLIVE"
}
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/samba/smb-ogboot.conf /etc/samba/
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

24
debian/ogboot.postrm vendored
View File

@ -1,24 +0,0 @@
#!/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

View File

@ -1,6 +0,0 @@
# 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

15
debian/ogboot.preinst vendored
View File

@ -1,15 +0,0 @@
#!/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

25
debian/ogboot.prerm vendored
View File

@ -1,25 +0,0 @@
#!/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

View File

@ -1,35 +0,0 @@
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

13
debian/rules vendored
View File

@ -1,13 +0,0 @@
#!/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;

View File

@ -1 +0,0 @@
3.0 (native)

View File

@ -1,8 +0,0 @@
{
"project": "Ogboot",
"version": "0.1.1",
"codename": "Espeto",
"definition": "http://www.andalucia.com/gastronomy/espeto.htm",
"release": "",
"ogagent": "1.1.2"
}

View File

@ -1,9 +1,449 @@
## Diseño de la Lógica y Comunicación entre los Endpoints del Componente `ogboot` y el Servidor `ogCore`
# Documentación de Ogboot
### Introducción
## 1. Descripción General del Componente
- 1.1 Introducción
- 1.2 Funcionalidades
- 1.2.1 Gestión de Imágenes de Arranque (ogLive)
- 1.2.2 Monitoreo y Configuración
- 1.2.3 Interfaz de Programación de Aplicaciones (API)
- 1.3 Arquitectura General
- 1.3.1 Componentes Principales
- 1.3.2 Estructura del Proyecto
- 1.3.3 Interacción entre Componentes
- 1.3.4 Seguridad y Permisos
## 2. Instalación
- 2.1 Requisitos Previos
- 2.1.1 Software Necesario
- 2.1.2 Hardware Requerido
- 2.1.3 Permisos y Configuraciones Previas
- 2.2 Instrucciones de Instalación
- 2.2.1 Descarga del Software
- 2.2.2 Instalación Paso a Paso
- 2.2.3 Configuración Inicial
## 3. Endpoints y API
- 3.1 Listado de Endpoints
- 3.1.1 Métodos y Rutas
- 3.1.2 Descripciones de los Endpoints
- 3.2 Ejemplos de Solicitudes y Respuestas
- 3.3 Manejo de Errores Comunes
- 3.4 Middleware y Autenticación
## 4. Configuración del Servidor
- 4.1 Configuración de Nginx
- 4.2 Configuración de PHP-FPM
- 4.3 Creación y Levantamiento del Demonio ogboot
- 4.4 Configuración de Usuarios y Permisos
## 5. Funciones del CLI (oglivecli)
- 5.1 Descripción de las Funciones
- 5.2 Ejemplos de Uso
- 5.3 Interacción con el Sistema y el Demonio
## 6. Integración con Otros Sistemas
- 6.1 Integración con TFTP
- 6.2 Configuración de PXE
- 6.3 Otros Servicios y Configuraciones
## 7. Seguridad
- 7.1 Consideraciones de Seguridad
- 7.2 Medidas para Mitigar Riesgos
- 7.3 Configuración Segura
## 8. Mantenimiento y Monitoreo
- 8.1 Monitoreo del Estado del Demonio
- 8.2 Procedimientos de Mantenimiento Recomendados
- 8.3 Solución de Problemas Comunes
## 9. Actualización y Desinstalación
- 9.1 Procedimientos de Actualización
- 9.2 Pasos para Desinstalar ogboot
## 10. Anexos
- 10.1 Ejemplos de Configuración de Archivos Relevantes
- 10.2 Listado de Comandos Útiles
- 10.3 Referencias a Documentación Externa
## 11. Ejemplos Prácticos
- 11.1 Casos de Uso Comunes
- 11.2 Scripts de Automatización
- 11.3 Integraciones Prácticas
## 1. Descripción General del Componente
### 1.1 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`.
### 1.2 Funcionalidades
#### 1.2.1 ogLive
El **ogLive** es un sistema operativo diseñado para iniciarse en clientes PCs y llevar a cabo diversas operaciones indicadas por OpenGnsys, como la creación de particiones y la restauración de sistemas operativos. Este sistema operativo se carga y ejecuta completamente en la RAM y se distribuye a través de la red, lo que le permite realizar una regeneración completa de todos los discos de almacenamiento en un equipo.
Desde el punto de vista de su diseño, el ogLive se divide en dos componentes, cada uno con una función específica en el proceso de arranque:
1. **Primera Fase: Kernel e Initrd**
- Esta fase incluye un Kernel y un Initrd, elementos tradicionales de una distribución de Ubuntu, pero con la adición de un proceso alternativo llamado `oginit`.
- El `oginit` permite cambiar el contexto (`pivot_root`) del Initrd a la partición raíz (rootfs) de manera rápida y flexible según las necesidades de OpenGnsys.
- El `oginit` permite utilizar un rootfs ubicado en la red a través de sistemas de archivos distribuidos como NFS, Samba o SSHFS, y crea enlaces en el minisistema del Initrd con los archivos del rootfs, facilitando así el uso de programas y utilidades que no pueden ser instalados en el Initrd.
- Este enfoque minimiza los problemas de red, ya que el sistema principal (Initrd) siempre reside en la RAM y solo accede al rootfs cuando se necesita una utilidad no presente en el Initrd.
2. **Segunda Fase: Rootfs en la Red**
- El rootfs, que es compartido por todos los clientes, se fusiona con el Initrd, lo que permite independizar los procesos de cada equipo.
- Este diseño admite varias configuraciones de arranque, donde los elementos de las dos fases pueden estar en diferentes ubicaciones.
Para aumentar la velocidad de descarga, se utiliza HTTP configurado por Nginx para la carga de la imagen de inicialización y el kernel. Esto reduce significativamente los retardos en la primera fase, donde se cargan aproximadamente 40 MB del Kernel y el Initrd en la memoria RAM. Una vez cargados, la conexión con el rootfs a través de Samba se establece de forma inmediata.
---
### 1.3 Arquitectura General del Sistema
#### Flujo de Comunicación entre el Cliente y el Servidor OgDHCP
El proceso de arranque en red utilizando ogboot sigue un flujo bien definido que comienza con la comunicación entre el cliente y el servidor DHCP, denominado **OgDHCP** en este contexto.
1. **Solicitud de Configuración de Red por Parte del Cliente:**
- Cuando un cliente se inicia, envía una solicitud al servidor OgDHCP para obtener los parámetros necesarios para arrancar en red. Este es el primer paso en el proceso de arranque PXE (Preboot Execution Environment).
2. **Asignación de IP y Parámetros de Arranque por OgDHCP:**
- El servidor OgDHCP responde a la solicitud del cliente asignándole una dirección IP. Además de la dirección IP, OgDHCP proporciona dos parámetros cruciales:
- **Next-server:** Esta es la dirección IP del servidor ogBoot, que se encargará de proporcionar los archivos necesarios para que el cliente pueda arrancar.
- **Boot-file-name:** Este parámetro especifica el archivo que el cliente debe cargar para continuar con el proceso de arranque. El nombre del archivo depende del tipo de firmware del cliente:
- **ipxe-efi:** Se utiliza para sistemas con firmware EFI.
- **undionly.pxe:** Se utiliza para sistemas con BIOS tradicional.
3. **Comunicación del Cliente con el Servidor ogBoot:**
- Con la dirección IP del servidor ogBoot (especificada en el `next-server`) y el nombre del archivo de arranque (`boot-file-name`), el cliente se comunica directamente con el servidor ogBoot.
- **ogBoot** tiene un directorio **tftpboot** donde están alojados los archivos de arranque, como **ipxe-efi** y **undionly.pxe**.
4. **Ejecución de Scripts Embebidos en los Ficheros de Arranque:**
- Los archivos de arranque descargados por el cliente (como `ipxe-efi` o `undionly.pxe`) contienen scripts embebidos llamados `dhcp_boot.ipxe`.
- Además de configurar la red del cliente, `dhcp_boot.ipxe` incluye instrucciones específicas que indican al cliente que ejecute un script de arranque basado en su dirección MAC.
- Estos scripts de arranque suelen tener nombres como `01-XX:XX:XX:XX:XX:XX`, donde `XX:XX:XX:XX:XX:XX` representa la dirección MAC del cliente. Por ejemplo, un nombre de archivo podría ser `01-00:50:56:34:48:11`.
5. **Carga del Kernel y la Imagen de Inicialización:**
- Los scripts de arranque específicos para cada cliente se encargan de la carga del kernel y la imagen de inicialización. Además, estos scripts incluyen configuraciones personalizadas para cada cliente, tales como:
- El nombre de la máquina.
- La dirección IP asignada.
- La versión de **ogLive** que el cliente utilizará para la carga.
- Otras configuraciones específicas del entorno y las necesidades del cliente.
---
---
### Requisitos Mínimos para la Instalación de ogBoot
1. **Requisitos de hardware:**
- **Almacenamiento mínimo**: Se requieren al menos **600 MB** de espacio en disco, ya que se descargará **ogLive 5.13** como parte de la instalación.
- **Memoria RAM**: Dependiendo del número de clientes que se vayan a gestionar, pero se recomienda al menos 2 GB de RAM para un servidor que gestione despliegues pequeños.
2. **Sistema operativo compatible:**
- **Distribuciones de Linux recomendadas**:
- Ubuntu 18.04 LTS o superior
- CentOS 7 o superior
- **Nota**: Es posible que otras distribuciones basadas en Linux también sean compatibles, pero se recomienda realizar pruebas en entornos similares a los descritos.
3. **Python:**
- Se requiere **Python 3.7 o superior**.
4. **Dependencias de software**:
- Las dependencias de software se instalan automáticamente durante el proceso de instalación. Estas incluyen:
- **tftpd-hpa**
- **nginx**
- **php-fpm**
- **composer**
- **Symfony**
- **NFS** y **Samba** para la configuración del sistema de archivos y la compartición de archivos.
5. **Permisos y usuarios:**
- La instalación requiere que se ejecute con **privilegios de root**.
- Durante la instalación, se crearán usuarios específicos, como:
- **ogboot**: Para ejecutar servicios y gestionar los componentes de ogBoot.
- **OPENGNSYS_CLIENT_USER**: Usuario creado para gestionar la comunicación con OpenGnsys.
6. **Red y conectividad:**
- Se recomienda que el servidor tenga acceso a Internet para descargar dependencias y actualizaciones.
- El servidor necesita estar en una red con un **servidor DHCP activo** para que los clientes puedan obtener sus configuraciones de red durante el arranque.
7. **Configuración de la red**:
- Es necesario un interfaz de red para la gestión del tráfico de los clientes, configurado automáticamente durante la instalación.
---
### Directorios Clave de ogBoot Instalado:
1. **client**:
- Este directorio contiene el cliente que será **servido por Samba** para su uso en los despliegues. Los archivos en este directorio son accesibles para los clientes a través de la red, facilitando la instalación y el arranque remoto.
2. **bin**:
- Contiene los scripts de gestión de ogBoot, incluyendo:
- **oglivecli**: Utilizado para la **gestión de ogLive**, permitiendo la instalación, borrado o consulta de imágenes de arranque.
- **setsmbpass**: Script encargado de gestionar las contraseñas de Samba y configurar el acceso seguro a los clientes.
3. **tftpboot**:
- En este directorio se alojan los **archivos de arranque** como `ipxe-efi` y `undionly.pxe`, así como los **ogLive montados** que serán utilizados por estos archivos de arranque para lanzar los sistemas operativos en los clientes.
4. **Resto de directorios**:
- **src**, **config**, **lib**, **etc**, **doc**, **composer.json**, y **installer** contienen los archivos y configuraciones de **Symfony**, que es el framework utilizado por ogBoot para gestionar su estructura interna y flujos de trabajo.
#### Comandos y Funciones:
1. **help**
- **Descripción**: Muestra la ayuda del script, incluyendo una lista completa de los comandos disponibles y sus descripciones.
- **Uso**: `oglivecli help`
2. **version**
- **Descripción**: Muestra la versión actual del script `oglivecli`.
- **Uso**: `oglivecli version`
3. **config [Parámetro]**
- **Descripción**: Muestra los parámetros de configuración específicos que utiliza ogBoot. Puede recibir un parámetro para mostrar un valor específico.
- **Uso**: `oglivecli config [Parámetro]`
4. **disk_usage**
- **Descripción**: Muestra información sobre el uso de disco en el servidor, lo que permite verificar cuánta capacidad de almacenamiento se está utilizando.
- **Uso**: `oglivecli disk_usage`
5. **list_installed_oglives**
- **Descripción**: Lista todos los clientes ogLive instalados en el servidor, mostrando las imágenes disponibles para su despliegue.
- **Uso**: `oglivecli list_installed_oglives`
6. **check_services_status**
- **Descripción**: Verifica el estado de los servicios críticos necesarios para el funcionamiento de ogBoot, como `oglive_daemon`, `tftpd-hpa`, y `nginx`.
- **Uso**: `oglivecli check_services_status`
7. **download**
- **Descripción**: Muestra un menú interactivo para descargar una imagen ISO de ogLive desde el sitio web de OpenGnsys.
- **Uso**: `oglivecli download`
8. **download Iso**
- **Descripción**: Permite descargar una imagen ISO específica de ogLive desde el sitio web de OpenGnsys.
- **Uso**: `oglivecli download [Iso]`
9. **install Iso**
- **Descripción**: Instala un nuevo cliente ogLive desde una ISO previamente descargada.
- **Uso**: `oglivecli install [Iso]`
10. **uninstall uuid**
- **Descripción**: Desinstala un cliente ogLive utilizando su UUID. Este comando elimina la imagen instalada del cliente.
- **Uso**: `oglivecli uninstall [uuid]`
11. **get_default**
- **Descripción**: Obtiene el valor del índice correspondiente al cliente ogLive predeterminado actualmente en uso.
- **Uso**: `oglivecli get_default`
12. **set_default uuid**
- **Descripción**: Establece un cliente ogLive como predeterminado utilizando su UUID.
- **Uso**: `oglivecli set_default [uuid]`
13. **get_info uuid**
- **Descripción**: Obtiene información en formato JSON sobre un cliente ogLive instalado, identificado por su UUID.
- **Uso**: `oglivecli get_info [uuid]`
### 4. Configuración del Servidor
#### 4.1 Configuración de Nginx
El servidor Nginx se configura para manejar las solicitudes de ogBoot y servir archivos tanto del proyecto Symfony como del directorio TFTP. A continuación se detalla la configuración relevante para ogBoot:
```nginx
server {
listen 80;
server_name 172.17.8.37 localhost; # IP del servidor
# Raíz del documento para el proyecto Symfony
root /opt/ogboot/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/php8.3-fpm.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;
# Manejo de la documentación de la API
location /api/doc {
try_files $uri /index.php?$query_string;
}
# Ruta base para servir archivos de TFTP
location /tftpboot {
alias /opt/ogboot/tftpboot;
autoindex on; # Permitir listado de directorios
try_files $uri $uri/ =404; # Intentar servir archivos, si no se encuentra devolver 404
# Seguridad: Bloquear el acceso a archivos PHP en el directorio tftpboot
location ~ \.php$ {
return 404;
}
# Logs para el directorio tftpboot
error_log /var/log/nginx/tftpboot_error.log;
access_log /var/log/nginx/tftpboot_access.log;
}
}
```
##### Puntos importantes:
- **Root del documento**: Se especifica que el contenido principal de ogBoot se sirve desde `/opt/ogboot/public`, que es la raíz del proyecto Symfony.
- **Tiempos de espera aumentados**: Se incrementa el tiempo de espera (`timeout`) en la sección de `/ogboot` debido a la duración de algunas operaciones críticas, como la instalación de ogLive.
- **Archivos TFTP**: El contenido del directorio `/tftpboot` es accesible mediante la ruta `/tftpboot`, y está configurado para permitir el listado de archivos y bloquear cualquier intento de ejecutar archivos PHP desde este directorio.
- **Logs de Nginx**: Los logs de error y acceso se guardan en archivos dedicados para facilitar la depuración de problemas.
#### 4.2 Configuración de PHP-FPM
La configuración de PHP-FPM es crucial para que ogBoot maneje adecuadamente las solicitudes a través de Nginx. En este caso, PHP-FPM está configurado para ejecutarse con el usuario `www-data` y el grupo `ogboot`:
- **fastcgi_pass**: El parámetro `fastcgi_pass` está configurado para utilizar el socket Unix en `/run/php/php8.3-fpm.sock`, asegurando que las solicitudes PHP se manejen correctamente.
- **Usuarios y permisos**:
- **Usuario**: `www-data`
- **Grupo**: `ogboot`
Esto asegura que los procesos PHP tengan los permisos adecuados para leer y escribir en los directorios relevantes, como los de Symfony y ogLive.
#### 4.3 Creación y Levantamiento del Demonio ogBoot
El demonio **ogboot** es esencial para el funcionamiento del sistema, y debe ser levantado tras la configuración del servidor. La creación del demonio implica los siguientes pasos:
1. **Creación del usuario `ogboot`**:
- Se crea un usuario específico para ejecutar los servicios relacionados con ogBoot, con los permisos adecuados para manejar el contenido del servidor.
2. **Levantamiento del servicio**:
- El demonio **ogboot** se levanta automáticamente tras la configuración, ejecutando las tareas esenciales para la gestión de imágenes y el arranque de clientes.
#### 4.4 Configuración de Samba
La configuración de Samba permite compartir los directorios necesarios con los clientes que se conectan a ogBoot. A continuación se detallan las configuraciones relevantes:
```ini
[tftpboot]
comment = OpenGnsys init files
browseable = no
writeable = no
path = /opt/opengnsys/tftpboot
guest ok = no
[ogclient]
comment = OpenGnsys Client
browseable = no
writeable = no
locking = no
path = /opt/opengnsys/client
guest ok = no
```
##### Puntos importantes:
- **Directorio `tftpboot`**:
- **Uso**: Se comparte el directorio `/opt/opengnsys/tftpboot` para servir los archivos de arranque a los clientes.
- **Permisos**: No es navegable (`browseable = no`), y no se permite escribir en él (`writeable = no`). Los clientes solo pueden acceder a los archivos necesarios.
- **Directorio `ogclient`**:
- **Uso**: Comparte el directorio `/opt/opengnsys/client`, que contiene el cliente OpenGnsys.
- **Permisos**: Al igual que en `tftpboot`, este directorio no es navegable ni escribible desde los clientes. Además, el bloqueo de archivos está deshabilitado (`locking = no`).
### Comandos del Script `oglivecli`
El script `oglivecli` es una herramienta de línea de comandos diseñada para gestionar las imágenes de ogLive, permitiendo realizar diversas operaciones relacionadas con la instalación, configuración y administración de estos clientes de arranque en el entorno ogBoot.
### 6. Integración con Otros Sistemas
#### 6.1 Integración con TFTP
En **ogBoot**, el servicio TFTP (Trivial File Transfer Protocol) es esencial para servir los archivos necesarios para el arranque de los clientes. El directorio **tftpboot** aloja los archivos de arranque y las imágenes de ogLive que serán utilizados en el proceso de arranque PXE.
En el directorio `/opt/ogboot/tftpboot`, se encuentran los siguientes archivos y directorios clave:
- **ipxe.efi**: El archivo de arranque para sistemas EFI.
- **undionly.kpxe**: El archivo de arranque para sistemas BIOS.
- **ipxe_scripts**: Scripts IPXE personalizados que gestionan el arranque de los clientes.
- **ogLive**: Directorio que contiene las imágenes del sistema operativo ogLive que serán utilizadas por los clientes.
- **ogclient**: El cliente OpenGnsys, que se carga a través de Samba.
El TFTP se configura para servir estos archivos a los clientes, permitiendo que accedan a los recursos necesarios para iniciar el proceso de arranque.
#### 6.2 Configuración de PXE
El **PXE (Preboot Execution Environment)** es utilizado para inicializar los clientes a través de la red. En el caso de ogBoot, el proceso PXE está configurado para proporcionar archivos de arranque según el firmware de los clientes (EFI o BIOS) y luego ejecutar scripts de IPXE personalizados.
##### Estructura de los Scripts IPXE
En el directorio `/opt/ogboot/tftpboot/ipxe_scripts`, se encuentran varios archivos de configuración de IPXE, incluyendo archivos como `default.ipxe`, `dhcp_boot.ipxe`, y plantillas específicas de arranque como `01-D05099AA8C06`, que están basadas en la dirección MAC del cliente.
- **Archivos de arranque personalizados**: Los scripts IPXE como `01-D05099AA8C06` están vinculados a clientes específicos basados en su dirección MAC. Esto permite configurar un arranque personalizado para cada cliente.
##### Ejemplo de una plantilla IPXE (mi_plantilla.ipxe)
```ipxe
#!ipxe
set timeout 0
set timeout-style hidden
set ISODIR __OGLIVE__
set default 0
set kernelargs __INFOHOST__
:try_iso
kernel http://__SERVERIP__/tftpboot/${ISODIR}/ogvmlinuz ${kernelargs} || goto fallback
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
boot
:fallback
set ISODIR ogLive
kernel http://__SERVERIP__/tftpboot/${ISODIR}/ogvmlinuz ${kernelargs}
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
boot
```
##### Parámetros Relevantes de la Plantilla:
- `__SERVERIP__`: Este parámetro se reemplaza con la dirección IP del servidor ogBoot, que sirve los archivos necesarios para el arranque.
- `__INFOHOST__`: Se sustituye con los parámetros del kernel específicos de la máquina que está arrancando. Estos parámetros pueden incluir configuraciones específicas como el nombre de la máquina, la dirección IP, y otros detalles necesarios para el arranque.
- `__OGLIVE__`: Se reemplaza con la versión de ogLive que será utilizada para arrancar la máquina cliente. Esto permite cargar diferentes versiones de ogLive según la configuración de cada cliente.
Este sistema de plantillas facilita la personalización del proceso de arranque para diferentes clientes, permitiendo que ogBoot adapte el arranque PXE según los requerimientos de cada máquina.
### Endpoints del Componente `ogboot`
@ -319,6 +759,8 @@ Para los nuevos flujos de trabajo, asumimos que habrá al menos una nueva tabla
SELECT * FROM oglives;
```
**Realización 2**: También se puede llevar a cabo desde **`ogBoot`** haciendo una consulta al endpoint
**Endpoint**:
- **`ogBoot`**: `/ogboot/v1/oglives`
- **Método**: `GET`
@ -346,11 +788,17 @@ SELECT * FROM oglives;
**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.
1. **Generación de JSON**: `ogCore` genera un JSON con los detalles del `ogLive`.
2. **Solicitud de Instalación**:
- **Endpoint**: `/ogboot/v1/oglives`
- **Método**: `POST`
- **Cuerpo de la Solicitud**:
```json
{
"iso": "ogLive-focal-5.11.0-22-generic-amd64-r20210413.992ebb9.iso"
}
```
- **Respuesta**:
```json
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
@ -362,8 +810,7 @@ SELECT * FROM oglives;
"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**:
3. **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)

View File

@ -1,103 +0,0 @@
#!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

View File

@ -1,6 +0,0 @@
# /etc/default/tftpd-hpa
TFTP_USERNAME="opengnsys"
TFTP_DIRECTORY="/opt/opengnsys/ogboot/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure -v"

View File

@ -1,11 +0,0 @@
#!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

View File

@ -1,14 +0,0 @@
#!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

View File

@ -1,57 +0,0 @@
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;
}
}

View File

@ -1,12 +0,0 @@
[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

View File

@ -1,3 +0,0 @@
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

View File

@ -1,6 +0,0 @@
[tftpboot]
comment = OpenGnsys init files
browseable = no
writeable = no
path = __OGBOOTDIR__/tftpboot
guest ok = no

View File

@ -1,7 +0,0 @@
[ogclient]
comment = OpenGnsys Client
browseable = no
writeable = no
locking = no
path = __OGBOOTDIR__/client
guest ok = no

View File

@ -1,6 +0,0 @@
[tftpboot]
comment = OpenGnsys init files
browseable = no
writeable = no
path = __OGBOOTDIR__/tftpboot
guest ok = no

View File

@ -1,8 +0,0 @@
{
"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"
}

View File

@ -1,894 +0,0 @@
#!/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()

View File

@ -0,0 +1,4 @@
#!/bin/bash
echo "Hello world"
touch "Hello world"

View File

@ -1,28 +0,0 @@
#!/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

View File

@ -1,102 +0,0 @@
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}")

View File

@ -1,91 +0,0 @@
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}")

View File

@ -63,4 +63,3 @@ function jq() {
echo "$OUTPUT"
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,149 @@
<?php
// src/OgBootBundle/Service/CurlRequestService.php
namespace App\OgBootBundle\Service;
use Exception;
use Psr\Log\LoggerInterface;
class CurlRequestService
{
public function convertMaskToCIDR($mask)
{
$bits = 0;
$mask = explode(".", $mask);
foreach ($mask as $octect)
$bits += strlen(str_replace("0", "", decbin($octect)));
return $bits;
}
// src/Service/CurlRequestService.php
public function installOglive($isoname)
{
$socketPath = '/tmp/oglive_daemon.sock';
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
if ($socket === false) {
syslog(LOG_ERR, 'Error al crear el socket: ' . socket_strerror(socket_last_error()));
return ['success' => false, 'output' => 'Error al crear el socket'];
}
$result = socket_connect($socket, $socketPath);
if ($result === false) {
syslog(LOG_ERR, 'Error al conectar con el socket: ' . socket_strerror(socket_last_error($socket)));
socket_close($socket);
return ['success' => false, 'output' => 'Error al conectar con el socket'];
}
$command = [
'action' => 'download',
'args' => [$isoname]
];
socket_write($socket, json_encode($command), strlen(json_encode($command)));
$response = '';
$status = [];
while ($buffer = socket_read($socket, 2048)) {
$response .= $buffer;
$status[] = json_decode($buffer, true);
}
socket_close($socket);
// Analiza el último estado recibido
$lastStatus = end($status);
if ($lastStatus && $lastStatus['status'] === 'completed') {
return ['success' => true, 'output' => $lastStatus];
} else {
return ['success' => false, 'output' => $status];
}
}
public function callOgLive($parameter)
{
$socketPath = '/var/run/oglive/oglive_daemon.sock';
file_put_contents('/tmp/serviceOglive.log', 'callOgLive called with parameter: ' . $parameter . PHP_EOL, FILE_APPEND);
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
if ($socket === false) {
$error = 'Error al crear el socket: ' . socket_strerror(socket_last_error());
file_put_contents('/tmp/serviceOglive.log', 'Socket creation error: ' . $error . PHP_EOL, FILE_APPEND);
return [
'success' => false,
'error' => $error
];
}
$result = socket_connect($socket, $socketPath);
if ($result === false) {
$error = 'Error al conectar con el socket: ' . socket_strerror(socket_last_error($socket));
file_put_contents('/tmp/serviceOglive.log', 'Socket connection error: ' . $error . PHP_EOL, FILE_APPEND);
socket_close($socket);
return [
'success' => false,
'error' => $error
];
}
$args = array_map('trim', explode(' ', $parameter));
$action = array_shift($args);
$command = [
'action' => $action,
'args' => $args
];
socket_write($socket, json_encode($command), strlen(json_encode($command)));
$response = '';
while ($buffer = socket_read($socket, 2048)) {
$response .= $buffer;
}
socket_close($socket);
file_put_contents('/tmp/serviceOglive.log', 'Raw response: ' . $response . PHP_EOL, FILE_APPEND);
if (empty($response)) {
$error = 'Respuesta vacía del demonio';
file_put_contents('/tmp/serviceOglive.log', 'Empty response error: ' . $error . PHP_EOL, FILE_APPEND);
return [
'success' => false,
'error' => $error
];
}
$decodedResponse = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$error = 'Error al decodificar JSON: ' . json_last_error_msg();
file_put_contents('/tmp/serviceOglive.log', 'JSON decode error: ' . $error . PHP_EOL, FILE_APPEND);
return [
'success' => false,
'error' => $error
];
}
if (isset($decodedResponse['success']) && $decodedResponse['success']) {
file_put_contents('/tmp/serviceOglive.log', 'Decoded successful response: ' . json_encode($decodedResponse['output']) . PHP_EOL, FILE_APPEND);
return $decodedResponse['output'];
} else {
$error = $decodedResponse['error'] ?? 'Unknown error';
file_put_contents('/tmp/serviceOglive.log', 'Error in response: ' . $error . PHP_EOL, FILE_APPEND);
return [
'success' => false,
'error' => $error
];
}
}
}

View File

@ -1,19 +0,0 @@
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.

View File

Binary file not shown.

View File

@ -1,103 +0,0 @@
#!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

View File

@ -1,84 +0,0 @@
#!ipxe
# Configuración inicial
set ISODIR ogLive
# Detectar si se está ejecutando en modo UEFI o BIOS
iseq ${platform} efi && goto uefi_boot || goto bios_boot
# BIOS Boot Logic
:bios_boot
echo "Running in BIOS mode..."
echo "Starting firstboot and secondboot flow using GRUB4DOS..."
chain http://__SERVERIP__/tftpboot/grub.exe --config-file="
timeout 0
set ISODIR=${ISODIR};
# Firstboot
find --set-root --ignore-floppies --ignore-cd /ogboot.me checkrange 0x07 parttype > nul;
cmp /ogboot.me /ogboot.firstboot || goto secondboot;
write /ogboot.firstboot iniciado;
pause Firstboot passed. File updated. Press any key to continue...;
chainloader +1;
boot;
# Secondboot
:secondboot
find --set-root --ignore-floppies --ignore-cd /ogboot.me checkrange 0x07 parttype > nul;
cmp /ogboot.me /ogboot.secondboot || goto fallback;
write /ogboot.secondboot iniciado;
pause Secondboot passed. File updated. Press any key to continue...;
chainloader +1;
boot;
# Fallback
:fallback
pause Firstboot and Secondboot failed. Press any key to continue...;
quit;
# OpenGnsys-CACHE
echo "Booting OpenGnsys-CACHE"
kernel tftp://__SERVERIP__/${ISODIR}/ogvmlinuz ro boot=oginit quiet splash vga=788 irqpoll acpi=on og2nd=sqfs ogprotocol=smb ogactiveadmin=false ogdebug=false ogupdateinitrd=true ogtmpfs=15 oglivedir=${ISODIR} INFOHOST
initrd tftp://__SERVERIP__/${ISODIR}/oginitrd.img
boot || echo "Failed to boot OpenGnsys-CACHE"
# OpenGnsys-NET
echo "Booting OpenGnsys-NET"
kernel tftp://__SERVERIP__/${ISODIR}/ogvmlinuz ro boot=oginit quiet splash vga=788 irqpoll acpi=on og2nd=sqfs ogprotocol=smb ogactiveadmin=false ogdebug=false ogtmpfs=15 oglivedir=${ISODIR} INFOHOST
initrd tftp://__SERVERIP__/${ISODIR}/oginitrd.img
boot || echo "Failed to boot OpenGnsys-NET"
# OpenGnsys-NET Default
echo "Booting OpenGnsys-NET Default"
kernel tftp://__SERVERIP__/ogLive/ogvmlinuz ro boot=oginit quiet splash vga=788 irqpoll acpi=on og2nd=sqfs ogprotocol=smb ogactiveadmin=false ogdebug=false ogtmpfs=15 oglivedir=ogLive INFOHOST
initrd tftp://__SERVERIP__/ogLive/oginitrd.img
boot || echo "Failed to boot OpenGnsys-NET Default"
exit
# UEFI Boot Logic
:uefi_boot
echo "Running in UEFI mode..."
set timeout 30
# Verificar y buscar cargadores en orden de prioridad
echo "Searching Grub loader..."
sanboot --no-describe --drive 0 --filename \EFI\grub\Boot\grubx64.efi && exit || echo "Grub not found."
echo "Searching rEFInd loader..."
sanboot --no-describe --drive 0 --filename \EFI\refind\shimx64.efi.signed && exit || echo "rEFInd not found."
echo "Searching Part-01-02 loader..."
sanboot --no-describe --drive 0 --filename \EFI\Part-01-02\Boot\ogloader.efi && exit || echo "Part-01-02 not found."
echo "Searching Part-01-03 loader..."
sanboot --no-describe --drive 0 --filename \EFI\Part-01-03\Boot\ogloader.efi && exit || echo "Part-01-03 not found."
echo "Searching Microsoft loader..."
sanboot --no-describe --drive 0 --filename \EFI\Microsoft\Boot\bootmgfw.efi && exit || echo "Microsoft loader not found."
echo "Searching Ubuntu loader..."
sanboot --no-describe --drive 0 --filename \EFI\ubuntu\grubx64.efi && exit || echo "Ubuntu loader not found."
# Fallback: Si no hay cargadores encontrados
echo "No bootable operating system detected by OpenGnsys. Falling back..."
exit

View File

@ -1,15 +0,0 @@
#!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

View File

@ -1,15 +0,0 @@
#!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

View File

@ -1,16 +0,0 @@
#!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

View File

@ -1,16 +0,0 @@
#!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

View File

@ -1,14 +0,0 @@
#!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 Menu WIP"
chain http://__SERVERIP__/tftpboot/grub.exe --config-file="timeout 0; title menu WIP;root (hd0,0);chainloader (hd0,0)+1;boot" || echo "Failed to boot in BIOS mode"
exit
:uefi_boot
echo "Running in UEFI mode - Booting Menu"
chain http://__SERVERIP__/tftpboot/grubx64.efi
exit

View File

@ -1,19 +0,0 @@
#!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 ${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

Some files were not shown because too many files have changed in this diff Show More