Compare commits

..

No commits in common. "main" and "ticket-577" have entirely different histories.

104 changed files with 2260 additions and 7134 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,111 +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.7] - 2024-06-25
### Changed
- Elimina el parámetro de kernel ogdebug del controlador y se le añade a las plantillas de arranque de oglive
## [0.8.6] - 2024-06-24
### Changed
- Modifica la plantilla de arranque por disco y partición para no tener hardcodeado la partición EFI
## [0.8.5] - 2024-06-24
### Changed
- Comprueba si existe una etiqueta para asignar root cuando corresponda en la plantilla de arranque por disco y partición
## [0.8.4] - 2024-06-20
### Changed
- Corrige oglivecli para que desmonte los puntos de montaje ante cualquier fallo en el script de instalación de oglive
## [0.8.3] - 2024-06-20
### Changed
- Añade el cambio de la 0.8.2
## [0.8.2] - 2024-06-20
### Changed
- Corrige un bug en oglivecli que impide cambiar el propietario del oglive
## [0.8.1] - 2024-06-18
### Changed
- Añade nuevos modulos al grubx64.efi
## [0.8.0] - 2024-06-18
### Changed
- Actualiza a 0.8.0 para incluir los cambios de la versión 0.7.2
## [0.7.2] - 2024-06-05
### Changed
- Añade scripts de grub y menu.lst para el arranque por disco y partición
- Añade plantilla ogliveadmin con permisos de administracion como parametro del kernel
- Añade plantilla de menú para el arranque por disco y partición y caché
## [0.7.1] - 2024-05-19
### Changed
- Añade scripts de grub y menu.lst para el arranque del Oglive por cache
## [0.7.0] - 2024-03-26
### Changed
- Updated files location
## [0.6.3] - 2025-03-19
### Changed
- Jenkinsfile to upload debian packages
## [0.6.2] - 2025-03-19
### Changed
- Jenkinsfile to upload debian packages
## [0.6.1] - 2025-02-25
### Fixed
- Arreglos menores
## [0.6.1] - 2025-02-25
### Fixed
- Arreglos menores
## [0.6.0] - 2025-02-25
### Changed
- No hay cambios en esta versión, se incrementa el tag de `0.5.12` a `0.6.0`.
## [0.5.12] - 2025-02-25
### Added
- Monta `efivars` al inicio del arranque del `oglive`.
### Fixed
- Corrige un error en un `awk` al obtener entradas NVRAM.
- Devuelve un array vacío cuando no hay `oglives` instalados.
- Devuelve una excepción cuando se intenta instalar un `Oglive` ya instalado.
## [0.5.11] - 2025-02-06
### Changed
- Permite la lectura de otros usuarios en el home `/opt/opengnsys` del usuario `opengnsys`.
## [0.5.10] - 2025-02-06
### Changed
- Cambia el home del usuario `opengnsys` a `/opt/opengnsys`.
## [0.5.9] - 2025-02-03
### Added
- Añade el puerto `8443` de `ogcore` al `PostConf.lib`.
## [0.5.8] - 2025-01-13
### Fixed
- Arregla un bug que no añadía los parámetros `ogcore` y `oglog` al crear los ficheros de arranque.
## [0.5.7] - 2025-01-13
### Added
- Añade logs para todos los endpoints siguiendo un formato JSON preestablecido.
### Changed
- Actualiza `monolog.yaml` para enviar logs al `journal` de la máquina.

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,200 +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
cleanup() {
code=$?
umount "$OGLIVEFILE" >/dev/null 2>&1
umount "$TMPDIR" >/dev/null 2>&1
umount "$TMPDIR_SQUASHFS" >/dev/null 2>&1
if [ $code -ne 0 ]; then
echo "Something went wrong (exit code $code), cleaning up..."
rm -r "$OGLIVEDIR" >/dev/null 2>&1
fi
}
trap cleanup EXIT
mount "$OGLIVEFILE" >/dev/null 2>&1 || { echo "{\"error\": \"MOUNT_FAILED\", \"message\": \"Failed to mount ISO file.\"}"; exit 500; }
cp -va "$TMPDIR/ogclient/"* "$OGLIVEDIR" >/dev/null 2>&1 || { echo "{\"error\": \"COPY_FAILED\", \"message\": \"Cannot copy files to $OGLIVEDIR.\"}"; exit 500; }
chmod -R u+w "$OGLIVEDIR" || { echo "{\"error\": \"PERMISSION_CHANGE_FAILED\", \"message\": \"Failed to change permissions for $OGLIVEDIR.\"}"; exit 500; }
umount "$TMPDIR" >/dev/null 2>&1
if [ ! -f "$INFOFILE" ]; then
rm -f "$TFTPDIR/$DEFOGLIVE" "$TFTPDIR/$OGCLIENT"
ln -vfs "$(basename "$OGLIVEDIR")" "$TFTPDIR/$DEFOGLIVE" >/dev/null 2>&1 || { echo "{\"error\": \"LINK_FAILED\", \"message\": \"Linking to $TFTPDIR/$DEFOGLIVE failed.\"}"; exit 500; }
ln -vfs "$DEFOGLIVE" "$TFTPDIR/$OGCLIENT" >/dev/null 2>&1 || { echo "{\"error\": \"LINK_FAILED\", \"message\": \"Linking to $TFTPDIR/$OGCLIENT failed.\"}"; exit 500; }
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; }
# 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
@ -493,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
)
@ -532,7 +513,6 @@ EOT
echo "$INFO"
}
# Set default ogLive client by checksum.
function set_default() {
local CHECKSUM=$1
@ -566,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 .)" \
@ -665,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; }
@ -688,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
)
@ -721,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
@ -734,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 ;;
@ -766,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,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 ogdebug=false ${kernelargs} || goto fallback
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
boot
:fallback
echo "OgLive default"
set ISODIR ogLive
kernel http://__SERVERIP__/tftpboot/${ISODIR}/ogvmlinuz ogdebug=false ${kernelargs}
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
boot

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 ogactiveadmin=true ogdebug=true ${kernelargs} || goto fallback
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
boot
:fallback
echo "OgLive default"
set ISODIR ogLive
kernel http://__SERVERIP__/tftpboot/${ISODIR}/ogvmlinuz ogactiveadmin=true ogdebug=true ${kernelargs}
initrd http://__SERVERIP__/tftpboot/${ISODIR}/oginitrd.img
boot

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